diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index ed078b997a3..80f2ad9797f 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -469,10 +469,6 @@ require_module = 1 module_type = list(/obj/item/robot_module/medical) module_flags = BORG_MODULE_MEDICAL - var/backpack = FALSE //True if we get the defib from a physical backpack unit rather than an upgrade card, so that we can return that upon deactivate() - -/obj/item/borg/upgrade/defib/backpack - backpack = TRUE /obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R, user = usr) . = ..() @@ -490,10 +486,33 @@ if (.) var/obj/item/shockpaddles/cyborg/S = locate() in R.module R.module.remove_module(S, TRUE) - if(backpack) - new /obj/item/defibrillator(get_turf(R)) - qdel(src) +///A version of the above that also acts as a holder of an actual defibrillator item used in place of the upgrade chip. +/obj/item/borg/upgrade/defib/backpack + var/obj/item/defibrillator/defib_instance + +/obj/item/borg/upgrade/defib/backpack/Initialize(mapload, obj/item/defibrillator/D) + . = ..() + if(!D) + D = new /obj/item/defibrillator + defib_instance = D + name = defib_instance.name + defib_instance.moveToNullspace() + RegisterSignal(defib_instance, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), .proc/on_defib_instance_qdel_or_moved) + +/obj/item/borg/upgrade/defib/backpack/proc/on_defib_instance_qdel_or_moved(obj/item/defibrillator/D) + defib_instance = null + qdel(src) + +/obj/item/borg/upgrade/defib/backpack/Destroy() + if(defib_instance) + QDEL_NULL(defib_instance) + return ..() + +/obj/item/borg/upgrade/defib/backpack/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + defib_instance?.forceMove(R.drop_location()) // [on_defib_instance_qdel_or_moved()] handles the rest. /obj/item/borg/upgrade/processor name = "medical cyborg surgical processor" diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index 3636c95d59a..51d56bf5b61 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -149,11 +149,9 @@ var/upgradepath = text2path(params["upgrade"]) var/obj/item/borg/upgrade/installedupgrade = locate(upgradepath) in borg if (installedupgrade) - installedupgrade.deactivate(borg, user) - borg.upgrades -= installedupgrade message_admins("[key_name_admin(user)] removed the [installedupgrade] upgrade from [ADMIN_LOOKUPFLW(borg)].") log_admin("[key_name(user)] removed the [installedupgrade] upgrade from [key_name(borg)].") - qdel(installedupgrade) + qdel(installedupgrade) // see [mob/living/silicon/robot/on_upgrade_deleted()]. else var/obj/item/borg/upgrade/upgrade = new upgradepath(borg) upgrade.action(borg, user) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 335a74754a8..7d3f1fcad14 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -85,7 +85,7 @@ Field repairs can be done with a welder."} if(stored_gun?.max_mod_capacity) . += "[stored_gun.get_remaining_mod_capacity()]% mod capacity remaining." - for(var/A in stored_gun.get_modkits()) + for(var/A in stored_gun.modkits) var/obj/item/borg/upgrade/modkit/M = A . += "There is \a [M] installed, using [M.cost]% capacity." @@ -140,7 +140,7 @@ if(istype(O, /obj/projectile/kinetic)) var/obj/projectile/kinetic/K = O if(K.kinetic_gun) - for(var/A in K.kinetic_gun.get_modkits()) + for(var/A in K.kinetic_gun.modkits) var/obj/item/borg/upgrade/modkit/M = A if(istype(M, /obj/item/borg/upgrade/modkit/minebot_passthrough)) return TRUE diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2f07c89e894..bb3d7408917 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -852,11 +852,8 @@ // Remove upgrades. for(var/obj/item/borg/upgrade/I in upgrades) - I.deactivate(src) I.forceMove(get_turf(src)) - upgrades.Cut() - ionpulse = FALSE revert_shell() @@ -904,7 +901,43 @@ hat = null if(!QDELETED(src)) //Don't update icons if we are deleted. update_icons() - . = ..() + return ..() + +///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) + return + if(!new_upgrade.action(src, user)) + to_chat(user, "Upgrade error.") + return FALSE + to_chat(user, "You apply the upgrade to [src].") + to_chat(src, "----------------\nNew hardware detected...Identified as \"[new_upgrade]\"...Setup complete.\n----------------") + if(new_upgrade.one_use) + logevent("Firmware [new_upgrade] run successfully.") + qdel(new_upgrade) + return FALSE + upgrades += new_upgrade + new_upgrade.forceMove(src) + RegisterSignal(new_upgrade, COMSIG_MOVABLE_MOVED, .proc/remove_from_upgrades) + RegisterSignal(new_upgrade, COMSIG_PARENT_QDELETING, .proc/on_upgrade_deleted) + logevent("Hardware [new_upgrade] installed successfully.") + +///Called when an upgrade is moved outside the robot. So don't call this directly, use forceMove etc. +/mob/living/silicon/robot/proc/remove_from_upgrades(obj/item/borg/upgrade/old_upgrade) + SIGNAL_HANDLER + if(loc == src) + return + old_upgrade.deactivate(src) + upgrades -= old_upgrade + UnregisterSignal(old_upgrade, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) + +///Called when an applied upgrade is deleted. +/mob/living/silicon/robot/proc/on_upgrade_deleted(obj/item/borg/upgrade/old_upgrade) + SIGNAL_HANDLER + if(!QDELETED(src)) + old_upgrade.deactivate(src) + upgrades -= old_upgrade + UnregisterSignal(old_upgrade, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) /** * make_shell: Makes an AI shell out of a cyborg unit diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 5196b095945..d196684e89d 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -116,6 +116,9 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(!istype(module, /obj/item/robot_module/medical)) to_chat(user, "[src] does not have correct mounting points for a defibrillator!") return + if(stat == DEAD) + to_chat(user, "This defibrillator unit will not function on a deceased cyborg!") + return var/obj/item/defibrillator/D = W if(D.slot_flags != ITEM_SLOT_BACK) //belt defibs need not apply to_chat(user, "This defibrillator unit doesn't seem to fit correctly!") @@ -126,13 +129,8 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(locate(/obj/item/borg/upgrade/defib) in src || locate(/obj/item/borg/upgrade/defib/backpack) in src) to_chat(user, "[src] already has a defibrillator!") return - var/obj/item/borg/upgrade/defib/backpack/B = new /obj/item/borg/upgrade/defib/backpack(src) - B.action(src, user) - to_chat(user, "You apply the upgrade to [src].") - to_chat(src, "----------------\nNew hardware detected...Identified as \"[D]\"...Setup complete.\n----------------") - upgrades += B - logevent("Hardware [D] detected and installed successfully.") - qdel(D) + var/obj/item/borg/upgrade/defib/backpack/B = new(null, D) + add_to_upgrades(B, user) return if(istype(W, /obj/item/ai_module)) @@ -190,23 +188,9 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real to_chat(user, "The cyborg must choose a module before it can be upgraded!") else if(U.locked) to_chat(user, "The upgrade is locked and cannot be used yet!") - else - if(!user.temporarilyRemoveItemFromInventory(U)) - return - if(U.action(src)) - to_chat(user, "You apply the upgrade to [src].") - to_chat(src, "----------------\nNew hardware detected...Identified as \"[U]\"...Setup complete.\n----------------") - if(U.one_use) - logevent("Firmware [U] run successfully.") - qdel(U) - else - U.forceMove(src) - upgrades += U - logevent("Hardware [U] installed successfully.") - - else - to_chat(user, "Upgrade error.") - U.forceMove(drop_location()) + else if(user.canUnEquip(U)) + return + add_to_upgrades(U, user) return if(istype(W, /obj/item/toner)) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index bc705726ded..cdc58f7062f 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -32,7 +32,7 @@ if(max_mod_capacity) . += "[get_remaining_mod_capacity()]% mod capacity remaining." . += "You can use a crowbar to remove modules." - for(var/A in get_modkits()) + for(var/A in modkits) var/obj/item/borg/upgrade/modkit/M = A . += "There is \a [M] installed, using [M.cost]% capacity." @@ -41,11 +41,18 @@ if(modkits.len) to_chat(user, "You pry the modifications out.") I.play_tool_sound(src, 100) - for(var/obj/item/borg/upgrade/modkit/M in modkits) - M.uninstall(src) + for(var/a in modkits) + var/obj/item/borg/upgrade/modkit/M = a + M.forceMove(drop_location()) //uninstallation handled in Exited(), or /mob/living/silicon/robot/remove_from_upgrades() for borgs else to_chat(user, "There are no modifications currently installed.") +/obj/item/gun/energy/kinetic_accelerator/Exited(atom/A) + if(modkits.len && (A in modkits)) + var/obj/item/borg/upgrade/modkit/MK = A + MK.uninstall(src) + . = ..() + /obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/borg/upgrade/modkit)) var/obj/item/borg/upgrade/modkit/MK = I @@ -55,19 +62,14 @@ /obj/item/gun/energy/kinetic_accelerator/proc/get_remaining_mod_capacity() var/current_capacity_used = 0 - for(var/A in get_modkits()) + for(var/A in modkits) var/obj/item/borg/upgrade/modkit/M = A current_capacity_used += M.cost return max_mod_capacity - current_capacity_used -/obj/item/gun/energy/kinetic_accelerator/proc/get_modkits() - . = list() - for(var/A in modkits) - . += A - /obj/item/gun/energy/kinetic_accelerator/proc/modify_projectile(obj/projectile/kinetic/K) K.kinetic_gun = src //do something special on-hit, easy! - for(var/A in get_modkits()) + for(var/A in modkits) var/obj/item/borg/upgrade/modkit/M = A M.modify_projectile(K) @@ -188,7 +190,7 @@ . = ..() if(.) if(kinetic_gun) - var/list/mods = kinetic_gun.get_modkits() + var/list/mods = kinetic_gun.modkits for(var/obj/item/borg/upgrade/modkit/M in mods) M.projectile_prehit(src, target, kinetic_gun) if(!lavaland_equipment_pressure_check(get_turf(target))) @@ -209,7 +211,7 @@ if(!target_turf) target_turf = get_turf(src) if(kinetic_gun) //hopefully whoever shot this was not very, very unfortunate. - var/list/mods = kinetic_gun.get_modkits() + var/list/mods = kinetic_gun.modkits for(var/obj/item/borg/upgrade/modkit/M in mods) M.projectile_strike_predamage(src, target_turf, target, kinetic_gun) for(var/obj/item/borg/upgrade/modkit/M in mods) @@ -259,9 +261,9 @@ . = ..() if (.) for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules) - return install(H, usr) + return install(H, usr, FALSE) -/obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) +/obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user, transfer_to_loc = TRUE) . = TRUE if(minebot_upgrade) if(minebot_exclusive && !istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone)) @@ -272,7 +274,7 @@ return FALSE if(denied_type) var/number_of_denied = 0 - for(var/A in KA.get_modkits()) + for(var/A in KA.modkits) var/obj/item/borg/upgrade/modkit/M = A if(istype(M, denied_type)) number_of_denied++ @@ -281,7 +283,7 @@ break if(KA.get_remaining_mod_capacity() >= cost) if(.) - if(!user.transferItemToLoc(src, KA)) + if(transfer_to_loc && !user.transferItemToLoc(src, KA)) return to_chat(user, "You install the modkit.") playsound(loc, 'sound/items/screwdriver.ogg', 100, TRUE) @@ -299,11 +301,8 @@ uninstall(KA) /obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/gun/energy/kinetic_accelerator/KA) - forceMove(get_turf(KA)) KA.modkits -= src - - /obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/projectile/kinetic/K) //use this one for effects you want to trigger before any damage is done at all and before damage is decreased by pressure