mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-15 09:03:23 +01:00
[TGUI] Air Alarms + Central Atmos Control (#14620)
* [TGUI] Air Alarms + Central Atmos Control * Mochi Tweaks
This commit is contained in:
Vendored
+5
-5
@@ -2,8 +2,8 @@
|
||||
|
||||
GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new())
|
||||
|
||||
/datum/repository/air_alarm/proc/air_alarm_data(var/list/monitored_alarms, var/refresh = 0, var/obj/machinery/alarm/passed_alarm)
|
||||
var/alarms[0]
|
||||
/datum/repository/air_alarm/proc/air_alarm_data(list/monitored_alarms, refresh = FALSE, obj/machinery/alarm/passed_alarm)
|
||||
var/list/alarms = list()
|
||||
|
||||
var/datum/cache_entry/cache_entry = cache_data
|
||||
if(!cache_entry)
|
||||
@@ -16,20 +16,20 @@ GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new())
|
||||
if(SSticker && SSticker.current_state < GAME_STATE_PLAYING && istype(passed_alarm)) // Generating the list for the first time as the game hasn't started - no need to run through the machines list everything every time
|
||||
alarms = cache_entry.data // Don't deleate the list
|
||||
if(is_station_contact(passed_alarm.z) && passed_alarm.remote_control) // Still need sanity checks
|
||||
alarms[++alarms.len] = passed_alarm.get_nano_data_console()
|
||||
alarms[++alarms.len] = passed_alarm.get_console_data()
|
||||
else
|
||||
for(var/obj/machinery/alarm/alarm in (monitored_alarms ? monitored_alarms : GLOB.air_alarms)) // Generating the whole list again is a bad habit but I can't be bothered to fix it right now
|
||||
if(!monitored_alarms && !is_station_contact(alarm.z))
|
||||
continue
|
||||
if(!alarm.remote_control)
|
||||
continue
|
||||
alarms[++alarms.len] = alarm.get_nano_data_console()
|
||||
alarms[++alarms.len] = alarm.get_console_data()
|
||||
|
||||
cache_entry.timestamp = world.time //+ 10 SECONDS
|
||||
cache_entry.data = alarms
|
||||
return alarms
|
||||
|
||||
/datum/repository/air_alarm/proc/update_cache(var/obj/machinery/alarm/alarm)
|
||||
/datum/repository/air_alarm/proc/update_cache(obj/machinery/alarm/alarm)
|
||||
return air_alarm_data(refresh = 1, passed_alarm = alarm)
|
||||
|
||||
#undef AIR_ALARM_DATA_CACHE_DURATION
|
||||
|
||||
+178
-197
@@ -44,12 +44,6 @@
|
||||
#define AALARM_PRESET_COLDROOM 3 // Kitchen coldroom
|
||||
#define AALARM_PRESET_SERVER 4 // Server coldroom
|
||||
|
||||
#define AALARM_SCREEN_MAIN 1
|
||||
#define AALARM_SCREEN_VENT 2
|
||||
#define AALARM_SCREEN_SCRUB 3
|
||||
#define AALARM_SCREEN_MODE 4
|
||||
#define AALARM_SCREEN_SENSORS 5
|
||||
|
||||
#define AALARM_REPORT_TIMEOUT 100
|
||||
|
||||
#define RCON_NO 1
|
||||
@@ -109,7 +103,6 @@
|
||||
|
||||
var/mode = AALARM_MODE_SCRUBBING
|
||||
var/preset = AALARM_PRESET_HUMAN
|
||||
var/screen = AALARM_SCREEN_MAIN
|
||||
var/area_uid
|
||||
var/area/alarm_area
|
||||
var/danger_level = ATMOS_ALARM_NONE
|
||||
@@ -377,7 +370,7 @@
|
||||
if(ATMOS_ALARM_DANGER)
|
||||
icon_state = "alarm1"
|
||||
|
||||
/obj/machinery/alarm/proc/register_env_machine(var/m_id, var/device_type)
|
||||
/obj/machinery/alarm/proc/register_env_machine(m_id, device_type)
|
||||
var/new_name
|
||||
if(device_type=="AVP")
|
||||
new_name = "[alarm_area.name] Vent Pump #[alarm_area.air_vent_names.len+1]"
|
||||
@@ -407,7 +400,7 @@
|
||||
frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM)
|
||||
|
||||
/obj/machinery/alarm/proc/send_signal(var/target, var/list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise
|
||||
/obj/machinery/alarm/proc/send_signal(target, list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
@@ -420,9 +413,7 @@
|
||||
signal.data["sigtype"] = "command"
|
||||
|
||||
radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM)
|
||||
// to_chat(world, text("Signal [] Broadcasted to []", command, target))
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/alarm/proc/apply_mode()
|
||||
switch(mode)
|
||||
@@ -573,10 +564,13 @@
|
||||
///////////////
|
||||
|
||||
/obj/machinery/alarm/attack_ai(mob/user)
|
||||
src.add_hiddenprint(user)
|
||||
return ui_interact(user)
|
||||
if(buildstage != 2)
|
||||
return
|
||||
|
||||
/obj/machinery/alarm/attack_ghost(user as mob)
|
||||
add_hiddenprint(user)
|
||||
return tgui_interact(user)
|
||||
|
||||
/obj/machinery/alarm/attack_ghost(mob/user)
|
||||
return interact(user)
|
||||
|
||||
/obj/machinery/alarm/attack_hand(mob/user)
|
||||
@@ -593,7 +587,7 @@
|
||||
wires.Interact(user)
|
||||
|
||||
if(!shorted)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/alarm/proc/ui_air_status()
|
||||
var/turf/location = get_turf(src)
|
||||
@@ -602,7 +596,7 @@
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
var/total = environment.oxygen + environment.nitrogen + environment.carbon_dioxide + environment.toxins
|
||||
if(total==0)
|
||||
if(total == 0)
|
||||
return null
|
||||
|
||||
var/datum/tlv/cur_tlv
|
||||
@@ -635,12 +629,12 @@
|
||||
cur_tlv = TLV["temperature"]
|
||||
var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature)
|
||||
|
||||
var/data[0]
|
||||
var/list/data = list()
|
||||
data["pressure"] = environment_pressure
|
||||
data["temperature"] = environment.temperature
|
||||
data["temperature_c"] = round(environment.temperature - T0C, 0.1)
|
||||
|
||||
var/percentages[0]
|
||||
var/list/percentages = list()
|
||||
percentages["oxygen"] = oxygen_percent
|
||||
percentages["nitrogen"] = nitrogen_percent
|
||||
percentages["co2"] = co2_percent
|
||||
@@ -648,7 +642,7 @@
|
||||
percentages["other"] = other_moles
|
||||
data["contents"] = percentages
|
||||
|
||||
var/danger[0]
|
||||
var/list/danger = list()
|
||||
danger["pressure"] = pressure_dangerlevel
|
||||
danger["temperature"] = temperature_dangerlevel
|
||||
danger["oxygen"] = oxygen_dangerlevel
|
||||
@@ -660,13 +654,12 @@
|
||||
data["danger"] = danger
|
||||
return data
|
||||
|
||||
/obj/machinery/alarm/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
/obj/machinery/alarm/proc/has_rcon_access(mob/user)
|
||||
return user && (isAI(user) || allowed(user) || emagged || rcon_setting == RCON_YES)
|
||||
|
||||
var/list/href_list = state.href_list(user)
|
||||
if(href_list)
|
||||
data["remote_connection"] = href_list["remote_connection"]
|
||||
data["remote_access"] = href_list["remote_access"]
|
||||
// Intentional nulls here
|
||||
/obj/machinery/alarm/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["name"] = sanitize(name)
|
||||
data["air"] = ui_air_status()
|
||||
@@ -676,70 +669,70 @@
|
||||
// Locked when:
|
||||
// Not sent from atmos console AND
|
||||
// Not silicon AND locked.
|
||||
data["locked"] = !is_authenticated(user, href_list)
|
||||
var/datum/tgui/active_ui = SStgui.get_open_ui(user, src, "main")
|
||||
data["locked"] = !is_authenticated(user, active_ui)
|
||||
data["rcon"] = rcon_setting
|
||||
data["target_temp"] = target_temperature - T0C
|
||||
data["atmos_alarm"] = alarm_area.atmosalm
|
||||
data["emagged"] = emagged
|
||||
data["modes"] = list(
|
||||
AALARM_MODE_SCRUBBING = list("name"="Filtering", "desc"="Scrubs out contaminants"),\
|
||||
AALARM_MODE_VENTING = list("name"="Draught", "desc"="Siphons out air while replacing"),\
|
||||
AALARM_MODE_PANIC = list("name"="Panic Siphon","desc"="Siphons air out of the room quickly"),\
|
||||
AALARM_MODE_REPLACEMENT = list("name"="Cycle", "desc"="Siphons air before replacing"),\
|
||||
AALARM_MODE_SIPHON = list("name"="Siphon", "desc"="Siphons air out of the room"),\
|
||||
AALARM_MODE_CONTAMINATED= list("name"="Contaminated","desc"="Scrubs out all contaminants quickly"),\
|
||||
AALARM_MODE_REFILL = list("name"="Refill", "desc"="Triples vent output"),\
|
||||
AALARM_MODE_OFF = list("name"="Off", "desc"="Shuts off vents and scrubbers"),\
|
||||
AALARM_MODE_FLOOD = list("name"="Flood", "desc"="Shuts off scrubbers and opens vents", "emagonly" = 1)
|
||||
AALARM_MODE_SCRUBBING = list("name"="Filtering", "desc"="Scrubs out contaminants", "id" = AALARM_MODE_SCRUBBING),\
|
||||
AALARM_MODE_VENTING = list("name"="Draught", "desc"="Siphons out air while replacing", "id" = AALARM_MODE_VENTING),\
|
||||
AALARM_MODE_PANIC = list("name"="Panic Siphon","desc"="Siphons air out of the room quickly", "id" = AALARM_MODE_PANIC),\
|
||||
AALARM_MODE_REPLACEMENT = list("name"="Cycle", "desc"="Siphons air before replacing", "id" = AALARM_MODE_REPLACEMENT),\
|
||||
AALARM_MODE_SIPHON = list("name"="Siphon", "desc"="Siphons air out of the room", "id" = AALARM_MODE_SIPHON),\
|
||||
AALARM_MODE_CONTAMINATED= list("name"="Contaminated","desc"="Scrubs out all contaminants quickly", "id" = AALARM_MODE_CONTAMINATED),\
|
||||
AALARM_MODE_REFILL = list("name"="Refill", "desc"="Triples vent output", "id" = AALARM_MODE_REFILL),\
|
||||
AALARM_MODE_OFF = list("name"="Off", "desc"="Shuts off vents and scrubbers", "id" = AALARM_MODE_OFF),\
|
||||
AALARM_MODE_FLOOD = list("name"="Flood", "desc"="Shuts off scrubbers and opens vents", "emagonly" = TRUE, "id" = AALARM_MODE_FLOOD)
|
||||
)
|
||||
data["mode"] = mode
|
||||
data["presets"] = list(
|
||||
AALARM_PRESET_HUMAN = list("name"="Human", "desc"="Checks for oxygen and nitrogen"),\
|
||||
AALARM_PRESET_VOX = list("name"="Vox", "desc"="Checks for nitrogen only"),\
|
||||
AALARM_PRESET_COLDROOM = list("name"="Coldroom", "desc"="For freezers"),\
|
||||
AALARM_PRESET_SERVER = list("name"="Server Room", "desc"="For server rooms")
|
||||
AALARM_PRESET_HUMAN = list("name"="Human", "desc"="Checks for oxygen and nitrogen", "id" = AALARM_PRESET_HUMAN),\
|
||||
AALARM_PRESET_VOX = list("name"="Vox", "desc"="Checks for nitrogen only", "id" = AALARM_PRESET_VOX),\
|
||||
AALARM_PRESET_COLDROOM = list("name"="Coldroom", "desc"="For freezers", "id" = AALARM_PRESET_COLDROOM),\
|
||||
AALARM_PRESET_SERVER = list("name"="Server Room", "desc"="For server rooms", "id" = AALARM_PRESET_SERVER)
|
||||
)
|
||||
data["preset"] = preset
|
||||
data["screen"] = screen
|
||||
|
||||
var/list/vents=list()
|
||||
var/list/vents = list()
|
||||
if(alarm_area.air_vent_names.len)
|
||||
for(var/id_tag in alarm_area.air_vent_names)
|
||||
var/vent_info[0]
|
||||
var/list/vent_info = list()
|
||||
var/long_name = alarm_area.air_vent_names[id_tag]
|
||||
var/list/vent_data = alarm_area.air_vent_info[id_tag]
|
||||
if(!vent_data)
|
||||
continue
|
||||
vent_info["id_tag"]=id_tag
|
||||
vent_info["name"]=sanitize(long_name)
|
||||
vent_info["id_tag"] = id_tag
|
||||
vent_info["name"] = sanitize(long_name)
|
||||
vent_info += vent_data
|
||||
vents+=list(vent_info)
|
||||
data["vents"]=vents
|
||||
vents += list(vent_info)
|
||||
data["vents"] = vents
|
||||
|
||||
var/list/scrubbers=list()
|
||||
var/list/scrubbers = list()
|
||||
if(alarm_area.air_scrub_names.len)
|
||||
for(var/id_tag in alarm_area.air_scrub_names)
|
||||
var/long_name = alarm_area.air_scrub_names[id_tag]
|
||||
var/list/scrubber_data = alarm_area.air_scrub_info[id_tag]
|
||||
if(!scrubber_data)
|
||||
continue
|
||||
scrubber_data["id_tag"]=id_tag
|
||||
scrubber_data["name"]=sanitize(long_name)
|
||||
scrubbers+=list(scrubber_data)
|
||||
data["scrubbers"]=scrubbers
|
||||
scrubber_data["id_tag"] = id_tag
|
||||
scrubber_data["name"] = sanitize(long_name)
|
||||
scrubbers += list(scrubber_data)
|
||||
data["scrubbers"] = scrubbers
|
||||
return data
|
||||
|
||||
/obj/machinery/alarm/proc/get_nano_data_console(mob/user)
|
||||
var/data[0]
|
||||
/obj/machinery/alarm/proc/get_console_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["name"] = sanitize(name)
|
||||
data["ref"] = "\ref[src]"
|
||||
data["danger"] = max(danger_level, alarm_area.atmosalm)
|
||||
var/area/Area = get_area(src)
|
||||
data["area"] = sanitize(Area.name)
|
||||
var/turf/pos = get_turf(src)
|
||||
data["x"] = pos.x
|
||||
data["y"] = pos.y
|
||||
data["z"] = pos.z
|
||||
var/area/A = get_area(src)
|
||||
data["area"] = sanitize(A.name)
|
||||
var/turf/T = get_turf(src)
|
||||
data["x"] = T.x
|
||||
data["y"] = T.y
|
||||
data["z"] = T.z
|
||||
return data
|
||||
|
||||
/obj/machinery/alarm/proc/generate_thresholds_menu()
|
||||
@@ -747,9 +740,9 @@
|
||||
var/list/thresholds = list()
|
||||
|
||||
var/list/gas_names = list(
|
||||
"oxygen" = "O<sub>2</sub>",
|
||||
"nitrogen" = "N<sub>2</sub>",
|
||||
"carbon dioxide" = "CO<sub>2</sub>",
|
||||
"oxygen" = "O2",
|
||||
"nitrogen" = "N2",
|
||||
"carbon dioxide" = "CO2",
|
||||
"plasma" = "Toxin",
|
||||
"other" = "Other")
|
||||
for(var/g in gas_names)
|
||||
@@ -776,28 +769,24 @@
|
||||
|
||||
return thresholds
|
||||
|
||||
/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/alarm/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "air_alarm.tmpl", name, 570, 410, state = state)
|
||||
ui = new(user, src, ui_key, "AirAlarm", name, 570, 410, master_ui, state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/alarm/proc/is_authenticated(var/mob/user, href_list)
|
||||
/obj/machinery/alarm/proc/is_authenticated(mob/user, datum/tgui/ui=null)
|
||||
// Return true if they are connecting with a remote console
|
||||
if(istype(ui?.master_ui?.src_object.type, /datum/tgui_module/atmos_control))
|
||||
return TRUE
|
||||
if(user.can_admin_interact())
|
||||
return 1
|
||||
else if(isAI(user) || isrobot(user) || emagged || is_auth_rcon(href_list))
|
||||
return 1
|
||||
return TRUE
|
||||
else if(isAI(user) || isrobot(user) || emagged)
|
||||
return TRUE
|
||||
else
|
||||
return !locked
|
||||
|
||||
/obj/machinery/alarm/proc/is_auth_rcon(href_list)
|
||||
if(href_list && href_list["remote_connection"] && href_list["remote_access"])
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/alarm/CanUseTopic(var/mob/user, var/datum/topic_state/state, var/href_list = list())
|
||||
/obj/machinery/alarm/tgui_status(mob/user, datum/tgui_state/state)
|
||||
if(buildstage != 2)
|
||||
return STATUS_CLOSE
|
||||
|
||||
@@ -807,146 +796,138 @@
|
||||
|
||||
. = shorted ? STATUS_DISABLED : STATUS_INTERACTIVE
|
||||
|
||||
if(. == STATUS_INTERACTIVE)
|
||||
var/extra_href = state.href_list(usr)
|
||||
// Prevent remote users from altering RCON settings or activating atmos alarms unless they already have access
|
||||
if((href_list["atmos_alarm"] || href_list["rcon"]) && extra_href["remote_connection"] && !extra_href["remote_access"])
|
||||
. = STATUS_UPDATE
|
||||
return min(..(), .)
|
||||
|
||||
/obj/machinery/alarm/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state)
|
||||
if(..(href, href_list, nowindow, state))
|
||||
return 1
|
||||
|
||||
var/state_href = state.href_list(usr)
|
||||
|
||||
if(href_list["rcon"])
|
||||
var/attempted_rcon_setting = text2num(href_list["rcon"])
|
||||
switch(attempted_rcon_setting)
|
||||
if(RCON_NO)
|
||||
rcon_setting = RCON_NO
|
||||
if(RCON_AUTO)
|
||||
rcon_setting = RCON_AUTO
|
||||
if(RCON_YES)
|
||||
rcon_setting = RCON_YES
|
||||
return 1
|
||||
// TODO: Refactor these utter pieces of garbage
|
||||
/obj/machinery/alarm/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["command"])
|
||||
if(!is_authenticated(usr, state_href))
|
||||
return
|
||||
. = TRUE
|
||||
|
||||
var/device_id = href_list["id_tag"]
|
||||
switch(href_list["command"])
|
||||
if( "power",
|
||||
"adjust_external_pressure",
|
||||
"set_external_pressure",
|
||||
"checks",
|
||||
"co2_scrub",
|
||||
"tox_scrub",
|
||||
"n2o_scrub",
|
||||
"n2_scrub",
|
||||
"o2_scrub",
|
||||
"widenet",
|
||||
"scrubbing",
|
||||
"direction")
|
||||
var/val
|
||||
if(href_list["val"])
|
||||
val=text2num(href_list["val"])
|
||||
else
|
||||
var/newval = input("Enter new value") as num|null
|
||||
if(isnull(newval))
|
||||
// Used for rcon auth
|
||||
var/datum/tgui/active_ui = SStgui.get_open_ui(usr, src, "main")
|
||||
|
||||
switch(action)
|
||||
if("set_rcon")
|
||||
var/attempted_rcon_setting = text2num(params["rcon"])
|
||||
switch(attempted_rcon_setting)
|
||||
if(RCON_NO)
|
||||
rcon_setting = RCON_NO
|
||||
if(RCON_AUTO)
|
||||
rcon_setting = RCON_AUTO
|
||||
if(RCON_YES)
|
||||
rcon_setting = RCON_YES
|
||||
|
||||
|
||||
if("command")
|
||||
if(!is_authenticated(usr, active_ui))
|
||||
return
|
||||
|
||||
var/device_id = params["id_tag"]
|
||||
switch(params["cmd"])
|
||||
if ("power",
|
||||
"adjust_external_pressure",
|
||||
"set_external_pressure",
|
||||
"checks",
|
||||
"co2_scrub",
|
||||
"tox_scrub",
|
||||
"n2o_scrub",
|
||||
"n2_scrub",
|
||||
"o2_scrub",
|
||||
"widenet",
|
||||
"scrubbing",
|
||||
"direction")
|
||||
var/val
|
||||
if(params["val"])
|
||||
val=text2num(params["val"])
|
||||
else
|
||||
var/newval = input("Enter new value") as num|null
|
||||
if(isnull(newval))
|
||||
return
|
||||
if(params["cmd"] == "set_external_pressure")
|
||||
if(newval > 1000 + ONE_ATMOSPHERE)
|
||||
newval = 1000 + ONE_ATMOSPHERE
|
||||
if(newval < 0)
|
||||
newval = 0
|
||||
val = newval
|
||||
|
||||
// For those who read this: This radio BS is what makes air alarms take 10 years to update in the UI
|
||||
send_signal(device_id, list(params["cmd"] = val))
|
||||
waiting_on_device = device_id
|
||||
|
||||
if("set_threshold")
|
||||
var/env = params["env"]
|
||||
var/varname = params["var"]
|
||||
var/datum/tlv/tlv = TLV[env]
|
||||
var/newval = input("Enter [varname] for [env]", "Alarm triggers", tlv.vars[varname]) as num|null
|
||||
|
||||
if(isnull(newval) || ..()) // No setting if you walked away
|
||||
return
|
||||
if(href_list["command"]=="set_external_pressure")
|
||||
if(newval>1000+ONE_ATMOSPHERE)
|
||||
newval = 1000+ONE_ATMOSPHERE
|
||||
if(newval<0)
|
||||
newval = 0
|
||||
val = newval
|
||||
if(newval < 0)
|
||||
tlv.vars[varname] = -1.0
|
||||
else if(env == "temperature" && newval > 5000)
|
||||
tlv.vars[varname] = 5000
|
||||
else if(env == "pressure" && newval > 50 * ONE_ATMOSPHERE)
|
||||
tlv.vars[varname] = 50 * ONE_ATMOSPHERE
|
||||
else if(env != "temperature" && env != "pressure" && newval > 200)
|
||||
tlv.vars[varname] = 200
|
||||
else
|
||||
newval = round(newval, 0.01)
|
||||
tlv.vars[varname] = newval
|
||||
|
||||
send_signal(device_id, list(href_list["command"] = val ) )
|
||||
waiting_on_device=device_id
|
||||
if("atmos_alarm")
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_DANGER, src))
|
||||
post_alert(ATMOS_ALARM_DANGER)
|
||||
alarmActivated = TRUE
|
||||
update_icon()
|
||||
|
||||
if("set_threshold")
|
||||
var/env = href_list["env"]
|
||||
var/varname = href_list["var"]
|
||||
var/datum/tlv/tlv = TLV[env]
|
||||
var/newval = input("Enter [varname] for [env]", "Alarm triggers", tlv.vars[varname]) as num|null
|
||||
if("atmos_reset")
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_NONE, src, TRUE))
|
||||
post_alert(ATMOS_ALARM_NONE)
|
||||
alarmActivated = FALSE
|
||||
update_icon()
|
||||
|
||||
if(isnull(newval) || ..(href, href_list, nowindow, state))
|
||||
return
|
||||
if(newval<0)
|
||||
tlv.vars[varname] = -1.0
|
||||
else if(env=="temperature" && newval>5000)
|
||||
tlv.vars[varname] = 5000
|
||||
else if(env=="pressure" && newval>50*ONE_ATMOSPHERE)
|
||||
tlv.vars[varname] = 50*ONE_ATMOSPHERE
|
||||
else if(env!="temperature" && env!="pressure" && newval>200)
|
||||
tlv.vars[varname] = 200
|
||||
else
|
||||
newval = round(newval,0.01)
|
||||
tlv.vars[varname] = newval
|
||||
if("mode")
|
||||
if(!is_authenticated(usr, active_ui))
|
||||
return
|
||||
|
||||
if(href_list["screen"])
|
||||
if(!is_authenticated(usr, state_href))
|
||||
return
|
||||
mode = text2num(params["mode"])
|
||||
apply_mode()
|
||||
|
||||
screen = text2num(href_list["screen"])
|
||||
return 1
|
||||
|
||||
if(href_list["atmos_alarm"])
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_DANGER, src))
|
||||
post_alert(ATMOS_ALARM_DANGER)
|
||||
alarmActivated = 1
|
||||
update_icon()
|
||||
return 1
|
||||
if("preset")
|
||||
if(!is_authenticated(usr, active_ui))
|
||||
return
|
||||
|
||||
if(href_list["atmos_reset"])
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_NONE, src, TRUE))
|
||||
post_alert(ATMOS_ALARM_NONE)
|
||||
alarmActivated = 0
|
||||
update_icon()
|
||||
return 1
|
||||
preset = text2num(params["preset"])
|
||||
apply_preset()
|
||||
|
||||
if(href_list["mode"])
|
||||
if(!is_authenticated(usr, state_href))
|
||||
return
|
||||
|
||||
mode = text2num(href_list["mode"])
|
||||
apply_mode()
|
||||
return 1
|
||||
if("temperature")
|
||||
var/datum/tlv/selected = TLV["temperature"]
|
||||
var/max_temperature = selected.max1 >= 0 ? min(selected.max1, MAX_TEMPERATURE) : max(selected.max1, MAX_TEMPERATURE)
|
||||
var/min_temperature = max(selected.min1, MIN_TEMPERATURE)
|
||||
var/max_temperature_c = max_temperature - T0C
|
||||
var/min_temperature_c = min_temperature - T0C
|
||||
var/input_temperature = input("What temperature would you like the system to maintain? (Capped between [min_temperature_c]C and [max_temperature_c]C)", "Thermostat Controls") as num|null
|
||||
if(isnull(input_temperature) || ..()) // No temp setting if you walked away
|
||||
return
|
||||
input_temperature = input_temperature + T0C
|
||||
if(input_temperature > max_temperature || input_temperature < min_temperature)
|
||||
to_chat(usr, "<span class='warning'>Temperature must be between [min_temperature_c]C and [max_temperature_c]C</span>")
|
||||
else
|
||||
target_temperature = input_temperature
|
||||
|
||||
if(href_list["preset"])
|
||||
if(!is_authenticated(usr, state_href))
|
||||
return
|
||||
|
||||
preset = text2num(href_list["preset"])
|
||||
apply_preset()
|
||||
return 1
|
||||
|
||||
if(href_list["temperature"])
|
||||
var/datum/tlv/selected = TLV["temperature"]
|
||||
var/max_temperature = selected.max1 >= 0 ? min(selected.max1, MAX_TEMPERATURE) : max(selected.max1, MAX_TEMPERATURE)
|
||||
var/min_temperature = max(selected.min1, MIN_TEMPERATURE)
|
||||
var/max_temperature_c = max_temperature - T0C
|
||||
var/min_temperature_c = min_temperature - T0C
|
||||
var/input_temperature = input("What temperature would you like the system to maintain? (Capped between [min_temperature_c]C and [max_temperature_c]C)", "Thermostat Controls") as num|null
|
||||
if(isnull(input_temperature) || ..(href, href_list, nowindow, state))
|
||||
return
|
||||
input_temperature = input_temperature + T0C
|
||||
if(input_temperature > max_temperature || input_temperature < min_temperature)
|
||||
to_chat(usr, "Temperature must be between [min_temperature_c]C and [max_temperature_c]C")
|
||||
else
|
||||
target_temperature = input_temperature
|
||||
return 1
|
||||
|
||||
/obj/machinery/alarm/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
src.emagged = 1
|
||||
emagged = TRUE
|
||||
if(user)
|
||||
user.visible_message("<span class='warning'>Sparks fly out of the [src]!</span>", "<span class='notice'>You emag the [src], disabling its safeties.</span>")
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, TRUE)
|
||||
return
|
||||
|
||||
/obj/machinery/alarm/attackby(obj/item/I, mob/user, params)
|
||||
@@ -962,7 +943,7 @@
|
||||
if(allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] the Air Alarm interface.</span>")
|
||||
updateUsrDialog()
|
||||
SStgui.update_uis(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
|
||||
@@ -1,39 +1,30 @@
|
||||
/obj/machinery/computer/atmoscontrol
|
||||
name = "\improper Central Atmospherics Computer"
|
||||
name = "\improper central atmospherics computer"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "atmos_key"
|
||||
icon_screen = "tank"
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
circuit = /obj/item/circuitboard/atmoscontrol
|
||||
req_access = list(ACCESS_ATMOSPHERICS)
|
||||
var/list/monitored_alarm_ids = null
|
||||
var/datum/nano_module/atmos_control/atmos_control
|
||||
var/datum/tgui_module/atmos_control/atmos_control
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/Initialize()
|
||||
. = ..()
|
||||
atmos_control = new(src)
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/laptop
|
||||
name = "atmospherics laptop"
|
||||
desc = "Cheap Nanotrasen laptop."
|
||||
icon_state = "medlaptop"
|
||||
density = 0
|
||||
density = FALSE
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/attack_ai(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
/obj/machinery/computer/atmoscontrol/attack_ai(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/attack_hand(mob/user)
|
||||
if(..())
|
||||
return 1
|
||||
ui_interact(user)
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
user.visible_message("<span class='warning'>\The [user] does something \the [src], causing the screen to flash!</span>",\
|
||||
"<span class='warning'>You cause the screen to flash as you gain full control.</span>",\
|
||||
"You hear an electronic warble.")
|
||||
atmos_control.emagged = 1
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/ui_interact(var/mob/user)
|
||||
if(!atmos_control)
|
||||
atmos_control = new(src, req_access, req_one_access, monitored_alarm_ids)
|
||||
atmos_control.ui_interact(user)
|
||||
/obj/machinery/computer/atmoscontrol/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
atmos_control.tgui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/mob/living/silicon
|
||||
var/register_alarms = 1
|
||||
var/datum/nano_module/alarm_monitor/all/alarm_monitor
|
||||
var/datum/nano_module/atmos_control/atmos_control
|
||||
var/register_alarms = TRUE
|
||||
var/datum/tgui_module/atmos_control/atmos_control
|
||||
var/datum/tgui_module/crew_monitor/crew_monitor
|
||||
var/datum/nano_module/law_manager/law_manager
|
||||
var/datum/tgui_module/power_monitor/digital/power_monitor
|
||||
@@ -41,7 +40,7 @@
|
||||
set category = "Subsystems"
|
||||
set name = "Atmospherics Control"
|
||||
|
||||
atmos_control.ui_interact(usr, state = GLOB.self_state)
|
||||
atmos_control.tgui_interact(usr, state = GLOB.tgui_self_state)
|
||||
|
||||
/********************
|
||||
* Crew Monitor *
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/datum/nano_module/atmos_control
|
||||
name = "Atmospherics Control"
|
||||
var/obj/access = new()
|
||||
var/emagged = 0
|
||||
var/ui_ref
|
||||
var/list/monitored_alarms = null
|
||||
|
||||
/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids)
|
||||
..()
|
||||
access.req_access = req_access
|
||||
access.req_one_access = req_one_access
|
||||
|
||||
if(monitored_alarm_ids)
|
||||
for(var/obj/machinery/alarm/alarm in GLOB.machines)
|
||||
if(alarm.alarm_id && (alarm.alarm_id in monitored_alarm_ids))
|
||||
monitored_alarms += alarm
|
||||
// machines may not yet be ordered at this point
|
||||
monitored_alarms = dd_sortedObjectList(monitored_alarms)
|
||||
|
||||
/datum/nano_module/atmos_control/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["alarm"])
|
||||
if(ui_ref)
|
||||
var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms ? monitored_alarms : GLOB.machines)
|
||||
if(alarm)
|
||||
var/datum/topic_state/air_alarm/TS = generate_state(alarm)
|
||||
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
|
||||
|
||||
/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 900, 800, state = state)
|
||||
ui.add_template("mapContent", "atmos_control_map_content.tmpl")
|
||||
ui.add_template("mapHeader", "atmos_control_map_header.tmpl")
|
||||
|
||||
// Send nanomaps
|
||||
var/datum/asset/nanomaps = get_asset_datum(/datum/asset/simple/nanomaps)
|
||||
nanomaps.send(user)
|
||||
|
||||
ui.set_show_map(1)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
ui_ref = ui
|
||||
|
||||
/datum/nano_module/atmos_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
data["alarms"] = GLOB.air_alarm_repository.air_alarm_data(monitored_alarms)
|
||||
|
||||
return data
|
||||
|
||||
/datum/nano_module/atmos_control/proc/generate_state(air_alarm)
|
||||
var/datum/topic_state/air_alarm/state = new()
|
||||
state.atmos_control = src
|
||||
state.air_alarm = air_alarm
|
||||
return state
|
||||
|
||||
/datum/topic_state/air_alarm
|
||||
var/datum/nano_module/atmos_control/atmos_control = null
|
||||
var/obj/machinery/alarm/air_alarm = null
|
||||
|
||||
/datum/topic_state/air_alarm/can_use_topic(var/src_object, var/mob/user)
|
||||
if(!isAI(user) && !in_range(atmos_control.nano_host(), user))
|
||||
return STATUS_CLOSE
|
||||
if(has_access(user))
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_UPDATE
|
||||
|
||||
/datum/topic_state/air_alarm/href_list(var/mob/user)
|
||||
var/list/extra_href = list()
|
||||
extra_href["remote_connection"] = TRUE
|
||||
extra_href["remote_access"] = has_access(user)
|
||||
|
||||
return extra_href
|
||||
|
||||
/datum/topic_state/air_alarm/proc/has_access(var/mob/user)
|
||||
return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || air_alarm.emagged || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO))
|
||||
@@ -0,0 +1,29 @@
|
||||
/datum/tgui_module/atmos_control
|
||||
name = "Atmospherics Control"
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("open_alarm")
|
||||
var/obj/machinery/alarm/alarm = locate(params["aref"]) in GLOB.air_alarms
|
||||
if(alarm)
|
||||
alarm.tgui_interact(usr, master_ui = ui, state = GLOB.tgui_always_state) // ALWAYS is intentional here, as the master_ui pass will prevent fuckery
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosControl", name, 800, 600, master_ui, state)
|
||||
|
||||
// Send nanomaps
|
||||
var/datum/asset/nanomaps = get_asset_datum(/datum/asset/simple/nanomaps)
|
||||
nanomaps.send(user)
|
||||
|
||||
ui.open()
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["alarms"] = GLOB.air_alarm_repository.air_alarm_data(GLOB.air_alarms)
|
||||
|
||||
return data
|
||||
@@ -1,254 +0,0 @@
|
||||
<!--
|
||||
Title: Air Alarm UI
|
||||
Used In File(s): /code/game/machinery/alarm.dm
|
||||
-->
|
||||
<!--
|
||||
#define AALARM_MODE_SCRUBBING 1
|
||||
#define AALARM_MODE_REPLACEMENT 2 //like scrubbing, but faster.
|
||||
#define AALARM_MODE_PANIC 3 //constantly sucks all air
|
||||
#define AALARM_MODE_CYCLE 4 //sucks off all air, then refill and switches to scrubbing
|
||||
#define AALARM_MODE_FILL 5 //emergency fill
|
||||
#define AALARM_MODE_OFF 6 //Shuts it all down.
|
||||
|
||||
#define AALARM_SCREEN_MAIN 1
|
||||
#define AALARM_SCREEN_VENT 2
|
||||
#define AALARM_SCREEN_SCRUB 3
|
||||
#define AALARM_SCREEN_MODE 4
|
||||
#define AALARM_SCREEN_SENSORS 5
|
||||
-->
|
||||
<h3>{{:data.name}}</h3>
|
||||
{{if !data.air}}
|
||||
<div class="notice">Unable to acquire air sample.</div>
|
||||
{{else}}
|
||||
<div class="statusDisplay">
|
||||
<div class="line">
|
||||
<div class="statusLabel">Pressure:</div>
|
||||
{{:helper.string("<div class='statusValue {0}'>{1} kPa</div>",helper.dangerToClass(data.air.danger.pressure),helper.smoothRound(data.air.pressure,4))}}
|
||||
<div class="statusValue" style="margin-left:5px;">
|
||||
{{if !data.locked}}
|
||||
{{if data.mode == 3}}
|
||||
{{:helper.link("DEACTIVATE PANIC SYPHON",null,{"mode" : 1},null,'linkOn')}}
|
||||
{{else}}
|
||||
{{:helper.link("ACTIVATE PANIC SYPHON",null,{"mode" : 3},null,'red')}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Oxygen:</div>
|
||||
{{:helper.displayBar(data.air.contents.oxygen, 0, 100, helper.dangerToClass(data.air.danger.oxygen))}}
|
||||
{{:helper.string("<div class='statusValue {0}'>{1}%</div>",helper.dangerToClass(data.air.danger.oxygen),helper.smoothRound(data.air.contents.oxygen))}}
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Nitrogen:</div>
|
||||
{{:helper.displayBar(data.air.contents.nitrogen, 0, 100, helper.dangerToClass(data.air.danger.nitrogen))}}
|
||||
{{:helper.string("<div class='statusValue {0}'>{1}%</div>",helper.dangerToClass(data.air.danger.nitrogen),helper.smoothRound(data.air.contents.nitrogen,0))}}
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Carbon Dioxide:</div>
|
||||
{{:helper.displayBar(data.air.contents.co2, 0, 100, helper.dangerToClass(data.air.danger.co2))}}
|
||||
{{:helper.string("<div class='statusValue {0}'>{1}%</div>",helper.dangerToClass(data.air.danger.co2),helper.smoothRound(data.air.contents.co2,0))}}
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Toxins:</div>
|
||||
{{:helper.displayBar(data.air.contents.plasma, 0, 100, helper.dangerToClass(data.air.danger.plasma))}}
|
||||
{{:helper.string("<div class='statusValue {0}'>{1}%</div>",helper.dangerToClass(data.air.danger.plasma),helper.smoothRound(data.air.contents.plasma,0))}}
|
||||
</div>
|
||||
{{if data.air.danger.other>0}}
|
||||
<div class="line">
|
||||
<div class="statusLabel">Other:</div>
|
||||
{{:helper.displayBar(data.air.contents.other, 0, 100, helper.dangerToClass(data.air.danger.other))}}
|
||||
{{:helper.string("<div class='statusValue {0}'>{1}%</div>",helper.dangerToClass(data.air.danger.other),helper.smoothRound(data.air.contents.other,0))}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="line">
|
||||
<div class="statusLabel">
|
||||
Temperature:
|
||||
</div>
|
||||
{{:helper.string("<div class='statusValue {0}'>{1}°K ({2}°C)</div>",helper.dangerToClass(data.air.danger.temperature),helper.smoothRound(data.air.temperature,2),helper.smoothRound(data.air.temperature_c,2))}}
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Local Status:</div>
|
||||
{{if data.air.danger.overall == 0}}
|
||||
{{if data.atmos_alarm}}
|
||||
<div class="average">Caution: Atmos alert in area</div>
|
||||
{{else}}
|
||||
<div class="good">Optimal</div>
|
||||
{{/if}}
|
||||
{{else data.air.danger.overall == 1}}
|
||||
<div class="average">Caution</div>
|
||||
{{else}}
|
||||
<div class="notice">DANGER: Internals Required</div>
|
||||
{{/if}}
|
||||
{{if !data.locked}}
|
||||
{{if data.alarmActivated}}
|
||||
{{:helper.link('Reset Alarm',null,{'atmos_reset':1},null,'linkOn')}}
|
||||
{{else}}
|
||||
{{:helper.link('Activate Alarm',null,{'atmos_alarm':1},null)}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="line">
|
||||
<!--
|
||||
#define RCON_NO 1
|
||||
#define RCON_AUTO 2
|
||||
#define RCON_YES 3
|
||||
-->
|
||||
<div class="statusLabel">Remote Control:</div>
|
||||
{{:helper.link('Off', null, {'rcon' : 1}, data.remote_connection && !data.remote_access ? (data.rcon == 1 ? '' : 'disabled') : null, data.rcon == 1 ? 'selected' : null)}}
|
||||
{{:helper.link('Auto', null, {'rcon' : 2}, data.remote_connection && !data.remote_access ? (data.rcon == 2 ? '' : 'disabled') : null, data.rcon == 2 ? 'selected' : null)}}
|
||||
{{:helper.link('On', null, {'rcon' : 3}, data.remote_connection && !data.remote_access ? (data.rcon == 3 ? '' : 'disabled') : null, data.rcon == 3 ? 'selected' : null)}}
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Thermostat:</div>
|
||||
{{:helper.link(data.target_temp+" C", 'thermometer', {'temperature': 1})}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if data.locked}}
|
||||
<div class="notice">Swipe card to unlock.</div>
|
||||
{{else}}
|
||||
<div class="notice">Remember to lock with ID card after use.</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">Screen:</div>
|
||||
<div class="itemContents">
|
||||
{{:helper.link('Main', 'gear',{'screen':1},(data.screen==1)?'linkOn':'')}}
|
||||
{{:helper.link('Vents', 'gear',{'screen':2},(data.screen==2)?'linkOn':'')}}
|
||||
{{:helper.link('Scrubbers', 'gear',{'screen':3},(data.screen==3)?'linkOn':'')}}
|
||||
{{:helper.link('Mode', 'gear',{'screen':4},(data.screen==4)?'linkOn':'')}}
|
||||
{{:helper.link('Thresholds','gear',{'screen':5},(data.screen==5)?'linkOn':'')}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- VENTS -->
|
||||
{{if data.screen == 2}}
|
||||
<h3>Vent Pump Settings</h3>
|
||||
{{for data.vents}}
|
||||
<div class="statusDisplay">
|
||||
<div class="line">
|
||||
<b>{{>value.name}}:</b>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Operating:</div>
|
||||
<div class="statusValue">
|
||||
{{:helper.link(value.power ? 'On':'Off','power-off',{'id_tag':value.id_tag,'command':'power','val':value.power?0:1},null)}}
|
||||
{{if value.direction=="siphon"}}
|
||||
{{:helper.link('Siphoning','arrow-circle-down',{'id_tag':value.id_tag,'command':'direction','val':'1'})}}
|
||||
{{else}}
|
||||
{{:helper.link('Blowing','arrow-up',{'id_tag':value.id_tag,'command':'direction','val':'0'})}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Pressure checks:</div>
|
||||
<div class="statusValue">
|
||||
{{:helper.link('External', 'power-off',{'id_tag':value.id_tag,'command':'checks','val':1},null,(value.checks == 1 ?'linkOn':''))}}
|
||||
{{:helper.link('Internal', 'power-off',{'id_tag':value.id_tag,'command':'checks','val':2},null,(value.checks == 2 ?'linkOn':''))}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">External pressure target:</div>
|
||||
<div class="statusValue">
|
||||
{{:helper.smoothRound(value.external,4)}} kPa
|
||||
</div>
|
||||
{{:helper.link('Set','gear',{'id_tag':value.id_tag,'command':'set_external_pressure'})}}
|
||||
{{:helper.link('Reset','refresh',{'id_tag':value.id_tag,'command':'set_external_pressure','val':101.325},null,'linkOn')}}
|
||||
</div>
|
||||
</div>
|
||||
{{empty}}
|
||||
<i>No vent pumps located in this area.</i>
|
||||
{{/for}}
|
||||
<!-- SCRUBBERS -->
|
||||
{{else data.screen == 3}}
|
||||
<h3>Scrubbers</h3>
|
||||
{{for data.scrubbers}}
|
||||
<div class="statusDisplay">
|
||||
<div class="line">
|
||||
<b>{{>value.name}}:</b>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Operating:</div>
|
||||
<div class="statusValue">
|
||||
{{:helper.link(value.power ? 'On':'Off','power-off',{'id_tag':value.id_tag,'command':'power','val':value.power?0:1},null)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Type:</div>
|
||||
<div class="statusValue">
|
||||
{{if value.scrubbing==0}}
|
||||
{{:helper.link('Siphoning','arrow-circle-down',{'id_tag':value.id_tag,'command':'scrubbing','val':1},null,'red')}}
|
||||
{{else}}
|
||||
{{:helper.link('Scrubbing','exchange',{'id_tag':value.id_tag,'command':'scrubbing','val':0},null,'linkOn')}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Scrub Range:</div>
|
||||
<div class="statusValue">
|
||||
{{:helper.link(value.widenet ? 'Extended' : 'Normal', null, { 'id_tag' : value.id_tag, 'command' : 'widenet', 'val' : value.widenet ? 0 : 1}, null, value.widenet ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
{{if value.scrubbing==1}}
|
||||
<div class="line">
|
||||
<div class="statusLabel">Filtering:</div>
|
||||
<div class="statusValue">
|
||||
{{:helper.link('CO<sub>2</sub>',null,{'id_tag':value.id_tag,'command':'co2_scrub','val':(value.filter_co2==0?1:0)},null,(value.filter_co2?'linkOn':''))}}
|
||||
{{:helper.link('Plasma', null,{'id_tag':value.id_tag,'command':'tox_scrub','val':(value.filter_toxins==0?1:0)},null,(value.filter_toxins?'linkOn':''))}}
|
||||
{{:helper.link('N<sub>2</sub>O',null,{'id_tag':value.id_tag,'command':'n2o_scrub','val':(value.filter_n2o==0?1:0)},null,(value.filter_n2o?'linkOn':''))}}
|
||||
{{:helper.link('O<sub>2</sub>', null,{'id_tag':value.id_tag,'command':'o2_scrub', 'val':(value.filter_o2 ==0?1:0)},null,(value.filter_o2 ?'linkOn':''))}}
|
||||
{{:helper.link('N<sub>2</sub>', null,{'id_tag':value.id_tag,'command':'n2_scrub', 'val':(value.filter_n2 ==0?1:0)},null,(value.filter_n2 ?'linkOn':''))}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{empty}}
|
||||
<i>No scrubbers located in this area.</i>
|
||||
{{/for}}
|
||||
<!-- MODES -->
|
||||
{{else data.screen == 4}}
|
||||
<h3>System Mode</h3>
|
||||
<div class="statusDisplay">
|
||||
{{for data.modes}}
|
||||
{{if !value.emagonly || value.emagonly && data.emagged}}
|
||||
<div class="line">
|
||||
<div class="statusLabel">{{:helper.link(value.name,'gear',{'mode':index+1},null,(index+1==data.mode?'linkOn':value.emagonly ? 'redButton' : ''))}}</div>
|
||||
<div class="statusValue">
|
||||
{{:value.desc}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
</div>
|
||||
<h3>System Preset</h3>
|
||||
<div class="notice">After making a selection, the system will automatically cycle in order to remove contaminants.</div>
|
||||
<div class="statusDisplay">
|
||||
{{for data.presets}}
|
||||
<div class="line">
|
||||
<div class="statusLabel">{{:helper.link(value.name,'gear',{'preset':index+1},null,(index+1==data.preset?'linkOn':''))}}</div>
|
||||
<div class="statusValue">
|
||||
{{:value.desc}}
|
||||
</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<!-- SENSORS -->
|
||||
{{else data.screen == 5}}
|
||||
<h3>Alarm Threshold</h3>
|
||||
Partial pressure for gases.
|
||||
<table class='fixed'>
|
||||
<tr>
|
||||
<td></td><td><span class='bad'>min2</span></td><td><span class='average'>min1</span></td><td><span class='average'>max1</span></td><td><span class='bad'>max2</span></td>
|
||||
</tr>
|
||||
{{for data.thresholds}}
|
||||
<tr>
|
||||
<td>{{:value.name}}</td>
|
||||
{{for value.settings :selectedItem:SelectedNull}}
|
||||
<td>
|
||||
{{:helper.link(selectedItem.selected >= 0 ? helper.round(selectedItem.selected*100)/100 : "Off", null, { 'command' : 'set_threshold', 'env' : selectedItem.env, 'var' : selectedItem.val })}}
|
||||
</td>
|
||||
{{/for}}
|
||||
</tr>
|
||||
{{/for}}
|
||||
<table>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
@@ -1,10 +0,0 @@
|
||||
{{:helper.link('Show Tracker Map', 'thumb-tack', {'showMap' : 1})}}
|
||||
<h3>Atmospherics Control</h3>
|
||||
<div class='item'>
|
||||
{{for data.alarms}}
|
||||
<div class="line">
|
||||
{{:helper.string("<div class='statusValue {0}'>{1}</div>", helper.dangerToClass(value.danger), value.name)}}
|
||||
{{:helper.link("Access", "gear", {"alarm" : value.ref}, null, "floatRight")}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
@@ -1,9 +0,0 @@
|
||||
{{for data.alarms}}
|
||||
{{if value.z == 1}}
|
||||
<div class="linkActive mapIcon mapIcon16 icon-airalarm {{:helper.dangerToClass(value.danger)}}" style="left: {{:(value.x)}}px; bottom: {{:(value.y - 1)}}px;" unselectable="on" data-href="{{:NanoUtility.generateHref({"alarm":value.ref, "showMap":0})}}">
|
||||
<div class="tooltip hidden">
|
||||
{{:value.name}} ({{:helper.dangerToSpan(value.danger)}}, {{:value.area}}: {{:value.x}}, {{:value.y}})
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
@@ -1,8 +0,0 @@
|
||||
{{:helper.link('Show Detail List', 'file-text', {'showMap' : 0})}}
|
||||
<div style="float: right; width: 240px;">
|
||||
<span style="float: left;">Zoom Level: </span>
|
||||
<div unselectable="on" class="link zoomLink" data-zoom-level="2">x1</div>
|
||||
<div unselectable="on" class="link zoomLink" data-zoom-level="4">x2</div>
|
||||
<div unselectable="on" class="link zoomLink" data-zoom-level="8">x4</div>
|
||||
<div unselectable="on" class="link zoomLink" data-zoom-level="16">x8</div>
|
||||
</div>
|
||||
+1
-1
@@ -2098,7 +2098,6 @@
|
||||
#include "code\modules\nano\interaction\physical.dm"
|
||||
#include "code\modules\nano\interaction\self.dm"
|
||||
#include "code\modules\nano\interaction\zlevel.dm"
|
||||
#include "code\modules\nano\modules\atmos_control.dm"
|
||||
#include "code\modules\nano\modules\human_appearance.dm"
|
||||
#include "code\modules\nano\modules\law_manager.dm"
|
||||
#include "code\modules\nano\modules\nano_module.dm"
|
||||
@@ -2440,6 +2439,7 @@
|
||||
#include "code\modules\tgui\states.dm"
|
||||
#include "code\modules\tgui\tgui.dm"
|
||||
#include "code\modules\tgui\modules\_base.dm"
|
||||
#include "code\modules\tgui\modules\atmos_control.dm"
|
||||
#include "code\modules\tgui\modules\crew_monitor.dm"
|
||||
#include "code\modules\tgui\modules\ert_manager.dm"
|
||||
#include "code\modules\tgui\modules\power_monitor.dm"
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
import { Fragment } from "inferno";
|
||||
import { useBackend, useLocalState } from "../backend";
|
||||
import { Button, LabeledList, Box, AnimatedNumber, Section, ProgressBar, Icon, Tabs, Table } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
import { InterfaceLockNoticeBox } from "./common/InterfaceLockNoticeBox";
|
||||
|
||||
export const AirAlarm = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
locked,
|
||||
} = data;
|
||||
// Bail straight away if there is no air
|
||||
return (
|
||||
<Window resizable>
|
||||
<Window.Content scrollable>
|
||||
<AirStatus />
|
||||
<InterfaceLockNoticeBox />
|
||||
{!locked && (
|
||||
<Fragment>
|
||||
<AirAlarmTabs />
|
||||
<AirAlarmUnlockedContent />
|
||||
</Fragment>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const Danger2Colour = danger => {
|
||||
if (danger === 0) {
|
||||
return "green";
|
||||
}
|
||||
if (danger === 1) {
|
||||
return "orange";
|
||||
}
|
||||
return "red";
|
||||
};
|
||||
|
||||
const AirStatus = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
air,
|
||||
mode,
|
||||
atmos_alarm,
|
||||
locked,
|
||||
alarmActivated,
|
||||
rcon,
|
||||
} = data;
|
||||
|
||||
let areaStatus;
|
||||
if (air.danger.overall === 0) {
|
||||
if (atmos_alarm === 0) {
|
||||
areaStatus = "Optimal";
|
||||
} else {
|
||||
areaStatus = "Caution: Atmos alert in area";
|
||||
}
|
||||
} else if (air.danger.overall === 1) {
|
||||
areaStatus = "Caution";
|
||||
} else {
|
||||
areaStatus = "DANGER: Internals Required";
|
||||
}
|
||||
|
||||
return (
|
||||
<Section title="Air Status">
|
||||
{air ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Pressure">
|
||||
<Box color={Danger2Colour(air.danger.pressure)}>
|
||||
<AnimatedNumber value={air.pressure} /> kPa
|
||||
{!locked && (
|
||||
<Fragment>
|
||||
|
||||
<Button
|
||||
content={mode === 3 ? "Deactivate Panic Siphon" : "Activate Panic Siphon"}
|
||||
selected={mode === 3}
|
||||
icon="exclamation-triangle"
|
||||
onClick={
|
||||
() => act('mode', { mode: (mode === 3 ? 1 : 3) })
|
||||
} />
|
||||
</Fragment>
|
||||
)}
|
||||
</Box>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Oxygen">
|
||||
<ProgressBar
|
||||
value={air.contents.oxygen / 100}
|
||||
color={Danger2Colour(air.danger.oxygen)} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Nitrogen">
|
||||
<ProgressBar
|
||||
value={air.contents.nitrogen / 100}
|
||||
color={Danger2Colour(air.danger.nitrogen)} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Carbon Dioxide">
|
||||
<ProgressBar
|
||||
value={air.contents.co2 / 100}
|
||||
color={Danger2Colour(air.danger.co2)} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Toxins">
|
||||
<ProgressBar
|
||||
value={air.contents.plasma / 100}
|
||||
color={Danger2Colour(air.danger.plasma)} />
|
||||
</LabeledList.Item>
|
||||
{air.contents.other > 0 && (
|
||||
<LabeledList.Item label="Other">
|
||||
<ProgressBar
|
||||
value={air.contents.other / 100}
|
||||
color={Danger2Colour(air.danger.other)} />
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
<LabeledList.Item label="Temperature">
|
||||
<Box color={Danger2Colour(air.danger.temperature)}>
|
||||
<AnimatedNumber value={air.temperature} /> K / <AnimatedNumber value={air.temperature_c} /> C
|
||||
<Button
|
||||
icon="thermometer-full"
|
||||
content={air.temperature_c + " C"}
|
||||
onClick={
|
||||
() => act('temperature')
|
||||
} />
|
||||
</Box>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Local Status">
|
||||
<Box color={Danger2Colour(air.danger.overall)}>
|
||||
{areaStatus}
|
||||
{!locked && (
|
||||
<Fragment>
|
||||
|
||||
<Button
|
||||
content={alarmActivated ? "Reset Alarm" : "Activate Alarm"}
|
||||
selected={alarmActivated}
|
||||
onClick={
|
||||
() => act(alarmActivated ? 'atmos_reset' : 'atmos_alarm')
|
||||
} />
|
||||
</Fragment>
|
||||
)}
|
||||
</Box>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Remote Control Settings">
|
||||
<Button
|
||||
content="Off"
|
||||
selected={rcon === 1}
|
||||
onClick={
|
||||
() => act('set_rcon', { rcon: 1 })
|
||||
} />
|
||||
<Button
|
||||
content="Auto"
|
||||
selected={rcon === 2}
|
||||
onClick={
|
||||
() => act('set_rcon', { rcon: 2 })
|
||||
} />
|
||||
<Button
|
||||
content="On"
|
||||
selected={rcon === 3}
|
||||
onClick={
|
||||
() => act('set_rcon', { rcon: 3 })
|
||||
} />
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
) : (
|
||||
<Box>
|
||||
Unable to acquire air sample!
|
||||
</Box>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const AirAlarmTabs = (props, context) => {
|
||||
const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0);
|
||||
return (
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
key="Vents"
|
||||
selected={0 === tabIndex}
|
||||
onClick={() => setTabIndex(0)}>
|
||||
<Icon name="sign-out-alt" /> Vent Control
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="Scrubbers"
|
||||
selected={1 === tabIndex}
|
||||
onClick={() => setTabIndex(1)}>
|
||||
<Icon name="sign-in-alt" /> Scrubber Control
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="Mode"
|
||||
selected={2 === tabIndex}
|
||||
onClick={() => setTabIndex(2)}>
|
||||
<Icon name="cog" /> Mode
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="Thresholds"
|
||||
selected={3 === tabIndex}
|
||||
onClick={() => setTabIndex(3)}>
|
||||
<Icon name="tachometer-alt" /> Thresholds
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
);
|
||||
};
|
||||
|
||||
const AirAlarmUnlockedContent = (props, context) => {
|
||||
const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0);
|
||||
switch (tabIndex) {
|
||||
case 0:
|
||||
return <AirAlarmVentsView />;
|
||||
case 1:
|
||||
return <AirAlarmScrubbersView />;
|
||||
case 2:
|
||||
return <AirAlarmModesView />;
|
||||
case 3:
|
||||
return <AirAlarmThresholdsView />;
|
||||
default:
|
||||
return "WE SHOULDN'T BE HERE!";
|
||||
}
|
||||
};
|
||||
|
||||
const AirAlarmVentsView = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { vents } = data;
|
||||
return (
|
||||
vents.map(v => (
|
||||
<Section title={v.name} key={v.name}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Status">
|
||||
<Button
|
||||
content={v.power ? "On" : "Off"}
|
||||
selected={v.power}
|
||||
icon="power-off"
|
||||
onClick={
|
||||
() => act('command', { cmd: 'power', val: (v.power === 1 ? 0 : 1), id_tag: v.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content={v.direction === "release" ? "Blowing" : "Siphoning"}
|
||||
icon={v.direction === "release" ? "sign-out-alt" : "sign-in-alt"}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'direction', val: (v.direction === "release" ? 0 : 1), id_tag: v.id_tag })
|
||||
} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Pressure Checks">
|
||||
<Button
|
||||
content="Internal"
|
||||
selected={v.checks === 1}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'checks', val: 1, id_tag: v.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content="External"
|
||||
selected={v.checks === 2}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'checks', val: 2, id_tag: v.id_tag })
|
||||
} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="External Pressure Target">
|
||||
<AnimatedNumber value={v.external} /> kPa
|
||||
<Button
|
||||
content="Set"
|
||||
icon="cog"
|
||||
onClick={
|
||||
() => act('command', { cmd: 'set_external_pressure', id_tag: v.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content="Reset"
|
||||
icon="redo-alt"
|
||||
onClick={
|
||||
() => act('command', { cmd: 'set_external_pressure', val: 101.325, id_tag: v.id_tag })
|
||||
} />
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
))
|
||||
);
|
||||
};
|
||||
|
||||
const AirAlarmScrubbersView = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { scrubbers } = data;
|
||||
return (
|
||||
scrubbers.map(s => (
|
||||
<Section title={s.name} key={s.name}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Status">
|
||||
<Button
|
||||
content={s.power ? "On" : "Off"}
|
||||
selected={s.power}
|
||||
icon="power-off"
|
||||
onClick={
|
||||
() => act('command', { cmd: 'power', val: (s.power === 1 ? 0 : 1), id_tag: s.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content={s.scrubbing === 0 ? "Siphoning" : "Scrubbing"}
|
||||
icon={s.scrubbing === 0 ? "sign-in-alt" : "filter"}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'scrubbing', val: (s.scrubbing === 0 ? 1 : 0), id_tag: s.id_tag })
|
||||
} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Range">
|
||||
<Button
|
||||
content={s.widenet ? "Extended" : "Normal"}
|
||||
selected={s.widenet}
|
||||
icon="expand-arrows-alt"
|
||||
onClick={
|
||||
() => act('command', { cmd: 'widenet', val: (s.widenet === 0 ? 1 : 0), id_tag: s.id_tag })
|
||||
} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Filtering">
|
||||
<Button
|
||||
content="Cargon Dioxide"
|
||||
selected={s.filter_co2}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'co2_scrub', val: (s.filter_co2 === 0 ? 1 : 0), id_tag: s.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content="Plasma"
|
||||
selected={s.filter_toxins}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'tox_scrub', val: (s.filter_toxins === 0 ? 1 : 0), id_tag: s.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content="Nitrous Oxide"
|
||||
selected={s.filter_n2o}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'n2o_scrub', val: (s.filter_n2o === 0 ? 1 : 0), id_tag: s.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content="Oxygen"
|
||||
selected={s.filter_o2}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'o2_scrub', val: (s.filter_o2 === 0 ? 1 : 0), id_tag: s.id_tag })
|
||||
} />
|
||||
<Button
|
||||
content="Nitrogen"
|
||||
selected={s.filter_n2}
|
||||
onClick={
|
||||
() => act('command', { cmd: 'n2_scrub', val: (s.filter_n2 === 0 ? 1 : 0), id_tag: s.id_tag })
|
||||
} />
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
))
|
||||
);
|
||||
};
|
||||
|
||||
const AirAlarmModesView = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
modes,
|
||||
presets,
|
||||
emagged,
|
||||
mode,
|
||||
preset,
|
||||
} = data;
|
||||
return (
|
||||
<Fragment>
|
||||
<Section title="System Mode">
|
||||
<Table>
|
||||
{modes.map(m => (
|
||||
(!m.emagonly || m.emagonly && !!emagged) && (
|
||||
<Table.Row key={m.name}>
|
||||
<Table.Cell textAlign="right" width={1}>
|
||||
<Button content={m.name} icon="cog" selected={m.id === mode} onClick={
|
||||
() => act('mode', { mode: m.id })
|
||||
} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{m.desc}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
<Section title="System Presets">
|
||||
<Box italic>
|
||||
After making a selection, the system will automatically cycle in order to remove contaminants.
|
||||
</Box>
|
||||
<Table mt={1}>
|
||||
{presets.map(p => (
|
||||
<Table.Row key={p.name}>
|
||||
<Table.Cell textAlign="right" width={1}>
|
||||
<Button content={p.name} icon="cog" selected={p.id === preset} onClick={
|
||||
() => act('preset', { preset: p.id })
|
||||
} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{p.desc}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const AirAlarmThresholdsView = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
thresholds,
|
||||
} = data;
|
||||
return (
|
||||
<Section title="Alarm Thresholds">
|
||||
<Table>
|
||||
<Table.Row header>
|
||||
<Table.Cell width="20%">
|
||||
Value
|
||||
</Table.Cell>
|
||||
<Table.Cell color="red" width="20%">
|
||||
Danger Min
|
||||
</Table.Cell>
|
||||
<Table.Cell color="orange" width="20%">
|
||||
Warning Min
|
||||
</Table.Cell>
|
||||
<Table.Cell color="orange" width="20%">
|
||||
Warning Max
|
||||
</Table.Cell>
|
||||
<Table.Cell color="red" width="20%">
|
||||
Danger Max
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
{thresholds.map(t => (
|
||||
<Table.Row key={t.name}>
|
||||
<Table.Cell>
|
||||
{t.name}
|
||||
</Table.Cell>
|
||||
{t.settings.map(s => (
|
||||
<Table.Cell key={s.val}>
|
||||
<Button content={s.selected === -1 ? "Off" : s.selected} onClick={
|
||||
() => act('command', { cmd: 'set_threshold', env: s.env, var: s.val })
|
||||
} />
|
||||
</Table.Cell>
|
||||
))}
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,143 @@
|
||||
import { useBackend, useLocalState } from "../backend";
|
||||
import { Box, Button, Icon, NanoMap, Table, Tabs } from "../components";
|
||||
import { TableCell } from '../components/Table';
|
||||
import { Window } from "../layouts";
|
||||
|
||||
const getStatus = level => {
|
||||
if (level === 0) {
|
||||
return (
|
||||
<Box color="green">
|
||||
Good
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
if (level === 1) {
|
||||
return (
|
||||
<Box color="orange" bold>
|
||||
Warning
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
if (level === 2) {
|
||||
return (
|
||||
<Box color="red" bold>
|
||||
DANGER
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusColour = level => {
|
||||
if (level === 0) {
|
||||
return "green";
|
||||
}
|
||||
if (level === 1) {
|
||||
return "orange";
|
||||
}
|
||||
if (level === 2) {
|
||||
return "red";
|
||||
}
|
||||
};
|
||||
|
||||
export const AtmosControl = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0);
|
||||
const decideTab = index => {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return <AtmosControlDataView />;
|
||||
case 1:
|
||||
return <AtmosControlMapView />;
|
||||
default:
|
||||
return "WE SHOULDN'T BE HERE!";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Window resizable>
|
||||
<Window.Content>
|
||||
<Box fillPositionedParent>
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
key="DataView"
|
||||
selected={0 === tabIndex}
|
||||
onClick={() => setTabIndex(0)}>
|
||||
<Icon name="table" /> Data View
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="MapView"
|
||||
selected={1 === tabIndex}
|
||||
onClick={() => setTabIndex(1)}>
|
||||
<Icon name="map-marked-alt" /> Map View
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
{decideTab(tabIndex)}
|
||||
</Box>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const AtmosControlDataView = (_properties, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { alarms } = data;
|
||||
return (
|
||||
<Box>
|
||||
<Table m="0.5rem">
|
||||
<Table.Row header>
|
||||
<Table.Cell>
|
||||
Name
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Status
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Access
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
{alarms.map(a => (
|
||||
<Table.Row key={a.name}>
|
||||
<TableCell>
|
||||
{a.name}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{getStatus(a.danger)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Button
|
||||
icon="cog"
|
||||
content="Access"
|
||||
onClick={() => act('open_alarm', {
|
||||
aref: a.ref,
|
||||
})} />
|
||||
</TableCell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const AtmosControlMapView = (_properties, context) => {
|
||||
const { data } = useBackend(context);
|
||||
const [zoom, setZoom] = useLocalState(context, 'zoom', 1);
|
||||
const { alarms } = data;
|
||||
return (
|
||||
<Box height="526px" mb="0.5rem" overflow="hidden">
|
||||
<NanoMap onZoom={v => setZoom(v)}>
|
||||
{alarms.filter(a => a.z === 1).map(aa => (
|
||||
// The AA means air alarm, and nothing else
|
||||
<NanoMap.Marker
|
||||
key={aa.ref}
|
||||
x={aa.x}
|
||||
y={aa.y}
|
||||
zoom={zoom}
|
||||
icon="circle"
|
||||
tooltip={aa.name}
|
||||
color={getStatusColour(aa.danger)}
|
||||
/>
|
||||
))}
|
||||
</NanoMap>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user