From 5245920cba5781b409d2920bf5a8cf8848b20605 Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Mon, 5 Feb 2024 18:10:15 +0100 Subject: [PATCH 1/2] Remove extools from ref finder --- code/game/world.dm | 3 - code/modules/admin/admin_verbs.dm | 4 - .../view_variables/reference_tracking.dm | 104 ------------------ .../admin/view_variables/topic_basic.dm | 10 -- code/modules/mob/mob.dm | 8 +- 5 files changed, 4 insertions(+), 125 deletions(-) diff --git a/code/game/world.dm b/code/game/world.dm index c7537d0064..77ceef0589 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -14,9 +14,6 @@ GLOBAL_LIST(topic_status_cache) call(debug_server, "auxtools_init")() enable_debugging() AUXTOOLS_CHECK(AUXMOS) -#ifdef EXTOOLS_REFERENCE_TRACKING - enable_reference_tracking() -#endif world.Profile(PROFILE_START) log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index ecc6337d94..3ebb9e8089 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -210,10 +210,6 @@ GLOBAL_PROTECT(admin_verbs_debug) #endif /datum/admins/proc/create_or_modify_area, /datum/admins/proc/fixcorruption, -#ifdef EXTOOLS_REFERENCE_TRACKING - /datum/admins/proc/view_refs, - /datum/admins/proc/view_del_failures, -#endif // /client/proc/check_timer_sources, /client/proc/toggle_cdn, /client/proc/discordnulls, diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm index 5953c8cf27..d56f76e7c9 100644 --- a/code/modules/admin/view_variables/reference_tracking.dm +++ b/code/modules/admin/view_variables/reference_tracking.dm @@ -1,107 +1,3 @@ -#ifdef EXTOOLS_REFERENCE_TRACKING - -GLOBAL_LIST_EMPTY(deletion_failures) - -/world/proc/enable_reference_tracking() - if (fexists(EXTOOLS)) - //call(EXTOOLS, "ref_tracking_initialize")() - -/proc/get_back_references(datum/D) - CRASH("/proc/get_back_references not hooked by extools, reference tracking will not function!") - -/proc/get_forward_references(datum/D) - CRASH("/proc/get_forward_references not hooked by extools, reference tracking will not function!") - -/proc/clear_references(datum/D) - return - -/datum/admins/proc/view_refs(atom/D in world) //it actually supports datums as well but byond no likey - set category = "Debug" - set name = "View References" - - if(!check_rights(R_DEBUG) || !D) - return - - var/list/backrefs = get_back_references(D) - if(isnull(backrefs)) - var/datum/browser/popup = new(usr, "ref_view", "
Error
") - popup.set_content("Reference tracking not enabled") - popup.open(FALSE) - return - - var/list/frontrefs = get_forward_references(D) - var/list/dat = list() - dat += "

References of \ref[D] - [D]


\[Refresh\]
" - dat += "

Back references - these things hold references to this object.

" - dat += "" - dat += "" - for(var/ref in backrefs) - var/datum/backreference = ref - if(isnull(backreference)) - dat += "" - if(istype(backreference)) - dat += "" - else if(islist(backreference)) - dat += "" - else - dat += "" - dat += "
RefTypeVariable NameFollow
GC'd Reference
[REF(backreference)][backreference.type][backrefs[backreference]]\[Follow\]
[REF(backreference)]list[backrefs[backreference]]\[Follow\]
Weird reference type. Add more debugging checks.

" - dat += "

Forward references - this object is referencing those things.

" - dat += "" - dat += "" - for(var/ref in frontrefs) - var/datum/backreference = frontrefs[ref] - dat += "" - dat += "
Variable nameRefTypeFollow
[ref][REF(backreference)][backreference.type]\[Follow\]

