From 5554f2cdd809c1e11d996e77084ccc35c412f7ab Mon Sep 17 00:00:00 2001
From: SkyratBot <59378654+SkyratBot@users.noreply.github.com>
Date: Tue, 23 Mar 2021 15:09:23 +0100
Subject: [PATCH] [MIRROR] Ice cream revamp: Ice cream is a component and cones
can hold multiple servings of ice cream now. (#4341)
* Ice cream revamp: Ice cream is a component and cones can hold multiple servings of ice cream now. (#57415)
* Ice cream rework WIP
* I'm done!
* i'll deal with my verbose engrish at a later date. I'm dead tired.
* linter aaaaaa
* Take a bite!
* FINALLY, A COMPONENT!
* ghost macro.
* Review, typos, beheading of a lame comsig.
* Typo. Now I'm self-obliged to test it again.
* It works.
* Ice cream revamp: Ice cream is a component and cones can hold multiple servings of ice cream now.
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
---
code/__DEFINES/food.dm | 12 +
code/__HELPERS/reagents.dm | 8 +
code/__HELPERS/unsorted.dm | 20 ++
code/datums/components/food/edible.dm | 1 +
.../components/food/ice_cream_holder.dm | 277 ++++++++++++++++++
code/game/objects/items/food/frozen.dm | 12 +
code/game/objects/items/food/pastries.dm | 35 +++
code/game/objects/items/robot/robot_items.dm | 6 +-
code/game/objects/structures/morgue.dm | 6 +-
.../kitchen_machinery/icecream_vat.dm | 241 +++++----------
tgstation.dme | 1 +
11 files changed, 437 insertions(+), 182 deletions(-)
create mode 100644 code/datums/components/food/ice_cream_holder.dm
diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm
index 6853c609b32..c20e202ab5b 100644
--- a/code/__DEFINES/food.dm
+++ b/code/__DEFINES/food.dm
@@ -75,3 +75,15 @@
#define DRINK_PRICE_EASY 35
#define DRINK_PRICE_MEDIUM 80
#define DRINK_PRICE_HIGH 200
+
+
+/// Flavour defines (also names) for GLOB.ice_cream_flavours list access. Safer from mispelling than plain text.
+#define ICE_CREAM_VANILLA "vanilla"
+#define ICE_CREAM_CHOCOLATE "chocolate"
+#define ICE_CREAM_STRAWBERRY "strawberry"
+#define ICE_CREAM_BLUE "blue"
+#define ICE_CREAM_MOB "mob"
+#define ICE_CREAM_CUSTOM "custom"
+#define ICE_CREAM_BLAND "bland"
+
+#define DEFAULT_MAX_ICE_CREAM_SCOOPS 3
diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm
index ac304e312aa..e959b9734ff 100644
--- a/code/__HELPERS/reagents.dm
+++ b/code/__HELPERS/reagents.dm
@@ -202,3 +202,11 @@
return
var/list/matching_reactions = GLOB.chemical_reactions_list_product_index[input_type]
return matching_reactions
+
+/proc/reagent_paths_list_to_text(list/reagents, addendum)
+ var/list/temp = list()
+ for(var/datum/reagent/R as anything in reagents)
+ temp |= initial(R.name)
+ if(addendum)
+ temp += addendum
+ return jointext(temp, ", ")
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index a22dc6b7bda..827e044b3be 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1453,4 +1453,24 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
set waitfor = FALSE
return call(source, proctype)(arglist(arguments))
+/// Returns the name of the mathematical tuple of same length as the number arg (rounded down).
+/proc/make_tuple(number)
+ var/static/list/units_prefix = list("", "un", "duo", "tre", "quattuor", "quin", "sex", "septen", "octo", "novem")
+ var/static/list/tens_prefix = list("", "decem", "vigin", "trigin", "quadragin", "quinquagin", "sexagin", "septuagin", "octogin", "nongen")
+ var/static/list/one_to_nine = list("monuple", "double", "triple", "quadruple", "quintuple", "sextuple", "septuple", "octuple", "nonuple")
+ number = round(number)
+ switch(number)
+ if(0)
+ return "empty tuple"
+ if(1 to 9)
+ return one_to_nine[number]
+ if(10 to 19)
+ return "[units_prefix[(number%10)+1]]decuple"
+ if(20 to 99)
+ return "[units_prefix[(number%10)+1]][tens_prefix[round((number % 100)/10)+1]]tuple"
+ if(100)
+ return "centuple"
+ else //It gets too tedious to use latin prefixes from here.
+ return "[number]-tuple"
+
#define TURF_FROM_COORDS_LIST(List) (locate(List[1], List[2], List[3]))
diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm
index cce7ed7336e..0558bdd5f7f 100644
--- a/code/datums/components/food/edible.dm
+++ b/code/datums/components/food/edible.dm
@@ -448,3 +448,4 @@ Behavior that's still missing from this component that original food items had t
for (var/t in E.tastes)
tastes[t] += E.tastes[t]
foodtypes |= E.foodtypes
+
diff --git a/code/datums/components/food/ice_cream_holder.dm b/code/datums/components/food/ice_cream_holder.dm
new file mode 100644
index 00000000000..88417476be5
--- /dev/null
+++ b/code/datums/components/food/ice_cream_holder.dm
@@ -0,0 +1,277 @@
+#define SCOOP_OFFSET 4
+#define SWEETENER_PER_SCOOP 10
+#define EXTRA_MAX_VOLUME_PER_SCOOP 20
+
+/// Ice Cream Holder: Allows the edible parent object to be used as an ice cream cone (or cup... in a next future).
+/datum/component/ice_cream_holder
+ /// List of servings of ice cream it is holding at the moment.
+ var/list/scoops
+ /// Servings of ice cream with custom names as key, and their base ones as assoc. (useful for mob/custom ice cream)
+ var/list/special_scoops
+ /*
+ * List of scoop overlays to add on update_overlays(). Separated from list/scoops considering how byond is inconsistent
+ * at handling duplicate keys and assocs.
+ */
+ var/list/scoop_overlays
+ /// Number of servings of ice cream it can get through normal methods.
+ var/max_scoops = DEFAULT_MAX_ICE_CREAM_SCOOPS
+ /// Changes the name of the food depending on amount and flavours of ice cream on it.
+ var/change_name = TRUE
+ /// name to use, if set, in place of [src] on update_name.
+ var/filled_name
+ /*
+ * Ditto as change_name, but for descriptions.
+ * If false, an examine signal is registered to let the amount and types of held ice cream be known anyway.
+ */
+ var/change_desc = FALSE
+ /// pixel offsets for scoop overlays. Useful for objects with off-centered sprites.
+ var/x_offset = 0
+ var/y_offset = 0
+ /*
+ * Extra reagent generated each time a new serving is added. Because apparently our sundaes are instead banana splits!
+ * And banana juice plus sugar equals laughter! (I'll leave it unchanged for honkdaes though)
+ */
+ var/datum/reagent/sweetener
+
+
+/datum/component/ice_cream_holder/Initialize(max_scoops = DEFAULT_MAX_ICE_CREAM_SCOOPS,
+ change_name = TRUE,
+ filled_name,
+ change_desc = FALSE,
+ x_offset = 0,
+ y_offset = 0,
+ datum/reagent/sweetener = /datum/reagent/consumable/sugar,
+ list/prefill_flavours)
+ if(!IS_EDIBLE(parent)) /// There is no easy way to add servings to those non-item edibles, but I won't stop you.
+ return COMPONENT_INCOMPATIBLE
+
+ var/atom/owner = parent
+
+ src.max_scoops = max_scoops
+ src.change_name = change_name
+ src.filled_name = filled_name
+ src.change_desc = change_desc
+ src.x_offset = x_offset
+ src.y_offset = y_offset
+ src.sweetener = sweetener
+
+ RegisterSignal(owner, COMSIG_ITEM_ATTACK_OBJ, .proc/on_item_attack_obj)
+ RegisterSignal(owner, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/on_update_overlays)
+ if(change_name)
+ RegisterSignal(owner, COMSIG_ATOM_UPDATE_NAME, .proc/on_update_name)
+ if(!change_desc)
+ RegisterSignal(owner, COMSIG_PARENT_EXAMINE_MORE, .proc/on_examine_more)
+ else
+ RegisterSignal(owner, COMSIG_ATOM_UPDATE_DESC, .proc/on_update_desc)
+
+ if(prefill_flavours)
+ for(var/entry in prefill_flavours)
+ var/list/flavour_args = list(src) + prefill_flavours[entry]
+ var/datum/ice_cream_flavour/flavour = GLOB.ice_cream_flavours[entry]
+ flavour?.add_flavour(arglist(flavour_args))
+
+/datum/component/ice_cream_holder/proc/on_update_name(atom/source, updates)
+ var/obj/obj = source
+ if(istype(obj) && obj.renamedByPlayer) //Renamed by the player.
+ return
+ var/scoops_len = length(scoops)
+ if(!scoops_len)
+ source.name = initial(source.name)
+ else
+ var/name_to_use = filled_name || initial(source.name)
+ var/list/unique_list = uniqueList(scoops)
+ if(scoops_len > 1 && length(unique_list) == 1) // multiple flavours, and all of the same type
+ source.name = "[make_tuple(scoops_len)] [scoops[1]] [name_to_use]" // "double vanilla" sounds cooler than just "vanilla"
+ else
+ source.name = "[english_list(unique_list)] [name_to_use]"
+
+/datum/component/ice_cream_holder/proc/on_update_desc(atom/source, updates)
+ var/obj/obj = source
+ if(istype(obj) && obj.renamedByPlayer) //Renamed by the player.
+ return
+ var/scoops_len = length(scoops)
+ if(!scoops_len)
+ source.desc = initial(source.desc)
+ else if(scoops_len == 1 || length(uniqueList(scoops)) == 1) /// Only one flavour.
+ var/key = scoops[1]
+ var/datum/ice_cream_flavour/flavour = GLOB.ice_cream_flavours[LAZYACCESS(special_scoops, key) || key]
+ if(!flavour?.desc) //I scream.
+ source.desc = initial(source.desc)
+ else
+ source.desc = replacetext(replacetext("[flavour.desc_prefix] [flavour.desc]", "$CONE_NAME", initial(source.name)), "$CUSTOM_NAME", key)
+ else /// Many flavours.
+ source.desc = "A delicious [initial(source.name)] filled with scoops of [english_list(scoops)] icecream. That's as many as [scoops_len] scoops!"
+
+/datum/component/ice_cream_holder/proc/on_examine_more(atom/source, mob/mob, list/examine_list)
+ var/scoops_len = length(scoops)
+ if(scoops_len == 1 || length(uniqueList(scoops)) == 1) /// Only one flavour.
+ var/key = scoops[1]
+ var/datum/ice_cream_flavour/flavour = GLOB.ice_cream_flavours[LAZYACCESS(special_scoops, key) || key]
+ if(flavour?.desc) //I scream.
+ examine_list += "[source.p_theyre(TRUE)] filled with scoops of [flavour ? flavour.name : "broken, unhappy"] icecream."
+ else
+ examine_list += replacetext(replacetext("[source.p_theyre(TRUE)] [flavour.desc]", "$CONE_NAME", initial(source.name)), "$CUSTOM_NAME", key)
+ else /// Many flavours.
+ examine_list += "[source.p_theyre(TRUE)] filled with scoops of [english_list(scoops)] icecream. That's as many as [scoops_len] scoops!"
+
+/datum/component/ice_cream_holder/proc/on_update_overlays(atom/source, list/new_overlays)
+ if(!scoops)
+ return
+ var/added_offset = 0
+ for(var/i in 1 to length(scoop_overlays))
+ var/image/overlay = scoop_overlays[i]
+ if(istext(overlay))
+ overlay = image('icons/obj/kitchen.dmi', overlay)
+ overlay.pixel_x = x_offset
+ overlay.pixel_y = y_offset + added_offset
+ new_overlays += overlay
+ added_offset += SCOOP_OFFSET
+
+/// Attack the ice cream vat to get some ice cream. This will change as new ways of getting ice cream are added.
+/datum/component/ice_cream_holder/proc/on_item_attack_obj(obj/item/source, obj/target, mob/user)
+ if(!istype(target, /obj/machinery/icecream_vat))
+ return
+ var/obj/machinery/icecream_vat/dispenser = target
+ if(length(scoops) < max_scoops)
+ if(dispenser.product_types[dispenser.selected_flavour] > 0)
+ var/datum/ice_cream_flavour/flavour = GLOB.ice_cream_flavours[dispenser.selected_flavour]
+ if(flavour.add_flavour(src, dispenser.beaker?.reagents.total_volume ? dispenser.beaker.reagents : null))
+ dispenser.visible_message("[icon2html(dispenser, viewers(source))] [user] scoops delicious [dispenser.selected_flavour] ice cream into [source].")
+ dispenser.product_types[dispenser.selected_flavour]--
+ dispenser.updateDialog()
+ else
+ to_chat(user, "There is not enough ice cream left!")
+ else
+ to_chat(user, "[source] can't hold anymore ice cream!")
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+/////ICE CREAM FLAVOUR DATUM STUFF
+
+GLOBAL_LIST_INIT_TYPED(ice_cream_flavours, /datum/ice_cream_flavour, init_ice_cream_flavours())
+
+/proc/init_ice_cream_flavours()
+ . = list()
+ for(var/datum/ice_cream_flavour/flavour as anything in subtypesof(/datum/ice_cream_flavour))
+ flavour = new flavour
+ .[flavour.name] = flavour
+
+/*
+ * The ice cream flavour datum. What makes these digital, frozen snacks so yummy.
+ * They are singletons, so please bear with me if they feel a little tortous to use at time.
+ */
+/datum/ice_cream_flavour
+ /// Make sure the same name is not found on other types; These are singletons keyed by their name after all.
+ var/name = "Coderlicious Gourmet Double Deluxe Undefined"
+ /// The icon state of the flavour, overlay or not.
+ var/icon_state = "icecream_vanilla"
+ /*
+ * The fluff text sent to the examiner when the snack has only one flavour of ice cream.
+ * $CONE_NAME and $CUSTOM_NAME are both placeholders for the cone and the custom ice cream name respectively.
+ */
+ var/desc = ""
+ /*
+ * Depending on the value of the [/datum/component/ice_cream/var/change_desc] bool, 'desc' may effectively be the description
+ * or a text string shown on [/atom/proc/examine_more]. In the former case, the desc is joined with this prefix.
+ */
+ var/desc_prefix = "A delicious $CONE_NAME"
+ /// The ingredients required to produce a unit with the ice cream vat, these are multiplied by 3.
+ var/list/ingredients = list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/vanilla)
+ /// The same as above, but in a readable text generated on New() that can also contain fluff ingredients such as "lot of love" or "optional flavorings".
+ var/ingredients_text = ""
+ /// the reagent added in 'add_flavour()'
+ var/reagent_type
+ /// the amount of reagent added in 'add_flavour()'
+ var/reagent_amount = 3
+ /// Is this flavour shown in the ice cream vat menu or not?
+ var/hidden = FALSE
+
+/datum/ice_cream_flavour/New()
+ if(ingredients)
+ ingredients_text = "(Ingredients: [reagent_paths_list_to_text(ingredients, ingredients_text)])"
+
+/// Adds a new flavour to the ice cream cone.
+/datum/ice_cream_flavour/proc/add_flavour(datum/component/ice_cream_holder/target, datum/reagents/R, custom_name)
+ var/atom/owner = target.parent
+ LAZYADD(target.scoops, custom_name || name)
+ if(icon_state)
+ LAZYADD(target.scoop_overlays, icon_state)
+ if(custom_name)
+ LAZYSET(target.special_scoops, custom_name, name)
+
+ owner.reagents.maximum_volume += EXTRA_MAX_VOLUME_PER_SCOOP
+ if(reagent_type)
+ owner.reagents.add_reagent(reagent_type, reagent_amount, reagtemp = T0C)
+ // Add some sugar/sweetener to make it a more substantial snack.
+ owner.reagents.add_reagent(target.sweetener, SWEETENER_PER_SCOOP, reagtemp = T0C)
+
+ var/update_flags = UPDATE_ICON
+ if(target.change_name)
+ update_flags |= UPDATE_NAME
+ if(target.change_desc)
+ update_flags |= UPDATE_DESC
+ owner.update_appearance(update_flags)
+ return TRUE
+
+///// OUR TYPES OF ICE CREAM, COME GET SOME.
+
+/datum/ice_cream_flavour/vanilla
+ name = ICE_CREAM_VANILLA
+ desc = "filled with vanilla ice cream. All the other ice creams take content from it."
+ reagent_type = /datum/reagent/consumable/vanilla
+
+/datum/ice_cream_flavour/chocolate
+ name = ICE_CREAM_CHOCOLATE
+ icon_state = "icecream_chocolate"
+ desc = "filled with chocolate ice cream. Surprisingly, made with real cocoa."
+ ingredients = list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/coco)
+ reagent_type = /datum/reagent/consumable/coco
+
+/datum/ice_cream_flavour/strawberry
+ name = ICE_CREAM_STRAWBERRY
+ icon_state = "icecream_strawberry"
+ desc = "filled with strawberry ice cream. Definitely not made with real strawberries."
+ ingredients = list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/berryjuice)
+ reagent_type = /datum/reagent/consumable/berryjuice
+
+/datum/ice_cream_flavour/blue
+ name = ICE_CREAM_BLUE
+ icon_state = "icecream_blue"
+ desc = "filled with blue ice cream. Made with real... blue?"
+ ingredients = list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/ethanol/singulo)
+ reagent_type = /datum/reagent/consumable/ethanol/singulo
+
+/datum/ice_cream_flavour/mob
+ name = ICE_CREAM_MOB
+ icon_state = "icecream_mob"
+ desc = "filled with bright red ice cream. That's probably not strawberry..."
+ desc_prefix = "A suspicious $CONE_NAME"
+ reagent_type = /datum/reagent/liquidgibs
+ hidden = TRUE
+
+/datum/ice_cream_flavour/custom
+ name = ICE_CREAM_CUSTOM
+ icon_state = "" //has its own mutable appearance overlay.
+ desc = "filled with artisanal icecream. Made with real $CUSTOM_NAME. Ain't that something."
+ ingredients = list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice)
+ ingredients_text = "optional flavorings"
+
+/datum/ice_cream_flavour/custom/add_flavour(datum/component/ice_cream_holder/target, datum/reagents/R, custom_name)
+ if(!R || R.total_volume < 4) //consumable reagents have stronger taste so higher volume are required to allow non-food flavourings to break through better.
+ return GLOB.ice_cream_flavours[ICE_CREAM_BLAND].add_flavour(target) //Bland, sugary ice and milk.
+ var/image/flavoring = image('icons/obj/kitchen.dmi', "icecream_custom")
+ var/datum/reagent/master = R.get_master_reagent()
+ custom_name = lowertext(master.name) // reagent names are capitalized, while items' aren't.
+ flavoring.color = master.color
+ LAZYADD(target.scoop_overlays, flavoring)
+ . = ..() // Make some space for reagents before attempting to transfer some to the target.
+ R.trans_to(target.parent, 4)
+
+/datum/ice_cream_flavour/bland
+ name = ICE_CREAM_BLAND
+ icon_state = "icecream_custom"
+ desc = "filled with anemic, flavorless icecream. You wonder why this was ever scooped..."
+ hidden = TRUE
+
+#undef SCOOP_OFFSET
+#undef SWEETENER_PER_SCOOP
+#undef EXTRA_MAX_VOLUME_PER_SCOOP
diff --git a/code/game/objects/items/food/frozen.dm b/code/game/objects/items/food/frozen.dm
index d7a82a57c6c..f3fb6985e19 100644
--- a/code/game/objects/items/food/frozen.dm
+++ b/code/game/objects/items/food/frozen.dm
@@ -29,6 +29,10 @@
tastes = list("blue cherries" = 2, "ice cream" = 2)
foodtypes = FRUIT | DAIRY | SUGAR
+/obj/item/food/spacefreezy/MakeEdible()
+ . = ..()
+ AddComponent(/datum/component/ice_cream_holder)
+
/obj/item/food/sundae
name = "sundae"
desc = "A classic dessert."
@@ -39,6 +43,10 @@
tastes = list("ice cream" = 1, "banana" = 1)
foodtypes = FRUIT | DAIRY | SUGAR
+/obj/item/food/sundae/MakeEdible()
+ . = ..()
+ AddComponent(/datum/component/ice_cream_holder, y_offset = -2, sweetener = /datum/reagent/consumable/caramel)
+
/obj/item/food/honkdae
name = "honkdae"
desc = "The clown's favorite dessert."
@@ -49,6 +57,10 @@
tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1)
foodtypes = FRUIT | DAIRY | SUGAR
+/obj/item/food/honkdae/MakeEdible()
+ . = ..()
+ AddComponent(/datum/component/ice_cream_holder, y_offset = -2) //The sugar will react with the banana forming laughter. Honk!
+
/////////////
//SNOWCONES//
/////////////
diff --git a/code/game/objects/items/food/pastries.dm b/code/game/objects/items/food/pastries.dm
index 65fe33a8f70..e760f2dc668 100644
--- a/code/game/objects/items/food/pastries.dm
+++ b/code/game/objects/items/food/pastries.dm
@@ -857,5 +857,40 @@
w_class = WEIGHT_CLASS_TINY
venue_value = FOOD_PRICE_CHEAP // Pastry base, 3u of sugar and a single. fucking. unit. of. milk. really?
+/obj/item/food/icecream
+ name = "waffle cone"
+ desc = "Delicious waffle cone, but no ice cream."
+ icon = 'icons/obj/kitchen.dmi'
+ icon_state = "icecream_cone_waffle"
+ food_reagents = list(/datum/reagent/consumable/nutriment = 5)
+ tastes = list("cream" = 2, "waffle" = 1)
+ bite_consumption = 4
+ foodtypes = DAIRY | SUGAR
+ max_volume = 10 //The max volumes scales up with the number of scoops of ice cream served.
+ /// These two variables are used by the ice cream vat. Latter is the one that shows on the UI.
+ var/list/ingredients = list(/datum/reagent/consumable/flour, /datum/reagent/consumable/sugar)
+ var/ingredients_text
+ /*
+ * Assoc list var used to prefill the cone with ice cream.
+ * Key is the flavour's name (use text defines; see __DEFINES/food.dm or ice_cream_holder.dm),
+ * assoc is the list of args that is going to be used in [flavour/add_flavour()]. Can as well be null for simple flavours.
+ */
+ var/list/prefill_flavours
+
+/obj/item/food/icecream/Initialize(mapload, list/prefill_flavours)
+ if(prefill_flavours)
+ src.prefill_flavours = prefill_flavours
+ return ..()
+
+/obj/item/food/icecream/MakeEdible()
+ . = ..()
+ AddComponent(/datum/component/ice_cream_holder, filled_name = "ice cream", change_desc = TRUE, prefill_flavours = prefill_flavours)
+
+/obj/item/food/icecream/chocolate
+ name = "chocolate cone"
+ desc = "Delicious chocolate cone, but no ice cream."
+ icon_state = "icecream_cone_chocolate"
+ food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/coco = 1)
+ ingredients = list(/datum/reagent/consumable/flour, /datum/reagent/consumable/sugar, /datum/reagent/consumable/coco)
#undef DONUT_SPRINKLE_CHANCE
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 221a73a5a51..ce19982c17f 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -393,10 +393,8 @@
if(DISPENSE_LOLLIPOP_MODE)
food_item = new /obj/item/food/chewable/lollipop(T)
if(DISPENSE_ICECREAM_MODE)
- food_item = new /obj/item/food/icecream(T)
- var/obj/item/food/icecream/I = food_item
- I.add_ice_cream("vanilla")
- I.desc = "Eat the ice cream."
+ food_item = new /obj/item/food/icecream(T, list(ICE_CREAM_VANILLA))
+ food_item.desc = "Eat the ice cream."
var/into_hands = FALSE
if(ismob(A))
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 4b1bfdd15cc..0a792ff6806 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -295,10 +295,8 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/structure/bodycontainer/crematorium/creamatorium/cremate(mob/user)
var/list/icecreams = new()
- for(var/i_scream in get_all_contents_type(/mob/living))
- var/obj/item/food/icecream/IC = new()
- IC.set_cone_type("waffle")
- IC.add_mob_flavor(i_scream)
+ for(var/mob/living/i_scream as anything in get_all_contents_type(/mob/living))
+ var/obj/item/food/icecream/IC = new(null, list(ICE_CREAM_MOB = list(null, i_scream.name)))
icecreams += IC
. = ..()
for(var/obj/IC in icecreams)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
index d1594f90a22..c85a5f6d3be 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
@@ -1,10 +1,4 @@
-#define ICECREAM_VANILLA 1
-#define ICECREAM_CHOCOLATE 2
-#define ICECREAM_STRAWBERRY 3
-#define ICECREAM_BLUE 4
-#define ICECREAM_CUSTOM 5
-#define CONE_WAFFLE 6
-#define CONE_CHOC 7
+#define PREFILL_AMOUNT 5
/obj/machinery/icecream_vat
name = "ice cream vat"
@@ -17,9 +11,10 @@
layer = BELOW_OBJ_LAYER
max_integrity = 300
var/list/product_types = list()
- var/dispense_flavour = ICECREAM_VANILLA
- var/flavour_name = "vanilla"
- var/obj/item/reagent_containers/beaker = null
+ var/selected_flavour = ICE_CREAM_VANILLA
+ var/obj/item/reagent_containers/beaker
+ /// List of prototypes of dispensable ice cream cones. path as key, instance as assoc.
+ var/static/list/obj/item/food/icecream/cone_prototypes
var/static/list/icecream_vat_reagents = list(
/datum/reagent/consumable/milk = 6,
/datum/reagent/consumable/flour = 6,
@@ -30,64 +25,43 @@
/datum/reagent/consumable/berryjuice = 6,
/datum/reagent/consumable/ethanol/singulo = 6)
-/obj/machinery/icecream_vat/proc/get_ingredient_list(type)
- switch(type)
- if(ICECREAM_CHOCOLATE)
- return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/coco)
- if(ICECREAM_STRAWBERRY)
- return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/berryjuice)
- if(ICECREAM_BLUE)
- return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/ethanol/singulo)
- if(ICECREAM_CUSTOM)
- return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice)
- if(CONE_WAFFLE)
- return list(/datum/reagent/consumable/flour, /datum/reagent/consumable/sugar)
- if(CONE_CHOC)
- return list(/datum/reagent/consumable/flour, /datum/reagent/consumable/sugar, /datum/reagent/consumable/coco)
- else //ICECREAM_VANILLA
- return list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice, /datum/reagent/consumable/vanilla)
-
-
-/obj/machinery/icecream_vat/proc/get_flavour_name(flavour_type)
- switch(flavour_type)
- if(ICECREAM_CHOCOLATE)
- return "chocolate"
- if(ICECREAM_STRAWBERRY)
- return "strawberry"
- if(ICECREAM_BLUE)
- return "blue"
- if(ICECREAM_CUSTOM)
- return "custom"
- if(CONE_WAFFLE)
- return "waffle"
- if(CONE_CHOC)
- return "chocolate"
- else //ICECREAM_VANILLA
- return "vanilla"
-
-
/obj/machinery/icecream_vat/Initialize()
. = ..()
- while(product_types.len < 7)
- product_types.Add(5)
+
+ if(!cone_prototypes)
+ cone_prototypes = list()
+ for(var/cone_path in typesof(/obj/item/food/icecream))
+ var/obj/item/food/icecream/cone = new cone_path
+ if(cone.ingredients)
+ cone_prototypes[cone_path] = cone
+ cone.ingredients_text = "(Ingredients: [reagent_paths_list_to_text(cone.ingredients)])"
+ else
+ qdel(cone)
+
create_reagents(100, NO_REACT | OPENCONTAINER)
+ reagents.chem_temp = T0C //So ice doesn't melt
+ for(var/flavour in GLOB.ice_cream_flavours)
+ if(GLOB.ice_cream_flavours[flavour].hidden)
+ continue
+ product_types[flavour] = PREFILL_AMOUNT
+ for(var/cone in cone_prototypes)
+ product_types[cone] = PREFILL_AMOUNT
+
for(var/reagent in icecream_vat_reagents)
reagents.add_reagent(reagent, icecream_vat_reagents[reagent], reagtemp = T0C)
- reagents.chem_temp = T0C //So ice doesn't melt
/obj/machinery/icecream_vat/ui_interact(mob/user)
. = ..()
var/dat
dat += "ICE CREAM