[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

🆑 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
/🆑

---------

Co-authored-by: Jacquerel <hnevard@ gmail.com>

* 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 <hnevard@ gmail.com>
This commit is contained in:
SkyratBot
2023-07-18 20:58:40 -04:00
committed by GitHub
co-authored by Jacquerel MrMelbert
parent 2cbf139d17
commit 7f6a3cea58
11 changed files with 91 additions and 88 deletions
+1 -2
View File
@@ -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
@@ -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
-3
View File
@@ -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)
+1 -2
View File
@@ -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)
-5
View File
@@ -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
+13 -11
View File
@@ -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
@@ -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()
. = ..()
+52 -51
View File
@@ -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)
@@ -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()
@@ -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 = "<span class='big bold'>You are a Syndicate medical cyborg!</span><br>\
@@ -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