[MIRROR] Ice cream now gives a chilling food effect (plus small food haste buff) (#26914)

* Ice cream now gives a chilling food effect (plus small food haste buff) (#81719)

## About The Pull Request
We have a `crafted_food_buff` in the code meant for specific food buffs
(and perhaps one day, debuffs) that has gone unused ever since it was
created during the 'Foodening' PR.

Anyway, yeah, this PR takes the fire step to implement it with ice cream
and other frozen treats.

Frozen treats (all food found in the `food/frozen.dm` file) have it by
default. Other ice cream holders such as waffles cones (and now regular
waffles too!) can aquire it when filled with ice cream. Using the ice
cream vat also adds the 'Chef Made' trait now, which is required for
food effects to happen.

Also very slight food effect refactor. There's no need to have five
different alert screen objects when only have to switch icon states.

This PR also adds an action speed modifier to the generic 'haste' food
effect. I'm confident the original creator would have done that too, but
action speed modifiers aren't as well-known.

## Why It's Good For The Game
People tend to make one feature, call it a day and then move on to the
next. Food effects are nice, however they're barely implemented, and I
don't like food being all the same-ish in the end.

## Changelog

🆑
add: Ice cream and frozen treats now have a chilling effect.
add: You can add a scoop of ice cream on waffles.
balance: added an action speed modifier to the generic food haste effect
(you do things, and not just run, an itsy bitsy faster)
/🆑

* Ice cream now gives a chilling food effect (plus small food haste buff)

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-03-16 22:50:16 -04:00
committed by GitHub
co-authored by Ghom
parent f2b105fb3e
commit 2a355aeed2
13 changed files with 92 additions and 68 deletions
@@ -58,6 +58,7 @@
RegisterSignal(owner, COMSIG_ITEM_ATTACK_ATOM, PROC_REF(on_item_attack_obj))
RegisterSignal(owner, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
RegisterSignal(owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
if(change_name)
RegisterSignal(owner, COMSIG_ATOM_UPDATE_NAME, PROC_REF(on_update_name))
if(!change_desc)
@@ -105,20 +106,27 @@
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!"
source.desc = "A delicious [initial(source.name)] filled with scoops of [english_list(scoops)] ice cream. That's as many as [scoops_len] scoops!"
/datum/component/ice_cream_holder/proc/on_examine(atom/source, mob/mob, list/examine_list)
SIGNAL_HANDLER
if(length(scoops) < max_scoops)
examine_list += span_tinynoticeital("you could use a ice cream vat to fill it with yummy ice cream...")
/datum/component/ice_cream_holder/proc/on_examine_more(atom/source, mob/mob, list/examine_list)
SIGNAL_HANDLER
var/scoops_len = length(scoops)
if(!scoops_len)
return
if(scoops_len == 1 || length(unique_list(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()] filled with scoops of [flavour ? flavour.name : "broken, unhappy"] icecream."
examine_list += "[source.p_Theyre()] filled with scoops of [flavour ? flavour.name : "broken, unhappy"] ice cream."
else
examine_list += replacetext(replacetext("[source.p_Theyre()] [flavour.desc]", "$CONE_NAME", initial(source.name)), "$CUSTOM_NAME", key)
else /// Many flavours.
examine_list += "[source.p_Theyre()] filled with scoops of [english_list(scoops)] icecream. That's as many as [scoops_len] scoops!"
examine_list += "[source.p_Theyre()] filled with scoops of [english_list(scoops)] ice cream. That's as many as [scoops_len] scoops!"
/datum/component/ice_cream_holder/proc/on_update_overlays(atom/source, list/new_overlays)
SIGNAL_HANDLER
@@ -330,14 +338,14 @@ GLOBAL_LIST_INIT_TYPED(ice_cream_flavours, /datum/ice_cream_flavour, init_ice_cr
/datum/ice_cream_flavour/custom
name = ICE_CREAM_CUSTOM
color = COLOR_STARLIGHT //has its own mutable appearance overlay it will be overwritten with anyways.
desc = "filled with artisanal icecream. Made with real $CUSTOM_NAME. Ain't that something."
desc = "filled with artisanal ice cream. Made with real $CUSTOM_NAME. Ain't that something."
ingredients = list(/datum/reagent/consumable/milk, /datum/reagent/consumable/ice)
ingredients_text = "optional flavorings"
takes_custom_ingredients = TRUE
/datum/ice_cream_flavour/custom/korta
name = ICE_CREAM_KORTA_CUSTOM
desc = "filled with artisanal lizard-friendly icecream. Made with real $CUSTOM_NAME. Ain't that something."
desc = "filled with artisanal lizard-friendly ice cream. Made with real $CUSTOM_NAME. Ain't that something."
ingredients = list(/datum/reagent/consumable/korta_milk, /datum/reagent/consumable/ice)
ingredients_text = "optional flavorings"
@@ -354,7 +362,7 @@ GLOBAL_LIST_INIT_TYPED(ice_cream_flavours, /datum/ice_cream_flavour, init_ice_cr
/datum/ice_cream_flavour/bland
name = ICE_CREAM_BLAND
color = COLOR_ICECREAM_CUSTOM
desc = "filled with anemic, flavorless icecream. You wonder why this was ever scooped..."
desc = "filled with anemic, flavorless ice cream. You wonder why this was ever scooped..."
hidden = TRUE
#undef SWEETENER_PER_SCOOP
@@ -0,0 +1,13 @@
///food effect applied by ice cream and frozen treats
/datum/status_effect/food/chilling
alert_type = /atom/movable/screen/alert/status_effect/icecream_chilling //different path, so we sprite one state and not five.
/datum/status_effect/food/chilling/tick(seconds_between_ticks)
var/minimum_temp = (BODYTEMP_HEAT_DAMAGE_LIMIT - 12 * strength)
if(owner.bodytemperature >= minimum_temp)
owner.adjust_bodytemperature(-2.75 * strength * seconds_between_ticks, min_temp = minimum_temp)
/atom/movable/screen/alert/status_effect/icecream_chilling
desc = "Nothing beats a cup of ice cream during hot, plasma-floody day..."
icon_state = "food_icecream"
@@ -1,8 +1,7 @@
/datum/status_effect/food/trait/shockimmune
alert_type = /atom/movable/screen/alert/status_effect/food_trait_shockimmune
alert_type = /atom/movable/screen/alert/status_effect/food/trait_shockimmune
trait = TRAIT_SHOCKIMMUNE
/atom/movable/screen/alert/status_effect/food_trait_shockimmune
/atom/movable/screen/alert/status_effect/food/trait_shockimmune
name = "Grounded"
desc = "That meal made me feel like a superconductor..."
icon_state = "food_buff_4"
@@ -0,0 +1,27 @@
///Haste makes the eater move and act faster
/datum/status_effect/food/haste
/datum/status_effect/food/haste/on_apply()
var/datum/movespeed_modifier/food_haste/speed_mod = new()
speed_mod.multiplicative_slowdown = -0.04 * strength
owner.add_movespeed_modifier(speed_mod, update = TRUE)
var/datum/actionspeed_modifier/status_effect/food_haste/action_mod = new()
action_mod.multiplicative_slowdown = -0.06 * strength
owner.add_actionspeed_modifier(action_mod, update = TRUE)
return ..()
/datum/status_effect/food/haste/be_replaced()
owner.remove_movespeed_modifier(/datum/movespeed_modifier/food_haste)
owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/food_haste)
return ..()
/datum/status_effect/food/haste/on_remove()
owner.remove_movespeed_modifier(/datum/movespeed_modifier/food_haste, update = TRUE)
owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/food_haste, update = TRUE)
return ..()
/datum/movespeed_modifier/food_haste
multiplicative_slowdown = -0.04
/datum/actionspeed_modifier/status_effect/food_haste
multiplicative_slowdown = -0.06
@@ -1,20 +0,0 @@
/// Haste makes the eater move faster
/datum/status_effect/food/haste
var/datum/movespeed_modifier/food_haste/modifier
/datum/status_effect/food/haste/on_apply()
modifier = new()
modifier.multiplicative_slowdown = -0.04 * strength
owner.add_movespeed_modifier(modifier, update = TRUE)
return ..()
/datum/status_effect/food/haste/be_replaced()
owner.remove_movespeed_modifier(modifier, update = TRUE)
return ..()
/datum/status_effect/food/haste/on_remove()
owner.remove_movespeed_modifier(modifier, update = TRUE)
return ..()
/datum/movespeed_modifier/food_haste
multiplicative_slowdown = -0.1
+4 -17
View File
@@ -3,37 +3,24 @@
id = "food_buff"
duration = 5 MINUTES // Same as food mood buffs
status_type = STATUS_EFFECT_REPLACE // Only one food buff allowed
alert_type = /atom/movable/screen/alert/status_effect/food
/// Buff power
var/strength
/datum/status_effect/food/on_creation(mob/living/new_owner, timeout_mod = 1, strength = 1)
src.strength = strength
//Generate alert when not specified
if(alert_type == /atom/movable/screen/alert/status_effect)
alert_type = "/atom/movable/screen/alert/status_effect/food/buff_[strength]"
if(isnum(timeout_mod))
duration *= timeout_mod
. = ..()
if(istype(linked_alert, /atom/movable/screen/alert/status_effect/food))
linked_alert.icon_state = "[linked_alert.base_icon_state]_[strength]"
/atom/movable/screen/alert/status_effect/food
name = "Hand-crafted meal"
desc = "Eating it made me feel better."
icon_state = "food_buff_1"
/atom/movable/screen/alert/status_effect/food/buff_1
icon_state = "food_buff_1"
/atom/movable/screen/alert/status_effect/food/buff_2
icon_state = "food_buff_2"
/atom/movable/screen/alert/status_effect/food/buff_3
icon_state = "food_buff_3"
/atom/movable/screen/alert/status_effect/food/buff_4
icon_state = "food_buff_4"
/atom/movable/screen/alert/status_effect/food/buff_5
icon_state = "food_buff_5"
base_icon_state = "food_buff"
/// Makes you gain a trait
/datum/status_effect/food/trait
+8 -1
View File
@@ -12,6 +12,7 @@
foodtypes = GRAIN | DAIRY | SUGAR
food_flags = FOOD_FINGER_FOOD
crafting_complexity = FOOD_COMPLEXITY_2
crafted_food_buff = /datum/status_effect/food/chilling
/obj/item/food/strawberryicecreamsandwich
name = "strawberry ice cream sandwich"
@@ -27,7 +28,7 @@
foodtypes = FRUIT | DAIRY | SUGAR
food_flags = FOOD_FINGER_FOOD
crafting_complexity = FOOD_COMPLEXITY_3
crafted_food_buff = /datum/status_effect/food/chilling
/obj/item/food/spacefreezy
name = "space freezy"
@@ -43,6 +44,7 @@
tastes = list("blue cherries" = 2, "ice cream" = 2)
foodtypes = FRUIT | DAIRY | SUGAR
crafting_complexity = FOOD_COMPLEXITY_3
crafted_food_buff = /datum/status_effect/food/chilling
/obj/item/food/spacefreezy/make_edible()
. = ..()
@@ -62,6 +64,7 @@
tastes = list("ice cream" = 1, "banana" = 1)
foodtypes = FRUIT | DAIRY | SUGAR
crafting_complexity = FOOD_COMPLEXITY_3
crafted_food_buff = /datum/status_effect/food/chilling
/obj/item/food/sundae/make_edible()
. = ..()
@@ -81,6 +84,7 @@
tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1)
foodtypes = FRUIT | DAIRY | SUGAR
crafting_complexity = FOOD_COMPLEXITY_4
crafted_food_buff = /datum/status_effect/food/chilling
/obj/item/food/honkdae/make_edible()
. = ..()
@@ -104,6 +108,7 @@
foodtypes = SUGAR //We use SUGAR as a base line to act in as junkfood, other wise we use fruit
food_flags = FOOD_FINGER_FOOD
crafting_complexity = FOOD_COMPLEXITY_2
crafted_food_buff = /datum/status_effect/food/chilling
/obj/item/food/snowcones/lime
name = "lime snowcone"
@@ -330,6 +335,7 @@
foodtypes = DAIRY | SUGAR
food_flags = FOOD_FINGER_FOOD
crafting_complexity = FOOD_COMPLEXITY_3
crafted_food_buff = /datum/status_effect/food/chilling
var/overlay_state = "creamsicle_o" //This is the edible part of the popsicle.
var/bite_states = 4 //This value value is used for correctly setting the bite_consumption to ensure every bite changes the sprite. Do not set to zero.
@@ -434,6 +440,7 @@
foodtypes = DAIRY | SUGAR
venue_value = FOOD_PRICE_NORMAL
crafting_complexity = FOOD_COMPLEXITY_3
crafted_food_buff = /datum/status_effect/food/chilling
/obj/item/food/popsicle/meatsicle
name = "Meatsicle"
+11 -8
View File
@@ -77,6 +77,10 @@
w_class = WEIGHT_CLASS_SMALL
crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/waffles/make_edible()
. = ..()
AddComponent(/datum/component/ice_cream_holder, max_scoops = 1, x_offset = -2)
/obj/item/food/soylentgreen
name = "\improper Soylent Green"
desc = "Not made of people. Honest." //Totally people.
@@ -123,6 +127,10 @@
w_class = WEIGHT_CLASS_SMALL
crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/rofflewaffles/make_edible()
. = ..()
AddComponent(/datum/component/ice_cream_holder, max_scoops = 1, x_offset = -2)
////////////////////////////////////////////OTHER////////////////////////////////////////////
/obj/item/food/cookie
@@ -356,7 +364,7 @@
bite_consumption = 4
foodtypes = DAIRY | SUGAR
food_flags = FOOD_FINGER_FOOD
crafting_complexity = FOOD_COMPLEXITY_3
crafting_complexity = FOOD_COMPLEXITY_2
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(
@@ -371,14 +379,10 @@
*/
var/list/prefill_flavours
/obj/item/food/icecream/New(loc, list/prefill_flavours)
/obj/item/food/icecream/Initialize(mapload, list/prefill_flavours)
if(ingredients)
ingredients_text = "Requires: [reagent_paths_list_to_text(ingredients)]"
return ..()
/obj/item/food/icecream/Initialize(mapload, list/prefill_flavours)
if(prefill_flavours)
src.prefill_flavours = prefill_flavours
src.prefill_flavours = prefill_flavours
return ..()
/obj/item/food/icecream/make_edible()
@@ -398,7 +402,6 @@
/datum/reagent/consumable/sugar,
/datum/reagent/consumable/coco,
)
crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/icecream/korta
name = "korta cone"
+1 -4
View File
@@ -60,10 +60,7 @@
if(DISPENSE_LOLLIPOP_MODE)
food_item = new /obj/item/food/lollipop/cyborg(turf_to_dispense_to)
if(DISPENSE_ICECREAM_MODE)
food_item = new /obj/item/food/icecream(
loc = turf_to_dispense_to,
prefill_flavours = list(ICE_CREAM_VANILLA),
)
food_item = new /obj/item/food/icecream(turf_to_dispense_to, list(ICE_CREAM_VANILLA))
food_item.desc = "Eat the ice cream."
var/into_hands = FALSE
+3 -7
View File
@@ -450,14 +450,10 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/structure/bodycontainer/crematorium/creamatorium/cremate(mob/user)
var/list/icecreams = list()
for(var/mob/living/i_scream as anything in get_all_contents_type(/mob/living))
var/obj/item/food/icecream/IC = new /obj/item/food/icecream(
loc = null,
prefill_flavours = list(ICE_CREAM_MOB = list(null, i_scream.name))
)
icecreams += IC
icecreams += new /obj/item/food/icecream(null, list(ICE_CREAM_MOB = list(null, i_scream.name)))
. = ..()
for(var/obj/IC in icecreams)
IC.forceMove(src)
for(var/obj/ice_cream as anything in icecreams)
ice_cream.forceMove(src)
/*
* Generic Tray
@@ -249,6 +249,12 @@
reagents.remove_reagent(reagents_used, CONE_REAGENET_NEEDED)
balloon_alert_to_viewers("scoops [selected_flavour]", "scoops [selected_flavour]")
if(istype(cone))
if(isnull(cone.crafted_food_buff))
cone.crafted_food_buff = /datum/status_effect/food/chilling
if(user.mind)
ADD_TRAIT(cone, TRAIT_FOOD_CHEF_MADE, REF(user.mind))
///Swaps the mode to the next one meant to be selected, then tells the user who changed it.
/obj/machinery/icecream_vat/proc/swap_modes(mob/user)
if(!user.can_perform_action(src))
Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 140 KiB

+3 -2
View File
@@ -1865,10 +1865,11 @@
#include "code\datums\status_effects\song_effects.dm"
#include "code\datums\status_effects\stacking_effect.dm"
#include "code\datums\status_effects\wound_effects.dm"
#include "code\datums\status_effects\buffs\food_haste.dm"
#include "code\datums\status_effects\buffs\food_traits.dm"
#include "code\datums\status_effects\buffs\stop_drop_roll.dm"
#include "code\datums\status_effects\buffs\stun_absorption.dm"
#include "code\datums\status_effects\buffs\food\chilling.dm"
#include "code\datums\status_effects\buffs\food\food_traits.dm"
#include "code\datums\status_effects\buffs\food\haste.dm"
#include "code\datums\status_effects\debuffs\blindness.dm"
#include "code\datums\status_effects\debuffs\choke.dm"
#include "code\datums\status_effects\debuffs\confusion.dm"