diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 54ac77bb0a8c..7120bfb2f785 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -555,20 +555,20 @@ /mob/living/on_virtual_z_change(new_virtual_z, previous_virtual_z) . = ..() - if(!client) - return if(previous_virtual_z) LAZYREMOVEASSOC(SSmobs.players_by_virtual_z, "[previous_virtual_z]", src) + if(!client) + return if(new_virtual_z) LAZYADDASSOC(SSmobs.players_by_virtual_z, "[new_virtual_z]", src) SSidlenpcpool.try_wakeup_virtual_z(new_virtual_z) /mob/dead/on_virtual_z_change(new_virtual_z, previous_virtual_z) . = ..() - if(!client) - return if(previous_virtual_z) LAZYREMOVEASSOC(SSmobs.dead_players_by_virtual_z, "[previous_virtual_z]", src) + if(!client) + return if(new_virtual_z) LAZYADDASSOC(SSmobs.dead_players_by_virtual_z, "[new_virtual_z]", src) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 86456eced666..22b15f162b25 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -314,7 +314,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod/retro, 17) mob_occupant.mind.special_role = null // Delete them from datacore. - var/announce_rank = null for(var/datum/data/record/R in GLOB.data_core.medical) if((R.fields["name"] == mob_occupant.real_name)) @@ -327,10 +326,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod/retro, 17) announce_rank = G.fields["rank"] qdel(G) - // Regardless of what ship you spawned in you need to be removed from it. - // This covers scenarios where you spawn in one ship but cryo in another. - for(var/datum/overmap/ship/controlled/sim_ship as anything in SSovermap.controlled_ships) - sim_ship.manifest -= mob_occupant.real_name + var/datum/overmap/ship/controlled/original_ship = mob_occupant.mind.original_ship.resolve() + original_ship.manifest -= mob_occupant.real_name var/obj/machinery/computer/cryopod/control_computer_obj = control_computer?.resolve() @@ -353,6 +350,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod/retro, 17) continue//means we already moved whatever this thing was in //I'm a professional, okay //what the fuck are you on rn and can I have some + //who are you even talking to if(is_type_in_typecache(W, preserve_items_typecache)) if(control_computer_obj && control_computer_obj.allow_items) control_computer_obj.frozen_items += W @@ -378,9 +376,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod/retro, 17) else mob_occupant.ghostize(TRUE) handle_objectives() - QDEL_NULL(occupant) open_machine() - name = initial(name) + qdel(mob_occupant) + //Just in case open_machine didn't clear it + occupant = null /obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user) if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 7063207255f5..a5e66f6df4ef 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -35,7 +35,6 @@ // Here lies irrigation. You won't be missed, because you were never used. /obj/machinery/hydroponics/Initialize() - RegisterSignal(src, COMSIG_ATOM_EXITED, PROC_REF(on_exited)) //Here lies "nutrilevel", killed by ArcaneMusic 20??-2019. Finally, we strive for a better future. Please use "reagents" instead create_reagents(20) reagents.add_reagent(/datum/reagent/plantnutriment/eznutriment, 10) //Half filled nutrient trays for dirt trays to have more to grow with in prison/lavaland. @@ -74,15 +73,9 @@ /obj/machinery/hydroponics/Destroy() if(myseed) - qdel(myseed) - myseed = null + QDEL_NULL(myseed) return ..() -/obj/machinery/hydroponics/proc/on_exited() - SIGNAL_HANDLER - if(myseed && (myseed.loc != src)) - myseed.forceMove(src) - /obj/machinery/hydroponics/constructable/attackby(obj/item/I, mob/user, params) if (user.a_intent != INTENT_HARM) // handle opening the panel @@ -357,8 +350,7 @@ var/oldPlantName if(myseed) // In case there's nothing in the tray beforehand oldPlantName = myseed.plantname - qdel(myseed) - myseed = null + QDEL_NULL(myseed) else oldPlantName = "empty tray" switch(rand(0,20)) // randomly pick predominative weed @@ -429,8 +421,7 @@ /obj/machinery/hydroponics/proc/mutateweed() // If the weeds gets the mutagent instead. Mind you, this pretty much destroys the old plant if(weedlevel > 5) if(myseed) - qdel(myseed) - myseed = null + QDEL_NULL(myseed) var/newWeed = pick(/obj/item/seeds/liberty, /obj/item/seeds/angel, /obj/item/seeds/nettle/death, /obj/item/seeds/kudzu) myseed = new newWeed dead = 0 @@ -608,8 +599,7 @@ plant_health = 0 if(harvest) harvest = FALSE //To make sure they can't just put in another seed and insta-harvest it - qdel(myseed) - myseed = null + QDEL_NULL(myseed) name = initial(name) desc = initial(desc) weedlevel = 0 //Has a side effect of cleaning up those nasty weeds @@ -664,8 +654,7 @@ else if(dead) dead = FALSE to_chat(user, "You remove the dead plant from [src].") - qdel(myseed) - myseed = null + QDEL_NULL(myseed) update_appearance() TRAY_NAME_UPDATE else diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index c09a3c8bd4c8..5a1e5bbf3387 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -96,7 +96,11 @@ INITIALIZE_IMMEDIATE(/mob/dead) return /mob/dead/Destroy() - LAZYREMOVEASSOC(SSmobs.dead_players_by_virtual_z, "[virtual_z()]", src) + for(var/level in SSmobs.dead_players_by_virtual_z) + LAZYREMOVEASSOC(SSmobs.dead_players_by_virtual_z, level, src) + // Forgive me for this one. This loop can be replaced by the line below by the one brave enough to fix + // observers not cleanly removing themselves from the dead_players_by_virtual_z /list when they should + //LAZYREMOVEASSOC(SSmobs.dead_players_by_virtual_z, "[virtual_z()]", src) return ..() /mob/dead/Login() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 821bef7d25ff..5983d8100112 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -52,6 +52,7 @@ S.removeSoulsharer(src) //If a sharer is destroy()'d, they are simply removed sharedSoullinks = null + QDEL_LIST(surgeries) QDEL_LIST(abilities) // so that the actions are deleted, which will clear refs to owner QDEL_LIST(roundstart_quirks) return ..() diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm index e0b5c0608b9d..aafa14ea8824 100644 --- a/code/modules/projectiles/ammunition/_ammunition.dm +++ b/code/modules/projectiles/ammunition/_ammunition.dm @@ -100,16 +100,24 @@ bounce_away(FALSE, NONE) . = ..() +/obj/item/ammo_casing/proc/on_eject() + forceMove(drop_location()) //Eject casing onto ground. + bounce_away(TRUE) + /obj/item/ammo_casing/proc/bounce_away(still_warm = FALSE, bounce_delay = 3) if(!heavy_metal) return update_appearance() SpinAnimation(10, 1) - var/turf/T = get_turf(src) + var/turf/location = get_turf(src) if(bounce_sfx_override) addtimer(CALLBACK(GLOBAL_PROC, PROC_REF(playsound), src, pick(bounce_sfx_override), 20, 1), bounce_delay) //Soft / non-solid turfs that shouldn't make a sound when a shell casing is ejected over them. return - if(still_warm && T && T.bullet_sizzle) + if(!location) + return + + if(still_warm && location.bullet_sizzle) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), src, 'sound/items/welder.ogg', 20, 1), bounce_delay) //If the turf is made of water and the shell casing is still hot, make a sizzling sound when it's ejected. - else if(T && T.bullet_bounce_sound) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), src, pick(T.bullet_bounce_sound), 20, 1), bounce_delay) //Soft / non-solid turfs that shouldn't make a sound when a shell casing is ejected over them. + + else if(location.bullet_bounce_sound) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), src, pick(location.bullet_bounce_sound), 20, 1), bounce_delay) //Soft / non-solid turfs that shouldn't make a sound when a shell casing is ejected over them. diff --git a/code/modules/projectiles/ammunition/caseless/_caseless.dm b/code/modules/projectiles/ammunition/caseless/_caseless.dm index c675e2317586..2fe0ecf808eb 100644 --- a/code/modules/projectiles/ammunition/caseless/_caseless.dm +++ b/code/modules/projectiles/ammunition/caseless/_caseless.dm @@ -3,13 +3,8 @@ firing_effect_type = null heavy_metal = FALSE -/obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from) - if (..()) //successfully firing - moveToNullspace() - QDEL_NULL(src) - return TRUE - else - return FALSE +/obj/item/ammo_casing/caseless/on_eject() + qdel(src) // Overridden; caseless ammo does not distinguish between "live" and "empty"/"spent" icon states (because it has no casing). /obj/item/ammo_casing/caseless/update_icon_state() diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index b640390ebfe4..be6811bda2e9 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -148,11 +148,10 @@ /obj/item/gun/ballistic/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE) if(!semi_auto && from_firing) return - var/obj/item/ammo_casing/AC = chambered //Find chambered round - if(istype(AC)) //there's a chambered round + var/obj/item/ammo_casing/casing = chambered //Find chambered round + if(istype(casing)) //there's a chambered round if(casing_ejector || !from_firing) - AC.forceMove(drop_location()) //Eject casing onto ground. - AC.bounce_away(TRUE) + casing.on_eject() chambered = null else if(empty_chamber) chambered = null @@ -268,7 +267,7 @@ if (istype(A, /obj/item/ammo_casing) || istype(A, /obj/item/ammo_box)) if (bolt_type == BOLT_TYPE_NO_BOLT || internal_magazine) if (chambered && !chambered.BB) - chambered.forceMove(drop_location()) + chambered.on_eject() chambered = null var/num_loaded = magazine.attackby(A, user, params, TRUE) if (num_loaded) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 4f98fe339c87..88323f0056a8 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -10,7 +10,7 @@ var/requires_bodypart_type = BODYTYPE_ORGANIC //Prevents you from performing an operation on incorrect limbs. 0 for any limb type var/list/possible_locs = list() //Multiple locations var/ignore_clothes = FALSE //This surgery ignores clothes - var/mob/living/carbon/target //Operation target mob + var/mob/living/target //Operation target mob var/obj/item/bodypart/operated_bodypart //Operable body part var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing. var/speed_modifier = 0 //Step speed modifier