diff --git a/code/datums/datum.dm b/code/datums/datum.dm index a4169004fc9..d170aeca852 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -419,6 +419,11 @@ filter_data = null atom_cast.filters = null +/// Calls qdel on itself, because signals dont allow callbacks +/datum/proc/selfdelete() + SIGNAL_HANDLER + qdel(src) + /// Return text from this proc to provide extra context to hard deletes that happen to it /// Optional, you should use this for cases where replication is difficult and extra context is required /// Can be called more then once per object, use harddel_deets_dumped to avoid duplicate calls (I am so sorry) diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm b/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm index 03bd6c224de..958fa51fcc1 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm @@ -115,16 +115,14 @@ // [Hazards & Traps] //cyborg holobarriers that die when the boss dies, how exciting +#define SELFDESTRUCT_QUEUE "hauntedtradingpost_sd" //make sure it matches the AI cores ID /obj/structure/holosign/barrier/cyborg/cybersun_ai_shield desc = "A fragile holographic energy field projected by an AI core. It keeps unwanted humanoids at safe distance." /obj/structure/holosign/barrier/cyborg/cybersun_ai_shield/Initialize(mapload) . = ..() - GLOB.selfdestructs_when_boss_dies += src - -/obj/structure/holosign/barrier/cyborg/cybersun_ai_shield/Destroy() - GLOB.selfdestructs_when_boss_dies -= src - return ..() + if(mapload) //shouldnt queue when we arent even part of a ruin, probably admin shitspawned + SSqueuelinks.add_to_queue(src, SELFDESTRUCT_QUEUE) //smes that produces power, until the boss dies then it self destructs and you gotta make your own power /obj/machinery/power/smes/magical/cybersun @@ -136,12 +134,7 @@ /obj/machinery/power/smes/magical/cybersun/Initialize(mapload) . = ..() if(donk_ai_slave) - GLOB.selfdestructs_when_boss_dies += src - -/obj/machinery/power/smes/magical/cybersun/Destroy() - if(donk_ai_slave) - GLOB.selfdestructs_when_boss_dies -= src - return ..() + SSqueuelinks.add_to_queue(src, SELFDESTRUCT_QUEUE) //this is a trigger for traps involving doors and shutters //doors get closed and bolted, shutters get cycled open/closed @@ -165,19 +158,31 @@ var/suicide_pact = FALSE //id of the suicide pact this tripwire is in var/suicide_pact_id -GLOBAL_LIST_EMPTY(tripwire_suicide_pact) /obj/machinery/button/door/invisible_tripwire/Initialize(mapload) . = ..() - if(donk_ai_slave == TRUE) - GLOB.selfdestructs_when_boss_dies += src - if(suicide_pact == TRUE && suicide_pact_id != null) - GLOB.tripwire_suicide_pact += src + if(donk_ai_slave) + SSqueuelinks.add_to_queue(src, SELFDESTRUCT_QUEUE) + if(suicide_pact && suicide_pact_id != null) + SSqueuelinks.add_to_queue(src, suicide_pact_id) + . = INITIALIZE_HINT_LATELOAD var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) AddElement(/datum/element/connect_loc, loc_connections) +/obj/machinery/button/door/invisible_tripwire/post_machine_initialize() + . = ..() + if(!suicide_pact || isnull(SSqueuelinks.queues[suicide_pact_id])) + return // we got beat to it + SSqueuelinks.pop_link(suicide_pact_id) + +/obj/machinery/button/door/invisible_tripwire/MatchedLinks(id, list/partners) + if(id != suicide_pact_id) + return + for(var/partner in partners) + RegisterSignal(partner, COMSIG_PUZZLE_COMPLETED, TYPE_PROC_REF(/datum, selfdelete)) + /obj/machinery/button/door/invisible_tripwire/proc/on_entered(atom/source, atom/movable/victim) SIGNAL_HANDLER if(!isliving(victim)) @@ -194,19 +199,9 @@ GLOBAL_LIST_EMPTY(tripwire_suicide_pact) INVOKE_ASYNC(src, TYPE_PROC_REF(/atom, interact), victim) if(multiuse && uses_remaining != 1) return - if(suicide_pact&& suicide_pact_id) - for (var/obj/machinery/button/door/invisible_tripwire/pact_member in GLOB.tripwire_suicide_pact) - if(src.suicide_pact_id == pact_member.suicide_pact_id) - qdel(pact_member) - qdel(src) - - -/obj/machinery/button/door/invisible_tripwire/Destroy() - if(donk_ai_slave) - GLOB.selfdestructs_when_boss_dies -= src if(suicide_pact && suicide_pact_id) - GLOB.tripwire_suicide_pact -= src - return ..() + SEND_SIGNAL(src, COMSIG_PUZZLE_COMPLETED) + qdel(src) //door button that destroys itself when it is pressed /obj/machinery/button/door/selfdestructs @@ -271,13 +266,8 @@ GLOBAL_LIST_EMPTY(tripwire_suicide_pact) proximity_monitor?.set_range(trigger_range) my_turf = get_turf(src) host_machine = locate(/obj/machinery) in loc - if(donk_ai_slave == TRUE) - GLOB.selfdestructs_when_boss_dies += src - -/obj/effect/overloader_trap/Destroy() - if(donk_ai_slave == TRUE) - GLOB.selfdestructs_when_boss_dies -= src - return ..() + if(donk_ai_slave) + SSqueuelinks.add_to_queue(src, SELFDESTRUCT_QUEUE) /obj/effect/overloader_trap/proc/check_faction(mob/target) for(var/faction1 in faction) @@ -381,3 +371,4 @@ GLOBAL_LIST_EMPTY(tripwire_suicide_pact) damage = 30 wound_bonus = -50 +#undef SELFDESTRUCT_QUEUE diff --git a/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm b/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm index e9b62f9deaf..7b27da8d977 100644 --- a/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm +++ b/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm @@ -31,8 +31,8 @@ var/datum/action/cooldown/mob_cooldown/targeted_mob_ability/donk_laser //is this being used as part of the haunted trading post ruin? if true, stuff there will self destruct when this mob dies var/donk_ai_master = FALSE -// list of stuff tagged to self destruct when this mob dies -GLOBAL_LIST_EMPTY(selfdestructs_when_boss_dies) + /// the queue id for the stuff that selfdestructs when we die + var/selfdestruct_queue_id = "hauntedtradingpost_sd" /mob/living/basic/cybersun_ai_core/Initialize(mapload) . = ..() @@ -45,21 +45,20 @@ GLOBAL_LIST_EMPTY(selfdestructs_when_boss_dies) BARRAGE_ABILITY_TYPEPATH = BB_CYBERSUN_CORE_BARRAGE, ) grant_actions_by_list(innate_actions) + if(mapload && donk_ai_master) + return INITIALIZE_HINT_LATELOAD + +/mob/living/basic/cybersun_ai_core/LateInitialize() + SSqueuelinks.add_to_queue(src, selfdestruct_queue_id) + SSqueuelinks.pop_link(selfdestruct_queue_id) + +/mob/living/basic/cybersun_ai_core/MatchedLinks(id, list/partners) // id == queue id (for multiple queue objects) + if(id != selfdestruct_queue_id) + return + for(var/datum/partner as anything in partners) // all our partners in the selfdestruct queue are now registered to qdel if I die + partner.RegisterSignal(src, COMSIG_QDELETING, TYPE_PROC_REF(/datum, selfdelete)) /mob/living/basic/cybersun_ai_core/death(gibbed) - if(donk_ai_master == TRUE) - //disable all the tripwire traps - for (var/obj/item/pressure_plate/puzzle/invisible_tripwire as anything in GLOB.selfdestructs_when_boss_dies) - qdel(invisible_tripwire) - //and the electric overload traps - for (var/obj/effect/overloader_trap as anything in GLOB.selfdestructs_when_boss_dies) - qdel(overloader_trap) - //then disable the AI defence holograms - for (var/obj/structure/holosign/barrier/cyborg/cybersun_ai_shield as anything in GLOB.selfdestructs_when_boss_dies) - qdel(cybersun_ai_shield) - //then the power generator - for (var/obj/machinery/power/smes/magical/cybersun as anything in GLOB.selfdestructs_when_boss_dies) - qdel(cybersun) do_sparks(number = 5, source = src) return ..()