From f57f95aa95cdc971d91ee5b5aec5d74e1533aee5 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Sat, 12 Jul 2025 19:51:58 +0530 Subject: [PATCH] [MDB Ignore] General maintenance for SMES (#91587) ## About The Pull Request - SMES now directly gives/takes charge to the power cells stored inside its component parts instead of modifying a `charge` variable whose value was set from the total charge of its stored cells - Removed `capacity` var. It's now derived from the total cells `max_charge`. Even then its value was set to this so manually setting it was a waste - Fixes #71918. Because of point 1, this also means if you install rigged cells in the SMES it now explodes - Adds examines & screentips for installing terminal & other tool acts - Smes can be connected to the powernet with a multitool with the panel open after construction. - General maintenance for portable smes as well. Repaths it to machine subtype instead of power cause all it's functionality wasn't used - Removed a bunch of unused defines, autodoc and shuffled around other code ## Changelog :cl: qol: SMES has examines and screentips for various stuff code: Improved code of SMES in general fix: smes can be connected to the powernet with a multitool with the panel open after construction refactor: SMES now functions consistently with its power cells & the RPED. /:cl: --- _maps/RandomZLevels/research.dmm | 1 - .../map_files/IceBoxStation/IceBoxStation.dmm | 1 - _maps/map_files/MetaStation/MetaStation.dmm | 1 - _maps/map_files/tramstation/tramstation.dmm | 1 - code/game/gamemodes/events.dm | 4 +- .../machines/machine_circuitboards.dm | 2 +- code/modules/power/smes.dm | 614 +++++++++--------- code/modules/power/smes_portable.dm | 318 ++++----- .../tgui/interfaces/{Smes.jsx => Smes.tsx} | 57 +- tools/UpdatePaths/Scripts/91587_smes_bank.txt | 1 + 10 files changed, 525 insertions(+), 475 deletions(-) rename tgui/packages/tgui/interfaces/{Smes.jsx => Smes.tsx} (86%) create mode 100644 tools/UpdatePaths/Scripts/91587_smes_bank.txt diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index 1729b5bde99..e37038cf57d 100644 --- a/_maps/RandomZLevels/research.dmm +++ b/_maps/RandomZLevels/research.dmm @@ -1134,7 +1134,6 @@ /area/awaymission/research/interior/security) "fw" = ( /obj/machinery/power/smes{ - capacity = 1.8e+008; charge = 2e+005 }, /obj/structure/cable, diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 7f1f21d0fe5..97e984cd9f9 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -55060,7 +55060,6 @@ /area/station/cargo/bitrunning/den) "pBI" = ( /obj/machinery/power/smes{ - capacity = 1.8e+008; charge = 2e+005 }, /obj/effect/decal/cleanable/cobweb/cobweb2, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 32e959f13d0..27859dfdf0a 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -51361,7 +51361,6 @@ /area/station/engineering/gravity_generator) "rMT" = ( /obj/machinery/power/smes{ - capacity = 1.8e+008; charge = 2e+005 }, /obj/effect/decal/cleanable/dirt, diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 478ab62af91..c44d92239f4 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -46243,7 +46243,6 @@ "pts" = ( /obj/machinery/power/smes{ charge = 10000; - capacity = 9e+06 }, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 8810ffc0fc6..a98b03d9c83 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -54,7 +54,7 @@ for(var/obj/machinery/power/smes/smes as anything in all_smes) if(!is_station_level(smes.z)) continue - smes.charge = smes.capacity + smes.adjust_charge(INFINITY) smes.output_level = smes.output_level_max smes.output_attempt = TRUE smes.update_appearance() @@ -86,7 +86,7 @@ for(var/obj/machinery/power/smes/smes as anything in all_smes) if(!is_station_level(smes.z)) continue - smes.charge = smes.capacity + smes.adjust_charge(INFINITY) smes.output_level = smes.output_level_max smes.output_attempt = TRUE smes.update_appearance() diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index cacae49c47f..a4ffec0488f 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -363,7 +363,7 @@ name = "portable SMES" greyscale_colors = CIRCUIT_COLOR_ENGINEERING needs_anchored = FALSE - build_path = /obj/machinery/power/smesbank + build_path = /obj/machinery/smesbank req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/power_store/battery = 5,) diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 0277fe9bf20..944ead1b826 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -1,18 +1,6 @@ // the SMES // stores power - -//Cache defines -#define SMES_CLEVEL_1 1 -#define SMES_CLEVEL_2 2 -#define SMES_CLEVEL_3 3 -#define SMES_CLEVEL_4 4 -#define SMES_CLEVEL_5 5 -#define SMES_OUTPUTTING 6 -#define SMES_NOT_OUTPUTTING 7 -#define SMES_INPUTTING 8 -#define SMES_INPUT_ATTEMPT 9 - /obj/machinery/power/smes name = "power storage unit" desc = "A high-capacity superconducting magnetic energy storage (SMES) unit." @@ -22,43 +10,53 @@ circuit = /obj/item/circuitboard/machine/smes can_change_cable_layer = TRUE - /// The charge capacity. - var/capacity = 50 * STANDARD_BATTERY_CHARGE // The board defaults with 5 high capacity batteries. - /// The current charge. + /// The initial charge of this smes. var/charge = 0 + /// Max capacity of all cells in this smes + VAR_PROTECTED/total_capacity = 0 - var/input_attempt = TRUE // TRUE = attempting to charge, FALSE = not attempting to charge - var/inputting = TRUE // TRUE = actually inputting, FALSE = not inputting - var/input_level = 50 KILO WATTS // amount of power the SMES attempts to charge by - var/input_level_max = 200 KILO WATTS // cap on input_level - var/input_available = 0 // amount of charge available from input last tick + /// TRUE = attempting to charge, FALSE = not attempting to charge + var/input_attempt = TRUE + /// TRUE = actually inputting, FALSE = not inputting + var/inputting = TRUE + /// amount of power the SMES attempts to charge by + var/input_level = 50 KILO WATTS + /// cap on input_level + var/input_level_max = 200 KILO WATTS + /// amount of charge available from input last tick + var/input_available = 0 - var/output_attempt = TRUE // TRUE = attempting to output, FALSE = not attempting to output - var/outputting = TRUE // TRUE = actually outputting, FALSE = not outputting - var/output_level = 50 KILO WATTS // amount of power the SMES attempts to output - var/output_level_max = 200 KILO WATTS // cap on output_level - var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power + /// TRUE = attempting to output, FALSE = not attempting to output + var/output_attempt = TRUE + /// TRUE = actually outputting, FALSE = not outputting + var/outputting = TRUE + /// amount of power the SMES attempts to output + var/output_level = 50 KILO WATTS + /// cap on output_level + var/output_level_max = 200 KILO WATTS + /// amount of power actually outputted. may be less than output_level if the powernet returns excess power + var/output_used = 0 - /// does this SMES show its input/output lights? + ///Should we show display lights var/show_display_lights = TRUE - + /// Terminal for charging this smes var/obj/machinery/power/terminal/terminal = null -/obj/machinery/power/smes/examine(user) - . = ..() - if(!terminal) - . += span_warning("This [src] has no power terminal!") - -/obj/machinery/power/smes/get_save_vars() - . = ..() - . += NAMEOF(src, charge) - . += NAMEOF(src, capacity) - . += NAMEOF(src, input_level) - . += NAMEOF(src, output_level) - return . - /obj/machinery/power/smes/Initialize(mapload) . = ..() + + //screentips + register_context() + + ///initial charge + if(charge) + for(var/obj/item/stock_parts/power_store/power_cell in component_parts) + power_cell.use(power_cell.charge()) + if(charge) + charge -= power_cell.give(charge) + charge = 0 + + //locate terminal dir_loop: for(var/direction in GLOB.cardinals) var/turf/turf = get_step(src, direction) @@ -66,124 +64,141 @@ if(term && term.dir == REVERSE_DIR(direction)) terminal = term break dir_loop - if(!terminal) atom_break() return terminal.master = src - update_appearance() + update_appearance(UPDATE_OVERLAYS) + +/obj/machinery/power/smes/disconnect_terminal() + if(terminal) + terminal.master = null + terminal = null + atom_break() + +/obj/machinery/power/smes/Destroy() + if(SSticker.IsRoundInProgress()) + var/turf/turf = get_turf(src) + message_admins("[src] deleted at [ADMIN_VERBOSEJMP(turf)]") + log_game("[src] deleted at [AREACOORD(turf)]") + investigate_log("deleted at [AREACOORD(turf)]", INVESTIGATE_ENGINE) + disconnect_terminal() + return ..() + +/obj/machinery/power/smes/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE + if(isnull(held_item)) + return + + if(istype(held_item, /obj/item/stack/cable_coil) && !terminal && can_place_terminal(user, held_item, silent = TRUE)) + context[SCREENTIP_CONTEXT_LMB] = "Install terminal" + return CONTEXTUAL_SCREENTIP_SET + + if(held_item.tool_behaviour == TOOL_SCREWDRIVER) + context[SCREENTIP_CONTEXT_LMB] = "[panel_open ? "Close" : "Open"] panel" + return CONTEXTUAL_SCREENTIP_SET + if(held_item.tool_behaviour == TOOL_WRENCH && panel_open) + context[SCREENTIP_CONTEXT_LMB] = "Rotate" + return CONTEXTUAL_SCREENTIP_SET + else if(held_item.tool_behaviour == TOOL_WIRECUTTER && terminal && panel_open) + context[SCREENTIP_CONTEXT_LMB] = "Cut terminal" + return CONTEXTUAL_SCREENTIP_SET + else if(held_item.tool_behaviour == TOOL_CROWBAR && !terminal && panel_open) + context[SCREENTIP_CONTEXT_LMB] = "Deconstruct" + return CONTEXTUAL_SCREENTIP_SET + +/obj/machinery/power/smes/examine(user) + . = ..() + + . += span_notice("it's maintainence panel can be [EXAMINE_HINT("screwed")] [panel_open ? "closed" : "opened"]") + if(panel_open) + if(!terminal) + . += span_notice("It can be [EXAMINE_HINT("pried")] apart.") + . += span_notice("It can [EXAMINE_HINT("wrenched")] to rotate.") + + if(!terminal) + . += span_warning("A terminal that requires [EXAMINE_HINT("10 cable pieces")] needs to be installed!.") + else if(panel_open) + . += span_notice("The terminal can be [EXAMINE_HINT("cut")] apart.") + +/obj/machinery/power/smes/update_overlays() + . = ..() + if(panel_open || !is_operational) + return + + if(show_display_lights) + . += "smes-op[outputting ? 1 : 0]" + . += "smes-oc[inputting ? 1 : 0]" + + var/clevel = chargedisplay() + if(clevel > 0) + . += "smes-og[clevel]" + +/obj/machinery/power/smes/get_save_vars() + . = ..() + charge = total_charge() + . += NAMEOF(src, charge) + . += NAMEOF(src, input_level) + . += NAMEOF(src, output_level) + +/// Returns the total charge of this smes +/obj/machinery/power/smes/proc/total_charge() + PROTECTED_PROC(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + + for(var/obj/item/stock_parts/power_store/power_cell in component_parts) + . += power_cell.charge() + +/** + * Adjusts the total charge of this smes + * Arguments + * + * * charge_adjust - the amount of give/take from this smes + */ +/obj/machinery/power/smes/proc/adjust_charge(charge_adjust) + var/give = charge_adjust > 0 + charge_adjust = abs(charge_adjust) + for(var/obj/item/stock_parts/power_store/power_cell in component_parts) + var/amount_adjusted + if(give) + amount_adjusted = power_cell.give(charge_adjust) + else + amount_adjusted = power_cell.use(charge_adjust, TRUE) + + . += amount_adjusted + charge_adjust -= amount_adjusted + if(!charge_adjust) + return /obj/machinery/power/smes/RefreshParts() SHOULD_CALL_PARENT(FALSE) + var/power_coefficient = 0 - var/max_charge = 0 - var/new_charge = 0 for(var/datum/stock_part/capacitor/capacitor in component_parts) power_coefficient += capacitor.tier input_level_max = initial(input_level_max) * power_coefficient output_level_max = initial(output_level_max) * power_coefficient + + total_capacity = 0 for(var/obj/item/stock_parts/power_store/power_cell in component_parts) - max_charge += power_cell.maxcharge - new_charge += power_cell.charge - capacity = max_charge - if(!initial(charge) && !charge) - charge = new_charge + total_capacity += power_cell.max_charge() + + update_static_data_for_all_viewers() /obj/machinery/power/smes/should_have_node() return TRUE -// adapted from APC item interacts for cable act handling -/obj/machinery/power/smes/item_interaction(mob/living/user, obj/item/tool, list/modifiers) - . = NONE - if(istype(tool, /obj/item/stack/cable_coil)) - . = cable_act(user, tool, LAZYACCESS(modifiers, RIGHT_CLICK)) - if(.) - return . - return . - -/obj/machinery/power/smes/cable_layer_act(mob/living/user, obj/item/tool) - if(!QDELETED(terminal)) - balloon_alert(user, "cut the terminal first!") - return ITEM_INTERACT_BLOCKING - return ..() - -//opening using screwdriver -/obj/machinery/power/smes/screwdriver_act(mob/living/user, obj/item/tool) - . = ITEM_INTERACT_BLOCKING - if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), tool)) - update_appearance() - return ITEM_INTERACT_SUCCESS - -//changing direction using wrench -/obj/machinery/power/smes/wrench_act(mob/living/user, obj/item/tool) - . = ITEM_INTERACT_BLOCKING - if(default_change_direction_wrench(user, tool)) - terminal = null - var/turf/turf = get_step(src, dir) - for(var/obj/machinery/power/terminal/term in turf) - if(term && term.dir == REVERSE_DIR(dir)) - terminal = term - terminal.master = src - to_chat(user, span_notice("Terminal found.")) - break - if(!terminal) - to_chat(user, span_alert("No power terminal found.")) - return ITEM_INTERACT_SUCCESS - set_machine_stat(machine_stat & ~BROKEN) - update_appearance() - return ITEM_INTERACT_SUCCESS - -//building and linking a terminal -/obj/machinery/power/smes/proc/cable_act(mob/living/user, obj/item/stack/cable_coil/installing_cable, is_right_clicking) - . = ITEM_INTERACT_BLOCKING - if(!can_place_terminal(user, installing_cable, silent = FALSE)) - return ITEM_INTERACT_BLOCKING - var/terminal_cable_layer - if(is_right_clicking) - var/choice = tgui_input_list(user, "Select Power Input Cable Layer", "Select Cable Layer", GLOB.cable_name_to_layer) - if(isnull(choice) \ - || !user.is_holding(installing_cable) \ - || !user.Adjacent(src) \ - || user.incapacitated \ - || !can_place_terminal(user, installing_cable, silent = TRUE) \ - ) - return ITEM_INTERACT_BLOCKING - terminal_cable_layer = GLOB.cable_name_to_layer[choice] - user.visible_message(span_notice("[user.name] starts adding cables to [src].")) - balloon_alert(user, "adding cables...") - playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) - - if(!do_after(user, 2 SECONDS, target = src)) - return ITEM_INTERACT_BLOCKING - if(!can_place_terminal(user, installing_cable, silent = TRUE)) - return ITEM_INTERACT_BLOCKING - var/obj/item/stack/cable_coil/cable = installing_cable - var/turf/turf = get_turf(user) - var/obj/structure/cable/connected_cable = turf.get_cable_node(terminal_cable_layer) //get the connecting node cable, if there's one - if (prob(50) && electrocute_mob(user, connected_cable, connected_cable, 1, TRUE)) //animate the electrocution if uncautious and unlucky - do_sparks(5, TRUE, src) - return ITEM_INTERACT_BLOCKING - cable.use(10) - user.visible_message(span_notice("[user.name] adds cables to [src].")) - balloon_alert(user, "cables added") - //build the terminal and link it to the network - make_terminal(turf, terminal_cable_layer) - terminal.connect_to_network() - return ITEM_INTERACT_SUCCESS - -//crowbarring it! -/obj/machinery/power/smes/crowbar_act(mob/living/user, obj/item/tool) - if(!panel_open) - return - var/turf/turf = get_turf(src) - if(default_deconstruction_crowbar(tool)) - message_admins("[src] has been deconstructed by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(turf)].") - user.log_message("deconstructed [src]", LOG_GAME) - investigate_log("deconstructed by [key_name(user)] at [AREACOORD(src)].", INVESTIGATE_ENGINE) - return - -/// Checks if we're in a valid state to place a terminal +/** + * Can we place the terminal based on the players position + * + * Arguments + * * mob/living/user - the player attempting to install the cable + * * obj/item/stack/cable_coil/installing_cable - the cable coil used to install the terminal + * * silent - should we display error messages +*/ /obj/machinery/power/smes/proc/can_place_terminal(mob/living/user, obj/item/stack/cable_coil/installing_cable, silent = TRUE) + PRIVATE_PROC(TRUE) + var/set_dir = get_dir(user, src) if(set_dir & (set_dir - 1))//we don't want diagonal click return FALSE @@ -207,141 +222,168 @@ return FALSE return TRUE +// adapted from APC item interacts for cable act handling +/obj/machinery/power/smes/item_interaction(mob/living/user, obj/item/stack/cable_coil/installing_cable, list/modifiers) + . = NONE + if(istype(installing_cable)) + . = ITEM_INTERACT_BLOCKING + if(!can_place_terminal(user, installing_cable, silent = FALSE)) + return ITEM_INTERACT_BLOCKING + + //select cable layer + var/terminal_cable_layer + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + var/choice = tgui_input_list(user, "Select Power Input Cable Layer", "Select Cable Layer", GLOB.cable_name_to_layer) + if(isnull(choice) \ + || !user.is_holding(installing_cable) \ + || !user.Adjacent(src) \ + || user.incapacitated \ + || !can_place_terminal(user, installing_cable, silent = TRUE) \ + ) + return ITEM_INTERACT_BLOCKING + terminal_cable_layer = GLOB.cable_name_to_layer[choice] + user.visible_message(span_notice("[user.name] starts adding cables to [src].")) + balloon_alert(user, "adding cables...") + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) + + //use cable + if(!do_after(user, 2 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + if(!can_place_terminal(user, installing_cable, silent = TRUE)) + return ITEM_INTERACT_BLOCKING + var/obj/item/stack/cable_coil/cable = installing_cable + var/turf/turf = get_turf(user) + var/obj/structure/cable/connected_cable = turf.get_cable_node(terminal_cable_layer) //get the connecting node cable, if there's one + if (prob(50) && electrocute_mob(user, connected_cable, connected_cable, 1, TRUE)) //animate the electrocution if uncautious and unlucky + do_sparks(5, TRUE, src) + return ITEM_INTERACT_BLOCKING + cable.use(10) + user.visible_message(span_notice("[user.name] adds cables to [src].")) + balloon_alert(user, "cables added") + + //build the terminal and link it to the network + terminal = new(turf) + terminal.master = src + terminal.cable_layer = terminal_cable_layer + terminal.setDir(get_dir(turf, src)) + terminal.connect_to_network() + set_machine_stat(machine_stat & ~BROKEN) + return ITEM_INTERACT_SUCCESS + +//opening using screwdriver +/obj/machinery/power/smes/screwdriver_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), tool)) + update_appearance(UPDATE_OVERLAYS) + return ITEM_INTERACT_SUCCESS + /obj/machinery/power/smes/wirecutter_act(mob/living/user, obj/item/item) - //disassembling the terminal - . = ..() + . = ITEM_INTERACT_FAILURE if(terminal && panel_open) terminal.dismantle(user, item) - return TRUE + return ITEM_INTERACT_SUCCESS - -/obj/machinery/power/smes/default_deconstruction_crowbar(obj/item/crowbar/crowbar) - if(istype(crowbar) && terminal) - balloon_alert(usr, "remove the power terminal!") - return FALSE - - return ..() - -/obj/machinery/power/smes/on_deconstruction(disassembled) - for(var/obj/item/stock_parts/power_store/cell in component_parts) - cell.charge = (charge / capacity) * cell.maxcharge - -/obj/machinery/power/smes/Destroy() - if(SSticker.IsRoundInProgress()) - var/turf/turf = get_turf(src) - message_admins("[src] deleted at [ADMIN_VERBOSEJMP(turf)]") - log_game("[src] deleted at [AREACOORD(turf)]") - investigate_log("deleted at [AREACOORD(turf)]", INVESTIGATE_ENGINE) +//crowbarring it! +/obj/machinery/power/smes/crowbar_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_FAILURE if(terminal) - disconnect_terminal() - return ..() - -// create a terminal object pointing towards the SMES -// wires will attach to this -/obj/machinery/power/smes/proc/make_terminal(turf/turf, terminal_cable_layer = cable_layer) - terminal = new/obj/machinery/power/terminal(turf) - terminal.cable_layer = terminal_cable_layer - terminal.setDir(get_dir(turf,src)) - terminal.master = src - set_machine_stat(machine_stat & ~BROKEN) - -/obj/machinery/power/smes/disconnect_terminal() - if(terminal) - terminal.master = null - terminal = null - atom_break() - -/// is this SMES in a suitable state to display overlays? -/obj/machinery/power/smes/proc/display_ready() - if(machine_stat & BROKEN) - return FALSE - if(panel_open) - return FALSE - return TRUE - -/obj/machinery/power/smes/update_overlays() - . = ..() - if(!display_ready()) + balloon_alert(user, "remove the power terminal!") return - if(show_display_lights) - . += "smes-op[outputting ? 1 : 0]" - . += "smes-oc[inputting ? 1 : 0]" + if(default_deconstruction_crowbar(tool)) + var/turf/ground = get_turf(src) + message_admins("[src] has been deconstructed by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(ground)].") + user.log_message("deconstructed [src]", LOG_GAME) + investigate_log("deconstructed by [key_name(user)] at [AREACOORD(src)].", INVESTIGATE_ENGINE) + return ITEM_INTERACT_SUCCESS - var/clevel = chargedisplay() - if(clevel > 0) - . += "smes-og[clevel]" +//changing direction using wrench +/obj/machinery/power/smes/wrench_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_FAILURE + if(default_change_direction_wrench(user, tool)) + disconnect_terminal() + for(var/obj/machinery/power/terminal/term in get_step(src, dir)) + if(term && term.dir == REVERSE_DIR(dir)) + terminal = term + terminal.master = src + to_chat(user, span_notice("Terminal found.")) + set_machine_stat(machine_stat & ~BROKEN) + update_appearance(UPDATE_OVERLAYS) + return ITEM_INTERACT_SUCCESS + to_chat(user, span_alert("No power terminal found.")) +/obj/machinery/power/smes/cable_layer_act(mob/living/user, obj/item/tool) + if(!panel_open) + balloon_alert(user, "open panel first!") + return ITEM_INTERACT_BLOCKING + return ..() +/obj/machinery/power/smes/multitool_act(mob/living/user, obj/item/tool) + . = ..() + if(. == ITEM_INTERACT_SUCCESS) + connect_to_network() + +///Returns the charge level this smes is at 0->5 for display purposes /obj/machinery/power/smes/proc/chargedisplay() - if(capacity <= 0) - return 0 - return clamp(round(5.5*charge/capacity),0,5) + SHOULD_BE_PURE(TRUE) + + return clamp(round(5 * (total_charge() / total_capacity)), 0, 5) /obj/machinery/power/smes/process(seconds_per_tick) - if(machine_stat & BROKEN) + if(!is_operational) return //store machine state to see if we need to update the icon overlays var/last_disp = chargedisplay() var/last_chrg = inputting var/last_onln = outputting - var/input_energy = power_to_energy(input_level) - var/output_energy = power_to_energy(output_level) //outputting - if(output_attempt) - if(outputting) - output_used = min(charge, output_energy) //limit output to that stored + if(output_attempt && powernet) + var/output_energy = power_to_energy(output_level) - if (add_avail(output_used)) // add output to powernet if it exists (smes side) - adjust_charge(-output_used) // reduce the storage (may be recovered in /restore() if excessive) + output_used = 0 + if(output_energy <= 0) + outputting = FALSE + else + outputting = TRUE + + // reduce the storage (may be recovered in /restore() if excessive) + output_used = adjust_charge(-output_energy) + if(output_used) + add_avail(output_used) + + // either from no charge or set to 0 + if(output_used < 0.1) + outputting = FALSE + investigate_log("lost power and turned off", INVESTIGATE_ENGINE) else outputting = FALSE - - if(output_used < 0.1) // either from no charge or set to 0 - outputting = FALSE - investigate_log("lost power and turned off", INVESTIGATE_ENGINE) - else if(output_attempt && charge > output_energy && output_level > 0) - outputting = TRUE - else - output_used = 0 else outputting = FALSE //inputting - if(terminal && input_attempt) + if(input_attempt && terminal) + var/input_energy = power_to_energy(input_level) + input_available = terminal.surplus() - - if(inputting) - if(input_available > 0) // if there's power available, try to charge - - var/load = min((capacity-charge), input_energy, input_available) // charge at set rate, limited to spare capacity - - adjust_charge(load) // increase the charge - - terminal.add_load(load) // add the load to the terminal side network - - else // if not enough capcity - inputting = FALSE // stop inputting - + if(input_energy <= 0) + inputting = FALSE else - if(input_attempt && input_available > 0) - inputting = TRUE + inputting = TRUE + + // increase the charge + var/load = adjust_charge(min(input_energy, input_available)) + if(load) + terminal.add_load(load) // add the load to the terminal side network + else + inputting = FALSE else inputting = FALSE // only update icon if state changed if(last_disp != chargedisplay() || last_chrg != inputting || last_onln != outputting) - update_appearance() - -/// Adjusts the charge in this SMES, used instead of directly adjusting the charge value. Mainly for the benefit of the power connector/portable SMES system. -/obj/machinery/power/smes/proc/adjust_charge(charge_adjust) - charge += charge_adjust - -/// Sets the charge in this SMES, used instead of directly adjusting the charge value. Mainly for the benefit of the power connector/portable SMES system. -/obj/machinery/power/smes/proc/set_charge(charge_set) - charge = charge_set + update_appearance(UPDATE_OVERLAYS) // called after all power processes are finished // restores charge level to smes if there was excess this ptick @@ -353,25 +395,18 @@ output_used = 0 return - var/excess = powernet.netexcess // this was how much wasn't used on the network last ptick, minus any removed by other SMESes - - excess = min(output_used, excess) // clamp it to how much was actually output by this SMES last ptick - - excess = min((capacity-charge), excess) // for safety, also limit recharge by space capacity of SMES (shouldn't happen) + var/excess = min(output_used, powernet.netexcess) // clamp it to how much was actually output by this SMES last ptick // now recharge this amount - var/clev = chargedisplay() - adjust_charge(excess) // restore unused power + excess = adjust_charge(excess) // restore unused power powernet.netexcess -= excess // remove the excess from the powernet, so later SMESes don't try to use it output_used -= excess - if(clev != chargedisplay() ) //if needed updates the icons overlay - update_appearance() - return - + if(clev != chargedisplay()) //if needed updates the icons overlay + update_appearance(UPDATE_OVERLAYS) /obj/machinery/power/smes/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -379,41 +414,44 @@ ui = new(user, src, "Smes", name) ui.open() +/obj/machinery/power/smes/ui_static_data(mob/user) + . = list( + "capacity" = total_capacity, + "inputLevelMax" = input_level_max, + "outputLevelMax" = output_level_max, + ) + /obj/machinery/power/smes/ui_data() - var/list/data = list( - "capacity" = capacity, - "capacityPercent" = round(100*charge/capacity, 0.1), - "charge" = charge, + . = list( + "charge" = total_charge(), "inputAttempt" = input_attempt, "inputting" = inputting, "inputLevel" = input_level, - "inputLevel_text" = display_power(input_level, convert = FALSE), - "inputLevelMax" = input_level_max, "inputAvailable" = energy_to_power(input_available), "outputAttempt" = output_attempt, - "outputting" = energy_to_power(outputting), "outputLevel" = output_level, - "outputLevel_text" = display_power(output_level, convert = FALSE), - "outputLevelMax" = output_level_max, "outputUsed" = energy_to_power(output_used), + "outputting" = outputting, ) - return data /obj/machinery/power/smes/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() if(.) return + switch(action) if("tryinput") input_attempt = !input_attempt - log_smes(usr) - update_appearance() - . = TRUE + log_smes(ui.user) + update_appearance(UPDATE_OVERLAYS) + return TRUE + if("tryoutput") output_attempt = !output_attempt - log_smes(usr) - update_appearance() - . = TRUE + log_smes(ui.user) + update_appearance(UPDATE_OVERLAYS) + return TRUE + if("input") var/target = params["target"] var/adjust = text2num(params["adjust"]) @@ -431,7 +469,9 @@ . = TRUE if(.) input_level = clamp(target, 0, input_level_max) - log_smes(usr) + log_smes(ui.user) + return + if("output") var/target = params["target"] var/adjust = text2num(params["adjust"]) @@ -449,25 +489,26 @@ . = TRUE if(.) output_level = clamp(target, 0, output_level_max) - log_smes(usr) + log_smes(ui.user) +///Logs the current state of this smes /obj/machinery/power/smes/proc/log_smes(mob/user) - investigate_log("Input/Output: [input_level]/[output_level] | Charge: [charge] | Output-mode: [output_attempt?"ON":"OFF"] | Input-mode: [input_attempt?"AUTO":"OFF"] by [user ? key_name(user) : "outside forces"]", INVESTIGATE_ENGINE) + PRIVATE_PROC(TRUE) + + investigate_log("Input/Output: [input_level]/[output_level] | Charge: [total_charge()] | Output-mode: [output_attempt?"ON":"OFF"] | Input-mode: [input_attempt?"AUTO":"OFF"] by [user ? key_name(user) : "outside forces"]", INVESTIGATE_ENGINE) /obj/machinery/power/smes/emp_act(severity) . = ..() if(. & EMP_PROTECT_SELF) return - input_attempt = rand(0,1) + input_attempt = rand(0, 1) inputting = input_attempt - output_attempt = rand(0,1) + output_attempt = rand(0, 1) outputting = output_attempt output_level = rand(0, output_level_max) input_level = rand(0, input_level_max) - adjust_charge(-STANDARD_BATTERY_CHARGE/severity) - if (charge < 0) - set_charge(0) - update_appearance() + adjust_charge(-STANDARD_BATTERY_CHARGE / severity) + update_appearance(UPDATE_OVERLAYS) log_smes() // Variant of SMES that starts with super power cells for higher longevity @@ -475,7 +516,6 @@ name = "super capacity power storage unit" desc = "A super-capacity superconducting magnetic energy storage (SMES) unit. Relatively rare, and typically installed in long-range outposts where minimal maintenance is expected." circuit = /obj/item/circuitboard/machine/smes/super - capacity = 100 * STANDARD_BATTERY_CHARGE /obj/machinery/power/smes/super/full charge = 100 * STANDARD_BATTERY_CHARGE @@ -494,17 +534,9 @@ name = "magical power storage unit" desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. Magically produces power." -/obj/machinery/power/smes/magical/process() - capacity = INFINITY - charge = INFINITY - ..() - -#undef SMES_CLEVEL_1 -#undef SMES_CLEVEL_2 -#undef SMES_CLEVEL_3 -#undef SMES_CLEVEL_4 -#undef SMES_CLEVEL_5 -#undef SMES_OUTPUTTING -#undef SMES_NOT_OUTPUTTING -#undef SMES_INPUTTING -#undef SMES_INPUT_ATTEMPT +/obj/machinery/power/smes/magical/adjust_charge(charge_adjust) + //give charge without consuming anything + if(charge_adjust < 0) + return abs(charge_adjust) + //no point charging this already infinite smes + return 0 diff --git a/code/modules/power/smes_portable.dm b/code/modules/power/smes_portable.dm index 3b2d6166959..5601942be0c 100644 --- a/code/modules/power/smes_portable.dm +++ b/code/modules/power/smes_portable.dm @@ -8,31 +8,13 @@ density = FALSE input_attempt = FALSE output_attempt = FALSE - show_display_lights = FALSE - capacity = 1 // solely to avoid div by zero - charge = 0 - var/obj/machinery/power/smesbank/connected_smes + ///The smes this connector is connected with + var/obj/machinery/smesbank/connected_smes -/obj/machinery/power/smes/connector/RefreshParts() - SHOULD_CALL_PARENT(FALSE) - var/power_coefficient = 0 - for(var/datum/stock_part/capacitor/capacitor in component_parts) - power_coefficient += capacitor.tier - input_level_max = initial(input_level_max) * power_coefficient - output_level_max = initial(output_level_max) * power_coefficient - -/obj/machinery/power/smes/connector/ui_act(action, params) - // prevent UI interactions if there's no SMES - if(!connected_smes) - balloon_alert(usr, "needs a connected SMES!") - return FALSE - return ..() - -/obj/machinery/power/smes/connector/display_ready() - if(!connected_smes) - return FALSE +/obj/machinery/power/smes/connector/Destroy() + connected_smes?.disconnect_port() // in the unlikely but possible case a SMES is connected and this explodes return ..() /obj/machinery/power/smes/connector/update_appearance(updates) @@ -41,20 +23,23 @@ /obj/machinery/power/smes/connector/update_overlays() . = ..() - if(connected_smes && inputting) + if(!connected_smes) + return + + if(inputting) . += "bp-c" else - if(connected_smes) - if(charge > 0) - . += "bp-o" - else - . += "bp-d" - connected_smes?.update_appearance(UPDATE_OVERLAYS) + if(total_charge() > 0) + . += "bp-o" + else + . += "bp-d" -/obj/machinery/power/smes/connector/crowbar_act(mob/living/user, obj/item/tool) - if(!connector_free(user)) - return ITEM_INTERACT_BLOCKING - return ..() +/obj/machinery/power/smes/connector/RefreshParts() + . = ..() + + //happens if the terminal gets rped without a bank attached. No division by zero error + if(!total_capacity) + total_capacity = 1 /obj/machinery/power/smes/connector/wrench_act(mob/living/user, obj/item/tool) if(!connector_free(user)) @@ -66,119 +51,139 @@ return ITEM_INTERACT_BLOCKING return ..() +/obj/machinery/power/smes/connector/crowbar_act(mob/living/user, obj/item/tool) + if(!connector_free(user)) + return ITEM_INTERACT_BLOCKING + return ..() + /// checks if the connector is free; if not, alerts a user and returns FALSE /obj/machinery/power/smes/connector/proc/connector_free(mob/living/user) + PRIVATE_PROC(TRUE) + if(connected_smes) balloon_alert(user, "disconnect SMES first!") return FALSE return TRUE -/// connects the actual portable SMES once it's assigned, adjusting charge/maxcharge -/obj/machinery/power/smes/connector/proc/on_connect_smes() - charge = connected_smes.charge - capacity = connected_smes.capacity - update_appearance() +/** + * Connects the power bank to the smes + * Arguments + * + * * obj/machinery/power/smesbank/bank - the bank to connect + */ +/obj/machinery/power/smes/connector/proc/connect_smes(obj/machinery/smesbank/bank) + SHOULD_NOT_OVERRIDE(TRUE) -/// disconnects the portable SMES, resetting internal charge + capacity -/obj/machinery/power/smes/connector/proc/on_disconnect_smes() - input_attempt = FALSE - output_attempt = FALSE - charge = initial(charge) - capacity = initial(capacity) - update_appearance() + connected_smes = bank + if(connected_smes) + total_capacity = 0 + for(var/obj/item/stock_parts/power_store/power_cell in connected_smes.component_parts) + component_parts += power_cell + total_capacity += power_cell.max_charge() + else + inputting = FALSE + outputting = FALSE + total_capacity = 1 + for(var/obj/item/stock_parts/power_store/power_cell in component_parts) + component_parts -= power_cell + update_appearance(UPDATE_OVERLAYS) -// we really should only be adjusting charge when there's a connected SMES bank. -/obj/machinery/power/smes/connector/adjust_charge(charge_adjust) - . = ..() - connected_smes?.charge += charge_adjust - -// same as above - if we have to set charge, affect the connected SMES bank as well -/obj/machinery/power/smes/connector/set_charge(charge_set) - . = ..() - connected_smes?.charge = charge_set - -/obj/machinery/power/smes/connector/Destroy() - connected_smes?.disconnect_port() // in the unlikely but possible case a SMES is connected and this explodes +/obj/machinery/power/smes/connector/ui_act(action, params) + // prevent UI interactions if there's no SMES + if(!connected_smes) + balloon_alert(usr, "needs a connected SMES!") + return FALSE return ..() /// The actual portable part of the portable SMES system. Pretty useless without an actual connector. -/obj/machinery/power/smesbank +/obj/machinery/smesbank name = "portable power storage unit" desc = "A portable, high-capacity superconducting magnetic energy storage (SMES) unit. Requires a separate power connector port to actually interface with power networks." + icon = 'icons/obj/machines/engine/other.dmi' icon_state = "port_smes" circuit = /obj/item/circuitboard/machine/smesbank use_power = NO_POWER_USE // well, technically density = TRUE anchored = FALSE - can_change_cable_layer = FALSE // cable layering is handled via connector port - /// The charge capacity. - var/capacity = 50 * STANDARD_BATTERY_CHARGE // The board defaults with 5 high capacity batteries. - /// The current charge. + + /// The initial charge of this smes charge. var/charge = 0 /// The port this is connected to. var/obj/machinery/power/smes/connector/connected_port -/obj/machinery/power/smesbank/on_construction(mob/user) +/obj/machinery/smesbank/Initialize(mapload) . = ..() + + ///Initial connection for mapload + if(mapload) + var/obj/machinery/power/smes/connector/possible_connector = locate(/obj/machinery/power/smes/connector) in loc + if(!possible_connector) + return + if(!connect_port(possible_connector)) + return + possible_connector.input_attempt = TRUE + possible_connector.output_attempt = TRUE + + ///Initial charge + if(charge) + for(var/obj/item/stock_parts/power_store/power_cell in component_parts) + power_cell.use(power_cell.charge()) + if(charge) + charge -= power_cell.give(charge) + charge = 0 + + register_context() + +/obj/machinery/smesbank/on_construction(mob/user) set_anchored(FALSE) -/obj/machinery/power/smesbank/Initialize(mapload) - . = ..() - if(mapload) - mapped_setup() +/obj/machinery/smesbank/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE + if(isnull(held_item)) + return -/obj/machinery/power/smesbank/interact(mob/user) + if(held_item.tool_behaviour == TOOL_WRENCH) + context[SCREENTIP_CONTEXT_LMB] = "[connected_port ? "Disconnect" : "Connect"]" + return CONTEXTUAL_SCREENTIP_SET + if(held_item.tool_behaviour == TOOL_SCREWDRIVER) + context[SCREENTIP_CONTEXT_LMB] = "[panel_open ? "Close" : "Open"] Panel" + return CONTEXTUAL_SCREENTIP_SET + if(held_item.tool_behaviour == TOOL_CROWBAR && panel_open && !connected_port) + context[SCREENTIP_CONTEXT_LMB] = "Deconstruct" + return CONTEXTUAL_SCREENTIP_SET + +/obj/machinery/smesbank/examine(user) + . = ..() + . += span_notice("its maintenance panel can be [EXAMINE_HINT("screwed")] [panel_open ? "closed" : "open"].") + if(connected_port) + . += span_notice("You need to [EXAMINE_HINT("unwrench")] from the port before deconstructing.") + else + if(panel_open) + . += span_notice("It can be [EXAMINE_HINT("pried")] apart.") + . += span_notice("It should be [EXAMINE_HINT("wrenched")] onto a connector port to operate.") + +/obj/machinery/smesbank/Destroy() + disconnect_port() + return ..() + +/obj/machinery/smesbank/update_overlays() + . = ..() + if(panel_open || !is_operational) + return + + if(connected_port) + . += "smes-op[connected_port.outputting ? 1 : 0]" + . += "smes-oc[connected_port.inputting ? 1 : 0]" + var/clevel = connected_port.chargedisplay() + if(clevel > 0) + . += "smes-og[clevel]" + +/obj/machinery/smesbank/interact(mob/user) . = ..() connected_port?.interact(user) -/obj/machinery/power/smesbank/examine(user) - . = ..() - if(!connected_port) - . += span_warning("This SMES has no connector port!") - -//opening using screwdriver -/obj/machinery/power/smesbank/screwdriver_act(mob/living/user, obj/item/tool) - . = ITEM_INTERACT_BLOCKING - if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), tool)) - update_appearance() - return ITEM_INTERACT_SUCCESS - -/obj/machinery/power/smesbank/RefreshParts() - SHOULD_CALL_PARENT(FALSE) - var/max_charge = 0 - var/new_charge = 0 - for(var/obj/item/stock_parts/power_store/power_cell in component_parts) - max_charge += power_cell.maxcharge - new_charge += power_cell.charge - capacity = max_charge - if(!initial(charge) && !charge) - charge = new_charge - -/obj/machinery/power/smesbank/update_overlays() - . = ..() - if(machine_stat & BROKEN) - return - - if(panel_open) - return - - . += "smes-op[connected_port?.outputting ? 1 : 0]" - . += "smes-oc[connected_port?.inputting ? 1 : 0]" - var/clevel = chargedisplay() - if(clevel > 0) - . += "smes-og[clevel]" - -/obj/machinery/power/smesbank/proc/chargedisplay() - return clamp(round(5.5*charge/capacity),0,5) - -/obj/machinery/power/smesbank/default_deconstruction_crowbar(obj/item/crowbar/crowbar) - if(istype(crowbar) && connected_port) - balloon_alert(usr, "disconnect from [connected_port] first!") - return FALSE - return ..() - // adapted from portable atmos connection code -/obj/machinery/power/smesbank/wrench_act(mob/living/user, obj/item/wrench) +/obj/machinery/smesbank/wrench_act(mob/living/user, obj/item/wrench) if(connected_port) wrench.play_tool_sound(src) if(!wrench.use_tool(src, user, 8 SECONDS)) @@ -189,7 +194,7 @@ span_hear("You hear a ratchet.")) investigate_log("was disconnected from [connected_port] by [key_name(user)].", INVESTIGATE_ENGINE) disconnect_port() - update_appearance() + update_appearance(UPDATE_OVERLAYS) return ITEM_INTERACT_SUCCESS var/obj/machinery/power/smes/connector/possible_connector = locate(/obj/machinery/power/smes/connector) in loc @@ -206,12 +211,31 @@ "[user] connects [src].", \ span_notice("You fasten [src] to [possible_connector]."), \ span_hear("You hear a ratchet.")) - update_appearance() + update_appearance(UPDATE_OVERLAYS) investigate_log("was connected to [possible_connector] by [key_name(user)].", INVESTIGATE_ENGINE) return ITEM_INTERACT_SUCCESS -/// Attempt to connect the portable SMES to a given connector. Adapted from portable atmos connection code. -/obj/machinery/power/smesbank/proc/connect_port(obj/machinery/power/smes/connector/possible_connector) +/obj/machinery/smesbank/screwdriver_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_FAILURE + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), tool)) + update_appearance(UPDATE_OVERLAYS) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/smesbank/default_deconstruction_crowbar(obj/item/crowbar/crowbar) + if(istype(crowbar) && connected_port) + balloon_alert(usr, "disconnect from [connected_port] first!") + return ITEM_INTERACT_FAILURE + return ..() + +/** + * Attempt to connect the portable SMES to a given connector. Adapted from portable atmos connection code. + * + * Arguments + * * obj/machinery/power/smes/connector/possible_connector - the connector we are trying to link with + */ +/obj/machinery/smesbank/proc/connect_port(obj/machinery/power/smes/connector/possible_connector) + PRIVATE_PROC(TRUE) + //Make sure not already connected to something else if(connected_port || !possible_connector || possible_connector.connected_smes || possible_connector.panel_open) return FALSE @@ -222,59 +246,39 @@ //Perform the connection connected_port = possible_connector - connected_port.connected_smes = src - possible_connector.on_connect_smes() - set_anchored(TRUE) //Prevent movement - connected_port.update_appearance() - update_appearance() + connected_port.connect_smes(src) + set_anchored(TRUE) + update_appearance(UPDATE_OVERLAYS) return TRUE /// Disconnects the portable SMES from its assigned connector, if it has any. Also adapted from portable atmos connection code. -/obj/machinery/power/smesbank/proc/disconnect_port() +/obj/machinery/smesbank/proc/disconnect_port() + SHOULD_NOT_OVERRIDE(TRUE) + if(!connected_port) return - connected_port.on_disconnect_smes() - connected_port.connected_smes = null + + connected_port.connect_smes(null) connected_port = null set_anchored(FALSE) - update_appearance() + update_appearance(UPDATE_OVERLAYS) -/obj/machinery/power/smesbank/Destroy() - disconnect_port() - return ..() - -/// Adjusts the charge of the portable SMES. See SMES code. -/obj/machinery/power/smesbank/proc/adjust_charge(charge_adjust) - charge += charge_adjust - -/// Sets the charge of the portable SMES. See SMES code. -/obj/machinery/power/smesbank/proc/set_charge(charge_set) - charge = charge_set - -/obj/machinery/power/smesbank/emp_act(severity) +/obj/machinery/smesbank/emp_act(severity) . = ..() if(. & EMP_PROTECT_SELF) return - adjust_charge(-STANDARD_BATTERY_CHARGE/severity) // EMP'd banks double-dip on draining if connected. too bad, i guess - if (charge < 0) - set_charge(0) - update_appearance() -/// Attempt to locate, connect to, and activate a portable connector, for pre-mapped portable SMESes. -/obj/machinery/power/smesbank/proc/mapped_setup() - var/obj/machinery/power/smes/connector/possible_connector = locate(/obj/machinery/power/smes/connector) in loc - if(!possible_connector) - return - if(!connect_port(possible_connector)) - return - possible_connector.input_attempt = TRUE - possible_connector.output_attempt = TRUE + ///Drain the charge + var/charge_adjust = STANDARD_BATTERY_CHARGE / severity + for(var/obj/item/stock_parts/power_store/power_cell in component_parts) + charge_adjust -= power_cell.use(charge_adjust, TRUE) + if(!charge_adjust) + break -/obj/machinery/power/smesbank/super +/obj/machinery/smesbank/super name = "super capacity power storage unit" desc = "A portable, super-capacity, superconducting magnetic energy storage (SMES) unit. Relatively rare, and typically installed in long-range outposts where minimal maintenance is expected." circuit = /obj/item/circuitboard/machine/smesbank/super - capacity = 100 * STANDARD_BATTERY_CHARGE -/obj/machinery/power/smesbank/super/full +/obj/machinery/smesbank/super/full charge = 100 * STANDARD_BATTERY_CHARGE diff --git a/tgui/packages/tgui/interfaces/Smes.jsx b/tgui/packages/tgui/interfaces/Smes.tsx similarity index 86% rename from tgui/packages/tgui/interfaces/Smes.jsx rename to tgui/packages/tgui/interfaces/Smes.tsx index 0fddccb02b6..d0747dc6bf0 100644 --- a/tgui/packages/tgui/interfaces/Smes.jsx +++ b/tgui/packages/tgui/interfaces/Smes.tsx @@ -1,24 +1,39 @@ import { Box, Button, - Flex, LabeledList, ProgressBar, Section, Slider, + Stack, } from 'tgui-core/components'; import { formatPower } from 'tgui-core/format'; +import { round } from 'tgui-core/math'; import { useBackend } from '../backend'; import { Window } from '../layouts'; +type Data = { + capacity: number; + charge: number; + inputAttempt: number; + inputting: number; + inputLevel: number; + inputLevelMax: number; + inputAvailable: number; + outputAttempt: number; + outputting: number; + outputLevel: number; + outputLevelMax: number; + outputUsed: number; +}; + // Common power multiplier const POWER_MUL = 1e3; -export const Smes = (props) => { - const { act, data } = useBackend(); +export const Smes = () => { + const { act, data } = useBackend(); const { - capacityPercent, capacity, charge, inputAttempt, @@ -32,6 +47,8 @@ export const Smes = (props) => { outputLevelMax, outputUsed, } = data; + + const capacityPercent = round(100 * (charge / capacity), 0.1); const inputState = (capacityPercent >= 100 && 'good') || (inputting && 'average') || 'bad'; const outputState = @@ -70,8 +87,8 @@ export const Smes = (props) => { - - + +