mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-21 11:07:12 +01:00
The Great Fire Extinguisher Refactor (#28005)
* Creation (suffering), success * AGHHHH! SPACES! * Update watertank.dm * comment update * Apply suggestions from code review Co-authored-by: Charlie Nolan <funnyman3595@gmail.com> Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com> --------- Signed-off-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com> Co-authored-by: Charlie Nolan <funnyman3595@gmail.com>
This commit is contained in:
@@ -17,12 +17,16 @@
|
||||
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
resistance_flags = FIRE_PROOF
|
||||
new_attack_chain = TRUE
|
||||
var/max_water = 50
|
||||
var/safety = TRUE
|
||||
var/refilling = FALSE
|
||||
/// FALSE by default, turfs picked from a spray are random, set to TRUE to make it always have at least one water effect per row
|
||||
/// If `TRUE`, using in hand will toggle the extinguisher's safety. This must be set to `FALSE` for extinguishers with different firing modes (i.e. backpacks).
|
||||
var/has_safety = TRUE
|
||||
/// If `TRUE`, the extinguisher will not fire.
|
||||
var/safety_active = TRUE
|
||||
/// When `FALSE`, turfs picked from a spray are random. When `TRUE`, it always has at least one water effect per row.
|
||||
var/precision = FALSE
|
||||
var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled
|
||||
/// Sets the `cooling_temperature` of the water reagent datum inside of the extinguisher when it is refilled.
|
||||
var/cooling_power = 2
|
||||
COOLDOWN_DECLARE(last_use)
|
||||
|
||||
/obj/item/extinguisher/mini
|
||||
@@ -31,8 +35,8 @@
|
||||
icon_state = "miniFE0"
|
||||
item_state = "miniFE"
|
||||
base_icon_state = "miniFE"
|
||||
hitsound = null //it is much lighter, after all.
|
||||
flags = null //doesn't CONDUCT
|
||||
hitsound = null // It is much lighter, after all.
|
||||
flags = null // Non-conductive, not made of metal.
|
||||
throwforce = 2
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = 3
|
||||
@@ -42,8 +46,8 @@
|
||||
|
||||
/obj/item/extinguisher/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>The safety is [safety ? "on" : "off"].</span>"
|
||||
|
||||
if(has_safety)
|
||||
. += "<span class='notice'>The safety is [safety_active ? "on" : "off"].</span>"
|
||||
|
||||
/obj/item/extinguisher/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -52,72 +56,81 @@
|
||||
reagents.add_reagent("water", max_water)
|
||||
ADD_TRAIT(src, TRAIT_CAN_POINT_WITH, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/extinguisher/attack_self__legacy__attackchain(mob/user as mob)
|
||||
safety = !safety
|
||||
icon_state = "[base_icon_state][!safety]"
|
||||
to_chat(user, "<span class='notice'>You [safety ? "enable" : "disable"] [src]'s safety.</span>")
|
||||
/obj/item/extinguisher/activate_self(mob/user)
|
||||
if(..())
|
||||
return
|
||||
|
||||
/obj/item/extinguisher/attack_obj__legacy__attackchain(obj/O, mob/living/user, params)
|
||||
if(AttemptRefill(O, user))
|
||||
refilling = TRUE
|
||||
return FALSE
|
||||
else
|
||||
return ..()
|
||||
// Backpack extinguishers have no safety mechanism.
|
||||
if(!has_safety)
|
||||
return
|
||||
|
||||
/obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user)
|
||||
safety_active = !safety_active
|
||||
icon_state = "[base_icon_state][!safety_active]"
|
||||
to_chat(user, "<span class='notice'>You [safety_active ? "enable" : "disable"] [src]'s safety.</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/item/extinguisher/interact_with_atom(atom/target, mob/living/user, list/modifiers)
|
||||
. = ..()
|
||||
if(attempt_refill(target, user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(extinguisher_spray(target, user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/item/extinguisher/ranged_interact_with_atom(atom/target, mob/living/user, list/modifiers)
|
||||
if(extinguisher_spray(target, user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/item/extinguisher/proc/attempt_refill(atom/target, mob/user)
|
||||
if(!istype(target, /obj/structure/reagent_dispensers/watertank) || !target.Adjacent(user))
|
||||
return FALSE
|
||||
var/old_safety = safety
|
||||
safety = TRUE
|
||||
|
||||
if(reagents.total_volume == reagents.maximum_volume)
|
||||
to_chat(user, "<span class='notice'>\The [src] is already full!</span>")
|
||||
safety = old_safety
|
||||
to_chat(user, "<span class='notice'>[src] is already full.</span>")
|
||||
return TRUE
|
||||
|
||||
var/obj/structure/reagent_dispensers/watertank/W = target
|
||||
var/transferred = W.reagents.trans_to(src, max_water)
|
||||
if(transferred > 0)
|
||||
to_chat(user, "<span class='notice'>\The [src] has been refilled by [transferred] units.</span>")
|
||||
playsound(loc, 'sound/effects/refill.ogg', 50, TRUE, -6)
|
||||
for(var/datum/reagent/water/R in reagents.reagent_list)
|
||||
R.cooling_temperature = cooling_power
|
||||
else
|
||||
if(!transferred)
|
||||
to_chat(user, "<span class='notice'>\The [W] is empty!</span>")
|
||||
safety = old_safety
|
||||
return TRUE
|
||||
|
||||
to_chat(user, "<span class='notice'>[src] has been refilled with [transferred] units.</span>")
|
||||
playsound(loc, 'sound/effects/refill.ogg', 50, TRUE, -6)
|
||||
for(var/datum/reagent/water/R in reagents.reagent_list)
|
||||
R.cooling_temperature = cooling_power
|
||||
return TRUE
|
||||
|
||||
/obj/item/extinguisher/afterattack__legacy__attackchain(atom/target, mob/user, flag)
|
||||
. = ..()
|
||||
//TODO; Add support for reagents in water.
|
||||
if(target.loc == user)//No more spraying yourself when putting your extinguisher away
|
||||
return
|
||||
/obj/item/extinguisher/proc/extinguisher_spray(atom/A, mob/living/user)
|
||||
. = TRUE
|
||||
|
||||
if(refilling)
|
||||
refilling = FALSE
|
||||
return
|
||||
|
||||
if(safety)
|
||||
return ..()
|
||||
if(reagents.total_volume < 1)
|
||||
to_chat(user, "<span class='danger'>[src] is empty.</span>")
|
||||
return
|
||||
// Violence, please!
|
||||
if(safety_active)
|
||||
return FALSE
|
||||
|
||||
if(!COOLDOWN_FINISHED(src, last_use))
|
||||
return
|
||||
|
||||
COOLDOWN_START(src, last_use, 2 SECONDS)
|
||||
if(reagents.total_volume < 1)
|
||||
to_chat(user, "<span class='danger'>[src] is empty.</span>")
|
||||
return
|
||||
|
||||
if(A.loc == user)
|
||||
return
|
||||
|
||||
COOLDOWN_START(src, last_use, 2 SECONDS)
|
||||
if(reagents.chem_temp > 300 || reagents.chem_temp < 280)
|
||||
add_attack_logs(user, target, "Sprayed with superheated or cooled fire extinguisher at Temperature [reagents.chem_temp]K")
|
||||
add_attack_logs(user, A, "Sprayed with superheated or cooled fire extinguisher at Temperature [reagents.chem_temp]K")
|
||||
playsound(loc, 'sound/effects/extinguish.ogg', 75, TRUE, -3)
|
||||
|
||||
var/direction = get_dir(src, target)
|
||||
var/direction = get_dir(src, A)
|
||||
|
||||
if(isobj(user.buckled) && !user.buckled.anchored && !istype(user.buckled, /obj/vehicle))
|
||||
INVOKE_ASYNC(src, PROC_REF(buckled_speed_move), user.buckled, direction)
|
||||
else
|
||||
user.newtonian_move(turn(direction, 180))
|
||||
|
||||
var/turf/T = get_turf(target)
|
||||
var/turf/T = get_turf(A)
|
||||
var/turf/T1 = get_step(T, turn(direction, 90))
|
||||
var/turf/T2 = get_step(T, turn(direction, -90))
|
||||
var/list/the_targets = list(T, T1, T2)
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
return
|
||||
|
||||
/proc/check_tank_exists(parent_tank, mob/living/carbon/human/M, obj/O)
|
||||
if(!parent_tank || !istype(parent_tank, /obj/item/watertank)) //To avoid weird issues from admin spawns
|
||||
if(!parent_tank || (!istype(parent_tank, /obj/item/watertank) && !istype(parent_tank, /obj/item/mod/module/firefighting_tank))) //To avoid weird issues from admin spawns
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
@@ -218,11 +218,12 @@
|
||||
name = "extinguisher nozzle"
|
||||
desc = "A heavy duty nozzle attached to a firefighter's backpack tank."
|
||||
icon = 'icons/obj/watertank.dmi'
|
||||
icon_state = "atmos_nozzle"
|
||||
icon_state = "atmos_nozzle_1"
|
||||
item_state = "nozzleatmos"
|
||||
safety = 0
|
||||
has_safety = FALSE
|
||||
safety_active = FALSE
|
||||
max_water = 500
|
||||
precision = 1
|
||||
precision = TRUE
|
||||
cooling_power = 5
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
flags = NODROP //Necessary to ensure that the nozzle and tank never seperate
|
||||
@@ -230,10 +231,23 @@
|
||||
var/obj/item/watertank/tank
|
||||
/// What mode are we currently in?
|
||||
var/nozzle_mode = EXTINGUISHER
|
||||
/// Are we overusing the metal synthesizer? can be used 5 times in quick succession, regains 1 use per 10 seconds
|
||||
var/metal_synthesis_cooldown = 0
|
||||
/// Is our nanofrost on cooldown?
|
||||
var/nanofrost_cooldown = FALSE
|
||||
/// How many shots of metal foam do we have?
|
||||
var/metal_synthesis_charge = 5
|
||||
/// Time to refill 1 charge of metal foam.
|
||||
var/metal_regen_time = 2 SECONDS
|
||||
/// Refire delay for nanofrost chunks.
|
||||
var/nanofrost_cooldown_time = 2 SECONDS
|
||||
COOLDOWN_DECLARE(nanofrost_cooldown)
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/examine(mob/user)
|
||||
. = ..()
|
||||
switch(nozzle_mode)
|
||||
if(EXTINGUISHER)
|
||||
. += "<span class='notice'>[src] is currently set to extinguishing mode.</span>"
|
||||
if(NANOFROST)
|
||||
. += "<span class='notice'>[src] is currently set to nanofrost mode.</span>"
|
||||
if(METAL_FOAM)
|
||||
. += "<span class='notice'>[src] is currently set to metal foam mode.</span>"
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/Initialize(mapload)
|
||||
if(!check_tank_exists(loc, src))
|
||||
@@ -255,67 +269,88 @@
|
||||
if(tank && loc != tank.loc)
|
||||
forceMove(tank)
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/attack_self__legacy__attackchain(mob/user)
|
||||
/obj/item/extinguisher/mini/nozzle/activate_self(mob/user)
|
||||
..()
|
||||
switch(nozzle_mode)
|
||||
if(EXTINGUISHER)
|
||||
nozzle_mode = NANOFROST
|
||||
tank.icon_state = "waterbackpackatmos_1"
|
||||
to_chat(user, "Swapped to nanofrost launcher")
|
||||
if(NANOFROST)
|
||||
nozzle_mode = METAL_FOAM
|
||||
tank.icon_state = "waterbackpackatmos_2"
|
||||
to_chat(user, "Swapped to metal foam synthesizer")
|
||||
if(METAL_FOAM)
|
||||
nozzle_mode = EXTINGUISHER
|
||||
tank.icon_state = "waterbackpackatmos_0"
|
||||
to_chat(user, "Swapped to water extinguisher")
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/update_icon_state()
|
||||
switch(nozzle_mode)
|
||||
if(EXTINGUISHER)
|
||||
icon_state = "atmos_nozzle_1"
|
||||
tank.icon_state = "waterbackpackatmos_0"
|
||||
if(NANOFROST)
|
||||
icon_state = "atmos_nozzle_2"
|
||||
tank.icon_state = "waterbackpackatmos_1"
|
||||
if(METAL_FOAM)
|
||||
icon_state = "atmos_nozzle_3"
|
||||
tank.icon_state = "waterbackpackatmos_2"
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/dropped(mob/user)
|
||||
..()
|
||||
if(istype(tank, /obj/item/mod/module/firefighting_tank))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>The nozzle snaps back onto the tank!</span>")
|
||||
tank.on = FALSE
|
||||
loc = tank
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/afterattack__legacy__attackchain(atom/target, mob/user)
|
||||
/obj/item/extinguisher/mini/nozzle/extinguisher_spray(atom/A, mob/living/user)
|
||||
if(nozzle_mode == EXTINGUISHER)
|
||||
..()
|
||||
return
|
||||
var/Adj = user.Adjacent(target)
|
||||
if(Adj)
|
||||
AttemptRefill(target, user)
|
||||
return ..()
|
||||
|
||||
. = TRUE
|
||||
switch(nozzle_mode)
|
||||
if(NANOFROST)
|
||||
if(Adj)
|
||||
return //Safety check so you don't blast yourself trying to refill your tank
|
||||
if(reagents.total_volume < 100)
|
||||
to_chat(user, "<span class='notice'>You need at least 100 units of water to use the nanofrost launcher!</span>")
|
||||
to_chat(user, "<span class='warning'>You need at least 100 units of water to use the nanofrost launcher!</span>")
|
||||
return
|
||||
if(nanofrost_cooldown)
|
||||
to_chat(user, "<span class='notice'>Nanofrost launcher is still recharging.</span>")
|
||||
|
||||
if(COOLDOWN_TIMELEFT(src, nanofrost_cooldown))
|
||||
to_chat(user, "<span class='warning'>The nanofrost launcher is still recharging!</span>")
|
||||
return
|
||||
nanofrost_cooldown = TRUE
|
||||
|
||||
COOLDOWN_START(src, nanofrost_cooldown, nanofrost_cooldown_time)
|
||||
reagents.remove_any(100)
|
||||
var/obj/effect/nanofrost_container/A = new /obj/effect/nanofrost_container(get_turf(src))
|
||||
var/obj/effect/nanofrost_container/iceball = new /obj/effect/nanofrost_container(get_turf(src))
|
||||
log_game("[key_name(user)] used Nanofrost at [get_area(user)] ([user.x], [user.y], [user.z]).")
|
||||
playsound(src,'sound/items/syringeproj.ogg', 40, TRUE)
|
||||
A.throw_at(target, 6, 2, user)
|
||||
iceball.throw_at(A, 6, 2, user)
|
||||
sleep(2)
|
||||
A.Smoke()
|
||||
addtimer(VARSET_CALLBACK(src, nanofrost_cooldown, FALSE))
|
||||
if(METAL_FOAM)
|
||||
if(!Adj)
|
||||
return
|
||||
if(metal_synthesis_cooldown >= 5)
|
||||
to_chat(user, "<span class='notice'>Metal foam mix is still being synthesized.</span>")
|
||||
return
|
||||
var/obj/effect/particle_effect/foam/metal/F = new /obj/effect/particle_effect/foam/metal(get_turf(target), TRUE)
|
||||
F.spread_amount = 0
|
||||
metal_synthesis_cooldown++
|
||||
addtimer(CALLBACK(src, PROC_REF(metal_cooldown)), 10 SECONDS)
|
||||
iceball.Smoke()
|
||||
return
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/proc/metal_cooldown()
|
||||
metal_synthesis_cooldown--
|
||||
if(METAL_FOAM)
|
||||
if(!user.Adjacent(A) || !isturf(A))
|
||||
return
|
||||
|
||||
if(metal_synthesis_charge <= 0)
|
||||
to_chat(user, "<span class='warning'>Metal foam mix is still being synthesized!</span>")
|
||||
return
|
||||
|
||||
if(reagents.total_volume < 10)
|
||||
to_chat(user, "<span class='warning'>You need at least 10 units of water to use the metal foam synthesizer!</span>")
|
||||
return
|
||||
|
||||
var/obj/effect/particle_effect/foam/metal/foam = new /obj/effect/particle_effect/foam/metal(get_turf(A), TRUE)
|
||||
foam.spread_amount = 0
|
||||
reagents.remove_any(10)
|
||||
metal_synthesis_charge--
|
||||
addtimer(CALLBACK(src, PROC_REF(refill_metal_charge)), metal_regen_time)
|
||||
return
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/proc/refill_metal_charge()
|
||||
metal_synthesis_charge++
|
||||
|
||||
/obj/effect/nanofrost_container
|
||||
name = "nanofrost container"
|
||||
|
||||
Reference in New Issue
Block a user