diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index c476232387d..7d96db38a05 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -148,9 +148,9 @@
infodisplay += mymob.healths
//Installed Module
- mymob.hands = new /obj/screen/robot/module()
- mymob.hands.screen_loc = ui_borg_module
- static_inventory += mymob.hands
+ mymobR.hands = new /obj/screen/robot/module()
+ mymobR.hands.screen_loc = ui_borg_module
+ static_inventory += mymobR.hands
module_store_icon = new /obj/screen/robot/store()
module_store_icon.screen_loc = ui_borg_store
@@ -176,6 +176,17 @@
static_inventory += using
mymobR.thruster_button = using
+/datum/hud/robot/Destroy()
+ var/mob/living/silicon/robot/myrob = mymob
+ myrob.inv1 = null
+ myrob.hands = null
+ myrob.inv2 = null
+ myrob.inv3 = null
+ myrob.lamp_button = null
+ myrob.thruster_button = null
+
+ return ..()
+
/datum/hud/proc/toggle_show_robot_modules()
if(!isrobot(mymob))
return
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index e3049e47634..9fedbe4c8d9 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -295,15 +295,12 @@
O.job = "Cyborg"
- O.cell = chest.cell
+ var/datum/robot_component/cell_component = O.components["power cell"]
+ cell_component.install(chest.cell)
chest.cell.forceMove(O)
chest.cell = null
+
M.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
- // Since we "magically" installed a cell, we also have to update the correct component.
- if(O.cell)
- var/datum/robot_component/cell_component = O.components["power cell"]
- cell_component.wrapped = O.cell
- cell_component.installed = 1
O.mmi = W
O.Namepick()
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index 634f7951663..9f71b00aad6 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -30,7 +30,8 @@
if(isAI(owner.current))
var/mob/living/silicon/ai/A = owner.current
A.clear_zeroth_law()
- A.common_radio.channels.Remove("Syndicate") // De-traitored AIs can still state laws over the syndicate channel without this
+ var/obj/item/radio/headset/heads/ai_integrated/radio = A.get_radio()
+ radio.channels.Remove("Syndicate") // De-traitored AIs can still state laws over the syndicate channel without this
A.laws.sorted_laws = A.laws.inherent_laws.Copy() // AI's 'notify laws' button will still state a law 0 because sorted_laws contains it
A.show_laws()
A.remove_malf_abilities()
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 55a82df214b..6ebc95cc177 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -163,7 +163,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
aiMulti = new(src)
aiRadio = new(src)
- common_radio = aiRadio
aiRadio.myAi = src
additional_law_channels["Binary"] = ":b "
additional_law_channels["Holopad"] = ":h"
@@ -172,7 +171,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(isturf(loc))
add_ai_verbs(src)
-
+
// Remove inherited verbs that effectively do nothing for AIs, or lead to unintended behaviour.
verbs -= /mob/living/verb/lay_down
verbs -= /mob/living/verb/mob_sleep
@@ -238,6 +237,9 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
QDEL_NULL(builtInCamera)
return ..()
+/mob/living/silicon/ai/get_radio()
+ return aiRadio
+
/mob/living/silicon/ai/proc/on_mob_init()
to_chat(src, "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).")
to_chat(src, "To look at other parts of the station, click on yourself to get a camera menu.")
@@ -247,11 +249,11 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "For department channels, use the following say commands:")
var/radio_text = ""
- for(var/i = 1 to common_radio.channels.len)
- var/channel = common_radio.channels[i]
+ for(var/i = 1 to aiRadio.channels.len)
+ var/channel = aiRadio.channels[i]
var/key = get_radio_key_from_channel(channel)
radio_text += "[key] - [channel]"
- if(i != common_radio.channels.len)
+ if(i != aiRadio.channels.len)
radio_text += ", "
to_chat(src, radio_text)
diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm
index 046c215f969..f6ad59bd794 100644
--- a/code/modules/mob/living/silicon/laws.dm
+++ b/code/modules/mob/living/silicon/laws.dm
@@ -116,7 +116,8 @@
/mob/living/silicon/proc/law_channels()
var/list/channels = new()
channels += MAIN_CHANNEL
- channels += common_radio.channels
+ var/obj/item/radio/radio = get_radio()
+ channels += radio.channels
channels += additional_law_channels
return channels
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index 9b553d58b39..c3c35180305 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -2,7 +2,7 @@
/datum/robot_component
var/name = "Component"
- var/installed = 0
+ var/installed = FALSE
var/powered = 1
var/toggled = 1
var/brute_damage = 0
@@ -16,27 +16,33 @@
/datum/robot_component/New(mob/living/silicon/robot/R)
owner = R
-/datum/robot_component/proc/install()
+// Should only ever be destroyed when a borg gets destroyed
+/datum/robot_component/Destroy(force, ...)
+ owner = null
+ QDEL_NULL(wrapped)
+ return ..()
+
+/datum/robot_component/proc/install(obj/item/I, update_health = TRUE)
+ wrapped = I
+ installed = TRUE
go_online()
- owner.updatehealth("component '[src]' installed")
+ if(update_health)
+ owner.updatehealth("component '[src]' installed")
/datum/robot_component/proc/uninstall()
+ wrapped = null
+ installed = FALSE
go_offline()
owner.updatehealth("component '[src]' removed")
/datum/robot_component/proc/destroy()
if(wrapped)
qdel(wrapped)
-
-
+ uninstall()
wrapped = new/obj/item/broken_device
- // The thing itself isn't there anymore, but some fried remains are.
- installed = -1
- uninstall()
-
/datum/robot_component/proc/take_damage(brute, electronics, sharp, updating_health = TRUE)
- if(installed != 1)
+ if(!installed)
return
if(owner && updating_health)
@@ -51,7 +57,7 @@
SStgui.update_uis(owner.self_diagnosis)
/datum/robot_component/proc/heal_damage(brute, electronics, updating_health = TRUE)
- if(installed != 1)
+ if(!installed)
// If it's not installed, can't repair it.
return 0
@@ -64,7 +70,14 @@
SStgui.update_uis(owner.self_diagnosis)
/datum/robot_component/proc/is_powered()
- return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (powered)
+ return installed && (brute_damage + electronics_damage < max_damage) && (powered)
+
+/datum/robot_component/proc/is_destroyed()
+ return istype(wrapped, /obj/item/broken_device)
+
+
+/datum/robot_component/proc/is_missing()
+ return isnull(wrapped)
/datum/robot_component/proc/consume_power()
if(toggled == 0)
@@ -113,16 +126,22 @@
name = "power cell"
max_damage = 50
-/datum/robot_component/cell/New(mob/living/silicon/robot/R)
- . = ..()
- // sets `external_type` to the borg's currently installed cell type
- if(owner.cell)
- var/obj/item/stock_parts/cell/C = owner.cell
- external_type = C.type
+/datum/robot_component/cell/install(obj/item/stock_parts/cell/C)
+ ..()
+ external_type = C.type // Update the cell component's `external_type` to the path of new cell
+ owner.cell = C
+
+/datum/robot_component/cell/uninstall()
+ ..()
+ owner.cell = null
/datum/robot_component/cell/is_powered()
return ..() && owner.cell
+/datum/robot_component/cell/Destroy(force, ...)
+ owner.cell = null
+ return ..()
+
/datum/robot_component/cell/destroy()
..()
owner.cell = null
@@ -168,7 +187,7 @@
/mob/living/silicon/robot/proc/is_component_functioning(module_name)
var/datum/robot_component/C = components[module_name]
- return C && C.installed == 1 && C.toggled && C.is_powered() && !C.component_disabled
+ return C && C.installed && C.toggled && C.is_powered() && !C.component_disabled
/mob/living/silicon/robot/proc/disable_component(module_name, duration)
var/datum/robot_component/D = get_component(module_name)
@@ -282,7 +301,7 @@
for(var/datum/robot_component/org in damaged)
user.show_message(text("\t []: [][] - [] - [] - []", \
capitalize(org.name), \
- (org.installed == -1) ? "DESTROYED " :"",\
+ (org.is_destroyed()) ? "DESTROYED " :"",\
(org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \
(org.brute_damage > 0) ? "[org.brute_damage]" :0, \
(org.toggled) ? "Toggled ON" : "Toggled OFF",\
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 339860971b2..6d310681944 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
//Hud stuff
+ var/obj/screen/hands = null
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
@@ -136,10 +137,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
update_headlamp()
radio = new /obj/item/radio/borg(src)
- common_radio = radio
-
- if(!cell) // Make sure a new cell gets created *before* executing initialize_components(). The cell component needs an existing cell for it to get set up properly
- cell = new default_cell_type(src)
init(alien, connect_to_AI, ai_to_sync_to)
@@ -159,8 +156,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
// Create all the robot parts.
for(var/V in components) if(V != "power cell")
var/datum/robot_component/C = components[V]
- C.installed = 1
- C.wrapped = new C.external_type
+ C.install(new C.external_type, FALSE)
..()
@@ -170,17 +166,19 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
verbs -= /mob/living/verb/lay_down
verbs -= /mob/living/verb/mob_sleep
- if(cell)
- var/datum/robot_component/cell_component = components["power cell"]
- cell_component.wrapped = cell
- cell_component.installed = 1
- cell_component.install()
+ // Install a default cell into the borg if none is there yet
+ var/datum/robot_component/cell_component = components["power cell"]
+ var/obj/item/stock_parts/cell/C = cell || new default_cell_type(src)
+ cell_component.install(C)
diag_hud_set_borgcell()
scanner = new(src)
scanner.Grant(src)
RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/create_trail)
+/mob/living/silicon/robot/get_radio()
+ return radio
+
/mob/living/silicon/robot/proc/create_trail(datum/source, atom/oldloc, _dir, forced)
if(ionpulse_on)
var/turf/T = get_turf(oldloc)
@@ -296,10 +294,14 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
QDEL_NULL(wires)
QDEL_NULL(module)
QDEL_NULL(camera)
- QDEL_NULL(cell)
QDEL_NULL(robot_suit)
QDEL_NULL(spark_system)
QDEL_NULL(self_diagnosis)
+ QDEL_LIST_ASSOC_VAL(components)
+ QDEL_NULL(rbPDA)
+ QDEL_NULL(radio)
+ scanner = null
+ module_actions.Cut()
return ..()
/mob/living/silicon/robot/proc/pick_module()
@@ -490,7 +492,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
for(var/V in components)
if(V == "power cell") continue
var/datum/robot_component/C = components[V]
- if(C.installed)
+ if(!C.is_missing())
installed_components += V
var/toggle = input(src, "Which component do you want to toggle?", "Toggle Component") as null|anything in installed_components
@@ -658,11 +660,11 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(istype(W, /obj/item/robot_parts/robot_component) && opened)
for(var/V in components)
var/datum/robot_component/C = components[V]
- if(!C.installed && istype(W, C.external_type))
- C.installed = 1
- C.wrapped = W
- C.install()
- user.drop_item()
+ if(C.is_missing() && istype(W, C.external_type))
+ if(!user.drop_item())
+ to_chat(user, "[W] seems to be stuck in your hand!")
+ return
+ C.install(W)
W.loc = null
var/obj/item/robot_parts/robot_component/WC = W
@@ -698,13 +700,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
else
user.drop_item()
W.loc = src
- cell = W
to_chat(user, "You insert the power cell.")
-
- C.installed = 1
- C.wrapped = W
- C.install()
- C.external_type = W.type // Update the cell component's `external_type` to the path of new cell
+ C.install(W)
//This will mean that removing and replacing a power cell will repair the mount, but I don't care at this point. ~Z
C.brute_damage = 0
C.electronics_damage = 0
@@ -837,7 +834,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(V == "power cell")
continue
var/datum/robot_component/C = components[V]
- if(C.installed == 1 || C.installed == -1)
+ if(!C.is_missing())
removable_components += V
if(module)
removable_components += module.custom_removals
@@ -856,9 +853,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
thing.burn = C.electronics_damage
thing.loc = loc
- var/was_installed = C.installed
- C.installed = 0
- if(was_installed == 1)
+ if(C.installed)
C.uninstall()
@@ -1438,12 +1433,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
for(var/datum/robot_component/borked_part in borked_parts)
brute = borked_part.brute_damage
burn = borked_part.electronics_damage
- borked_part.installed = 1
- borked_part.wrapped = new borked_part.external_type
- if(ispath(borked_part.external_type, /obj/item/stock_parts/cell)) // is the broken part a cell?
- cell = new borked_part.external_type // borgs that have their cell destroyed have their `cell` var set to null. we need create a new cell for them based on their old cell type.
borked_part.heal_damage(brute,burn)
- borked_part.install()
+ borked_part.install(new borked_part.external_type)
/mob/living/silicon/robot/proc/check_sprite(spritename)
. = FALSE
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index 8f7e86f4c57..71c2ce2b4f4 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -6,7 +6,7 @@
var/amount = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
- if(C.installed != 0 && (!repairable_only || C.installed != -1)) // Installed ones only and if repair only remove the borked ones
+ if(C.installed || (!repairable_only && C.is_destroyed())) // Installed ones only and if repair only remove the borked ones
amount += C.brute_damage
return amount
@@ -14,7 +14,7 @@
var/amount = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
- if(C.installed != 0 && (!repairable_only || C.installed != -1)) // Installed ones only and if repair only remove the borked ones
+ if(C.installed || (!repairable_only && C.is_destroyed())) // Installed ones only and if repair only remove the borked ones
amount += C.electronics_damage
return amount
@@ -36,7 +36,7 @@
var/list/datum/robot_component/parts = list()
for(var/V in components)
var/datum/robot_component/C = components[V]
- if((C.installed == 1 || (get_borked && C.installed == -1) || (get_missing && C.installed == 0)) && ((get_brute && C.brute_damage) || (get_burn && C.electronics_damage)))
+ if((C.installed || (get_borked && C.is_destroyed()) || (get_missing && C.is_missing())) && ((get_brute && C.brute_damage) || (get_burn && C.electronics_damage)))
parts += C
return parts
@@ -44,7 +44,7 @@
var/list/datum/robot_component/parts = list()
for(var/V in components)
var/datum/robot_component/C = components[V]
- if(C.installed == 0)
+ if(C.is_missing())
parts += C
return parts
@@ -52,7 +52,7 @@
var/list/rval = new
for(var/V in components)
var/datum/robot_component/C = components[V]
- if(C.installed == 1)
+ if(C.installed)
rval += C
return rval
@@ -60,7 +60,7 @@
if(!LAZYLEN(components))
return 0
var/datum/robot_component/C = components["armour"]
- if(C && C.installed == 1)
+ if(C && C.installed)
return C
return 0
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 6469bfbf6a6..9faa3c1c6d8 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -43,9 +43,7 @@
cell.add_fingerprint(user)
user.put_in_active_hand(cell)
to_chat(user, "You remove \the [cell].")
- cell = null
var/datum/robot_component/C = components["power cell"]
- C.installed = 0
C.uninstall()
module?.update_cells(TRUE)
diag_hud_set_borgcell()
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 2ca6822951a..60fbcd8459e 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -36,8 +36,6 @@
var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use
var/d_hud = DATA_HUD_DIAGNOSTIC_BASIC //There is only one kind of diag hud
- var/obj/item/radio/common_radio
-
/mob/living/silicon/New()
GLOB.silicon_mob_list |= src
..()
@@ -66,8 +64,12 @@
QDEL_NULL(crew_monitor)
QDEL_NULL(law_manager)
QDEL_NULL(power_monitor)
+ QDEL_NULL(aiCamera)
return ..()
+/mob/living/silicon/proc/get_radio()
+ return
+
/mob/living/silicon/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 2f7511e3b04..fe3cb652939 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -12,7 +12,6 @@
/// The zone this mob is currently targeting
var/zone_selected = null
- var/obj/screen/hands = null
var/obj/screen/pullin = null
var/obj/screen/i_select = null
var/obj/screen/m_select = null
diff --git a/code/modules/tgui/modules/robot_self_diagnosis.dm b/code/modules/tgui/modules/robot_self_diagnosis.dm
index be4a3ee8ad0..3d06eaf067f 100644
--- a/code/modules/tgui/modules/robot_self_diagnosis.dm
+++ b/code/modules/tgui/modules/robot_self_diagnosis.dm
@@ -20,7 +20,7 @@
var/datum/robot_component/C = owner.components[c]
data["component_data"] += list(list(
"name" = C.name,
- "installed" = C.installed,
+ "installed" = C.is_destroyed() ? -1 : C.installed,
"brute_damage" = C.brute_damage,
"electronic_damage" = C.electronics_damage,
"max_damage" = C.max_damage,