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,