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/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 += "| Ref | Type | Variable Name | Follow | "
- for(var/ref in backrefs)
- var/datum/backreference = ref
- if(isnull(backreference))
- dat += "
|---|
| GC'd Reference |
"
- if(istype(backreference))
- dat += "| [REF(backreference)] | [backreference.type] | [backrefs[backreference]] | \[Follow\] |
"
- else if(islist(backreference))
- dat += "| [REF(backreference)] | list | [backrefs[backreference]] | \[Follow\] |
"
- else
- dat += "| Weird reference type. Add more debugging checks. |
"
- dat += "
"
- dat += "Forward references - this object is referencing those things.
"
- dat += ""
- dat += "| Variable name | Ref | Type | Follow | "
- for(var/ref in frontrefs)
- var/datum/backreference = frontrefs[ref]
- dat += "
|---|
| [ref] | [REF(backreference)] | [backreference.type] | \[Follow\] |
"
- dat += "
"
- 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 += "| GC'd Reference | Clear Nulls |
"
- continue
- var/datum/thing = t
- dat += "| \ref[thing] | [thing.type][thing.gc_destroyed ? " (destroyed)" : ""] [ADMIN_VV(thing)] |
"
- dat += "
"
- 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/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 e91788423a..ded4367de2 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()
@@ -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.")