From 7f6a3cea582d4f2dc2fd33eac1b4101d3099849d Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 19 Jul 2023 02:58:40 +0200 Subject: [PATCH] [MIRROR] Removes side effects in Destroy from cyborgs, misc related code cleanup [MDB IGNORE] (#22575) * Removes side effects in Destroy from cyborgs, misc related code cleanup (#76867) ## About The Pull Request - Removes side effects from cyborg `Destroy` - Right result in more cyborgs getting dusted... Will have to check this out. - General AI / cyborg code cleanup Fixes #76855 ## Why It's Good For The Game Some more consistent, clean code ## Changelog :cl: Melbert fix: Cyborgs no longer drop their radio key when deleted, only when deconstructed first fix: Cyborgs no longer drop their MMI on deletion, only prior to deletion. This may result in bad code rearing its ugly head, open an issue report on the github if you're a cyborg and get ghosted when you feel like you shouldn't fix: Runtime from syndie cyborgs spawning fix: AI deaths are reported to black box /:cl: --------- Co-authored-by: Jacquerel * Removes side effects in Destroy from cyborgs, misc related code cleanup --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Jacquerel --- code/game/objects/items/robot/robot_parts.dm | 3 +- code/modules/antagonists/cult/blood_magic.dm | 1 - code/modules/mob/living/brain/MMI.dm | 3 - code/modules/mob/living/living.dm | 3 +- code/modules/mob/living/silicon/ai/ai.dm | 5 - code/modules/mob/living/silicon/ai/death.dm | 24 ++-- .../modules/mob/living/silicon/robot/death.dm | 10 +- .../modules/mob/living/silicon/robot/robot.dm | 103 +++++++++--------- .../mob/living/silicon/robot/robot_defense.dm | 4 +- .../mob/living/silicon/robot/robot_defines.dm | 16 +++ code/modules/mob/living/silicon/silicon.dm | 7 -- 11 files changed, 91 insertions(+), 88 deletions(-) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index f10af1c628a..c42145ff2a7 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -316,8 +316,7 @@ chest.cell.forceMove(O) 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(brainmob.client) // This canonizes that MMI'd cyborgs have memories of their previous life diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index da1655f35ac..9b28611e197 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -603,7 +603,6 @@ user.visible_message(span_danger("The dark cloud recedes from what was formerly [candidate], revealing a\n [construct_class]!")) make_new_construct_from_class(construct_class, THEME_CULT, candidate, user, FALSE, T) uses-- - candidate.mmi = null qdel(candidate) channeling = FALSE else diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 0de10eda4c9..3dc3d08d399 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -22,9 +22,6 @@ laws.set_laws_config() /obj/item/mmi/Destroy() - if(iscyborg(loc)) - var/mob/living/silicon/robot/borg = loc - borg.mmi = null set_mecha(null) QDEL_NULL(brainmob) QDEL_NULL(brain) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 53663519ccf..805e48234bb 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1385,8 +1385,7 @@ // Disconnect AI's in shells if(Robot.connected_ai) Robot.connected_ai.disconnect_shell() - if(Robot.mmi) - qdel(Robot.mmi) + QDEL_NULL(Robot.mmi) Robot.notify_ai(AI_NOTIFICATION_NEW_BORG) else for(var/obj/item/item in src) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 2a4670d266b..326ed391bb8 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -991,11 +991,6 @@ // I am so sorry SEND_SIGNAL(src, COMSIG_MOB_RESET_PERSPECTIVE) -/mob/living/silicon/ai/death(gibbed) - if(!isnull(deployed_shell)) - disconnect_shell() // farewell my sweet prince; for a shell is nothing without an AI to control it - return ..() - /mob/living/silicon/ai/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) . = ..() if(!.) //successfully ressuscitated from death diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 7a7e238b296..e064cb3da58 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -6,30 +6,30 @@ // Will update all AI status displays with a blue screen of death INVOKE_ASYNC(src, PROC_REF(emote), "bsod") + if(!isnull(deployed_shell)) + disconnect_shell() + . = ..() cut_overlays() //remove portraits - var/old_icon = icon_state - if("[icon_state]_dead" in icon_states(icon)) - icon_state = "[icon_state]_dead" + var/base_icon = icon_state + if(icon_exists(icon, "[base_icon]_dead")) + icon_state = "[base_icon]_dead" else icon_state = "ai_dead" - if("[old_icon]_death_transition" in icon_states(icon)) - flick("[old_icon]_death_transition", src) + + if(icon_exists(icon, "[base_icon]_death_transition")) + flick("[base_icon]_death_transition", src) cameraFollow = null - set_anchored(FALSE) //unbolt floorbolts - status_flags |= CANPUSH //we want it to be pushable when unanchored on death - REMOVE_TRAIT(src, TRAIT_NO_TELEPORT, AI_ANCHOR_TRAIT) //removes the anchor trait, because its not anchored anymore - move_resist = MOVE_FORCE_NORMAL - is_anchored = FALSE + if(is_anchored) + flip_anchored() if(eyeobj) eyeobj.setLoc(get_turf(src)) set_eyeobj_visible(FALSE) - GLOB.shuttle_caller_list -= src SSshuttle.autoEvac() @@ -41,6 +41,8 @@ if(explosive) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), loc, 3, 6, 12, null, 15), 1 SECONDS) + SSblackbox.ReportDeath(src) + /mob/living/silicon/ai/proc/ShutOffDoomsdayDevice() if(nuking) nuking = FALSE diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index bf29bf5f771..81026bf11b9 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 cada82ec4df..1f2cafbd5cb 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -89,18 +89,6 @@ alert_control.listener.RegisterSignal(src, COMSIG_LIVING_DEATH, TYPE_PROC_REF(/datum/alarm_listener, prevent_alarm_changes)) alert_control.listener.RegisterSignal(src, COMSIG_LIVING_REVIVE, TYPE_PROC_REF(/datum/alarm_listener, allow_alarm_changes)) -/mob/living/silicon/robot/model/syndicate/Initialize(mapload) - . = ..() - laws = new /datum/ai_laws/syndicate_override() - addtimer(CALLBACK(src, PROC_REF(show_playstyle)), 5) - -/mob/living/silicon/robot/model/syndicate/create_modularInterface() - if(!modularInterface) - modularInterface = new /obj/item/modular_computer/pda/silicon/cyborg/syndicate(src) - modularInterface.saved_identification = real_name - modularInterface.saved_job = "Cyborg" - return ..() - /mob/living/silicon/robot/set_suicide(suicide_state) . = ..() if(mmi) @@ -128,30 +116,12 @@ //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.set_stat(CONSCIOUS) - mind.transfer_to(mmi.brainmob) - mmi.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") - mmi = null - if(modularInterface) - QDEL_NULL(modularInterface) if(connected_ai) set_connected_ai(null) if(shell) GLOB.available_ai_shells -= src - else - if(T && istype(radio) && istype(radio.keyslot)) - radio.keyslot.forceMove(T) - radio.keyslot = null + + QDEL_NULL(modularInterface) QDEL_NULL(wires) QDEL_NULL(model) QDEL_NULL(eye_lights) @@ -533,31 +503,62 @@ lampButton?.update_appearance() update_icons() -/mob/living/silicon/robot/proc/deconstruct() +/mob/living/silicon/robot/proc/cyborg_deconstruct() SEND_SIGNAL(src, COMSIG_BORG_SAFE_DECONSTRUCT) if(shell) undeploy() - var/turf/T = get_turf(src) + var/turf/drop_to = drop_location() if (robot_suit) - robot_suit.drop_all_parts(T) + robot_suit.drop_all_parts(drop_to) else - new /obj/item/robot_suit(T) - new /obj/item/bodypart/leg/left/robot(T) - new /obj/item/bodypart/leg/right/robot(T) - new /obj/item/stack/cable_coil(T, 1) - new /obj/item/bodypart/chest/robot(T) - new /obj/item/bodypart/arm/left/robot(T) - new /obj/item/bodypart/arm/right/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() + new /obj/item/robot_suit(drop_to) + new /obj/item/bodypart/leg/left/robot(drop_to) + new /obj/item/bodypart/leg/right/robot(drop_to) + new /obj/item/stack/cable_coil(drop_to, 1) + new /obj/item/bodypart/chest/robot(drop_to) + new /obj/item/bodypart/arm/left/robot(drop_to) + new /obj/item/bodypart/arm/right/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) - cell?.forceMove(T) // Cell can be null, if removed beforehand 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 + /mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname) if(!connected_ai) return @@ -736,9 +737,6 @@ return TRUE -/mob/living/silicon/robot/model/syndicate/ResetModel() - return - /mob/living/silicon/robot/proc/has_model() if(!model || model.type == /obj/item/robot_model) . = FALSE @@ -780,6 +778,9 @@ if(gone == cell) cell = null + if(gone == mmi) + mmi = null + ///Use this to add upgrades to robots. It'll register signals for when the upgrade is moved or deleted, if not single use. /mob/living/silicon/robot/proc/add_to_upgrades(obj/item/borg/upgrade/new_upgrade, mob/user) if(new_upgrade in upgrades) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index b4147e76fe1..61cccd35f9b 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -305,9 +305,9 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real spark_system.start() return to_chat(user, span_notice("You start to unfasten [src]'s securing bolts...")) - if(tool.use_tool(src, user, 50, volume=50) && !cell) + 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/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index e9b8bbff823..36e000327bf 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -202,10 +202,26 @@ cell = /obj/item/stock_parts/cell/hyper radio = /obj/item/radio/borg/syndicate +/mob/living/silicon/robot/model/syndicate/Initialize(mapload) + laws = new /datum/ai_laws/syndicate_override() + laws.associate(src) + . = ..() + addtimer(CALLBACK(src, PROC_REF(show_playstyle)), 0.5 SECONDS) + +/mob/living/silicon/robot/model/syndicate/create_modularInterface() + if(!modularInterface) + modularInterface = new /obj/item/modular_computer/pda/silicon/cyborg/syndicate(src) + modularInterface.saved_identification = real_name + modularInterface.saved_job = "Cyborg" + return ..() + /mob/living/silicon/robot/model/syndicate/proc/show_playstyle() if(playstyle_string) to_chat(src, playstyle_string) +/mob/living/silicon/robot/model/syndicate/ResetModel() + return + /mob/living/silicon/robot/model/syndicate/medical icon_state = "synd_medical" playstyle_string = "You are a Syndicate medical cyborg!
\ diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 8328b3b16dc..c2aaab8fc23 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -106,13 +106,6 @@ modularInterface.saved_job = "Cyborg" return ..() -/mob/living/silicon/robot/model/syndicate/create_modularInterface() - if(!modularInterface) - modularInterface = new /obj/item/modular_computer/pda/silicon/cyborg/syndicate(src) - modularInterface.saved_job = "Cyborg" - return ..() - - /mob/living/silicon/med_hud_set_health() return //we use a different hud