" - dat = dat.Join() - - var/datum/browser/popup = new(usr, "ref_view", "
References of \ref[D]
") - popup.set_content(dat) - popup.open(FALSE) - - -/datum/admins/proc/view_del_failures() - set category = "Debug" - set name = "View Deletion Failures" - - if(!check_rights(R_DEBUG)) - return - - var/list/dat = list("") - for(var/t in GLOB.deletion_failures) - if(isnull(t)) - dat += "" - continue - var/datum/thing = t - dat += "" - dat += "
GC'd Reference | Clear Nulls
\ref[thing] | [thing.type][thing.gc_destroyed ? " (destroyed)" : ""] [ADMIN_VV(thing)]

" - dat = dat.Join() - - var/datum/browser/popup = new(usr, "del_failures", "
Deletion Failures
") - popup.set_content(dat) - popup.open(FALSE) - - -/datum/proc/find_references() - testing("Beginning search for references to a [type].") - var/list/backrefs = get_back_references(src) - for(var/ref in backrefs) - if(isnull(ref)) - log_world("## TESTING: Datum reference found, but gone now.") - continue - if(islist(ref)) - log_world("## TESTING: Found [type] \ref[src] in list.") - continue - var/datum/datum_ref = ref - if(!istype(datum_ref)) - log_world("## TESTING: Found [type] \ref[src] in unknown type reference: [datum_ref].") - return - log_world("## TESTING: Found [type] \ref[src] in [datum_ref.type][datum_ref.gc_destroyed ? " (destroyed)" : ""]") - message_admins("Found [type] \ref[src] [ADMIN_VV(src)] in [datum_ref.type][datum_ref.gc_destroyed ? " (destroyed)" : ""] [ADMIN_VV(datum_ref)]") - testing("Completed search for references to a [type].") - -#endif - #ifdef REFERENCE_TRACKING /datum/proc/find_references(skip_alert) diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm index 21c79eeda0..288f5cceee 100644 --- a/code/modules/admin/view_variables/topic_basic.dm +++ b/code/modules/admin/view_variables/topic_basic.dm @@ -47,16 +47,6 @@ usr.client.debug_variables(src) return - #ifdef EXTOOLS_REFERENCE_TRACKING - if(href_list[VV_HK_VIEW_REFERENCES]) - var/datum/D = locate(href_list[VV_HK_TARGET]) - if(!D) - to_chat(usr, "Unable to locate item.") - return - usr.client.holder.view_refs(target) - return - #endif - if(href_list[VV_HK_MARK]) usr.client.mark_datum(target) if(href_list[VV_HK_TAG]) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e91788423a..db91727886 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -21,10 +21,10 @@ hook_vr("mob_new",list(src)) /mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game. - if(client) - stack_trace("Mob with client has been deleted.") - else if(ckey) - stack_trace("Mob without client but with associated ckey, [ckey], has been deleted.") + // if(client) + // stack_trace("Mob with client has been deleted.") + // else if(ckey) + // stack_trace("Mob without client but with associated ckey, [ckey], has been deleted.") unset_machine() remove_from_mob_list() remove_from_dead_mob_list() From 1a0a31322552d40c1301772051d9bfa04ceb439e Mon Sep 17 00:00:00 2001 From: nickstershovel <143797359+ariaworld@users.noreply.github.com> Date: Sat, 10 Feb 2024 21:42:20 +0100 Subject: [PATCH 2/2] Fix borgs, fix ssd_mob_list removal --- .../signals/signals_mob/signals_mob_main.dm | 2 + code/_compile_options.dm | 3 - code/_onclick/hud/robot.dm | 1 + code/datums/ai_laws.dm | 4 + code/game/objects/items/robot/robot_parts.dm | 22 +++- code/modules/antagonists/cult/blood_magic.dm | 1 - code/modules/antagonists/cult/runes.dm | 2 +- code/modules/mob/living/brain/MMI.dm | 21 +-- code/modules/mob/living/living.dm | 1 + code/modules/mob/living/silicon/ai/death.dm | 14 +- .../modules/mob/living/silicon/robot/death.dm | 10 +- .../modules/mob/living/silicon/robot/robot.dm | 123 ++++++++---------- .../mob/living/silicon/robot/robot_defense.dm | 2 +- code/modules/mob/living/silicon/silicon.dm | 15 ++- code/modules/mob/mob.dm | 7 + code/modules/projectiles/projectile/magic.dm | 3 +- .../code/modules/mob/living/logout.dm | 6 +- 17 files changed, 131 insertions(+), 106 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index e6c3464ff7..ff61369eb2 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -1,2 +1,4 @@ /// from mob/proc/dropItemToGround() #define COMSIG_MOB_DROPPING_ITEM "mob_dropping_item" +///from base of mob/set_stat(): (new_stat, old_stat) +#define COMSIG_MOB_STATCHANGE "mob_statchange" diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 61b66e90bc..908b4239cb 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -15,9 +15,6 @@ //#define REFERENCE_TRACKING #ifdef REFERENCE_TRACKING -///alternate to reftracking, extool variant (outdated, EoL, doesn't work, should be removed) -//#define EXTOOLS_REFERENCE_TRACKING - ///Should we be logging our findings or not #define REFERENCE_TRACKING_LOG diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index bfdaae8069..9c5dc6aa05 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -338,6 +338,7 @@ return var/mob/living/silicon/S = usr S.toggle_sensors() + /atom/movable/screen/robot/modPC name = "Modular Interface" icon_state = "template" diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 21cf562b57..dba7fa3b92 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -18,6 +18,10 @@ var/list/devillaws = list() var/id = DEFAULT_AI_LAWID +/datum/ai_laws/Destroy() + owner = null + return ..() + /datum/ai_laws/proc/lawid_to_type(lawid) var/all_ai_laws = subtypesof(/datum/ai_laws) for(var/al in all_ai_laws) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 1667e023f5..323226dbe3 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -98,6 +98,25 @@ to_chat(user, "There is nothing to remove from the endoskeleton.") update_icon() +/// Drops all included parts to the passed location +/// This will also dissassemble the parts being dropped into components as well +/obj/item/robot_suit/proc/drop_all_parts(atom/drop_to = drop_location()) + l_leg?.forceMove(drop_to) + r_leg?.forceMove(drop_to) + l_arm?.forceMove(drop_to) + r_arm?.forceMove(drop_to) + + if(chest) + chest.forceMove(drop_to) + new /obj/item/stack/cable_coil(drop_to, 1) + chest.wired = FALSE + chest.cell?.forceMove(drop_to) + + if(head) + head.flash1?.forceMove(drop_to) + head.flash2?.forceMove(drop_to) + head.forceMove(drop_to) + /obj/item/robot_suit/proc/put_in_hand_or_drop(mob/living/user, obj/item/I) //normal put_in_hands() drops the item ontop of the player, this drops it at the suit's loc if(!user.put_in_hands(I)) I.forceMove(drop_location()) @@ -306,8 +325,7 @@ chest.cell.forceMove(O) chest.cell = null W.forceMove(O)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. - if(O.mmi) //we delete the mmi created by robot/New() - qdel(O.mmi) + QDEL_NULL(O.mmi) //we delete the mmi created by robot/New() O.mmi = W //and give the real mmi to the borg. O.updatename() playsound(O.loc, 'sound/voice/liveagain.ogg', 75, TRUE) diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 5847510255..2e334c59c9 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -657,7 +657,6 @@ makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T) SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) uses-- - candidate.mmi = null qdel(candidate) else candidate.color = prev_color diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 809a69d393..c3d1520ef4 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -317,7 +317,7 @@ structure_check() searches for nearby cultist structures required for the invoca if(iscyborg(sacrificial)) var/mob/living/silicon/robot/bot = sacrificial playsound(sacrificial, 'sound/magic/disable_tech.ogg', 100, TRUE) - bot.deconstruct() + bot.cyborg_deconstruct() else if(ishuman(sacrificial)) playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, TRUE) diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 847d3370c1..20f5813666 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -32,7 +32,7 @@ else . += "mmi_dead" -/obj/item/mmi/Initialize(mapload) +/obj/item/mmi/Initialize() . = ..() radio = new(src) //Spawns a radio inside the MMI. radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0. @@ -185,20 +185,11 @@ brainmob.emote("alarm") /obj/item/mmi/Destroy() - if(iscyborg(loc)) - var/mob/living/silicon/robot/borg = loc - borg.mmi = null - if(brainmob) - qdel(brainmob) - brainmob = null - if(brain) - qdel(brain) - brain = null - if(mecha) - mecha = null - if(radio) - qdel(radio) - radio = null + mecha = null + QDEL_NULL(brainmob) + QDEL_NULL(brain) + QDEL_NULL(radio) + QDEL_NULL(laws) return ..() /obj/item/mmi/deconstruct(disassembled = TRUE) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5f06d2d53c..68925aca88 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -39,6 +39,7 @@ remove_from_all_data_huds() GLOB.mob_living_list -= src + GLOB.ssd_mob_list -= src QDEL_LIST(diseases) return ..() diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 14f9490481..21f8646ec1 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -6,6 +6,9 @@ // Will update all AI status displays with a blue screen of death INVOKE_ASYNC(src, .proc/emote, "bsod") + if(!isnull(deployed_shell)) + disconnect_shell() + . = ..() var/old_icon = icon_state @@ -18,8 +21,14 @@ cameraFollow = null + if(is_anchored) + flip_anchored() + + //Citadel-Station Edit start move_resist = MOVE_FORCE_NORMAL update_mobility() + //Citadel-Station Edit end + if(eyeobj) eyeobj.setLoc(get_turf(src)) set_eyeobj_visible(FALSE) @@ -30,8 +39,7 @@ ShutOffDoomsdayDevice() if(explosive) - spawn(10) - explosion(src.loc, 3, 6, 12, 15) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), loc, 3, 6, 12, null, 15), 1 SECONDS) if(istype(loc, /obj/item/aicard/aitater)) loc.icon_state = "aitater-404" @@ -40,6 +48,8 @@ else if(istype(loc, /obj/item/aicard)) loc.icon_state = "aicard-404" + SSblackbox.ReportDeath(src) + /mob/living/silicon/ai/proc/ShutOffDoomsdayDevice() if(nuking) set_security_level("red") diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 4fd2888e00..0f3bab4b1e 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -3,9 +3,9 @@ new /obj/effect/temp_visual/gib_animation(loc, "gibbed-r") /mob/living/silicon/robot/dust(just_ash, drop_items, force) - if(mmi) - qdel(mmi) - ..() + // You do not get MMI'd if you are dusted + QDEL_NULL(mmi) + return ..() /mob/living/silicon/robot/spawn_dust() new /obj/effect/decal/remains/robot(loc) @@ -16,7 +16,9 @@ /mob/living/silicon/robot/death(gibbed) if(stat == DEAD) return - if(!gibbed) + if(gibbed) + dump_into_mmi() + else logevent("FATAL -- SYSTEM HALT") modularInterface.shutdown_computer() . = ..() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 676c19bf6d..a917d15d2f 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -98,42 +98,25 @@ modularInterface.layer = ABOVE_HUD_PLANE modularInterface.plane = ABOVE_HUD_PLANE -//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO /mob/living/silicon/robot/Destroy() - var/atom/T = drop_location()//To hopefully prevent run time errors. - if(mmi && mind)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside. - if(T) - mmi.forceMove(T) - if(mmi.brainmob) - if(mmi.brainmob.stat == DEAD) - mmi.brainmob.stat = CONSCIOUS - mmi.brainmob.remove_from_dead_mob_list() - mmi.brainmob.add_to_alive_mob_list() - mind.transfer_to(mmi.brainmob) - mmi.update_icon() - else - to_chat(src, "Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug.") - ghostize() - stack_trace("Borg MMI lacked a brainmob") - mmi = null - if(modularInterface) - QDEL_NULL(modularInterface) if(connected_ai) set_connected_ai(null) - if(shell) //??? why would you give an ai radio keys? - revert_shell() - else - if(T && istype(radio) && istype(radio.keyslot)) - radio.keyslot.forceMove(T) - radio.keyslot = null - QDEL_LIST(upgrades) + if(shell) + GLOB.available_ai_shells -= src + QDEL_NULL(modularInterface) QDEL_NULL(wires) QDEL_NULL(module) QDEL_NULL(eye_lights) QDEL_NULL(inv1) QDEL_NULL(inv2) QDEL_NULL(inv3) + QDEL_NULL(hands) + QDEL_NULL(spark_system) QDEL_NULL(aiPDA) + QDEL_LIST(upgrades) + QDEL_NULL(cell) + QDEL_NULL(robot_suit) + QDEL_NULL(thruster_button) cell = null return ..() @@ -662,50 +645,58 @@ lampButton?.update_icon() update_icons() -/mob/living/silicon/robot/proc/deconstruct() +/mob/living/silicon/robot/proc/cyborg_deconstruct() // SEND_SIGNAL(src, COMSIG_BORG_SAFE_DECONSTRUCT) - var/turf/T = get_turf(src) - if (robot_suit) - robot_suit.forceMove(T) - robot_suit.l_leg.forceMove(T) - robot_suit.l_leg = null - robot_suit.r_leg.forceMove(T) - robot_suit.r_leg = null - new /obj/item/stack/cable_coil(T, robot_suit.chest.wired) - robot_suit.chest.forceMove(T) - robot_suit.chest.wired = FALSE - robot_suit.chest = null - robot_suit.l_arm.forceMove(T) - robot_suit.l_arm = null - robot_suit.r_arm.forceMove(T) - robot_suit.r_arm = null - robot_suit.head.forceMove(T) - robot_suit.head.flash1.forceMove(T) - robot_suit.head.flash1.burn_out() - robot_suit.head.flash1 = null - robot_suit.head.flash2.forceMove(T) - robot_suit.head.flash2.burn_out() - robot_suit.head.flash2 = null - robot_suit.head = null - robot_suit.update_icon() + var/turf/drop_to = drop_location(src) + if(robot_suit) + robot_suit.drop_all_parts(drop_to) else - new /obj/item/robot_suit(T) - new /obj/item/bodypart/l_leg/robot(T) - new /obj/item/bodypart/r_leg/robot(T) - new /obj/item/stack/cable_coil(T, 1) - new /obj/item/bodypart/chest/robot(T) - new /obj/item/bodypart/l_arm/robot(T) - new /obj/item/bodypart/r_arm/robot(T) - new /obj/item/bodypart/head/robot(T) - var/b - for(b=0, b!=2, b++) - var/obj/item/assembly/flash/handheld/F = new /obj/item/assembly/flash/handheld(T) - F.burn_out() - if (cell) //Sanity check. - cell.forceMove(T) - cell = null + new /obj/item/robot_suit(drop_to) + new /obj/item/bodypart/l_leg/robot(drop_to) + new /obj/item/bodypart/r_leg/robot(drop_to) + new /obj/item/stack/cable_coil(drop_to, 1) + new /obj/item/bodypart/chest/robot(drop_to) + new /obj/item/bodypart/l_arm/robot(drop_to) + new /obj/item/bodypart/r_arm/robot(drop_to) + new /obj/item/bodypart/head/robot(drop_to) + for(var/i in 1 to 2) + var/obj/item/assembly/flash/handheld/borgeye = new(drop_to) + borgeye.burn_out() + + cell?.forceMove(drop_to) // Cell can be null, if removed beforehand + radio?.keyslot?.forceMove(drop_to) + radio?.keyslot = null + + dump_into_mmi(drop_to) + qdel(src) +/// Dumps the current occupant of the cyborg into an MMI at the passed location +/// Returns the borg's MMI on success +/mob/living/silicon/robot/proc/dump_into_mmi(atom/at_location = drop_location()) + if(isnull(mmi)) + return + + var/obj/item/mmi/removing = mmi + mmi.forceMove(at_location) // Nulls it out via exited + + if(isnull(mind)) // no one to transfer, just leave the MMI. + return mmi + + if(removing.brainmob) + if(removing.brainmob.stat == DEAD) + removing.brainmob.set_stat(CONSCIOUS) + mind.transfer_to(removing.brainmob) + removing.update_appearance() + + else + to_chat(src, span_boldannounce("Oops! Something went very wrong, your MMI was unable to receive your mind. \ + You have been ghosted. Please make a bug report so we can fix this bug.")) + ghostize() + stack_trace("Borg MMI lacked a brainmob") + + return mmi + ///This is the subtype that gets created by robot suits. It's needed so that those kind of borgs don't have a useless cell in them /mob/living/silicon/robot/nocell cell = null diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index f8217945db..d842afd455 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -161,7 +161,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real to_chat(user, span_notice("You start to unfasten [src]'s securing bolts...")) if(tool.use_tool(src, user, 5 SECONDS, volume = 50) && !cell) user.visible_message(span_notice("[user] deconstructs [src]!"), span_notice("You unfasten the securing bolts, and [src] falls to pieces!")) - deconstruct() + cyborg_deconstruct() return /mob/living/silicon/robot/fire_act() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 47d1661021..89d7937077 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -69,19 +69,20 @@ AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!", _save_key = null) AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _save_key = "ooc_notes", _examine_no_preview = TRUE) +/mob/living/silicon/Destroy() + QDEL_NULL(radio) + QDEL_NULL(aicamera) + QDEL_NULL(builtInCamera) + QDEL_NULL(laws) + GLOB.silicon_mobs -= src + return ..() + /mob/living/silicon/med_hud_set_health() return //we use a different hud /mob/living/silicon/med_hud_set_status() return //we use a different hud -/mob/living/silicon/Destroy() - radio = null - aicamera = null - QDEL_NULL(builtInCamera) - GLOB.silicon_mobs -= src - return ..() - /mob/living/silicon/contents_explosion(severity, target, origin) return diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index db91727886..ded4367de2 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1097,6 +1097,13 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) if(I.item_flags & SLOWS_WHILE_IN_HAND) . += I.slowdown +/mob/proc/set_stat(new_stat) + if(new_stat == stat) + return + . = stat + stat = new_stat + SEND_SIGNAL(src, COMSIG_MOB_STATCHANGE, new_stat, .) + /** * Mostly called by doUnEquip() * Like item dropped() on mob side. diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index b56742dd23..c47a6e85ee 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -135,8 +135,7 @@ if(iscyborg(M)) var/mob/living/silicon/robot/Robot = M - if(Robot.mmi) - qdel(Robot.mmi) + QDEL_NULL(Robot.mmi) Robot.notify_ai(NEW_BORG) else for(var/obj/item/W in contents) diff --git a/modular_splurt/code/modules/mob/living/logout.dm b/modular_splurt/code/modules/mob/living/logout.dm index f3eac5be48..fbdc16258f 100644 --- a/modular_splurt/code/modules/mob/living/logout.dm +++ b/modular_splurt/code/modules/mob/living/logout.dm @@ -32,8 +32,10 @@ log_game("[src] ignored auto-cryo by being: In a VR sleeper.") return - // Add to SSD list - GLOB.ssd_mob_list |= src + // Avoid adding deleted mobs to the list + if(!QDELETED(src)) + // Add to SSD list + GLOB.ssd_mob_list |= src // Log mob SSD status log_game("[src] was added to the SSD list.")