From 5ba6ab4f7b3b8821ff5e292c81b41c124c3d954d Mon Sep 17 00:00:00 2001 From: Molti <108117184+Moltijoe@users.noreply.github.com> Date: Fri, 31 May 2024 00:21:25 -0500 Subject: [PATCH] Renames lava component and fixes a couple bugs (#22116) * fuck it * Update lingering.dm * Update lingering.dm * Update lingering.dm * callback instead of subtype * alexkar stuff * Update lingering.dm --- code/datums/helper_datums/teleport.dm | 2 +- code/game/turfs/open/lava.dm | 57 +++- .../awaymissions/mission_code/snowdin.dm | 71 ++++- .../hostile/megafauna/swarmer.dm | 2 +- code/modules/swarmers/swarmer_act.dm | 2 +- yogstation.dme | 2 +- yogstation/code/datums/components/lava.dm | 253 ------------------ .../code/datums/components/lingering.dm | 108 ++++++++ .../code/modules/jungleland/jungle_turfs.dm | 44 ++- 9 files changed, 279 insertions(+), 262 deletions(-) delete mode 100644 yogstation/code/datums/components/lava.dm create mode 100644 yogstation/code/datums/components/lingering.dm diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 5e021c983bbe..4cb26017ece6 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -173,7 +173,7 @@ continue if(extended_safety_checks) - var/datum/component/lava/safety_check = F.GetComponent(/datum/component/lava) + var/datum/component/lingering/safety_check = F.GetComponent(/datum/component/lingering) if(safety_check && !safety_check.is_safe()) //chasms aren't /floor, and so are pre-filtered continue diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 060729c30579..b85a10e056fa 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -1,5 +1,8 @@ ///LAVA +/// list of typepaths that if they're on the same tile as lava will prevent the damage +GLOBAL_LIST_INIT(lavasafeties, typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))) + /turf/open/lava name = "lava" icon_state = "lava" @@ -34,7 +37,59 @@ if(!smoothing_flags) update_appearance() AddComponent(/datum/component/fishable/lava) - AddComponent(/datum/component/lava) + AddComponent(/datum/component/lingering, CALLBACK(src, PROC_REF(burn_stuff)), GLOB.lavasafeties) + +/turf/open/lava/proc/burn_stuff(thing, delta_time) + if(isobj(thing)) + var/obj/O = thing + if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing) + return + . = TRUE + if((O.resistance_flags & (ON_FIRE))) + return + if(!(O.resistance_flags & FLAMMABLE)) + O.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava + if(O.resistance_flags & FIRE_PROOF) + O.resistance_flags &= ~FIRE_PROOF + if(O.armor.fire > 50) //obj with 100% fire armor still get slowly burned away. + O.armor = O.armor.setRating(fire = 50) + O.fire_act(10000, 1000 * delta_time) + + else if (isliving(thing)) + . = TRUE + var/mob/living/L = thing + if(L.movement_type & FLYING) + return //YOU'RE FLYING OVER IT + var/buckle_check = L.buckling + if(!buckle_check) + buckle_check = L.buckled + if(isobj(buckle_check)) + var/obj/O = buckle_check + if(O.resistance_flags & LAVA_PROOF) + return + else if(isliving(buckle_check)) + var/mob/living/live = buckle_check + if("lava" in live.weather_immunities) + return + + if(!L.on_fire) + L.update_fire() + + if(iscarbon(L)) + var/mob/living/carbon/C = L + var/obj/item/clothing/S = C.get_item_by_slot(ITEM_SLOT_OCLOTHING) + var/obj/item/clothing/H = C.get_item_by_slot(ITEM_SLOT_HEAD) + + if(S && H && S.clothing_flags & LAVAPROTECT && H.clothing_flags & LAVAPROTECT) + return + + if("lava" in L.weather_immunities) + return + + L.adjustFireLoss(20 * delta_time) + if(L) //mobs turning into object corpses could get deleted here. + L.adjust_fire_stacks(20 * delta_time) + L.ignite_mob() /turf/open/lava/update_overlays() . = ..() diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index b8fc23869664..f5cebb981033 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -174,9 +174,74 @@ light_color = LIGHT_COLOR_PURPLE lava_temperature = 73 // cold, not hot -/turf/open/lava/plasma/Initialize(mapload) - . = ..() - AddComponent(/datum/component/lava/plasma) //overwrites the regular lava component +/turf/open/lava/plasma/burn_stuff(thing, delta_time) + if (isliving(thing)) //objects are unaffected for now + . = TRUE + var/mob/living/L = thing + if(L.movement_type & FLYING) + return //YOU'RE FLYING OVER IT + if(WEATHER_SNOW in L.weather_immunities) + return + + var/buckle_check = L.buckling + if(!buckle_check) + buckle_check = L.buckled + if(isobj(buckle_check)) + var/obj/O = buckle_check + if(O.resistance_flags & FREEZE_PROOF) + return + + else if(isliving(buckle_check)) + var/mob/living/live = buckle_check + if(WEATHER_SNOW in live.weather_immunities) + return + + L.adjustFireLoss(2) + if(L) + L.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual + L.adjust_bodytemperature(-rand(50,65)) //its cold, man + if(ishuman(L))//are they a carbon? + var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs + var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman + var/mob/living/carbon/human/PP = L + var/datum/species/S = PP.dna.species + if(istype(S, /datum/species/plasmaman) || (S.inherent_biotypes & MOB_ROBOTIC)) //ignore plasmamen/robotic species + return + + for(var/BP in PP.bodyparts) + var/obj/item/bodypart/NN = BP + if(NN.status == BODYPART_ROBOTIC) + robo_parts += NN + if(NN.body_zone == BODY_ZONE_HEAD) //don't add the head to the list, just transform them into an plasmaman when it's the only thing left + continue + if(NN.status == BODYPART_ORGANIC && !(NN.species_id == "plasmaman" || NN.species_id == "husk")) //getting every organic, non-plasmaman limb (augments/androids are immune to this) + plasma_parts += NN + + if(prob(35)) //checking if the delay is over & if the victim actually has any parts to nom + PP.adjustToxLoss(15) + PP.adjustFireLoss(25) + if(length(plasma_parts)) + playsound(PP, 'sound/effects/wounds/sizzle2.ogg', 80, TRUE) + var/obj/item/bodypart/NB = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs to replace + if(PP.stat != DEAD) + PP.emote("scream") + PP.visible_message(span_warning("[L] screams in pain as [L.p_their()] [NB] melts down to the bone!"), span_userdanger("You scream out in pain as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")) + else + PP.visible_message(span_warning("[L]'s [NB] melts down to the bone!")) + var/obj/item/bodypart/replacement_part = new NB.type + replacement_part.species_id = "plasmaman" + replacement_part.original_owner = "plasma river" + replacement_part.replace_limb(PP) + qdel(NB) + else if(!length(robo_parts)) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman + playsound(PP, 'sound/effects/wounds/sizzle2.ogg', 80, TRUE) + PP.ignite_mob() + PP.cure_husk(BURN) //cure the probable husk first + PP.set_species(/datum/species/plasmaman) + PP.regenerate_icons() + PP.visible_message(span_warning("[L] bursts into a brilliant purple flame as [L.p_their()] entire body is that of a skeleton!"), \ + span_userdanger("Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!")) + /turf/open/lava/plasma/attackby(obj/item/I, mob/user, params) var/obj/item/reagent_containers/glass/C = I diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm index 5fbda065103f..070e0468aa70 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm @@ -141,7 +141,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa /mob/living/simple_animal/hostile/swarmer/ai/Move(atom/newloc) if(newloc) if(newloc.z == z) //so these actions are Z-specific - var/datum/component/lava/safety_check = newloc.GetComponent(/datum/component/lava) + var/datum/component/lingering/safety_check = newloc.GetComponent(/datum/component/lingering) if(safety_check && !safety_check.is_safe()) StartAction(20) new /obj/structure/lattice/catwalk/swarmer_catwalk(newloc) diff --git a/code/modules/swarmers/swarmer_act.dm b/code/modules/swarmers/swarmer_act.dm index 61ccaa00ca56..d2635ab8fea1 100644 --- a/code/modules/swarmers/swarmer_act.dm +++ b/code/modules/swarmers/swarmer_act.dm @@ -64,7 +64,7 @@ return FALSE /turf/open/lava/swarmer_act() - var/datum/component/lava/safety_check = src.GetComponent(/datum/component/lava) + var/datum/component/lingering/safety_check = src.GetComponent(/datum/component/lingering) if(safety_check && !safety_check.is_safe()) //chasms aren't /floor, and so are pre-filtered new /obj/structure/lattice/catwalk/swarmer_catwalk(src) return FALSE diff --git a/yogstation.dme b/yogstation.dme index cb155555aa05..06c879dc9720 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -4029,7 +4029,7 @@ #include "yogstation\code\datums\components\crawl.dm" #include "yogstation\code\datums\components\fishable.dm" #include "yogstation\code\datums\components\fishingbonus.dm" -#include "yogstation\code\datums\components\lava.dm" +#include "yogstation\code\datums\components\lingering.dm" #include "yogstation\code\datums\components\pinnable_accessory.dm" #include "yogstation\code\datums\components\radioactive.dm" #include "yogstation\code\datums\components\randomcrits.dm" diff --git a/yogstation/code/datums/components/lava.dm b/yogstation/code/datums/components/lava.dm deleted file mode 100644 index 6644b19fd0ef..000000000000 --- a/yogstation/code/datums/components/lava.dm +++ /dev/null @@ -1,253 +0,0 @@ -/datum/component/lava - var/turf/open/tile - dupe_type = /datum/component/lava //overwrite other types of lava - -/datum/component/lava/Initialize() - if(!istype(parent, /turf)) - return COMPONENT_INCOMPATIBLE - tile = parent - -/datum/component/lava/RegisterWithParent() - . = ..() - RegisterSignal(parent, COMSIG_ATOM_HITBY, PROC_REF(hitby)) - RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(Entered)) - RegisterSignal(parent, COMSIG_ATOM_EXITED, PROC_REF(Exited)) - tile = parent - -/datum/component/lava/UnregisterFromParent() - . = ..() - UnregisterSignal(parent, COMSIG_ATOM_HITBY, PROC_REF(hitby)) - UnregisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(Entered)) - UnregisterSignal(parent, COMSIG_ATOM_EXITED, PROC_REF(Exited)) - STOP_PROCESSING(SSobj, src) - -//////////////////////////////////////////////////////////////////////////////////// -//---------------------------------Triggers---------------------------------------// -//////////////////////////////////////////////////////////////////////////////////// -/datum/component/lava/proc/hitby(datum/source, atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - if(damage_stuff(AM)) - START_PROCESSING(SSobj, src) - -/datum/component/lava/proc/Entered(datum/source, atom/movable/AM) - if(damage_stuff(AM)) - START_PROCESSING(SSobj, src) - -/datum/component/lava/proc/Exited(datum/source, atom/movable/Obj, atom/newloc) - if(isliving(Obj)) - var/mob/living/L = Obj - if(!islava(newloc) && !L.on_fire) - L.update_fire() - -/datum/component/lava/process(delta_time) - if(!damage_stuff(null, delta_time)) - STOP_PROCESSING(SSobj, src) - -//////////////////////////////////////////////////////////////////////////////////// -//---------------------------------safety check-----------------------------------// -//////////////////////////////////////////////////////////////////////////////////// -/datum/component/lava/proc/is_safe() - //if anything matching this typecache is found in the lava, we don't burn things - var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile)) - - var/list/found_safeties = typecache_filter_list(tile.contents, lava_safeties_typecache) - - for(var/obj/structure/stone_tile/S in found_safeties) - if(S.fallen) - LAZYREMOVE(found_safeties, S) - return LAZYLEN(found_safeties) - -/datum/component/lava/proc/damage_stuff(AM, delta_time = 1) - . = 0 - - if(is_safe()) - return FALSE - - var/thing_to_check = tile - if(!istype(thing_to_check, /turf)) - return - - if (AM) - thing_to_check = list(AM) - for(var/thing in thing_to_check) - if(apply_damage(thing, delta_time)) - . = 1 - -//////////////////////////////////////////////////////////////////////////////////// -//--------------------------------Do the effect-----------------------------------// -//////////////////////////////////////////////////////////////////////////////////// -/datum/component/lava/proc/apply_damage(thing, delta_time) //override this for subtypes - . = 0 - if(isobj(thing)) - var/obj/O = thing - if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing) - return - . = 1 - if((O.resistance_flags & (ON_FIRE))) - return - if(!(O.resistance_flags & FLAMMABLE)) - O.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava - if(O.resistance_flags & FIRE_PROOF) - O.resistance_flags &= ~FIRE_PROOF - if(O.armor.fire > 50) //obj with 100% fire armor still get slowly burned away. - O.armor = O.armor.setRating(fire = 50) - O.fire_act(10000, 1000 * delta_time) - - else if (isliving(thing)) - . = 1 - var/mob/living/L = thing - if(L.movement_type & FLYING) - return //YOU'RE FLYING OVER IT - var/buckle_check = L.buckling - if(!buckle_check) - buckle_check = L.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & LAVA_PROOF) - return - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if("lava" in live.weather_immunities) - return - - if(!L.on_fire) - L.update_fire() - - if(iscarbon(L)) - var/mob/living/carbon/C = L - var/obj/item/clothing/S = C.get_item_by_slot(ITEM_SLOT_OCLOTHING) - var/obj/item/clothing/H = C.get_item_by_slot(ITEM_SLOT_HEAD) - - if(S && H && S.clothing_flags & LAVAPROTECT && H.clothing_flags & LAVAPROTECT) - return - - if("lava" in L.weather_immunities) - return - - L.adjustFireLoss(20 * delta_time) - if(L) //mobs turning into object corpses could get deleted here. - L.adjust_fire_stacks(20 * delta_time) - L.ignite_mob() - -//////////////////////////////////////////////////////////////////////////////////// -//-------------------------------Toxic water lava---------------------------------// -//////////////////////////////////////////////////////////////////////////////////// -/datum/component/lava/toxic/apply_damage(thing, delta_time) - . = 0 - if(isobj(thing)) //objects are unaffected for now - return - else if (isliving(thing)) - . = 1 - var/mob/living/L = thing - if(L.movement_type & (FLYING|FLOATING)) - return //YOU'RE FLYING OVER IT - if(HAS_TRAIT(L,TRAIT_SULPH_PIT_IMMUNE)) - return - var/buckle_check = L.buckling - if(!buckle_check) - buckle_check = L.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & ACID_PROOF) - return - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if(live.movement_type & (FLYING|FLOATING)) - return - if(HAS_TRAIT(live, TRAIT_SULPH_PIT_IMMUNE)) - return - - if(ishuman(L)) - var/mob/living/carbon/human/humie = L - var/chance = (100 - humie.getarmor(null,BIO)) * 0.33 - - if(isipc(humie) && prob(chance)) - humie.adjustFireLoss(15) - to_chat(humie,span_danger("the sulphuric solution burns and singes into your plating!")) - return - - if(prob((chance * 0.5) + 10)) - humie.acid_act(15,15) - - if(HAS_TRAIT(L,TRAIT_TOXIMMUNE) || HAS_TRAIT(L,TRAIT_TOXINLOVER)) - return - - humie.reagents.add_reagent(/datum/reagent/toxic_metabolities, 2) - - else if(prob(25)) - L.acid_act(5,7.5) - -//////////////////////////////////////////////////////////////////////////////////// -//----------------------------Plasma river lava-----------------------------------// -//////////////////////////////////////////////////////////////////////////////////// -/datum/component/lava/plasma/apply_damage(thing, delta_time) - . = 0 - if(isobj(thing)) - var/obj/O = thing - if((O.resistance_flags & (FREEZE_PROOF)) || O.throwing) - return - - else if (isliving(thing)) - . = 1 - var/mob/living/L = thing - if(L.movement_type & FLYING) - return //YOU'RE FLYING OVER IT - if(WEATHER_SNOW in L.weather_immunities) - return - - var/buckle_check = L.buckling - if(!buckle_check) - buckle_check = L.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & FREEZE_PROOF) - return - - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if(WEATHER_SNOW in live.weather_immunities) - return - - L.adjustFireLoss(2) - if(L) - L.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual - L.adjust_bodytemperature(-rand(50,65)) //its cold, man - if(ishuman(L))//are they a carbon? - var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs - var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman - var/mob/living/carbon/human/PP = L - var/datum/species/S = PP.dna.species - if(istype(S, /datum/species/plasmaman) || (S.inherent_biotypes & MOB_ROBOTIC)) //ignore plasmamen/robotic species - return - - for(var/BP in PP.bodyparts) - var/obj/item/bodypart/NN = BP - if(NN.status == BODYPART_ROBOTIC) - robo_parts += NN - if(NN.body_zone == BODY_ZONE_HEAD) //don't add the head to the list, just transform them into an plasmaman when it's the only thing left - return - if(NN.status == BODYPART_ORGANIC && !(NN.species_id == "plasmaman" || NN.species_id == "husk")) //getting every organic, non-plasmaman limb (augments/androids are immune to this) - plasma_parts += NN - - if(prob(35)) //checking if the delay is over & if the victim actually has any parts to nom - PP.adjustToxLoss(15) - PP.adjustFireLoss(25) - if(length(plasma_parts)) - var/obj/item/bodypart/NB = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs to replace - playsound(PP, 'sound/effects/wounds/sizzle2.ogg', 80, TRUE) - if(PP.stat != DEAD) - PP.emote("scream") - PP.visible_message(span_warning("[L] screams in pain as [L.p_their()] [NB] melts down to the bone!"), span_userdanger("You scream out in pain as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")) - else - PP.visible_message(span_warning("[L]'s [NB] melts down to the bone!")) - var/obj/item/bodypart/replacement_part = new NB.type - replacement_part.species_id = "plasmaman" - replacement_part.original_owner = "plasma river" - replacement_part.replace_limb(PP) - qdel(NB) - else if(!length(robo_parts)) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman - PP.ignite_mob() - PP.cure_husk(BURN) //cure the probable husk first - PP.set_species(/datum/species/plasmaman) - PP.regenerate_icons() - PP.visible_message(span_warning("[L] bursts into a brilliant purple flame as [L.p_their()] entire body is that of a skeleton!"), \ - span_userdanger("Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!")) diff --git a/yogstation/code/datums/components/lingering.dm b/yogstation/code/datums/components/lingering.dm new file mode 100644 index 000000000000..624ee40228c3 --- /dev/null +++ b/yogstation/code/datums/components/lingering.dm @@ -0,0 +1,108 @@ +/datum/component/lingering + dupe_mode = COMPONENT_DUPE_ALLOWED + /// A callback on the parent to be called when it tries to apply an affect on an atom + var/datum/callback/affect_callback + /// A list of things that if even one is on the tile, will prevent the effect + var/list/safeties_typecache + +/** + * Lingering component + * + * essentially caltrops, but it keeps triggering every SSobj tick + * + * vars: + * * affect_callback (required) A callback that triggers a proc that returns true or false, false will stop the processing of the component + * * safeties_typecache (optional) A list of typepaths that if they're on the same tile will prevent the effect + */ +/datum/component/lingering/Initialize(datum/callback/affect_callback, list/safeties_typecache) + if(!istype(parent, /turf)) + return COMPONENT_INCOMPATIBLE + if(!affect_callback) + stack_trace("Lingering component has been applied to a turf without an affect callback proc") + return COMPONENT_INCOMPATIBLE + src.affect_callback = affect_callback + src.safeties_typecache = safeties_typecache + +/datum/component/lingering/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_ATOM_HITBY, PROC_REF(hitby)) + RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(Entered)) + +/datum/component/lingering/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_ATOM_HITBY) + UnregisterSignal(parent, COMSIG_ATOM_ENTERED) + STOP_PROCESSING(SSobj, src) + . = ..() + +//////////////////////////////////////////////////////////////////////////////////// +//---------------------------------Triggers---------------------------------------// +//////////////////////////////////////////////////////////////////////////////////// +/datum/component/lingering/proc/hitby(datum/source, atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + if(affect_target(AM)) + START_PROCESSING(SSobj, src) + +/datum/component/lingering/proc/Entered(datum/source, atom/movable/AM) + if(affect_target(AM)) + START_PROCESSING(SSobj, src) + +/datum/component/lingering/process(delta_time) + if(!affect_stuff(delta_time)) + STOP_PROCESSING(SSobj, src) + +//////////////////////////////////////////////////////////////////////////////////// +//---------------------------------safety check-----------------------------------// +//////////////////////////////////////////////////////////////////////////////////// +/datum/component/lingering/proc/is_safe() + if(!safeties_typecache) + return FALSE + + var/turf/open/place = get_turf(parent) + + var/list/found_safeties = typecache_filter_list(place.contents, safeties_typecache) + + for(var/obj/structure/stone_tile/S in found_safeties) //snowflake check because stone tiles work weirdly, not ideal + if(S.fallen) + LAZYREMOVE(found_safeties, S) + + return LAZYLEN(found_safeties) + +//////////////////////////////////////////////////////////////////////////////////// +//-----------------------------single tick upon enter-----------------------------// +//////////////////////////////////////////////////////////////////////////////////// +/datum/component/lingering/proc/affect_target(AM) + . = FALSE + + if(!affect_callback) + stack_trace("Lingering component has been applied to a turf without an affect callback proc") //covering my bases + return + + if(is_safe()) //we don't want to damage the target, but we want to start processing just in case + return TRUE + + if(AM) //if it's a specific object, apply to that one + return affect_callback.Invoke(AM, 1) + +//////////////////////////////////////////////////////////////////////////////////// +//--------------------------Tick everything inside on process---------------------// +//////////////////////////////////////////////////////////////////////////////////// +/datum/component/lingering/proc/affect_stuff(delta_time = 1) + . = FALSE + + if(!affect_callback) + stack_trace("Lingering component has been applied to a turf without an affect callback proc") //covering my bases + return + + var/turf/open/place = get_turf(parent) //otherwise, apply to every object on the turf + + if(!place) + return + + var/safe = is_safe() //we call this here so it doesn't need to be called multiple times if it returns false + + for(var/thing in place.contents) + if(safe) //we don't want to damage anything, but if there's something here, make sure to keep processing just in case it stops being safe + return TRUE + if(thing == parent) + continue + if(affect_callback.Invoke(thing, delta_time)) + . = TRUE diff --git a/yogstation/code/modules/jungleland/jungle_turfs.dm b/yogstation/code/modules/jungleland/jungle_turfs.dm index e2441e54ee80..e1a76e78172b 100644 --- a/yogstation/code/modules/jungleland/jungle_turfs.dm +++ b/yogstation/code/modules/jungleland/jungle_turfs.dm @@ -197,7 +197,49 @@ Temperature: 126.85 °C (400 K) /turf/open/water/toxic_pit/Initialize(mapload) . = ..() - AddComponent(/datum/component/lava/toxic) + AddComponent(/datum/component/lingering, CALLBACK(src, PROC_REF(toxic_stuff)), GLOB.lavasafeties) + +/turf/open/water/toxic_pit/proc/toxic_stuff(thing, delta_time) + if (isliving(thing)) //objects are unaffected for now + . = TRUE + var/mob/living/L = thing + if(L.movement_type & (FLYING|FLOATING)) + return //YOU'RE FLYING OVER IT + if(HAS_TRAIT(L,TRAIT_SULPH_PIT_IMMUNE)) + return + var/buckle_check = L.buckling + if(!buckle_check) + buckle_check = L.buckled + if(isobj(buckle_check)) + var/obj/O = buckle_check + if(O.resistance_flags & ACID_PROOF) + return + else if(isliving(buckle_check)) + var/mob/living/live = buckle_check + if(live.movement_type & (FLYING|FLOATING)) + return + if(HAS_TRAIT(live, TRAIT_SULPH_PIT_IMMUNE)) + return + + if(ishuman(L)) + var/mob/living/carbon/human/humie = L + var/chance = (100 - humie.getarmor(null,BIO)) * 0.33 + + if(isipc(humie) && prob(chance)) + humie.adjustFireLoss(15) + to_chat(humie,span_danger("the sulphuric solution burns and singes into your plating!")) + return + + if(prob((chance * 0.5) + 10)) + humie.acid_act(15,15) + + if(HAS_TRAIT(L,TRAIT_TOXIMMUNE) || HAS_TRAIT(L,TRAIT_TOXINLOVER)) + return + + humie.reagents.add_reagent(/datum/reagent/toxic_metabolities, 2) + + else if(prob(25)) + L.acid_act(5,7.5) /turf/open/water/toxic_pit/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.construction_mode)