diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index 89770d0c50e..e24aa5dabdf 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -26,7 +26,7 @@ var/obj/machinery/atmospherics/portables_connector/port = locate() in loc if(port) connect(port) - + /obj/machinery/portable_atmospherics/canister/Initialize() ..() @@ -41,6 +41,7 @@ air_contents.react() else update_icon() + SSvueui.check_uis_for_change(src) /obj/machinery/portable_atmospherics/Destroy() qdel(air_contents) @@ -113,6 +114,7 @@ user.drop_from_inventory(T,src) src.holding = T update_icon() + SSvueui.check_uis_for_change(src) return else if (W.iswrench()) @@ -120,6 +122,7 @@ disconnect() to_chat(user, "You disconnect \the [src] from the port.") update_icon() + SSvueui.check_uis_for_change(src) return else var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc @@ -127,6 +130,7 @@ if(connect(possible_port)) to_chat(user, "You connect \the [src] to the port.") update_icon() + SSvueui.check_uis_for_change(src) return else to_chat(user, "\The [src] failed to connect to the port.") @@ -170,6 +174,7 @@ cell = C user.visible_message("[user] opens the panel on [src] and inserts [C].", "You open the panel on [src] and insert [C].") power_change() + SSvueui.check_uis_for_change(src) return if(I.isscrewdriver()) @@ -182,6 +187,7 @@ cell.forceMove(src.loc) cell = null power_change() + SSvueui.check_uis_for_change(src) return ..() @@ -206,4 +212,4 @@ if(air_contents.gas.len == 0) return - message_admins("'[src.name]' was opened[cause ? " by [cause]" : ""], containing [english_list(air_contents.gas)]. (JMP)") \ No newline at end of file + message_admins("'[src.name]' was opened[cause ? " by [cause]" : ""], containing [english_list(air_contents.gas)]. (JMP)") diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index dee8f8e52a1..26da0601ecf 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -61,6 +61,7 @@ target_pressure = rand(0,1300) update_icon() + SSvueui.check_uis_for_change(src) ..(severity) @@ -111,6 +112,7 @@ update_icon() src.updateDialog() + SSvueui.check_uis_for_change(src) /obj/machinery/portable_atmospherics/powered/pump/return_air() return air_contents @@ -127,8 +129,8 @@ /obj/machinery/portable_atmospherics/powered/pump/attack_hand(var/mob/user) ui_interact(user) -/obj/machinery/portable_atmospherics/powered/pump/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1) - var/list/data[0] +/obj/machinery/portable_atmospherics/powered/pump/vueui_data_change(list/data, mob/user, datum/vueui/ui) + data = ..() || list() data["portConnected"] = connected_port ? 1 : 0 data["tankPressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0) data["targetpressure"] = round(target_pressure) @@ -143,13 +145,13 @@ data["hasHoldingTank"] = holding ? 1 : 0 if (holding) data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)) + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +/obj/machinery/portable_atmospherics/powered/pump/ui_interact(mob/user) + var/datum/vueui/ui = SSvueui.get_open_ui(user, src) if (!ui) - ui = new(user, src, ui_key, "portpump.tmpl", "Portable Pump", 480, 410, state = physical_state) - ui.set_initial_data(data) + ui = new(user, src, "machinery-atmospherics-portpump", 480, 410, "Portable Pump") ui.open() - ui.set_auto_update(1) /obj/machinery/portable_atmospherics/powered/pump/Topic(href, href_list) if(..()) @@ -166,10 +168,10 @@ holding.forceMove(loc) holding = null . = 1 - if (href_list["pressure_adj"]) - var/diff = text2num(href_list["pressure_adj"]) - target_pressure = min(10*ONE_ATMOSPHERE, max(0, target_pressure+diff)) + if (href_list["pressure_set"]) + target_pressure = between(pressuremin, text2num(href_list["pressure_set"]), pressuremax) . = 1 if(.) update_icon() + SSvueui.check_uis_for_change(src) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index d1e89c39cda..19922d1fdec 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -127,7 +127,6 @@ var/obj/item/cell/cell var/chargelevel = 0.0005 // Cap for how fast APC cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second) var/cellused = 0 - var/initalchargelevel = 0.0005 // Cap for how fast APC cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second) var/start_charge = 90 // initial cell charge % var/cell_type = /obj/item/cell/apc var/opened = COVER_CLOSED @@ -139,7 +138,7 @@ var/infected = FALSE var/operating = TRUE var/charging = CHARGING_OFF - var/chargemode = CHARGE_MODE_DISCHARGE + var/chargemode = TRUE // whether we're trying to charge var/chargecount = 0 var/locked = TRUE var/coverlocked = TRUE @@ -177,7 +176,7 @@ var/emergency_lights = FALSE var/time = 0 - var/charge_mode = CHARGE_MODE_CHARGE + var/charge_mode = CHARGE_MODE_CHARGE // if we're actually able to charge var/last_time = 1 /obj/machinery/power/apc/updateDialog() @@ -537,6 +536,7 @@ //to_chat(user, "You remove the power cell.") charging = CHARGING_OFF update_icon() + SSvueui.check_uis_for_change(src) return else if (istype(W, /obj/item/cell) && opened != COVER_CLOSED) // trying to put a cell inside if(cell) @@ -556,6 +556,7 @@ SPAN_NOTICE("You insert \the [cell].")) chargecount = 0 update_icon() + SSvueui.check_uis_for_change(src) else if (W.isscrewdriver()) // haxing if(opened != COVER_CLOSED) if (cell) @@ -587,7 +588,7 @@ else if(opened != COVER_CLOSED) to_chat(user, "You must close the cover to swipe an ID card.") else if(wiresexposed) - to_chat(user, "You must close the panel") + to_chat(user, "You must close the wiring panel to swipe an ID card.") else if(stat & (BROKEN|MAINT)) to_chat(user, "Nothing happens.") else if(hacker) @@ -596,6 +597,7 @@ if(allowed(usr) && !isWireCut(APC_WIRE_IDSCAN)) locked = !locked to_chat(user, "You [ locked ? "lock" : "unlock"] the APC interface.") + SSvueui.check_uis_for_change(src) update_icon() else to_chat(user, SPAN_WARNING("Access denied.")) @@ -730,6 +732,7 @@ emagged = FALSE if(infected) infected = FALSE + SSvueui.check_uis_for_change(src) else to_chat(user, SPAN_NOTICE("There has been a connection issue.")) return @@ -789,6 +792,7 @@ to_chat(user, SPAN_NOTICE("You hack the charging slot. The next IPC that charges from this APC will be hacked and slaved to you.")) infected = TRUE hacker = user + SSvueui.check_uis_for_change(src) if(!(emagged || hacker)) // trying to unlock with an emag card if(opened != COVER_CLOSED) to_chat(user, "You must close the cover to swipe an ID card.") @@ -804,6 +808,7 @@ locked = FALSE to_chat(user, SPAN_NOTICE("You hack the APC interface open.")) update_icon() + SSvueui.check_uis_for_change(src) else to_chat(user, SPAN_WARNING("You fail to [ locked ? "unlock" : "lock"] the APC interface.")) return TRUE @@ -887,6 +892,7 @@ SPAN_NOTICE("You remove the power cell.")) charging = CHARGING_ON update_icon() + SSvueui.check_uis_for_change(src) return if(stat & (BROKEN|MAINT)) return @@ -902,67 +908,49 @@ return ui_interact(user) -/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(!user) - return +/obj/machinery/power/apc/vueui_data_change(list/data, mob/user, datum/vueui/ui) + var/list/monitordata = ..() + data = list() + if(monitordata) + data = monitordata var/isAdmin = isobserver(user) && check_rights(R_ADMIN, FALSE, user) - var/list/data = list( - "locked" = (locked && !emagged) ? TRUE : FALSE, - "isOperating" = operating, - "externalPower" = main_status, - "powerCellStatus" = cell ? cell.percent() : null, - "chargeMode" = chargemode, - "lightingMode" = night_mode, - "chargingStatus" = charging, - "totalLoad" = round(lastused_total), - "totalCharging" = round(lastused_charging), - "coverLocked" = coverlocked, - "failTime" = failure_timer * 2, - "siliconUser" = isAdmin || issilicon(user), - "emergencyMode" = !emergency_lights, - "time" = time, - "charge_mode" = charge_mode, - - "powerChannels" = list( - list( - "title" = "Equipment", - "powerLoad" = lastused_equip, - "status" = equipment, - "topicParams" = list( - "auto" = list("eqp" = 3), - "on" = list("eqp" = 2), - "off" = list("eqp" = 1) - ) - ), - list( - "title" = "Lighting", - "powerLoad" = round(lastused_light), - "status" = lighting, - "topicParams" = list( - "auto" = list("lgt" = 3), - "on" = list("lgt" = 2), - "off" = list("lgt" = 1) - ) - ), - list( - "title" = "Environment", - "powerLoad" = round(lastused_environ), - "status" = environ, - "topicParams" = list( - "auto" = list("env" = 3), - "on" = list("env" = 2), - "off" = list("env" = 1) - ) - ) + data["locked"] = (locked && !emagged) + data["powerCellStatus"] = cell?.percent() + data["failTime"] = failure_timer * 2 + data["siliconUser"] = isAdmin || issilicon(user) + data["totalLoad"] = round(lastused_total) + data["totalCharging"] = round(lastused_charging) + data["isOperating"] = operating + data["chargeMode"] = chargemode + data["externalPower"] = main_status + data["lightingMode"] = night_mode + data["chargingStatus"] = charging + data["coverLocked"] = coverlocked + data["emergencyMode"] = !emergency_lights + data["time"] = time + data["charge_mode"] = charge_mode + data["powerChannels"] = list(\ + "Equipment" = list(\ + "powerLoad" = lastused_equip,\ + "status" = equipment + ), + "Lighting" = list( + "powerLoad" = round(lastused_light), + "status" = lighting + ), + "Environment" = list( + "powerLoad" = round(lastused_environ), + "status" = environ ) ) + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +/obj/machinery/power/apc/ui_interact(mob/user) + var/datum/vueui/ui = SSvueui.get_open_ui(user, src) if (!ui) - ui = new(user, src, ui_key, "apc.tmpl", "[area.name] - APC", 665, data["siliconUser"] ? 540 : 480) - ui.set_initial_data(data) + ui = new(user, src, "machinery-power-apc", 665, (isobserver(user) && check_rights(R_ADMIN, FALSE, user) || issilicon(user)) ? 540 : 480, "[area.name] - APC") ui.open() - ui.set_auto_update(TRUE) + ui.auto_update_content = TRUE /obj/machinery/power/apc/proc/report() return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])" @@ -977,6 +965,7 @@ area.power_equip = FALSE area.power_environ = FALSE area.power_change() + SSvueui.check_uis_for_change(src) /obj/machinery/power/apc/proc/isWireCut(var/wireIndex) return wires.IsIndexCut(wireIndex) @@ -984,15 +973,14 @@ /obj/machinery/power/apc/proc/can_use(mob/user, var/loud = 0) //used by attack_hand() and Topic() if(inoperable()) return FALSE + var/use_flags = issilicon(user) && USE_ALLOW_NON_ADJACENT // AIs and borgs can use it at range + use_flags |= (check_rights(R_ADMIN, FALSE, user) && USE_ALLOW_NONLIVING) // admins can use the UI when ghosting + if(use_check(user, use_flags, show_messages = TRUE)) + return FALSE if(isobserver(user)) - return check_rights(R_ADMIN, FALSE, user) // admins can use the UI when ghosting - if(user.stat) - to_chat(user, SPAN_WARNING("You must be conscious to use [src]!")) - return FALSE + return check_rights(R_ADMIN, FALSE, user) if(!user.client) return FALSE - if(!user.IsAdvancedToolUser()) - return FALSE if(user.restrained()) to_chat(user, SPAN_WARNING("You must have free hands to use [src].")) return FALSE @@ -1002,20 +990,13 @@ if (issilicon(user)) var/permit = FALSE // Malfunction variable. If AI hacks APC it can control it even without AI control wire. - var/mob/living/silicon/ai/AI = user var/mob/living/silicon/robot/robot = user - if(hacker) - if(hacker == AI) - permit = TRUE - else if(istype(robot) && robot.connected_ai && robot.connected_ai == hacker) // Cyborgs can use APCs hacked by their AI - permit = TRUE + if(hacker == user || hacker == robot.connected_ai) // Cyborgs can use APCs hacked by their AI + permit = TRUE if(aidisabled && !permit) if(!loud) - to_chat(user, SPAN_DANGER("\The [src] have AI control disabled!")) - return FALSE - else - if (!in_range(src, user) || !isturf(loc)) + to_chat(user, SPAN_DANGER("[src] has AI control disabled!")) return FALSE var/mob/living/carbon/human/H = user @@ -1031,30 +1012,31 @@ /obj/machinery/power/apc/Topic(href, href_list) if(..()) - return TRUE + return TOPIC_NOACTION if(!can_use(usr, 1)) - return TRUE + return TOPIC_NOACTION if (href_list["lmode"]) toggle_nightlight(href_list["lmode"]) update_icon() - return TRUE + SSvueui.check_uis_for_change(src) + return TOPIC_REFRESH var/isAdmin = isobserver(usr) && check_rights(R_ADMIN, FALSE) if(!issilicon(usr) && !isAdmin && locked && !emagged) // Shouldn't happen, this is here to prevent href exploits to_chat(usr, "You must unlock the panel to use this!") - return TRUE + return TOPIC_NOACTION if (href_list["emergency_lights"]) - emergency_lights = href_list["emergency_lights"] != "off" + emergency_lights = !emergency_lights for (var/obj/machinery/light/L in area) if (!initial(L.no_emergency)) L.no_emergency = emergency_lights //If there was an override set on creation, keep that override INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE) CHECK_TICK - return TRUE + return TOPIC_REFRESH if (href_list["lock"]) coverlocked = !coverlocked @@ -1072,22 +1054,17 @@ if(!chargemode) charging = CHARGING_OFF update_icon() + SSvueui.check_uis_for_change(src) - else if (href_list["eqp"]) - var/val = text2num(href_list["eqp"]) - equipment = setsubsystem(val) - update_icon() - update() - - else if (href_list["lgt"]) - var/val = text2num(href_list["lgt"]) - lighting = setsubsystem(val) - update_icon() - update() - - else if (href_list["env"]) - var/val = text2num(href_list["env"]) - environ = setsubsystem(val) + else if (href_list["set"]) + var/val = text2num(href_list["set"]) + switch(href_list["chan"]) + if("Equipment") + equipment = setsubsystem(val) + if("Lighting") + lighting = setsubsystem(val) + if("Environment") + environ = setsubsystem(val) update_icon() update() @@ -1102,8 +1079,10 @@ else locked = !locked update_icon() + SSvueui.check_uis_for_change(src) - return FALSE + SSvueui.check_uis_for_change(src) + return TOPIC_REFRESH /obj/machinery/power/apc/proc/toggle_breaker() operating = !operating @@ -1184,14 +1163,14 @@ // draw power from cell as before to power the area cellused = min(cell.charge, CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell cell.use(cellused) - + var/draw = 0 if(excess > lastused_total) // if power excess recharge the cell // by the same amount just used - var/draw = draw_power(cellused/CELLRATE) // draw the power needed to charge this cell + draw = draw_power(cellused/CELLRATE) // draw the power needed to charge this cell cell.give(draw * CELLRATE) else // no excess, and not enough per-apc if( (cell.charge/CELLRATE + excess) >= lastused_total) // can we draw enough from cell+grid to cover last usage? - var/draw = draw_power(excess) + draw = draw_power(excess) cell.charge = min(cell.maxcharge, cell.charge + CELLRATE * draw) //recharge with what we can charging = CHARGING_OFF else // not enough power available to run the last tick! @@ -1215,8 +1194,8 @@ ch = draw_power(ch/CELLRATE) // Removes the power we're taking from the grid cell.give(ch*CELLRATE) // actually recharge the cell - lastused_charging = ch - lastused_total += ch // Sensors need this to stop reporting APC charging as "Other" load + lastused_charging = ch + draw + lastused_total += ch + draw // Sensors need this to stop reporting APC charging as "Other" load else charging = CHARGING_OFF // stop charging chargecount = 0 @@ -1239,7 +1218,7 @@ charging = CHARGING_ON else // chargemode off - charging = CHARGING_ON + charging = CHARGING_OFF chargecount = 0 else // no cell, switch everything off @@ -1423,12 +1402,12 @@ /obj/machinery/power/apc/proc/update_time() - var/delta_power = (lastused_charging) ? (-lastused_charging) : (lastused_total) - delta_power *= 0.0005 + var/delta_power = (lastused_charging * 2) - lastused_total + delta_power *= CELLRATE - var/goal = (delta_power > 0) ? (cell.charge) : (cell.maxcharge - cell.charge) - - var/time_secs = (delta_power) ? ((goal / abs(delta_power)) / (round(world.time - last_time) / 10)) : (0) + var/goal = (delta_power < 0) ? (cell.charge) : (cell.maxcharge - cell.charge) + time = world.time + (delta_power ? ((goal / abs(delta_power)) * (world.time - last_time)) : 0) + // If it is negative - we are discharging if(delta_power < 0) charge_mode = CHARGE_MODE_DISCHARGE else if(delta_power > 0) @@ -1436,7 +1415,6 @@ else charge_mode = CHARGE_MODE_STABLE last_time = world.time - time = ((time_secs / 3600) > 1) ? ("[round(time_secs / 3600)] hours, [round((time_secs % 3600) / 60)] minutes") : ("[round(time_secs / 60)] minutes, [round(time_secs % 60)] seconds") #undef UPDATE_CELL_IN #undef UPDATE_OPENED1 diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 3bb61a4ec0d..70f8bf0b632 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -201,8 +201,7 @@ delta_power *= SMESRATE var/goal = (delta_power < 0) ? (charge) : (capacity - charge) - - var/time_secs = (delta_power) ? ((goal / abs(delta_power)) * (round(world.time - last_time) / 10)) : (0) + time = world.time + (delta_power ? ((goal / abs(delta_power)) * (world.time - last_time)) : 0) // If it is negative - we are discharging if(delta_power < 0) charge_mode = 0 @@ -211,7 +210,6 @@ else charge_mode = 2 last_time = world.time - time = ((time_secs / 3600) > 1) ? ("[round(time_secs / 3600)] hours, [round((time_secs % 3600) / 60)] minutes") : ("[round(time_secs / 60)] minutes, [round(time_secs % 60)] seconds") /obj/machinery/power/smes/machinery_process() if(!can_function()) @@ -252,6 +250,8 @@ else outputting = 0 + SSvueui.check_uis_for_change(src) + // called after all power processes are finished // restores charge level to smes if there was excess this ptick /obj/machinery/power/smes/proc/restore(var/percent_load) @@ -277,6 +277,7 @@ if(clev != chargedisplay() ) //if needed updates the icons overlay update_icon() + SSvueui.check_uis_for_change(src) return //Will return 1 on failure @@ -393,7 +394,32 @@ return 0 return 1 -/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/power/smes/vueui_data_change(list/data, mob/user, datum/vueui/ui) + // this is the data that will be sent to the ui + data = list() + var/list/monitordata = ..() + if(monitordata) + data = monitordata + data["nameTag"] = name_tag + data["chargeTaken"] = round(input_taken) + data["charging"] = inputting + data["chargeAttempt"] = input_attempt + data["chargeLevel"] = input_level + data["chargeMax"] = input_level_max + data["outputLoad"] = round(output_used) + data["outputting"] = outputting + data["outputOnline"] = output_attempt + data["outputLevel"] = output_level + data["outputMax"] = output_level_max + data["time"] = time + data["chargeMode"] = charge_mode + data["storedCapacity"] = 0 + if(capacity) + data["storedCapacity"] = round(100.0*charge/capacity, 0.1) + data["failTime"] = failure_timer * 2 + return data + +/obj/machinery/power/smes/ui_interact(mob/user) if(!can_function()) if(!terminal) to_chat(user, SPAN_WARNING("\The [src] is lacking a terminal!")) @@ -401,41 +427,13 @@ if(is_badly_damaged()) to_chat(user, SPAN_WARNING("\The [src] is too damaged to function!")) return - - // this is the data which will be sent to the ui - var/data[0] - data["nameTag"] = name_tag - if(capacity) - data["storedCapacity"] = round(100.0*charge/capacity, 0.1) - else - data["storedCapacity"] = 0 - data["charging"] = inputting - data["chargeMode"] = input_attempt - data["chargeLevel"] = input_level - data["chargeMax"] = input_level_max - data["charge_taken"] = round(input_taken) - data["outputOnline"] = output_attempt - data["outputLevel"] = output_level - data["outputMax"] = output_level_max - data["outputLoad"] = round(output_used) - data["failTime"] = failure_timer * 2 - data["outputting"] = outputting - data["time"] = time - data["charge_mode"] = charge_mode - - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + var/datum/vueui/ui = SSvueui.get_open_ui(user, src) if (!ui) // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "smes.tmpl", "SMES Unit", 540, 420) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) + ui = new(user, src, "machinery-power-smes", 540, 420, "SMES Unit") // open the new ui window ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) /obj/machinery/power/smes/proc/Percentage() return round(100.0*charge/capacity, 0.1) @@ -447,7 +445,6 @@ if( href_list["cmode"] ) inputting(!input_attempt) update_icon() - else if( href_list["online"] ) outputting(!output_attempt) update_icon() @@ -455,27 +452,11 @@ failure_timer = 0 update_icon() else if( href_list["input"] ) - switch( href_list["input"] ) - if("min") - input_level = 0 - if("max") - input_level = input_level_max - if("set") - input_level = input(usr, "Enter new input level (0-[input_level_max])", "SMES Input Power Control", input_level) as num - input_level = max(0, min(input_level_max, input_level)) // clamp to range - + input_level = clamp(href_list["input"], 0, input_level_max) // clamp to range else if( href_list["output"] ) - switch( href_list["output"] ) - if("min") - output_level = 0 - if("max") - output_level = output_level_max - if("set") - output_level = input(usr, "Enter new output level (0-[output_level_max])", "SMES Output Power Control", output_level) as num - output_level = max(0, min(output_level_max, output_level)) // clamp to range - + output_level = clamp(href_list["output"], 0, output_level_max) // clamp to range investigate_log("input/output; on":"off"] | Input-mode: [input_attempt?"auto":"off"] by [usr.key]","singulo") - + SSvueui.check_uis_for_change(src) return 1 /obj/machinery/power/smes/proc/energy_fail(var/duration) diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index cf956b79f63..0bf9945b87b 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -352,29 +352,23 @@ Consume(user) // This is purely informational UI that may be accessed by AIs or robots -/obj/machinery/power/supermatter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - +/obj/machinery/power/supermatter/vueui_data_change(list/data, mob/user, datum/vueui/ui) + data = ..() || list() data["integrity_percentage"] = round(get_integrity()) var/datum/gas_mixture/env = null if(!istype(src.loc, /turf/space)) env = src.loc.return_air() - - if(!env) - data["ambient_temp"] = 0 - data["ambient_pressure"] = 0 - else - data["ambient_temp"] = round(env.temperature) - data["ambient_pressure"] = round(env.return_pressure()) + data["ambient_temp"] = round(env?.temperature) + data["ambient_pressure"] = round(env?.return_pressure()) data["detonating"] = grav_pulling + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +/obj/machinery/power/supermatter/ui_interact(mob/user) + var/datum/vueui/ui = SSvueui.get_open_ui(user, src) if (!ui) - ui = new(user, src, ui_key, "supermatter_crystal.tmpl", "Supermatter Crystal", 500, 300) - ui.set_initial_data(data) + ui = new(user, src, "machinery-power-supermattercrystal", 500, 300, "Supermatter Crystal", state = interactive_state) + ui.auto_update_content = TRUE ui.open() - ui.set_auto_update(1) - /* /obj/machinery/power/supermatter/proc/transfer_energy() diff --git a/code/modules/vueui/var_monitor.dm b/code/modules/vueui/var_monitor.dm index b49e0396b1a..481f92d327f 100644 --- a/code/modules/vueui/var_monitor.dm +++ b/code/modules/vueui/var_monitor.dm @@ -63,4 +63,4 @@ // Transform functions. // Do not override. /datum/vueui_var_monitor/proc/transform_to_boolean(invert, source, current) - return !!source ^ invert \ No newline at end of file + return !!source ^ invert diff --git a/html/changelogs/mdp-vue-power.yml b/html/changelogs/mdp-vue-power.yml new file mode 100644 index 00000000000..0c089c7172e --- /dev/null +++ b/html/changelogs/mdp-vue-power.yml @@ -0,0 +1,46 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: MoondancerPony + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - refactor: "Vue-ifies portable air pumps, APCs, SMES units, and the AI/admin Supermatter Crystal monitor. A lot of them have been spruced up as well!" + - backend: "Adds an optional min/max button to VueUI numeric inputs." + - tweak: "Fixes some missing formatting for VueUI progress bars." + - tweak: "FontAwesome icons in VueUI windows are now fixed-width. Thanks for pointing out the issue, Geeves!" + - tweak: "VueUI group-item elements now have their labels top-aligned." + - tweak: "VueUI windows now have a transparent background box to provide more visual contrast. This might cause issues with window sizes; please report them if encountered so the default sizes can be adjusted." diff --git a/nano/templates/apc.tmpl b/nano/templates/apc.tmpl deleted file mode 100644 index 1b87d9ed7b1..00000000000 --- a/nano/templates/apc.tmpl +++ /dev/null @@ -1,231 +0,0 @@ -{{if data.failTime}} -
-

SYSTEM FAILURE

- I/O regulators malfunction detected! Waiting for system reboot...
- Automatic reboot in {{:data.failTime}} seconds... - {{:helper.link('Reboot Now', 'refresh', {'reboot' : 1})}}


-
-{{else}} -
- {{if data.siliconUser}} -
- Interface Lock: -
-
- {{:helper.link('Engaged', 'locked', {'toggleaccess' : 1}, data.locked ? 'selected' : null)}}{{:helper.link('Disengaged', 'unlocked', {'toggleaccess' : 1}, data.malfStatus >= 2 ? 'linkOff' : (data.locked ? null : 'selected'))}} -
-
- {{else}} - {{if data.locked}} - Swipe an ID card to unlock this interface - {{else}} - Swipe an ID card to lock this interface - {{/if}} - {{/if}} -
- -
- -

Power Status

- -
-
- Main Breaker: -
-
- {{if data.locked && !data.siliconUser}} - {{if data.isOperating}} - On - {{else}} - Off - {{/if}} - {{else}} - {{:helper.link('On', 'power', {'breaker' : 1}, data.isOperating ? 'selected' : null)}}{{:helper.link('Off', 'close', {'breaker' : 1}, data.isOperating ? null : 'selected')}} - {{/if}} -
-
- -
-
- External Power: -
-
- {{if data.externalPower == 2}} - Good - {{else data.externalPower == 1}} - Low - {{else}} - None - {{/if}} -
-
- -
-
- Power Cell: -
- {{if data.powerCellStatus == null}} -
- Power cell removed. -
- {{else}} - - {{:helper.displayBar(data.powerCellStatus, 0, 100, (data.powerCellStatus >= 50) ? 'good' : (data.powerCellStatus >= 25) ? 'average' : 'bad')}} -
- {{:helper.round(data.powerCellStatus*10)/10}}% -
- {{/if}} -
- -
-
- Power Cell charge status: -
-
-
- {{if data.charge_mode == 1}} - APC's power cell will be fully charged in {{:data.time}} - {{else data.charge_mode == 2}} - APC's power cell input and output are equal - {{else}} - APC's power cell will run out of charge in {{:data.time}} - {{/if}} - -
-
-
- - {{if data.powerCellStatus != null}} -
-
- Charge Mode: -
-
- {{if data.locked && !data.siliconUser}} - {{if data.chargeMode}} - Auto - {{else}} - Off - {{/if}} - {{else}} - {{:helper.link('Auto', 'refresh', {'cmode' : 1}, data.chargeMode ? 'selected' : null)}}{{:helper.link('Off', 'close', {'cmode' : 1}, data.chargeMode ? null : 'selected')}} - {{/if}} -   - {{if data.chargingStatus > 1}} - [Fully Charged] - {{else data.chargingStatus == 1}} - [Charging] - {{else}} - [Not Charging] - {{/if}} -
-
- {{/if}} -
-
- Night Lighting: -
-
- {{:helper.link('On', 'night', {'lmode' : 'on'}, data.lightingMode ? 'selected' : null)}}{{:helper.link('Off', 'close', {'lmode' : 'off'}, data.lightingMode ? null : 'selected')}} -
-
-
-
- Emergency Lighting: -
-
- {{if data.locked && !data.siliconUser}} - {{if data.emergencyMode}} - On - {{else}} - Off - {{/if}} -
- {{else}} - {{:helper.link(data.emergencyMode ? 'On' : 'Off', 'lightbulb', {'emergency_lights' : data.emergencyMode ? 'on' : 'off'}, null)}} - {{/if}} -
-
- -

Power Channels

- - {{for data.powerChannels}} -
-
- {{:value.title}}: -
-
- {{:value.powerLoad}} W -
-
-    - {{if value.status <= 1}} - Off - {{else value.status >= 2}} - On - {{/if}} - {{if data.locked}} - {{if value.status == 1 || value.status == 3}} -   Auto - {{else}} -   Manual - {{/if}} - {{/if}} -
- {{if !data.locked || data.siliconUser}} -
- {{:helper.link('Auto', 'refresh', value.topicParams.auto, (value.status == 1 || value.status == 3) ? 'selected' : null)}} - {{:helper.link('On', 'power', value.topicParams.on, (value.status == 2) ? 'selected' : null)}} - {{:helper.link('Off', 'close', value.topicParams.off, (value.status == 0) ? 'selected' : null)}} -
- {{/if}} -
- {{/for}} - -
-
- Total Load: -
-
- {{if data.totalCharging}} - {{:data.totalLoad}}W (+ {{:data.totalCharging}}W Charging) - {{else}} - {{:data.totalLoad}}W - {{/if}} -
-
- -
 
- -
-
- Cover Lock: -
-
- {{if data.locked && !data.siliconUser}} - {{if data.coverLocked}} - Engaged - {{else}} - Disengaged - {{/if}} - {{else}} - {{:helper.link('Engaged', 'locked', {'lock' : 1}, data.coverLocked ? 'selected' : null)}}{{:helper.link('Disengaged', 'unlocked', {'lock' : 1}, data.coverLocked ? null : 'selected')}} - {{/if}} -
-
- - {{if data.siliconUser}} -

System Overrides

- -
- {{:helper.link('Overload Lighting Circuit', 'lightbulb', {'overload' : 1})}} - {{if data.malfStatus == 1}} - {{:helper.link('Override Programming', 'script', {'malfhack' : 1})}} - {{else data.malfStatus > 1}} -
APC Hacked
- {{/if}} -
- {{/if}} - - -{{/if}} diff --git a/nano/templates/smes.tmpl b/nano/templates/smes.tmpl deleted file mode 100644 index 79d3d97b531..00000000000 --- a/nano/templates/smes.tmpl +++ /dev/null @@ -1,128 +0,0 @@ -{{if data.failTime}} -
-

SYSTEM FAILURE

- I/O regulators malfunction detected! Waiting for system reboot...
- Automatic reboot in {{:data.failTime}} seconds... - {{:helper.link('Reboot Now', 'refresh', {'reboot' : 1})}}


-
-{{else}} -
-
- Stored Capacity: -
-
- {{:helper.displayBar(data.storedCapacity, 0, 100, data.charging ? 'good' : 'average')}} -
- {{:helper.round(data.storedCapacity)}}% -
-
-
- -
-
- Charge status: -
-
-
- {{if data.charge_mode == 1}} - SMES will be fully charged in {{:data.time}} - {{else data.charge_mode == 2}} - SMES input and output are equal - {{else}} - SMES will run out of charge in {{:data.time}} - {{/if}} - -
-
-
- -

Input Management

-
-
- Charge Mode: -
-
- {{:helper.link('Auto', 'refresh', {'cmode' : 1}, data.chargeMode ? 'selected' : null)}}{{:helper.link('Off', 'close', {'cmode' : 1}, data.chargeMode ? null : 'selected')}} -   - {{if data.charging == 2}} - [Charging] - {{else data.charging == 1}} - [Partially Charging] - {{else}} - [Not Charging] - {{/if}} -
-
- -
-
- Input Level: -
-
- {{:helper.displayBar(data.chargeLevel, 0, data.chargeMax)}} -
- {{:helper.link('MIN', null, {'input' : 'min'}, (data.chargeLevel > 0) ? null : 'disabled')}} - {{:helper.link('SET', null, {'input' : 'set'}, null)}} - {{:helper.link('MAX', null, {'input' : 'max'}, (data.chargeLevel < data.chargeMax) ? null : 'disabled')}} -
 {{:data.chargeLevel}} W 
-
-
- -
-
- Input Load: -
-
- {{:helper.displayBar(data.charge_taken, 0, data.chargeMax, (data.charge_taken < data.chargeLevel) ? 'average' : 'good')}} -
- {{:data.charge_taken}} W -
-
-
- -

Output Management

-
-
- Output Status: -
-
- {{:helper.link('Online', 'power', {'online' : 1}, data.outputOnline ? 'selected' : null)}}{{:helper.link('Offline', 'close', {'online' : 1}, data.outputOnline ? null : 'selected')}} -   - {{if data.outputting == 2}} - [Outputting] - {{else data.outputting == 1}} - [Disconnected or No Charge] - {{else}} - [Not Outputting] - {{/if}} -
-
- -
-
- Output Level: -
-
- {{:helper.displayBar(data.outputLevel, 0, data.outputMax)}} -
- {{:helper.link('MIN', null, {'output' : 'min'}, (data.outputLevel > 0) ? null : 'disabled')}} - {{:helper.link('SET', null, {'output' : 'set'}, null)}} - {{:helper.link('MAX', null, {'output' : 'max'}, (data.outputLevel < data.outputMax) ? null : 'disabled')}} -
 {{:data.outputLevel}} W 
-
-
-
- -
-
- Output Load: -
-
- {{:helper.displayBar(data.outputLoad, 0, data.outputMax, (data.outputLoad < data.outputLevel) ? 'good' : 'average')}} -
- {{:data.outputLoad}} W -
-
-
- -{{/if}} diff --git a/nano/templates/supermatter_crystal.tmpl b/nano/templates/supermatter_crystal.tmpl deleted file mode 100644 index b06aaae7466..00000000000 --- a/nano/templates/supermatter_crystal.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{if data.detonating}} -
-

