diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index dcdf5aa268..017a3f8bfe 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -9,17 +9,18 @@ #define IMPLOYAL_HUD "5" // loyality implant #define IMPCHEM_HUD "6" // chemical implant #define IMPTRACK_HUD "7" // tracking implant -#define DIAG_STAT_HUD "8" // Silicon/Mech Status +#define DIAG_STAT_HUD "8" // Silicon/Mech/Circuit Status #define DIAG_HUD "9" // Silicon health bar -#define DIAG_BATT_HUD "10"// Borg/Mech power meter +#define DIAG_BATT_HUD "10"// Borg/Mech/Circutry power meter #define DIAG_MECH_HUD "11"// Mech health bar #define DIAG_BOT_HUD "12"// Bot HUDs -#define DIAG_TRACK_HUD "13"// Mech tracking beacon -#define DIAG_AIRLOCK_HUD "14"//Airlock shock overlay -#define DIAG_PATH_HUD "15"//Bot path indicators -#define GLAND_HUD "16"//Gland indicators for abductors +#define DIAG_CIRCUIT_HUD "13"// Circuit assembly health bar +#define DIAG_TRACK_HUD "14"// Mech/Silicon tracking beacon, Circutry long range icon +#define DIAG_AIRLOCK_HUD "15"//Airlock shock overlay +#define DIAG_PATH_HUD "16"//Bot path indicators +#define GLAND_HUD "17"//Gland indicators for abductors //for antag huds. these are used at the /mob level -#define ANTAG_HUD "17" +#define ANTAG_HUD "18" //by default everything in the hud_list of an atom is an image //a value in hud_list with one of these will change that behavior diff --git a/code/__DEFINES/integrated_electronics.dm b/code/__DEFINES/integrated_electronics.dm index 77ee69892e..a7f732f646 100644 --- a/code/__DEFINES/integrated_electronics.dm +++ b/code/__DEFINES/integrated_electronics.dm @@ -10,6 +10,11 @@ #define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box and able to be printed in the IC printer. #define IC_SPAWN_RESEARCH 2 // If the circuit design will be available in the IC printer after upgrading it. +// Categories that help differentiate circuits that can do different tipes of actions +#define IC_ACTION_MOVEMENT 1 // If the circuit can move the assembly +#define IC_ACTION_COMBAT 2 // If the circuit can cause harm +#define IC_ACTION_LONG_RANGE 4 // If the circuit communicate with something outside of the assembly + // Displayed along with the pin name to show what type of pin it is. #define IC_FORMAT_ANY "\" #define IC_FORMAT_STRING "\" diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 585feba979..8024322037 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -52,10 +52,10 @@ /datum/atom_hud/data/diagnostic /datum/atom_hud/data/diagnostic/basic - hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD) + hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD) /datum/atom_hud/data/diagnostic/advanced - hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_PATH_HUD) + hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_PATH_HUD) /datum/atom_hud/data/bot_path hud_icons = list(DIAG_PATH_HUD) @@ -415,6 +415,56 @@ else holder.icon_state = "" +/*~~~~~~~~~~~~ + Circutry! +~~~~~~~~~~~~~*/ +/obj/item/device/electronic_assembly/proc/diag_hud_set_circuithealth(hide = FALSE) + var/image/holder = hud_list[DIAG_CIRCUIT_HUD] + var/icon/I = icon(icon, icon_state, dir) + holder.pixel_y = I.Height() - world.icon_size + if((!isturf(loc))||hide) //if not on the ground dont show overlay + holder.icon_state = null + else + holder.icon_state = "huddiag[RoundDiagBar(obj_integrity/max_integrity)]" + +/obj/item/device/electronic_assembly/proc/diag_hud_set_circuitcell(hide = FALSE) + var/image/holder = hud_list[DIAG_BATT_HUD] + var/icon/I = icon(icon, icon_state, dir) + holder.pixel_y = I.Height() - world.icon_size + if((!isturf(loc))||hide) //if not on the ground dont show overlay + holder.icon_state = null + else if(battery) + var/chargelvl = battery.charge/battery.maxcharge + holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" + else + holder.icon_state = "hudnobatt" + +/obj/item/device/electronic_assembly/proc/diag_hud_set_circuitstat(hide = FALSE) //On, On and dangerous, or Off + var/image/holder = hud_list[DIAG_STAT_HUD] + var/icon/I = icon(icon, icon_state, dir) + holder.pixel_y = I.Height() - world.icon_size + if((!isturf(loc))||hide) //if not on the ground dont show overlay + holder.icon_state = null + else if(!battery) + holder.icon_state = "hudoffline" + else if(battery.charge == 0) + holder.icon_state = "hudoffline" + else if(combat_circuits) //has a circuit that can harm people + holder.icon_state = "hudwarn" + else //Bot is on and not dangerous + holder.icon_state = prefered_hud_icon + +/obj/item/device/electronic_assembly/proc/diag_hud_set_circuittracking(hide = FALSE) + var/image/holder = hud_list[DIAG_TRACK_HUD] + var/icon/I = icon(icon, icon_state, dir) + holder.pixel_y = I.Height() - world.icon_size + if((!isturf(loc))||hide) //if not on the ground dont show overlay + holder.icon_state = null + else if(long_range_circuits) + holder.icon_state = "hudtracking" + else + holder.icon_state = null + /*~~~~~~~~~~~~ Airlocks! ~~~~~~~~~~~~~*/ diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 510d7da94e..399debfe95 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -20,6 +20,11 @@ var/charge_tick = FALSE var/charge_delay = 4 var/use_cyborg_cell = TRUE + var/allowed_circuit_action_flags = IC_ACTION_COMBAT | IC_ACTION_LONG_RANGE //which circuit flags are allowed + var/combat_circuits = 0 //number of combat cicuits in the assembly, used for diagnostic hud + var/long_range_circuits = 0 //number of long range cicuits in the assembly, used for diagnostic hud + var/prefered_hud_icon = "hudstat" // Used by the AR circuit to change the hud icon. + hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays max_integrity = 50 armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) @@ -32,14 +37,29 @@ START_PROCESSING(SScircuit, src) materials[MAT_METAL] = round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier + //sets up diagnostic hud view + prepare_huds() + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) + diag_hud_set_circuithealth() + diag_hud_set_circuitcell() + diag_hud_set_circuitstat() + diag_hud_set_circuittracking() + /obj/item/device/electronic_assembly/Destroy() STOP_PROCESSING(SScircuit, src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.remove_from_hud(src) return ..() /obj/item/device/electronic_assembly/process() handle_idle_power() check_pulling() + //updates diagnostic hud + diag_hud_set_circuithealth() + diag_hud_set_circuitcell() + /obj/item/device/electronic_assembly/proc/handle_idle_power() // First we generate power. for(var/obj/item/integrated_circuit/passive/power/P in assembly_components) @@ -127,6 +147,7 @@ playsound(src, 'sound/items/Crowbar.ogg', 50, 1) to_chat(usr, "You pull \the [battery] out of \the [src]'s power supplier.") battery = null + diag_hud_set_circuitstat() //update diagnostic hud if(href_list["component"]) var/obj/item/integrated_circuit/component = locate(href_list["component"]) in assembly_components @@ -170,6 +191,22 @@ interact(usr) // To refresh the UI. +/obj/item/device/electronic_assembly/pickup(mob/living/user) + . = ..() + //update diagnostic hud when picked up, true is used to force the hud to be hidden + diag_hud_set_circuithealth(TRUE) + diag_hud_set_circuitcell(TRUE) + diag_hud_set_circuitstat(TRUE) + diag_hud_set_circuittracking(TRUE) + +/obj/item/device/electronic_assembly/dropped(mob/user) + . = ..() + //update diagnostic hud when dropped + diag_hud_set_circuithealth() + diag_hud_set_circuitcell() + diag_hud_set_circuitstat() + diag_hud_set_circuittracking() + /obj/item/device/electronic_assembly/proc/rename() var/mob/M = usr if(!check_interactivity(M)) @@ -232,6 +269,9 @@ if((total_complexity + IC.complexity) > max_complexity) to_chat(user, "You can't seem to add the '[IC]', since this setup's too complicated for the case.") return FALSE + if((allowed_circuit_action_flags & IC.action_flags) != IC.action_flags) + to_chat(user, "You can't seem to add the '[IC]', since the case doesn't support the circuit type.") + return FALSE if(!user.transferItemToLoc(IC, src)) return FALSE @@ -249,6 +289,16 @@ component.assembly = src assembly_components |= component + //increment numbers for diagnostic hud + if(component.action_flags & IC_ACTION_COMBAT) + combat_circuits += 1; + if(component.action_flags & IC_ACTION_LONG_RANGE) + long_range_circuits += 1; + + //diagnostic hud update + diag_hud_set_circuitstat() + diag_hud_set_circuittracking() + /obj/item/device/electronic_assembly/proc/try_remove_component(obj/item/integrated_circuit/IC, mob/user, silent) if(!opened) @@ -276,6 +326,16 @@ component.assembly = null assembly_components.Remove(component) + //decriment numbers for diagnostic hud + if(component.action_flags & IC_ACTION_COMBAT) + combat_circuits -= 1; + if(component.action_flags & IC_ACTION_LONG_RANGE) + long_range_circuits -= 1; + + //diagnostic hud update + diag_hud_set_circuitstat() + diag_hud_set_circuittracking() + /obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity) for(var/obj/item/integrated_circuit/input/S in assembly_components) @@ -313,6 +373,7 @@ user.transferItemToLoc(I, loc) cell.forceMove(src) battery = cell + diag_hud_set_circuitstat() //update diagnostic hud playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) to_chat(user, "You slot \the [cell] inside \the [src]'s power supplier.") interact(user) @@ -498,6 +559,7 @@ w_class = WEIGHT_CLASS_BULKY max_components = IC_MAX_SIZE_BASE * 3 max_complexity = IC_COMPLEXITY_BASE * 3 + allowed_circuit_action_flags = IC_ACTION_MOVEMENT | IC_ACTION_COMBAT | IC_ACTION_LONG_RANGE /obj/item/device/electronic_assembly/drone/can_move() return TRUE diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 82dead20c3..ce55a50151 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -19,6 +19,7 @@ var/power_draw_per_use = 0 // How much power is drawn when work()'d. var/power_draw_idle = 0 // How much power is drawn when doing nothing. var/spawn_flags // Used for world initializing, see the #defines above. + var/action_flags = NONE // Used for telling circuits that can do certain actions from other circuits. var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places. var/removable = TRUE // Determines if a circuit is removable from the assembly. var/displayed_name = "" diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 7ee035a2ec..329fcfe7b5 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -171,6 +171,11 @@ var/obj/item/device/electronic_assembly/E = built E.opened = TRUE E.update_icon() + //reupdate diagnostic hud because it was put_in_hands() and not pickup()'ed + E.diag_hud_set_circuithealth() + E.diag_hud_set_circuitcell() + E.diag_hud_set_circuitstat() + E.diag_hud_set_circuittracking() to_chat(usr, "[capitalize(built.name)] printed.") playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE) @@ -205,6 +210,8 @@ to_chat(usr, "It uses advanced component designs.") else to_chat(usr, "It uses unknown component designs. Printer upgrade is required to proceed.") + if(program["unsupported_circuit"]) + to_chat(usr, "This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one.") to_chat(usr, "Used space: [program["used_space"]]/[program["max_space"]].") to_chat(usr, "Complexity: [program["complexity"]]/[program["max_complexity"]].") to_chat(usr, "Metal cost: [program["metal_cost"]].") @@ -215,6 +222,8 @@ if(program["requires_upgrades"] && !upgraded) to_chat(usr, "This program uses unknown component designs. Printer upgrade is required to proceed.") + if(program["unsupported_circuit"]) + to_chat(usr, "This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one.") else var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) if(materials.use_amount_type(program["metal_cost"], MAT_METAL)) diff --git a/code/modules/integrated_electronics/core/saved_circuits.dm b/code/modules/integrated_electronics/core/saved_circuits.dm index a1d3d63a5f..8833f6872f 100644 --- a/code/modules/integrated_electronics/core/saved_circuits.dm +++ b/code/modules/integrated_electronics/core/saved_circuits.dm @@ -204,7 +204,7 @@ // Returns assembly (type: list) if the save is valid. // Returns error code (type: text) if loading has failed. // The following parameters area calculated during validation and added to the returned save list: -// "requires_upgrades", "metal_cost", "complexity", "max_complexity", "used_space", "max_space" +// "requires_upgrades", "unsupported_circuit", "metal_cost", "complexity", "max_complexity", "used_space", "max_space" /datum/controller/subsystem/processing/circuit/proc/validate_electronic_assembly(program) var/list/blocks = json_decode(program) if(!blocks) @@ -275,6 +275,10 @@ if(!(component.spawn_flags & IC_SPAWN_DEFAULT)) blocks["requires_upgrades"] = TRUE + // Check if the assembly supports the circucit + if((component.action_flags & assembly.allowed_circuit_action_flags) != component.action_flags) + blocks["unsupported_circuit"] = TRUE + // Check complexity and space limitations if(blocks["used_space"] > blocks["max_space"]) diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index c22e38d56a..07a7542b80 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -523,6 +523,7 @@ "on signal sent" = IC_PINTYPE_PULSE_OUT, "on signal received" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + action_flags = IC_ACTION_LONG_RANGE power_draw_idle = 5 power_draw_per_use = 40 @@ -608,6 +609,7 @@ ) activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + action_flags = IC_ACTION_LONG_RANGE power_draw_per_use = 50 var/datum/ntnet_connection/exonet = null diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index f150e9cfcd..ddac72a76a 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -23,6 +23,7 @@ ) var/obj/item/gun/energy/installed_gun = null spawn_flags = IC_SPAWN_RESEARCH + action_flags = IC_ACTION_COMBAT power_draw_per_use = 0 var/mode = FALSE @@ -142,6 +143,7 @@ outputs = list() activators = list("step towards dir" = IC_PINTYPE_PULSE_IN,"on step"=IC_PINTYPE_PULSE_OUT,"blocked"=IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH + action_flags = IC_ACTION_MOVEMENT power_draw_per_use = 100 /obj/item/integrated_circuit/manipulation/locomotion/do_work() @@ -163,7 +165,7 @@ /obj/item/integrated_circuit/manipulation/grenade name = "grenade primer" - desc = "This circuit comes with the ability to attach most types of grenades at prime them at will." + desc = "This circuit comes with the ability to attach most types of grenades and prime them at will." extended_desc = "Time between priming and detonation is limited to between 1 to 12 seconds but is optional. \ If unset, not a number, or a number less than 1 then the grenade's built-in timing will be used. \ Beware: Once primed there is no aborting the process!" @@ -173,6 +175,7 @@ outputs = list() activators = list("prime grenade" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_RESEARCH + action_flags = IC_ACTION_COMBAT var/obj/item/grenade/attached_grenade var/pre_attached_grenade_type @@ -410,6 +413,7 @@ "fire" = IC_PINTYPE_PULSE_IN ) spawn_flags = IC_SPAWN_RESEARCH + action_flags = IC_ACTION_COMBAT power_draw_per_use = 50 /obj/item/integrated_circuit/manipulation/thrower/do_work() diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 6a90ff5f2a..19a7a8b610 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -248,6 +248,7 @@ outputs = list() activators = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + action_flags = IC_ACTION_LONG_RANGE power_draw_idle = 0 // Raises to 20 when on. var/obj/machinery/camera/camera var/updating = FALSE @@ -336,3 +337,32 @@ text_output += "\an ["\improper[name]"] labeled '[displayed_name]'" text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit *" : "unlit"]." to_chat(user, text_output) + +/obj/item/integrated_circuit/output/diagnostic_hud + name = "AR interface" + desc = "Takes an icon name as an input, and will update the status hud when data is written to it." + extended_desc = "Takes an icon name as an input, and will update the status hud when data is written to it, this means it can change the icon and have the icon stay that way even if the circuit is removed. The acceptable inputs are 'alert' and 'move'. Any input other than that will return the icon to its default state. The danger warning and offline status will appear over any input from this circuit." + var/list/icons = list( + "alert" = "hudalert", + "move" = "hudmove" + ) + complexity = 1 + icon_state = "led" + inputs = list( + "icon" = IC_PINTYPE_STRING + ) + outputs = list() + activators = list() + power_draw_idle = 0 + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/output/diagnostic_hud/on_data_written() + var/ID = get_pin_data(IC_INPUT, 1) + var/selected_icon = icons[ID] + if(assembly) + if(selected_icon) + assembly.prefered_hud_icon = selected_icon + else + assembly.prefered_hud_icon = "hudstat" + //update the diagnostic hud + assembly.diag_hud_set_circuitstat() \ No newline at end of file