Shoving nerds into deep-fryers (and other kitchen equipment) (#20172)

* refactor cooking machines

* uhh numbers

* Break out shove attacks, make them significantly weaker

* Address reviews, slightly improve docs

* Up damage numbers

* Steel's review
This commit is contained in:
Luc
2023-03-16 14:13:15 -04:00
committed by GitHub
parent 7803b0287b
commit 9e4eea7578
5 changed files with 175 additions and 66 deletions
@@ -20,6 +20,10 @@
///Set to TRUE if the machine supports upgrades / deconstruction, or else it will ignore stuff like screwdrivers and parts exchangers
var/upgradeable = FALSE
var/datum/looping_sound/kitchen/deep_fryer/soundloop
/// Time between special attacks
var/special_attack_cooldown_time = 5 SECONDS
/// Whether or not a special attack can be performed right now
var/special_attack_on_cooldown = FALSE
/obj/machinery/cooker/Initialize(mapload)
. = ..()
@@ -45,13 +49,69 @@
/obj/machinery/cooker/proc/setRegents(obj/item/reagent_containers/OldReg, obj/item/reagent_containers/NewReg)
OldReg.reagents.trans_to(NewReg, OldReg.reagents.total_volume)
/**
* Perform the special grab interaction.
* Return TRUE to drop the grab or FALSE to keep the grab afterwards.
*/
/obj/machinery/cooker/proc/special_attack(mob/user, mob/living/carbon/target, obj/item/grab/G)
to_chat(user, "<span class='alert'>This is ridiculous. You can not fit [target] in this [src].</span>")
return FALSE
/obj/machinery/cooker/shove_impact(mob/living/target, mob/living/attacker)
if(special_attack_on_cooldown)
return FALSE
if(!on)
// only do a special interaction if it's actually cooking something
return FALSE
. = special_attack_shove(target, attacker)
addtimer(VARSET_CALLBACK(src, special_attack_on_cooldown, FALSE), special_attack_cooldown_time)
/**
* Perform a special shove attack.
* The return value of this proc gets passed up to shove_impact, so returning TRUE will prevent any further shove handling (like knockdown).
*/
/obj/machinery/cooker/proc/special_attack_shove(mob/living/target, mob/living/attacker)
return FALSE
/**
* Verify if we would be able to perform our grab attack.
*/
/obj/machinery/cooker/proc/can_grab_attack(obj/item/grab/G, mob/user, verbose = FALSE)
if(special_attack_on_cooldown)
return FALSE
if(!istype(G))
return FALSE
if(!iscarbon(G.affecting))
if(verbose)
to_chat(user, "<span class='warning'>You can't shove that in there!</span>")
return FALSE
if(G.state < GRAB_AGGRESSIVE)
if(verbose)
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
return FALSE
return TRUE
/obj/machinery/cooker/proc/special_attack_grab(obj/item/grab/G, mob/user)
if(!can_grab_attack(G, user, FALSE)) // do it silently, but still make sure this isn't called without sanity checking first
return FALSE
var/result = special_attack(user, G.affecting, G)
user.changeNext_move(CLICK_CD_MELEE)
special_attack_on_cooldown = TRUE
addtimer(VARSET_CALLBACK(src, special_attack_on_cooldown, FALSE), special_attack_cooldown_time)
if(result && !isnull(G) && !QDELETED(G))
qdel(G)
return TRUE // end the attack chain
// check if you can put it in the machine
/obj/machinery/cooker/proc/checkValid(obj/item/check, mob/user)
if(on)
to_chat(user, "<span class='notice'>[src] is still active!</span>")
return FALSE
if(istype(check, /obj/item/grab))
return special_attack(check, user)
return can_grab_attack(check, user, TRUE) // tell the user here
if(has_specials && checkSpecials(check))
return TRUE
if(istype(check, /obj/item/reagent_containers/food/snacks) || emagged)
@@ -147,6 +207,8 @@
else
L.death()
break
if(istype(I, /obj/item/grab))
return special_attack_grab(I, user)
addtimer(CALLBACK(src, PROC_REF(finish_cook), I, user), cooktime)
/obj/machinery/cooker/proc/finish_cook(obj/item/I, mob/user, params)
@@ -190,11 +252,6 @@
if(default_deconstruction_screwdriver(user, openicon, officon, I))
return TRUE
/obj/machinery/cooker/proc/special_attack(obj/item/grab/G, mob/user)
return 0
// MAKE SURE TO OVERRIDE THESE ON THE MACHINE IF IT HAS SPECIAL FOOD INTERACTIONS!
// FAILURE TO OVERRIDE WILL RESULT IN FAILURE TO PROPERLY HANDLE SPECIAL INTERACTIONS! --FalseIncarnate
/obj/machinery/cooker/proc/checkSpecials(obj/item/I)
@@ -84,26 +84,33 @@
emagged = TRUE
return
/obj/machinery/cooker/deepfryer/special_attack(obj/item/grab/G, mob/user)
if(ishuman(G.affecting))
if(G.state < GRAB_AGGRESSIVE)
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
return 0
var/mob/living/carbon/human/C = G.affecting
var/obj/item/organ/external/head/head = C.get_organ("head")
if(!istype(head))
to_chat(user, "<span class='warning'>This person doesn't have a head!</span>")
return 0
C.visible_message("<span class='danger'>[user] dunks [C]'s face into [src]!</span>", \
"<span class='userdanger'>[user] dunks your face into [src]!</span>")
C.emote("scream")
user.changeNext_move(CLICK_CD_MELEE)
C.apply_damage(25, BURN, "head") //25 fire damage and disfigurement because your face was just deep fried!
head.disfigure()
add_attack_logs(user, G.affecting, "Deep-fried with [src]")
qdel(G) //Removes the grip so the person MIGHT have a small chance to run the fuck away and to prevent rapid dunks.
return 0
return 0
/obj/machinery/cooker/deepfryer/special_attack_shove(mob/living/target, mob/living/attacker)
target.visible_message(
"<span class='danger'>[attacker] shoves [target] against [src], and [target] reaches into the hot oil trying to catch [target.p_their()] fall!</span>",
"<span class='userdanger'>[attacker] shoves you into [src], your hands landing in hot oil!</span>",
"<span class='danger'>You hear a splash and a loud sizzle.</span>"
)
target.apply_damage(10, BURN, BODY_ZONE_PRECISE_L_HAND)
target.apply_damage(10, BURN, BODY_ZONE_PRECISE_R_HAND)
playsound(src, 'sound/goonstation/misc/drinkfizz.ogg', 25)
return FALSE
/obj/machinery/cooker/deepfryer/special_attack(mob/user, mob/living/carbon/target)
var/obj/item/organ/external/head/head = target.get_organ("head")
if(!istype(head))
to_chat(user, "<span class='warning'>This person doesn't have a head!</span>")
return FALSE // you'll probably get smacked against it
target.visible_message(
"<span class='danger'>[user] dunks [target]'s face into [src]!</span>",
"<span class='userdanger'>[user] dunks your face into [src]!</span>",
"<span class='danger'>You hear a splash and a loud sizzle.</span>"
)
playsound(src, "sound/machines/kitchen/deep_fryer_emerge.ogg", 100)
target.emote("scream")
target.apply_damage(45, BURN, "head") // 45 fire damage and disfigurement because your face was just deep fried!
head.disfigure()
add_attack_logs(user, target, "Deep-fried with [src]")
return TRUE
/// Make foam consisting of burning oil.
/obj/machinery/cooker/deepfryer/proc/make_foam(ice_amount)
@@ -44,18 +44,24 @@
E += M.rating
efficiency = round((E/2), 1) // There's 2 lasers, so halve the effect on the efficiency to keep it balanced
/obj/machinery/kitchen_machine/grill/special_attack(obj/item/grab/G, mob/user)
if(ishuman(G.affecting))
if(G.state < GRAB_AGGRESSIVE)
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
return 0
var/mob/living/carbon/human/C = G.affecting
C.visible_message("<span class='danger'>[user] forces [C] onto [src], searing [C]'s body!</span>", \
"<span class='userdanger'>[user] forces you onto [src]! It burns!</span>")
C.emote("scream")
user.changeNext_move(CLICK_CD_MELEE)
C.adjustFireLoss(30)
add_attack_logs(user, G.affecting, "Burned with [src]")
qdel(G) //Removes the grip to prevent rapid sears and give you a chance to run
return 0
return 0
/obj/machinery/kitchen_machine/grill/special_attack_shove(mob/user, mob/living/carbon/target)
target.visible_message(
"<span class='danger'>[user] shoves [target] onto [src], the active grill surface searing [user.p_them()]!</span>",
"<span class='userdanger'>[user] shoves you onto [src], and the hot surface sears you!</span>",
)
target.adjustFireLoss(15)
/obj/machinery/kitchen_machine/grill/special_attack(mob/user, mob/living/carbon/target, from_grab)
target.visible_message(
"<span class='danger'>[user] forces [target] onto [src]'s hot cooking surface, searing [target]'s body!</span>",
"<span class='userdanger'>[user] forces you onto [src]! HOT HOT HOT!</span>",
"<span class='warning'>You hear some meat being put on to cook.</span>"
)
target.emote("scream")
playsound(src, "sound/machines/kitchen/grill_mid.ogg", 100)
target.adjustFireLoss(30)
target.forceMove(get_turf(src))
target.Weaken(2 SECONDS)
add_attack_logs(user, target, "Burned with [src]")
return TRUE
@@ -25,6 +25,10 @@
///Sound used when starting and ending cooking
var/datum/looping_sound/kitchen/soundloop
var/soundloop_type
/// Time between special attacks
var/special_attack_cooldown_time = 7 SECONDS
/// Whether or not a special attack can be performed right now
var/special_attack_on_cooldown = FALSE
/*******************
* Initialising
@@ -111,8 +115,9 @@
if(!(R.id in GLOB.cooking_reagents[recipe_type]))
to_chat(user, "<span class='alert'>Your [O] contains components unsuitable for cookery.</span>")
return TRUE
else if(istype(O,/obj/item/grab))
return special_attack(O, user)
else if(istype(O, /obj/item/grab))
var/obj/item/grab/G = O
return special_attack_grab(G, user)
else
to_chat(user, "<span class='alert'>You have no idea what you can cook with [O].</span>")
return TRUE
@@ -141,8 +146,49 @@
/obj/machinery/kitchen_machine/attack_ai(mob/user)
return FALSE
/obj/machinery/kitchen_machine/proc/special_attack(obj/item/grab/G, mob/user)
to_chat(user, "<span class='alert'>This is ridiculous. You can not fit [G.affecting] in this [src].</span>")
/obj/machinery/kitchen_machine/proc/special_attack_grab(obj/item/grab/G, mob/user)
if(special_attack_on_cooldown)
return FALSE
if(!istype(G))
return FALSE
if(!iscarbon(G.affecting))
to_chat(user, "<span class='warning'>You can't shove that in there!</span>")
return FALSE
if(G.state < GRAB_AGGRESSIVE)
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
return FALSE
var/result = special_attack(user, G.affecting, TRUE)
user.changeNext_move(CLICK_CD_MELEE)
special_attack_on_cooldown = TRUE
addtimer(VARSET_CALLBACK(src, special_attack_on_cooldown, FALSE), special_attack_cooldown_time)
if(result && !isnull(G) && !QDELETED(G))
qdel(G)
return TRUE
/**
* Perform the special grab interaction.
* Return TRUE to drop the grab or FALSE to keep the grab afterwards.
*/
/obj/machinery/kitchen_machine/proc/special_attack(mob/user, mob/living/carbon/target, obj/item/grab/G)
to_chat(user, "<span class='alert'>This is ridiculous. You can not fit [target] in this [src].</span>")
return FALSE
/obj/machinery/kitchen_machine/shove_impact(mob/living/target, mob/living/attacker)
if(special_attack_on_cooldown)
return FALSE
if(!operating)
// only do a special interaction if it's actually cooking something
return FALSE
return special_attack_shove(target, attacker)
/**
* Perform a special shove attack.
* The return value of this proc gets passed up to shove_impact, so returning TRUE will prevent any further shove handling (like knockdown).
*/
/obj/machinery/kitchen_machine/proc/special_attack_shove(mob/living/target, mob/living/attacker)
return FALSE
/********************
@@ -44,24 +44,17 @@
E += M.rating
efficiency = round((E/2), 1) // There's 2 lasers, so halve the effect on the efficiency to keep it balanced
/obj/machinery/kitchen_machine/oven/special_attack(obj/item/grab/G, mob/user)
if(ishuman(G.affecting))
if(G.state < GRAB_AGGRESSIVE)
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
return 0
var/mob/living/carbon/human/C = G.affecting
var/obj/item/organ/external/head/head = C.get_organ("head")
if(!istype(head))
to_chat(user, "<span class='warning'>This person doesn't have a head!</span>")
return 0
C.visible_message("<span class='danger'>[user] bashes [C]'s head in [src]'s door!</span>", \
"<span class='userdanger'>[user] bashes your head in [src]'s door! It feels rather hot in the oven!</span>")
C.emote("scream")
user.changeNext_move(CLICK_CD_MELEE)
C.apply_damage(5, BURN, "head") //5 fire damage, 15 brute damage, and weakening because your head was just in a hot oven with the door bashing into your neck!
C.apply_damage(15, BRUTE, "head")
C.Weaken(4 SECONDS)
add_attack_logs(user, G.affecting, "Smashed with [src]")
qdel(G) //Removes the grip to prevent rapid bashes. With the weaken, you PROBABLY can't run unless they are slow to grab you again...
return 0
return 0
/obj/machinery/kitchen_machine/oven/special_attack(mob/user, mob/living/target)
var/obj/item/organ/external/head/head = target.get_organ("head")
if(!istype(head))
to_chat(user, "<span class='warning'>This person doesn't have a head!</span>")
return FALSE
target.visible_message("<span class='danger'>[user] bashes [target]'s head in [src]'s door!</span>", \
"<span class='userdanger'>[user] bashes your head in [src]'s door! It feels rather hot in the oven!</span>")
target.apply_damage(25, BURN, "head") //5 fire damage, 15 brute damage, and weakening because your head was just in a hot oven with the door bashing into your neck!
target.apply_damage(25, BRUTE, "head")
target.Weaken(4 SECONDS) // With the weaken, you PROBABLY can't run unless they are slow to grab you again...
target.emote("scream")
playsound(src, "sound/machines/kitchen/oven_loop_end.ogg", 100)
add_attack_logs(user, target, "Smashed with [src]")
return TRUE