CRYSTAL DELAMINATING

-

Evacuate area immediately

-
-
-{{else}} -

Crystal Integrity

- {{:helper.displayBar(data.integrity_percentage, 0, 100, (data.integrity_percentage >= 90) ? 'good' : (data.integrity_percentage >= 25) ? 'average' : 'bad')}} - {{:data.integrity_percentage}} % -

Environment

- - Temperature: - - - {{:helper.displayBar(data.ambient_temp, 0, 10000, (data.ambient_temp >= 5000) ? 'bad' : (data.ambient_temp >= 4000) ? 'average' : 'good')}} - {{:data.ambient_temp}} K - - - Pressure: - - - {{:data.ambient_pressure}} kPa - -{{/if}} \ No newline at end of file diff --git a/vueui/src/assets/global.scss b/vueui/src/assets/global.scss index 46c683abbb4..562b349fdfc 100644 --- a/vueui/src/assets/global.scss +++ b/vueui/src/assets/global.scss @@ -55,6 +55,9 @@ body.vueui { #content > div { margin-right: 8px; margin-top: 8px; + background-image: url(resources/uiTransparent.png); + padding: 0.5em; + box-sizing: border-box; } .uiTitleWrapper { @@ -173,6 +176,7 @@ a, .button, button, input[type=submit], input[type=button], input[type=reset], i font-weight: bold; padding: 3px 4px; margin: 4px 0px; + box-sizing: border-box; } .displayBar { diff --git a/vueui/src/assets/icons.scss b/vueui/src/assets/icons.scss index 4ef23e169db..647528fb266 100644 --- a/vueui/src/assets/icons.scss +++ b/vueui/src/assets/icons.scss @@ -23,6 +23,7 @@ $fa-css-prefix: "ic"; .uiIcon16 { @include fa-icon; @extend .fas; + @extend .#{$fa-css-prefix}-fw; font-size: 12px; padding: 2px; } @@ -236,22 +237,22 @@ $fa-css-prefix: "ic"; "chiefengineer" $fa-var-wrench, "researchdirector" $fa-var-lightbulb, "chiefmedicalofficer" $fa-var-plus, - + /* Engineering Positions */ "stationengineer" $fa-var-wrench, "atmospherictechnician" $fa-var-wrench, - + /* Medical Positions */ "medicaldoctor" $fa-var-plus, "psychiatrist" $fa-var-plus, "chemist" $fa-var-plus, - + /* Science Positions */ "scientist" $fa-var-lightbulb, "geneticist" $fa-var-lightbulb, "roboticist" $fa-var-lightbulb, "xenobiologist" $fa-var-lightbulb, - + /* Security Positions */ "warden" $fa-var-key, "detective" $fa-var-key, @@ -267,4 +268,4 @@ $fa-css-prefix: "ic"; } } } -} \ No newline at end of file +} diff --git a/vueui/src/assets/resources/uiTransparent.png b/vueui/src/assets/resources/uiTransparent.png new file mode 100644 index 00000000000..d7d9d8db905 Binary files /dev/null and b/vueui/src/assets/resources/uiTransparent.png differ diff --git a/vueui/src/components/view/machinery/atmospherics/portpump.vue b/vueui/src/components/view/machinery/atmospherics/portpump.vue new file mode 100644 index 00000000000..83dd55b5f6d --- /dev/null +++ b/vueui/src/components/view/machinery/atmospherics/portpump.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/vueui/src/components/view/machinery/power/apc.vue b/vueui/src/components/view/machinery/power/apc.vue new file mode 100644 index 00000000000..247bc6ef997 --- /dev/null +++ b/vueui/src/components/view/machinery/power/apc.vue @@ -0,0 +1,171 @@ + + + diff --git a/vueui/src/components/view/machinery/power/smes.vue b/vueui/src/components/view/machinery/power/smes.vue new file mode 100644 index 00000000000..f8b719e89dc --- /dev/null +++ b/vueui/src/components/view/machinery/power/smes.vue @@ -0,0 +1,125 @@ + + + diff --git a/vueui/src/components/view/machinery/power/supermattercrystal.vue b/vueui/src/components/view/machinery/power/supermattercrystal.vue new file mode 100644 index 00000000000..ca65d09013b --- /dev/null +++ b/vueui/src/components/view/machinery/power/supermattercrystal.vue @@ -0,0 +1,44 @@ + + + diff --git a/vueui/src/components/vui/button.vue b/vueui/src/components/vui/button.vue index 0a827013f94..86e7bfce6fc 100644 --- a/vueui/src/components/vui/button.vue +++ b/vueui/src/components/vui/button.vue @@ -1,6 +1,6 @@ @@ -14,6 +14,14 @@ export default { type: String, default: "" }, + rotate: { + type: Number, + default: 0 + }, + flip: { + type: String, + default: "" + }, params: { type: Object, default: null @@ -52,6 +60,24 @@ export default { } Utils.sendToTopic(this.params, this.pushState) } + }, + computed: { + getRotateClass() { + switch(this.rotate % 360) { + case 90: + return "ic-rotate-90" + case 180: + return "ic-rotate-180" + case 270: + return "ic-rotate-270" + default: + return "" + } + }, + getFlipClass() { + if(!this.flip) return + return `ic-flip-${this.flip}` + } } } diff --git a/vueui/src/components/vui/group-item.vue b/vueui/src/components/vui/group-item.vue index f58a3261cb6..54a2161ba7b 100644 --- a/vueui/src/components/vui/group-item.vue +++ b/vueui/src/components/vui/group-item.vue @@ -29,5 +29,6 @@ div.item { .itemLabel { padding-right: 8px; width: 4%; + vertical-align: top; } diff --git a/vueui/src/components/vui/input/numeric.vue b/vueui/src/components/vui/input/numeric.vue index 95c0454eaa9..196ad4151d0 100644 --- a/vueui/src/components/vui/input/numeric.vue +++ b/vueui/src/components/vui/input/numeric.vue @@ -1,8 +1,10 @@ @@ -14,6 +16,14 @@ export default { type: Number, default: 0 }, + minButton: { + type: Boolean, + default: false + }, + maxButton: { + type: Boolean, + default: false + }, buttonCount: { type: Number, default: 1 diff --git a/vueui/src/components/vui/progress.vue b/vueui/src/components/vui/progress.vue index c8c1b8d263e..26abdfabbb3 100644 --- a/vueui/src/components/vui/progress.vue +++ b/vueui/src/components/vui/progress.vue @@ -29,6 +29,16 @@ export default {