From a01e23768f0837e70159808f3ad05b33f3c171e3 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:17:38 +0200 Subject: [PATCH] [MIRROR] B.O.R.I.S. Module Bugfix [MDB IGNORE] (#24431) * B.O.R.I.S. Module Bugfix (#79047) ## About The Pull Request The boris module that turns a cyborg into an AI shell is a bit weird. It can be used like an MMI or a positronic brain directly on a completed borg exoskeleton. It can also be used like any other cyborg upgrade on a completed cyborg, if an only if that cyborg is not controlled by a player already. If you reset an AI shell, it is intended to make the cyborg un-player controlled and to drop the boris module onto the ground. From there, you are supposed to be able put it back in like any other upgrade. However, this behavior was bugged. Due to certain parts of the code not calling procs they should have, the boris module was not being properly removed from the list of upgrades when the shell was reset (in most cases). This meant that the boris module could not be re-applied to the newly empty borg. Furthermore, if the empty borg was deconstructed then the dropped boris module would immediately be deleted. This PR just fixes all that behavior so it works properly. I also fixed a weird typo with removing cells from borgs because I noticed it while testing. ## Why It's Good For The Game Bugs are bad. ## Changelog :cl: fix: B.O.R.I.S. modules can once again be properly applied to the unformatted borg created when you reset an AI shell. /:cl: * B.O.R.I.S. Module Bugfix --------- Co-authored-by: GPeckman <21979502+GPeckman@users.noreply.github.com> --- code/game/objects/items/robot/robot_parts.dm | 2 +- .../objects/items/robot/robot_upgrades.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 20 ++++++++++++++----- .../mob/living/silicon/robot/robot_defense.dm | 6 +++--- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 3f698c5c08f..e92b4332846 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -283,7 +283,7 @@ if(!user.temporarilyRemoveItemFromInventory(W)) return - var/mob/living/silicon/robot/O = new /mob/living/silicon/robot/nocell(get_turf(loc)) + var/mob/living/silicon/robot/O = new /mob/living/silicon/robot/nocell(get_turf(loc), user) if(!O) return if(M.laws && M.laws.id != DEFAULT_AI_LAWID) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 94432b35d3d..92dd162a9b0 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -522,7 +522,7 @@ /obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R, user = usr) . = ..() if(.) - if(R.shell) + if(locate(/obj/item/borg/upgrade/ai) in R.upgrades) to_chat(user, span_warning("This unit is already an AI shell!")) return FALSE if(R.key) //You cannot replace a player unless the key is completely removed. diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index fe28d41fe84..373f5e59a4f 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -60,7 +60,9 @@ //If this body is meant to be a borg controlled by the AI player if(shell) - make_shell() + var/obj/item/borg/upgrade/ai/board = new(src) + make_shell(board) + add_to_upgrades(board) else //MMI stuff. Held togheter by magic. ~Miauw if(!mmi?.brainmob) @@ -798,8 +800,10 @@ 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) +///Called when a mob uses an upgrade on an open borg. Checks to make sure the upgrade can be applied +/mob/living/silicon/robot/proc/apply_upgrade(obj/item/borg/upgrade/new_upgrade, mob/user) + if(isnull(user)) + return FALSE if(new_upgrade in upgrades) return FALSE if(!user.temporarilyRemoveItemFromInventory(new_upgrade)) //calling the upgrade's dropped() proc /before/ we add action buttons @@ -809,6 +813,10 @@ new_upgrade.forceMove(loc) //gets lost otherwise return FALSE to_chat(user, span_notice("You apply the upgrade to [src].")) + add_to_upgrades(new_upgrade) + +///Moves the upgrade inside the robot and registers relevant signals. +/mob/living/silicon/robot/proc/add_to_upgrades(obj/item/borg/upgrade/new_upgrade) to_chat(src, "----------------\nNew hardware detected...Identified as \"[new_upgrade]\"...Setup complete.\n----------------") if(new_upgrade.one_use) logevent("Firmware [new_upgrade] run successfully.") @@ -844,8 +852,10 @@ * * board - B.O.R.I.S. module board used for transforming the cyborg into AI shell */ /mob/living/silicon/robot/proc/make_shell(obj/item/borg/upgrade/ai/board) - if(!board) - upgrades |= new /obj/item/borg/upgrade/ai(src) + if(isnull(board)) + stack_trace("make_shell was called without a board argument! This is never supposed to happen!") + return FALSE + shell = TRUE braintype = "AI Shell" name = "Empty AI Shell-[ident]" diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 09440ec22a3..f49fda57449 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -78,7 +78,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real to_chat(user, span_warning("[src] already has a defibrillator!")) return var/obj/item/borg/upgrade/defib/backpack/B = new(null, D) - add_to_upgrades(B, user) + apply_upgrade(B, user) return if(istype(W, /obj/item/ai_module)) @@ -142,7 +142,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(!user.canUnEquip(U)) to_chat(user, span_warning("The upgrade is stuck to you and you can't seem to let go of it!")) return - add_to_upgrades(U, user) + apply_upgrade(U, user) return if(istype(W, /obj/item/toner)) @@ -232,8 +232,8 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real return cell.update_appearance() cell.add_fingerprint(user) - user.put_in_active_hand(cell) to_chat(user, span_notice("You remove \the [cell].")) + user.put_in_active_hand(cell) update_icons() diag_hud_set_borgcell()