From 4a653f9caae9d49bf3a3013affbedbda9b682a93 Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:06:19 +1300 Subject: [PATCH 01/13] Default Sprite --- .../icons/obj/devices/circuitry_n_data.dmi | Bin 0 -> 643 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 maplestation_modules/icons/obj/devices/circuitry_n_data.dmi diff --git a/maplestation_modules/icons/obj/devices/circuitry_n_data.dmi b/maplestation_modules/icons/obj/devices/circuitry_n_data.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f28ca937b6232e0dfada81963b16fe56b5ed5f85 GIT binary patch literal 643 zcmV-}0(||6P)V=-0C)i_%_#*CJk{ zr;0zz9FX&iMwQDC$GZcP0NA4(04N}qyumphu#z*e7u7b!QK!@4#XZPwsgE4uwRqv% z(KY%PB?2fJ*Z}mQIIhxnz@7(*XJGWqip`6C%;OYeXa|wbqH$&$g&k5l0HFbT8PJSd z@zhPS`fHAt(7Is6D!N1vi7gL;_fi}1mQz5uOh{;fp$-m!xtNJ4E?Gmg)+2)fh*Q8A zU~L2^pzmvD*BOv?<0N)FNqG#A!$9vEmjb2+Mo!w~FG8V#Scp%-w5e1R$pGM*6^{dt zknR}@4d|163Id*TPoVhzARGZ1`T*Z}K3{<$YhdRJg~FFJ%$&_;liq+ZG+E7$=OhCV z8W09)0jvjHVSYC Date: Wed, 25 Dec 2024 23:02:19 +1300 Subject: [PATCH 02/13] adds a module for borgs to do magic! --- maplestation.dme | 1 + .../code/modules/magic/mana/living_mana.dm | 12 ++++ .../code/modules/objects/robot_magic.dm | 63 +++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 maplestation_modules/code/modules/objects/robot_magic.dm diff --git a/maplestation.dme b/maplestation.dme index f073cbd17427..825409e1f1fe 100644 --- a/maplestation.dme +++ b/maplestation.dme @@ -6486,6 +6486,7 @@ #include "maplestation_modules\code\modules\mod\mod_control.dm" #include "maplestation_modules\code\modules\mod\modules\modules_general.dm" #include "maplestation_modules\code\modules\movespeed\modifiers\reagent.dm" +#include "maplestation_modules\code\modules\objects\robot_magic.dm" #include "maplestation_modules\code\modules\paperwork\stamps.dm" #include "maplestation_modules\code\modules\pixel_shift\code\pixel_shift_component.dm" #include "maplestation_modules\code\modules\pixel_shift\code\pixel_shift_keybind.dm" diff --git a/maplestation_modules/code/modules/magic/mana/living_mana.dm b/maplestation_modules/code/modules/magic/mana/living_mana.dm index 5169b609d71b..a90dd8b0a09a 100644 --- a/maplestation_modules/code/modules/magic/mana/living_mana.dm +++ b/maplestation_modules/code/modules/magic/mana/living_mana.dm @@ -1,3 +1,15 @@ +//Silicon stuff +/mob/living/silicon + has_initial_mana_pool = TRUE + +/mob/living/silicon/get_initial_mana_pool_type() + return /datum/mana_pool/mob/living/silicon + +/datum/mana_pool/mob/living/silicon + maximum_mana_capacity = 25 + + +//Carbon stuff /mob/living/carbon has_initial_mana_pool = TRUE diff --git a/maplestation_modules/code/modules/objects/robot_magic.dm b/maplestation_modules/code/modules/objects/robot_magic.dm new file mode 100644 index 000000000000..1346ecc095c4 --- /dev/null +++ b/maplestation_modules/code/modules/objects/robot_magic.dm @@ -0,0 +1,63 @@ + +/obj/item/borg/upgrade/magic + name = "borg magical focus" + desc = "A magical focus which allows borgs to create magic." + icon = 'maplestation_modules/icons/obj/devices/circuitry_n_data.dmi' + icon_state = "cyborg_magic_focus" + w_class = WEIGHT_CLASS_SMALL + + has_initial_mana_pool = TRUE + ///the mana pool from the borg that the upgrade is inside. Set to null when not in a borg. + var/datum/mana_pool/borg_mana_pool = null + +//mana pool stuff for the magic borg upgrade +/datum/mana_pool/borg_focus + maximum_mana_capacity = CARBON_BASE_MANA_CAPACITY //same as carbons! + +/obj/item/borg/upgrade/magic/get_initial_mana_pool_type() + return /datum/mana_pool/mob/living/silicon + +/obj/item/borg/upgrade/magic/action(mob/living/silicon/robot/borg) + . = ..() + if(.) + //add the spells to the borg's actions + var/list/list_value = borg.client.prefs.read_preference(/datum/preference/spellbook) + for (var/datum/spellbook_item/entry in spellbook_list_to_datums(list_value)) + entry.apply(borg, list_value[entry.type]) + + //store the borg's current mana pool for returning it when the module is removed + if (borg.mana_pool != null) //incase the borg has no mana pool + borg_mana_pool = borg.mana_pool + + //put the upgrade's magic pool into the borg. + if(src.mana_pool != null) + mana_pool = borg.initialize_mana_pool(src.mana_pool) + borg.set_mana_pool(mana_pool) // no need to check if the borg has a mana pool, as this makes one. + + //if the upgrade has no magic pool for some reason, make one! + else + mana_pool = borg.initialize_mana_pool(src.mana_pool) + borg.set_mana_pool(mana_pool) + +/obj/item/borg/upgrade/magic/deactivate(mob/living/silicon/robot/borg, user = usr) + . = ..() + if(.) + //removes the spells + for (var/datum/action/cooldown/spell/action_to_remove in borg.actions) + action_to_remove.Remove(borg) + //resets the mana pool to before + borg.set_mana_pool(borg_mana_pool) + borg_mana_pool = null //removes the borg's mana pool var from the upgrade as this upgrade being removed from the borg + +//borg panel qdels, so i gotta make sure it works when borg panel removes it. +// /obj/item/borg/upgrade/magic/proc/clear_on_delete(datum/to_clear) +// RegisterSignal(to_clear, COMSIG_QDELETING, PROC_REF(on_delete)) + +// /obj/item/borg/upgrade/magic/proc/on_delete() +// if(.) +// //removes the spells +// for (var/datum/action/cooldown/spell/action_to_remove in borg.actions) +// action_to_remove.Remove(borg) +// //resets the mana pool to before +// borg.set_mana_pool(borg_mana_pool) +// borg_mana_pool = null //removes the borg's mana pool var from the upgrade as this upgrade being removed from the borg From b9f3c4350fbb7002abb44eba1b35bbe7dddc646d Mon Sep 17 00:00:00 2001 From: Waterpig <49160555+Majkl-J@users.noreply.github.com> Date: Sat, 1 Jun 2024 22:52:10 +0200 Subject: [PATCH 03/13] Borgs: the moduling (Various fixups to borg module code) (#83116) - Gets rid of the item addition copypaste code (Why nobody did this for 7 years is beyond me) - Adds variable and proper checks for if a module is already installed (Borgs will no longer eat up unlimited masses of lavaproof track upgrades, among others) (Technically this never allows duplicates, at least currently, as I don't recall any modules being capable to used multiple times intentionally without also deleting themselves with single_use) - Unsingleletters most if not all of `robot_upgrades.dm` Makes the borg module code much cleaner, makes it significantly easier for new ones to be added. Fixes unintended behaviour with some modules being able to stack, which until now was always solved by copypasting code. :cl: fix: Fixed some borg modules just being constantly eaten up by borgs even when they shouldn't allow duplicates refactor: Borg module code now has better handling for adding/removing items, and to prevent duplicate module usage (Unless one wishes to override the behaviour. /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> Co-authored-by: san7890 --- .../objects/effects/spawners/random/exotic.dm | 2 +- .../objects/items/robot/robot_upgrades.dm | 785 +++++++----------- .../designs/mechfabricator_designs.dm | 2 +- 3 files changed, 299 insertions(+), 490 deletions(-) diff --git a/code/game/objects/effects/spawners/random/exotic.dm b/code/game/objects/effects/spawners/random/exotic.dm index add4faf5c500..e802e30056f4 100644 --- a/code/game/objects/effects/spawners/random/exotic.dm +++ b/code/game/objects/effects/spawners/random/exotic.dm @@ -50,7 +50,7 @@ /obj/item/storage/medkit/brute = 27, /obj/item/storage/medkit/fire = 27, /obj/item/storage/toolbox/syndicate = 12, - /obj/item/borg/upgrade/ddrill = 3, + /obj/item/borg/upgrade/diamond_drill = 3, /obj/item/knife/butcher = 14, /obj/item/clothing/glasses/night = 10, /obj/item/pickaxe/drill/diamonddrill = 6, diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 27dfb028992d..11efdc231876 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -13,23 +13,61 @@ var/list/model_type = null /// Bitflags listing model compatibility. Used in the exosuit fabricator for creating sub-categories. var/list/model_flags = NONE - // if true, is not stored in the robot to be ejected - // if model is reset + + /// List of items to add with the module, if any + var/list/items_to_add + /// List of items to remove with the module, if any + var/list/items_to_remove + // if true, is not stored in the robot to be ejected if model is reset var/one_use = FALSE + // If the module allows duplicates of itself to exist within the borg. + // one_use technically makes this value not mean anything, maybe could be just one variable with flags? + var/allow_duplicates = FALSE -/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R, user = usr) - if(R.stat == DEAD) +/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/borg, mob/living/user = usr) + if(borg.stat == DEAD) to_chat(user, span_warning("[src] will not function on a deceased cyborg!")) return FALSE - if(model_type && !is_type_in_list(R.model, model_type)) - to_chat(R, span_alert("Upgrade mounting error! No suitable hardpoint detected.")) + if(model_type && !is_type_in_list(borg.model, model_type)) + to_chat(borg, span_alert("Upgrade mounting error! No suitable hardpoint detected.")) to_chat(user, span_warning("There's no mounting point for the module!")) return FALSE + if(!allow_duplicates && (locate(type) in borg.contents)) + to_chat(borg, span_alert("Upgrade mounting error! Hardpoint already occupied!")) + to_chat(user, span_warning("The mounting point for the module is already occupied!")) + return FALSE + // Handles adding/removing items. + if(length(items_to_add)) + install_items(borg, user, items_to_add) + if(length(items_to_remove)) + remove_items(borg, user, items_to_remove) return TRUE -/obj/item/borg/upgrade/proc/deactivate(mob/living/silicon/robot/R, user = usr) - if (!(src in R.upgrades)) +/obj/item/borg/upgrade/proc/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) + if (!(src in borg.upgrades)) return FALSE + + // Handles reverting the items back + if(length(items_to_add)) + remove_items(borg, user, items_to_add) + if(length(items_to_remove)) + install_items(borg, user, items_to_remove) + return TRUE + +// Handles adding items with the module +/obj/item/borg/upgrade/proc/install_items(mob/living/silicon/robot/borg, mob/living/user = usr, list/items) + for(var/item_to_add in items) + var/obj/item/module_item = new item_to_add(borg.model.modules) + borg.model.basic_modules += module_item + borg.model.add_module(module_item, FALSE, TRUE) + return TRUE + +// Handles removing some items as the module is installed +/obj/item/borg/upgrade/proc/remove_items(mob/living/silicon/robot/borg, mob/living/user = usr, list/items) + for(var/item_to_remove in items) + var/obj/item/module_item = locate(item_to_remove) in borg.model.modules + if (module_item) + borg.model.remove_module(module_item, TRUE) return TRUE /obj/item/borg/upgrade/rename @@ -43,16 +81,17 @@ heldname = sanitize_name(tgui_input_text(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN), allow_numbers = TRUE) user.log_message("set \"[heldname]\" as a name in a cyborg reclassification board at [loc_name(user)]", LOG_GAME) -/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - var/oldname = R.real_name - var/oldkeyname = key_name(R) - R.custom_name = heldname - R.updatename() - if(oldname == R.real_name) - R.notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, R.real_name) - usr.log_message("used a cyborg reclassification board to rename [oldkeyname] to [key_name(R)]", LOG_GAME) + if(!.) + return . + var/oldname = borg.real_name + var/oldkeyname = key_name(borg) + borg.custom_name = heldname + borg.updatename() + if(oldname == borg.real_name) + borg.notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, borg.real_name) + user.log_message("used a cyborg reclassification board to rename [oldkeyname] to [key_name(borg)]", LOG_GAME) /obj/item/borg/upgrade/disablercooler name = "cyborg rapid disabler cooling module" @@ -61,50 +100,57 @@ require_model = TRUE model_type = list(/obj/item/robot_model/security) model_flags = BORG_MODEL_SECURITY + // We handle this in a custom way + allow_duplicates = TRUE -/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.model.modules - if(!T) - to_chat(user, span_warning("There's no disabler in this unit!")) - return FALSE - if(T.charge_delay <= 2) - to_chat(R, span_warning("A cooling unit is already installed!")) - to_chat(user, span_warning("There's no room for another cooling unit!")) - return FALSE + if(!.) + return . - T.charge_delay = max(2 , T.charge_delay - 4) + var/obj/item/gun/energy/disabler/cyborg/disabler = locate() in borg.model.modules + if(isnull(disabler)) + to_chat(user, span_warning("There's no disabler in this unit!")) + return FALSE + if(disabler.charge_delay <= 2) + to_chat(borg, span_warning("A cooling unit is already installed!")) + to_chat(user, span_warning("There's no room for another cooling unit!")) + return FALSE + + disabler.charge_delay = max(2 , disabler.charge_delay - 4) -/obj/item/borg/upgrade/disablercooler/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/disablercooler/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.model.modules - if(!T) - return FALSE - T.charge_delay = initial(T.charge_delay) + if(!.) + return . + var/obj/item/gun/energy/disabler/cyborg/disabler = locate() in borg.model.modules + if(isnull(disabler)) + return FALSE + disabler.charge_delay = initial(disabler.charge_delay) /obj/item/borg/upgrade/thrusters name = "ion thruster upgrade" desc = "An energy-operated thruster system for cyborgs." icon_state = "cyborg_upgrade3" -/obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - if(R.ionpulse) - to_chat(user, span_warning("This unit already has ion thrusters installed!")) - return FALSE + if(!.) + return . + if(borg.ionpulse) + to_chat(user, span_warning("This unit already has ion thrusters installed!")) + return FALSE - R.ionpulse = TRUE - R.toggle_ionpulse() //Enabled by default + borg.ionpulse = TRUE + borg.toggle_ionpulse() //Enabled by default -/obj/item/borg/upgrade/thrusters/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/thrusters/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - R.ionpulse = FALSE + if(!.) + return . + borg.ionpulse = FALSE -/obj/item/borg/upgrade/ddrill +/obj/item/borg/upgrade/diamond_drill name = "mining cyborg diamond drill" desc = "A diamond drill replacement for the mining model's standard drill." icon_state = "cyborg_upgrade3" @@ -112,30 +158,8 @@ model_type = list(/obj/item/robot_model/miner) model_flags = BORG_MODEL_MINER -/obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - for(var/obj/item/pickaxe/drill/cyborg/D in R.model) - R.model.remove_module(D, TRUE) - for(var/obj/item/shovel/S in R.model) - R.model.remove_module(S, TRUE) - - var/obj/item/pickaxe/drill/cyborg/diamond/DD = new /obj/item/pickaxe/drill/cyborg/diamond(R.model) - R.model.basic_modules += DD - R.model.add_module(DD, FALSE, TRUE) - -/obj/item/borg/upgrade/ddrill/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - for(var/obj/item/pickaxe/drill/cyborg/diamond/DD in R.model) - R.model.remove_module(DD, TRUE) - - var/obj/item/pickaxe/drill/cyborg/D = new (R.model) - R.model.basic_modules += D - R.model.add_module(D, FALSE, TRUE) - var/obj/item/shovel/S = new (R.model) - R.model.basic_modules += S - R.model.add_module(S, FALSE, TRUE) + items_to_add = list(/obj/item/pickaxe/drill/cyborg/diamond) + items_to_remove = list(/obj/item/pickaxe/drill/cyborg, /obj/item/shovel) /obj/item/borg/upgrade/soh name = "mining cyborg satchel of holding" @@ -145,25 +169,8 @@ model_type = list(/obj/item/robot_model/miner) model_flags = BORG_MODEL_MINER -/obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R) - . = ..() - if(.) - for(var/obj/item/storage/bag/ore/cyborg/S in R.model) - R.model.remove_module(S, TRUE) - - var/obj/item/storage/bag/ore/holding/H = new /obj/item/storage/bag/ore/holding(R.model) - R.model.basic_modules += H - R.model.add_module(H, FALSE, TRUE) - -/obj/item/borg/upgrade/soh/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - for(var/obj/item/storage/bag/ore/holding/H in R.model) - R.model.remove_module(H, TRUE) - - var/obj/item/storage/bag/ore/cyborg/S = new (R.model) - R.model.basic_modules += S - R.model.add_module(S, FALSE, TRUE) + items_to_add = list(/obj/item/storage/bag/ore/holding) + items_to_remove = list(/obj/item/storage/bag/ore/cyborg) /obj/item/borg/upgrade/tboh name = "janitor cyborg trash bag of holding" @@ -173,25 +180,8 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR -/obj/item/borg/upgrade/tboh/action(mob/living/silicon/robot/R) - . = ..() - if(.) - for(var/obj/item/storage/bag/trash/cyborg/TB in R.model.modules) - R.model.remove_module(TB, TRUE) - - var/obj/item/storage/bag/trash/bluespace/cyborg/B = new /obj/item/storage/bag/trash/bluespace/cyborg(R.model) - R.model.basic_modules += B - R.model.add_module(B, FALSE, TRUE) - -/obj/item/borg/upgrade/tboh/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - for(var/obj/item/storage/bag/trash/bluespace/cyborg/B in R.model.modules) - R.model.remove_module(B, TRUE) - - var/obj/item/storage/bag/trash/cyborg/TB = new (R.model) - R.model.basic_modules += TB - R.model.add_module(TB, FALSE, TRUE) + items_to_add = list(/obj/item/storage/bag/trash/bluespace/cyborg) + items_to_remove = list(/obj/item/storage/bag/trash/cyborg) /obj/item/borg/upgrade/amop name = "janitor cyborg advanced mop" @@ -201,25 +191,8 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR -/obj/item/borg/upgrade/amop/action(mob/living/silicon/robot/R) - . = ..() - if(.) - for(var/obj/item/mop/cyborg/M in R.model.modules) - R.model.remove_module(M, TRUE) - - var/obj/item/mop/advanced/cyborg/mop = new /obj/item/mop/advanced/cyborg(R.model) - R.model.basic_modules += mop - R.model.add_module(mop, FALSE, TRUE) - -/obj/item/borg/upgrade/amop/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - for(var/obj/item/mop/advanced/cyborg/A in R.model.modules) - R.model.remove_module(A, TRUE) - - var/obj/item/mop/cyborg/M = new (R.model) - R.model.basic_modules += M - R.model.add_module(M, FALSE, TRUE) + items_to_add = list(/obj/item/mop/advanced/cyborg) + items_to_remove = list(/obj/item/mop/cyborg) /obj/item/borg/upgrade/prt name = "janitor cyborg plating repair tool" @@ -229,18 +202,7 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR -/obj/item/borg/upgrade/prt/action(mob/living/silicon/robot/R) - . = ..() - if(.) - var/obj/item/cautery/prt/P = new (R.model) - R.model.basic_modules += P - R.model.add_module(P, FALSE, TRUE) - -/obj/item/borg/upgrade/prt/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - for(var/obj/item/cautery/prt/P in R.model.modules) - R.model.remove_module(P, TRUE) + items_to_add = list(/obj/item/cautery/prt) /obj/item/borg/upgrade/syndicate name = "illegal equipment module" @@ -248,22 +210,24 @@ icon_state = "cyborg_upgrade3" require_model = TRUE -/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - if(R.emagged) - return FALSE + if(!.) + return . + if(borg.emagged) + return FALSE - R.SetEmagged(TRUE) - R.logevent("WARN: hardware installed with missing security certificate!") //A bit of fluff to hint it was an illegal tech item - R.logevent("WARN: root privleges granted to PID [num2hex(rand(1,65535), -1)][num2hex(rand(1,65535), -1)].") //random eight digit hex value. Two are used because rand(1,4294967295) throws an error + borg.SetEmagged(TRUE) + borg.logevent("WARN: hardware installed with missing security certificate!") //A bit of fluff to hint it was an illegal tech item + borg.logevent("WARN: root privleges granted to PID [num2hex(rand(1,65535), -1)][num2hex(rand(1,65535), -1)].") //random eight digit hex value. Two are used because rand(1,4294967295) throws an error - return TRUE + return TRUE -/obj/item/borg/upgrade/syndicate/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/syndicate/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - R.SetEmagged(FALSE) + if(!.) + return . + borg.SetEmagged(FALSE) /obj/item/borg/upgrade/lavaproof name = "mining cyborg lavaproof chassis" @@ -274,15 +238,17 @@ model_type = list(/obj/item/robot_model/miner) model_flags = BORG_MODEL_MINER -/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - R.add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) + if(!.) + return . + borg.add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) -/obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - R.remove_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) + if(!.) + return . + borg.remove_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) /obj/item/borg/upgrade/selfrepair name = "self-repair module" @@ -298,24 +264,21 @@ var/powercost = 10 var/datum/action/toggle_action -/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - var/obj/item/borg/upgrade/selfrepair/U = locate() in R - if(U) - to_chat(user, span_warning("This unit is already equipped with a self-repair module!")) - return FALSE - - icon_state = "selfrepair_off" - toggle_action = new /datum/action/item_action/toggle(src) - toggle_action.Grant(R) + if(!.) + return . + icon_state = "selfrepair_off" + toggle_action = new /datum/action/item_action/toggle(src) + toggle_action.Grant(borg) -/obj/item/borg/upgrade/selfrepair/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/selfrepair/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - toggle_action.Remove(R) - QDEL_NULL(toggle_action) - deactivate_sr() + if(!.) + return . + toggle_action.Remove(borg) + QDEL_NULL(toggle_action) + deactivate_sr() /obj/item/borg/upgrade/selfrepair/ui_action_click() if(on) @@ -396,17 +359,19 @@ model_flags = BORG_MODEL_MEDICAL var/list/additional_reagents = list() -/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - for(var/obj/item/reagent_containers/borghypo/medical/H in R.model.modules) - H.upgrade_hypo() + if(!.) + return . + for(var/obj/item/reagent_containers/borghypo/medical/hypo in borg.model.modules) + hypo.upgrade_hypo() -/obj/item/borg/upgrade/hypospray/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/hypospray/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - for(var/obj/item/reagent_containers/borghypo/medical/H in R.model.modules) - H.remove_hypo_upgrade() + if(!.) + return . + for(var/obj/item/reagent_containers/borghypo/medical/hypo in borg.model.modules) + hypo.remove_hypo_upgrade() /obj/item/borg/upgrade/hypospray/expanded name = "medical cyborg expanded hypospray" @@ -419,22 +384,84 @@ pierce armor and thick material." icon_state = "cyborg_upgrade3" -/obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - var/found_hypo = FALSE - for(var/obj/item/reagent_containers/borghypo/H in R.model.modules) - H.bypass_protection = TRUE - found_hypo = TRUE + if(!.) + return . + var/found_hypo = FALSE + for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.modules) + hypo.bypass_protection = TRUE + found_hypo = TRUE + for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.emag_modules) + hypo.bypass_protection = TRUE + found_hypo = TRUE + + if(!found_hypo) + to_chat(user, span_warning("This unit is already equipped with a piercing hypospray upgrade!")) //check to see if we already have this module + return FALSE - if(!found_hypo) +/obj/item/borg/upgrade/piercing_hypospray/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) + . = ..() + if(!.) + return . + for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.modules) + hypo.bypass_protection = initial(hypo.bypass_protection) + for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.emag_modules) + hypo.bypass_protection = initial(hypo.bypass_protection) + +/obj/item/borg/upgrade/surgery_omnitool + name = "cyborg surgical omni-tool upgrade" + desc = "An upgrade to the Medical model, upgrading the built-in \ + surgical omnitool, to be on par with advanced surgical tools" + icon_state = "cyborg_upgrade3" + require_model = TRUE + model_type = list(/obj/item/robot_model/medical, /obj/item/robot_model/syndicate_medical) + model_flags = BORG_MODEL_MEDICAL + +/obj/item/borg/upgrade/surgery_omnitool/action(mob/living/silicon/robot/cyborg, mob/living/user = usr) + . = ..() + if(!.) + return . + for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) + if(omnitool_upgrade.upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) + omnitool.upgrade_omnitool() + +/obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) + . = ..() + if(!.) + return . + for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + omnitool.downgrade_omnitool() + +/obj/item/borg/upgrade/engineering_omnitool + name = "cyborg engineering omni-tool upgrade" + desc = "An upgrade to the Engineering model, upgrading the built-in \ + engineering omnitool, to be on par with advanced engineering tools" + icon_state = "cyborg_upgrade3" + require_model = TRUE + model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) + model_flags = BORG_MODEL_ENGINEERING + +/obj/item/borg/upgrade/engineering_omnitool/action(mob/living/silicon/robot/cyborg, mob/living/user = usr) + . = ..() + if(!.) + return . + for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules) + if(omnitool_upgrade.upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) return FALSE + for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) + omnitool.upgrade_omnitool() -/obj/item/borg/upgrade/piercing_hypospray/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() - if (.) - for(var/obj/item/reagent_containers/borghypo/H in R.model.modules) - H.bypass_protection = initial(H.bypass_protection) + if(!.) + return . + for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + omnitool.downgrade_omnitool() /obj/item/borg/upgrade/defib name = "medical cyborg defibrillator" @@ -445,37 +472,31 @@ model_type = list(/obj/item/robot_model/medical) model_flags = BORG_MODEL_MEDICAL -/obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - var/obj/item/borg/upgrade/defib/backpack/BP = locate() in R //If a full defib unit was used to upgrade prior, we can just pop it out now and replace - if(BP) - BP.deactivate(R, user) - to_chat(user, span_notice("You remove the defibrillator unit to make room for the compact upgrade.")) - var/obj/item/shockpaddles/cyborg/S = new(R.model) - R.model.basic_modules += S - R.model.add_module(S, FALSE, TRUE) - -/obj/item/borg/upgrade/defib/deactivate(mob/living/silicon/robot/R, user = usr) + items_to_add = list(/obj/item/shockpaddles/cyborg) + +/obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - var/obj/item/shockpaddles/cyborg/S = locate() in R.model - R.model.remove_module(S, TRUE) + if(!.) + return . + var/obj/item/borg/upgrade/defib/backpack/defib_pack = locate() in borg //If a full defib unit was used to upgrade prior, we can just pop it out now and replace + if(defib_pack) + defib_pack.deactivate(borg, user) + to_chat(user, span_notice("The defibrillator pops out of the chassis as the compact upgrade installs.")) ///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) +/obj/item/borg/upgrade/defib/backpack/Initialize(mapload, obj/item/defibrillator/defib) . = ..() - if(!D) - D = new /obj/item/defibrillator - defib_instance = D + if(isnull(defib)) + defib = new /obj/item/defibrillator + defib_instance = defib name = defib_instance.name defib_instance.moveToNullspace() RegisterSignals(defib_instance, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(on_defib_instance_qdel_or_moved)) -/obj/item/borg/upgrade/defib/backpack/proc/on_defib_instance_qdel_or_moved(obj/item/defibrillator/D) +/obj/item/borg/upgrade/defib/backpack/proc/on_defib_instance_qdel_or_moved(obj/item/defibrillator/defib) SIGNAL_HANDLER defib_instance = null if(!QDELETED(src)) @@ -486,10 +507,11 @@ QDEL_NULL(defib_instance) return ..() -/obj/item/borg/upgrade/defib/backpack/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/defib/backpack/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - defib_instance?.forceMove(R.drop_location()) // [on_defib_instance_qdel_or_moved()] handles the rest. + if(!.) + return . + defib_instance?.forceMove(borg.drop_location()) // [on_defib_instance_qdel_or_moved()] handles the rest. /obj/item/borg/upgrade/processor name = "medical cyborg surgical processor" @@ -501,81 +523,70 @@ model_type = list(/obj/item/robot_model/medical, /obj/item/robot_model/syndicate_medical) model_flags = BORG_MODEL_MEDICAL -/obj/item/borg/upgrade/processor/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - var/obj/item/surgical_processor/SP = new(R.model) - R.model.basic_modules += SP - R.model.add_module(SP, FALSE, TRUE) - -/obj/item/borg/upgrade/processor/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - var/obj/item/surgical_processor/SP = locate() in R.model - R.model.remove_module(SP, TRUE) + items_to_add = list(/obj/item/surgical_processor) /obj/item/borg/upgrade/ai name = "B.O.R.I.S. module" desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI." icon_state = "boris" -/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - 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. - to_chat(user, span_warning("Intelligence patterns detected in this [R.braintype]. Aborting.")) - return FALSE + if(!.) + return . + if(borg.key) //You cannot replace a player unless the key is completely removed. + to_chat(user, span_warning("Intelligence patterns detected in this [borg.braintype]. Aborting.")) + return FALSE - R.make_shell(src) + borg.make_shell(src) -/obj/item/borg/upgrade/ai/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/ai/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - if(R.shell) - R.undeploy() - R.notify_ai(AI_NOTIFICATION_AI_SHELL) + if(!. || !borg.shell) + return . + + borg.undeploy() + borg.notify_ai(AI_NOTIFICATION_AI_SHELL) /obj/item/borg/upgrade/expand name = "borg expander" desc = "A cyborg resizer, it makes a cyborg huge." icon_state = "cyborg_upgrade3" -/obj/item/borg/upgrade/expand/action(mob/living/silicon/robot/robot, user = usr) +/obj/item/borg/upgrade/expand/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(!. || HAS_TRAIT(robot, TRAIT_NO_TRANSFORM)) + if(!. || HAS_TRAIT(borg, TRAIT_NO_TRANSFORM)) return FALSE - if(robot.hasExpanded) + if(borg.hasExpanded) to_chat(usr, span_warning("This unit already has an expand module installed!")) return FALSE - ADD_TRAIT(robot, TRAIT_NO_TRANSFORM, REF(src)) - var/prev_lockcharge = robot.lockcharge - robot.SetLockdown(TRUE) - robot.set_anchored(TRUE) + ADD_TRAIT(borg, TRAIT_NO_TRANSFORM, REF(src)) + var/prev_lockcharge = borg.lockcharge + borg.SetLockdown(TRUE) + borg.set_anchored(TRUE) var/datum/effect_system/fluid_spread/smoke/smoke = new - smoke.set_up(1, holder = robot, location = robot.loc) + smoke.set_up(1, holder = borg, location = borg.loc) smoke.start() sleep(0.2 SECONDS) for(var/i in 1 to 4) - playsound(robot, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, TRUE, -1) + playsound(borg, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, TRUE, -1) sleep(1.2 SECONDS) if(!prev_lockcharge) - robot.SetLockdown(FALSE) - robot.set_anchored(FALSE) - REMOVE_TRAIT(robot, TRAIT_NO_TRANSFORM, REF(src)) - robot.hasExpanded = TRUE - robot.update_transform(2) + borg.SetLockdown(FALSE) + borg.set_anchored(FALSE) + REMOVE_TRAIT(borg, TRAIT_NO_TRANSFORM, REF(src)) + borg.hasExpanded = TRUE + borg.update_transform(2) -/obj/item/borg/upgrade/expand/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/expand/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - if (R.hasExpanded) - R.hasExpanded = FALSE - R.update_transform(0.5) + if(!.) + return . + if (borg.hasExpanded) + borg.hasExpanded = FALSE + borg.update_transform(0.5) /obj/item/borg/upgrade/rped name = "engineering cyborg RPED" @@ -586,24 +597,7 @@ model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) model_flags = BORG_MODEL_ENGINEERING -/obj/item/borg/upgrade/rped/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - var/obj/item/storage/part_replacer/cyborg/RPED = locate() in R - if(RPED) - to_chat(user, span_warning("This unit is already equipped with a RPED module!")) - return FALSE - - RPED = new(R.model) - R.model.basic_modules += RPED - R.model.add_module(RPED, FALSE, TRUE) - -/obj/item/borg/upgrade/rped/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - var/obj/item/storage/part_replacer/cyborg/RPED = locate() in R.model - if (RPED) - R.model.remove_module(RPED, TRUE) + items_to_add = list(/obj/item/storage/part_replacer/cyborg) /obj/item/borg/upgrade/inducer name = "engineering integrated power inducer" @@ -612,24 +606,7 @@ model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) model_flags = BORG_MODEL_ENGINEERING -/obj/item/borg/upgrade/inducer/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - var/obj/item/inducer/cyborg/inter_inducer = locate() in R - if(inter_inducer) - return FALSE - inter_inducer = new(R.model) - R.model.basic_modules += inter_inducer - R.model.add_module(inter_inducer, FALSE, TRUE) - inter_inducer.cell = R.cell - -/obj/item/borg/upgrade/inducer/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - var/obj/item/inducer/cyborg/inter_inducer = locate() in R.model - if (inter_inducer) - R.model.remove_module(inter_inducer, TRUE) - inter_inducer.cell = null + items_to_add = list(/obj/item/inducer/cyborg) /obj/item/inducer/cyborg name = "Internal inducer" @@ -645,39 +622,32 @@ require_model = TRUE model_type = list(/obj/item/robot_model/medical, /obj/item/robot_model/syndicate_medical) model_flags = BORG_MODEL_MEDICAL + + items_to_add = list(/obj/item/pinpointer/crew) var/datum/action/crew_monitor -/obj/item/borg/upgrade/pinpointer/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/pinpointer/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if(.) - - var/obj/item/pinpointer/crew/PP = locate() in R.model - if(PP) - to_chat(user, span_warning("This unit is already equipped with a pinpointer module!")) - return FALSE - - PP = new(R.model) - R.model.basic_modules += PP - R.model.add_module(PP, FALSE, TRUE) - crew_monitor = new /datum/action/item_action/crew_monitor(src) - crew_monitor.Grant(R) - icon_state = "scanner" + if(!.) + return . + crew_monitor = new /datum/action/item_action/crew_monitor(src) + crew_monitor.Grant(borg) + icon_state = "scanner" -/obj/item/borg/upgrade/pinpointer/deactivate(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/pinpointer/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() - if (.) - icon_state = "pinpointer_crew" - crew_monitor.Remove(R) - QDEL_NULL(crew_monitor) - var/obj/item/pinpointer/crew/PP = locate() in R.model - R.model.remove_module(PP, TRUE) + if(!.) + return . + icon_state = "pinpointer_crew" + crew_monitor.Remove(borg) + QDEL_NULL(crew_monitor) /obj/item/borg/upgrade/pinpointer/ui_action_click() if(..()) return - var/mob/living/silicon/robot/Cyborg = usr - GLOB.crewmonitor.show(Cyborg,Cyborg) + var/mob/living/silicon/robot/borg = usr + GLOB.crewmonitor.show(borg,borg) /datum/action/item_action/crew_monitor name = "Interface With Crew Monitor" @@ -688,10 +658,10 @@ icon_state = "cyborg_upgrade3" var/obj/item/robot_model/new_model = null -/obj/item/borg/upgrade/transform/action(mob/living/silicon/robot/R, user = usr) +/obj/item/borg/upgrade/transform/action(mob/living/silicon/robot/borg, mob/living/user = usr) . = ..() if(. && new_model) - R.model.transform_to(new_model) + borg.model.transform_to(new_model) /obj/item/borg/upgrade/transform/clown name = "borg model picker (Clown)" @@ -707,24 +677,7 @@ model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) model_flags = BORG_MODEL_ENGINEERING -/obj/item/borg/upgrade/circuit_app/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - var/obj/item/borg/apparatus/circuit/C = locate() in R.model.modules - if(C) - to_chat(user, span_warning("This unit is already equipped with a circuit apparatus!")) - return FALSE - - C = new(R.model) - R.model.basic_modules += C - R.model.add_module(C, FALSE, TRUE) - -/obj/item/borg/upgrade/circuit_app/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - var/obj/item/borg/apparatus/circuit/C = locate() in R.model.modules - if (C) - R.model.remove_module(C, TRUE) + items_to_add = list(/obj/item/borg/apparatus/circuit) /obj/item/borg/upgrade/beaker_app name = "beaker storage apparatus" @@ -734,24 +687,7 @@ model_type = list(/obj/item/robot_model/medical) model_flags = BORG_MODEL_MEDICAL -/obj/item/borg/upgrade/beaker_app/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - var/obj/item/borg/apparatus/beaker/extra/E = locate() in R.model.modules - if(E) - to_chat(user, span_warning("This unit has no room for additional beaker storage!")) - return FALSE - - E = new(R.model) - R.model.basic_modules += E - R.model.add_module(E, FALSE, TRUE) - -/obj/item/borg/upgrade/beaker_app/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - var/obj/item/borg/apparatus/beaker/extra/E = locate() in R.model.modules - if (E) - R.model.remove_module(E, TRUE) + items_to_add = list(/obj/item/borg/apparatus/beaker/extra) /obj/item/borg/upgrade/drink_app name = "glass storage apparatus" @@ -761,24 +697,7 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE -/obj/item/borg/upgrade/drink_app/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - var/obj/item/borg/apparatus/beaker/drink/E = locate() in R.model.modules - if(E) - to_chat(user, span_warning("This unit has no room for additional drink storage!")) - return FALSE - - E = new(R.model) - R.model.basic_modules += E - R.model.add_module(E, FALSE, TRUE) - -/obj/item/borg/upgrade/drink_app/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - var/obj/item/borg/apparatus/beaker/drink/E = locate() in R.model.modules - if (E) - R.model.remove_module(E, TRUE) + items_to_add = list(/obj/item/borg/apparatus/beaker/drink) /obj/item/borg/upgrade/broomer name = "experimental push broom" @@ -788,25 +707,7 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR -/obj/item/borg/upgrade/broomer/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if (!.) - return - var/obj/item/pushbroom/cyborg/BR = locate() in R.model.modules - if (BR) - to_chat(user, span_warning("This janiborg is already equipped with an experimental broom!")) - return FALSE - BR = new(R.model) - R.model.basic_modules += BR - R.model.add_module(BR, FALSE, TRUE) - -/obj/item/borg/upgrade/broomer/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (!.) - return - var/obj/item/pushbroom/cyborg/BR = locate() in R.model.modules - if (BR) - R.model.remove_module(BR, TRUE) + items_to_add = list(/obj/item/pushbroom/cyborg) /obj/item/borg/upgrade/condiment_synthesizer name = "Service Cyborg Condiment Synthesiser" @@ -816,25 +717,7 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE -/obj/item/borg/upgrade/condiment_synthesizer/action(mob/living/silicon/robot/install, user = usr) - . = ..() - if(!.) - return FALSE - var/obj/item/reagent_containers/borghypo/condiment_synthesizer/cynthesizer = locate() in install.model.modules - if(cynthesizer) - install.balloon_alert_to_viewers("already installed!") - return FALSE - cynthesizer = new(install.model) - install.model.basic_modules += cynthesizer - install.model.add_module(cynthesizer, FALSE, TRUE) - -/obj/item/borg/upgrade/condiment_synthesizer/deactivate(mob/living/silicon/robot/install, user = usr) - . = ..() - if (!.) - return FALSE - var/obj/item/reagent_containers/borghypo/condiment_synthesizer/cynthesizer = locate() in install.model.modules - if (cynthesizer) - install.model.remove_module(cynthesizer, TRUE) + items_to_add = list(/obj/item/reagent_containers/borghypo/condiment_synthesizer) /obj/item/borg/upgrade/silicon_knife name = "Service Cyborg Kitchen Toolset" @@ -844,25 +727,7 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE -/obj/item/borg/upgrade/silicon_knife/action(mob/living/silicon/robot/install, user = usr) - . = ..() - if(!.) - return FALSE - var/obj/item/knife/kitchen/silicon/snife = locate() in install.model.modules - if(snife) - install.balloon_alert_to_viewers("already installed!") - return FALSE - snife = new(install.model) - install.model.basic_modules += snife - install.model.add_module(snife, FALSE, TRUE) - -/obj/item/borg/upgrade/silicon_knife/deactivate(mob/living/silicon/robot/install, user = usr) - . = ..() - if (!.) - return FALSE - var/obj/item/knife/kitchen/silicon/snife = locate() in install.model.modules - if (snife) - install.model.remove_module(snife, TRUE) + items_to_add = list(/obj/item/knife/kitchen/silicon) /obj/item/borg/upgrade/service_apparatus name = "Service Cyborg Service Apparatus" @@ -872,54 +737,16 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE -/obj/item/borg/upgrade/service_apparatus/action(mob/living/silicon/robot/install, user = usr) - . = ..() - if(!.) - return FALSE - var/obj/item/borg/apparatus/service/saparatus = locate() in install.model.modules - if(saparatus) - install.balloon_alert_to_viewers("already installed!") - return FALSE - saparatus = new(install.model) - install.model.basic_modules += saparatus - install.model.add_module(saparatus, FALSE, TRUE) - -/obj/item/borg/upgrade/service_apparatus/deactivate(mob/living/silicon/robot/install, user = usr) - . = ..() - if (!.) - return FALSE - var/obj/item/borg/apparatus/service/saparatus = locate() in install.model.modules - if (saparatus) - install.model.remove_module(saparatus, TRUE) + items_to_add = list(/obj/item/borg/apparatus/service) /obj/item/borg/upgrade/rolling_table name = "Service Cyborg Rolling Table Dock" desc = "An upgrade to the service model cyborg, to help provide mobile service." icon_state = "cyborg_upgrade3" require_model = TRUE - model_type = list(/obj/item/robot_model/service) + model_type = list(/obj/item/rolling_table_dock) model_flags = BORG_MODEL_SERVICE -/obj/item/borg/upgrade/rolling_table/action(mob/living/silicon/robot/install, user = usr) - . = ..() - if(!.) - return FALSE - var/obj/item/rolling_table_dock/rtable = locate() in install.model.modules - if(rtable) - install.balloon_alert_to_viewers("already installed!") - return FALSE - rtable = new(install.model) - install.model.basic_modules += rtable - install.model.add_module(rtable, FALSE, TRUE) - -/obj/item/borg/upgrade/rolling_table/deactivate(mob/living/silicon/robot/install, user = usr) - . = ..() - if (!.) - return FALSE - var/obj/item/rolling_table_dock/rtable = locate() in install.model.modules - if (rtable) - install.model.remove_module(rtable, TRUE) - /obj/item/borg/upgrade/service_cookbook name = "Service Cyborg Cookbook" desc = "An upgrade to the service model cyborg, that lets them create more foods." @@ -928,25 +755,7 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE -/obj/item/borg/upgrade/service_cookbook/action(mob/living/silicon/robot/install, user = usr) - . = ..() - if(!.) - return FALSE - var/obj/item/borg/cookbook/book = locate() in install.model.modules - if(book) - install.balloon_alert_to_viewers("already installed!") - return FALSE - book = new(install.model) - install.model.basic_modules += book - install.model.add_module(book, FALSE, TRUE) - -/obj/item/borg/upgrade/service_cookbook/deactivate(mob/living/silicon/robot/install, user = usr) - . = ..() - if (!.) - return FALSE - var/obj/item/borg/cookbook/book = locate() in install.model.modules - if(book) - install.model.remove_module(book, TRUE) + model_type = list(/obj/item/borg/cookbook) ///This isn't an upgrade or part of the same path, but I'm gonna just stick it here because it's a tool used on cyborgs. //A reusable tool that can bring borgs back to life. They gotta be repaired first, though. diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index cb45306702c5..c3e384dcb70c 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1260,7 +1260,7 @@ name = "Diamond Drill" id = "borg_upgrade_diamonddrill" build_type = MECHFAB - build_path = /obj/item/borg/upgrade/ddrill + build_path = /obj/item/borg/upgrade/diamond_drill materials = list( /datum/material/iron=SHEET_MATERIAL_AMOUNT*5, /datum/material/glass =SHEET_MATERIAL_AMOUNT*3, From 725f66f75fa7b9c18359e953f56a5a8abf1a6430 Mon Sep 17 00:00:00 2001 From: zxaber <37497534+zxaber@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:32:51 -0700 Subject: [PATCH 04/13] Cyborg Omnitool Refactor (#83880) - Complete rewrite of borg omnitool code; - - Borgs that use omnitools now have a "Omni Toolbox" that holds whatever tools the Omnitool would cover. The toolbox keeps track of Omnitool "Arms" in a list, as well as when to upgrade (or downgrade) tool speed. The toolbox is not seen by the player directly. - - Omnitool "Arms" will display available tools based on the Omni Toolbox's contents. Selecting one does not move the tool out of the toolbox, but instead simply overrides any following clicks with a melee attack chain of the selected item. This is reminiscent of how borg apparatus tools work. When selecting a tool, the Omnitool "arm" will also set its own icon state to match the tool selected. - - Because all Omnitool "arms" are using the same tools from the same toolbox, actions done with one can be seen from another. For example, using the first Omnitool to scan the Silo with the engineer borg's multitool will update the tool's buffer, and it can be used later, even if the multitool is selected by the second Omnitool. - Because we're now using real tools, rather than a single tool item faking tool usage via tool flags, almost all interactions with tools should properly carry over. - Added Cyborg versions of the medical toolset, for use with the Medical Cyborg omnitool, so that we can finally use the really nice borg-version medical tool sprites. Easier to read code. Fixes #83667 Fixes #83537 Fixes #83077 Fixes #82918 partially; Heating beakers works, but the tile quick-swap function will not function; the action is initiated by a click from the tile stack rather than the crowbar. :cl: fix: Refactored borg omnitool code, fixing most of the unique interaction issues. /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/datums/components/surgery_initiator.dm | 7 +- .../telecomms/machine_interactions.dm | 7 +- code/game/objects/items/robot/items/tools.dm | 140 ++++++++++++++++++ .../objects/items/robot/robot_upgrades.dm | 28 ++-- .../mob/living/silicon/robot/robot_model.dm | 33 +++-- code/modules/surgery/surgery.dm | 4 + code/modules/surgery/tools.dm | 30 ++++ 7 files changed, 215 insertions(+), 34 deletions(-) diff --git a/code/datums/components/surgery_initiator.dm b/code/datums/components/surgery_initiator.dm index 1cc60d78b555..00dbf6e51c7a 100644 --- a/code/datums/components/surgery_initiator.dm +++ b/code/datums/components/surgery_initiator.dm @@ -134,8 +134,11 @@ required_tool_type = TOOL_SCREWDRIVER if(iscyborg(user)) - close_tool = locate(/obj/item/cautery) in user.held_items - if(!close_tool) + var/has_cautery = FALSE + for(var/obj/item/borg/cyborg_omnitool/toolarm in user.held_items) + if(toolarm.selected && istype(toolarm.selected, /obj/item/cautery)) + has_cautery = TRUE + if(!has_cautery) patient.balloon_alert(user, "need a cautery in an inactive slot to stop the surgery!") return else if(!close_tool || close_tool.tool_behaviour != required_tool_type) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index fe0c2804b28e..9eadec2cb05e 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -255,8 +255,11 @@ var/mob/living/silicon/ai/U = user multitool = U.aiMulti else if(iscyborg(user) && in_range(user, src)) - if(istype(user.get_active_held_item(), /obj/item/multitool)) - multitool = user.get_active_held_item() + var/mob/living/silicon/robot/borguser = user + for(var/obj/item/borg/cyborg_omnitool/toolarm in borguser.held_items) + if(istype(toolarm.selected, /obj/item/multitool)) + multitool = toolarm.selected + break return multitool /obj/machinery/telecomms/proc/canAccess(mob/user) diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm index 773458964f77..5efad83b673b 100644 --- a/code/game/objects/items/robot/items/tools.dm +++ b/code/game/objects/items/robot/items/tools.dm @@ -175,4 +175,144 @@ projectile.speed *= (1 / projectile_speed_coefficient) projectile.cut_overlay(projectile_effect) +////////////////////// +///CYBORG OMNITOOLS/// +////////////////////// + +/** + Onmi Toolboxs act as a cache of tools for a particular borg's omnitools. Not all borg + get a toolbox (as not all borgs use omnitools), and those that do can only have one + toolbox. The toolbox keeps track of a borg's omnitool arms, and handles speed upgrades. + + Omnitools are the actual tool arms for the cyborg to interact with. When attack_self + is called, they can select a tool from the toolbox. The tool is not moved, and instead + only referenced in place of the omnitool's own attacks. The omnitool also takes on + the tool's sprite, which completes the illusion. In this way, multiple tools are + shared between multiple omnitool arms. A multitool's buffer, for example, will not + depend on which omnitool arm was used to set it. +*/ +/obj/item/cyborg_omnitoolbox + name = "broken cyborg toolbox" + desc = "Some internal part of a broken cyborg." + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "lollipop" + toolspeed = 10 + ///List of Omnitool "arms" that the borg has. + var/list/omnitools = list() + ///List of paths for tools. These will be created during Initialize() + var/list/toolpaths = list() + ///Target Toolspeed to set after reciving an omnitool upgrade + var/upgraded_toolspeed = 10 + ///Whether we currently have the upgraded speed + var/currently_upgraded = FALSE + +/obj/item/cyborg_omnitoolbox/Initialize(mapload) + . = ..() + if(!toolpaths.len) + return + + var/obj/item/newitem + for(var/newpath in toolpaths) + newitem = new newpath(src) + newitem.toolspeed = toolspeed //In case thse have different base speeds as stand-alone tools on other borgs + ADD_TRAIT(newitem, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + +/obj/item/cyborg_omnitoolbox/proc/set_upgrade(upgrade = FALSE) + for(var/obj/item/tool in contents) + if(upgrade) + tool.toolspeed = upgraded_toolspeed + else + tool.toolspeed = toolspeed + currently_upgraded = upgrade + +/obj/item/cyborg_omnitoolbox/engineering + toolspeed = 0.5 + upgraded_toolspeed = 0.3 + toolpaths = list( + /obj/item/wrench/cyborg, + /obj/item/wirecutters/cyborg, + /obj/item/screwdriver/cyborg, + /obj/item/crowbar/cyborg, + /obj/item/multitool/cyborg, + ) + +/obj/item/cyborg_omnitoolbox/medical + toolspeed = 1 + upgraded_toolspeed = 0.7 + toolpaths = list( + /obj/item/scalpel/cyborg, + /obj/item/surgicaldrill/cyborg, + /obj/item/hemostat/cyborg, + /obj/item/retractor/cyborg, + /obj/item/cautery/cyborg, + /obj/item/circular_saw/cyborg, + /obj/item/bonesetter/cyborg, + ) + +/obj/item/borg/cyborg_omnitool + name = "broken cyborg tool arm" + desc = "Some internal part of a broken cyborg." + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "lollipop" + ///Ref to the toolbox, since our own loc will be changing + var/obj/item/cyborg_omnitoolbox/toolbox + ///Ref to currently selected tool, if any + var/obj/item/selected + +/obj/item/borg/cyborg_omnitool/Initialize(mapload) + . = ..() + if(!iscyborg(loc.loc)) + return + var/obj/item/robot_model/model = loc + var/obj/item/cyborg_omnitoolbox/chassis_toolbox = model.toolbox + if(!chassis_toolbox) + return + toolbox = chassis_toolbox + toolbox.omnitools += src + +/obj/item/borg/cyborg_omnitool/attack_self(mob/user) + var/list/radial_menu_options = list() + for(var/obj/item/borgtool in toolbox.contents) + radial_menu_options[borgtool] = image(icon = borgtool.icon, icon_state = borgtool.icon_state) + var/obj/item/potential_new_tool = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE) + if(!potential_new_tool) + return ..() + if(potential_new_tool == selected) + return ..() + for(var/obj/item/borg/cyborg_omnitool/coworker in toolbox.omnitools) + if(coworker.selected == potential_new_tool) + coworker.deselect() //Can I borrow that please + break + selected = potential_new_tool + icon_state = selected.icon_state + playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) + return ..() + +/obj/item/borg/cyborg_omnitool/proc/deselect() + if(!selected) + return + selected = null + icon_state = initial(icon_state) + playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) + +/obj/item/borg/cyborg_omnitool/cyborg_unequip() + deselect() + return ..() + +/obj/item/borg/cyborg_omnitool/pre_attack(atom/atom, mob/living/user, params) + if(selected) + selected.melee_attack_chain(user, atom, params) + return TRUE + return ..() + +/obj/item/borg/cyborg_omnitool/engineering + name = "engineering omni-toolset" + desc = "A set of engineering tools used by cyborgs to conduct various engineering tasks." + icon_state = "toolkit_engiborg" + +/obj/item/borg/cyborg_omnitool/medical + name = "surgical omni-toolset" + desc = "A set of surgical tools used by cyborgs to operate on various surgical operations." + icon_state = "toolkit_medborg" + #undef PKBORG_DAMPEN_CYCLE_DELAY diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 11efdc231876..10235dfc5c0a 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -422,19 +422,18 @@ . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) - omnitool.upgrade_omnitool() + if(cyborg.model.toolbox.currently_upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + cyborg.model.toolbox.set_upgrade(TRUE) + ADD_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) /obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) - omnitool.downgrade_omnitool() + cyborg.model.toolbox.set_upgrade(FALSE) + REMOVE_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) /obj/item/borg/upgrade/engineering_omnitool name = "cyborg engineering omni-tool upgrade" @@ -449,19 +448,16 @@ . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) - omnitool.upgrade_omnitool() + if(cyborg.model.toolbox.currently_upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + cyborg.model.toolbox.set_upgrade(TRUE) /obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) - omnitool.downgrade_omnitool() + cyborg.model.toolbox.set_upgrade(FALSE) /obj/item/borg/upgrade/defib name = "medical cyborg defibrillator" diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index 8bd3cb565e39..060568508c12 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -53,9 +53,17 @@ var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3) ///List of skins the borg can be reskinned to, optional var/list/borg_skins + ///Omnitoolbox, holder of certain borg tools. Not all models have one + var/obj/item/cyborg_omnitoolbox/toolbox + ///Path to toolbox, if a model gets one + var/toolbox_path /obj/item/robot_model/Initialize(mapload) . = ..() + + if(toolbox_path) + toolbox = new toolbox_path(src) + for(var/path in basic_modules) var/obj/item/new_module = new path(src) basic_modules += new_module @@ -385,6 +393,7 @@ model_select_icon = "engineer" model_traits = list(TRAIT_NEGATES_GRAVITY) hat_offset = -4 + toolbox_path = /obj/item/cyborg_omnitoolbox/engineering /obj/item/robot_model/janitor name = "Janitor" @@ -655,14 +664,9 @@ /obj/item/borg/apparatus/beaker, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, - /obj/item/surgical_drapes, - /obj/item/retractor, - /obj/item/hemostat, - /obj/item/cautery, - /obj/item/surgicaldrill, - /obj/item/scalpel, - /obj/item/circular_saw, - /obj/item/bonesetter, + /obj/item/borg/cyborg_omnitool/medical, + /obj/item/borg/cyborg_omnitool/medical, + /obj/item/surgical_drapes/cyborg, /obj/item/blood_filter, /obj/item/extinguisher/mini, /obj/item/emergency_bed/silicon, @@ -680,6 +684,7 @@ model_select_icon = "medical" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 + toolbox_path = /obj/item/cyborg_omnitoolbox/medical borg_skins = list( "Machinified Doctor" = list(SKIN_ICON_STATE = "medical"), "Qualified Doctor" = list(SKIN_ICON_STATE = "qualified_doctor"), @@ -865,12 +870,10 @@ /obj/item/reagent_containers/borghypo/syndicate, /obj/item/shockpaddles/syndicate/cyborg, /obj/item/healthanalyzer, - /obj/item/surgical_drapes, - /obj/item/retractor, - /obj/item/hemostat, - /obj/item/cautery, - /obj/item/surgicaldrill, - /obj/item/scalpel, + /obj/item/borg/cyborg_omnitool/medical, + /obj/item/borg/cyborg_omnitool/medical, + /obj/item/surgical_drapes/cyborg, + /obj/item/blood_filter, /obj/item/melee/energy/sword/cyborg/saw, /obj/item/bonesetter, /obj/item/blood_filter, @@ -887,6 +890,7 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 + toolbox_path = /obj/item/cyborg_omnitoolbox/medical /obj/item/robot_model/saboteur name = "Syndicate Saboteur" @@ -919,6 +923,7 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE, TRAIT_NEGATES_GRAVITY) hat_offset = -4 + toolbox_path = /obj/item/cyborg_omnitoolbox/engineering canDispose = TRUE /obj/item/robot_model/syndicate/kiltborg diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 7320e6ed9475..832c0dcd78db 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -119,6 +119,10 @@ if(isnull(step)) return FALSE var/obj/item/tool = user.get_active_held_item() + if(istype(tool, /obj/item/borg/cyborg_omnitool)) //catches borg surgeries + var/obj/item/borg/cyborg_omnitool/toolarm = tool + if(toolarm.selected) + tool = toolarm.selected if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) return TRUE if(tool && tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 66363173e8c3..75702f56c265 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -25,6 +25,9 @@ desc = "Micro-mechanical manipulator for retracting stuff." toolspeed = 0.5 +/obj/item/retractor/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_retractor" /obj/item/hemostat name = "hemostat" @@ -55,6 +58,9 @@ desc = "Tiny servos power a pair of pincers to stop bleeding." toolspeed = 0.5 +/obj/item/hemostat/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_hemostat" /obj/item/cautery name = "cautery" @@ -89,6 +95,10 @@ desc = "A heated element that cauterizes wounds." toolspeed = 0.5 +/obj/item/cautery/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_cautery" + /obj/item/cautery/advanced name = "searing tool" desc = "It projects a high power laser used for medical applications." @@ -179,6 +189,10 @@ playsound(user, 'sound/machines/juicer.ogg', 20, TRUE) return MANUAL_SUICIDE +/obj/item/surgicaldrill/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_drill" + /obj/item/surgicaldrill/augment desc = "Effectively a small power drill contained within your arm. May or may not pierce the heavens." hitsound = 'sound/weapons/circsawhit.ogg' @@ -232,6 +246,10 @@ user.visible_message(span_suicide("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS +/obj/item/scalpel/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_scalpel" + /obj/item/scalpel/augment desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." toolspeed = 0.5 @@ -286,6 +304,10 @@ /obj/item/circular_saw/get_surgery_tool_overlay(tray_extended) return surgical_tray_overlay +/obj/item/circular_saw/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_saw" + /obj/item/circular_saw/augment desc = "A small but very fast spinning saw. It rips and tears until it is done." w_class = WEIGHT_CLASS_SMALL @@ -310,6 +332,10 @@ . = ..() AddComponent(/datum/component/surgery_initiator) +/obj/item/surgical_drapes/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_surgicaldrapes" + /obj/item/surgical_processor //allows medical cyborgs to scan and initiate advanced surgeries name = "surgical processor" desc = "A device for scanning and initiating surgeries from a disk or operating computer." @@ -595,6 +621,10 @@ /obj/item/bonesetter/get_surgery_tool_overlay(tray_extended) return "bonesetter" + (tray_extended ? "" : "_out") +/obj/item/bonesetter/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_bonesetter" + /obj/item/blood_filter name = "blood filter" desc = "For filtering the blood." From 53948665b7557921187427b085d0b84c511a7aa5 Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 00:24:41 +1300 Subject: [PATCH 05/13] Revert "Cyborg Omnitool Refactor (#83880)" This reverts commit 725f66f75fa7b9c18359e953f56a5a8abf1a6430. --- code/datums/components/surgery_initiator.dm | 7 +- .../telecomms/machine_interactions.dm | 7 +- code/game/objects/items/robot/items/tools.dm | 140 ------------------ .../objects/items/robot/robot_upgrades.dm | 28 ++-- .../mob/living/silicon/robot/robot_model.dm | 33 ++--- code/modules/surgery/surgery.dm | 4 - code/modules/surgery/tools.dm | 30 ---- 7 files changed, 34 insertions(+), 215 deletions(-) diff --git a/code/datums/components/surgery_initiator.dm b/code/datums/components/surgery_initiator.dm index 00dbf6e51c7a..1cc60d78b555 100644 --- a/code/datums/components/surgery_initiator.dm +++ b/code/datums/components/surgery_initiator.dm @@ -134,11 +134,8 @@ required_tool_type = TOOL_SCREWDRIVER if(iscyborg(user)) - var/has_cautery = FALSE - for(var/obj/item/borg/cyborg_omnitool/toolarm in user.held_items) - if(toolarm.selected && istype(toolarm.selected, /obj/item/cautery)) - has_cautery = TRUE - if(!has_cautery) + close_tool = locate(/obj/item/cautery) in user.held_items + if(!close_tool) patient.balloon_alert(user, "need a cautery in an inactive slot to stop the surgery!") return else if(!close_tool || close_tool.tool_behaviour != required_tool_type) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 9eadec2cb05e..fe0c2804b28e 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -255,11 +255,8 @@ var/mob/living/silicon/ai/U = user multitool = U.aiMulti else if(iscyborg(user) && in_range(user, src)) - var/mob/living/silicon/robot/borguser = user - for(var/obj/item/borg/cyborg_omnitool/toolarm in borguser.held_items) - if(istype(toolarm.selected, /obj/item/multitool)) - multitool = toolarm.selected - break + if(istype(user.get_active_held_item(), /obj/item/multitool)) + multitool = user.get_active_held_item() return multitool /obj/machinery/telecomms/proc/canAccess(mob/user) diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm index 5efad83b673b..773458964f77 100644 --- a/code/game/objects/items/robot/items/tools.dm +++ b/code/game/objects/items/robot/items/tools.dm @@ -175,144 +175,4 @@ projectile.speed *= (1 / projectile_speed_coefficient) projectile.cut_overlay(projectile_effect) -////////////////////// -///CYBORG OMNITOOLS/// -////////////////////// - -/** - Onmi Toolboxs act as a cache of tools for a particular borg's omnitools. Not all borg - get a toolbox (as not all borgs use omnitools), and those that do can only have one - toolbox. The toolbox keeps track of a borg's omnitool arms, and handles speed upgrades. - - Omnitools are the actual tool arms for the cyborg to interact with. When attack_self - is called, they can select a tool from the toolbox. The tool is not moved, and instead - only referenced in place of the omnitool's own attacks. The omnitool also takes on - the tool's sprite, which completes the illusion. In this way, multiple tools are - shared between multiple omnitool arms. A multitool's buffer, for example, will not - depend on which omnitool arm was used to set it. -*/ -/obj/item/cyborg_omnitoolbox - name = "broken cyborg toolbox" - desc = "Some internal part of a broken cyborg." - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "lollipop" - toolspeed = 10 - ///List of Omnitool "arms" that the borg has. - var/list/omnitools = list() - ///List of paths for tools. These will be created during Initialize() - var/list/toolpaths = list() - ///Target Toolspeed to set after reciving an omnitool upgrade - var/upgraded_toolspeed = 10 - ///Whether we currently have the upgraded speed - var/currently_upgraded = FALSE - -/obj/item/cyborg_omnitoolbox/Initialize(mapload) - . = ..() - if(!toolpaths.len) - return - - var/obj/item/newitem - for(var/newpath in toolpaths) - newitem = new newpath(src) - newitem.toolspeed = toolspeed //In case thse have different base speeds as stand-alone tools on other borgs - ADD_TRAIT(newitem, TRAIT_NODROP, CYBORG_ITEM_TRAIT) - -/obj/item/cyborg_omnitoolbox/proc/set_upgrade(upgrade = FALSE) - for(var/obj/item/tool in contents) - if(upgrade) - tool.toolspeed = upgraded_toolspeed - else - tool.toolspeed = toolspeed - currently_upgraded = upgrade - -/obj/item/cyborg_omnitoolbox/engineering - toolspeed = 0.5 - upgraded_toolspeed = 0.3 - toolpaths = list( - /obj/item/wrench/cyborg, - /obj/item/wirecutters/cyborg, - /obj/item/screwdriver/cyborg, - /obj/item/crowbar/cyborg, - /obj/item/multitool/cyborg, - ) - -/obj/item/cyborg_omnitoolbox/medical - toolspeed = 1 - upgraded_toolspeed = 0.7 - toolpaths = list( - /obj/item/scalpel/cyborg, - /obj/item/surgicaldrill/cyborg, - /obj/item/hemostat/cyborg, - /obj/item/retractor/cyborg, - /obj/item/cautery/cyborg, - /obj/item/circular_saw/cyborg, - /obj/item/bonesetter/cyborg, - ) - -/obj/item/borg/cyborg_omnitool - name = "broken cyborg tool arm" - desc = "Some internal part of a broken cyborg." - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "lollipop" - ///Ref to the toolbox, since our own loc will be changing - var/obj/item/cyborg_omnitoolbox/toolbox - ///Ref to currently selected tool, if any - var/obj/item/selected - -/obj/item/borg/cyborg_omnitool/Initialize(mapload) - . = ..() - if(!iscyborg(loc.loc)) - return - var/obj/item/robot_model/model = loc - var/obj/item/cyborg_omnitoolbox/chassis_toolbox = model.toolbox - if(!chassis_toolbox) - return - toolbox = chassis_toolbox - toolbox.omnitools += src - -/obj/item/borg/cyborg_omnitool/attack_self(mob/user) - var/list/radial_menu_options = list() - for(var/obj/item/borgtool in toolbox.contents) - radial_menu_options[borgtool] = image(icon = borgtool.icon, icon_state = borgtool.icon_state) - var/obj/item/potential_new_tool = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE) - if(!potential_new_tool) - return ..() - if(potential_new_tool == selected) - return ..() - for(var/obj/item/borg/cyborg_omnitool/coworker in toolbox.omnitools) - if(coworker.selected == potential_new_tool) - coworker.deselect() //Can I borrow that please - break - selected = potential_new_tool - icon_state = selected.icon_state - playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) - return ..() - -/obj/item/borg/cyborg_omnitool/proc/deselect() - if(!selected) - return - selected = null - icon_state = initial(icon_state) - playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) - -/obj/item/borg/cyborg_omnitool/cyborg_unequip() - deselect() - return ..() - -/obj/item/borg/cyborg_omnitool/pre_attack(atom/atom, mob/living/user, params) - if(selected) - selected.melee_attack_chain(user, atom, params) - return TRUE - return ..() - -/obj/item/borg/cyborg_omnitool/engineering - name = "engineering omni-toolset" - desc = "A set of engineering tools used by cyborgs to conduct various engineering tasks." - icon_state = "toolkit_engiborg" - -/obj/item/borg/cyborg_omnitool/medical - name = "surgical omni-toolset" - desc = "A set of surgical tools used by cyborgs to operate on various surgical operations." - icon_state = "toolkit_medborg" - #undef PKBORG_DAMPEN_CYCLE_DELAY diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 10235dfc5c0a..11efdc231876 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -422,18 +422,19 @@ . = ..() if(!.) return . - if(cyborg.model.toolbox.currently_upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - cyborg.model.toolbox.set_upgrade(TRUE) - ADD_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) + for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) + if(omnitool_upgrade.upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) + omnitool.upgrade_omnitool() /obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - cyborg.model.toolbox.set_upgrade(FALSE) - REMOVE_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) + for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + omnitool.downgrade_omnitool() /obj/item/borg/upgrade/engineering_omnitool name = "cyborg engineering omni-tool upgrade" @@ -448,16 +449,19 @@ . = ..() if(!.) return . - if(cyborg.model.toolbox.currently_upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - cyborg.model.toolbox.set_upgrade(TRUE) + for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules) + if(omnitool_upgrade.upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) + omnitool.upgrade_omnitool() /obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - cyborg.model.toolbox.set_upgrade(FALSE) + for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + omnitool.downgrade_omnitool() /obj/item/borg/upgrade/defib name = "medical cyborg defibrillator" diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index 060568508c12..8bd3cb565e39 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -53,17 +53,9 @@ var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3) ///List of skins the borg can be reskinned to, optional var/list/borg_skins - ///Omnitoolbox, holder of certain borg tools. Not all models have one - var/obj/item/cyborg_omnitoolbox/toolbox - ///Path to toolbox, if a model gets one - var/toolbox_path /obj/item/robot_model/Initialize(mapload) . = ..() - - if(toolbox_path) - toolbox = new toolbox_path(src) - for(var/path in basic_modules) var/obj/item/new_module = new path(src) basic_modules += new_module @@ -393,7 +385,6 @@ model_select_icon = "engineer" model_traits = list(TRAIT_NEGATES_GRAVITY) hat_offset = -4 - toolbox_path = /obj/item/cyborg_omnitoolbox/engineering /obj/item/robot_model/janitor name = "Janitor" @@ -664,9 +655,14 @@ /obj/item/borg/apparatus/beaker, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, - /obj/item/borg/cyborg_omnitool/medical, - /obj/item/borg/cyborg_omnitool/medical, - /obj/item/surgical_drapes/cyborg, + /obj/item/surgical_drapes, + /obj/item/retractor, + /obj/item/hemostat, + /obj/item/cautery, + /obj/item/surgicaldrill, + /obj/item/scalpel, + /obj/item/circular_saw, + /obj/item/bonesetter, /obj/item/blood_filter, /obj/item/extinguisher/mini, /obj/item/emergency_bed/silicon, @@ -684,7 +680,6 @@ model_select_icon = "medical" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 - toolbox_path = /obj/item/cyborg_omnitoolbox/medical borg_skins = list( "Machinified Doctor" = list(SKIN_ICON_STATE = "medical"), "Qualified Doctor" = list(SKIN_ICON_STATE = "qualified_doctor"), @@ -870,10 +865,12 @@ /obj/item/reagent_containers/borghypo/syndicate, /obj/item/shockpaddles/syndicate/cyborg, /obj/item/healthanalyzer, - /obj/item/borg/cyborg_omnitool/medical, - /obj/item/borg/cyborg_omnitool/medical, - /obj/item/surgical_drapes/cyborg, - /obj/item/blood_filter, + /obj/item/surgical_drapes, + /obj/item/retractor, + /obj/item/hemostat, + /obj/item/cautery, + /obj/item/surgicaldrill, + /obj/item/scalpel, /obj/item/melee/energy/sword/cyborg/saw, /obj/item/bonesetter, /obj/item/blood_filter, @@ -890,7 +887,6 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 - toolbox_path = /obj/item/cyborg_omnitoolbox/medical /obj/item/robot_model/saboteur name = "Syndicate Saboteur" @@ -923,7 +919,6 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE, TRAIT_NEGATES_GRAVITY) hat_offset = -4 - toolbox_path = /obj/item/cyborg_omnitoolbox/engineering canDispose = TRUE /obj/item/robot_model/syndicate/kiltborg diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 832c0dcd78db..7320e6ed9475 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -119,10 +119,6 @@ if(isnull(step)) return FALSE var/obj/item/tool = user.get_active_held_item() - if(istype(tool, /obj/item/borg/cyborg_omnitool)) //catches borg surgeries - var/obj/item/borg/cyborg_omnitool/toolarm = tool - if(toolarm.selected) - tool = toolarm.selected if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) return TRUE if(tool && tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 75702f56c265..66363173e8c3 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -25,9 +25,6 @@ desc = "Micro-mechanical manipulator for retracting stuff." toolspeed = 0.5 -/obj/item/retractor/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_retractor" /obj/item/hemostat name = "hemostat" @@ -58,9 +55,6 @@ desc = "Tiny servos power a pair of pincers to stop bleeding." toolspeed = 0.5 -/obj/item/hemostat/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_hemostat" /obj/item/cautery name = "cautery" @@ -95,10 +89,6 @@ desc = "A heated element that cauterizes wounds." toolspeed = 0.5 -/obj/item/cautery/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_cautery" - /obj/item/cautery/advanced name = "searing tool" desc = "It projects a high power laser used for medical applications." @@ -189,10 +179,6 @@ playsound(user, 'sound/machines/juicer.ogg', 20, TRUE) return MANUAL_SUICIDE -/obj/item/surgicaldrill/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_drill" - /obj/item/surgicaldrill/augment desc = "Effectively a small power drill contained within your arm. May or may not pierce the heavens." hitsound = 'sound/weapons/circsawhit.ogg' @@ -246,10 +232,6 @@ user.visible_message(span_suicide("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS -/obj/item/scalpel/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_scalpel" - /obj/item/scalpel/augment desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." toolspeed = 0.5 @@ -304,10 +286,6 @@ /obj/item/circular_saw/get_surgery_tool_overlay(tray_extended) return surgical_tray_overlay -/obj/item/circular_saw/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_saw" - /obj/item/circular_saw/augment desc = "A small but very fast spinning saw. It rips and tears until it is done." w_class = WEIGHT_CLASS_SMALL @@ -332,10 +310,6 @@ . = ..() AddComponent(/datum/component/surgery_initiator) -/obj/item/surgical_drapes/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_surgicaldrapes" - /obj/item/surgical_processor //allows medical cyborgs to scan and initiate advanced surgeries name = "surgical processor" desc = "A device for scanning and initiating surgeries from a disk or operating computer." @@ -621,10 +595,6 @@ /obj/item/bonesetter/get_surgery_tool_overlay(tray_extended) return "bonesetter" + (tray_extended ? "" : "_out") -/obj/item/bonesetter/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_bonesetter" - /obj/item/blood_filter name = "blood filter" desc = "For filtering the blood." From 601f607af204c3bf7e38e7f5b59bd71585a90ccf Mon Sep 17 00:00:00 2001 From: zxaber <37497534+zxaber@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:32:51 -0700 Subject: [PATCH 06/13] Cyborg Omnitool Refactor (#83880) - Complete rewrite of borg omnitool code; - - Borgs that use omnitools now have a "Omni Toolbox" that holds whatever tools the Omnitool would cover. The toolbox keeps track of Omnitool "Arms" in a list, as well as when to upgrade (or downgrade) tool speed. The toolbox is not seen by the player directly. - - Omnitool "Arms" will display available tools based on the Omni Toolbox's contents. Selecting one does not move the tool out of the toolbox, but instead simply overrides any following clicks with a melee attack chain of the selected item. This is reminiscent of how borg apparatus tools work. When selecting a tool, the Omnitool "arm" will also set its own icon state to match the tool selected. - - Because all Omnitool "arms" are using the same tools from the same toolbox, actions done with one can be seen from another. For example, using the first Omnitool to scan the Silo with the engineer borg's multitool will update the tool's buffer, and it can be used later, even if the multitool is selected by the second Omnitool. - Because we're now using real tools, rather than a single tool item faking tool usage via tool flags, almost all interactions with tools should properly carry over. - Added Cyborg versions of the medical toolset, for use with the Medical Cyborg omnitool, so that we can finally use the really nice borg-version medical tool sprites. Easier to read code. Fixes #83667 Fixes #83537 Fixes #83077 Fixes #82918 partially; Heating beakers works, but the tile quick-swap function will not function; the action is initiated by a click from the tile stack rather than the crowbar. :cl: fix: Refactored borg omnitool code, fixing most of the unique interaction issues. /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/datums/components/surgery_initiator.dm | 7 +- .../telecomms/machine_interactions.dm | 7 +- code/game/objects/items/robot/items/tools.dm | 140 ++++++++++++++++++ .../objects/items/robot/robot_upgrades.dm | 28 ++-- .../mob/living/silicon/robot/robot_model.dm | 12 ++ code/modules/surgery/surgery.dm | 4 + code/modules/surgery/tools.dm | 30 ++++ 7 files changed, 208 insertions(+), 20 deletions(-) diff --git a/code/datums/components/surgery_initiator.dm b/code/datums/components/surgery_initiator.dm index 1cc60d78b555..00dbf6e51c7a 100644 --- a/code/datums/components/surgery_initiator.dm +++ b/code/datums/components/surgery_initiator.dm @@ -134,8 +134,11 @@ required_tool_type = TOOL_SCREWDRIVER if(iscyborg(user)) - close_tool = locate(/obj/item/cautery) in user.held_items - if(!close_tool) + var/has_cautery = FALSE + for(var/obj/item/borg/cyborg_omnitool/toolarm in user.held_items) + if(toolarm.selected && istype(toolarm.selected, /obj/item/cautery)) + has_cautery = TRUE + if(!has_cautery) patient.balloon_alert(user, "need a cautery in an inactive slot to stop the surgery!") return else if(!close_tool || close_tool.tool_behaviour != required_tool_type) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index fe0c2804b28e..9eadec2cb05e 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -255,8 +255,11 @@ var/mob/living/silicon/ai/U = user multitool = U.aiMulti else if(iscyborg(user) && in_range(user, src)) - if(istype(user.get_active_held_item(), /obj/item/multitool)) - multitool = user.get_active_held_item() + var/mob/living/silicon/robot/borguser = user + for(var/obj/item/borg/cyborg_omnitool/toolarm in borguser.held_items) + if(istype(toolarm.selected, /obj/item/multitool)) + multitool = toolarm.selected + break return multitool /obj/machinery/telecomms/proc/canAccess(mob/user) diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm index 773458964f77..5efad83b673b 100644 --- a/code/game/objects/items/robot/items/tools.dm +++ b/code/game/objects/items/robot/items/tools.dm @@ -175,4 +175,144 @@ projectile.speed *= (1 / projectile_speed_coefficient) projectile.cut_overlay(projectile_effect) +////////////////////// +///CYBORG OMNITOOLS/// +////////////////////// + +/** + Onmi Toolboxs act as a cache of tools for a particular borg's omnitools. Not all borg + get a toolbox (as not all borgs use omnitools), and those that do can only have one + toolbox. The toolbox keeps track of a borg's omnitool arms, and handles speed upgrades. + + Omnitools are the actual tool arms for the cyborg to interact with. When attack_self + is called, they can select a tool from the toolbox. The tool is not moved, and instead + only referenced in place of the omnitool's own attacks. The omnitool also takes on + the tool's sprite, which completes the illusion. In this way, multiple tools are + shared between multiple omnitool arms. A multitool's buffer, for example, will not + depend on which omnitool arm was used to set it. +*/ +/obj/item/cyborg_omnitoolbox + name = "broken cyborg toolbox" + desc = "Some internal part of a broken cyborg." + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "lollipop" + toolspeed = 10 + ///List of Omnitool "arms" that the borg has. + var/list/omnitools = list() + ///List of paths for tools. These will be created during Initialize() + var/list/toolpaths = list() + ///Target Toolspeed to set after reciving an omnitool upgrade + var/upgraded_toolspeed = 10 + ///Whether we currently have the upgraded speed + var/currently_upgraded = FALSE + +/obj/item/cyborg_omnitoolbox/Initialize(mapload) + . = ..() + if(!toolpaths.len) + return + + var/obj/item/newitem + for(var/newpath in toolpaths) + newitem = new newpath(src) + newitem.toolspeed = toolspeed //In case thse have different base speeds as stand-alone tools on other borgs + ADD_TRAIT(newitem, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + +/obj/item/cyborg_omnitoolbox/proc/set_upgrade(upgrade = FALSE) + for(var/obj/item/tool in contents) + if(upgrade) + tool.toolspeed = upgraded_toolspeed + else + tool.toolspeed = toolspeed + currently_upgraded = upgrade + +/obj/item/cyborg_omnitoolbox/engineering + toolspeed = 0.5 + upgraded_toolspeed = 0.3 + toolpaths = list( + /obj/item/wrench/cyborg, + /obj/item/wirecutters/cyborg, + /obj/item/screwdriver/cyborg, + /obj/item/crowbar/cyborg, + /obj/item/multitool/cyborg, + ) + +/obj/item/cyborg_omnitoolbox/medical + toolspeed = 1 + upgraded_toolspeed = 0.7 + toolpaths = list( + /obj/item/scalpel/cyborg, + /obj/item/surgicaldrill/cyborg, + /obj/item/hemostat/cyborg, + /obj/item/retractor/cyborg, + /obj/item/cautery/cyborg, + /obj/item/circular_saw/cyborg, + /obj/item/bonesetter/cyborg, + ) + +/obj/item/borg/cyborg_omnitool + name = "broken cyborg tool arm" + desc = "Some internal part of a broken cyborg." + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "lollipop" + ///Ref to the toolbox, since our own loc will be changing + var/obj/item/cyborg_omnitoolbox/toolbox + ///Ref to currently selected tool, if any + var/obj/item/selected + +/obj/item/borg/cyborg_omnitool/Initialize(mapload) + . = ..() + if(!iscyborg(loc.loc)) + return + var/obj/item/robot_model/model = loc + var/obj/item/cyborg_omnitoolbox/chassis_toolbox = model.toolbox + if(!chassis_toolbox) + return + toolbox = chassis_toolbox + toolbox.omnitools += src + +/obj/item/borg/cyborg_omnitool/attack_self(mob/user) + var/list/radial_menu_options = list() + for(var/obj/item/borgtool in toolbox.contents) + radial_menu_options[borgtool] = image(icon = borgtool.icon, icon_state = borgtool.icon_state) + var/obj/item/potential_new_tool = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE) + if(!potential_new_tool) + return ..() + if(potential_new_tool == selected) + return ..() + for(var/obj/item/borg/cyborg_omnitool/coworker in toolbox.omnitools) + if(coworker.selected == potential_new_tool) + coworker.deselect() //Can I borrow that please + break + selected = potential_new_tool + icon_state = selected.icon_state + playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) + return ..() + +/obj/item/borg/cyborg_omnitool/proc/deselect() + if(!selected) + return + selected = null + icon_state = initial(icon_state) + playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) + +/obj/item/borg/cyborg_omnitool/cyborg_unequip() + deselect() + return ..() + +/obj/item/borg/cyborg_omnitool/pre_attack(atom/atom, mob/living/user, params) + if(selected) + selected.melee_attack_chain(user, atom, params) + return TRUE + return ..() + +/obj/item/borg/cyborg_omnitool/engineering + name = "engineering omni-toolset" + desc = "A set of engineering tools used by cyborgs to conduct various engineering tasks." + icon_state = "toolkit_engiborg" + +/obj/item/borg/cyborg_omnitool/medical + name = "surgical omni-toolset" + desc = "A set of surgical tools used by cyborgs to operate on various surgical operations." + icon_state = "toolkit_medborg" + #undef PKBORG_DAMPEN_CYCLE_DELAY diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 11efdc231876..10235dfc5c0a 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -422,19 +422,18 @@ . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) - omnitool.upgrade_omnitool() + if(cyborg.model.toolbox.currently_upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + cyborg.model.toolbox.set_upgrade(TRUE) + ADD_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) /obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) - omnitool.downgrade_omnitool() + cyborg.model.toolbox.set_upgrade(FALSE) + REMOVE_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) /obj/item/borg/upgrade/engineering_omnitool name = "cyborg engineering omni-tool upgrade" @@ -449,19 +448,16 @@ . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) - omnitool.upgrade_omnitool() + if(cyborg.model.toolbox.currently_upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + cyborg.model.toolbox.set_upgrade(TRUE) /obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) - omnitool.downgrade_omnitool() + cyborg.model.toolbox.set_upgrade(FALSE) /obj/item/borg/upgrade/defib name = "medical cyborg defibrillator" diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index 8bd3cb565e39..96e2fab88113 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -53,9 +53,17 @@ var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3) ///List of skins the borg can be reskinned to, optional var/list/borg_skins + ///Omnitoolbox, holder of certain borg tools. Not all models have one + var/obj/item/cyborg_omnitoolbox/toolbox + ///Path to toolbox, if a model gets one + var/toolbox_path /obj/item/robot_model/Initialize(mapload) . = ..() + + if(toolbox_path) + toolbox = new toolbox_path(src) + for(var/path in basic_modules) var/obj/item/new_module = new path(src) basic_modules += new_module @@ -385,6 +393,7 @@ model_select_icon = "engineer" model_traits = list(TRAIT_NEGATES_GRAVITY) hat_offset = -4 + toolbox_path = /obj/item/cyborg_omnitoolbox/engineering /obj/item/robot_model/janitor name = "Janitor" @@ -680,6 +689,7 @@ model_select_icon = "medical" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 + toolbox_path = /obj/item/cyborg_omnitoolbox/medical borg_skins = list( "Machinified Doctor" = list(SKIN_ICON_STATE = "medical"), "Qualified Doctor" = list(SKIN_ICON_STATE = "qualified_doctor"), @@ -887,6 +897,7 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 + toolbox_path = /obj/item/cyborg_omnitoolbox/medical /obj/item/robot_model/saboteur name = "Syndicate Saboteur" @@ -919,6 +930,7 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE, TRAIT_NEGATES_GRAVITY) hat_offset = -4 + toolbox_path = /obj/item/cyborg_omnitoolbox/engineering canDispose = TRUE /obj/item/robot_model/syndicate/kiltborg diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 7320e6ed9475..832c0dcd78db 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -119,6 +119,10 @@ if(isnull(step)) return FALSE var/obj/item/tool = user.get_active_held_item() + if(istype(tool, /obj/item/borg/cyborg_omnitool)) //catches borg surgeries + var/obj/item/borg/cyborg_omnitool/toolarm = tool + if(toolarm.selected) + tool = toolarm.selected if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) return TRUE if(tool && tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 66363173e8c3..75702f56c265 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -25,6 +25,9 @@ desc = "Micro-mechanical manipulator for retracting stuff." toolspeed = 0.5 +/obj/item/retractor/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_retractor" /obj/item/hemostat name = "hemostat" @@ -55,6 +58,9 @@ desc = "Tiny servos power a pair of pincers to stop bleeding." toolspeed = 0.5 +/obj/item/hemostat/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_hemostat" /obj/item/cautery name = "cautery" @@ -89,6 +95,10 @@ desc = "A heated element that cauterizes wounds." toolspeed = 0.5 +/obj/item/cautery/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_cautery" + /obj/item/cautery/advanced name = "searing tool" desc = "It projects a high power laser used for medical applications." @@ -179,6 +189,10 @@ playsound(user, 'sound/machines/juicer.ogg', 20, TRUE) return MANUAL_SUICIDE +/obj/item/surgicaldrill/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_drill" + /obj/item/surgicaldrill/augment desc = "Effectively a small power drill contained within your arm. May or may not pierce the heavens." hitsound = 'sound/weapons/circsawhit.ogg' @@ -232,6 +246,10 @@ user.visible_message(span_suicide("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS +/obj/item/scalpel/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_scalpel" + /obj/item/scalpel/augment desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." toolspeed = 0.5 @@ -286,6 +304,10 @@ /obj/item/circular_saw/get_surgery_tool_overlay(tray_extended) return surgical_tray_overlay +/obj/item/circular_saw/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_saw" + /obj/item/circular_saw/augment desc = "A small but very fast spinning saw. It rips and tears until it is done." w_class = WEIGHT_CLASS_SMALL @@ -310,6 +332,10 @@ . = ..() AddComponent(/datum/component/surgery_initiator) +/obj/item/surgical_drapes/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_surgicaldrapes" + /obj/item/surgical_processor //allows medical cyborgs to scan and initiate advanced surgeries name = "surgical processor" desc = "A device for scanning and initiating surgeries from a disk or operating computer." @@ -595,6 +621,10 @@ /obj/item/bonesetter/get_surgery_tool_overlay(tray_extended) return "bonesetter" + (tray_extended ? "" : "_out") +/obj/item/bonesetter/cyborg + icon = 'icons/mob/silicon/robot_items.dmi' + icon_state = "toolkit_medborg_bonesetter" + /obj/item/blood_filter name = "blood filter" desc = "For filtering the blood." From 6807761a2ae83ed557a4d20cdc698c0dd3ec5940 Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 00:41:33 +1300 Subject: [PATCH 07/13] mini fixes Co-Authored-By: Jeremiah <42397676+jlsnow301@users.noreply.github.com> --- maplestation_modules/code/modules/objects/robot_magic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maplestation_modules/code/modules/objects/robot_magic.dm b/maplestation_modules/code/modules/objects/robot_magic.dm index 1346ecc095c4..0aa7248ecf9f 100644 --- a/maplestation_modules/code/modules/objects/robot_magic.dm +++ b/maplestation_modules/code/modules/objects/robot_magic.dm @@ -39,7 +39,7 @@ mana_pool = borg.initialize_mana_pool(src.mana_pool) borg.set_mana_pool(mana_pool) -/obj/item/borg/upgrade/magic/deactivate(mob/living/silicon/robot/borg, user = usr) +/obj/item/borg/upgrade/magic/deactivate(mob/living/silicon/robot/borg) . = ..() if(.) //removes the spells From 7250485edd763562ff09624ab372c56b2ed73618 Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 00:52:53 +1300 Subject: [PATCH 08/13] Revert "Cyborg Omnitool Refactor (#83880)" This reverts commit 601f607af204c3bf7e38e7f5b59bd71585a90ccf. --- code/datums/components/surgery_initiator.dm | 7 +- .../telecomms/machine_interactions.dm | 7 +- code/game/objects/items/robot/items/tools.dm | 140 ------------------ .../objects/items/robot/robot_upgrades.dm | 28 ++-- .../mob/living/silicon/robot/robot_model.dm | 12 -- code/modules/surgery/surgery.dm | 4 - code/modules/surgery/tools.dm | 30 ---- 7 files changed, 20 insertions(+), 208 deletions(-) diff --git a/code/datums/components/surgery_initiator.dm b/code/datums/components/surgery_initiator.dm index 00dbf6e51c7a..1cc60d78b555 100644 --- a/code/datums/components/surgery_initiator.dm +++ b/code/datums/components/surgery_initiator.dm @@ -134,11 +134,8 @@ required_tool_type = TOOL_SCREWDRIVER if(iscyborg(user)) - var/has_cautery = FALSE - for(var/obj/item/borg/cyborg_omnitool/toolarm in user.held_items) - if(toolarm.selected && istype(toolarm.selected, /obj/item/cautery)) - has_cautery = TRUE - if(!has_cautery) + close_tool = locate(/obj/item/cautery) in user.held_items + if(!close_tool) patient.balloon_alert(user, "need a cautery in an inactive slot to stop the surgery!") return else if(!close_tool || close_tool.tool_behaviour != required_tool_type) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 9eadec2cb05e..fe0c2804b28e 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -255,11 +255,8 @@ var/mob/living/silicon/ai/U = user multitool = U.aiMulti else if(iscyborg(user) && in_range(user, src)) - var/mob/living/silicon/robot/borguser = user - for(var/obj/item/borg/cyborg_omnitool/toolarm in borguser.held_items) - if(istype(toolarm.selected, /obj/item/multitool)) - multitool = toolarm.selected - break + if(istype(user.get_active_held_item(), /obj/item/multitool)) + multitool = user.get_active_held_item() return multitool /obj/machinery/telecomms/proc/canAccess(mob/user) diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm index 5efad83b673b..773458964f77 100644 --- a/code/game/objects/items/robot/items/tools.dm +++ b/code/game/objects/items/robot/items/tools.dm @@ -175,144 +175,4 @@ projectile.speed *= (1 / projectile_speed_coefficient) projectile.cut_overlay(projectile_effect) -////////////////////// -///CYBORG OMNITOOLS/// -////////////////////// - -/** - Onmi Toolboxs act as a cache of tools for a particular borg's omnitools. Not all borg - get a toolbox (as not all borgs use omnitools), and those that do can only have one - toolbox. The toolbox keeps track of a borg's omnitool arms, and handles speed upgrades. - - Omnitools are the actual tool arms for the cyborg to interact with. When attack_self - is called, they can select a tool from the toolbox. The tool is not moved, and instead - only referenced in place of the omnitool's own attacks. The omnitool also takes on - the tool's sprite, which completes the illusion. In this way, multiple tools are - shared between multiple omnitool arms. A multitool's buffer, for example, will not - depend on which omnitool arm was used to set it. -*/ -/obj/item/cyborg_omnitoolbox - name = "broken cyborg toolbox" - desc = "Some internal part of a broken cyborg." - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "lollipop" - toolspeed = 10 - ///List of Omnitool "arms" that the borg has. - var/list/omnitools = list() - ///List of paths for tools. These will be created during Initialize() - var/list/toolpaths = list() - ///Target Toolspeed to set after reciving an omnitool upgrade - var/upgraded_toolspeed = 10 - ///Whether we currently have the upgraded speed - var/currently_upgraded = FALSE - -/obj/item/cyborg_omnitoolbox/Initialize(mapload) - . = ..() - if(!toolpaths.len) - return - - var/obj/item/newitem - for(var/newpath in toolpaths) - newitem = new newpath(src) - newitem.toolspeed = toolspeed //In case thse have different base speeds as stand-alone tools on other borgs - ADD_TRAIT(newitem, TRAIT_NODROP, CYBORG_ITEM_TRAIT) - -/obj/item/cyborg_omnitoolbox/proc/set_upgrade(upgrade = FALSE) - for(var/obj/item/tool in contents) - if(upgrade) - tool.toolspeed = upgraded_toolspeed - else - tool.toolspeed = toolspeed - currently_upgraded = upgrade - -/obj/item/cyborg_omnitoolbox/engineering - toolspeed = 0.5 - upgraded_toolspeed = 0.3 - toolpaths = list( - /obj/item/wrench/cyborg, - /obj/item/wirecutters/cyborg, - /obj/item/screwdriver/cyborg, - /obj/item/crowbar/cyborg, - /obj/item/multitool/cyborg, - ) - -/obj/item/cyborg_omnitoolbox/medical - toolspeed = 1 - upgraded_toolspeed = 0.7 - toolpaths = list( - /obj/item/scalpel/cyborg, - /obj/item/surgicaldrill/cyborg, - /obj/item/hemostat/cyborg, - /obj/item/retractor/cyborg, - /obj/item/cautery/cyborg, - /obj/item/circular_saw/cyborg, - /obj/item/bonesetter/cyborg, - ) - -/obj/item/borg/cyborg_omnitool - name = "broken cyborg tool arm" - desc = "Some internal part of a broken cyborg." - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "lollipop" - ///Ref to the toolbox, since our own loc will be changing - var/obj/item/cyborg_omnitoolbox/toolbox - ///Ref to currently selected tool, if any - var/obj/item/selected - -/obj/item/borg/cyborg_omnitool/Initialize(mapload) - . = ..() - if(!iscyborg(loc.loc)) - return - var/obj/item/robot_model/model = loc - var/obj/item/cyborg_omnitoolbox/chassis_toolbox = model.toolbox - if(!chassis_toolbox) - return - toolbox = chassis_toolbox - toolbox.omnitools += src - -/obj/item/borg/cyborg_omnitool/attack_self(mob/user) - var/list/radial_menu_options = list() - for(var/obj/item/borgtool in toolbox.contents) - radial_menu_options[borgtool] = image(icon = borgtool.icon, icon_state = borgtool.icon_state) - var/obj/item/potential_new_tool = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE) - if(!potential_new_tool) - return ..() - if(potential_new_tool == selected) - return ..() - for(var/obj/item/borg/cyborg_omnitool/coworker in toolbox.omnitools) - if(coworker.selected == potential_new_tool) - coworker.deselect() //Can I borrow that please - break - selected = potential_new_tool - icon_state = selected.icon_state - playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) - return ..() - -/obj/item/borg/cyborg_omnitool/proc/deselect() - if(!selected) - return - selected = null - icon_state = initial(icon_state) - playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE) - -/obj/item/borg/cyborg_omnitool/cyborg_unequip() - deselect() - return ..() - -/obj/item/borg/cyborg_omnitool/pre_attack(atom/atom, mob/living/user, params) - if(selected) - selected.melee_attack_chain(user, atom, params) - return TRUE - return ..() - -/obj/item/borg/cyborg_omnitool/engineering - name = "engineering omni-toolset" - desc = "A set of engineering tools used by cyborgs to conduct various engineering tasks." - icon_state = "toolkit_engiborg" - -/obj/item/borg/cyborg_omnitool/medical - name = "surgical omni-toolset" - desc = "A set of surgical tools used by cyborgs to operate on various surgical operations." - icon_state = "toolkit_medborg" - #undef PKBORG_DAMPEN_CYCLE_DELAY diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 10235dfc5c0a..11efdc231876 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -422,18 +422,19 @@ . = ..() if(!.) return . - if(cyborg.model.toolbox.currently_upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - cyborg.model.toolbox.set_upgrade(TRUE) - ADD_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) + for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) + if(omnitool_upgrade.upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) + omnitool.upgrade_omnitool() /obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - cyborg.model.toolbox.set_upgrade(FALSE) - REMOVE_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) + for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + omnitool.downgrade_omnitool() /obj/item/borg/upgrade/engineering_omnitool name = "cyborg engineering omni-tool upgrade" @@ -448,16 +449,19 @@ . = ..() if(!.) return . - if(cyborg.model.toolbox.currently_upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - cyborg.model.toolbox.set_upgrade(TRUE) + for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules) + if(omnitool_upgrade.upgraded) + to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + return FALSE + for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) + omnitool.upgrade_omnitool() /obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) return . - cyborg.model.toolbox.set_upgrade(FALSE) + for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + omnitool.downgrade_omnitool() /obj/item/borg/upgrade/defib name = "medical cyborg defibrillator" diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index 96e2fab88113..8bd3cb565e39 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -53,17 +53,9 @@ var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3) ///List of skins the borg can be reskinned to, optional var/list/borg_skins - ///Omnitoolbox, holder of certain borg tools. Not all models have one - var/obj/item/cyborg_omnitoolbox/toolbox - ///Path to toolbox, if a model gets one - var/toolbox_path /obj/item/robot_model/Initialize(mapload) . = ..() - - if(toolbox_path) - toolbox = new toolbox_path(src) - for(var/path in basic_modules) var/obj/item/new_module = new path(src) basic_modules += new_module @@ -393,7 +385,6 @@ model_select_icon = "engineer" model_traits = list(TRAIT_NEGATES_GRAVITY) hat_offset = -4 - toolbox_path = /obj/item/cyborg_omnitoolbox/engineering /obj/item/robot_model/janitor name = "Janitor" @@ -689,7 +680,6 @@ model_select_icon = "medical" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 - toolbox_path = /obj/item/cyborg_omnitoolbox/medical borg_skins = list( "Machinified Doctor" = list(SKIN_ICON_STATE = "medical"), "Qualified Doctor" = list(SKIN_ICON_STATE = "qualified_doctor"), @@ -897,7 +887,6 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE) hat_offset = 3 - toolbox_path = /obj/item/cyborg_omnitoolbox/medical /obj/item/robot_model/saboteur name = "Syndicate Saboteur" @@ -930,7 +919,6 @@ model_select_icon = "malf" model_traits = list(TRAIT_PUSHIMMUNE, TRAIT_NEGATES_GRAVITY) hat_offset = -4 - toolbox_path = /obj/item/cyborg_omnitoolbox/engineering canDispose = TRUE /obj/item/robot_model/syndicate/kiltborg diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 832c0dcd78db..7320e6ed9475 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -119,10 +119,6 @@ if(isnull(step)) return FALSE var/obj/item/tool = user.get_active_held_item() - if(istype(tool, /obj/item/borg/cyborg_omnitool)) //catches borg surgeries - var/obj/item/borg/cyborg_omnitool/toolarm = tool - if(toolarm.selected) - tool = toolarm.selected if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) return TRUE if(tool && tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 75702f56c265..66363173e8c3 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -25,9 +25,6 @@ desc = "Micro-mechanical manipulator for retracting stuff." toolspeed = 0.5 -/obj/item/retractor/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_retractor" /obj/item/hemostat name = "hemostat" @@ -58,9 +55,6 @@ desc = "Tiny servos power a pair of pincers to stop bleeding." toolspeed = 0.5 -/obj/item/hemostat/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_hemostat" /obj/item/cautery name = "cautery" @@ -95,10 +89,6 @@ desc = "A heated element that cauterizes wounds." toolspeed = 0.5 -/obj/item/cautery/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_cautery" - /obj/item/cautery/advanced name = "searing tool" desc = "It projects a high power laser used for medical applications." @@ -189,10 +179,6 @@ playsound(user, 'sound/machines/juicer.ogg', 20, TRUE) return MANUAL_SUICIDE -/obj/item/surgicaldrill/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_drill" - /obj/item/surgicaldrill/augment desc = "Effectively a small power drill contained within your arm. May or may not pierce the heavens." hitsound = 'sound/weapons/circsawhit.ogg' @@ -246,10 +232,6 @@ user.visible_message(span_suicide("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS -/obj/item/scalpel/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_scalpel" - /obj/item/scalpel/augment desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." toolspeed = 0.5 @@ -304,10 +286,6 @@ /obj/item/circular_saw/get_surgery_tool_overlay(tray_extended) return surgical_tray_overlay -/obj/item/circular_saw/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_saw" - /obj/item/circular_saw/augment desc = "A small but very fast spinning saw. It rips and tears until it is done." w_class = WEIGHT_CLASS_SMALL @@ -332,10 +310,6 @@ . = ..() AddComponent(/datum/component/surgery_initiator) -/obj/item/surgical_drapes/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_surgicaldrapes" - /obj/item/surgical_processor //allows medical cyborgs to scan and initiate advanced surgeries name = "surgical processor" desc = "A device for scanning and initiating surgeries from a disk or operating computer." @@ -621,10 +595,6 @@ /obj/item/bonesetter/get_surgery_tool_overlay(tray_extended) return "bonesetter" + (tray_extended ? "" : "_out") -/obj/item/bonesetter/cyborg - icon = 'icons/mob/silicon/robot_items.dmi' - icon_state = "toolkit_medborg_bonesetter" - /obj/item/blood_filter name = "blood filter" desc = "For filtering the blood." From 01f0256411878fa20a4ad45a9a270badfe5f974a Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 00:52:58 +1300 Subject: [PATCH 09/13] Revert "Borgs: the moduling (Various fixups to borg module code) (#83116)" This reverts commit b9f3c4350fbb7002abb44eba1b35bbe7dddc646d. --- .../objects/effects/spawners/random/exotic.dm | 2 +- .../objects/items/robot/robot_upgrades.dm | 785 +++++++++++------- .../designs/mechfabricator_designs.dm | 2 +- 3 files changed, 490 insertions(+), 299 deletions(-) diff --git a/code/game/objects/effects/spawners/random/exotic.dm b/code/game/objects/effects/spawners/random/exotic.dm index e802e30056f4..add4faf5c500 100644 --- a/code/game/objects/effects/spawners/random/exotic.dm +++ b/code/game/objects/effects/spawners/random/exotic.dm @@ -50,7 +50,7 @@ /obj/item/storage/medkit/brute = 27, /obj/item/storage/medkit/fire = 27, /obj/item/storage/toolbox/syndicate = 12, - /obj/item/borg/upgrade/diamond_drill = 3, + /obj/item/borg/upgrade/ddrill = 3, /obj/item/knife/butcher = 14, /obj/item/clothing/glasses/night = 10, /obj/item/pickaxe/drill/diamonddrill = 6, diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 11efdc231876..27dfb028992d 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -13,61 +13,23 @@ var/list/model_type = null /// Bitflags listing model compatibility. Used in the exosuit fabricator for creating sub-categories. var/list/model_flags = NONE - - /// List of items to add with the module, if any - var/list/items_to_add - /// List of items to remove with the module, if any - var/list/items_to_remove - // if true, is not stored in the robot to be ejected if model is reset + // if true, is not stored in the robot to be ejected + // if model is reset var/one_use = FALSE - // If the module allows duplicates of itself to exist within the borg. - // one_use technically makes this value not mean anything, maybe could be just one variable with flags? - var/allow_duplicates = FALSE -/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/borg, mob/living/user = usr) - if(borg.stat == DEAD) +/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R, user = usr) + if(R.stat == DEAD) to_chat(user, span_warning("[src] will not function on a deceased cyborg!")) return FALSE - if(model_type && !is_type_in_list(borg.model, model_type)) - to_chat(borg, span_alert("Upgrade mounting error! No suitable hardpoint detected.")) + if(model_type && !is_type_in_list(R.model, model_type)) + to_chat(R, span_alert("Upgrade mounting error! No suitable hardpoint detected.")) to_chat(user, span_warning("There's no mounting point for the module!")) return FALSE - if(!allow_duplicates && (locate(type) in borg.contents)) - to_chat(borg, span_alert("Upgrade mounting error! Hardpoint already occupied!")) - to_chat(user, span_warning("The mounting point for the module is already occupied!")) - return FALSE - // Handles adding/removing items. - if(length(items_to_add)) - install_items(borg, user, items_to_add) - if(length(items_to_remove)) - remove_items(borg, user, items_to_remove) return TRUE -/obj/item/borg/upgrade/proc/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) - if (!(src in borg.upgrades)) +/obj/item/borg/upgrade/proc/deactivate(mob/living/silicon/robot/R, user = usr) + if (!(src in R.upgrades)) return FALSE - - // Handles reverting the items back - if(length(items_to_add)) - remove_items(borg, user, items_to_add) - if(length(items_to_remove)) - install_items(borg, user, items_to_remove) - return TRUE - -// Handles adding items with the module -/obj/item/borg/upgrade/proc/install_items(mob/living/silicon/robot/borg, mob/living/user = usr, list/items) - for(var/item_to_add in items) - var/obj/item/module_item = new item_to_add(borg.model.modules) - borg.model.basic_modules += module_item - borg.model.add_module(module_item, FALSE, TRUE) - return TRUE - -// Handles removing some items as the module is installed -/obj/item/borg/upgrade/proc/remove_items(mob/living/silicon/robot/borg, mob/living/user = usr, list/items) - for(var/item_to_remove in items) - var/obj/item/module_item = locate(item_to_remove) in borg.model.modules - if (module_item) - borg.model.remove_module(module_item, TRUE) return TRUE /obj/item/borg/upgrade/rename @@ -81,17 +43,16 @@ heldname = sanitize_name(tgui_input_text(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN), allow_numbers = TRUE) user.log_message("set \"[heldname]\" as a name in a cyborg reclassification board at [loc_name(user)]", LOG_GAME) -/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - var/oldname = borg.real_name - var/oldkeyname = key_name(borg) - borg.custom_name = heldname - borg.updatename() - if(oldname == borg.real_name) - borg.notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, borg.real_name) - user.log_message("used a cyborg reclassification board to rename [oldkeyname] to [key_name(borg)]", LOG_GAME) + if(.) + var/oldname = R.real_name + var/oldkeyname = key_name(R) + R.custom_name = heldname + R.updatename() + if(oldname == R.real_name) + R.notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, R.real_name) + usr.log_message("used a cyborg reclassification board to rename [oldkeyname] to [key_name(R)]", LOG_GAME) /obj/item/borg/upgrade/disablercooler name = "cyborg rapid disabler cooling module" @@ -100,57 +61,50 @@ require_model = TRUE model_type = list(/obj/item/robot_model/security) model_flags = BORG_MODEL_SECURITY - // We handle this in a custom way - allow_duplicates = TRUE -/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - - var/obj/item/gun/energy/disabler/cyborg/disabler = locate() in borg.model.modules - if(isnull(disabler)) - to_chat(user, span_warning("There's no disabler in this unit!")) - return FALSE - if(disabler.charge_delay <= 2) - to_chat(borg, span_warning("A cooling unit is already installed!")) - to_chat(user, span_warning("There's no room for another cooling unit!")) - return FALSE + if(.) + var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.model.modules + if(!T) + to_chat(user, span_warning("There's no disabler in this unit!")) + return FALSE + if(T.charge_delay <= 2) + to_chat(R, span_warning("A cooling unit is already installed!")) + to_chat(user, span_warning("There's no room for another cooling unit!")) + return FALSE - disabler.charge_delay = max(2 , disabler.charge_delay - 4) + T.charge_delay = max(2 , T.charge_delay - 4) -/obj/item/borg/upgrade/disablercooler/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/disablercooler/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - var/obj/item/gun/energy/disabler/cyborg/disabler = locate() in borg.model.modules - if(isnull(disabler)) - return FALSE - disabler.charge_delay = initial(disabler.charge_delay) + if (.) + var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.model.modules + if(!T) + return FALSE + T.charge_delay = initial(T.charge_delay) /obj/item/borg/upgrade/thrusters name = "ion thruster upgrade" desc = "An energy-operated thruster system for cyborgs." icon_state = "cyborg_upgrade3" -/obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - if(borg.ionpulse) - to_chat(user, span_warning("This unit already has ion thrusters installed!")) - return FALSE + if(.) + if(R.ionpulse) + to_chat(user, span_warning("This unit already has ion thrusters installed!")) + return FALSE - borg.ionpulse = TRUE - borg.toggle_ionpulse() //Enabled by default + R.ionpulse = TRUE + R.toggle_ionpulse() //Enabled by default -/obj/item/borg/upgrade/thrusters/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/thrusters/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - borg.ionpulse = FALSE + if (.) + R.ionpulse = FALSE -/obj/item/borg/upgrade/diamond_drill +/obj/item/borg/upgrade/ddrill name = "mining cyborg diamond drill" desc = "A diamond drill replacement for the mining model's standard drill." icon_state = "cyborg_upgrade3" @@ -158,8 +112,30 @@ model_type = list(/obj/item/robot_model/miner) model_flags = BORG_MODEL_MINER - items_to_add = list(/obj/item/pickaxe/drill/cyborg/diamond) - items_to_remove = list(/obj/item/pickaxe/drill/cyborg, /obj/item/shovel) +/obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + for(var/obj/item/pickaxe/drill/cyborg/D in R.model) + R.model.remove_module(D, TRUE) + for(var/obj/item/shovel/S in R.model) + R.model.remove_module(S, TRUE) + + var/obj/item/pickaxe/drill/cyborg/diamond/DD = new /obj/item/pickaxe/drill/cyborg/diamond(R.model) + R.model.basic_modules += DD + R.model.add_module(DD, FALSE, TRUE) + +/obj/item/borg/upgrade/ddrill/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + for(var/obj/item/pickaxe/drill/cyborg/diamond/DD in R.model) + R.model.remove_module(DD, TRUE) + + var/obj/item/pickaxe/drill/cyborg/D = new (R.model) + R.model.basic_modules += D + R.model.add_module(D, FALSE, TRUE) + var/obj/item/shovel/S = new (R.model) + R.model.basic_modules += S + R.model.add_module(S, FALSE, TRUE) /obj/item/borg/upgrade/soh name = "mining cyborg satchel of holding" @@ -169,8 +145,25 @@ model_type = list(/obj/item/robot_model/miner) model_flags = BORG_MODEL_MINER - items_to_add = list(/obj/item/storage/bag/ore/holding) - items_to_remove = list(/obj/item/storage/bag/ore/cyborg) +/obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R) + . = ..() + if(.) + for(var/obj/item/storage/bag/ore/cyborg/S in R.model) + R.model.remove_module(S, TRUE) + + var/obj/item/storage/bag/ore/holding/H = new /obj/item/storage/bag/ore/holding(R.model) + R.model.basic_modules += H + R.model.add_module(H, FALSE, TRUE) + +/obj/item/borg/upgrade/soh/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + for(var/obj/item/storage/bag/ore/holding/H in R.model) + R.model.remove_module(H, TRUE) + + var/obj/item/storage/bag/ore/cyborg/S = new (R.model) + R.model.basic_modules += S + R.model.add_module(S, FALSE, TRUE) /obj/item/borg/upgrade/tboh name = "janitor cyborg trash bag of holding" @@ -180,8 +173,25 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR - items_to_add = list(/obj/item/storage/bag/trash/bluespace/cyborg) - items_to_remove = list(/obj/item/storage/bag/trash/cyborg) +/obj/item/borg/upgrade/tboh/action(mob/living/silicon/robot/R) + . = ..() + if(.) + for(var/obj/item/storage/bag/trash/cyborg/TB in R.model.modules) + R.model.remove_module(TB, TRUE) + + var/obj/item/storage/bag/trash/bluespace/cyborg/B = new /obj/item/storage/bag/trash/bluespace/cyborg(R.model) + R.model.basic_modules += B + R.model.add_module(B, FALSE, TRUE) + +/obj/item/borg/upgrade/tboh/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + for(var/obj/item/storage/bag/trash/bluespace/cyborg/B in R.model.modules) + R.model.remove_module(B, TRUE) + + var/obj/item/storage/bag/trash/cyborg/TB = new (R.model) + R.model.basic_modules += TB + R.model.add_module(TB, FALSE, TRUE) /obj/item/borg/upgrade/amop name = "janitor cyborg advanced mop" @@ -191,8 +201,25 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR - items_to_add = list(/obj/item/mop/advanced/cyborg) - items_to_remove = list(/obj/item/mop/cyborg) +/obj/item/borg/upgrade/amop/action(mob/living/silicon/robot/R) + . = ..() + if(.) + for(var/obj/item/mop/cyborg/M in R.model.modules) + R.model.remove_module(M, TRUE) + + var/obj/item/mop/advanced/cyborg/mop = new /obj/item/mop/advanced/cyborg(R.model) + R.model.basic_modules += mop + R.model.add_module(mop, FALSE, TRUE) + +/obj/item/borg/upgrade/amop/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + for(var/obj/item/mop/advanced/cyborg/A in R.model.modules) + R.model.remove_module(A, TRUE) + + var/obj/item/mop/cyborg/M = new (R.model) + R.model.basic_modules += M + R.model.add_module(M, FALSE, TRUE) /obj/item/borg/upgrade/prt name = "janitor cyborg plating repair tool" @@ -202,7 +229,18 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR - items_to_add = list(/obj/item/cautery/prt) +/obj/item/borg/upgrade/prt/action(mob/living/silicon/robot/R) + . = ..() + if(.) + var/obj/item/cautery/prt/P = new (R.model) + R.model.basic_modules += P + R.model.add_module(P, FALSE, TRUE) + +/obj/item/borg/upgrade/prt/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + for(var/obj/item/cautery/prt/P in R.model.modules) + R.model.remove_module(P, TRUE) /obj/item/borg/upgrade/syndicate name = "illegal equipment module" @@ -210,24 +248,22 @@ icon_state = "cyborg_upgrade3" require_model = TRUE -/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - if(borg.emagged) - return FALSE + if(.) + if(R.emagged) + return FALSE - borg.SetEmagged(TRUE) - borg.logevent("WARN: hardware installed with missing security certificate!") //A bit of fluff to hint it was an illegal tech item - borg.logevent("WARN: root privleges granted to PID [num2hex(rand(1,65535), -1)][num2hex(rand(1,65535), -1)].") //random eight digit hex value. Two are used because rand(1,4294967295) throws an error + R.SetEmagged(TRUE) + R.logevent("WARN: hardware installed with missing security certificate!") //A bit of fluff to hint it was an illegal tech item + R.logevent("WARN: root privleges granted to PID [num2hex(rand(1,65535), -1)][num2hex(rand(1,65535), -1)].") //random eight digit hex value. Two are used because rand(1,4294967295) throws an error - return TRUE + return TRUE -/obj/item/borg/upgrade/syndicate/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/syndicate/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - borg.SetEmagged(FALSE) + if (.) + R.SetEmagged(FALSE) /obj/item/borg/upgrade/lavaproof name = "mining cyborg lavaproof chassis" @@ -238,17 +274,15 @@ model_type = list(/obj/item/robot_model/miner) model_flags = BORG_MODEL_MINER -/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - borg.add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) + if(.) + R.add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) -/obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - borg.remove_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) + if (.) + R.remove_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), type) /obj/item/borg/upgrade/selfrepair name = "self-repair module" @@ -264,21 +298,24 @@ var/powercost = 10 var/datum/action/toggle_action -/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - icon_state = "selfrepair_off" - toggle_action = new /datum/action/item_action/toggle(src) - toggle_action.Grant(borg) + if(.) + var/obj/item/borg/upgrade/selfrepair/U = locate() in R + if(U) + to_chat(user, span_warning("This unit is already equipped with a self-repair module!")) + return FALSE -/obj/item/borg/upgrade/selfrepair/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) + icon_state = "selfrepair_off" + toggle_action = new /datum/action/item_action/toggle(src) + toggle_action.Grant(R) + +/obj/item/borg/upgrade/selfrepair/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - toggle_action.Remove(borg) - QDEL_NULL(toggle_action) - deactivate_sr() + if (.) + toggle_action.Remove(R) + QDEL_NULL(toggle_action) + deactivate_sr() /obj/item/borg/upgrade/selfrepair/ui_action_click() if(on) @@ -359,19 +396,17 @@ model_flags = BORG_MODEL_MEDICAL var/list/additional_reagents = list() -/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - for(var/obj/item/reagent_containers/borghypo/medical/hypo in borg.model.modules) - hypo.upgrade_hypo() + if(.) + for(var/obj/item/reagent_containers/borghypo/medical/H in R.model.modules) + H.upgrade_hypo() -/obj/item/borg/upgrade/hypospray/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/hypospray/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - for(var/obj/item/reagent_containers/borghypo/medical/hypo in borg.model.modules) - hypo.remove_hypo_upgrade() + if (.) + for(var/obj/item/reagent_containers/borghypo/medical/H in R.model.modules) + H.remove_hypo_upgrade() /obj/item/borg/upgrade/hypospray/expanded name = "medical cyborg expanded hypospray" @@ -384,84 +419,22 @@ pierce armor and thick material." icon_state = "cyborg_upgrade3" -/obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - var/found_hypo = FALSE - for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.modules) - hypo.bypass_protection = TRUE - found_hypo = TRUE - for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.emag_modules) - hypo.bypass_protection = TRUE - found_hypo = TRUE - - if(!found_hypo) - to_chat(user, span_warning("This unit is already equipped with a piercing hypospray upgrade!")) //check to see if we already have this module - return FALSE + if(.) + var/found_hypo = FALSE + for(var/obj/item/reagent_containers/borghypo/H in R.model.modules) + H.bypass_protection = TRUE + found_hypo = TRUE -/obj/item/borg/upgrade/piercing_hypospray/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) - . = ..() - if(!.) - return . - for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.modules) - hypo.bypass_protection = initial(hypo.bypass_protection) - for(var/obj/item/reagent_containers/borghypo/hypo in borg.model.emag_modules) - hypo.bypass_protection = initial(hypo.bypass_protection) - -/obj/item/borg/upgrade/surgery_omnitool - name = "cyborg surgical omni-tool upgrade" - desc = "An upgrade to the Medical model, upgrading the built-in \ - surgical omnitool, to be on par with advanced surgical tools" - icon_state = "cyborg_upgrade3" - require_model = TRUE - model_type = list(/obj/item/robot_model/medical, /obj/item/robot_model/syndicate_medical) - model_flags = BORG_MODEL_MEDICAL - -/obj/item/borg/upgrade/surgery_omnitool/action(mob/living/silicon/robot/cyborg, mob/living/user = usr) - . = ..() - if(!.) - return . - for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE - for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) - omnitool.upgrade_omnitool() - -/obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) - . = ..() - if(!.) - return . - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) - omnitool.downgrade_omnitool() - -/obj/item/borg/upgrade/engineering_omnitool - name = "cyborg engineering omni-tool upgrade" - desc = "An upgrade to the Engineering model, upgrading the built-in \ - engineering omnitool, to be on par with advanced engineering tools" - icon_state = "cyborg_upgrade3" - require_model = TRUE - model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) - model_flags = BORG_MODEL_ENGINEERING - -/obj/item/borg/upgrade/engineering_omnitool/action(mob/living/silicon/robot/cyborg, mob/living/user = usr) - . = ..() - if(!.) - return . - for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) + if(!found_hypo) return FALSE - for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) - omnitool.upgrade_omnitool() -/obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) +/obj/item/borg/upgrade/piercing_hypospray/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) - omnitool.downgrade_omnitool() + if (.) + for(var/obj/item/reagent_containers/borghypo/H in R.model.modules) + H.bypass_protection = initial(H.bypass_protection) /obj/item/borg/upgrade/defib name = "medical cyborg defibrillator" @@ -472,31 +445,37 @@ model_type = list(/obj/item/robot_model/medical) model_flags = BORG_MODEL_MEDICAL - items_to_add = list(/obj/item/shockpaddles/cyborg) - -/obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - var/obj/item/borg/upgrade/defib/backpack/defib_pack = locate() in borg //If a full defib unit was used to upgrade prior, we can just pop it out now and replace - if(defib_pack) - defib_pack.deactivate(borg, user) - to_chat(user, span_notice("The defibrillator pops out of the chassis as the compact upgrade installs.")) + if(.) + var/obj/item/borg/upgrade/defib/backpack/BP = locate() in R //If a full defib unit was used to upgrade prior, we can just pop it out now and replace + if(BP) + BP.deactivate(R, user) + to_chat(user, span_notice("You remove the defibrillator unit to make room for the compact upgrade.")) + var/obj/item/shockpaddles/cyborg/S = new(R.model) + R.model.basic_modules += S + R.model.add_module(S, FALSE, TRUE) + +/obj/item/borg/upgrade/defib/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/shockpaddles/cyborg/S = locate() in R.model + R.model.remove_module(S, TRUE) ///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/defib) +/obj/item/borg/upgrade/defib/backpack/Initialize(mapload, obj/item/defibrillator/D) . = ..() - if(isnull(defib)) - defib = new /obj/item/defibrillator - defib_instance = defib + if(!D) + D = new /obj/item/defibrillator + defib_instance = D name = defib_instance.name defib_instance.moveToNullspace() RegisterSignals(defib_instance, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(on_defib_instance_qdel_or_moved)) -/obj/item/borg/upgrade/defib/backpack/proc/on_defib_instance_qdel_or_moved(obj/item/defibrillator/defib) +/obj/item/borg/upgrade/defib/backpack/proc/on_defib_instance_qdel_or_moved(obj/item/defibrillator/D) SIGNAL_HANDLER defib_instance = null if(!QDELETED(src)) @@ -507,11 +486,10 @@ QDEL_NULL(defib_instance) return ..() -/obj/item/borg/upgrade/defib/backpack/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/defib/backpack/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - defib_instance?.forceMove(borg.drop_location()) // [on_defib_instance_qdel_or_moved()] handles the rest. + 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" @@ -523,70 +501,81 @@ model_type = list(/obj/item/robot_model/medical, /obj/item/robot_model/syndicate_medical) model_flags = BORG_MODEL_MEDICAL - items_to_add = list(/obj/item/surgical_processor) +/obj/item/borg/upgrade/processor/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/surgical_processor/SP = new(R.model) + R.model.basic_modules += SP + R.model.add_module(SP, FALSE, TRUE) + +/obj/item/borg/upgrade/processor/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/surgical_processor/SP = locate() in R.model + R.model.remove_module(SP, TRUE) /obj/item/borg/upgrade/ai name = "B.O.R.I.S. module" desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI." icon_state = "boris" -/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - if(borg.key) //You cannot replace a player unless the key is completely removed. - to_chat(user, span_warning("Intelligence patterns detected in this [borg.braintype]. Aborting.")) - return FALSE + if(.) + 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. + to_chat(user, span_warning("Intelligence patterns detected in this [R.braintype]. Aborting.")) + return FALSE - borg.make_shell(src) + R.make_shell(src) -/obj/item/borg/upgrade/ai/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/ai/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!. || !borg.shell) - return . - - borg.undeploy() - borg.notify_ai(AI_NOTIFICATION_AI_SHELL) + if (.) + if(R.shell) + R.undeploy() + R.notify_ai(AI_NOTIFICATION_AI_SHELL) /obj/item/borg/upgrade/expand name = "borg expander" desc = "A cyborg resizer, it makes a cyborg huge." icon_state = "cyborg_upgrade3" -/obj/item/borg/upgrade/expand/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/expand/action(mob/living/silicon/robot/robot, user = usr) . = ..() - if(!. || HAS_TRAIT(borg, TRAIT_NO_TRANSFORM)) + if(!. || HAS_TRAIT(robot, TRAIT_NO_TRANSFORM)) return FALSE - if(borg.hasExpanded) + if(robot.hasExpanded) to_chat(usr, span_warning("This unit already has an expand module installed!")) return FALSE - ADD_TRAIT(borg, TRAIT_NO_TRANSFORM, REF(src)) - var/prev_lockcharge = borg.lockcharge - borg.SetLockdown(TRUE) - borg.set_anchored(TRUE) + ADD_TRAIT(robot, TRAIT_NO_TRANSFORM, REF(src)) + var/prev_lockcharge = robot.lockcharge + robot.SetLockdown(TRUE) + robot.set_anchored(TRUE) var/datum/effect_system/fluid_spread/smoke/smoke = new - smoke.set_up(1, holder = borg, location = borg.loc) + smoke.set_up(1, holder = robot, location = robot.loc) smoke.start() sleep(0.2 SECONDS) for(var/i in 1 to 4) - playsound(borg, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, TRUE, -1) + playsound(robot, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, TRUE, -1) sleep(1.2 SECONDS) if(!prev_lockcharge) - borg.SetLockdown(FALSE) - borg.set_anchored(FALSE) - REMOVE_TRAIT(borg, TRAIT_NO_TRANSFORM, REF(src)) - borg.hasExpanded = TRUE - borg.update_transform(2) + robot.SetLockdown(FALSE) + robot.set_anchored(FALSE) + REMOVE_TRAIT(robot, TRAIT_NO_TRANSFORM, REF(src)) + robot.hasExpanded = TRUE + robot.update_transform(2) -/obj/item/borg/upgrade/expand/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/expand/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - if (borg.hasExpanded) - borg.hasExpanded = FALSE - borg.update_transform(0.5) + if (.) + if (R.hasExpanded) + R.hasExpanded = FALSE + R.update_transform(0.5) /obj/item/borg/upgrade/rped name = "engineering cyborg RPED" @@ -597,7 +586,24 @@ model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) model_flags = BORG_MODEL_ENGINEERING - items_to_add = list(/obj/item/storage/part_replacer/cyborg) +/obj/item/borg/upgrade/rped/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/storage/part_replacer/cyborg/RPED = locate() in R + if(RPED) + to_chat(user, span_warning("This unit is already equipped with a RPED module!")) + return FALSE + + RPED = new(R.model) + R.model.basic_modules += RPED + R.model.add_module(RPED, FALSE, TRUE) + +/obj/item/borg/upgrade/rped/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/storage/part_replacer/cyborg/RPED = locate() in R.model + if (RPED) + R.model.remove_module(RPED, TRUE) /obj/item/borg/upgrade/inducer name = "engineering integrated power inducer" @@ -606,7 +612,24 @@ model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) model_flags = BORG_MODEL_ENGINEERING - items_to_add = list(/obj/item/inducer/cyborg) +/obj/item/borg/upgrade/inducer/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/inducer/cyborg/inter_inducer = locate() in R + if(inter_inducer) + return FALSE + inter_inducer = new(R.model) + R.model.basic_modules += inter_inducer + R.model.add_module(inter_inducer, FALSE, TRUE) + inter_inducer.cell = R.cell + +/obj/item/borg/upgrade/inducer/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/inducer/cyborg/inter_inducer = locate() in R.model + if (inter_inducer) + R.model.remove_module(inter_inducer, TRUE) + inter_inducer.cell = null /obj/item/inducer/cyborg name = "Internal inducer" @@ -622,32 +645,39 @@ require_model = TRUE model_type = list(/obj/item/robot_model/medical, /obj/item/robot_model/syndicate_medical) model_flags = BORG_MODEL_MEDICAL - - items_to_add = list(/obj/item/pinpointer/crew) var/datum/action/crew_monitor -/obj/item/borg/upgrade/pinpointer/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/pinpointer/action(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - crew_monitor = new /datum/action/item_action/crew_monitor(src) - crew_monitor.Grant(borg) - icon_state = "scanner" + if(.) + + var/obj/item/pinpointer/crew/PP = locate() in R.model + if(PP) + to_chat(user, span_warning("This unit is already equipped with a pinpointer module!")) + return FALSE + + PP = new(R.model) + R.model.basic_modules += PP + R.model.add_module(PP, FALSE, TRUE) + crew_monitor = new /datum/action/item_action/crew_monitor(src) + crew_monitor.Grant(R) + icon_state = "scanner" -/obj/item/borg/upgrade/pinpointer/deactivate(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/pinpointer/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() - if(!.) - return . - icon_state = "pinpointer_crew" - crew_monitor.Remove(borg) - QDEL_NULL(crew_monitor) + if (.) + icon_state = "pinpointer_crew" + crew_monitor.Remove(R) + QDEL_NULL(crew_monitor) + var/obj/item/pinpointer/crew/PP = locate() in R.model + R.model.remove_module(PP, TRUE) /obj/item/borg/upgrade/pinpointer/ui_action_click() if(..()) return - var/mob/living/silicon/robot/borg = usr - GLOB.crewmonitor.show(borg,borg) + var/mob/living/silicon/robot/Cyborg = usr + GLOB.crewmonitor.show(Cyborg,Cyborg) /datum/action/item_action/crew_monitor name = "Interface With Crew Monitor" @@ -658,10 +688,10 @@ icon_state = "cyborg_upgrade3" var/obj/item/robot_model/new_model = null -/obj/item/borg/upgrade/transform/action(mob/living/silicon/robot/borg, mob/living/user = usr) +/obj/item/borg/upgrade/transform/action(mob/living/silicon/robot/R, user = usr) . = ..() if(. && new_model) - borg.model.transform_to(new_model) + R.model.transform_to(new_model) /obj/item/borg/upgrade/transform/clown name = "borg model picker (Clown)" @@ -677,7 +707,24 @@ model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) model_flags = BORG_MODEL_ENGINEERING - items_to_add = list(/obj/item/borg/apparatus/circuit) +/obj/item/borg/upgrade/circuit_app/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/borg/apparatus/circuit/C = locate() in R.model.modules + if(C) + to_chat(user, span_warning("This unit is already equipped with a circuit apparatus!")) + return FALSE + + C = new(R.model) + R.model.basic_modules += C + R.model.add_module(C, FALSE, TRUE) + +/obj/item/borg/upgrade/circuit_app/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/borg/apparatus/circuit/C = locate() in R.model.modules + if (C) + R.model.remove_module(C, TRUE) /obj/item/borg/upgrade/beaker_app name = "beaker storage apparatus" @@ -687,7 +734,24 @@ model_type = list(/obj/item/robot_model/medical) model_flags = BORG_MODEL_MEDICAL - items_to_add = list(/obj/item/borg/apparatus/beaker/extra) +/obj/item/borg/upgrade/beaker_app/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/borg/apparatus/beaker/extra/E = locate() in R.model.modules + if(E) + to_chat(user, span_warning("This unit has no room for additional beaker storage!")) + return FALSE + + E = new(R.model) + R.model.basic_modules += E + R.model.add_module(E, FALSE, TRUE) + +/obj/item/borg/upgrade/beaker_app/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/borg/apparatus/beaker/extra/E = locate() in R.model.modules + if (E) + R.model.remove_module(E, TRUE) /obj/item/borg/upgrade/drink_app name = "glass storage apparatus" @@ -697,7 +761,24 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE - items_to_add = list(/obj/item/borg/apparatus/beaker/drink) +/obj/item/borg/upgrade/drink_app/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/borg/apparatus/beaker/drink/E = locate() in R.model.modules + if(E) + to_chat(user, span_warning("This unit has no room for additional drink storage!")) + return FALSE + + E = new(R.model) + R.model.basic_modules += E + R.model.add_module(E, FALSE, TRUE) + +/obj/item/borg/upgrade/drink_app/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/borg/apparatus/beaker/drink/E = locate() in R.model.modules + if (E) + R.model.remove_module(E, TRUE) /obj/item/borg/upgrade/broomer name = "experimental push broom" @@ -707,7 +788,25 @@ model_type = list(/obj/item/robot_model/janitor) model_flags = BORG_MODEL_JANITOR - items_to_add = list(/obj/item/pushbroom/cyborg) +/obj/item/borg/upgrade/broomer/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if (!.) + return + var/obj/item/pushbroom/cyborg/BR = locate() in R.model.modules + if (BR) + to_chat(user, span_warning("This janiborg is already equipped with an experimental broom!")) + return FALSE + BR = new(R.model) + R.model.basic_modules += BR + R.model.add_module(BR, FALSE, TRUE) + +/obj/item/borg/upgrade/broomer/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (!.) + return + var/obj/item/pushbroom/cyborg/BR = locate() in R.model.modules + if (BR) + R.model.remove_module(BR, TRUE) /obj/item/borg/upgrade/condiment_synthesizer name = "Service Cyborg Condiment Synthesiser" @@ -717,7 +816,25 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE - items_to_add = list(/obj/item/reagent_containers/borghypo/condiment_synthesizer) +/obj/item/borg/upgrade/condiment_synthesizer/action(mob/living/silicon/robot/install, user = usr) + . = ..() + if(!.) + return FALSE + var/obj/item/reagent_containers/borghypo/condiment_synthesizer/cynthesizer = locate() in install.model.modules + if(cynthesizer) + install.balloon_alert_to_viewers("already installed!") + return FALSE + cynthesizer = new(install.model) + install.model.basic_modules += cynthesizer + install.model.add_module(cynthesizer, FALSE, TRUE) + +/obj/item/borg/upgrade/condiment_synthesizer/deactivate(mob/living/silicon/robot/install, user = usr) + . = ..() + if (!.) + return FALSE + var/obj/item/reagent_containers/borghypo/condiment_synthesizer/cynthesizer = locate() in install.model.modules + if (cynthesizer) + install.model.remove_module(cynthesizer, TRUE) /obj/item/borg/upgrade/silicon_knife name = "Service Cyborg Kitchen Toolset" @@ -727,7 +844,25 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE - items_to_add = list(/obj/item/knife/kitchen/silicon) +/obj/item/borg/upgrade/silicon_knife/action(mob/living/silicon/robot/install, user = usr) + . = ..() + if(!.) + return FALSE + var/obj/item/knife/kitchen/silicon/snife = locate() in install.model.modules + if(snife) + install.balloon_alert_to_viewers("already installed!") + return FALSE + snife = new(install.model) + install.model.basic_modules += snife + install.model.add_module(snife, FALSE, TRUE) + +/obj/item/borg/upgrade/silicon_knife/deactivate(mob/living/silicon/robot/install, user = usr) + . = ..() + if (!.) + return FALSE + var/obj/item/knife/kitchen/silicon/snife = locate() in install.model.modules + if (snife) + install.model.remove_module(snife, TRUE) /obj/item/borg/upgrade/service_apparatus name = "Service Cyborg Service Apparatus" @@ -737,16 +872,54 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE - items_to_add = list(/obj/item/borg/apparatus/service) +/obj/item/borg/upgrade/service_apparatus/action(mob/living/silicon/robot/install, user = usr) + . = ..() + if(!.) + return FALSE + var/obj/item/borg/apparatus/service/saparatus = locate() in install.model.modules + if(saparatus) + install.balloon_alert_to_viewers("already installed!") + return FALSE + saparatus = new(install.model) + install.model.basic_modules += saparatus + install.model.add_module(saparatus, FALSE, TRUE) + +/obj/item/borg/upgrade/service_apparatus/deactivate(mob/living/silicon/robot/install, user = usr) + . = ..() + if (!.) + return FALSE + var/obj/item/borg/apparatus/service/saparatus = locate() in install.model.modules + if (saparatus) + install.model.remove_module(saparatus, TRUE) /obj/item/borg/upgrade/rolling_table name = "Service Cyborg Rolling Table Dock" desc = "An upgrade to the service model cyborg, to help provide mobile service." icon_state = "cyborg_upgrade3" require_model = TRUE - model_type = list(/obj/item/rolling_table_dock) + model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE +/obj/item/borg/upgrade/rolling_table/action(mob/living/silicon/robot/install, user = usr) + . = ..() + if(!.) + return FALSE + var/obj/item/rolling_table_dock/rtable = locate() in install.model.modules + if(rtable) + install.balloon_alert_to_viewers("already installed!") + return FALSE + rtable = new(install.model) + install.model.basic_modules += rtable + install.model.add_module(rtable, FALSE, TRUE) + +/obj/item/borg/upgrade/rolling_table/deactivate(mob/living/silicon/robot/install, user = usr) + . = ..() + if (!.) + return FALSE + var/obj/item/rolling_table_dock/rtable = locate() in install.model.modules + if (rtable) + install.model.remove_module(rtable, TRUE) + /obj/item/borg/upgrade/service_cookbook name = "Service Cyborg Cookbook" desc = "An upgrade to the service model cyborg, that lets them create more foods." @@ -755,7 +928,25 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE - model_type = list(/obj/item/borg/cookbook) +/obj/item/borg/upgrade/service_cookbook/action(mob/living/silicon/robot/install, user = usr) + . = ..() + if(!.) + return FALSE + var/obj/item/borg/cookbook/book = locate() in install.model.modules + if(book) + install.balloon_alert_to_viewers("already installed!") + return FALSE + book = new(install.model) + install.model.basic_modules += book + install.model.add_module(book, FALSE, TRUE) + +/obj/item/borg/upgrade/service_cookbook/deactivate(mob/living/silicon/robot/install, user = usr) + . = ..() + if (!.) + return FALSE + var/obj/item/borg/cookbook/book = locate() in install.model.modules + if(book) + install.model.remove_module(book, TRUE) ///This isn't an upgrade or part of the same path, but I'm gonna just stick it here because it's a tool used on cyborgs. //A reusable tool that can bring borgs back to life. They gotta be repaired first, though. diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index c3e384dcb70c..cb45306702c5 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1260,7 +1260,7 @@ name = "Diamond Drill" id = "borg_upgrade_diamonddrill" build_type = MECHFAB - build_path = /obj/item/borg/upgrade/diamond_drill + build_path = /obj/item/borg/upgrade/ddrill materials = list( /datum/material/iron=SHEET_MATERIAL_AMOUNT*5, /datum/material/glass =SHEET_MATERIAL_AMOUNT*3, From e20ca54101b9223e74b4dd89e2cd3fb5ae3d4c09 Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 01:01:41 +1300 Subject: [PATCH 10/13] fixes Co-Authored-By: Jeremiah <42397676+jlsnow301@users.noreply.github.com> --- maplestation_modules/code/modules/objects/robot_magic.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maplestation_modules/code/modules/objects/robot_magic.dm b/maplestation_modules/code/modules/objects/robot_magic.dm index 0aa7248ecf9f..252ccd569785 100644 --- a/maplestation_modules/code/modules/objects/robot_magic.dm +++ b/maplestation_modules/code/modules/objects/robot_magic.dm @@ -31,8 +31,7 @@ //put the upgrade's magic pool into the borg. if(src.mana_pool != null) - mana_pool = borg.initialize_mana_pool(src.mana_pool) - borg.set_mana_pool(mana_pool) // no need to check if the borg has a mana pool, as this makes one. + borg.set_mana_pool(src.mana_pool) // no need to check if the borg has a mana pool, as this makes one. //if the upgrade has no magic pool for some reason, make one! else From 35286201f84174b26fbe7e4666fddeeaa5acabfd Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 01:13:52 +1300 Subject: [PATCH 11/13] fixy fixy --- maplestation_modules/code/modules/objects/robot_magic.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maplestation_modules/code/modules/objects/robot_magic.dm b/maplestation_modules/code/modules/objects/robot_magic.dm index 252ccd569785..5dc6b0450102 100644 --- a/maplestation_modules/code/modules/objects/robot_magic.dm +++ b/maplestation_modules/code/modules/objects/robot_magic.dm @@ -15,7 +15,7 @@ maximum_mana_capacity = CARBON_BASE_MANA_CAPACITY //same as carbons! /obj/item/borg/upgrade/magic/get_initial_mana_pool_type() - return /datum/mana_pool/mob/living/silicon + return /datum/mana_pool/borg_focus /obj/item/borg/upgrade/magic/action(mob/living/silicon/robot/borg) . = ..() @@ -31,6 +31,7 @@ //put the upgrade's magic pool into the borg. if(src.mana_pool != null) + borg.initialize_mana_pool(src.mana_pool) borg.set_mana_pool(src.mana_pool) // no need to check if the borg has a mana pool, as this makes one. //if the upgrade has no magic pool for some reason, make one! From 6c8f68e78c26a93e25f1ad6605acf3d2f556e50b Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 13:16:32 +1300 Subject: [PATCH 12/13] Fixes the borg panel so that it works. Co-Authored-By: Ossa88 (SYNAPSE) <8151625+ossa88@users.noreply.github.com> --- code/modules/admin/verbs/borgpanel.dm | 33 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index b8fd3698a563..fca4b543f6ad 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -51,11 +51,24 @@ "scrambledcodes" = borg.scrambledcodes ) .["upgrades"] = list() - var/static/list/not_shown_upgrades = list(/obj/item/borg/upgrade/hypospray) - for (var/upgradetype in subtypesof(/obj/item/borg/upgrade)-not_shown_upgrades) //hypospray is a dummy parent for hypospray upgrades - var/obj/item/borg/upgrade/upgrade = upgradetype - if (initial(upgrade.model_type) && !is_type_in_list(borg.model, initial(upgrade.model_type))) // Upgrade requires a different model //HEY ASSHOLE, INITIAL DOESNT WORK WITH LISTS - continue + var/list/excluded_upgrades = list( + /obj/item/borg/upgrade/hypospray, //hypospray is a dummy parent for hypospray upgrades + /obj/item/borg/upgrade/transform, + /obj/item/borg/upgrade/rename, + /obj/item/borg_restart_board, + /obj/item/borg/upgrade/modkit, + ) + for (var/upgradetype in subtypesof(/obj/item/borg/upgrade)-excluded_upgrades) + var/obj/item/borg/upgrade/upgrade = new upgradetype() + if(upgrade.model_type) // Only show upgrades that can be given. Cannot initial() lists either. + // is_type_in_list() doesn't work, so this: + var/has_req_module = FALSE + for(var/req_model_type in upgrade.model_type) + if(borg.model.type == req_model_type) + has_req_module = TRUE + break + if(!has_req_module) + continue var/installed = FALSE if (locate(upgradetype) in borg) installed = TRUE @@ -79,7 +92,7 @@ .["ais"] += list(list("name" = ai.name, "ref" = REF(ai), "connected" = (borg.connected_ai == ai))) -/datum/borgpanel/ui_act(action, params) +/datum/borgpanel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() if(.) return @@ -149,17 +162,19 @@ borg.fully_replace_character_name(borg.real_name,new_name) if ("toggle_upgrade") var/upgradepath = text2path(params["upgrade"]) - var/obj/item/borg/upgrade/installedupgrade = locate(upgradepath) in borg + var/obj/item/borg/upgrade/installedupgrade = locate(upgradepath) in borg.upgrades if (installedupgrade) message_admins("[key_name_admin(user)] removed the [installedupgrade] upgrade from [ADMIN_LOOKUPFLW(borg)].") log_silicon("[key_name(user)] removed the [installedupgrade] upgrade from [key_name(borg)].") qdel(installedupgrade) // see [mob/living/silicon/robot/on_upgrade_deleted()]. else var/obj/item/borg/upgrade/upgrade = new upgradepath(borg) - upgrade.action(borg, user) - borg.upgrades += upgrade message_admins("[key_name_admin(user)] added the [upgrade] borg upgrade to [ADMIN_LOOKUPFLW(borg)].") log_silicon("[key_name(user)] added the [upgrade] borg upgrade to [key_name(borg)].") + if(upgrade.action(borg, user)) + borg.add_to_upgrades(upgrade) + else + qdel(upgrade) if ("toggle_radio") var/channel = params["channel"] if (channel in borg.radio.channels) // We're removing a channel From a8649810f285579b48c4c9840c9148424361a53f Mon Sep 17 00:00:00 2001 From: Constellado <64122807+Constellado@users.noreply.github.com> Date: Thu, 26 Dec 2024 15:34:05 +1300 Subject: [PATCH 13/13] fixes --- .../code/modules/objects/robot_magic.dm | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/maplestation_modules/code/modules/objects/robot_magic.dm b/maplestation_modules/code/modules/objects/robot_magic.dm index 5dc6b0450102..450b52ed2e82 100644 --- a/maplestation_modules/code/modules/objects/robot_magic.dm +++ b/maplestation_modules/code/modules/objects/robot_magic.dm @@ -30,14 +30,9 @@ borg_mana_pool = borg.mana_pool //put the upgrade's magic pool into the borg. - if(src.mana_pool != null) - borg.initialize_mana_pool(src.mana_pool) - borg.set_mana_pool(src.mana_pool) // no need to check if the borg has a mana pool, as this makes one. + borg.initialize_mana_pool_if_possible() - //if the upgrade has no magic pool for some reason, make one! - else - mana_pool = borg.initialize_mana_pool(src.mana_pool) - borg.set_mana_pool(mana_pool) + borg.set_mana_pool(mana_pool) /obj/item/borg/upgrade/magic/deactivate(mob/living/silicon/robot/borg) . = ..() @@ -47,17 +42,6 @@ action_to_remove.Remove(borg) //resets the mana pool to before borg.set_mana_pool(borg_mana_pool) + borg.initialize_mana_pool_if_possible() borg_mana_pool = null //removes the borg's mana pool var from the upgrade as this upgrade being removed from the borg -//borg panel qdels, so i gotta make sure it works when borg panel removes it. -// /obj/item/borg/upgrade/magic/proc/clear_on_delete(datum/to_clear) -// RegisterSignal(to_clear, COMSIG_QDELETING, PROC_REF(on_delete)) - -// /obj/item/borg/upgrade/magic/proc/on_delete() -// if(.) -// //removes the spells -// for (var/datum/action/cooldown/spell/action_to_remove in borg.actions) -// action_to_remove.Remove(borg) -// //resets the mana pool to before -// borg.set_mana_pool(borg_mana_pool) -// borg_mana_pool = null //removes the borg's mana pool var from the upgrade as this upgrade being removed from the borg