TGUI Engineering: Squashed Edition (Commits Below)

TGUI APCs

 TGUI vending machines

 Fix AI default_tgui_interaction

 TGUI Airlocks

 Station & Atmospheric Alert TGUI + Misc NTOS-TGUI Fixes

 TGUI Air Alarms & Central Atmospheric Control

 Airlock TGUI

 TG... got rid of UI for fire alarm. í´·

 TGUI Gas Heating/Cooling System

 TGUI Gas Pump & Passive Gate + Fixes

 TGUI Omni Atmospherics

 TGUI Pipe Dispensers & RPD

 TGUI IntelliCore & Vending Fix

 TGUI Handheld Tanks

 TGUI Portable Pump & Scrubber

 TGUI Tank Dispenser & Canisters

 TGUI Radios

 TGUI SMES & Air Alarm adjustment

 Tweak vending machine interfaces a tad

 TGUI Algae Farm

 TGUI general_air_control

 - Distro & Waste Console
 - Riot Control Console
 - Atmos Intake Console
 - Engine Cooling Console

 TGUI Heavy Scrubber Control (and body scanner fix)

 TGUI trinary devices & shutoff monitor

 TGUI Telecomms Log Browser

 TGUI Telecomms Machine Browser

 TGUI Spaceheater Internal Panel

 TGUI Gravity Generator

 TGUI Id Cards & Fix ID Card Images

 TGUI Id Card Redesign

 TGUI Turbolift

 TGUI Suit Cycler & Suit Storage Unit & Vending Fixes

 TGUI Power Monitor

 TGUI Signalers

 TGUI Employment Records

 TGUI Drone Console

 TGUI RIGSuits

 TGUI PA & PACMAN, and Margin Fix

 TGUI Solar Panels & Fix Power Monitor

 Adjust TGUI modules & their interaction with NTOS

 TGUI RCON

 TGUI Message Monitor

 Bump TGUI line limit to 120 (ParadiseSS13/Paradise#14002)

 TGUI Exonet & NTNet Relay

 TGUI Telecomms Multitool Menu

 TGUI Shield Capacitor & Shield Generator

 TGUI Supermatter-everything & Refactors
This commit is contained in:
ShadowLarkens
2020-08-09 04:46:31 -07:00
parent f1a95c31f8
commit 951f37d2e3
222 changed files with 13749 additions and 9249 deletions
@@ -140,7 +140,7 @@
/obj/machinery/atmospherics/binary/algae_farm/attack_hand(mob/user)
if(..())
return 1
ui_interact(user)
tgui_interact(user)
/obj/machinery/atmospherics/binary/algae_farm/RefreshParts()
..()
@@ -165,7 +165,13 @@
moles_per_tick = initial(moles_per_tick) + (manip_rating**2 - 1)
/obj/machinery/atmospherics/binary/algae_farm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state)
/obj/machinery/atmospherics/binary/algae_farm/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AlgaeFarm", name)
ui.open()
/obj/machinery/atmospherics/binary/algae_farm/tgui_data(mob/user)
var/data[0]
data["panelOpen"] = panel_open
@@ -198,41 +204,28 @@
"percent" = air2.total_moles ? round((air2.gas[output_gas] / air2.total_moles) * 100) : 0,
"moles" = round(air2.gas[output_gas], 0.01))
// 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)
if (!ui)
ui = new(user, src, ui_key, "algae_farm_vr.tmpl", "Algae Farm Control Panel", 500, 600)
ui.set_initial_data(data)
ui.set_auto_update(TRUE)
ui.open()
return data
/obj/machinery/atmospherics/binary/algae_farm/Topic(href, href_list)
/obj/machinery/atmospherics/binary/algae_farm/tgui_act(action, params)
if(..())
return 1
usr.set_machine(src)
return TRUE
add_fingerprint(usr)
// Queue management can be done even while busy
if(href_list["activate"])
update_use_power(USE_POWER_ACTIVE)
update_icon()
updateUsrDialog()
return
if(href_list["deactivate"])
update_use_power(USE_POWER_IDLE)
update_icon()
updateUsrDialog()
return
if(href_list["ejectMaterial"])
var/matName = href_list["ejectMaterial"]
if(!(matName in stored_material))
return
eject_materials(matName, 0)
updateUsrDialog()
return
switch(action)
if("toggle")
if(use_power == USE_POWER_IDLE)
update_use_power(USE_POWER_ACTIVE)
else
update_use_power(USE_POWER_IDLE)
update_icon()
. = TRUE
if("ejectMaterial")
var/matName = params["mat"]
if(!(matName in stored_material))
return
eject_materials(matName, 0)
. = TRUE
// TODO - These should be replaced with materials datum.
@@ -209,18 +209,21 @@
/obj/machinery/atmospherics/binary/passive_gate/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
add_fingerprint(usr)
if(!allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
usr.set_machine(src)
ui_interact(user)
return
tgui_interact(user)
/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/atmospherics/binary/passive_gate/tgui_interact(mob/user, datum/tgui/ui)
if(stat & (BROKEN|NOPOWER))
return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PressureRegulator", name)
ui.open()
/obj/machinery/atmospherics/binary/passive_gate/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/data[0]
@@ -235,51 +238,48 @@
"last_flow_rate" = round(last_flow_rate*10),
)
// 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)
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, "pressure_regulator.tmpl", name, 470, 370)
ui.set_initial_data(data) // when the ui is first opened this is the data it will use
ui.open() // open the new ui window
ui.set_auto_update(1) // auto update every Master Controller tick
return data
/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
if(..()) return 1
/obj/machinery/atmospherics/binary/passive_gate/tgui_act(action, params)
if(..())
return TRUE
if(href_list["toggle_valve"])
unlocked = !unlocked
switch(action)
if("toggle_valve")
. = TRUE
unlocked = !unlocked
if("regulate_mode")
. = TRUE
switch(params["mode"])
if("off") regulate_mode = REGULATE_NONE
if("input") regulate_mode = REGULATE_INPUT
if("output") regulate_mode = REGULATE_OUTPUT
if(href_list["regulate_mode"])
switch(href_list["regulate_mode"])
if ("off") regulate_mode = REGULATE_NONE
if ("input") regulate_mode = REGULATE_INPUT
if ("output") regulate_mode = REGULATE_OUTPUT
if("set_press")
. = TRUE
switch(params["press"])
if("min")
target_pressure = 0
if("max")
target_pressure = max_pressure_setting
if("set")
var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure) as num
src.target_pressure = between(0, new_pressure, max_pressure_setting)
switch(href_list["set_press"])
if ("min")
target_pressure = 0
if ("max")
target_pressure = max_pressure_setting
if ("set")
var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure) as num
src.target_pressure = between(0, new_pressure, max_pressure_setting)
if("set_flow_rate")
. = TRUE
switch(params["press"])
if("min")
set_flow_rate = 0
if("max")
set_flow_rate = air1.volume
if("set")
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate) as num
src.set_flow_rate = between(0, new_flow_rate, air1.volume)
switch(href_list["set_flow_rate"])
if ("min")
set_flow_rate = 0
if ("max")
set_flow_rate = air1.volume
if ("set")
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[air1.volume]kPa)","Flow Rate Control",src.set_flow_rate) as num
src.set_flow_rate = between(0, new_flow_rate, air1.volume)
usr.set_machine(src) //Is this even needed with NanoUI?
src.update_icon()
src.add_fingerprint(usr)
return
update_icon()
add_fingerprint(usr)
/obj/machinery/atmospherics/binary/passive_gate/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!W.is_wrench())
@@ -143,10 +143,15 @@ Thus, the two variables affect pump operation are set in New():
return 1
/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/atmospherics/binary/pump/tgui_interact(mob/user, datum/tgui/ui)
if(stat & (BROKEN|NOPOWER))
return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GasPump", name)
ui.open()
/obj/machinery/atmospherics/binary/pump/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/data[0]
@@ -159,15 +164,7 @@ Thus, the two variables affect pump operation are set in New():
"max_power_draw" = power_rating,
)
// 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)
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, "gas_pump.tmpl", name, 470, 290)
ui.set_initial_data(data) // when the ui is first opened this is the data it will use
ui.open() // open the new ui window
ui.set_auto_update(1) // auto update every Master Controller tick
return data
/obj/machinery/atmospherics/binary/pump/Initialize()
. = ..()
@@ -204,36 +201,40 @@ Thus, the two variables affect pump operation are set in New():
update_icon()
return
/obj/machinery/atmospherics/binary/pump/attack_hand(user as mob)
/obj/machinery/atmospherics/binary/pump/attack_ghost(mob/user)
tgui_interact(user)
/obj/machinery/atmospherics/binary/pump/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
add_fingerprint(usr)
if(!allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
usr.set_machine(src)
ui_interact(user)
return
tgui_interact(user)
/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
if(..()) return 1
/obj/machinery/atmospherics/binary/pump/tgui_act(action, params)
if(..())
return TRUE
if(href_list["power"])
update_use_power(!use_power)
switch(action)
if("power")
update_use_power(!use_power)
. = TRUE
if("set_press")
var/press = params["press"]
switch(press)
if("min")
target_pressure = 0
if("max")
target_pressure = max_pressure_setting
if("set")
var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = between(0, new_pressure, max_pressure_setting)
. = TRUE
switch(href_list["set_press"])
if ("min")
target_pressure = 0
if ("max")
target_pressure = max_pressure_setting
if ("set")
var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = between(0, new_pressure, max_pressure_setting)
usr.set_machine(src)
src.add_fingerprint(usr)
src.update_icon()
add_fingerprint(usr)
update_icon()
/obj/machinery/atmospherics/binary/pump/power_change()
var/old_stat = stat
@@ -87,23 +87,14 @@
return 1
/obj/machinery/atmospherics/omni/atmos_filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = new()
data = build_uidata()
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330)
ui.set_initial_data(data)
/obj/machinery/atmospherics/omni/atmos_filter/tgui_interact(mob/user,datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "OmniFilter", name)
ui.open()
/obj/machinery/atmospherics/omni/atmos_filter/proc/build_uidata()
var/list/data = new()
/obj/machinery/atmospherics/omni/atmos_filter/tgui_data(mob/user)
var/list/data = list()
data["power"] = use_power
data["config"] = configuring
@@ -156,34 +147,41 @@
else
return null
/obj/machinery/atmospherics/omni/atmos_filter/Topic(href, href_list)
if(..()) return 1
switch(href_list["command"])
/obj/machinery/atmospherics/omni/atmos_filter/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("power")
if(!configuring)
update_use_power(!use_power)
else
update_use_power(USE_POWER_OFF)
. = TRUE
if("configure")
configuring = !configuring
if(configuring)
update_use_power(USE_POWER_OFF)
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
if(configuring && !use_power)
switch(href_list["command"])
if("set_flow_rate")
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
set_flow_rate = between(0, new_flow_rate, max_flow_rate)
if("switch_mode")
switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"]))
if("switch_filter")
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide")
switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter))
. = TRUE
if("set_flow_rate")
if(!configuring || use_power)
return
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
set_flow_rate = between(0, new_flow_rate, max_flow_rate)
. = TRUE
if("switch_mode")
if(!configuring || use_power)
return
switch_mode(dir_flag(params["dir"]), mode_return_switch(params["mode"]))
. = TRUE
if("switch_filter")
if(!configuring || use_power)
return
var/new_filter = input(usr,"Select filter mode:","Change filter",params["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide")
switch_filter(dir_flag(params["dir"]), mode_return_switch(new_filter))
. = TRUE
update_icon()
SSnanoui.update_uis(src)
return
/obj/machinery/atmospherics/omni/atmos_filter/proc/mode_return_switch(var/mode)
switch(mode)
@@ -124,22 +124,13 @@
return 1
/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
usr.set_machine(src)
var/list/data = new()
data = build_uidata()
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330)
ui.set_initial_data(data)
/obj/machinery/atmospherics/omni/mixer/tgui_interact(mob/user,datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "OmniMixer", name)
ui.open()
/obj/machinery/atmospherics/omni/mixer/proc/build_uidata()
/obj/machinery/atmospherics/omni/mixer/tgui_data(mob/user)
var/list/data = new()
data["power"] = use_power
@@ -172,36 +163,45 @@
return data
/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list)
if(..()) return 1
/obj/machinery/atmospherics/omni/mixer/tgui_act(action, params)
if(..())
return TRUE
switch(href_list["command"])
switch(action)
if("power")
. = TRUE
if(!configuring)
update_use_power(!use_power)
else
update_use_power(USE_POWER_OFF)
if("configure")
. = TRUE
configuring = !configuring
if(configuring)
update_use_power(USE_POWER_OFF)
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
if(configuring && !use_power)
switch(href_list["command"])
if("set_flow_rate")
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
set_flow_rate = between(0, new_flow_rate, max_flow_rate)
if("switch_mode")
switch_mode(dir_flag(href_list["dir"]), href_list["mode"])
if("switch_con")
change_concentration(dir_flag(href_list["dir"]))
if("switch_conlock")
con_lock(dir_flag(href_list["dir"]))
if("set_flow_rate")
. = TRUE
if(!configuring || use_power)
return
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
set_flow_rate = between(0, new_flow_rate, max_flow_rate)
if("switch_mode")
. = TRUE
if(!configuring || use_power)
return
switch_mode(dir_flag(params["dir"]), params["mode"])
if("switch_con")
. = TRUE
if(!configuring || use_power)
return
change_concentration(dir_flag(params["dir"]))
if("switch_conlock")
. = TRUE
if(!configuring || use_power)
return
con_lock(dir_flag(params["dir"]))
update_icon()
SSnanoui.update_uis(src)
return
/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE)
if(mode != ATM_INPUT && mode != ATM_OUTPUT)
@@ -110,7 +110,7 @@
return
src.add_fingerprint(usr)
ui_interact(user)
tgui_interact(user)
return
/obj/machinery/atmospherics/omni/proc/build_icons()
@@ -111,7 +111,7 @@
if(frequency)
set_frequency(frequency)
/obj/machinery/atmospherics/trinary/atmos_filter/attack_hand(user as mob) // -- TLE
/obj/machinery/atmospherics/trinary/atmos_filter/attack_hand(user) // -- TLE
if(..())
return
@@ -119,81 +119,106 @@
to_chat(user, "<span class='warning'>Access denied.</span>")
return
var/dat
var/current_filter_type
switch(filter_type)
if(0)
current_filter_type = "Phoron"
if(1)
current_filter_type = "Oxygen"
if(2)
current_filter_type = "Nitrogen"
if(3)
current_filter_type = "Carbon Dioxide"
if(4)
current_filter_type = "Nitrous Oxide"
if(-1)
current_filter_type = "Nothing"
else
current_filter_type = "ERROR - Report this bug to the admin, please!"
tgui_interact(user)
dat += {"
<b>Power: </b><a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
<b>Filtering: </b>[current_filter_type]<br><HR>
<h4>Set Filter Type:</h4>
<A href='?src=\ref[src];filterset=0'>Phoron</A><BR>
<A href='?src=\ref[src];filterset=1'>Oxygen</A><BR>
<A href='?src=\ref[src];filterset=2'>Nitrogen</A><BR>
<A href='?src=\ref[src];filterset=3'>Carbon Dioxide</A><BR>
<A href='?src=\ref[src];filterset=4'>Nitrous Oxide</A><BR>
<A href='?src=\ref[src];filterset=-1'>Nothing</A><BR>
<HR>
<B>Set Flow Rate Limit:</B>
[src.set_flow_rate]L/s | <a href='?src=\ref[src];set_flow_rate=1'>Change</a><BR>
<B>Flow rate: </B>[round(last_flow_rate, 0.1)]L/s
"}
// var/dat
// var/current_filter_type
// switch(filter_type)
// if(0)
// current_filter_type = "Phoron"
// if(1)
// current_filter_type = "Oxygen"
// if(2)
// current_filter_type = "Nitrogen"
// if(3)
// current_filter_type = "Carbon Dioxide"
// if(4)
// current_filter_type = "Nitrous Oxide"
// if(-1)
// current_filter_type = "Nothing"
// else
// current_filter_type = "ERROR - Report this bug to the admin, please!"
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmos_filter")
onclose(user, "atmos_filter")
return
// dat += {"
// <b>Power: </b><a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
// <b>Filtering: </b>[current_filter_type]<br><HR>
// <h4>Set Filter Type:</h4>
// <A href='?src=\ref[src];filterset=0'>Phoron</A><BR>
// <A href='?src=\ref[src];filterset=1'>Oxygen</A><BR>
// <A href='?src=\ref[src];filterset=2'>Nitrogen</A><BR>
// <A href='?src=\ref[src];filterset=3'>Carbon Dioxide</A><BR>
// <A href='?src=\ref[src];filterset=4'>Nitrous Oxide</A><BR>
// <A href='?src=\ref[src];filterset=-1'>Nothing</A><BR>
// <HR>
// <B>Set Flow Rate Limit:</B>
// [src.set_flow_rate]L/s | <a href='?src=\ref[src];set_flow_rate=1'>Change</a><BR>
// <B>Flow rate: </B>[round(last_flow_rate, 0.1)]L/s
// "}
/obj/machinery/atmospherics/trinary/atmos_filter/Topic(href, href_list) // -- TLE
// user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmos_filter")
// onclose(user, "atmos_filter")
/obj/machinery/atmospherics/trinary/atmos_filter/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AtmosFilter", name)
ui.open()
/obj/machinery/atmospherics/trinary/atmos_filter/tgui_data(mob/user)
var/list/data = list()
data["on"] = use_power
data["rate"] = set_flow_rate
data["max_rate"] = air1.volume
data["filter_types"] = list()
data["filter_types"] += list(list("name" = "Nothing", "f_type" = -1, "selected" = filter_type == -1))
data["filter_types"] += list(list("name" = "Phoron", "f_type" = 0, "selected" = filter_type == 0))
data["filter_types"] += list(list("name" = "Oxygen", "f_type" = 1, "selected" = filter_type == 1))
data["filter_types"] += list(list("name" = "Nitrogen", "f_type" = 2, "selected" = filter_type == 2))
data["filter_types"] += list(list("name" = "Carbon Dioxide", "f_type" = 3, "selected" = filter_type == 3))
data["filter_types"] += list(list("name" = "Nitrous Oxide", "f_type" = 4, "selected" = filter_type == 4))
return data
/obj/machinery/atmospherics/trinary/atmos_filter/tgui_act(action, params)
if(..())
return 1
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["filterset"])
filter_type = text2num(href_list["filterset"])
return TRUE
filtered_out.Cut() //no need to create new lists unnecessarily
switch(filter_type)
if(0) //removing hydrocarbons
filtered_out += "phoron"
filtered_out += "oxygen_agent_b"
if(1) //removing O2
filtered_out += "oxygen"
if(2) //removing N2
filtered_out += "nitrogen"
if(3) //removing CO2
filtered_out += "carbon_dioxide"
if(4)//removing N2O
filtered_out += "sleeping_agent"
switch(action)
if("power")
update_use_power(!use_power)
if("rate")
var/rate = params["rate"]
if(rate == "max")
rate = air1.volume
. = TRUE
else if(text2num(rate) != null)
rate = text2num(rate)
. = TRUE
if(.)
set_flow_rate = clamp(rate, 0, air1.volume)
if("filter")
. = TRUE
filter_type = text2num(params["filterset"])
filtered_out.Cut() //no need to create new lists unnecessarily
switch(filter_type)
if(0) //removing hydrocarbons
filtered_out += "phoron"
filtered_out += "oxygen_agent_b"
if(1) //removing O2
filtered_out += "oxygen"
if(2) //removing N2
filtered_out += "nitrogen"
if(3) //removing CO2
filtered_out += "carbon_dioxide"
if(4)//removing N2O
filtered_out += "sleeping_agent"
if (href_list["temp"])
src.temp = null
if(href_list["set_flow_rate"])
var/new_flow_rate = input(usr,"Enter new flow rate (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate) as num
src.set_flow_rate = max(0, min(air1.volume, new_flow_rate))
if(href_list["power"])
update_use_power(!use_power)
src.update_icon()
src.updateUsrDialog()
/*
for(var/mob/M in viewers(1, src))
if ((M.client && M.machine == src))
src.attack_hand(M)
*/
return
add_fingerprint(usr)
update_icon()
//
// Mirrored Orientation - Flips the output dir to opposite side from normal.
@@ -77,59 +77,88 @@
return 1
/obj/machinery/atmospherics/trinary/mixer/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AtmosMixer", name)
ui.open()
/obj/machinery/atmospherics/trinary/mixer/tgui_data(mob/user)
var/list/data = list()
data["on"] = use_power
data["set_pressure"] = round(set_flow_rate)
data["max_pressure"] = min(air1.volume, air2.volume)
data["node1_concentration"] = round(mixing_inputs[air1]*100, 1)
data["node2_concentration"] = round(mixing_inputs[air2]*100, 1)
var/list/node_connects = get_node_connect_dirs()
data["node1_dir"] = dir_name(node_connects[1],TRUE)
data["node2_dir"] = dir_name(node_connects[2],TRUE)
return data
/obj/machinery/atmospherics/trinary/mixer/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
usr.set_machine(src)
var/list/node_connects = get_node_connect_dirs()
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
<b>Set Flow Rate Limit: </b>
[set_flow_rate]L/s | <a href='?src=\ref[src];set_press=1'>Change</a>
<br>
<b>Flow Rate: </b>[round(last_flow_rate, 0.1)]L/s
<br><hr>
<b>Node 1 ([dir_name(node_connects[1],TRUE)]) Concentration:</b>
<a href='?src=\ref[src];node1_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node1_c=-0.01'>-</a>
[mixing_inputs[air1]]([mixing_inputs[air1]*100]%)
<a href='?src=\ref[src];node1_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node1_c=0.1'>+</a>
<br>
<b>Node 2 ([dir_name(node_connects[2],TRUE)]) Concentration:</b>
<a href='?src=\ref[src];node2_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node2_c=-0.01'>-</a>
[mixing_inputs[air2]]([mixing_inputs[air2]*100]%)
<a href='?src=\ref[src];node2_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node2_c=0.1'>+</a>
"}
tgui_interact(user)
// src.add_fingerprint(usr)
// if(!src.allowed(user))
// to_chat(user, "<span class='warning'>Access denied.</span>")
// return
// usr.set_machine(src)
// var/list/node_connects = get_node_connect_dirs()
// var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
// <b>Set Flow Rate Limit: </b>
// [set_flow_rate]L/s | <a href='?src=\ref[src];set_press=1'>Change</a>
// <br>
// <b>Flow Rate: </b>[round(last_flow_rate, 0.1)]L/s
// <br><hr>
// <b>Node 1 ([dir_name(node_connects[1],TRUE)]) Concentration:</b>
// <a href='?src=\ref[src];node1_c=-0.1'><b>-</b></a>
// <a href='?src=\ref[src];node1_c=-0.01'>-</a>
// [mixing_inputs[air1]]([mixing_inputs[air1]*100]%)
// <a href='?src=\ref[src];node1_c=0.01'><b>+</b></a>
// <a href='?src=\ref[src];node1_c=0.1'>+</a>
// <br>
// <b>Node 2 ([dir_name(node_connects[2],TRUE)]) Concentration:</b>
// <a href='?src=\ref[src];node2_c=-0.1'><b>-</b></a>
// <a href='?src=\ref[src];node2_c=-0.01'>-</a>
// [mixing_inputs[air2]]([mixing_inputs[air2]*100]%)
// <a href='?src=\ref[src];node2_c=0.01'><b>+</b></a>
// <a href='?src=\ref[src];node2_c=0.1'>+</a>
// "}
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_mixer")
onclose(user, "atmo_mixer")
return
// user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_mixer")
// onclose(user, "atmo_mixer")
// return
/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
if(..()) return 1
if(href_list["power"])
update_use_power(!use_power)
if(href_list["set_press"])
var/max_flow_rate = min(air1.volume, air2.volume)
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",src.set_flow_rate) as num
src.set_flow_rate = max(0, min(max_flow_rate, new_flow_rate))
if(href_list["node1_c"])
var/value = text2num(href_list["node1_c"])
src.mixing_inputs[air1] = max(0, min(1, src.mixing_inputs[air1] + value))
src.mixing_inputs[air2] = 1.0 - mixing_inputs[air1]
if(href_list["node2_c"])
var/value = text2num(href_list["node2_c"])
src.mixing_inputs[air2] = max(0, min(1, src.mixing_inputs[air2] + value))
src.mixing_inputs[air1] = 1.0 - mixing_inputs[air2]
src.update_icon()
src.updateUsrDialog()
return
/obj/machinery/atmospherics/trinary/mixer/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("power")
update_use_power(!use_power)
. = TRUE
if("pressure")
var/pressure = params["pressure"]
if(pressure == "max")
pressure = min(air1.volume, air2.volume)
. = TRUE
else if(text2num(pressure) != null)
pressure = text2num(pressure)
. = TRUE
if(.)
set_flow_rate = clamp(pressure, 0, min(air1.volume, air2.volume))
if("node1")
var/value = text2num(params["concentration"])
mixing_inputs[air1] = max(0, min(1, value / 100))
mixing_inputs[air2] = 1.0 - mixing_inputs[air1]
. = TRUE
if("node2")
var/value = text2num(params["concentration"])
mixing_inputs[air2] = max(0, min(1, value / 100))
mixing_inputs[air1] = 1.0 - mixing_inputs[air2]
. = TRUE
update_icon()
//
// "T" Orientation - Inputs are on oposite sides instead of adjacent
+27 -29
View File
@@ -53,12 +53,18 @@
return
/obj/machinery/atmospherics/unary/freezer/attack_ai(mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/atmospherics/unary/freezer/attack_hand(mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/atmospherics/unary/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/atmospherics/unary/freezer/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GasTemperatureSystem", name)
ui.open()
/obj/machinery/atmospherics/unary/freezer/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/data[0]
data["on"] = use_power ? 1 : 0
@@ -76,34 +82,26 @@
temp_class = "average"
data["gasTemperatureClass"] = temp_class
// 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)
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, "freezer.tmpl", "Gas Cooling System", 440, 300)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
return data
/obj/machinery/atmospherics/unary/freezer/Topic(href, href_list)
/obj/machinery/atmospherics/unary/freezer/tgui_act(action, params)
if(..())
return 1
if(href_list["toggleStatus"])
update_use_power(!use_power)
update_icon()
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
if(amount > 0)
set_temperature = min(set_temperature + amount, 1000)
else
set_temperature = max(set_temperature + amount, 0)
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
set_power_level(new_setting)
return TRUE
. = TRUE
switch(action)
if("toggleStatus")
update_use_power(!use_power)
update_icon()
if("setGasTemperature")
var/amount = text2num(params["temp"])
if(amount > 0)
set_temperature = min(amount, 1000)
else
set_temperature = max(amount, 0)
if("setPower") //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(params["value"]), 100)
set_power_level(new_setting)
add_fingerprint(usr)
@@ -75,12 +75,18 @@
update_icon()
/obj/machinery/atmospherics/unary/heater/attack_ai(mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/atmospherics/unary/heater/attack_hand(mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/atmospherics/unary/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/atmospherics/unary/heater/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GasTemperatureSystem", name)
ui.open()
/obj/machinery/atmospherics/unary/heater/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/data[0]
data["on"] = use_power ? 1 : 0
@@ -91,39 +97,31 @@
data["targetGasTemperature"] = round(set_temperature)
data["powerSetting"] = power_setting
var/temp_class = "normal"
var/temp_class = "average"
if(air_contents.temperature > (T20C+40))
temp_class = "bad"
data["gasTemperatureClass"] = temp_class
// 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)
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, "freezer.tmpl", "Gas Heating System", 440, 300)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
return data
/obj/machinery/atmospherics/unary/heater/Topic(href, href_list)
/obj/machinery/atmospherics/unary/heater/tgui_act(action, params)
if(..())
return 1
if(href_list["toggleStatus"])
update_use_power(!use_power)
update_icon()
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
if(amount > 0)
set_temperature = min(set_temperature + amount, max_temperature)
else
set_temperature = max(set_temperature + amount, 0)
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
set_power_level(new_setting)
return TRUE
. = TRUE
switch(action)
if("toggleStatus")
update_use_power(!use_power)
update_icon()
if("setGasTemperature")
var/amount = text2num(params["temp"])
if(amount > 0)
set_temperature = min(amount, max_temperature)
else
set_temperature = max(amount, 0)
if("setPower") //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(params["value"]), 100)
set_power_level(new_setting)
add_fingerprint(usr)
@@ -374,6 +374,12 @@
ONE_ATMOSPHERE*50
)
if("reset_external_pressure" in signal.data)
external_pressure_bound = ONE_ATMOSPHERE
if("reset_internal_pressure" in signal.data)
internal_pressure_bound = 0
if(signal.data["init"] != null)
name = signal.data["init"]
return
+1 -1
View File
@@ -58,6 +58,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_MAPPING 25
#define INIT_ORDER_DECALS 20
#define INIT_ORDER_JOB 17
#define INIT_ORDER_ALARM 16 // Must initialize before atoms.
#define INIT_ORDER_ATOMS 15
#define INIT_ORDER_MACHINES 10
#define INIT_ORDER_SHUTTLES 3
@@ -70,7 +71,6 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_HOLOMAPS -5
#define INIT_ORDER_NIGHTSHIFT -6
#define INIT_ORDER_OVERLAY -7
#define INIT_ORDER_ALARM -8
#define INIT_ORDER_OPENSPACE -10
#define INIT_ORDER_XENOARCH -20
#define INIT_ORDER_CIRCUIT -21
+1
View File
@@ -101,6 +101,7 @@ var/list/outfits_decls_by_type_
H.equip_to_slot_or_del(new path(H), slot_in_backpack)
post_equip(H)
if(W) // We set ID info last to ensure the ID photo is as correct as possible.
H.set_id_info(W)
return 1
+201 -246
View File
@@ -125,6 +125,7 @@
// breathable air according to human/Life()
TLV["oxygen"] = list(16, 19, 135, 140) // Partial pressure, kpa
TLV["nitrogen"] = list(0, 0,135,140) // Partial pressure, kpa
TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
TLV["phoron"] = list(-1.0, -1.0, 0, 0.5) // Partial pressure, kpa
TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa
@@ -463,7 +464,7 @@
frequency.post_signal(src, alert_signal)
/obj/machinery/alarm/attack_ai(mob/user)
ui_interact(user)
tgui_interact(user)
/obj/machinery/alarm/attack_hand(mob/user)
. = ..()
@@ -472,157 +473,150 @@
return interact(user)
/obj/machinery/alarm/interact(mob/user)
ui_interact(user)
tgui_interact(user)
wires.Interact(user)
/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 = default_state)
var/data[0]
var/remote_connection = 0
var/remote_access = 0
if(state)
var/list/href = state.href_list(user)
remote_connection = href["remote_connection"] // Remote connection means we're non-adjacent/connecting from another computer
remote_access = href["remote_access"] // Remote access means we also have the privilege to alter the air alarm.
/obj/machinery/alarm/tgui_status(mob/user)
if(isAI(user) && aidisabled)
to_chat(user, "AI control has been disabled.")
else if(!shorted)
return ..()
return STATUS_CLOSE
data["locked"] = locked && !issilicon(user)
data["remote_connection"] = remote_connection
data["remote_access"] = remote_access
data["rcon"] = rcon_setting
data["screen"] = screen
populate_status(data)
if(!(locked && !remote_connection) || remote_access || issilicon(user))
populate_controls(data)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
/obj/machinery/alarm/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/state)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "air_alarm.tmpl", name, 325, 625, master_ui = master_ui, state = state)
ui.set_initial_data(data)
ui = new(user, src, "AirAlarm", name, parent_ui)
if(state)
ui.set_state(state)
ui.open()
ui.set_auto_update(1)
/obj/machinery/alarm/proc/populate_status(var/data)
var/turf/location = get_turf(src)
var/datum/gas_mixture/environment = location.return_air()
var/total = environment.total_moles
/obj/machinery/alarm/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = list(
"locked" = locked,
"siliconUser" = issilicon(user),
"remoteUser" = !!ui.parent_ui,
"danger_level" = danger_level,
"target_temperature" = "[target_temperature - T0C]C",
"rcon" = rcon_setting,
)
var/list/environment_data = new
data["has_environment"] = total
if(total)
var/pressure = environment.return_pressure()
environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_dangerlevel)
environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_dangerlevel)
environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = co2_dangerlevel)
environment_data[++environment_data.len] = list("name" = "Toxins", "value" = environment.gas["phoron"] / total * 100, "unit" = "%", "danger_level" = phoron_dangerlevel)
environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_dangerlevel)
data["total_danger"] = danger_level
data["environment"] = environment_data
data["atmos_alarm"] = alarm_area.atmosalm
data["fire_alarm"] = alarm_area.fire != null
data["target_temperature"] = "[target_temperature - T0C]C"
var/area/A = get_area(src)
data["atmos_alarm"] = A?.atmosalm
data["fire_alarm"] = A?.fire
/obj/machinery/alarm/proc/populate_controls(var/list/data)
switch(screen)
if(AALARM_SCREEN_MAIN)
data["mode"] = mode
if(AALARM_SCREEN_VENT)
var/vents[0]
for(var/id_tag in alarm_area.air_vent_names)
var/long_name = alarm_area.air_vent_names[id_tag]
var/list/info = alarm_area.air_vent_info[id_tag]
if(!info)
continue
vents[++vents.len] = list(
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"power" = info["power"],
"checks" = info["checks"],
"direction" = info["direction"],
"external" = info["external"]
)
data["vents"] = vents
if(AALARM_SCREEN_SCRUB)
var/scrubbers[0]
for(var/id_tag in alarm_area.air_scrub_names)
var/long_name = alarm_area.air_scrub_names[id_tag]
var/list/info = alarm_area.air_scrub_info[id_tag]
if(!info)
continue
scrubbers[++scrubbers.len] = list(
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"power" = info["power"],
"scrubbing" = info["scrubbing"],
"panic" = info["panic"],
"filters" = list()
)
scrubbers[scrubbers.len]["filters"] += list(list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"]))
scrubbers[scrubbers.len]["filters"] += list(list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"]))
scrubbers[scrubbers.len]["filters"] += list(list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"]))
scrubbers[scrubbers.len]["filters"] += list(list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"]))
scrubbers[scrubbers.len]["filters"] += list(list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"]))
scrubbers[scrubbers.len]["filters"] += list(list("name" = "Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"]))
data["scrubbers"] = scrubbers
if(AALARM_SCREEN_MODE)
var/modes[0]
modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)
modes[++modes.len] = list("name" = "Replace Air - Siphons out air while replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 0)
modes[++modes.len] = list("name" = "Panic - Siphons air out of the room", "mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1)
modes[++modes.len] = list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_CYCLE, "selected" = mode == AALARM_MODE_CYCLE, "danger" = 1)
modes[++modes.len] = list("name" = "Fill - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FILL, "selected" = mode == AALARM_MODE_FILL, "danger" = 0)
modes[++modes.len] = list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0)
data["modes"] = modes
data["mode"] = mode
if(AALARM_SCREEN_SENSORS)
var/list/selected
var/thresholds[0]
var/turf/T = get_turf(src)
var/datum/gas_mixture/environment = T.return_air()
var/list/gas_names = list(
"oxygen" = "O<sub>2</sub>",
"carbon dioxide" = "CO<sub>2</sub>",
"phoron" = "Toxin",
"other" = "Other")
for(var/g in gas_names)
thresholds[++thresholds.len] = list("name" = gas_names[g], "settings" = list())
selected = TLV[g]
for(var/i = 1, i <= 4, i++)
thresholds[thresholds.len]["settings"] += list(list("env" = g, "val" = i, "selected" = selected[i]))
data["environment_data"] = list()
var/pressure = environment.return_pressure()
data["environment_data"] += list(list(
"name" = "Pressure",
"value" = pressure,
"unit" = "kPa",
"danger_level" = get_danger_level(pressure, TLV["pressure"])
))
var/temperature = environment.temperature
data["environment_data"] += list(list(
"name" = "Temperature",
"value" = temperature,
"unit" = "K ([round(temperature - T0C, 0.1)]C)",
"danger_level" = get_danger_level(temperature, TLV["temperature"])
))
selected = TLV["pressure"]
thresholds[++thresholds.len] = list("name" = "Pressure", "settings" = list())
var/total_moles = environment.total_moles
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
for(var/gas_id in environment.gas)
if(!(gas_id in TLV))
continue
data["environment_data"] += list(list(
"name" = gas_id,
"value" = environment.gas[gas_id] / total_moles * 100,
"unit" = "%",
"danger_level" = get_danger_level(environment.gas[gas_id] * partial_pressure, TLV[gas_id])
))
if(!locked || issilicon(user) || data["remoteUser"])
data["vents"] = list()
for(var/id_tag in A.air_vent_names)
var/long_name = A.air_vent_names[id_tag]
var/list/info = A.air_vent_info[id_tag]
if(!info)
continue
data["vents"] += list(list(
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"power" = info["power"],
"checks" = info["checks"],
"excheck" = info["checks"]&1,
"incheck" = info["checks"]&2,
"direction" = info["direction"],
"external" = info["external"],
"internal" = info["internal"],
"extdefault"= (info["external"] == ONE_ATMOSPHERE),
"intdefault"= (info["internal"] == 0),
))
data["scrubbers"] = list()
for(var/id_tag in alarm_area.air_scrub_names)
var/long_name = alarm_area.air_scrub_names[id_tag]
var/list/info = alarm_area.air_scrub_info[id_tag]
if(!info)
continue
data["scrubbers"] += list(list(
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"power" = info["power"],
"scrubbing" = info["scrubbing"],
"panic" = info["panic"],
"filters" = list()
))
data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"]))
data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"]))
data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"]))
data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"]))
data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"]))
data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"]))
var/list/modes = list()
data["mode"] = mode
modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)
modes[++modes.len] = list("name" = "Replace Air - Siphons out air while replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 0)
modes[++modes.len] = list("name" = "Panic - Siphons air out of the room", "mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1)
modes[++modes.len] = list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_CYCLE, "selected" = mode == AALARM_MODE_CYCLE, "danger" = 1)
modes[++modes.len] = list("name" = "Fill - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FILL, "selected" = mode == AALARM_MODE_FILL, "danger" = 0)
modes[++modes.len] = list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0)
data["modes"] = modes
var/list/selected
var/list/thresholds = list()
var/list/gas_names = list("oxygen", "carbon dioxide", "phoron", "other")
for(var/g in gas_names)
thresholds[++thresholds.len] = list("name" = g, "settings" = list())
selected = TLV[g]
for(var/i = 1, i <= 4, i++)
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = i, "selected" = selected[i]))
thresholds[thresholds.len]["settings"] += list(list("env" = g, "val" = i, "selected" = selected[i]))
selected = TLV["temperature"]
thresholds[++thresholds.len] = list("name" = "Temperature", "settings" = list())
for(var/i = 1, i <= 4, i++)
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = i, "selected" = selected[i]))
selected = TLV["pressure"]
thresholds[++thresholds.len] = list("name" = "Pressure", "settings" = list())
for(var/i = 1, i <= 4, i++)
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = i, "selected" = selected[i]))
data["thresholds"] = thresholds
selected = TLV["temperature"]
thresholds[++thresholds.len] = list("name" = "Temperature", "settings" = list())
for(var/i = 1, i <= 4, i++)
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = i, "selected" = selected[i]))
/obj/machinery/alarm/CanUseTopic(var/mob/user, var/datum/topic_state/state, var/href_list = list())
if(aidisabled && isAI(user))
to_chat(user, "<span class='warning'>AI control for \the [src] interface has been disabled.</span>")
return STATUS_CLOSE
data["thresholds"] = thresholds
return data
. = shorted ? STATUS_DISABLED : STATUS_INTERACTIVE
/obj/machinery/alarm/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
if(. == STATUS_INTERACTIVE)
var/extra_href = state.href_list(usr)
// Prevent remote users from altering RCON settings unless they already have access
if(href_list["rcon"] && extra_href["remote_connection"] && !extra_href["remote_access"])
. = STATUS_UPDATE
return min(..(), .)
/obj/machinery/alarm/Topic(href, href_list, var/datum/topic_state/state)
if(..(href, href_list, state))
return 1
// hrefs that can always be called -walter0o
if(href_list["rcon"])
var/attempted_rcon_setting = text2num(href_list["rcon"])
if(action == "rcon")
var/attempted_rcon_setting = text2num(params["rcon"])
switch(attempted_rcon_setting)
if(RCON_NO)
@@ -631,9 +625,9 @@
rcon_setting = RCON_AUTO
if(RCON_YES)
rcon_setting = RCON_YES
return 1
return TRUE
if(href_list["temperature"])
if(action == "temperature")
var/list/selected = TLV["temperature"]
var/max_temperature = min(selected[3] - T0C, MAX_TEMPERATURE)
var/min_temperature = max(selected[2] - T0C, MIN_TEMPERATURE)
@@ -643,119 +637,80 @@
to_chat(usr, "Temperature must be between [min_temperature]C and [max_temperature]C")
else
target_temperature = input_temperature + T0C
return 1
return TRUE
// Account for remote users here.
// Yes, this is kinda snowflaky; however, I would argue it would be far more snowflakey
// to include "custom hrefs" and all the other bullshit that nano states have just for the
// like, two UIs, that want remote access to other UIs.
if((locked && !issilicon(usr) && !istype(state, /datum/tgui_state/air_alarm_remote)) || (issilicon(usr) && aidisabled))
return
// hrefs that need the AA unlocked -walter0o
var/extra_href = state.href_list(usr)
if(!(locked && !extra_href["remote_connection"]) || extra_href["remote_access"] || issilicon(usr))
if(href_list["command"])
var/device_id = href_list["id_tag"]
switch(href_list["command"])
if("set_external_pressure")
var/input_pressure = input("What pressure you like the system to mantain?", "Pressure Controls") as num|null
if(isnum(input_pressure))
send_signal(device_id, list(href_list["command"] = input_pressure))
return 1
var/device_id = params["id_tag"]
switch(action)
if("lock")
if(issilicon(usr) && !wires.is_cut(WIRE_IDSCAN))
locked = !locked
. = TRUE
if( "power",
"o2_scrub",
"n2_scrub",
"co2_scrub",
"tox_scrub",
"n2o_scrub",
"fuel_scrub",
"panic_siphon",
"scrubbing",
"direction")
send_signal(device_id, list("[action]" = text2num(params["val"])), usr)
. = TRUE
if("excheck")
send_signal(device_id, list("checks" = text2num(params["val"])^1), usr)
. = TRUE
if("incheck")
send_signal(device_id, list("checks" = text2num(params["val"])^2), usr)
. = TRUE
if("set_external_pressure", "set_internal_pressure")
var/target = params["value"]
if(!isnull(target))
send_signal(device_id, list("[action]" = target), usr)
. = TRUE
if("reset_external_pressure")
send_signal(device_id, list("reset_external_pressure"), usr)
. = TRUE
if("reset_internal_pressure")
send_signal(device_id, list("reset_internal_pressure"), usr)
. = TRUE
if("threshold")
var/env = params["env"]
if("reset_external_pressure")
send_signal(device_id, list(href_list["command"] = ONE_ATMOSPHERE))
return 1
if( "power",
"adjust_external_pressure",
"checks",
"o2_scrub",
"n2_scrub",
"co2_scrub",
"tox_scrub",
"n2o_scrub",
"fuel_scrub",
"panic_siphon",
"scrubbing",
"direction")
send_signal(device_id, list(href_list["command"] = text2num(href_list["val"])))
return 1
if("set_threshold")
var/env = href_list["env"]
var/threshold = text2num(href_list["var"])
var/list/selected = TLV[env]
var/list/thresholds = list("lower bound", "low warning", "high warning", "upper bound")
var/newval = input("Enter [thresholds[threshold]] for [env]", "Alarm triggers", selected[threshold]) as null | num
if(isnull(newval))
return 1
if(newval<0)
selected[threshold] = -1.0
else if(env=="temperature" && newval>5000)
selected[threshold] = 5000
else if(env=="pressure" && newval>50*ONE_ATMOSPHERE)
selected[threshold] = 50*ONE_ATMOSPHERE
else if(env!="temperature" && env!="pressure" && newval>200)
selected[threshold] = 200
else
newval = round(newval,0.01)
selected[threshold] = newval
if(threshold == 1)
if(selected[1] > selected[2])
selected[2] = selected[1]
if(selected[1] > selected[3])
selected[3] = selected[1]
if(selected[1] > selected[4])
selected[4] = selected[1]
if(threshold == 2)
if(selected[1] > selected[2])
selected[1] = selected[2]
if(selected[2] > selected[3])
selected[3] = selected[2]
if(selected[2] > selected[4])
selected[4] = selected[2]
if(threshold == 3)
if(selected[1] > selected[3])
selected[1] = selected[3]
if(selected[2] > selected[3])
selected[2] = selected[3]
if(selected[3] > selected[4])
selected[4] = selected[3]
if(threshold == 4)
if(selected[1] > selected[4])
selected[1] = selected[4]
if(selected[2] > selected[4])
selected[2] = selected[4]
if(selected[3] > selected[4])
selected[3] = selected[4]
apply_mode()
return 1
if(href_list["screen"])
screen = text2num(href_list["screen"])
return 1
if(href_list["atmos_unlock"])
switch(href_list["atmos_unlock"])
if("0")
alarm_area.firedoors_close()
if("1")
alarm_area.firedoors_open()
return 1
if(href_list["atmos_alarm"])
var/name = params["var"]
var/value = input("New [name] for [env]:", name, TLV[env][name]) as num|null
if(!isnull(value) && !..())
if(value < 0)
TLV[env][name] = -1
else
TLV[env][name] = round(value, 0.01)
// investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS)
. = TRUE
if("mode")
mode = text2num(params["mode"])
// investigate_log("was turned to [get_mode_name(mode)] mode by [key_name(usr)]",INVESTIGATE_ATMOS)
apply_mode(usr)
. = TRUE
if("alarm")
if(alarm_area.atmosalert(2, src))
apply_danger_level(2)
update_icon()
return 1
. = TRUE
if("reset")
atmos_reset()
. = TRUE
update_icon()
if(href_list["atmos_reset"])
if(alarm_area.atmosalert(0, src))
apply_danger_level(0)
update_icon()
return 1
if(href_list["mode"])
mode = text2num(href_list["mode"])
apply_mode()
return 1
/obj/machinery/alarm/proc/atmos_reset()
if(alarm_area.atmosalert(0, src))
apply_danger_level(0)
update_icon()
/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob)
add_fingerprint(user)
+149 -183
View File
@@ -94,7 +94,7 @@ obj/machinery/computer/general_air_control/Destroy()
if(..(user))
return
ui_interact(user)
tgui_interact(user)
/obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -104,9 +104,13 @@ obj/machinery/computer/general_air_control/Destroy()
sensor_information[id_tag] = signal.data
/obj/machinery/computer/general_air_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
/obj/machinery/computer/general_air_control/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GeneralAtmoControl", name)
ui.open()
/obj/machinery/computer/general_air_control/tgui_data(mob/user)
var/list/data = list()
var/sensors_ui[0]
if(sensors.len)
@@ -119,12 +123,7 @@ obj/machinery/computer/general_air_control/Destroy()
data["sensors"] = sensors_ui
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmo_control.tmpl", name, 525, 600)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(5)
return data
/obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
@@ -147,20 +146,9 @@ obj/machinery/computer/general_air_control/Destroy()
var/pressure_setting = ONE_ATMOSPHERE * 45
circuit = /obj/item/weapon/circuitboard/air_management/tank_control
/obj/machinery/computer/general_air_control/large_tank_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
/obj/machinery/computer/general_air_control/large_tank_control/tgui_data(mob/user)
var/list/data = ..()
var/list/data = list()
var/sensors_ui[0]
if(sensors.len)
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
var/list/sensor_data = sensor_information[id_tag]
sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data)
else
sensors_ui = null
data["sensors"] = sensors_ui
data["tanks"] = 1
if(input_info)
@@ -175,13 +163,10 @@ obj/machinery/computer/general_air_control/Destroy()
data["input_flow_setting"] = round(input_flow_setting, 0.1)
data["pressure_setting"] = pressure_setting
data["max_pressure"] = 50*ONE_ATMOSPHERE
data["max_flowrate"] = ATMOS_DEFAULT_VOLUME_PUMP + 500
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmo_control.tmpl", name, 660, 500)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(5)
return data
/obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -195,54 +180,56 @@ obj/machinery/computer/general_air_control/Destroy()
else
..(signal)
/obj/machinery/computer/general_air_control/large_tank_control/Topic(href, href_list)
/obj/machinery/computer/general_air_control/large_tank_control/tgui_act(action, params)
if(..())
return 1
return TRUE
if(href_list["adj_pressure"])
var/change = text2num(href_list["adj_pressure"])
pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE)
return 1
switch(action)
if("adj_pressure")
var/new_pressure = text2num(params["adj_pressure"])
pressure_setting = between(0, new_pressure, 50*ONE_ATMOSPHERE)
return TRUE
if(href_list["adj_input_flow_rate"])
var/change = text2num(href_list["adj_input_flow_rate"])
input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
return 1
if("adj_input_flow_rate")
var/new_flow = text2num(params["adj_input_flow_rate"])
input_flow_setting = between(0, new_flow, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
return TRUE
if(!radio_connection)
return 0
return FALSE
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
if(href_list["in_refresh_status"])
input_info = null
signal.data = list ("tag" = input_tag, "status" = 1)
. = 1
switch(action)
if("in_refresh_status")
input_info = null
signal.data = list ("tag" = input_tag, "status" = 1)
. = TRUE
if(href_list["in_toggle_injector"])
input_info = null
signal.data = list ("tag" = input_tag, "power_toggle" = 1)
. = 1
if("in_toggle_injector")
input_info = null
signal.data = list ("tag" = input_tag, "power_toggle" = 1)
. = TRUE
if(href_list["in_set_flowrate"])
input_info = null
signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]")
. = 1
if("in_set_flowrate")
input_info = null
signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]")
. = TRUE
if(href_list["out_refresh_status"])
output_info = null
signal.data = list ("tag" = output_tag, "status" = 1)
. = 1
if("out_refresh_status")
output_info = null
signal.data = list ("tag" = output_tag, "status" = 1)
. = TRUE
if(href_list["out_toggle_power"])
output_info = null
signal.data = list ("tag" = output_tag, "power_toggle" = 1)
. = 1
if("out_toggle_power")
output_info = null
signal.data = list ("tag" = output_tag, "power_toggle" = 1)
. = TRUE
if(href_list["out_set_pressure"])
output_info = null
signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]")
. = 1
if("out_set_pressure")
output_info = null
signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]")
. = TRUE
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
@@ -258,40 +245,29 @@ obj/machinery/computer/general_air_control/Destroy()
var/pressure_setting = 100
circuit = /obj/item/weapon/circuitboard/air_management/supermatter_core
/obj/machinery/computer/general_air_control/supermatter_core/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list()
var/sensors_ui[0]
if(sensors.len)
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
var/list/sensor_data = sensor_information[id_tag]
sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data)
else
sensors_ui = null
data["sensors"] = sensors_ui
/obj/machinery/computer/general_air_control/supermatter_core/tgui_data(mob/user)
var/list/data = ..()
data["core"] = 1
if(input_info)
data["input_info"] = list("power" = input_info["power"], "volume_rate" = round(input_info["volume_rate"], 0.1))
else
data["input_info"] = null
if(output_info)
data["output_info"] = list("power" = output_info["power"], "pressure_limit" = output_info["external"])
// Yes, TECHNICALLY this is not output pressure, it's a pressure LIMIT. HOWEVER. The fact that the UI uses "output_pressure"
// in EXACTLY THE SAME WAY as "pressure_limit" means this should just pass it as the other fucking data argument because holy shit what the
// fuck
data["output_info"] = list("power" = output_info["power"], "output_pressure" = output_info["external"])
else
data["output_info"] = null
data["input_flow_setting"] = round(input_flow_setting, 0.1)
data["pressure_setting"] = pressure_setting
data["max_pressure"] = 10*ONE_ATMOSPHERE
data["max_flowrate"] = ATMOS_DEFAULT_VOLUME_PUMP + 500
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmo_control.tmpl", name, 650, 500)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(5)
return data
/obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -305,54 +281,56 @@ obj/machinery/computer/general_air_control/Destroy()
else
..(signal)
/obj/machinery/computer/general_air_control/supermatter_core/Topic(href, href_list)
/obj/machinery/computer/general_air_control/supermatter_core/tgui_act(action, params)
if(..())
return 1
return TRUE
if(href_list["adj_pressure"])
var/change = text2num(href_list["adj_pressure"])
pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE)
return 1
switch(action)
if("adj_pressure")
var/new_pressure = text2num(params["adj_pressure"])
pressure_setting = between(0, new_pressure, 10*ONE_ATMOSPHERE)
return TRUE
if(href_list["adj_input_flow_rate"])
var/change = text2num(href_list["adj_input_flow_rate"])
input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
return 1
if("adj_input_flow_rate")
var/new_flow = text2num(params["adj_input_flow_rate"])
input_flow_setting = between(0, new_flow, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
return TRUE
if(!radio_connection)
return 0
return FALSE
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
if(href_list["in_refresh_status"])
input_info = null
signal.data = list ("tag" = input_tag, "status" = 1)
. = 1
switch(action)
if("in_refresh_status")
input_info = null
signal.data = list ("tag" = input_tag, "status" = 1)
. = TRUE
if(href_list["in_toggle_injector"])
input_info = null
signal.data = list ("tag" = input_tag, "power_toggle" = 1)
. = 1
if("in_toggle_injector")
input_info = null
signal.data = list ("tag" = input_tag, "power_toggle" = 1)
. = TRUE
if(href_list["in_set_flowrate"])
input_info = null
signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]")
. = 1
if("in_set_flowrate")
input_info = null
signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]")
. = TRUE
if(href_list["out_refresh_status"])
output_info = null
signal.data = list ("tag" = output_tag, "status" = 1)
. = 1
if("out_refresh_status")
output_info = null
signal.data = list ("tag" = output_tag, "status" = 1)
. = TRUE
if(href_list["out_toggle_power"])
output_info = null
signal.data = list ("tag" = output_tag, "power_toggle" = 1)
. = 1
if("out_toggle_power")
output_info = null
signal.data = list ("tag" = output_tag, "power_toggle" = 1)
. = TRUE
if(href_list["out_set_pressure"])
output_info = null
signal.data = list ("tag" = output_tag, "set_external_pressure" = "[pressure_setting]", "checks" = 1)
. = 1
if("out_set_pressure")
output_info = null
signal.data = list ("tag" = output_tag, "set_external_pressure" = "[pressure_setting]", "checks" = 1)
. = TRUE
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
@@ -370,7 +348,7 @@ obj/machinery/computer/general_air_control/Destroy()
/obj/machinery/computer/general_air_control/fuel_injection/process()
if(automation)
if(!radio_connection)
return 0
return FALSE
var/injecting = 0
for(var/id_tag in sensor_information)
@@ -396,20 +374,8 @@ obj/machinery/computer/general_air_control/Destroy()
..()
/obj/machinery/computer/general_air_control/fuel_injection/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list()
var/sensors_ui[0]
if(sensors.len)
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
var/list/sensor_data = sensor_information[id_tag]
sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data)
else
sensors_ui = null
data["sensors"] = sensors_ui
/obj/machinery/computer/general_air_control/fuel_injection/tgui_data(mob/user)
var/list/data = ..()
data["fuel"] = 1
data["automation"] = automation
@@ -418,12 +384,7 @@ obj/machinery/computer/general_air_control/Destroy()
else
data["device_info"] = null
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmo_control.tmpl", name, 650, 500)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(5)
return data
/obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -435,55 +396,60 @@ obj/machinery/computer/general_air_control/Destroy()
else
..(signal)
/obj/machinery/computer/general_air_control/fuel_injection/Topic(href, href_list)
/obj/machinery/computer/general_air_control/fuel_injection/tgui_act(action, params)
if(..())
return
return TRUE
switch(action)
if("refresh_status")
device_info = null
if(!radio_connection)
return FALSE
if(href_list["refresh_status"])
device_info = null
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"status" = 1,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
. = TRUE
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"status" = 1,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
if("toggle_automation")
automation = !automation
. = TRUE
if(href_list["toggle_automation"])
automation = !automation
if("toggle_injector")
device_info = null
if(!radio_connection)
return FALSE
if(href_list["toggle_injector"])
device_info = null
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"power_toggle" = 1,
"sigtype"="command"
)
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"power_toggle" = 1,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
. = TRUE
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
if("injection")
if(!radio_connection)
return FALSE
if(href_list["injection"])
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"inject" = 1,
"sigtype"="command"
)
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"inject" = 1,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
. = TRUE
@@ -24,94 +24,70 @@
/obj/machinery/computer/area_atmos/attack_hand(var/mob/user as mob)
if(..(user))
return
src.add_fingerprint(usr)
var/dat = {"
<html>
<head>
<style type="text/css">
a.green:link
{
color:#00CC00;
}
a.green:visited
{
color:#00CC00;
}
a.green:hover
{
color:#00CC00;
}
a.green:active
{
color:#00CC00;
}
a.red:link
{
color:#FF0000;
}
a.red:visited
{
color:#FF0000;
}
a.red:hover
{
color:#FF0000;
}
a.red:active
{
color:#FF0000;
}
</style>
</head>
<body>
<center><h1>Area Air Control</h1></center>
<font color="red">[status]</font><br>
<a href="?src=\ref[src];scan=1">Scan</a>
<table border="1" width="90%">"}
for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in connectedscrubbers)
dat += {"
<tr>
<td>
[scrubber.name]<br>
Pressure: [round(scrubber.air_contents.return_pressure(), 0.01)] kPa<br>
Flow Rate: [round(scrubber.last_flow_rate,0.1)] L/s<br>
</td>
<td width="150">
<a class="green" href="?src=\ref[src];scrub=\ref[scrubber];toggle=1">Turn On</a>
<a class="red" href="?src=\ref[src];scrub=\ref[scrubber];toggle=0">Turn Off</a><br>
Load: [round(scrubber.last_power_draw)] W
</td>
</tr>"}
tgui_interact(user)
dat += {"
</table><br>
<i>[zone]</i>
</body>
</html>"}
user << browse("[dat]", "window=miningshuttle;size=400x400")
status = ""
/obj/machinery/computer/area_atmos/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["scan"])
scanscrubbers()
else if(href_list["toggle"])
var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber = locate(href_list["scrub"])
/obj/machinery/computer/area_atmos/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AreaScrubberControl", name)
ui.open()
/obj/machinery/computer/area_atmos/tgui_data(mob/user)
var/list/data = list()
data["scrubbers"] = list()
for(var/id in connectedscrubbers)
var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber = connectedscrubbers[id]
if(!validscrubber(scrubber))
spawn(20)
status = "ERROR: Couldn't connect to scrubber! (timeout)"
connectedscrubbers -= scrubber
src.updateUsrDialog()
return
connectedscrubbers -= scrubber
continue
data["scrubbers"].Add(list(list(
"id" = id,
"name" = scrubber.name,
"on" = scrubber.on,
"pressure" = scrubber.air_contents.return_pressure(),
"flow_rate" = scrubber.last_flow_rate,
"load" = scrubber.last_power_draw,
"area" = get_area(scrubber),
)))
scrubber.on = text2num(href_list["toggle"])
scrubber.update_icon()
return data
/obj/machinery/computer/area_atmos/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("toggle")
var/scrub_id = params["id"]
var/obj/machinery/portable_atmospherics/powered/scrubber/huge/S = connectedscrubbers["[scrub_id]"]
if(!validscrubber(S))
connectedscrubbers -= S
return TRUE
S.on = !S.on
S.update_icon()
. = TRUE
if("allon")
INVOKE_ASYNC(src, .proc/toggle_all, TRUE)
. = TRUE
if("alloff")
INVOKE_ASYNC(src, .proc/toggle_all, FALSE)
. = TRUE
if("scan")
scanscrubbers()
. = TRUE
add_fingerprint(usr)
/obj/machinery/computer/area_atmos/proc/toggle_all(on)
for(var/id in connectedscrubbers)
var/obj/machinery/portable_atmospherics/powered/scrubber/huge/S = connectedscrubbers["[id]"]
if(!validscrubber(S))
connectedscrubbers -= S
continue
S.on = on
S.update_icon()
CHECK_TICK
/obj/machinery/computer/area_atmos/proc/validscrubber(obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber as obj)
if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z)
@@ -119,13 +95,12 @@
return TRUE
/obj/machinery/computer/area_atmos/proc/scanscrubbers()
connectedscrubbers = new()
connectedscrubbers = list()
var/found = 0
for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in range(range, src.loc))
if(istype(scrubber))
found = 1
connectedscrubbers += scrubber
found = 1
connectedscrubbers["[scrubber.id]"] = scrubber
if(!found)
status = "ERROR: No scrubber found!"
@@ -142,7 +117,7 @@
var/found = 0
var/area/A = get_area(src)
for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in A)
connectedscrubbers += scrubber
connectedscrubbers["[scrubber.id]"] = scrubber
found = 1
if(!found)
@@ -151,7 +126,10 @@
src.updateUsrDialog()
/obj/machinery/computer/area_atmos/area/validscrubber(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber)
if(get_area(scrubber) == get_area(src))
return 1
if(!istype(scrubber))
return FALSE
return 0
if(get_area(scrubber) == get_area(src))
return TRUE
return FALSE
@@ -17,12 +17,15 @@
for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in world)
if(scrubber.scrub_id == src.scrub_id)
connectedscrubbers += scrubber
connectedscrubbers["[scrubber.id]"] = scrubber
src.updateUsrDialog()
SStgui.update_uis(src)
/obj/machinery/computer/area_atmos/tag/validscrubber(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber)
if(!istype(scrubber))
return FALSE
if(scrubber.scrub_id == src.scrub_id)
return 1
return TRUE
return 0
return FALSE
+86 -83
View File
@@ -266,105 +266,108 @@ update_flag
return src.attack_hand(user)
/obj/machinery/portable_atmospherics/canister/attack_hand(var/mob/user as mob)
return src.ui_interact(user)
return tgui_interact(user)
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if (src.destroyed)
/obj/machinery/portable_atmospherics/canister/tgui_state(mob/user)
return GLOB.tgui_physical_state
/obj/machinery/portable_atmospherics/canister/tgui_interact(mob/user, datum/tgui/ui)
if(destroyed)
return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Canister", name)
ui.open()
// this is the data which will be sent to the ui
var/data[0]
data["name"] = name
/obj/machinery/portable_atmospherics/canister/tgui_data(mob/user)
var/list/data = list()
data["canLabel"] = can_label ? 1 : 0
data["portConnected"] = connected_port ? 1 : 0
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["connected"] = connected_port ? 1 : 0
data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["releasePressure"] = round(release_pressure ? release_pressure : 0)
data["defaultReleasePressure"] = round(initial(release_pressure))
data["minReleasePressure"] = round(ONE_ATMOSPHERE/10)
data["maxReleasePressure"] = round(10*ONE_ATMOSPHERE)
data["valveOpen"] = valve_open ? 1 : 0
data["hasHoldingTank"] = holding ? 1 : 0
if (holding)
data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure()))
if(holding)
data["holding"] = list()
data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
else
data["holding"] = null
// 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)
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, "canister.tmpl", "Canister", 480, 400)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
return data
/obj/machinery/portable_atmospherics/canister/Topic(href, href_list)
/obj/machinery/portable_atmospherics/canister/tgui_act(action, params)
if(..())
return TRUE
//Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict. // yeah but without SOME sort of Topic check any dick can mess with them via exploits as he pleases -walter0o
//First comment might be outdated.
if (!istype(src.loc, /turf))
return 0
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) // exploit protection -walter0o
usr << browse(null, "window=canister")
onclose(usr, "canister")
return
if(href_list["toggle"])
if (valve_open)
if (holding)
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the [holding]<br>"
switch(action)
if("relabel")
if(can_label)
var/list/colors = list(\
"\[N2O\]" = "redws", \
"\[N2\]" = "red", \
"\[O2\]" = "blue", \
"\[Phoron\]" = "orangeps", \
"\[CO2\]" = "black", \
"\[Air\]" = "grey", \
"\[CAUTION\]" = "yellow", \
)
var/label = input("Choose canister label", "Gas canister") as null|anything in colors
if(label)
canister_color = colors[label]
icon_state = colors[label]
name = "Canister: [label]"
if("pressure")
var/pressure = params["pressure"]
if(pressure == "reset")
pressure = initial(release_pressure)
. = TRUE
else if(pressure == "min")
pressure = ONE_ATMOSPHERE/10
. = TRUE
else if(pressure == "max")
pressure = 10*ONE_ATMOSPHERE
. = TRUE
else if(pressure == "input")
pressure = input("New release pressure ([ONE_ATMOSPHERE/10]-[10*ONE_ATMOSPHERE] kPa):", name, release_pressure) as num|null
if(!isnull(pressure) && !..())
. = TRUE
else if(text2num(pressure) != null)
pressure = text2num(pressure)
. = TRUE
if(.)
release_pressure = clamp(round(pressure), ONE_ATMOSPHERE/10, 10*ONE_ATMOSPHERE)
if("valve")
if(valve_open)
if(holding)
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the [holding]<br>"
else
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the <font color='red'><b>air</b></font><br>"
else
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the <font color='red'><b>air</b></font><br>"
else
if (holding)
release_log += "Valve was <b>opened</b> by [usr] ([usr.ckey]), starting the transfer into the [holding]<br>"
else
release_log += "Valve was <b>opened</b> by [usr] ([usr.ckey]), starting the transfer into the <font color='red'><b>air</b></font><br>"
log_open()
valve_open = !valve_open
if(holding)
release_log += "Valve was <b>opened</b> by [usr] ([usr.ckey]), starting the transfer into the [holding]<br>"
else
release_log += "Valve was <b>opened</b> by [usr] ([usr.ckey]), starting the transfer into the <font color='red'><b>air</b></font><br>"
log_open()
valve_open = !valve_open
. = TRUE
if("eject")
if(holding)
if(valve_open)
valve_open = 0
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the [holding]<br>"
if(istype(holding, /obj/item/weapon/tank))
holding.manipulated_by = usr.real_name
holding.loc = loc
holding = null
. = TRUE
if (href_list["remove_tank"])
if(holding)
if (valve_open)
valve_open = 0
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the [holding]<br>"
if(istype(holding, /obj/item/weapon/tank))
holding.manipulated_by = usr.real_name
holding.loc = loc
holding = null
if (href_list["pressure_adj"])
var/diff = text2num(href_list["pressure_adj"])
if(diff > 0)
release_pressure = min(10*ONE_ATMOSPHERE, release_pressure+diff)
else
release_pressure = max(ONE_ATMOSPHERE/10, release_pressure+diff)
if (href_list["relabel"])
if (can_label)
var/list/colors = list(\
"\[N2O\]" = "redws", \
"\[N2\]" = "red", \
"\[O2\]" = "blue", \
"\[Phoron\]" = "orangeps", \
"\[CO2\]" = "black", \
"\[Air\]" = "grey", \
"\[CAUTION\]" = "yellow", \
)
var/label = input("Choose canister label", "Gas canister") as null|anything in colors
if (label)
src.canister_color = colors[label]
src.icon_state = colors[label]
src.name = "Canister: [label]"
src.add_fingerprint(usr)
add_fingerprint(usr)
update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/phoron/New()
..()
+60 -38
View File
@@ -119,51 +119,73 @@
return src.attack_hand(user)
/obj/machinery/portable_atmospherics/powered/pump/attack_hand(var/mob/user)
ui_interact(user)
tgui_interact(user)
/obj/machinery/portable_atmospherics/powered/pump/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1)
/obj/machinery/portable_atmospherics/powered/pump/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortablePump", name)
ui.open()
/obj/machinery/portable_atmospherics/powered/pump/tgui_state(mob/user)
return GLOB.tgui_physical_state
/obj/machinery/portable_atmospherics/powered/pump/tgui_data(mob/user)
var/list/data[0]
data["portConnected"] = connected_port ? 1 : 0
data["tankPressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0)
data["targetpressure"] = round(target_pressure)
data["pump_dir"] = direction_out
data["minpressure"] = round(pressuremin)
data["maxpressure"] = round(pressuremax)
data["on"] = on ? TRUE : FALSE
data["direction"] = !direction_out ? TRUE : FALSE
data["connected"] = connected_port ? TRUE : FALSE
data["pressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0)
data["target_pressure"] = round(target_pressure ? target_pressure : 0)
data["default_pressure"] = round(initial(target_pressure))
data["min_pressure"] = round(pressuremin)
data["max_pressure"] = round(pressuremax)
data["powerDraw"] = round(last_power_draw)
data["cellCharge"] = cell ? cell.charge : 0
data["cellMaxCharge"] = cell ? cell.maxcharge : 1
data["on"] = on ? 1 : 0
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))
if(holding)
data["holding"] = list()
data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)
else
data["holding"] = null
return data
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "portpump.tmpl", "Portable Pump", 480, 410, state = physical_state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/portable_atmospherics/powered/pump/Topic(href, href_list)
/obj/machinery/portable_atmospherics/powered/pump/tgui_act(action, params)
if(..())
return 1
return TRUE
if(href_list["power"])
on = !on
. = 1
if(href_list["direction"])
direction_out = !direction_out
. = 1
if (href_list["remove_tank"])
if(holding)
holding.loc = 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))
. = 1
switch(action)
if("power")
on = !on
. = 1
if("direction")
direction_out = !direction_out
. = 1
if("eject")
if(holding)
holding.loc = loc
holding = null
. = 1
if("pressure")
var/pressure = params["pressure"]
if(pressure == "reset")
pressure = initial(target_pressure)
. = TRUE
else if(pressure == "min")
pressure = pressuremin
. = TRUE
else if(pressure == "max")
pressure = pressuremax
. = TRUE
else if(text2num(pressure) != null)
pressure = text2num(pressure)
. = TRUE
if(.)
target_pressure = clamp(round(pressure), pressuremin, pressuremax)
if(.)
update_icon()
update_icon()
+35 -31
View File
@@ -96,49 +96,53 @@
return src.attack_hand(user)
/obj/machinery/portable_atmospherics/powered/scrubber/attack_hand(var/mob/user)
ui_interact(user)
return
tgui_interact(user)
/obj/machinery/portable_atmospherics/powered/scrubber/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1)
var/list/data[0]
data["portConnected"] = connected_port ? 1 : 0
data["tankPressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0)
/obj/machinery/portable_atmospherics/powered/scrubber/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortableScrubber", name)
ui.open()
/obj/machinery/portable_atmospherics/powered/scrubber/tgui_data(mob/user)
var/list/data = list()
data["on"] = on ? 1 : 0
data["connected"] = connected_port ? 1 : 0
data["pressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0)
data["rate"] = round(volume_rate)
data["minrate"] = round(minrate)
data["maxrate"] = round(maxrate)
data["powerDraw"] = round(last_power_draw)
data["cellCharge"] = cell ? cell.charge : 0
data["cellMaxCharge"] = cell ? cell.maxcharge : 1
data["on"] = on ? 1 : 0
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))
if(holding)
data["holding"] = list()
data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)
else
data["holding"] = null
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "portscrubber.tmpl", "Portable Scrubber", 480, 400, state = physical_state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
return data
/obj/machinery/portable_atmospherics/powered/scrubber/Topic(href, href_list)
/obj/machinery/portable_atmospherics/powered/scrubber/tgui_act(action, params)
if(..())
return 1
return TRUE
switch(action)
if("power")
on = !on
. = TRUE
if("eject")
if(holding)
holding.loc = loc
holding = null
. = TRUE
if("volume_adj")
volume_rate = CLAMP(text2num(params["vol"]), minrate, maxrate)
. = TRUE
if(href_list["power"])
on = !on
. = 1
if (href_list["remove_tank"])
if(holding)
holding.loc = loc
holding = null
. = 1
if (href_list["volume_adj"])
var/diff = text2num(href_list["volume_adj"])
volume_rate = CLAMP(volume_rate+diff, minrate, maxrate)
. = 1
update_icon()
+1 -1
View File
@@ -447,7 +447,7 @@
network.Cut()
update_coverage(1)
/obj/machinery/camera/proc/nano_structure()
/obj/machinery/camera/proc/tgui_structure()
var/cam[0]
cam["name"] = sanitize(c_tag)
cam["deact"] = !can_use()
+5 -6
View File
@@ -13,7 +13,7 @@
circuit = /obj/item/weapon/circuitboard/rcon_console
req_one_access = list(access_engine)
var/current_tag = null
var/datum/nano_module/rcon/rcon
var/datum/tgui_module/rcon/rcon
/obj/machinery/computer/rcon/New()
..()
@@ -29,13 +29,12 @@
// Description: Opens UI of this machine.
/obj/machinery/computer/rcon/attack_hand(var/mob/user as mob)
..()
ui_interact(user)
tgui_interact(user)
// Proc: ui_interact()
// Parameters: 4 (standard NanoUI parameters)
// Description: Uses dark magic (NanoUI) to render this machine's UI
/obj/machinery/computer/rcon/ui_interact(mob/user, ui_key = "rcon", var/datum/nanoui/ui = null, var/force_open = 1)
rcon.ui_interact(user, ui_key, ui, force_open)
// Description: Uses dark magic (TGUI) to render this machine's UI
/obj/machinery/computer/rcon/tgui_interact(mob/user, datum/tgui/ui)
rcon.tgui_interact(user, ui)
/obj/machinery/computer/rcon/update_icon()
..()
+1 -1
View File
@@ -82,7 +82,7 @@
/obj/machinery/computer/aifixer/tgui_act(action, params)
if(..())
return
return TRUE
if(!occupier)
restoring = FALSE
+30 -34
View File
@@ -17,16 +17,22 @@ var/global/list/minor_air_alarms = list()
atmosphere_alarm.register_alarm(src, /obj/machinery/computer/station_alert/update_icon)
/obj/machinery/computer/atmos_alert/Destroy()
atmosphere_alarm.unregister_alarm(src)
..()
atmosphere_alarm.unregister_alarm(src)
..()
/obj/machinery/computer/atmos_alert/attack_hand(mob/user)
ui_interact(user)
tgui_interact(user)
/obj/machinery/computer/atmos_alert/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/major_alarms[0]
var/minor_alarms[0]
/obj/machinery/computer/atmos_alert/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AtmosAlertConsole", name)
ui.open()
/obj/machinery/computer/atmos_alert/tgui_data(mob/user)
var/list/data = list()
var/list/major_alarms = list()
var/list/minor_alarms = list()
for(var/datum/alarm/alarm in atmosphere_alarm.major_alarms(get_z(src)))
major_alarms[++major_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]")
@@ -37,12 +43,7 @@ var/global/list/minor_air_alarms = list()
data["priority_alarms"] = major_alarms
data["minor_alarms"] = minor_alarms
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_alert.tmpl", src.name, 500, 500)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
return data
/obj/machinery/computer/atmos_alert/update_icon()
if(!(stat & (NOPOWER|BROKEN)))
@@ -57,26 +58,21 @@ var/global/list/minor_air_alarms = list()
icon_screen = initial(icon_screen)
..()
/obj/machinery/computer/atmos_alert/Topic(href, href_list)
/obj/machinery/computer/atmos_alert/tgui_act(action, params)
if(..())
return 1
return TRUE
if(href_list["clear_alarm"])
var/datum/alarm/alarm = locate(href_list["clear_alarm"]) in atmosphere_alarm.alarms
if(alarm)
for(var/datum/alarm_source/alarm_source in alarm.sources)
var/obj/machinery/alarm/air_alarm = alarm_source.source
if(istype(air_alarm))
var/list/new_ref = list("atmos_reset" = 1)
air_alarm.Topic(href, new_ref, state = air_alarm_topic)
return 1
var/datum/topic_state/air_alarm_topic/air_alarm_topic = new()
/datum/topic_state/air_alarm_topic/href_list(var/mob/user)
var/list/extra_href = list()
extra_href["remote_connection"] = 1
extra_href["remote_access"] = 1
return extra_href
switch(action)
if("clear")
var/datum/alarm/alarm = locate(params["ref"]) in atmosphere_alarm.alarms
if(alarm)
for(var/datum/alarm_source/alarm_source in alarm.sources)
var/obj/machinery/alarm/air_alarm = alarm_source.source
if(istype(air_alarm))
// I have to leave a note here:
// Once upon a time, this called air_alarm.Topic() with a custom topic state
// in order to perform three lines of code. In other words, pure insanity.
// Whyyyyyyyyyyyyyyyyyyyyyyy.
air_alarm.atmos_reset()
. = TRUE
update_icon()
@@ -13,7 +13,7 @@
circuit = /obj/item/weapon/circuitboard/atmoscontrol
req_access = list(access_ce)
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/New()
..()
@@ -27,12 +27,12 @@
density = 0
/obj/machinery/computer/atmoscontrol/attack_ai(var/mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/computer/atmoscontrol/attack_hand(mob/user)
if(..())
return 1
ui_interact(user)
tgui_interact(user)
/obj/machinery/computer/atmoscontrol/emag_act(var/remaining_carges, var/mob/user)
if(!emagged)
@@ -42,7 +42,7 @@
atmos_control.emagged = 1
return 1
/obj/machinery/computer/atmoscontrol/ui_interact(var/mob/user)
/obj/machinery/computer/atmoscontrol/tgui_interact(var/mob/user)
if(!atmos_control)
atmos_control = new(src, req_access, req_one_access, monitored_alarm_ids)
atmos_control.ui_interact(user)
atmos_control.tgui_interact(user)
+210 -393
View File
@@ -12,23 +12,21 @@
//Sparks effect - For emag
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
//Messages - Saves me time if I want to change something.
var/noserver = "<span class='alert'>ALERT: No server detected.</span>"
var/incorrectkey = "<span class='warning'>ALERT: Incorrect decryption key!</span>"
var/defaultmsg = "<span class='notice'>Welcome. Please select an option.</span>"
var/rebootmsg = "<span class='warning'>%$&(£: Critical %$$@ Error // !RestArting! <lOadiNg backUp iNput ouTput> - ?pLeaSe wAit!</span>"
var/noserver = list("text" = "ALERT: No server detected.", "style" = "alert")
var/incorrectkey = list("text" = "ALERT: Incorrect decryption key!", "style" = "warning")
var/defaultmsg = list("text" = "Welcome. Please select an option.", "style" = "notice")
var/rebootmsg = list("text" = "%$&(£: Critical %$$@ Error // !RestArting! <lOadiNg backUp iNput ouTput> - ?pLeaSe wAit!", "style" = "warning")
//Computer properties
var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
var/hacking = 0 // Is it being hacked into by the AI/Cyborg
var/emag = 0 // When it is emagged.
var/message = "<span class='notice'>System bootup complete. Please select an option.</span>" // The message that shows on the main menu.
var/auth = 0 // Are they authenticated?
var/optioncount = 8
// Custom Message Properties
// Custom temp Properties
var/customsender = "System Administrator"
var/obj/item/device/pda/customrecepient = null
var/customjob = "Admin"
var/custommessage = "This is a test, please ignore."
var/list/temp = null
/obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/living/user as mob)
if(stat & (NOPOWER|BROKEN))
@@ -48,17 +46,16 @@
// Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online.
// It'll take more time if there's more characters in the password..
if(!emag && operable())
if(!isnull(src.linkedServer))
if(!isnull(linkedServer))
emag = 1
screen = 2
spark_system.set_up(5, 0, src)
src.spark_system.start()
spark_system.start()
var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
MK.loc = src.loc
MK.loc = loc
// Will help make emagging the console not so easy to get away with.
MK.info += "<br><br><font color='red'>£%@%(*$%&(£&?*(%&£/{}</font>"
spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
message = rebootmsg
spawn(100*length(linkedServer.decryptkey)) UnmagConsole()
temp = rebootmsg
update_icon()
return 1
else
@@ -78,201 +75,92 @@
linkedServer = message_servers[1]
return ..()
/obj/machinery/computer/message_monitor/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "MessageMonitor", name)
ui.open()
/obj/machinery/computer/message_monitor/tgui_data(mob/user)
var/list/data = list()
data["customsender"] = customsender
data["customrecepient"] = "[customrecepient]"
data["customjob"] = customjob
data["custommessage"] = custommessage
data["temp"] = temp
data["hacking"] = !!hacking
data["emag"] = !!emag
data["auth"] = !!auth
data["linkedServer"] = list()
if(linkedServer && auth)
data["linkedServer"]["active"] = linkedServer.active
data["linkedServer"]["broke"] = linkedServer.stat & (NOPOWER|BROKEN)
data["linkedServer"]["pda_msgs"] = list()
for(var/datum/data_pda_msg/pda in linkedServer.pda_msgs)
data["linkedServer"]["pda_msgs"].Add(list(list(
"ref" = "\ref[pda]",
"sender" = pda.sender,
"recipient" = pda.recipient,
"message" = pda.message,
)))
data["linkedServer"]["rc_msgs"] = list()
for(var/datum/data_rc_msg/rc in linkedServer.rc_msgs)
data["linkedServer"]["rc_msgs"].Add(list(list(
"ref" = "\ref[rc]",
"sender" = rc.send_dpt,
"recipient" = rc.rec_dpt,
"message" = rc.message,
"stamp" = rc.stamp,
"id_auth" = rc.id_auth,
"priority" = rc.priority,
)))
var/spamIndex = 0
data["linkedServer"]["spamFilter"] = list()
for(var/token in linkedServer.spamfilter)
spamIndex++
data["linkedServer"]["spamFilter"].Add(list(list(
"index" = spamIndex,
"token" = token,
)))
//Get out list of viable PDAs
var/list/obj/item/device/pda/sendPDAs = list()
for(var/obj/item/device/pda/P in PDAs)
if(!P.owner || P.toff || P.hidden)
continue
sendPDAs["[P.name]"] = "\ref[P]"
data["possibleRecipients"] = sendPDAs
data["isMalfAI"] = ((istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) && (user.mind.special_role && user.mind.original == user))
return data
/obj/machinery/computer/message_monitor/attack_hand(var/mob/living/user as mob)
if(stat & (NOPOWER|BROKEN))
return
if(!istype(user))
return
//If the computer is being hacked or is emagged, display the reboot message.
if(hacking || emag)
message = rebootmsg
var/dat = "<head><title>Message Monitor Console</title></head><body>"
dat += "<center><h2>Message Monitor Console</h2></center><hr>"
dat += "<center><h4><font color='blue'[message]</h5></center>"
if(auth)
dat += "<h4><dd><A href='?src=\ref[src];auth=1'>&#09;<font color='green'>\[Authenticated\]</font></a>&#09;/"
dat += " Server Power: <A href='?src=\ref[src];active=1'>[src.linkedServer && src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</a></h4>"
else
dat += "<h4><dd><A href='?src=\ref[src];auth=1'>&#09;<font color='red'>\[Unauthenticated\]</font></a>&#09;/"
dat += " Server Power: <u>[src.linkedServer && src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</u></h4>"
if(hacking || emag)
screen = 2
else if(!auth || !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) message = noserver
screen = 0
switch(screen)
//Main menu
if(0)
//&#09; = TAB
var/i = 0
dat += "<dd><A href='?src=\ref[src];find=1'>&#09;[++i]. Link To A Server</a></dd>"
if(auth)
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
dat += "<dd><A>&#09;ERROR: Server not found!</A><br></dd>"
else
dat += "<dd><A href='?src=\ref[src];view=1'>&#09;[++i]. View Message Logs </a><br></dd>"
dat += "<dd><A href='?src=\ref[src];viewr=1'>&#09;[++i]. View Request Console Logs </a></br></dd>"
dat += "<dd><A href='?src=\ref[src];clear=1'>&#09;[++i]. Clear Message Logs</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];clearr=1'>&#09;[++i]. Clear Request Console Logs</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];pass=1'>&#09;[++i]. Set Custom Key</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];msg=1'>&#09;[++i]. Send Admin Message</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];spam=1'>&#09;[++i]. Modify Spam Filter</a><br></dd>"
else
for(var/n = ++i; n <= optioncount; n++)
dat += "<dd><font color='blue'>&#09;[n]. ---------------</font><br></dd>"
if((istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) && (user.mind.special_role && user.mind.original == user))
//Malf/Traitor AIs can bruteforce into the system to gain the Key.
dat += "<dd><A href='?src=\ref[src];hack=1'><i><font color='Red'>*&@#. Bruteforce Key</font></i></font></a><br></dd>"
else
dat += "<br>"
//Bottom message
if(!auth)
dat += "<br><hr><dd><span class='notice'>Please authenticate with the server in order to show additional options.</span>"
else
dat += "<br><hr><dd><span class='warning'>Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties.</span>"
//Message Logs
if(1)
var/index = 0
//var/recipient = "Unspecified" //name of the person
//var/sender = "Unspecified" //name of the sender
//var/message = "Blank" //transferred message
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
dat += "<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15%'>Sender</th><th width='15%'>Recipient</th><th width='300px' word-wrap: break-word>Message</th></tr>"
for(var/datum/data_pda_msg/pda in src.linkedServer.pda_msgs)
index++
if(index > 3000)
break
// Del - Sender - Recepient - Message
// X - Al Green - Your Mom - WHAT UP!?
dat += "<tr><td width = '5%'><center><A href='?src=\ref[src];delete=\ref[pda]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[pda.sender]</td><td width='15%'>[pda.recipient]</td><td width='300px'>[pda.message]</td></tr>"
dat += "</table>"
//Hacking screen.
if(2)
if(istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot))
dat += "Brute-forcing for server key.<br> It will take 20 seconds for every character that the password has."
dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time."
else
//It's the same message as the one above but in binary. Because robots understand binary and humans don't... well I thought it was clever.
dat += {"01000010011100100111010101110100011001010010110<br>
10110011001101111011100100110001101101001011011100110011<br>
10010000001100110011011110111001000100000011100110110010<br>
10111001001110110011001010111001000100000011010110110010<br>
10111100100101110001000000100100101110100001000000111011<br>
10110100101101100011011000010000001110100011000010110101<br>
10110010100100000001100100011000000100000011100110110010<br>
10110001101101111011011100110010001110011001000000110011<br>
00110111101110010001000000110010101110110011001010111001<br>
00111100100100000011000110110100001100001011100100110000<br>
10110001101110100011001010111001000100000011101000110100<br>
00110000101110100001000000111010001101000011001010010000<br>
00111000001100001011100110111001101110111011011110111001<br>
00110010000100000011010000110000101110011001011100010000<br>
00100100101101110001000000111010001101000011001010010000<br>
00110110101100101011000010110111001110100011010010110110<br>
10110010100101100001000000111010001101000011010010111001<br>
10010000001100011011011110110111001110011011011110110110<br>
00110010100100000011000110110000101101110001000000111001<br>
00110010101110110011001010110000101101100001000000111100<br>
10110111101110101011100100010000001110100011100100111010<br>
10110010100100000011010010110111001110100011001010110111<br>
00111010001101001011011110110111001110011001000000110100<br>
10110011000100000011110010110111101110101001000000110110<br>
00110010101110100001000000111001101101111011011010110010<br>
10110111101101110011001010010000001100001011000110110001<br>
10110010101110011011100110010000001101001011101000010111<br>
00010000001001101011000010110101101100101001000000111001<br>
10111010101110010011001010010000001101110011011110010000<br>
00110100001110101011011010110000101101110011100110010000<br>
00110010101101110011101000110010101110010001000000111010<br>
00110100001100101001000000111001001101111011011110110110<br>
10010000001100100011101010111001001101001011011100110011<br>
10010000001110100011010000110000101110100001000000111010<br>
001101001011011010110010100101110"}
//Fake messages
if(3)
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];Reset=1'>Reset</a></center><hr>"
dat += {"<table border='1' width='100%'>
<tr><td width='20%'><A href='?src=\ref[src];select=Sender'>Sender</a></td>
<td width='20%'><A href='?src=\ref[src];select=RecJob'>Sender's Job</a></td>
<td width='20%'><A href='?src=\ref[src];select=Recepient'>Recipient</a></td>
<td width='300px' word-wrap: break-word><A href='?src=\ref[src];select=Message'>Message</a></td></tr>"}
//Sender - Sender's Job - Recepient - Message
//Al Green- Your Dad - Your Mom - WHAT UP!?
dat += {"<tr><td width='20%'>[customsender]</td>
<td width='20%'>[customjob]</td>
<td width='20%'>[customrecepient ? customrecepient.owner : "NONE"]</td>
<td width='300px'>[custommessage]</td></tr>"}
dat += "</table><br><center><A href='?src=\ref[src];select=Send'>Send</a></center>"
//Request Console Logs
if(4)
var/index = 0
/* data_rc_msg
X - 5%
var/rec_dpt = "Unspecified" //name of the person - 15%
var/send_dpt = "Unspecified" //name of the sender- 15%
var/message = "Blank" //transferred message - 300px
var/stamp = "Unstamped" - 15%
var/id_auth = "Unauthenticated" - 15%
var/priority = "Normal" - 10%
*/
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
dat += {"<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15%'>Sending Dep.</th><th width='15%'>Receiving Dep.</th>
<th width='300px' word-wrap: break-word>Message</th><th width='15%'>Stamp</th><th width='15%'>ID Auth.</th><th width='15%'>Priority.</th></tr>"}
for(var/datum/data_rc_msg/rc in src.linkedServer.rc_msgs)
index++
if(index > 3000)
break
// Del - Sender - Recepient - Message
// X - Al Green - Your Mom - WHAT UP!?
dat += {"<tr><td width = '5%'><center><A href='?src=\ref[src];deleter=\ref[rc]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[rc.send_dpt]</td>
<td width='15%'>[rc.rec_dpt]</td><td width='300px'>[rc.message]</td><td width='15%'>[rc.stamp]</td><td width='15%'>[rc.id_auth]</td><td width='15%'>[rc.priority]</td></tr>"}
dat += "</table>"
//Spam filter modification
if(5)
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
var/index = 0
for(var/token in src.linkedServer.spamfilter)
index++
if(index > 3000)
break
dat += "<dd>[index]&#09; <a href='?src=\ref[src];deltoken=[index]'>\[[token]\]</a><br></dd>"
dat += "<hr>"
if (linkedServer.spamfilter.len < linkedServer.spamfilter_limit)
dat += "<a href='?src=\ref[src];addtoken=1'>Add token</a><br>"
dat += "</body>"
message = defaultmsg
user << browse(dat, "window=message;size=700x700")
onclose(user, "message")
return
tgui_interact(user)
/obj/machinery/computer/message_monitor/attack_ai(mob/user as mob)
return src.attack_hand(user)
return attack_hand(user)
/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user as mob)
if(isnull(linkedServer))
to_chat(user, "<span class='warning'>Could not complete brute-force: Linked Server Disconnected!</span>")
else
var/currentKey = src.linkedServer.decryptkey
var/currentKey = linkedServer.decryptkey
to_chat(user, "<span class='warning'>Brute-force completed! The key is '[currentKey]'.</span>")
src.hacking = 0
hacking = 0
update_icon()
src.screen = 0 // Return the screen back to normal
/obj/machinery/computer/message_monitor/proc/UnmagConsole()
src.emag = 0
emag = 0
update_icon()
/obj/machinery/computer/message_monitor/proc/ResetMessage()
@@ -281,227 +169,156 @@
custommessage = "This is a test, please ignore."
customjob = "Admin"
/obj/machinery/computer/message_monitor/Topic(href, href_list)
/obj/machinery/computer/message_monitor/tgui_act(action, params)
if(..())
return 1
if(stat & (NOPOWER|BROKEN))
return
if(!istype(usr, /mob/living))
return
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
return TRUE
switch(action)
if("cleartemp")
temp = null
. = TRUE
//Authenticate
if (href_list["auth"])
if(auth)
auth = 0
screen = 0
else
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
auth = 1
else
message = incorrectkey
//Turn the server on/off.
if (href_list["active"])
if(auth) linkedServer.active = !linkedServer.active
if("auth")
var/dkey = params["key"]
if(dkey && dkey != "")
if(linkedServer.decryptkey == dkey)
auth = TRUE
else
temp = incorrectkey
. = TRUE
if("deauth")
auth = FALSE
. = TRUE
//Find a server
if (href_list["find"])
if("find")
if(message_servers && message_servers.len > 1)
src.linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers
message = "<span class='alert'>NOTICE: Server selected.</span>"
linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers
set_temp("NOTICE: Server selected.", "alert")
else if(message_servers && message_servers.len > 0)
linkedServer = message_servers[1]
message = "<span class='notice'>NOTICE: Only Single Server Detected - Server selected.</span>"
set_temp("NOTICE: Only Single Server Detected - Server selected.", "average")
else
message = noserver
//View the logs - KEY REQUIRED
if (href_list["view"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
if(auth)
src.screen = 1
//Clears the logs - KEY REQUIRED
if (href_list["clear"])
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
if(auth)
src.linkedServer.pda_msgs = list()
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
//Clears the request console logs - KEY REQUIRED
if (href_list["clearr"])
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
if(auth)
src.linkedServer.rc_msgs = list()
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
//Change the password - KEY REQUIRED
if (href_list["pass"])
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
if(auth)
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
if(length(newkey) <= 3)
message = "<span class='notice'>NOTICE: Decryption key too short!</span>"
else if(length(newkey) > 16)
message = "<span class='notice'>NOTICE: Decryption key too long!</span>"
else if(newkey && newkey != "")
src.linkedServer.decryptkey = newkey
message = "<span class='notice'>NOTICE: Decryption key set.</span>"
else
message = incorrectkey
temp = noserver
//Hack the Console to get the password
if (href_list["hack"])
if("hack")
if((istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot)) && (usr.mind.special_role && usr.mind.original == usr))
src.hacking = 1
src.screen = 2
hacking = 1
update_icon()
//Time it takes to bruteforce is dependant on the password length.
spawn(100*length(src.linkedServer.decryptkey))
if(src && src.linkedServer && usr)
spawn(100*length(linkedServer.decryptkey))
if(src && linkedServer && usr)
BruteForce(usr)
if(!auth)
return
if(!linkedServer || linkedServer.stat & (NOPOWER|BROKEN))
temp = noserver
return TRUE
switch(action)
//Turn the server on/off.
if("active")
linkedServer.active = !linkedServer.active
. = TRUE
//Clears the logs - KEY REQUIRED
if("del_pda")
linkedServer.pda_msgs = list()
set_temp("NOTICE: Logs cleared.", "average")
. = TRUE
//Clears the request console logs - KEY REQUIRED
if("del_rc")
linkedServer.rc_msgs = list()
set_temp("NOTICE: Logs cleared.", "average")
. = TRUE
//Change the password - KEY REQUIRED
if("pass")
var/dkey = trim(input(usr, "Please enter the current decryption key.") as text|null)
if(dkey && dkey != "")
if(linkedServer.decryptkey == dkey)
var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
if(length(newkey) <= 3)
set_temp("NOTICE: Decryption key too short!", "average")
else if(length(newkey) > 16)
set_temp("NOTICE: Decryption key too long!", "average")
else if(newkey && newkey != "")
linkedServer.decryptkey = newkey
set_temp("NOTICE: Decryption key set.", "average")
else
temp = incorrectkey
. = TRUE
//Delete the log.
if (href_list["delete"])
//Are they on the view logs screen?
if(screen == 1)
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else //if(istype(href_list["delete"], /datum/data_pda_msg))
src.linkedServer.pda_msgs -= locate(href_list["delete"])
message = "<span class='notice'>NOTICE: Log Deleted!</span>"
//Delete the request console log.
if (href_list["deleter"])
//Are they on the view logs screen?
if(screen == 4)
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else //if(istype(href_list["delete"], /datum/data_pda_msg))
src.linkedServer.rc_msgs -= locate(href_list["deleter"])
message = "<span class='notice'>NOTICE: Log Deleted!</span>"
//Create a custom message
if (href_list["msg"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
if("delete")
if(params["type"] == "pda")
linkedServer.pda_msgs -= locate(params["id"])
else
if(auth)
src.screen = 3
linkedServer.rc_msgs -= locate(params["id"])
set_temp("NOTICE: Log Deleted!", "average")
. = TRUE
//Fake messaging selection - KEY REQUIRED
if (href_list["select"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
screen = 0
if("set_sender")
customsender = sanitize(params["val"])
. = TRUE
if("set_sender_job")
customjob = sanitize(params["val"])
. = TRUE
if("set_recipient")
var/ref = params["val"]
var/obj/item/device/pda/P = locate(ref)
if(!istype(P) || !P.owner || P.toff || P.hidden)
return FALSE
customrecepient = P
. = TRUE
if("set_message")
custommessage = sanitize(params["val"])
. = TRUE
if("send_message")
if(isnull(customsender) || customsender == "")
customsender = "UNKNOWN"
if(isnull(customrecepient))
set_temp("NOTICE: No recepient selected!", "average")
return TRUE
if(isnull(custommessage) || custommessage == "")
set_temp("NOTICE: No message entered!", "average")
return TRUE
var/obj/item/device/pda/PDARec = null
for(var/obj/item/device/pda/P in PDAs)
if(!P.owner || P.toff || P.hidden) continue
if(P.owner == customsender)
PDARec = P
//Sender isn't faking as someone who exists
if(isnull(PDARec))
linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
customrecepient.new_message(customsender, customsender, customjob, custommessage)
//Sender is faking as someone who exists
else
switch(href_list["select"])
linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
customrecepient.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]")))
//Reset
if("Reset")
ResetMessage()
if(!customrecepient.conversations.Find("\ref[PDARec]"))
customrecepient.conversations.Add("\ref[PDARec]")
//Select Your Name
if("Sender")
customsender = sanitize(input(usr, "Please enter the sender's name.") as text|null)
customrecepient.new_message(PDARec, custommessage)
//Finally..
ResetMessage()
. = TRUE
//Select Receiver
if("Recepient")
//Get out list of viable PDAs
var/list/obj/item/device/pda/sendPDAs = list()
for(var/obj/item/device/pda/P in PDAs)
if(!P.owner || P.toff || P.hidden) continue
sendPDAs += P
if(PDAs && PDAs.len > 0)
customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortAtom(sendPDAs)
else
customrecepient = null
if("addtoken")
linkedServer.spamfilter += input(usr,"Enter text you want to be filtered out","Token creation") as text|null
. = TRUE
//Enter custom job
if("RecJob")
customjob = sanitize(input(usr, "Please enter the sender's job.") as text|null)
if("deltoken")
var/tokennum = text2num(params["deltoken"])
linkedServer.spamfilter.Cut(tokennum, tokennum + 1)
. = TRUE
//Enter message
if("Message")
custommessage = input(usr, "Please enter your message.") as text|null
custommessage = sanitize(custommessage)
//Send message
if("Send")
if(isnull(customsender) || customsender == "")
customsender = "UNKNOWN"
if(isnull(customrecepient))
message = "<span class='notice'>NOTICE: No recepient selected!</span>"
return src.attack_hand(usr)
if(isnull(custommessage) || custommessage == "")
message = "<span class='notice'>NOTICE: No message entered!</span>"
return src.attack_hand(usr)
var/obj/item/device/pda/PDARec = null
for (var/obj/item/device/pda/P in PDAs)
if (!P.owner || P.toff || P.hidden) continue
if(P.owner == customsender)
PDARec = P
//Sender isn't faking as someone who exists
if(isnull(PDARec))
src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
customrecepient.new_message(customsender, customsender, customjob, custommessage)
//Sender is faking as someone who exists
else
src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
customrecepient.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]")))
if(!customrecepient.conversations.Find("\ref[PDARec]"))
customrecepient.conversations.Add("\ref[PDARec]")
customrecepient.new_message(PDARec, custommessage)
//Finally..
ResetMessage()
//Request Console Logs - KEY REQUIRED
if(href_list["viewr"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
if(auth)
src.screen = 4
//to_chat(usr,href_list["select"])
if(href_list["spam"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
if(auth)
src.screen = 5
if(href_list["addtoken"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
src.linkedServer.spamfilter += input(usr,"Enter text you want to be filtered out","Token creation") as text|null
if(href_list["deltoken"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
var/tokennum = text2num(href_list["deltoken"])
src.linkedServer.spamfilter.Cut(tokennum,tokennum+1)
if (href_list["back"])
src.screen = 0
return src.attack_hand(usr)
/obj/machinery/computer/message_monitor/proc/set_temp(text = "", style = "info", update_now = FALSE)
temp = list(text = text, style = style)
if(update_now)
SStgui.update_uis(src)
/obj/item/weapon/paper/monitorkey
name = "Monitor Decryption Key"
@@ -5,23 +5,19 @@
icon_screen = "power_monitor"
light_color = "#a97faa"
circuit = /obj/item/weapon/circuitboard/shutoff_monitor
var/datum/nano_module/shutoff_monitor/monitor
var/datum/tgui_module/shutoff_monitor/monitor
/obj/machinery/computer/shutoff_monitor/New()
..()
monitor = new(src)
/obj/machinery/computer/shutoff_monitor/Destroy()
qdel(monitor)
monitor = null
QDEL_NULL(monitor)
..()
/obj/machinery/computer/shutoff_monitor/attack_hand(var/mob/user as mob)
..()
ui_interact(user)
/obj/machinery/computer/shutoff_monitor/ui_interact(mob/user, ui_key = "shutoff_monitor", var/datum/nanoui/ui = null, var/force_open = 1)
monitor.ui_interact(user, ui_key, ui, force_open)
monitor.tgui_interact(user)
/obj/machinery/computer/shutoff_monitor/update_icon()
..()
+273 -356
View File
@@ -1,5 +1,11 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
#define GENERAL_RECORD_LIST 2
#define GENERAL_RECORD_MAINT 3
#define GENERAL_RECORD_DATA 4
#define FIELD(N, V, E) list(field = N, value = V, edit = E)
/obj/machinery/computer/skills//TODO:SANITY
name = "employment records console"
desc = "Used to view, edit and maintain employment records."
@@ -16,20 +22,40 @@
var/screen = null
var/datum/data/record/active1 = null
var/a_id = null
var/temp = null
var/list/temp = null
var/printing = null
var/can_change_id = 0
var/list/Perp
var/tempname = null
//Sorting Variables
var/sortBy = "name"
var/order = 1 // -1 = Descending - 1 = Ascending
// The below are used to make modal generation more convenient
var/static/list/field_edit_questions
var/static/list/field_edit_choices
/obj/machinery/computer/skills/Initialize()
..()
field_edit_questions = list(
// General
"name" = "Please input new name:",
"id" = "Please input new ID:",
"sex" = "Please select new sex:",
"age" = "Please input new age:",
"fingerprint" = "Please input new fingerprint hash:",
)
field_edit_choices = list(
// General
"sex" = all_genders_text_list,
"p_stat" = list("*Deceased*", "*SSD*", "Active", "Physically Unfit", "Disabled"),
"m_stat" = list("*Insane*", "*Unstable*", "*Watch*", "Stable"),
)
/obj/machinery/computer/skills/Destroy()
active1 = null
return ..()
/obj/machinery/computer/skills/attackby(obj/item/O as obj, var/mob/user)
if(istype(O, /obj/item/weapon/card/id) && !scan && user.unEquip(O))
O.loc = src
scan = O
to_chat(user, "You insert [O].")
tgui_interact(user)
else
..()
@@ -43,380 +69,271 @@
if (using_map && !(src.z in using_map.contact_levels))
to_chat(user, "<span class='danger'>Unable to establish a connection:</span> You're too far away from the station!")
return
var/dat
tgui_interact(user)
if (temp)
dat = text("<TT>[]</TT><BR><BR><A href='?src=\ref[];choice=Clear Screen'>Clear Screen</A>", temp, src)
else
dat = text("Confirm Identity: <A href='?src=\ref[];choice=Confirm Identity'>[]</A><HR>", src, (scan ? text("[]", scan.name) : "----------"))
if (authenticated)
switch(screen)
if(1.0)
dat += {"
<p style='text-align:center;'>"}
dat += text("<A href='?src=\ref[];choice=Search Records'>Search Records</A><BR>", src)
dat += text("<A href='?src=\ref[];choice=New Record (General)'>New Record</A><BR>", src)
dat += {"
</p>
<table style="text-align:center;" cellspacing="0" width="100%">
<tr>
<th>Records:</th>
</tr>
</table>
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th><A href='?src=\ref[src];choice=Sorting;sort=name'>Name</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=id'>ID</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=rank'>Rank</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=fingerprint'>Fingerprints</A></th>
</tr>"}
if(!isnull(data_core.general))
for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order))
for(var/datum/data/record/E in data_core.security)
var/background
dat += text("<tr style=[]><td><A href='?src=\ref[];choice=Browse Record;d_rec=\ref[]'>[]</a></td>", background, src, R, R.fields["name"])
dat += text("<td>[]</td>", R.fields["id"])
dat += text("<td>[]</td>", R.fields["rank"])
dat += text("<td>[]</td>", R.fields["fingerprint"])
dat += "</table><hr width='75%' />"
dat += text("<A href='?src=\ref[];choice=Record Maintenance'>Record Maintenance</A><br><br>", src)
dat += text("<A href='?src=\ref[];choice=Log Out'>{Log Out}</A>",src)
if(2.0)
dat += "<B>Records Maintenance</B><HR>"
dat += "<BR><A href='?src=\ref[src];choice=Delete All Records'>Delete All Records</A><BR><BR><A href='?src=\ref[src];choice=Return'>Back</A>"
if(3.0)
dat += "<CENTER><B>Employment Record</B></CENTER><BR>"
if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
var/icon/front = active1.fields["photo_front"]
var/icon/side = active1.fields["photo_side"]
user << browse_rsc(front, "front.png")
user << browse_rsc(side, "side.png")
dat += "<table><tr><td>"
dat += "Name: <A href='?src=\ref[src];choice=Edit Field;field=name'>[active1.fields["name"]]</A><BR>"
dat += "ID: <A href='?src=\ref[src];choice=Edit Field;field=id'>[active1.fields["id"]]</A><BR>\n"
dat += "Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n"
dat += "Sex: <A href='?src=\ref[src];choice=Edit Field;field=sex'>[active1.fields["sex"]]</A><BR>\n"
dat += "Age: <A href='?src=\ref[src];choice=Edit Field;field=age'>[active1.fields["age"]]</A><BR>\n"
dat += "Rank: <A href='?src=\ref[src];choice=Edit Field;field=rank'>[active1.fields["rank"]]</A><BR>\n"
dat += "Fingerprint: <A href='?src=\ref[src];choice=Edit Field;field=fingerprint'>[active1.fields["fingerprint"]]</A><BR>\n"
dat += "Physical Status: [active1.fields["p_stat"]]<BR>\n"
dat += "Mental Status: [active1.fields["m_stat"]]<BR><BR>\n"
/obj/machinery/computer/skills/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GeneralRecords", "Employee Records") // 800, 380
ui.open()
ui.set_autoupdate(FALSE)
dat += "Employment/skills summary:<BR>"
dat += decode(active1.fields["notes"])
dat += "<BR><BR><BR>"
var/counter = 1
while(src.active1.fields[text("com_[]", counter)])
dat += text("[]<BR><A href='?src=\ref[];choice=del_c;del_c=[]'>Delete Entry</A><BR><BR>", src.active1.fields[text("com_[]", counter)], src, counter)
counter++
dat += "<A href='?src=\ref[src];choice=add_c'>Add Entry</A><BR><BR></td>"
dat += "<td align = center valign = top>Photo:<br><img src=front.png height=80 width=80 border=4>"
dat += "<img src=side.png height=80 width=80 border=4></td></tr></table>"
else
dat += "<B>General Record Lost!</B><BR>"
dat += text("\n<A href='?src=\ref[];choice=Delete Record (ALL)'>Delete Record (ALL)</A><BR><BR>\n<A href='?src=\ref[];choice=Print Record'>Print Record</A><BR>\n<A href='?src=\ref[];choice=Return'>Back</A><BR>", src, src, src)
if(4.0)
if(!Perp.len)
dat += text("ERROR. String could not be located.<br><br><A href='?src=\ref[];choice=Return'>Back</A>", src)
else
dat += {"
<table style="text-align:center;" cellspacing="0" width="100%">
<tr> "}
dat += text("<th>Search Results for '[]':</th>", tempname)
dat += {"
</tr>
</table>
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th>Name</th>
<th>ID</th>
<th>Rank</th>
<th>Fingerprints</th>
</tr> "}
for(var/i=1, i<=Perp.len, i += 2)
var/crimstat = ""
var/datum/data/record/R = Perp[i]
if(istype(Perp[i+1],/datum/data/record/))
var/datum/data/record/E = Perp[i+1]
crimstat = E.fields["criminal"]
var/background
background = "'background-color:#00FF7F;'"
dat += text("<tr style=[]><td><A href='?src=\ref[];choice=Browse Record;d_rec=\ref[]'>[]</a></td>", background, src, R, R.fields["name"])
dat += text("<td>[]</td>", R.fields["id"])
dat += text("<td>[]</td>", R.fields["rank"])
dat += text("<td>[]</td>", R.fields["fingerprint"])
dat += text("<td>[]</td></tr>", crimstat)
dat += "</table><hr width='75%' />"
dat += text("<br><A href='?src=\ref[];choice=Return'>Return to index.</A>", src)
/obj/machinery/computer/skills/tgui_data(mob/user)
var/data[0]
data["temp"] = temp
data["scan"] = scan ? scan.name : null
data["authenticated"] = authenticated
data["rank"] = rank
data["screen"] = screen
data["printing"] = printing
data["isAI"] = isAI(user)
data["isRobot"] = isrobot(user)
if(authenticated)
switch(screen)
if(GENERAL_RECORD_LIST)
if(!isnull(data_core.general))
var/list/records = list()
data["records"] = records
for(var/datum/data/record/R in sortRecord(data_core.general))
records[++records.len] = list(
"ref" = "\ref[R]",
"id" = R.fields["id"],
"name" = R.fields["name"],
"b_dna" = R.fields["b_dna"])
if(GENERAL_RECORD_DATA)
var/list/general = list()
data["general"] = general
if(istype(active1, /datum/data/record) && data_core.general.Find(active1))
var/list/fields = list()
general["fields"] = fields
fields[++fields.len] = FIELD("Name", active1.fields["name"], "name")
fields[++fields.len] = FIELD("ID", active1.fields["id"], "id")
fields[++fields.len] = FIELD("Sex", active1.fields["sex"], "sex")
fields[++fields.len] = FIELD("Age", active1.fields["age"], "age")
fields[++fields.len] = FIELD("Fingerprint", active1.fields["fingerprint"], "fingerprint")
fields[++fields.len] = FIELD("Physical Status", active1.fields["p_stat"], null)
fields[++fields.len] = FIELD("Mental Status", active1.fields["m_stat"], null)
var/list/photos = list()
general["photos"] = photos
photos[++photos.len] = active1.fields["photo-south"]
photos[++photos.len] = active1.fields["photo-west"]
general["has_photos"] = (active1.fields["photo-south"] || active1.fields["photo-west"] ? 1 : 0)
if(!active1.fields["comments"] || !islist(active1.fields["comments"]))
active1.fields["comments"] = list()
general["skills"] = active1.fields["notes"]
general["comments"] = active1.fields["comments"]
general["empty"] = 0
else
else
dat += text("<A href='?src=\ref[];choice=Log In'>{Log In}</A>", src)
user << browse(text("<HEAD><TITLE>Employment Records</TITLE></HEAD><TT>[]</TT>", dat), "window=secure_rec;size=600x400")
onclose(user, "secure_rec")
return
general["empty"] = 1
/*Revised /N
I can't be bothered to look more of the actual code outside of switch but that probably needs revising too.
What a mess.*/
/obj/machinery/computer/skills/Topic(href, href_list)
data["modal"] = tgui_modal_data(src)
return data
/obj/machinery/computer/skills/tgui_act(action, params)
if(..())
return 1
if (!( data_core.general.Find(active1) ))
return TRUE
add_fingerprint(usr)
if(!data_core.general.Find(active1))
active1 = null
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
switch(href_list["choice"])
// SORTING!
if("Sorting")
// Reverse the order if clicked twice
if(sortBy == href_list["sort"])
if(order == 1)
order = -1
else
order = 1
else
// New sorting order!
sortBy = href_list["sort"]
order = initial(order)
//BASIC FUNCTIONS
if("Clear Screen")
temp = null
if ("Return")
screen = 1
. = TRUE
if(tgui_act_modal(action, params))
return
switch(action)
if("scan")
if(scan)
scan.forceMove(loc)
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(scan)
scan = null
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.forceMove(src)
scan = I
if("cleartemp")
temp = null
if("login")
var/login_type = text2num(params["login_type"])
if(login_type == LOGIN_TYPE_NORMAL && istype(scan))
if(check_access(scan))
authenticated = scan.registered_name
rank = scan.assignment
else if(login_type == LOGIN_TYPE_AI && isAI(usr))
authenticated = usr.name
rank = "AI"
else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr))
authenticated = usr.name
var/mob/living/silicon/robot/R = usr
rank = "[R.modtype] [R.braintype]"
if(authenticated)
active1 = null
screen = GENERAL_RECORD_LIST
else
. = FALSE
if(.)
return
if("Confirm Identity")
if (scan)
if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand())
if(authenticated)
. = TRUE
switch(action)
if("logout")
if(scan)
scan.forceMove(loc)
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(scan)
else
scan.loc = get_turf(src)
scan = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I))
I.loc = src
scan = I
if("Log Out")
authenticated = null
screen = null
active1 = null
if("Log In")
if (istype(usr, /mob/living/silicon/ai))
src.active1 = null
src.authenticated = usr.name
src.rank = "AI"
src.screen = 1
else if (istype(usr, /mob/living/silicon/robot))
src.active1 = null
src.authenticated = usr.name
var/mob/living/silicon/robot/R = usr
src.rank = R.braintype
src.screen = 1
else if (istype(scan, /obj/item/weapon/card/id))
active1 = null
if(check_access(scan))
authenticated = scan.registered_name
rank = scan.assignment
screen = 1
//RECORD FUNCTIONS
if("Search Records")
var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text
if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr)))
return
Perp = new/list()
t1 = lowertext(t1)
var/list/components = splittext(t1, " ")
if(components.len > 5)
return //Lets not let them search too greedily.
for(var/datum/data/record/R in data_core.general)
var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"]
for(var/i = 1, i<=components.len, i++)
if(findtext(temptext,components[i]))
var/prelist = new/list(2)
prelist[1] = R
Perp += prelist
for(var/i = 1, i<=Perp.len, i+=2)
for(var/datum/data/record/E in data_core.security)
var/datum/data/record/R = Perp[i]
if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
Perp[i+1] = E
tempname = t1
screen = 4
if("Record Maintenance")
screen = 2
if("screen")
screen = clamp(text2num(params["screen"]) || 0, GENERAL_RECORD_LIST, GENERAL_RECORD_MAINT)
active1 = null
if ("Browse Record")
var/datum/data/record/R = locate(href_list["d_rec"])
if (!( data_core.general.Find(R) ))
temp = "Record Not Found!"
else
for(var/datum/data/record/E in data_core.security)
active1 = R
screen = 3
/* if ("Search Fingerprints")
var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text
if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!istype(usr, /mob/living/silicon))))
return
active1 = null
t1 = lowertext(t1)
for(var/datum/data/record/R in data_core.general)
if (lowertext(R.fields["fingerprint"]) == t1)
active1 = R
if (!( active1 ))
temp = text("Could not locate record [].", t1)
else
for(var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"]))
screen = 3 */
if ("Print Record")
if (!( printing ))
printing = 1
sleep(50)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc )
P.info = "<CENTER><B>Employment Record</B></CENTER><BR>"
if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
P.info += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>\nEmployment/Skills Summary:<BR>\n[]<BR>", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"], active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"], decode(active1.fields["notes"]))
else
P.info += "<B>General Record Lost!</B><BR>"
P.info += "</TT>"
if(active1)
P.name = "Employment Record ([active1.fields["name"]])"
else
P.name = "Employment Record (Unknown/Invald Entry)"
log_debug("[usr] ([usr.ckey]) attempted to print a null employee record, this should be investigated.")
printing = null
// Add comment
if ("add_c")
if (!( istype(src.active1, /datum/data/record) ))
return
var/a1 = src.active1
var/t1 = sanitize(input("Add Comment:", "Emp. records", null, null) as message)
if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
return
var/counter = 1
while(src.active1.fields[text("com_[]", counter)])
counter++
src.active1.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]<BR>[t1]")
// Delete comment
if ("del_c")
var/target = href_list["del_c"]
if (istype(src.active1, /datum/data/record) && src.active1.fields["com_[target]"])
src.active1.fields["com_[target]"] = "<B>Deleted</B>"
//RECORD DELETE
if ("Delete All Records")
temp = ""
temp += "Are you sure you wish to delete all Employment records?<br>"
temp += "<a href='?src=\ref[src];choice=Purge All Records'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
if ("Purge All Records")
if(PDA_Manifest.len)
if("del_all")
if(PDA_Manifest)
PDA_Manifest.Cut()
for(var/datum/data/record/R in data_core.security)
for(var/datum/data/record/R in data_core.general)
qdel(R)
temp = "All Employment records deleted."
set_temp("All employment records deleted.")
if("del_r")
if(PDA_Manifest)
PDA_Manifest.Cut()
if(active1)
for(var/datum/data/record/R in data_core.medical)
if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
qdel(R)
set_temp("Employment record deleted.")
QDEL_NULL(active1)
if("d_rec")
var/datum/data/record/general_record = locate(params["d_rec"] || "")
if(!data_core.general.Find(general_record))
set_temp("Record not found.", "danger")
return
if ("Delete Record (ALL)")
if (active1)
temp = "<h5>Are you sure you wish to delete the record (ALL)?</h5>"
temp += "<a href='?src=\ref[src];choice=Delete Record (ALL) Execute'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
//RECORD CREATE
if ("New Record (General)")
if(PDA_Manifest.len)
active1 = general_record
screen = GENERAL_RECORD_DATA
if("new")
if(PDA_Manifest)
PDA_Manifest.Cut()
active1 = data_core.CreateGeneralRecord()
screen = GENERAL_RECORD_DATA
set_temp("Employment record created.", "success")
if("del_c")
var/index = text2num(params["del_c"] || "")
if(!index || !istype(active1, /datum/data/record))
return
//FIELD FUNCTIONS
if ("Edit Field")
var/a1 = active1
switch(href_list["field"])
if("name")
if (istype(active1, /datum/data/record))
var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
if ((!( t1 ) || !length(trim(t1)) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon)))) || active1 != a1)
return
active1.fields["name"] = t1
if("id")
if (istype(active1, /datum/data/record))
var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text)
if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
active1.fields["id"] = t1
if("fingerprint")
if (istype(active1, /datum/data/record))
var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text)
if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
active1.fields["fingerprint"] = t1
if("sex")
if (istype(active1, /datum/data/record))
if (active1.fields["sex"] == "Male")
active1.fields["sex"] = "Female"
else
active1.fields["sex"] = "Male"
if("age")
if (istype(active1, /datum/data/record))
var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
active1.fields["age"] = t1
if("rank")
var/list/L = list( "Head of Personnel", "Colony Director", "AI" )
//This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
if ((istype(active1, /datum/data/record) && L.Find(rank)))
temp = "<h5>Rank:</h5>"
temp += "<ul>"
for(var/rank in joblist)
temp += "<li><a href='?src=\ref[src];choice=Change Rank;rank=[rank]'>[rank]</a></li>"
temp += "</ul>"
else
alert(usr, "You do not have the required rank to do this!")
if("species")
if (istype(active1, /datum/data/record))
var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)
if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
active1.fields["species"] = t1
var/list/comments = active1.fields["comments"]
index = clamp(index, 1, length(comments))
if(comments[index])
comments.Cut(index, index + 1)
if("print_p")
if(!printing)
printing = TRUE
// playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE)
SStgui.update_uis(src)
addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS)
else
return FALSE
//TEMPORARY MENU FUNCTIONS
else//To properly clear as per clear screen.
temp=null
switch(href_list["choice"])
if ("Change Rank")
if (active1)
if(PDA_Manifest.len)
PDA_Manifest.Cut()
active1.fields["rank"] = href_list["rank"]
if(href_list["rank"] in joblist)
active1.fields["real_rank"] = href_list["real_rank"]
if ("Delete Record (ALL) Execute")
if (active1)
if(PDA_Manifest.len)
PDA_Manifest.Cut()
for(var/datum/data/record/R in data_core.medical)
if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
qdel(R)
else
qdel(active1)
/**
* Called in tgui_act() to process modal actions
*
* Arguments:
* * action - The action passed by tgui
* * params - The params passed by tgui
*/
/obj/machinery/computer/skills/proc/tgui_act_modal(action, params)
. = TRUE
var/id = params["id"] // The modal's ID
var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"]
switch(tgui_modal_act(src, action, params))
if(TGUI_MODAL_OPEN)
switch(id)
if("edit")
var/field = arguments["field"]
if(!length(field) || !field_edit_questions[field])
return
var/question = field_edit_questions[field]
var/choices = field_edit_choices[field]
if(length(choices))
tgui_modal_choice(src, id, question, arguments = arguments, value = arguments["value"], choices = choices)
else
temp = "This function does not appear to be working at the moment. Our apologies."
tgui_modal_input(src, id, question, arguments = arguments, value = arguments["value"])
if("add_c")
tgui_modal_input(src, id, "Please enter your message:")
else
return FALSE
if(TGUI_MODAL_ANSWER)
var/answer = params["answer"]
switch(id)
if("edit")
var/field = arguments["field"]
if(!length(field) || !field_edit_questions[field])
return
var/list/choices = field_edit_choices[field]
if(length(choices) && !(answer in choices))
return
add_fingerprint(usr)
updateUsrDialog()
return
if(field == "age")
answer = text2num(answer)
if(istype(active1) && (field in active1.fields))
active1.fields[field] = answer
. = TRUE
if("add_c")
if(!length(answer) || !istype(active1) || !length(authenticated))
return
active1.fields["comments"] += list(list(
header = "Made by [authenticated] ([rank]) at [worldtime2stationtime(world.time)]",
text = answer
))
else
return FALSE
else
return FALSE
/**
* Called when the print timer finishes
*/
/obj/machinery/computer/skills/proc/print_finish()
var/obj/item/weapon/paper/P = new(loc)
P.info = "<center><b>Medical Record</b></center><br>"
if(istype(active1, /datum/data/record) && data_core.general.Find(active1))
P.info += {"Name: [active1.fields["name"]] ID: [active1.fields["id"]]
<br>\nSex: [active1.fields["sex"]]
<br>\nAge: [active1.fields["age"]]
<br>\nFingerprint: [active1.fields["fingerprint"]]
<br>\nPhysical Status: [active1.fields["p_stat"]]
<br>\nMental Status: [active1.fields["m_stat"]]<br>
<br>\nEmployment/Skills Summary: [active1.fields["notes"]]
<br>\n
<center><b>Comments/Log</b></center><br>"}
for(var/c in active1.fields["comments"])
P.info += "[c]<br>"
else
P.info += "<b>General Record Lost!</b><br>"
P.info += "</tt>"
P.name = "paper - 'Employment Record: [active1.fields["name"]]'"
printing = FALSE
SStgui.update_uis(src)
/**
* Sets a temporary message to display to the user
*
* Arguments:
* * text - Text to display, null/empty to clear the message from the UI
* * style - The style of the message: (color name), info, success, warning, danger, virus
*/
/obj/machinery/computer/skills/proc/set_temp(text = "", style = "info", update_now = FALSE)
temp = list(text = text, style = style)
if(update_now)
SStgui.update_uis(src)
/obj/machinery/computer/skills/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
@@ -6,15 +6,15 @@
icon_screen = "alert:0"
light_color = "#e6ffff"
circuit = /obj/item/weapon/circuitboard/stationalert_engineering
var/datum/nano_module/alarm_monitor/alarm_monitor
var/monitor_type = /datum/nano_module/alarm_monitor/engineering
var/datum/tgui_module/alarm_monitor/alarm_monitor
var/monitor_type = /datum/tgui_module/alarm_monitor/engineering
/obj/machinery/computer/station_alert/security
monitor_type = /datum/nano_module/alarm_monitor/security
monitor_type = /datum/tgui_module/alarm_monitor/security
circuit = /obj/item/weapon/circuitboard/stationalert_security
/obj/machinery/computer/station_alert/all
monitor_type = /datum/nano_module/alarm_monitor/all
monitor_type = /datum/tgui_module/alarm_monitor/all
circuit = /obj/item/weapon/circuitboard/stationalert_all
/obj/machinery/computer/station_alert/Initialize()
@@ -31,18 +31,18 @@
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
interact(user)
tgui_interact(user)
return
/obj/machinery/computer/station_alert/attack_hand(mob/user)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
interact(user)
tgui_interact(user)
return
/obj/machinery/computer/station_alert/interact(mob/user)
alarm_monitor.ui_interact(user)
/obj/machinery/computer/station_alert/tgui_interact(mob/user)
alarm_monitor.tgui_interact(user)
/obj/machinery/computer/station_alert/update_icon()
if(!(stat & (BROKEN|NOPOWER)))
+133 -87
View File
@@ -740,32 +740,52 @@ About the new airlock wires panel:
return
/obj/machinery/door/airlock/attack_ai(mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/door/airlock/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/data[0]
/obj/machinery/door/airlock/attack_ghost(mob/user)
tgui_interact(user)
data["main_power_loss"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1)
data["backup_power_loss"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1)
data["electrified"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1)
data["open"] = !density
var/commands[0]
commands[++commands.len] = list("name" = "IdScan", "command"= "idscan", "active" = !aiDisabledIdScanner, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1)
commands[++commands.len] = list("name" = "Bolts", "command"= "bolts", "active" = !locked, "enabled" = "Raised ", "disabled" = "Dropped", "danger" = 0, "act" = 0)
commands[++commands.len] = list("name" = "Bolt Lights", "command"= "lights", "active" = lights, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1)
commands[++commands.len] = list("name" = "Safeties", "command"= "safeties", "active" = safe, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0)
commands[++commands.len] = list("name" = "Timing", "command"= "timing", "active" = normalspeed, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0)
commands[++commands.len] = list("name" = "Door State", "command"= "open", "active" = density, "enabled" = "Closed", "disabled" = "Opened", "danger" = 0, "act" = 0)
data["commands"] = commands
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "door_control.tmpl", "Door Controls", 450, 350, state = state)
ui.set_initial_data(data)
/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AiAirlock", name)
ui.open()
ui.set_auto_update(1)
return TRUE
/obj/machinery/door/airlock/tgui_data(mob/user)
var/list/data = list()
var/list/power = list()
power["main"] = main_power_lost_until > 0 ? 0 : 2
power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1)
power["backup"] = backup_power_lost_until > 0 ? 0 : 2
power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1)
data["power"] = power
data["shock"] = (electrified_until == 0) ? 2 : 0
data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1)
data["id_scanner"] = !aiDisabledIdScanner
data["locked"] = locked // bolted
data["lights"] = lights // bolt lights
data["safe"] = safe // safeties
data["speed"] = normalspeed // safe speed
data["welded"] = welded // welded
data["opened"] = !density // opened
var/list/wire = list()
wire["main_1"] = !wires.is_cut(WIRE_MAIN_POWER1)
wire["main_2"] = !wires.is_cut(WIRE_MAIN_POWER2)
wire["backup_1"] = !wires.is_cut(WIRE_BACKUP_POWER1)
wire["backup_2"] = !wires.is_cut(WIRE_BACKUP_POWER2)
wire["shock"] = !wires.is_cut(WIRE_ELECTRIFY)
wire["id_scanner"] = !wires.is_cut(WIRE_IDSCAN)
wire["bolts"] = !wires.is_cut(WIRE_DOOR_BOLTS)
wire["lights"] = !wires.is_cut(WIRE_BOLT_LIGHT)
wire["safe"] = !wires.is_cut(WIRE_SAFETY)
wire["timing"] = !wires.is_cut(WIRE_SPEED)
data["wires"] = wire
return data
/obj/machinery/door/airlock/proc/hack(mob/user as mob)
if(src.aiHacking==0)
@@ -844,80 +864,106 @@ About the new airlock wires panel:
..(user)
return
/obj/machinery/door/airlock/CanUseTopic(var/mob/user)
if(operating < 0) //emagged
to_chat(user, "<span class='warning'>Unable to interface: Internal error.</span>")
return STATUS_CLOSE
if(issilicon(user) && !src.canAIControl())
if(src.canAIHack(user))
src.hack(user)
else
if (src.isAllPowerLoss()) //don't really like how this gets checked a second time, but not sure how else to do it.
to_chat(user, "<span class='warning'>Unable to interface: Connection timed out.</span>")
else
to_chat(user, "<span class='warning'>Unable to interface: Connection refused.</span>")
return STATUS_CLOSE
return ..()
/obj/machinery/door/airlock/Topic(href, href_list)
/obj/machinery/door/airlock/tgui_act(action, params)
if(..())
return 1
return TRUE
if(!user_allowed(usr))
return TRUE
var/activate = text2num(href_list["activate"])
switch (href_list["command"])
if("idscan")
set_idscan(activate, 1)
if("main_power")
switch(action)
if("disrupt-main")
if(!main_power_lost_until)
src.loseMainPower()
if("backup_power")
loseMainPower()
update_icon()
else
to_chat(usr, "<span class='warning'>Main power is already offline.</span>")
. = TRUE
if("disrupt-backup")
if(!backup_power_lost_until)
src.loseBackupPower()
if("bolts")
if(wires.is_cut(WIRE_DOOR_BOLTS))
to_chat(usr, "The door bolt control wire is cut - Door bolts permanently dropped.")
else if(activate && src.lock())
to_chat(usr, "The door bolts have been dropped.")
else if(!activate && src.unlock())
to_chat(usr, "The door bolts have been raised.")
if("electrify_temporary")
electrify(30 * activate, 1)
if("electrify_permanently")
electrify(-1 * activate, 1)
if("open")
if(src.welded)
to_chat(usr, "The airlock has been welded shut!")
else if(src.locked)
to_chat(usr, "The door bolts are down!")
else if(activate && density)
open()
else if(!activate && !density)
close()
if("safeties")
set_safeties(!activate, 1)
if("timing")
// Door speed control
if(wires.is_cut(WIRE_SPEED))
to_chat(usr, "The timing wire is cut - Cannot alter timing.")
else if (activate && src.normalspeed)
normalspeed = 0
else if (!activate && !src.normalspeed)
normalspeed = 1
if("lights")
// Bolt lights
loseBackupPower()
update_icon()
else
to_chat(usr, "<span class='warning'>Backup power is already offline.</span>")
. = TRUE
if("shock-restore")
electrify(0, 1)
. = TRUE
if("shock-temp")
electrify(30, 1)
. = TRUE
if("shock-perm")
electrify(-1, 1)
. = TRUE
if("idscan-toggle")
set_idscan(aiDisabledIdScanner, 1)
. = TRUE
// if("emergency-toggle")
// toggle_emergency(usr)
// . = TRUE
if("bolt-toggle")
toggle_bolt(usr)
. = TRUE
if("light-toggle")
if(wires.is_cut(WIRE_BOLT_LIGHT))
to_chat(usr, "The bolt lights wire is cut - The door bolt lights are permanently disabled.")
else if (!activate && src.lights)
lights = 0
to_chat(usr, "The door bolt lights have been disabled.")
else if (activate && !src.lights)
lights = 1
to_chat(usr, "The door bolt lights have been enabled.")
return
lights = !lights
update_icon()
. = TRUE
if("safe-toggle")
set_safeties(!safe, 1)
. = TRUE
if("speed-toggle")
if(wires.is_cut(WIRE_SPEED))
to_chat(usr, "The timing wire is cut - Cannot alter timing.")
return
normalspeed = !normalspeed
. = TRUE
if("open-close")
user_toggle_open(usr)
. = TRUE
update_icon()
return 1
/obj/machinery/door/airlock/proc/user_allowed(mob/user)
var/allowed = (issilicon(user) && canAIControl(user))
if(!allowed && isobserver(user))
var/mob/observer/dead/D = user
if(D.can_admin_interact())
allowed = TRUE
return allowed
/obj/machinery/door/airlock/proc/toggle_bolt(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_DOOR_BOLTS))
to_chat(user, "<span class='warning'>The door bolt drop wire is cut - you can't toggle the door bolts.</span>")
return
if(locked)
if(!arePowerSystemsOn())
to_chat(user, "<span class='warning'>The door has no power - you can't raise the door bolts.</span>")
else
unlock()
to_chat(user, "<span class='notice'>The door bolts have been raised.</span>")
// log_combat(user, src, "unbolted")
else
lock()
to_chat(user, "<span class='warning'>The door bolts have been dropped.</span>")
// log_combat(user, src, "bolted")
/obj/machinery/door/airlock/proc/user_toggle_open(mob/user)
if(!user_allowed(user))
return
if(welded)
to_chat(user, text("<span class='warning'>The airlock has been welded shut!</span>"))
else if(locked)
to_chat(user, text("<span class='warning'>The door bolts are down!</span>"))
else if(!density)
close()
else
open()
/obj/machinery/door/airlock/proc/can_remove_electronics()
return src.p_open && (operating < 0 || (!operating && welded && !src.arePowerSystemsOn() && density && (!src.locked || (stat & BROKEN))))
@@ -14,6 +14,7 @@
var/tag_secure = 0
var/list/dummy_terminals = list()
var/cycle_to_external_air = 0
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "purge", "secure")
/obj/machinery/embedded_controller/radio/airlock/Destroy()
// TODO - Leshana - Implement dummy terminals
@@ -23,90 +24,42 @@
//dummy_terminals.Cut()
return ..()
/obj/machinery/embedded_controller/radio/airlock/CanUseTopic(var/mob/user)
/obj/machinery/embedded_controller/radio/airlock/tgui_status(mob/user, datum/tgui_state/state)
. = ..()
if(!allowed(user))
return min(STATUS_UPDATE, ..())
else
return ..()
return min(STATUS_UPDATE, .)
//Advanced airlock controller for when you want a more versatile airlock controller - useful for turning simple access control rooms into airlocks
/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller
name = "Advanced Airlock Controller"
/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data = list(
/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/tgui_data(mob/user)
. = list(
"chamber_pressure" = round(program.memory["chamber_sensor_pressure"]),
"external_pressure" = round(program.memory["external_sensor_pressure"]),
"internal_pressure" = round(program.memory["internal_sensor_pressure"]),
"processing" = program.memory["processing"],
"purge" = program.memory["purge"],
"secure" = program.memory["secure"]
"secure" = program.memory["secure"],
"internalTemplateName" = "AirlockConsoleAdvanced",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "advanced_airlock_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/Topic(href, href_list)
if((. = ..()))
return
switch(href_list["command"]) //anti-HTML-hacking checks
if("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "purge", "secure")
program.receive_user_command(href_list["command"])
return 1
//Airlock controller for airlock control - most airlocks on the station use this
/obj/machinery/embedded_controller/radio/airlock/airlock_controller
name = "Airlock Controller"
tag_secure = 1
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort")
/obj/machinery/embedded_controller/radio/airlock/airlock_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data = list(
/obj/machinery/embedded_controller/radio/airlock/airlock_controller/tgui_data(mob/user)
. = list(
"chamber_pressure" = round(program.memory["chamber_sensor_pressure"]),
"exterior_status" = program.memory["exterior_status"],
"interior_status" = program.memory["interior_status"],
"processing" = program.memory["processing"],
"internalTemplateName" = "AirlockConsoleSimple",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "simple_airlock_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/airlock/airlock_controller/Topic(href, href_list)
if((. = ..()))
return
var/clean = 0
switch(href_list["command"]) //anti-HTML-hacking checks
if("cycle_ext")
clean = 1
if("cycle_int")
clean = 1
if("force_ext")
clean = 1
if("force_int")
clean = 1
if("abort")
clean = 1
if(clean)
program.receive_user_command(href_list["command"])
return 1
//Access controller for door control - used in virology and the like
/obj/machinery/embedded_controller/radio/airlock/access_controller
icon = 'icons/obj/airlock_machines.dmi'
@@ -114,6 +67,7 @@
name = "Access Controller"
tag_secure = 1
valid_actions = list("cycle_ext_door", "cycle_int_door", "force_ext", "force_int")
/obj/machinery/embedded_controller/radio/airlock/access_controller/update_icon()
@@ -125,40 +79,10 @@
else
icon_state = "access_control_off"
/obj/machinery/embedded_controller/radio/airlock/access_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data = list(
/obj/machinery/embedded_controller/radio/airlock/access_controller/tgui_data(mob/user)
. = list(
"exterior_status" = program.memory["exterior_status"],
"interior_status" = program.memory["interior_status"],
"processing" = program.memory["processing"]
"processing" = program.memory["processing"],
"internalTemplateName" = "DoorAccessConsole",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "door_access_console.tmpl", name, 330, 220)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/airlock/access_controller/Topic(href, href_list)
if((. = ..()))
return
var/clean = 0
switch(href_list["command"]) //anti-HTML-hacking checks
if("cycle_ext_door")
clean = 1
if("cycle_int_door")
clean = 1
if("force_ext")
if(program.memory["interior_status"]["state"] == "closed")
clean = 1
if("force_int")
if(program.memory["exterior_status"]["state"] == "closed")
clean = 1
if(clean)
program.receive_user_command(href_list["command"])
return 1
@@ -1,4 +1,5 @@
// Provides remote access to a controller (since they must be unique).
// TGUITODO: Actually make these weird things work... well, as much as possible.
/obj/machinery/dummy_airlock_controller
name = "airlock control terminal"
icon = 'icons/obj/airlock_machines.dmi'
@@ -13,6 +13,7 @@
var/datum/computer/file/embedded_program/docking/airlock/docking_program
var/display_name // For mappers to override docking_program.display_name (how would it show up on docking monitoring program)
tag_secure = 1
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "toggle_override")
/obj/machinery/embedded_controller/radio/airlock/docking_port/Initialize()
. = ..()
@@ -34,12 +35,11 @@
else
..()
/obj/machinery/embedded_controller/radio/airlock/docking_port/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
/obj/machinery/embedded_controller/radio/airlock/docking_port/tgui_data(mob/user)
var/datum/computer/file/embedded_program/docking/airlock/docking_program = program
var/datum/computer/file/embedded_program/airlock/docking/airlock_program = docking_program.airlock_program
data = list(
. = list(
"chamber_pressure" = round(airlock_program.memory["chamber_sensor_pressure"]),
"exterior_status" = airlock_program.memory["exterior_status"],
"interior_status" = airlock_program.memory["interior_status"],
@@ -48,49 +48,16 @@
"airlock_disabled" = !(docking_program.undocked() || docking_program.override_enabled),
"override_enabled" = docking_program.override_enabled,
"docking_codes" = docking_program.docking_codes,
"name" = docking_program.get_name()
"name" = docking_program.get_name(),
"internalTemplateName" = "AirlockConsoleDocking",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "docking_airlock_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/airlock/docking_port/Topic(href, href_list)
if((. = ..()))
return
var/clean = 0
switch(href_list["command"]) //anti-HTML-hacking checks
if("cycle_ext")
clean = 1
if("cycle_int")
clean = 1
if("force_ext")
clean = 1
if("force_int")
clean = 1
if("abort")
clean = 1
if("toggle_override")
clean = 1
if(clean)
program.receive_user_command(href_list["command"])
return 1
///////////////////////////////////////////////////////////////////////////////
//A docking controller for an airlock based docking port
//
/datum/computer/file/embedded_program/docking/airlock
var/datum/computer/file/embedded_program/airlock/docking/airlock_program
/datum/computer/file/embedded_program/docking/airlock/New(var/obj/machinery/embedded_controller/M, var/datum/computer/file/embedded_program/airlock/docking/A)
..(M)
airlock_program = A
@@ -15,9 +15,7 @@
for (var/i = 1; i <= tags.len; i++)
child_names[tags[i]] = names[i]
/obj/machinery/embedded_controller/radio/docking_port_multi/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
/obj/machinery/embedded_controller/radio/docking_port_multi/tgui_data(mob/user)
var/datum/computer/file/embedded_program/docking/multi/docking_program = program // Cast to proper type
var/list/airlocks[child_names.len]
@@ -25,23 +23,14 @@
for (var/child_tag in child_names)
airlocks[i++] = list("name"=child_names[child_tag], "override_enabled"=(docking_program.children_override[child_tag] == "enabled"))
data = list(
. = list(
"docking_status" = docking_program.get_docking_status(),
"airlocks" = airlocks,
"internalTemplateName" = "DockingConsoleMulti",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "multi_docking_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/docking_port_multi/Topic(href, href_list)
return 1 // Apparently we swallow all input (this is corrected legacy code)
/obj/machinery/embedded_controller/radio/docking_port_multi/tgui_act(action, params)
return // Apparently we swallow all input (this is corrected legacy code)
//a docking port based on an airlock
// This is the actual controller that will be commanded by the master defined above
@@ -50,12 +39,13 @@
program = /datum/computer/file/embedded_program/airlock/multi_docking
var/master_tag //for mapping
tag_secure = 1
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "toggle_override")
/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/tgui_data(mob/user)
var/datum/computer/file/embedded_program/airlock/multi_docking/airlock_program = program // Cast to proper type
data = list(
. = list(
"chamber_pressure" = round(airlock_program.memory["chamber_sensor_pressure"]),
"exterior_status" = airlock_program.memory["exterior_status"],
"interior_status" = airlock_program.memory["interior_status"],
@@ -63,42 +53,9 @@
"docking_status" = airlock_program.master_status,
"airlock_disabled" = (airlock_program.docking_enabled && !airlock_program.override_enabled),
"override_enabled" = airlock_program.override_enabled,
"internalTemplateName" = "AirlockConsoleDocking",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "docking_airlock_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/Topic(href, href_list)
if((. = ..()))
return
var/clean = 0
switch(href_list["command"]) //anti-HTML-hacking checks
if("cycle_ext")
clean = 1
if("cycle_int")
clean = 1
if("force_ext")
clean = 1
if("force_int")
clean = 1
if("abort")
clean = 1
if("toggle_override")
clean = 1
if(clean)
program.receive_user_command(href_list["command"])
return 1
/*** DEBUG VERBS ***
/datum/computer/file/embedded_program/docking/multi/proc/print_state()
@@ -4,6 +4,7 @@
use_power = USE_POWER_IDLE
idle_power_usage = 10
var/datum/computer/file/embedded_program/program //the currently executing program
var/list/valid_actions = list()
var/on = 1
/obj/machinery/embedded_controller/Initialize()
@@ -24,18 +25,19 @@
if(program)
program.receive_signal(signal, receive_method, receive_param)
//spawn(5) program.process() //no, program.process sends some signals and machines respond and we here again and we lag -rastaf0
/obj/machinery/embedded_controller/Topic(href, href_list)
if((. = ..()))
return
/obj/machinery/embedded_controller/Topic()
. = ..()
stack_trace("WARNING: Embedded controller [src] ([type]) had Topic() called unexpectedly. Please report this.")
/obj/machinery/embedded_controller/tgui_act(action, params)
if(..())
return TRUE
if(LAZYLEN(valid_actions))
if(action in valid_actions)
program.receive_user_command(action)
if(usr)
usr.set_machine(src)
src.add_fingerprint(usr)
// We would now pass it to the program, except that some of our embedded controller types want to block certain commands.
// Until/unless that is refactored differently, we rely on subtypes to pass it on.
//if(program)
// return program.receive_user_command(href_list["command"])
add_fingerprint(usr)
/obj/machinery/embedded_controller/process()
if(program)
@@ -44,19 +46,23 @@
update_icon()
/obj/machinery/embedded_controller/attack_ai(mob/user as mob)
src.ui_interact(user)
tgui_interact(user)
/obj/machinery/embedded_controller/attack_hand(mob/user as mob)
if(!user.IsAdvancedToolUser())
return 0
src.ui_interact(user)
tgui_interact(user)
/obj/machinery/embedded_controller/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "EmbeddedController", src)
ui.open()
//
// Embedded controller with a radio! (Most things (All things?) use this)
//
/obj/machinery/embedded_controller/radio
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "airlock_control_standby"
@@ -3,42 +3,18 @@
name = "docking hatch controller"
program = /datum/computer/file/embedded_program/docking/simple
var/tag_door
valid_actions = list("force_door", "toggle_override")
/obj/machinery/embedded_controller/radio/simple_docking_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
/obj/machinery/embedded_controller/radio/simple_docking_controller/tgui_data(mob/user)
var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type
data = list(
. = list(
"docking_status" = docking_program.get_docking_status(),
"override_enabled" = docking_program.override_enabled,
"door_state" = docking_program.memory["door_status"]["state"],
"door_lock" = docking_program.memory["door_status"]["lock"],
"exterior_status" = docking_program.memory["door_status"],
"internalTemplateName" = "DockingConsoleSimple",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "simple_docking_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/simple_docking_controller/Topic(href, href_list)
if((. = ..()))
return
var/clean = 0
switch(href_list["command"]) //anti-HTML-hacking checks
if("force_door")
clean = 1
if("toggle_override")
clean = 1
if(clean)
program.receive_user_command(href_list["command"])
return
//A docking controller program for a simple door based docking port
/datum/computer/file/embedded_program/docking/simple
var/tag_door
+48 -47
View File
@@ -94,17 +94,25 @@
// Proc: attack_hand()
// Parameters: 1 (user - the person clicking on the machine)
// Description: Opens the NanoUI interface with ui_interact()
// Description: Opens the TGUI interface with tgui_interact()
/obj/machinery/exonet_node/attack_hand(mob/user)
ui_interact(user)
tgui_interact(user)
// Proc: ui_interact()
// Parameters: 4 (standard NanoUI arguments)
// Proc: tgui_interact()
// Parameters: 2 (user - person interacting with the UI, ui - the UI itself, in a refresh)
// Description: Handles opening the TGUI interface
/obj/machinery/exonet_node/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ExonetNode", src)
ui.open()
// Proc: tgui_data()
// Parameters: 1 (user - the person using the interface)
// Description: Allows the user to turn the machine on or off, or open or close certain 'ports' for things like external PDA messages, newscasters, etc.
/obj/machinery/exonet_node/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/exonet_node/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/data[0]
var/list/data = list()
data["on"] = toggle ? 1 : 0
data["allowPDAs"] = allow_external_PDAs
@@ -112,53 +120,46 @@
data["allowNewscasters"] = allow_external_newscasters
data["logs"] = logs
return data
// 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)
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, "exonet_node.tmpl", "Exonet Node #157", 400, 400)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
// Proc: Topic()
// Parameters: 2 (standard Topic arguments)
// Description: Responds to button presses on the NanoUI interface.
/obj/machinery/exonet_node/Topic(href, href_list)
// Proc: tgui_act()
// Parameters: 2 (standard tgui_act arguments)
// Description: Responds to button presses on the TGUI interface.
/obj/machinery/exonet_node/tgui_act(action, params)
if(..())
return 1
if(href_list["toggle_power"])
toggle = !toggle
update_power()
if(!toggle)
var/msg = "[usr.client.key] ([usr]) has turned [src] off, at [x],[y],[z]."
message_admins(msg)
log_game(msg)
return TRUE
if(href_list["toggle_PDA_port"])
allow_external_PDAs = !allow_external_PDAs
switch(action)
if("toggle_power")
. = TRUE
toggle = !toggle
update_power()
if(!toggle)
var/msg = "[usr.client.key] ([usr]) has turned [src] off, at [x],[y],[z]."
message_admins(msg)
log_game(msg)
if(href_list["toggle_communicator_port"])
allow_external_communicators = !allow_external_communicators
if(!allow_external_communicators)
var/msg = "[usr.client.key] ([usr]) has turned [src]'s communicator port off, at [x],[y],[z]."
message_admins(msg)
log_game(msg)
if("toggle_PDA_port")
. = TRUE
allow_external_PDAs = !allow_external_PDAs
if(href_list["toggle_newscaster_port"])
allow_external_newscasters = !allow_external_newscasters
if(!allow_external_newscasters)
var/msg = "[usr.client.key] ([usr]) has turned [src]'s newscaster port off, at [x],[y],[z]."
message_admins(msg)
log_game(msg)
if("toggle_communicator_port")
. = TRUE
allow_external_communicators = !allow_external_communicators
if(!allow_external_communicators)
var/msg = "[usr.client.key] ([usr]) has turned [src]'s communicator port off, at [x],[y],[z]."
message_admins(msg)
log_game(msg)
if("toggle_newscaster_port")
. = TRUE
allow_external_newscasters = !allow_external_newscasters
if(!allow_external_newscasters)
var/msg = "[usr.client.key] ([usr]) has turned [src]'s newscaster port off, at [x],[y],[z]."
message_admins(msg)
log_game(msg)
update_icon()
SSnanoui.update_uis(src)
add_fingerprint(usr)
// Proc: get_exonet_node()
+15 -67
View File
@@ -27,6 +27,10 @@ FIRE ALARM
/obj/machinery/firealarm/alarms_hidden
alarms_hidden = TRUE
/obj/machinery/firealarm/examine()
. = ..()
. += "Current security level: [seclevel]"
/obj/machinery/firealarm/Initialize()
. = ..()
if(z in using_map.contact_levels)
@@ -127,81 +131,24 @@ FIRE ALARM
if(user.stat || stat & (NOPOWER | BROKEN))
return
user.set_machine(src)
var/area/A = src.loc
var/d1
var/d2
if(istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon))
A = A.loc
if(A.fire)
d1 = text("<A href='?src=\ref[];reset=1'>Reset - Lockdown</A>", src)
else
d1 = text("<A href='?src=\ref[];alarm=1'>Alarm - Lockdown</A>", src)
if(timing)
d2 = text("<A href='?src=\ref[];time=0'>Stop Time Lock</A>", src)
else
d2 = text("<A href='?src=\ref[];time=1'>Initiate Time Lock</A>", src)
var/second = round(time) % 60
var/minute = (round(time) - second) / 60
var/dat = "<HTML><HEAD></HEAD><BODY><TT><B>Fire alarm</B> [d1]\n<HR>The current alert level is: <b>[get_security_level()]</b><br><br>\nTimer System: [d2]<BR>\nTime Left: [(minute ? "[minute]:" : null)][second] <A href='?src=\ref[src];tp=-30'>-</A> <A href='?src=\ref[src];tp=-1'>-</A> <A href='?src=\ref[src];tp=1'>+</A> <A href='?src=\ref[src];tp=30'>+</A>\n</TT></BODY></HTML>"
user << browse(dat, "window=firealarm")
onclose(user, "firealarm")
add_fingerprint(user)
var/area/A = get_area(src)
if(A.fire)
reset(user)
else
A = A.loc
if(A.fire)
d1 = text("<A href='?src=\ref[];reset=1'>[]</A>", src, stars("Reset - Lockdown"))
else
d1 = text("<A href='?src=\ref[];alarm=1'>[]</A>", src, stars("Alarm - Lockdown"))
if(timing)
d2 = text("<A href='?src=\ref[];time=0'>[]</A>", src, stars("Stop Time Lock"))
else
d2 = text("<A href='?src=\ref[];time=1'>[]</A>", src, stars("Initiate Time Lock"))
var/second = round(time) % 60
var/minute = (round(time) - second) / 60
var/dat = "<HTML><HEAD></HEAD><BODY><TT><B>[stars("Fire alarm")]</B> [d1]\n<HR><b>The current alert level is: [stars(get_security_level())]</b><br><br>\nTimer System: [d2]<BR>\nTime Left: [(minute ? text("[]:", minute) : null)][second] <A href='?src=\ref[src];tp=-30'>-</A> <A href='?src=\ref[src];tp=-1'>-</A> <A href='?src=\ref[src];tp=1'>+</A> <A href='?src=\ref[src];tp=30'>+</A>\n</TT></BODY></HTML>"
user << browse(dat, "window=firealarm")
onclose(user, "firealarm")
return
alarm(0, user)
/obj/machinery/firealarm/Topic(href, href_list)
..()
if(usr.stat || stat & (BROKEN | NOPOWER))
return
if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
if(href_list["reset"])
reset()
else if(href_list["alarm"])
alarm()
else if(href_list["time"])
timing = text2num(href_list["time"])
last_process = world.timeofday
START_PROCESSING(SSobj, src)
else if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
time = min(max(round(time), 0), 120)
updateUsrDialog()
add_fingerprint(usr)
else
usr << browse(null, "window=firealarm")
return
return
/obj/machinery/firealarm/proc/reset()
/obj/machinery/firealarm/proc/reset(mob/user)
if(!(working))
return
var/area/area = get_area(src)
for(var/obj/machinery/firealarm/FA in area)
fire_alarm.clearAlarm(src.loc, FA)
update_icon()
return
if(user)
log_game("[user] reset a fire alarm at [COORD(src)]")
/obj/machinery/firealarm/proc/alarm(var/duration = 0)
/obj/machinery/firealarm/proc/alarm(var/duration = 0, mob/user)
if(!(working))
return
var/area/area = get_area(src)
@@ -209,7 +156,8 @@ FIRE ALARM
fire_alarm.triggerAlarm(loc, FA, duration, hidden = alarms_hidden)
update_icon()
playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4)
return
if(user)
log_game("[user] triggered a fire alarm at [COORD(src)]")
/obj/machinery/firealarm/proc/set_security_level(var/newlevel)
if(seclevel != newlevel)
+76 -93
View File
@@ -15,69 +15,94 @@
"Fuel" = PIPING_LAYER_FUEL,
"Aux" = PIPING_LAYER_AUX
)
var/disposals = FALSE
// TODO - Its about time to make this NanoUI don't we think?
/obj/machinery/pipedispenser/attack_hand(var/mob/user as mob)
if((. = ..()))
return
src.interact(user)
tgui_interact(user)
/obj/machinery/pipedispenser/interact(mob/user)
user.set_machine(src)
/obj/machinery/pipedispenser/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/pipes),
)
var/list/lines = list()
for(var/category in atmos_pipe_recipes)
lines += "<b>[category]:</b><BR>"
if(category == "Pipes")
for(var/pipename in pipe_layers)
var/pipelayer = pipe_layers[pipename]
lines += "<a class='[p_layer == pipelayer ? "linkOn" : "linkOff"]' href='?src=\ref[src];setlayer=[pipelayer]'>[pipename]</a> "
lines += "<br>"
for(var/datum/pipe_recipe/PI in atmos_pipe_recipes[category])
lines += PI.Render(src)
var/dat = lines.Join()
var/datum/browser/popup = new(user, "pipedispenser", name, 300, 800, src)
popup.set_content("<TT>[dat]</TT>")
popup.open()
return
/obj/machinery/pipedispenser/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PipeDispenser", name)
ui.open()
/obj/machinery/pipedispenser/Topic(href, href_list)
/obj/machinery/pipedispenser/tgui_data(mob/user)
var/list/data = list(
"disposals" = disposals,
"p_layer" = p_layer,
"pipe_layers" = pipe_layers,
)
var/list/recipes
if(disposals)
recipes = GLOB.disposal_pipe_recipes
else
recipes = GLOB.atmos_pipe_recipes
for(var/c in recipes)
var/list/cat = recipes[c]
var/list/r = list()
for(var/i in 1 to cat.len)
var/datum/pipe_recipe/info = cat[i]
r += list(list("pipe_name" = info.name, "pipe_index" = i))
data["categories"] += list(list("cat_name" = c, "recipes" = r))
return data
/obj/machinery/pipedispenser/tgui_act(action, params)
if(..())
return
return TRUE
if(unwrenched || !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=pipedispenser")
usr.unset_machine(src)
return
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["setlayer"])
var/new_pipe_layer = text2num(href_list["setlayer"])
if(isnum(new_pipe_layer))
p_layer = new_pipe_layer
updateDialog()
else if(href_list["makepipe"])
if(!wait)
var/obj/machinery/atmospherics/p_type = text2path(href_list["makepipe"])
var/p_dir = text2num(href_list["dir"])
var/pi_type = initial(p_type.construction_type)
var/obj/item/pipe/P = new pi_type(src.loc, p_type, p_dir)
P.setPipingLayer(p_layer)
P.add_fingerprint(usr)
wait = 1
spawn(10)
wait = 0
else if(href_list["makemeter"])
if(!wait)
new /obj/item/pipe_meter(/*usr.loc*/ src.loc)
wait = 1
spawn(15)
wait = 0
return
return TRUE
. = TRUE
switch(action)
if("p_layer")
p_layer = text2num(params["p_layer"])
if("dispense_pipe")
if(!wait)
var/list/recipes
if(disposals)
recipes = GLOB.disposal_pipe_recipes
else
recipes = GLOB.atmos_pipe_recipes
var/datum/pipe_recipe/recipe = recipes[params["category"]][text2num(params["pipe_type"])]
var/obj/created_object = null
if(istype(recipe, /datum/pipe_recipe/pipe))
var/datum/pipe_recipe/pipe/R = recipe
created_object = new R.construction_type(loc, recipe.pipe_type, NORTH)
var/obj/item/pipe/P = created_object
P.setPipingLayer(p_layer)
else if(istype(recipe, /datum/pipe_recipe/disposal))
var/datum/pipe_recipe/disposal/D = recipe
var/obj/structure/disposalconstruct/C = new(loc, D.pipe_type, NORTH, 0, D.subtype ? D.subtype : 0)
C.update()
created_object = C
else if(istype(recipe, /datum/pipe_recipe/meter))
created_object = new recipe.pipe_type(loc)
else
log_runtime(EXCEPTION("Warning: [usr] attempted to spawn pipe recipe type by params [json_encode(params)] ([recipe] [recipe?.type]), but it was not allowed by this machine ([src] [type])"))
return
created_object.add_fingerprint(usr)
wait = TRUE
VARSET_IN(src, wait, FALSE, 15)
/obj/machinery/pipedispenser/attackby(var/obj/item/W as obj, var/mob/user as mob)
src.add_fingerprint(usr)
if (istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter))
to_chat(usr, "<span class='notice'>You put [W] back to [src].</span>")
to_chat(usr, "<span class='notice'>You put [W] back in [src].</span>")
user.drop_item()
qdel(W)
return
@@ -117,15 +142,7 @@
icon_state = "pipe_d"
density = 1
anchored = 1.0
/*
//Allow you to push disposal pipes into it (for those with density 1)
/obj/machinery/pipedispenser/disposal/Crossed(var/obj/structure/disposalconstruct/pipe as obj)
if(istype(pipe) && !pipe.anchored)
qdel(pipe)
Nah
*/
disposals = TRUE
//Allow you to drag-drop disposal pipes into it
/obj/machinery/pipedispenser/disposal/MouseDrop_T(var/obj/structure/disposalconstruct/pipe as obj, mob/usr as mob)
@@ -138,43 +155,9 @@ Nah
if (pipe.anchored)
return
to_chat(usr, "<span class='notice'>You shove [pipe] back in [src].</span>")
qdel(pipe)
/obj/machinery/pipedispenser/disposal/interact(mob/user)
user.set_machine(src)
var/list/lines = list()
for(var/category in disposal_pipe_recipes)
lines += "<b>[category]:</b><BR>"
for(var/datum/pipe_recipe/PI in disposal_pipe_recipes[category])
lines += PI.Render(src)
var/dat = lines.Join()
var/datum/browser/popup = new(user, "pipedispenser", name, 300, 500, src)
popup.set_content("<TT>[dat]</TT>")
popup.open()
return
/obj/machinery/pipedispenser/disposal/Topic(href, href_list)
if(href_list["makepipe"] || href_list["setlayer"] || href_list["makemeter"]) // Asking the disposal machine to do atmos stuff?
return // That's a no no.
if((. = ..()))
return
if(href_list["dmake"])
if(unwrenched || !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=pipedispenser")
return
if(!wait)
var/ptype = text2num(href_list["dmake"])
var/pdir = (href_list["dir"] ? text2num(href_list["dir"]) : NORTH)
var/psub = (href_list["sort"] ? text2num(href_list["sort"]) : 0)
var/obj/structure/disposalconstruct/C = new (src.loc, ptype, pdir, 0, psub)
C.add_fingerprint(usr)
C.update()
wait = 1
VARSET_IN(src, wait, FALSE, 15)
return
// adding a pipe dispensers that spawn unhooked from the ground
/obj/machinery/pipedispenser/orderable
anchored = 0
+103 -69
View File
@@ -2,75 +2,69 @@
// Recipies for Pipe Dispenser and (someday) the RPD
//
var/global/list/atmos_pipe_recipes = null
var/global/list/disposal_pipe_recipes = null
var/global/list/all_pipe_recipes = null // VOREStation Add
GLOBAL_LIST_INIT(atmos_pipe_recipes, list(
"Pipes" = list(
new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple),
new /datum/pipe_recipe/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold),
new /datum/pipe_recipe/pipe("Manual Valve", /obj/machinery/atmospherics/valve),
new /datum/pipe_recipe/pipe("Digital Valve", /obj/machinery/atmospherics/valve/digital),
new /datum/pipe_recipe/pipe("Pipe cap", /obj/machinery/atmospherics/pipe/cap),
new /datum/pipe_recipe/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w),
new /datum/pipe_recipe/pipe("Manual T-Valve", /obj/machinery/atmospherics/tvalve),
new /datum/pipe_recipe/pipe("Digital T-Valve", /obj/machinery/atmospherics/tvalve/digital),
new /datum/pipe_recipe/pipe("Upward Pipe", /obj/machinery/atmospherics/pipe/zpipe/up),
new /datum/pipe_recipe/pipe("Downward Pipe", /obj/machinery/atmospherics/pipe/zpipe/down),
new /datum/pipe_recipe/pipe("Universal Pipe Adaptor",/obj/machinery/atmospherics/pipe/simple/visible/universal),
),
"Devices" = list(
new /datum/pipe_recipe/pipe("Connector", /obj/machinery/atmospherics/portables_connector),
new /datum/pipe_recipe/pipe("Unary Vent", /obj/machinery/atmospherics/unary/vent_pump),
new /datum/pipe_recipe/pipe("Aux Vent", /obj/machinery/atmospherics/unary/vent_pump/aux),
new /datum/pipe_recipe/pipe("Passive Vent", /obj/machinery/atmospherics/pipe/vent),
new /datum/pipe_recipe/pipe("Injector", /obj/machinery/atmospherics/unary/outlet_injector),
new /datum/pipe_recipe/pipe("Gas Pump", /obj/machinery/atmospherics/binary/pump),
new /datum/pipe_recipe/pipe("Fuel Pump", /obj/machinery/atmospherics/binary/pump/fuel),
new /datum/pipe_recipe/pipe("Aux Pump", /obj/machinery/atmospherics/binary/pump/aux),
new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate),
new /datum/pipe_recipe/pipe("High Power Gas Pump", /obj/machinery/atmospherics/binary/pump/high_power),
new /datum/pipe_recipe/pipe("Automatic Shutoff Valve",/obj/machinery/atmospherics/valve/shutoff),
new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber),
new /datum/pipe_recipe/meter("Meter"),
new /datum/pipe_recipe/pipe("Gas Filter", /obj/machinery/atmospherics/trinary/atmos_filter),
new /datum/pipe_recipe/pipe("Gas Mixer", /obj/machinery/atmospherics/trinary/mixer),
new /datum/pipe_recipe/pipe("Gas Mixer 'T'", /obj/machinery/atmospherics/trinary/mixer/t_mixer),
new /datum/pipe_recipe/pipe("Omni Gas Mixer", /obj/machinery/atmospherics/omni/mixer),
new /datum/pipe_recipe/pipe("Omni Gas Filter", /obj/machinery/atmospherics/omni/atmos_filter),
),
"Heat Exchange" = list(
new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/heat_exchanging),
new /datum/pipe_recipe/pipe("Junction", /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction),
new /datum/pipe_recipe/pipe("Heat Exchanger", /obj/machinery/atmospherics/unary/heat_exchanger),
),
"Insulated pipes" = list(
new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/insulated),
)
))
/hook/startup/proc/init_pipe_recipes()
global.atmos_pipe_recipes = list(
"Pipes" = list(
new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple),
new /datum/pipe_recipe/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold),
new /datum/pipe_recipe/pipe("Manual Valve", /obj/machinery/atmospherics/valve),
new /datum/pipe_recipe/pipe("Digital Valve", /obj/machinery/atmospherics/valve/digital),
new /datum/pipe_recipe/pipe("Pipe cap", /obj/machinery/atmospherics/pipe/cap),
new /datum/pipe_recipe/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w),
new /datum/pipe_recipe/pipe("Manual T-Valve", /obj/machinery/atmospherics/tvalve),
new /datum/pipe_recipe/pipe("Digital T-Valve", /obj/machinery/atmospherics/tvalve/digital),
new /datum/pipe_recipe/pipe("Upward Pipe", /obj/machinery/atmospherics/pipe/zpipe/up),
new /datum/pipe_recipe/pipe("Downward Pipe", /obj/machinery/atmospherics/pipe/zpipe/down),
new /datum/pipe_recipe/pipe("Universal Pipe Adaptor",/obj/machinery/atmospherics/pipe/simple/visible/universal),
),
"Devices" = list(
new /datum/pipe_recipe/pipe("Connector", /obj/machinery/atmospherics/portables_connector),
new /datum/pipe_recipe/pipe("Unary Vent", /obj/machinery/atmospherics/unary/vent_pump),
new /datum/pipe_recipe/pipe("Aux Vent", /obj/machinery/atmospherics/unary/vent_pump/aux),
new /datum/pipe_recipe/pipe("Passive Vent", /obj/machinery/atmospherics/pipe/vent),
new /datum/pipe_recipe/pipe("Injector", /obj/machinery/atmospherics/unary/outlet_injector),
new /datum/pipe_recipe/pipe("Gas Pump", /obj/machinery/atmospherics/binary/pump),
new /datum/pipe_recipe/pipe("Fuel Pump", /obj/machinery/atmospherics/binary/pump/fuel),
new /datum/pipe_recipe/pipe("Aux Pump", /obj/machinery/atmospherics/binary/pump/aux),
new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate),
new /datum/pipe_recipe/pipe("High Power Gas Pump", /obj/machinery/atmospherics/binary/pump/high_power),
new /datum/pipe_recipe/pipe("Automatic Shutoff Valve",/obj/machinery/atmospherics/valve/shutoff),
new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber),
new /datum/pipe_recipe/meter("Meter"),
new /datum/pipe_recipe/pipe("Gas Filter", /obj/machinery/atmospherics/trinary/atmos_filter),
new /datum/pipe_recipe/pipe("Gas Mixer", /obj/machinery/atmospherics/trinary/mixer),
new /datum/pipe_recipe/pipe("Gas Mixer 'T'", /obj/machinery/atmospherics/trinary/mixer/t_mixer),
new /datum/pipe_recipe/pipe("Omni Gas Mixer", /obj/machinery/atmospherics/omni/mixer),
new /datum/pipe_recipe/pipe("Omni Gas Filter", /obj/machinery/atmospherics/omni/atmos_filter),
),
"Heat Exchange" = list(
new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/heat_exchanging),
new /datum/pipe_recipe/pipe("Junction", /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction),
new /datum/pipe_recipe/pipe("Heat Exchanger", /obj/machinery/atmospherics/unary/heat_exchanger),
),
"Insulated pipes" = list(
new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/insulated),
)
GLOBAL_LIST_INIT(disposal_pipe_recipes, list(
"Disposal Pipes" = list(
new /datum/pipe_recipe/disposal("Pipe", DISPOSAL_PIPE_STRAIGHT, "conpipe-s", PIPE_STRAIGHT),
new /datum/pipe_recipe/disposal("Bent Pipe", DISPOSAL_PIPE_CORNER, "conpipe-c"),
new /datum/pipe_recipe/disposal("Junction", DISPOSAL_PIPE_JUNCTION, "conpipe-j1", PIPE_TRIN_M),
new /datum/pipe_recipe/disposal("Y-Junction", DISPOSAL_PIPE_JUNCTION_Y, "conpipe-y"),
new /datum/pipe_recipe/disposal("Sort Junction", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_NORMAL),
new /datum/pipe_recipe/disposal("Sort Junction (Wildcard)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_WILDCARD),
new /datum/pipe_recipe/disposal("Sort Junction (Untagged)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_UNTAGGED),
new /datum/pipe_recipe/disposal("Tagger", DISPOSAL_PIPE_TAGGER, "pipe-tagger", PIPE_STRAIGHT),
new /datum/pipe_recipe/disposal("Tagger (Partial)", DISPOSAL_PIPE_TAGGER_PARTIAL, "pipe-tagger-partial", PIPE_STRAIGHT),
new /datum/pipe_recipe/disposal("Trunk", DISPOSAL_PIPE_TRUNK, "conpipe-t"),
new /datum/pipe_recipe/disposal("Upwards", DISPOSAL_PIPE_UPWARD, "pipe-u"),
new /datum/pipe_recipe/disposal("Downwards", DISPOSAL_PIPE_DOWNWARD, "pipe-d"),
new /datum/pipe_recipe/disposal("Bin", DISPOSAL_PIPE_BIN, "disposal", PIPE_ONEDIR),
new /datum/pipe_recipe/disposal("Outlet", DISPOSAL_PIPE_OUTLET, "outlet"),
new /datum/pipe_recipe/disposal("Chute", DISPOSAL_PIPE_CHUTE, "intake"),
)
global.disposal_pipe_recipes = list(
"Disposal Pipes" = list(
new /datum/pipe_recipe/disposal("Pipe", DISPOSAL_PIPE_STRAIGHT, "conpipe-s", PIPE_STRAIGHT),
new /datum/pipe_recipe/disposal("Bent Pipe", DISPOSAL_PIPE_CORNER, "conpipe-c"),
new /datum/pipe_recipe/disposal("Junction", DISPOSAL_PIPE_JUNCTION, "conpipe-j1", PIPE_TRIN_M),
new /datum/pipe_recipe/disposal("Y-Junction", DISPOSAL_PIPE_JUNCTION_Y, "conpipe-y"),
new /datum/pipe_recipe/disposal("Sort Junction", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_NORMAL),
new /datum/pipe_recipe/disposal("Sort Junction (Wildcard)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_WILDCARD),
new /datum/pipe_recipe/disposal("Sort Junction (Untagged)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_UNTAGGED),
new /datum/pipe_recipe/disposal("Tagger", DISPOSAL_PIPE_TAGGER, "pipe-tagger", PIPE_STRAIGHT),
new /datum/pipe_recipe/disposal("Tagger (Partial)", DISPOSAL_PIPE_TAGGER_PARTIAL, "pipe-tagger-partial", PIPE_STRAIGHT),
new /datum/pipe_recipe/disposal("Trunk", DISPOSAL_PIPE_TRUNK, "conpipe-t"),
new /datum/pipe_recipe/disposal("Upwards", DISPOSAL_PIPE_UPWARD, "pipe-u"),
new /datum/pipe_recipe/disposal("Downwards", DISPOSAL_PIPE_DOWNWARD, "pipe-d"),
new /datum/pipe_recipe/disposal("Bin", DISPOSAL_PIPE_BIN, "disposal", PIPE_ONEDIR),
new /datum/pipe_recipe/disposal("Outlet", DISPOSAL_PIPE_OUTLET, "outlet"),
new /datum/pipe_recipe/disposal("Chute", DISPOSAL_PIPE_CHUTE, "intake"),
)
)
global.all_pipe_recipes = disposal_pipe_recipes + atmos_pipe_recipes // VOREStation Add
return TRUE
))
//
// New method of handling pipe construction. Instead of numeric constants and a giant switch statement of doom
@@ -83,11 +77,52 @@ var/global/list/all_pipe_recipes = null // VOREStation Add
var/icon_state = null // This tells the RPD what kind of pipe icon to render for the preview.
var/icon_state_m = null // This stores the mirrored version of the regular state (if available).
var/dirtype // If using an RPD, this tells more about what previews to show.
var/pipe_type
// Render an HTML link to select this pipe type. Returns text.
/datum/pipe_recipe/proc/Render(dispenser)
return "<A href='?src=\ref[dispenser]&[Params()]'>[name]</A><BR>"
// Get preview for UIs
/datum/pipe_recipe/proc/get_preview(selected_dir)
var/list/dirs
switch(dirtype)
if(PIPE_STRAIGHT, PIPE_BENDABLE)
dirs = list("[NORTH]" = "Vertical", "[EAST]" = "Horizontal")
if(dirtype == PIPE_BENDABLE)
dirs += list("[NORTHWEST]" = "West to North", "[NORTHEAST]" = "North to East",
"[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South")
if(PIPE_TRINARY)
dirs = list("[NORTH]" = "West South East", "[SOUTH]" = "East North West",
"[EAST]" = "North West South", "[WEST]" = "South East North")
if(PIPE_TRIN_M)
dirs = list("[NORTH]" = "North East South", "[SOUTHWEST]" = "North West South",
"[NORTHEAST]" = "South East North", "[SOUTH]" = "South West North",
"[WEST]" = "West North East", "[SOUTHEAST]" = "West South East",
"[NORTHWEST]" = "East North West", "[EAST]" = "East South West",)
if(PIPE_DIRECTIONAL)
dirs = list("[NORTH]" = "North", "[SOUTH]" = "South", "[WEST]" = "West", "[EAST]" = "East")
if(PIPE_ONEDIR)
dirs = list("[SOUTH]" = name)
if(PIPE_UNARY_FLIPPABLE)
dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West",
"[NORTHEAST]" = "North Flipped", "[SOUTHEAST]" = "East Flipped", "[SOUTHWEST]" = "South Flipped", "[NORTHWEST]" = "West Flipped")
var/list/rows = list()
var/list/row = list("previews" = list())
var/i = 0
for(var/dir in dirs)
var/numdir = text2num(dir)
var/flipped = ((dirtype == PIPE_TRIN_M) || (dirtype == PIPE_UNARY_FLIPPABLE)) && (numdir in GLOB.cornerdirs)
row["previews"] += list(list("selected" = (numdir == selected_dir), "dir" = dir2text(numdir), "dir_name" = dirs[dir], "icon_state" = icon_state, "flipped" = flipped))
if(i++ || dirtype == PIPE_ONEDIR)
rows += list(row)
row = list("previews" = list())
i = 0
return rows
// Parameters for the Topic link returned by Render(). Returns text.
/datum/pipe_recipe/proc/Params()
return ""
@@ -97,7 +132,6 @@ var/global/list/all_pipe_recipes = null // VOREStation Add
//
/datum/pipe_recipe/pipe
var/obj/item/pipe/construction_type // The type PATH to the type of pipe fitting object the recipe makes.
var/obj/machinery/atmospherics/pipe_type // The type PATH of what actual pipe the fitting becomes.
var/paintable = FALSE // If TRUE, allow the RPD to paint this pipe. // VOREStation Add
/datum/pipe_recipe/pipe/New(var/label, var/obj/machinery/atmospherics/path)
@@ -129,6 +163,7 @@ var/global/list/all_pipe_recipes = null // VOREStation Add
/datum/pipe_recipe/meter
dirtype = PIPE_ONEDIR
icon_state = "meter"
pipe_type = /obj/item/pipe_meter
/datum/pipe_recipe/meter/New(label)
name = label
@@ -140,7 +175,6 @@ var/global/list/all_pipe_recipes = null // VOREStation Add
// Subtype for disposal pipes
//
/datum/pipe_recipe/disposal
var/pipe_type // pipe_type is one of the DISPOSAL_PIPE_ ptype constants.
var/subtype // subtype is one of the DISPOSAL_SORT_ constants.
/datum/pipe_recipe/disposal/New(var/label, var/ptype, var/state, dt=PIPE_DIRECTIONAL, var/sort=0)
+56 -56
View File
@@ -11,6 +11,7 @@
var/set_temperature = T0C + 20 //K
var/heating_power = 40000
clicksound = "switch"
interact_offline = TRUE
/obj/machinery/space_heater/New()
..()
@@ -88,75 +89,74 @@
interact(user)
/obj/machinery/space_heater/interact(mob/user as mob)
if(panel_open)
var/dat
dat = "Power cell: "
if(cell)
dat += "<A href='byond://?src=\ref[src];op=cellremove'>Installed</A><BR>"
else
dat += "<A href='byond://?src=\ref[src];op=cellinstall'>Removed</A><BR>"
dat += "Power Level: [cell ? round(cell.percent(),1) : 0]%<BR><BR>"
dat += "Set Temperature: "
dat += "<A href='?src=\ref[src];op=temp;val=-5'>-</A>"
dat += " [set_temperature]K ([set_temperature-T0C]&deg;C)"
dat += "<A href='?src=\ref[src];op=temp;val=5'>+</A><BR>"
user.set_machine(src)
user << browse("<HEAD><TITLE>Space Heater Control Panel</TITLE></HEAD><TT>[dat]</TT>", "window=spaceheater")
onclose(user, "spaceheater")
tgui_interact(user)
else
on = !on
user.visible_message("<span class='notice'>[user] switches [on ? "on" : "off"] the [src].</span>","<span class='notice'>You switch [on ? "on" : "off"] the [src].</span>")
update_icon()
return
/obj/machinery/space_heater/tgui_state(mob/user)
return GLOB.tgui_physical_state
/obj/machinery/space_heater/Topic(href, href_list)
if(usr.stat)
return
if((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
/obj/machinery/space_heater/tgui_status(mob/user)
if(!panel_open)
return STATUS_CLOSE
return ..()
switch(href_list["op"])
/obj/machinery/space_heater/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SpaceHeater", name)
ui.open()
if("temp")
var/value = text2num(href_list["val"])
/obj/machinery/space_heater/tgui_data(mob/user)
var/list/data = list()
// limit to 0-90 degC
set_temperature = dd_range(T0C, T0C + 90, set_temperature + value)
data["cell"] = !!cell
data["power"] = round(cell?.percent(), 1)
data["temp"] = set_temperature
data["minTemp"] = T0C
data["maxTemp"] = T0C + 90
if("cellremove")
if(panel_open && cell && !usr.get_active_hand())
usr.visible_message("<span class='notice'>\The [usr] removes \the [cell] from \the [src].</span>", "<span class='notice'>You remove \the [cell] from \the [src].</span>")
cell.update_icon()
usr.put_in_hands(cell)
cell.add_fingerprint(usr)
cell = null
return data
/obj/machinery/space_heater/tgui_act(action, params)
if(..())
return TRUE
if(!panel_open)
return FALSE
switch(action)
if("temp")
// limit to 0-90 degC
set_temperature = clamp(text2num(params["newtemp"]), T0C, T0C + 90)
. = TRUE
if("cellremove")
if(cell && !usr.get_active_hand())
usr.visible_message("<span class='notice'>[usr] removes [cell] from [src].</span>", "<span class='notice'>You remove [cell] from [src].</span>")
cell.update_icon()
usr.put_in_hands(cell)
cell.add_fingerprint(usr)
cell = null
power_change()
. = TRUE
if("cellinstall")
if(!cell)
var/obj/item/weapon/cell/C = usr.get_active_hand()
if(istype(C))
usr.drop_item()
cell = C
C.loc = src
C.add_fingerprint(usr)
power_change()
if("cellinstall")
if(panel_open && !cell)
var/obj/item/weapon/cell/C = usr.get_active_hand()
if(istype(C))
usr.drop_item()
cell = C
C.loc = src
C.add_fingerprint(usr)
power_change()
usr.visible_message("<span class='notice'>[usr] inserts \the [C] into \the [src].</span>", "<span class='notice'>You insert \the [C] into \the [src].</span>")
updateDialog()
else
usr << browse(null, "window=spaceheater")
usr.unset_machine()
return
usr.visible_message("<span class='notice'>[usr] inserts \the [C] into \the [src].</span>", "<span class='notice'>You insert \the [C] into \the [src].</span>")
. = TRUE
/obj/machinery/space_heater/process()
if(on)
+185 -190
View File
@@ -83,114 +83,93 @@
return
return
/obj/machinery/suit_storage_unit/attack_hand(mob/user as mob)
var/dat
/obj/machinery/suit_storage_unit/attack_hand(mob/user)
if(..())
return
if(stat & NOPOWER)
return
if(!user.IsAdvancedToolUser())
return 0
if(panelopen) //The maintenance panel is open. Time for some shady stuff
dat+= "<HEAD><TITLE>Suit storage unit: Maintenance panel</TITLE></HEAD>"
dat+= "<Font color ='black'><B>Maintenance panel controls</B></font><HR>"
dat+= "<font color ='grey'>The panel is ridden with controls, button and meters, labeled in strange signs and symbols that <BR>you cannot understand. Probably the manufactoring world's language.<BR> Among other things, a few controls catch your eye.</font><BR><BR>"
dat+= text("<font color ='black'>A small dial with a small lambda symbol on it. It's pointing towards a gauge that reads []</font>.<BR> <font color='blue'><A href='?src=\ref[];toggleUV=1'> Turn towards []</A></font><BR>",(issuperUV ? "15nm" : "185nm"),src,(issuperUV ? "185nm" : "15nm"))
dat+= text("<font color ='black'>A thick old-style button, with 2 grimy LED lights next to it. The [] LED is on.</font><BR><font color ='blue'><A href='?src=\ref[];togglesafeties=1'>Press button</a></font>",(safetieson? "<font color='green'><B>GREEN</B></font>" : "<font color='red'><B>RED</B></font>"),src)
dat+= text("<HR><BR><A href='?src=\ref[];mach_close=suit_storage_unit'>Close panel</A>", user)
//user << browse(dat, "window=ssu_m_panel;size=400x500")
//onclose(user, "ssu_m_panel")
else if(isUV) //The thing is running its cauterisation cycle. You have to wait.
dat += "<HEAD><TITLE>Suit storage unit</TITLE></HEAD>"
dat+= "<font color ='red'><B>Unit is cauterising contents with selected UV ray intensity. Please wait.</font></B><BR>"
//dat+= "<font colr='black'><B>Cycle end in: [cycletimeleft()] seconds. </font></B>"
//user << browse(dat, "window=ssu_cycling_panel;size=400x500")
//onclose(user, "ssu_cycling_panel")
tgui_interact(user)
/obj/machinery/suit_storage_unit/tgui_state(mob/user)
return GLOB.tgui_notcontained_state
/obj/machinery/suit_storage_unit/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SuitStorageUnit", name)
ui.open()
/obj/machinery/suit_storage_unit/tgui_data()
var/list/data = list()
data["broken"] = isbroken
data["panelopen"] = panelopen
data["locked"] = islocked
data["open"] = isopen
data["safeties"] = safetieson
data["uv_active"] = isUV
data["uv_super"] = issuperUV
if(HELMET)
data["helmet"] = HELMET.name
else
if(!isbroken)
dat+= "<HEAD><TITLE>Suit storage unit</TITLE></HEAD>"
dat+= "<font color='blue'><font size = 4><B>U-Stor-It Suit Storage Unit, model DS1900</B></FONT><BR>"
dat+= "<B>Welcome to the Unit control panel.</B></FONT><HR>"
dat+= text("<font color='black'>Helmet storage compartment: <B>[]</B></font><BR>",(HELMET ? HELMET.name : "</font><font color ='grey'>No helmet detected."))
if(HELMET && isopen)
dat+=text("<A href='?src=\ref[];dispense_helmet=1'>Dispense helmet</A><BR>",src)
dat+= text("<font color='black'>Suit storage compartment: <B>[]</B></font><BR>",(SUIT ? SUIT.name : "</font><font color ='grey'>No exosuit detected."))
if(SUIT && isopen)
dat+=text("<A href='?src=\ref[];dispense_suit=1'>Dispense suit</A><BR>",src)
dat+= text("<font color='black'>Breathmask storage compartment: <B>[]</B></font><BR>",(MASK ? MASK.name : "</font><font color ='grey'>No breathmask detected."))
if(MASK && isopen)
dat+=text("<A href='?src=\ref[];dispense_mask=1'>Dispense mask</A><BR>",src)
if(OCCUPANT)
dat+= "<HR><B><font color ='red'>WARNING: Biological entity detected inside the Unit's storage. Please remove.</B></font><BR>"
dat+= "<A href='?src=\ref[src];eject_guy=1'>Eject extra load</A>"
dat+= text("<HR><font color='black'>Unit is: [] - <A href='?src=\ref[];toggle_open=1'>[] Unit</A></font> ",(isopen ? "Open" : "Closed"),src,(isopen ? "Close" : "Open"))
if(isopen)
dat+="<HR>"
else
dat+= text(" - <A href='?src=\ref[];toggle_lock=1'><font color ='orange'>*[] Unit*</A></font><HR>",src,(islocked ? "Unlock" : "Lock"))
dat+= text("Unit status: []",(islocked? "<font color ='red'><B>**LOCKED**</B></font><BR>" : "<font color ='green'><B>**UNLOCKED**</B></font><BR>"))
dat+= text("<A href='?src=\ref[];start_UV=1'>Start Disinfection cycle</A><BR>",src)
dat += text("<BR><BR><A href='?src=\ref[];mach_close=suit_storage_unit'>Close control panel</A>", user)
//user << browse(dat, "window=Suit Storage Unit;size=400x500")
//onclose(user, "Suit Storage Unit")
else //Ohhhh shit it's dirty or broken! Let's inform the guy.
dat+= "<HEAD><TITLE>Suit storage unit</TITLE></HEAD>"
dat+= "<font color='maroon'><B>Unit chamber is too contaminated to continue usage. Please call for a qualified individual to perform maintenance.</font></B><BR><BR>"
dat+= text("<HR><A href='?src=\ref[];mach_close=suit_storage_unit'>Close control panel</A>", user)
//user << browse(dat, "window=suit_storage_unit;size=400x500")
//onclose(user, "suit_storage_unit")
data["helmet"] = null
if(SUIT)
data["suit"] = SUIT.name
else
data["suit"] = null
if(MASK)
data["mask"] = MASK.name
else
data["mask"] = null
data["storage"] = null
if(OCCUPANT)
data["occupied"] = TRUE
else
data["occupied"] = FALSE
return data
user << browse(dat, "window=suit_storage_unit;size=400x500")
onclose(user, "suit_storage_unit")
return
/obj/machinery/suit_storage_unit/tgui_act(action, params) //I fucking HATE this proc
if(..() || isUV || isbroken)
return TRUE
/obj/machinery/suit_storage_unit/Topic(href, href_list) //I fucking HATE this proc
if(..())
return
if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
usr.set_machine(src)
if(href_list["toggleUV"])
toggleUV(usr)
updateUsrDialog()
update_icon()
if(href_list["togglesafeties"])
togglesafeties(usr)
updateUsrDialog()
update_icon()
if(href_list["dispense_helmet"])
dispense_helmet(usr)
updateUsrDialog()
update_icon()
if(href_list["dispense_suit"])
dispense_suit(usr)
updateUsrDialog()
update_icon()
if(href_list["dispense_mask"])
dispense_mask(usr)
updateUsrDialog()
update_icon()
if(href_list["toggle_open"])
switch(action)
if("door")
toggle_open(usr)
updateUsrDialog()
update_icon()
if(href_list["toggle_lock"])
toggle_lock(usr)
updateUsrDialog()
update_icon()
if(href_list["start_UV"])
. = TRUE
if("dispense")
switch(params["item"])
if("helmet")
dispense_helmet(usr)
if("mask")
dispense_mask(usr)
if("suit")
dispense_suit(usr)
. = TRUE
if("uv")
start_UV(usr)
updateUsrDialog()
update_icon()
if(href_list["eject_guy"])
. = TRUE
if("lock")
toggle_lock(usr)
. = TRUE
if("eject_guy")
eject_occupant(usr)
updateUsrDialog()
update_icon()
/*if(href_list["refresh"])
updateUsrDialog()*/
. = TRUE
// Panel Open stuff
if(!. && panelopen)
switch(action)
if("toggleUV")
toggleUV(usr)
. = TRUE
if("togglesafeties")
togglesafeties(usr)
. = TRUE
update_icon()
add_fingerprint(usr)
return
/obj/machinery/suit_storage_unit/proc/toggleUV(mob/user as mob)
@@ -847,9 +826,7 @@
return 1
/obj/machinery/suit_cycler/attack_hand(mob/user as mob)
add_fingerprint(user)
if(..() || stat & (BROKEN|NOPOWER))
return
@@ -860,116 +837,134 @@
if(shock(user, 100))
return
user.set_machine(src)
tgui_interact(user)
var/dat = "<HEAD><TITLE>Suit Cycler Interface</TITLE></HEAD>"
/obj/machinery/suit_cycler/tgui_state(mob/user)
return GLOB.tgui_notcontained_state
if(active)
dat+= "<br><font color='red'><B>The [model_text ? "[model_text] " : ""]suit cycler is currently in use. Please wait...</b></font>"
/obj/machinery/suit_cycler/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SuitCycler", name)
ui.open()
else if(locked)
dat += "<br><font color='red'><B>The [model_text ? "[model_text] " : ""]suit cycler is currently locked. Please contact your system administrator.</b></font>"
if(allowed(user))
dat += "<br><a href='?src=\ref[src];toggle_lock=1'>\[unlock unit\]</a>"
/obj/machinery/suit_cycler/tgui_data(mob/user)
var/list/data = list()
data["departments"] = departments
data["species"] = species
data["model_text"] = model_text
data["can_repair"] = can_repair
data["userHasAccess"] = allowed(user)
data["locked"] = locked
data["active"] = active
data["safeties"] = safeties
data["uv_active"] = (active && irradiating > 0)
data["uv_level"] = radiation_level
data["max_uv_level"] = emagged ? 5 : 3
if(helmet)
data["helmet"] = helmet.name
else
dat += "<h1>Suit cycler</h1>"
dat += "<B>Welcome to the [model_text ? "[model_text] " : ""]suit cycler control panel. <a href='?src=\ref[src];toggle_lock=1'>\[lock unit\]</a></B><HR>"
data["helmet"] = null
if(suit)
data["suit"] = suit.name
if(istype(suit) && can_repair)
data["damage"] = suit.damage
else
data["suit"] = null
data["damage"] = null
if(occupant)
data["occupied"] = TRUE
else
data["occupied"] = FALSE
dat += "<h2>Maintenance</h2>"
dat += "<b>Helmet: </b> [helmet ? "\the [helmet]" : "no helmet stored" ]. <A href='?src=\ref[src];eject_helmet=1'>\[eject\]</a><br/>"
dat += "<b>Suit: </b> [suit ? "\the [suit]" : "no suit stored" ]. <A href='?src=\ref[src];eject_suit=1'>\[eject\]</a>"
return data
if(can_repair && suit && istype(suit))
dat += "[(suit.damage ? " <A href='?src=\ref[src];repair_suit=1'>\[repair\]</a>" : "")]"
/obj/machinery/suit_cycler/tgui_act(action, params)
if(..())
return TRUE
dat += "<br/><b>UV decontamination systems:</b> <font color = '[emagged ? "red'>SYSTEM ERROR" : "green'>READY"]</font><br>"
dat += "Output level: [radiation_level]<br>"
dat += "<A href='?src=\ref[src];select_rad_level=1'>\[select power level\]</a> <A href='?src=\ref[src];begin_decontamination=1'>\[begin decontamination cycle\]</a><br><hr>"
switch(action)
if("dispense")
switch(params["item"])
if("helmet")
helmet.forceMove(get_turf(src))
helmet = null
if("suit")
suit.forceMove(get_turf(src))
suit = null
. = TRUE
if("department")
var/choice = params["department"]
if(choice in departments)
target_department = choice
. = TRUE
if("species")
var/choice = params["species"]
if(choice in species)
target_species = choice
. = TRUE
if("radlevel")
radiation_level = clamp(params["radlevel"], 1, emagged ? 5 : 3)
. = TRUE
if("repair_suit")
if(!suit || !can_repair)
return
active = 1
spawn(100)
repair_suit()
finished_job()
. = TRUE
dat += "<h2>Customisation</h2>"
dat += "<b>Target product:</b> <A href='?src=\ref[src];select_department=1'>[target_department]</a>, <A href='?src=\ref[src];select_species=1'>[target_species]</a>."
dat += "<A href='?src=\ref[src];apply_paintjob=1'><br>\[apply customisation routine\]</a><br><hr>"
if("apply_paintjob")
if(!suit && !helmet)
return
active = 1
spawn(100)
apply_paintjob()
finished_job()
. = TRUE
if(panel_open)
wires.Interact(user)
if("lock")
if(allowed(usr))
locked = !locked
to_chat(usr, "You [locked ? "" : "un"]lock \the [src].")
else
to_chat(usr, "<span class='danger'>Access denied.</span>")
. = TRUE
user << browse(dat, "window=suit_cycler")
onclose(user, "suit_cycler")
return
if("eject_guy")
eject_occupant(usr)
. = TRUE
/obj/machinery/suit_cycler/Topic(href, href_list)
if(href_list["eject_suit"])
if(!suit) return
suit.loc = get_turf(src)
suit = null
else if(href_list["eject_helmet"])
if(!helmet) return
helmet.loc = get_turf(src)
helmet = null
else if(href_list["select_department"])
var/choice = input("Please select the target department paintjob.","Suit cycler",null) as null|anything in departments
if(choice) target_department = choice
else if(href_list["select_species"])
var/choice = input("Please select the target species configuration.","Suit cycler",null) as null|anything in species
if(choice) target_species = choice
else if(href_list["select_rad_level"])
var/choices = list(1,2,3)
if(emagged)
choices = list(1,2,3,4,5)
radiation_level = input("Please select the desired radiation level.","Suit cycler",null) as null|anything in choices
else if(href_list["repair_suit"])
if("uv")
if(safeties && occupant)
to_chat(usr, "<span class='danger'>The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.</span>")
return
if(!suit || !can_repair) return
active = 1
spawn(100)
repair_suit()
finished_job()
active = 1
irradiating = 10
else if(href_list["apply_paintjob"])
sleep(10)
if(!suit && !helmet) return
active = 1
spawn(100)
apply_paintjob()
finished_job()
if(helmet)
if(radiation_level > 2)
helmet.decontaminate()
if(radiation_level > 1)
helmet.clean_blood()
else if(href_list["toggle_safties"])
safeties = !safeties
if(suit)
if(radiation_level > 2)
suit.decontaminate()
if(radiation_level > 1)
suit.clean_blood()
else if(href_list["toggle_lock"])
if(allowed(usr))
locked = !locked
to_chat(usr, "You [locked ? "" : "un"]lock \the [src].")
else
to_chat(usr, "<span class='danger'>Access denied.</span>")
else if(href_list["begin_decontamination"])
if(safeties && occupant)
to_chat(usr, "<span class='danger'>The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.</span>")
return
active = 1
irradiating = 10
updateUsrDialog()
sleep(10)
if(helmet)
if(radiation_level > 2)
helmet.decontaminate()
if(radiation_level > 1)
helmet.clean_blood()
if(suit)
if(radiation_level > 2)
suit.decontaminate()
if(radiation_level > 1)
suit.clean_blood()
updateUsrDialog()
return
. = TRUE
/obj/machinery/suit_cycler/process()
+92 -138
View File
@@ -8,187 +8,138 @@
desc = "View communication logs here. Translation not guaranteed."
icon_screen = "comm_logs"
var/screen = 0 // the screen number:
var/list/servers = list() // the servers located by the computer
var/obj/machinery/telecomms/server/SelectedServer
circuit = /obj/item/weapon/circuitboard/comm_server
var/network = "NULL" // the network to probe
var/temp = "" // temporary feedback messages
var/list/temp = null // temporary feedback messages
var/universal_translate = 0 // set to 1 if it can translate nonhuman speech
req_access = list(access_tcomsat)
attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
user.set_machine(src)
var/dat = "<TITLE>Telecommunication Server Monitor</TITLE><center><b>Telecommunications Server Monitor</b></center>"
/obj/machinery/computer/telecomms/server/tgui_data(mob/user)
var/list/data = list()
switch(screen)
data["universal_translate"] = universal_translate
data["network"] = network
data["temp"] = temp
data["servers"] = list()
for(var/obj/machinery/telecomms/T in servers)
data["servers"].Add(list(list(
"id" = T.id,
"name" = T.name,
)))
// --- Main Menu ---
data["selectedServer"] = null
if(SelectedServer)
data["selectedServer"] = list(
"id" = SelectedServer.id,
"totalTraffic" = SelectedServer.totaltraffic,
"logs" = list()
)
if(0)
dat += "<br>[temp]<br>"
dat += "<br>Current Network: <a href='?src=\ref[src];network=1'>[network]</a><br>"
if(servers.len)
dat += "<br>Detected Telecommunication Servers:<ul>"
for(var/obj/machinery/telecomms/T in servers)
dat += "<li><a href='?src=\ref[src];viewserver=[T.id]'>\ref[T] [T.name]</a> ([T.id])</li>"
dat += "</ul>"
dat += "<br><a href='?src=\ref[src];operation=release'>\[Flush Buffer\]</a>"
var/i = 0
for(var/c in SelectedServer.log_entries)
i++
var/datum/comm_log_entry/C = c
// This is necessary to prevent leaking information to the clientside
var/static/list/acceptable_params = list("uspeech", "intelligible", "message", "name", "race", "job", "timecode")
var/list/parameters = list()
for(var/log_param in acceptable_params)
parameters["[log_param]"] = C.parameters["[log_param]"]
else
dat += "<br>No servers detected. Scan for servers: <a href='?src=\ref[src];operation=scan'>\[Scan\]</a>"
data["selectedServer"]["logs"].Add(list(list(
"name" = C.name,
"input_type" = C.input_type,
"id" = i,
"parameters" = parameters,
)))
return data
// --- Viewing Server ---
if(1)
dat += "<br>[temp]<br>"
dat += "<center><a href='?src=\ref[src];operation=mainmenu'>\[Main Menu\]</a> <a href='?src=\ref[src];operation=refresh'>\[Refresh\]</a></center>"
dat += "<br>Current Network: [network]"
dat += "<br>Selected Server: [SelectedServer.id]"
if(SelectedServer.totaltraffic >= 1024)
dat += "<br>Total recorded traffic: [round(SelectedServer.totaltraffic / 1024)] Terrabytes<br><br>"
else
dat += "<br>Total recorded traffic: [SelectedServer.totaltraffic] Gigabytes<br><br>"
dat += "Stored Logs: <ol>"
var/i = 0
for(var/datum/comm_log_entry/C in SelectedServer.log_entries)
i++
// If the log is a speech file
if(C.input_type == "Speech File")
dat += "<li><font color = #008F00>[C.name]</font> <font color = #FF0000><a href='?src=\ref[src];delete=[i]'>\[X\]</a></font><br>"
// -- Determine race of orator --
var/race = C.parameters["race"] // The actual race of the mob
var/language = C.parameters["language"] // The language spoken, or null/""
// -- If the orator is a human, or universal translate is active, OR mob has universal speech on --
if(universal_translate || C.parameters["uspeech"] || C.parameters["intelligible"])
dat += "<u><font color = #18743E>Data type</font></u>: [C.input_type]<br>"
dat += "<u><font color = #18743E>Source</font></u>: [C.parameters["name"]] (Job: [C.parameters["job"]])<br>"
dat += "<u><font color = #18743E>Class</font></u>: [race]<br>"
dat += "<u><font color = #18743E>Contents</font></u>: \"[C.parameters["message"]]\"<br>"
if(language)
dat += "<u><font color = #18743E>Language</font></u>: [language]<br/>"
// -- Orator is not human and universal translate not active --
else
dat += "<u><font color = #18743E>Data type</font></u>: Audio File<br>"
dat += "<u><font color = #18743E>Source</font></u>: <i>Unidentifiable</i><br>"
dat += "<u><font color = #18743E>Class</font></u>: [race]<br>"
dat += "<u><font color = #18743E>Contents</font></u>: <i>Unintelligble</i><br>"
dat += "</li><br>"
else if(C.input_type == "Execution Error")
dat += "<li><font color = #990000>[C.name]</font> <font color = #FF0000><a href='?src=\ref[src];delete=[i]'>\[X\]</a></font><br>"
dat += "<u><font color = #787700>Output</font></u>: \"[C.parameters["message"]]\"<br>"
dat += "</li><br>"
dat += "</ol>"
user << browse(dat, "window=comm_monitor;size=575x400")
onclose(user, "server_control")
temp = ""
/obj/machinery/computer/telecomms/server/attack_hand(mob/user)
if(stat & (BROKEN|NOPOWER))
return
tgui_interact(user)
/obj/machinery/computer/telecomms/server/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TelecommsLogBrowser", name)
ui.open()
/obj/machinery/computer/telecomms/server/tgui_act(action, params)
if(..())
return TRUE
Topic(href, href_list)
if(..())
return
add_fingerprint(usr)
add_fingerprint(usr)
usr.set_machine(src)
if(href_list["viewserver"])
screen = 1
switch(action)
if("view")
for(var/obj/machinery/telecomms/T in servers)
if(T.id == href_list["viewserver"])
if(T.id == params["id"])
SelectedServer = T
break
. = TRUE
if(href_list["operation"])
switch(href_list["operation"])
if("mainmenu")
SelectedServer = null
. = TRUE
if("release")
servers = list()
screen = 0
if("release")
servers = list()
SelectedServer = null
. = TRUE
if("mainmenu")
screen = 0
if("scan")
if(servers.len > 0)
set_temp("FAILED: CANNOT PROBE WHEN BUFFER FULL", "bad")
return TRUE
if("scan")
if(servers.len > 0)
temp = "<font color = #D70B00>- FAILED: CANNOT PROBE WHEN BUFFER FULL -</font>"
for(var/obj/machinery/telecomms/server/T in range(25, src))
if(T.network == network)
servers.Add(T)
else
for(var/obj/machinery/telecomms/server/T in range(25, src))
if(T.network == network)
servers.Add(T)
if(!servers.len)
set_temp("FAILED: UNABLE TO LOCATE SERVERS IN \[[network]\]", "bad")
else
set_temp("[servers.len] SERVERS PROBED & BUFFERED", "good")
. = TRUE
if(!servers.len)
temp = "<font color = #D70B00>- FAILED: UNABLE TO LOCATE SERVERS IN \[[network]\] -</font>"
else
temp = "<font color = #336699>- [servers.len] SERVERS PROBED & BUFFERED -</font>"
screen = 0
if(href_list["delete"])
if(!src.allowed(usr) && !emagged)
if("delete")
if(!allowed(usr) && !emagged)
to_chat(usr, "<span class='warning'>ACCESS DENIED.</span>")
return
if(SelectedServer)
var/datum/comm_log_entry/D = SelectedServer.log_entries[text2num(href_list["delete"])]
temp = "<font color = #336699>- DELETED ENTRY: [D.name] -</font>"
var/datum/comm_log_entry/D = SelectedServer.log_entries[text2num(params["id"])]
set_temp("DELETED ENTRY: [D.name]", "bad")
SelectedServer.log_entries.Remove(D)
qdel(D)
else
temp = "<font color = #D70B00>- FAILED: NO SELECTED MACHINE -</font>"
if(href_list["network"])
set_temp("FAILED: NO SELECTED MACHINE", "bad")
. = TRUE
if("network")
var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
if(newnet && ((usr in range(1, src) || issilicon(usr))))
if(length(newnet) > 15)
temp = "<font color = #D70B00>- FAILED: NETWORK TAG STRING TOO LENGHTLY -</font>"
set_temp("FAILED: NETWORK TAG STRING TOO LENGTHY", "bad")
return TRUE
network = newnet
servers = list()
set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good")
else
network = newnet
screen = 0
servers = list()
temp = "<font color = #336699>- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -</font>"
updateUsrDialog()
return
. = TRUE
if("cleartemp")
temp = null
. = TRUE
/obj/machinery/computer/telecomms/server/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
@@ -197,3 +148,6 @@
to_chat(user, "<span class='notice'>You you disable the security protocols</span>")
src.updateUsrDialog()
return 1
/obj/machinery/computer/telecomms/server/proc/set_temp(var/text, var/color = "average")
temp = list("color" = color, "text" = text)
@@ -11,8 +11,7 @@
#define TELECOMM_Z 3
/obj/machinery/telecomms
var/temp = "" // output message
var/list/temp = null // output message
/obj/machinery/telecomms/attackby(obj/item/P as obj, mob/user as mob)
@@ -40,74 +39,72 @@
/obj/machinery/telecomms/attack_ai(var/mob/user as mob)
attack_hand(user)
/obj/machinery/telecomms/attack_hand(var/mob/user as mob)
/obj/machinery/telecomms/tgui_data(mob/user)
var/list/data = list()
data["temp"] = temp
data["on"] = on
// You need a multitool to use this, or be silicon
if(!issilicon(user))
// istype returns false if the value is null
if(!istype(user.get_active_hand(), /obj/item/device/multitool))
return
data["id"] = null
data["network"] = null
data["autolinkers"] = FALSE
data["shadowlink"] = FALSE
data["options"] = list()
data["linked"] = list()
data["filter"] = list()
data["multitool"] = FALSE
data["multitool_buffer"] = null
if(stat & (BROKEN|NOPOWER))
return
if(on || interact_offline)
data["id"] = id
data["network"] = network
data["autolinkers"] = !!LAZYLEN(autolinkers)
data["shadowlink"] = !!hide
var/obj/item/device/multitool/P = get_multitool(user)
data["options"] = Options_Menu()
user.set_machine(src)
var/dat
dat = "<font face = \"Courier\"><HEAD><TITLE>[src.name]</TITLE></HEAD><center><H3>[src.name] Access</H3></center>"
dat += "<br>[temp]<br>"
dat += "<br>Power Status: <a href='?src=\ref[src];input=toggle'>[src.toggled ? "On" : "Off"]</a>"
if(on && toggled)
if(id != "" && id)
dat += "<br>Identification String: <a href='?src=\ref[src];input=id'>[id]</a>"
else
dat += "<br>Identification String: <a href='?src=\ref[src];input=id'>NULL</a>"
dat += "<br>Network: <a href='?src=\ref[src];input=network'>[network]</a>"
dat += "<br>Prefabrication: [autolinkers.len ? "TRUE" : "FALSE"]"
if(hide) dat += "<br>Shadow Link: ACTIVE</a>"
//Show additional options for certain machines.
dat += Options_Menu()
dat += "<br>Linked Network Entities: <ol>"
var/obj/item/device/multitool/P = get_multitool(user)
data["multitool"] = !!P
data["multitool_buffer"] = null
if(P && P.buffer)
P.update_icon()
data["multitool_buffer"] = list("name" = "[P.buffer]", "id" = "[P.buffer.id]")
var/i = 0
data["linked"] = list()
for(var/obj/machinery/telecomms/T in links)
i++
if(T.hide && !src.hide)
continue
dat += "<li>\ref[T] [T.name] ([T.id]) <a href='?src=\ref[src];unlink=[i]'>\[X\]</a></li>"
dat += "</ol>"
dat += "<br>Filtering Frequencies: "
i = 0
if(length(freq_listening))
data["linked"].Add(list(list(
"ref" = "\ref[T]",
"name" = "[T]",
"id" = T.id,
"index" = i,
)))
data["filter"] = list()
if(LAZYLEN(freq_listening))
for(var/x in freq_listening)
i++
if(i < length(freq_listening))
dat += "[format_frequency(x)] GHz<a href='?src=\ref[src];delete=[x]'>\[X\]</a>; "
else
dat += "[format_frequency(x)] GHz<a href='?src=\ref[src];delete=[x]'>\[X\]</a>"
else
dat += "NONE"
data["filter"].Add(list(list(
"name" = "[format_frequency(x)]",
"freq" = x,
)))
dat += "<br> <a href='?src=\ref[src];input=freq'>\[Add Filter\]</a>"
dat += "<hr>"
return data
if(P)
if(P.buffer)
dat += "<br><br>MULTITOOL BUFFER: [P.buffer] ([P.buffer.id]) <a href='?src=\ref[src];link=1'>\[Link\]</a> <a href='?src=\ref[src];flush=1'>\[Flush\]"
else
dat += "<br><br>MULTITOOL BUFFER: <a href='?src=\ref[src];buffer=1'>\[Add Machine\]</a>"
P.update_icon()
/obj/machinery/telecomms/tgui_status(mob/user)
if(!issilicon(user))
if(!istype(user.get_active_hand(), /obj/item/device/multitool))
return STATUS_CLOSE
. = ..()
dat += "</font>"
temp = ""
user << browse(dat, "window=tcommachine;size=520x500;can_resize=0")
onclose(user, "dormitory")
/obj/machinery/telecomms/attack_hand(var/mob/user as mob)
tgui_interact(user)
/obj/machinery/telecomms/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TelecommsMultitoolMenu", name)
ui.open()
// Off-Site Relays
//
@@ -148,7 +145,7 @@
// Example of how to use below.
/obj/machinery/telecomms/proc/Options_Menu()
return ""
return list()
/*
// Add an option to the processor to switch processing mode. (COMPRESS -> UNCOMPRESS or UNCOMPRESS -> COMPRESS)
@@ -158,213 +155,230 @@
*/
// The topic for Additional Options. Use this for checking href links for your specific option.
// Example of how to use below.
/obj/machinery/telecomms/proc/Options_Topic(href, href_list)
/obj/machinery/telecomms/proc/Options_Act(action, params)
return
/*
/obj/machinery/telecomms/processor/Options_Topic(href, href_list)
/obj/machinery/telecomms/processor/Options_Act(action, params)
if(href_list["process"])
temp = "<font color = #666633>-% Processing mode changed. %-</font>"
set_temp("-% Processing mode changed. %-", "average")
src.process_mode = !src.process_mode
*/
// RELAY
/obj/machinery/telecomms/relay/Options_Menu()
var/dat = ""
if(src.z == TELECOMM_Z)
dat += "<br>Signal Locked to Station: <A href='?src=\ref[src];change_listening=1'>[listening_level == STATION_Z ? "TRUE" : "FALSE"]</a>"
dat += "<br>Broadcasting: <A href='?src=\ref[src];broadcast=1'>[broadcasting ? "YES" : "NO"]</a>"
dat += "<br>Receiving: <A href='?src=\ref[src];receive=1'>[receiving ? "YES" : "NO"]</a>"
return dat
var/list/data = ..()
data["use_listening_level"] = TRUE
data["use_broadcasting"] = TRUE
data["use_receiving"] = TRUE
data["listening_level"] = (listening_level == STATION_Z)
data["broadcasting"] = broadcasting
data["receiving"] = receiving
return data
/obj/machinery/telecomms/relay/Options_Topic(href, href_list)
/obj/machinery/telecomms/relay/Options_Act(action, params)
if(..())
return TRUE
if(href_list["receive"])
receiving = !receiving
temp = "<font color = #666633>-% Receiving mode changed. %-</font>"
if(href_list["broadcast"])
broadcasting = !broadcasting
temp = "<font color = #666633>-% Broadcasting mode changed. %-</font>"
if(href_list["change_listening"])
//Lock to the station OR lock to the current position!
//You need at least two receivers and two broadcasters for this to work, this includes the machine.
var/result = toggle_level()
if(result)
temp = "<font color = #666633>-% [src]'s signal has been successfully changed.</font>"
else
temp = "<font color = #666633>-% [src] could not lock it's signal onto the station. Two broadcasters or receivers required.</font>"
switch(action)
if("receive")
. = TRUE
receiving = !receiving
set_temp("-% Receiving mode changed. %-", "average")
if("broadcast")
. = TRUE
broadcasting = !broadcasting
set_temp("-% Broadcasting mode changed. %-", "average")
if("change_listening")
. = TRUE
//Lock to the station OR lock to the current position!
//You need at least two receivers and two broadcasters for this to work, this includes the machine.
var/result = toggle_level()
if(result)
set_temp("-% [src]'s signal has been successfully changed.", "average")
else
set_temp("-% [src] could not lock it's signal onto the station. Two broadcasters or receivers required.", "average")
// BUS
/obj/machinery/telecomms/bus/Options_Menu()
var/dat = "<br>Change Signal Frequency: <A href='?src=\ref[src];change_freq=1'>[change_frequency ? "YES ([change_frequency])" : "NO"]</a>"
return dat
var/list/data = ..()
data["use_change_freq"] = TRUE
data["change_freq"] = change_frequency
return data
/obj/machinery/telecomms/bus/Options_Topic(href, href_list)
if(href_list["change_freq"])
var/newfreq = input(usr, "Specify a new frequency for new signals to change to. Enter null to turn off frequency changing. Decimals assigned automatically.", src, network) as null|num
if(canAccess(usr))
if(newfreq)
if(findtext(num2text(newfreq), "."))
newfreq *= 10 // shift the decimal one place
if(newfreq < 10000)
change_frequency = newfreq
temp = "<font color = #666633>-% New frequency to change to assigned: \"[newfreq] GHz\" %-</font>"
else
change_frequency = 0
temp = "<font color = #666633>-% Frequency changing deactivated %-</font>"
/obj/machinery/telecomms/bus/Options_Act(action, params)
if(..())
return TRUE
switch(action)
if("change_freq")
. = TRUE
var/newfreq = input(usr, "Specify a new frequency for new signals to change to. Enter null to turn off frequency changing. Decimals assigned automatically.", src, network) as null|num
if(canAccess(usr))
if(newfreq)
if(findtext(num2text(newfreq), "."))
newfreq *= 10 // shift the decimal one place
if(newfreq < 10000)
change_frequency = newfreq
set_temp("-% New frequency to change to assigned: \"[newfreq] GHz\" %-", "average")
else
change_frequency = 0
set_temp("-% Frequency changing deactivated %-", "average")
// BROADCASTER
/obj/machinery/telecomms/broadcaster/Options_Menu()
// Note the machine 'displays' 1 higher than overmap_range to save users from the abstraction that range '0' is valid and everything on the same turf.
var/dat = "<br>Broadcast Range (affects power usage)<br><a href='?src=\ref[src];range_down=1'>-</a> [overmap_range+1] gigameter\s <a href='?src=\ref[src];range_up=1'>+</a>"
return dat
var/list/data = ..()
data["use_broadcast_range"] = TRUE
data["range"] = overmap_range
data["minRange"] = overmap_range_min
data["maxRange"] = overmap_range_max
return data
/obj/machinery/telecomms/broadcaster/Options_Topic(href, href_list)
if(href_list["range_down"])
if(overmap_range > overmap_range_min)
overmap_range--
update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
if(href_list["range_up"])
if(overmap_range < overmap_range_max)
overmap_range++
/obj/machinery/telecomms/broadcaster
interact_offline = TRUE // because you can accidentally nuke power grids with these, need to be able to fix mistake
/obj/machinery/telecomms/broadcaster/Options_Act(action, params)
if(..())
return TRUE
switch(action)
if("range")
var/new_range = params["range"]
overmap_range = clamp(new_range, overmap_range_min, overmap_range_max)
update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
// RECEIVER
/obj/machinery/telecomms/receiver/Options_Menu()
// Note the machine 'displays' 1 higher than overmap_range to save users from the abstraction that range '0' is valid and everything on the same turf.
var/dat = "<br>Receive Range (affects power usage)<br><a href='?src=\ref[src];range_down=1'>-</a> [overmap_range+1] gigameter\s <a href='?src=\ref[src];range_up=1'>+</a>"
return dat
var/list/data = ..()
data["use_receive_range"] = TRUE
data["range"] = overmap_range
data["minRange"] = overmap_range_min
data["maxRange"] = overmap_range_max
return data
/obj/machinery/telecomms/receiver/Options_Topic(href, href_list)
if(href_list["range_down"])
if(overmap_range > overmap_range_min)
overmap_range--
update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
if(href_list["range_up"])
if(overmap_range < overmap_range_max)
overmap_range++
/obj/machinery/telecomms/receiver
interact_offline = TRUE // because you can accidentally nuke power grids with these, need to be able to fix mistake
/obj/machinery/telecomms/receiver/Options_Act(action, params)
if(..())
return TRUE
switch(action)
if("range")
var/new_range = params["range"]
overmap_range = clamp(new_range, overmap_range_min, overmap_range_max)
update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
/obj/machinery/telecomms/Topic(href, href_list)
if(!issilicon(usr))
if(!istype(usr.get_active_hand(), /obj/item/device/multitool))
return
if(stat & (BROKEN|NOPOWER))
return
/obj/machinery/telecomms/tgui_act(action, params)
if(..())
return TRUE
var/obj/item/device/multitool/P = get_multitool(usr)
if(href_list["input"])
switch(href_list["input"])
switch(action)
if("toggle")
src.toggled = !src.toggled
set_temp("-% [src] has been [src.toggled ? "activated" : "deactivated"].", "average")
update_power()
. = TRUE
if("toggle")
if("id")
var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID for this machine", src, id) as null|text),1,MAX_MESSAGE_LEN)
if(newid && canAccess(usr))
id = newid
set_temp("-% New ID assigned: \"[id]\" %-", "average")
. = TRUE
src.toggled = !src.toggled
temp = "<font color = #666633>-% [src] has been [src.toggled ? "activated" : "deactivated"].</font>"
update_power()
if("network")
var/newnet = input(usr, "Specify the new network for this machine. This will break all current links.", src, network) as null|text
if(newnet && canAccess(usr))
/*
if("hide")
src.hide = !hide
temp = "<font color = #666633>-% Shadow Link has been [src.hide ? "activated" : "deactivated"].</font>"
*/
if(length(newnet) > 15)
set_temp("-% Too many characters in new network tag %-", "average")
if("id")
var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID for this machine", src, id) as null|text),1,MAX_MESSAGE_LEN)
if(newid && canAccess(usr))
id = newid
temp = "<font color = #666633>-% New ID assigned: \"[id]\" %-</font>"
else
for(var/obj/machinery/telecomms/T in links)
T.links.Remove(src)
if("network")
var/newnet = input(usr, "Specify the new network for this machine. This will break all current links.", src, network) as null|text
if(newnet && canAccess(usr))
if(length(newnet) > 15)
temp = "<font color = #666633>-% Too many characters in new network tag %-</font>"
else
for(var/obj/machinery/telecomms/T in links)
T.links.Remove(src)
network = newnet
links = list()
temp = "<font color = #666633>-% New network tag assigned: \"[network]\" %-</font>"
network = newnet
links = list()
set_temp("-% New network tag assigned: \"[network]\" %-", "average")
. = TRUE
if("freq")
var/newfreq = input(usr, "Specify a new frequency to filter (GHz). Decimals assigned automatically.", src, network) as null|num
if(newfreq && canAccess(usr))
if(findtext(num2text(newfreq), "."))
newfreq *= 10 // shift the decimal one place
if(!(newfreq in freq_listening) && newfreq < 10000)
freq_listening.Add(newfreq)
temp = "<font color = #666633>-% New frequency filter assigned: \"[newfreq] GHz\" %-</font>"
if("freq")
var/newfreq = input(usr, "Specify a new frequency to filter (GHz). Decimals assigned automatically.", src, network) as null|num
if(newfreq && canAccess(usr))
if(findtext(num2text(newfreq), "."))
newfreq *= 10 // shift the decimal one place
if(!(newfreq in freq_listening) && newfreq < 10000)
freq_listening.Add(newfreq)
set_temp("-% New frequency filter assigned: \"[newfreq] GHz\" %-", "average")
. = TRUE
if(href_list["delete"])
if("delete")
var/x = text2num(params["delete"])
set_temp("-% Removed frequency filter [x] %-", "average")
freq_listening.Remove(x)
. = TRUE
// changed the layout about to workaround a pesky runtime -- Doohl
if("unlink")
if(text2num(params["unlink"]) <= length(links))
var/obj/machinery/telecomms/T = links[text2num(params["unlink"])]
set_temp("-% Removed \ref[T] [T.name] from linked entities. %-", "average")
var/x = text2num(href_list["delete"])
temp = "<font color = #666633>-% Removed frequency filter [x] %-</font>"
freq_listening.Remove(x)
// Remove link entries from both T and src.
if(href_list["unlink"])
if(src in T.links)
T.links.Remove(src)
links.Remove(T)
. = TRUE
if(text2num(href_list["unlink"]) <= length(links))
var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])]
temp = "<font color = #666633>-% Removed \ref[T] [T.name] from linked entities. %-</font>"
if("link")
if(P)
if(P.buffer && P.buffer != src)
if(!(src in P.buffer.links))
P.buffer.links.Add(src)
// Remove link entries from both T and src.
if(!(P.buffer in src.links))
src.links.Add(P.buffer)
if(src in T.links)
T.links.Remove(src)
links.Remove(T)
set_temp("-% Successfully linked with \ref[P.buffer] [P.buffer.name] %-", "average")
if(href_list["link"])
else
set_temp("-% Unable to acquire buffer %-", "average")
. = TRUE
if(P)
if(P.buffer && P.buffer != src)
if(!(src in P.buffer.links))
P.buffer.links.Add(src)
if("buffer")
P.buffer = src
set_temp("-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-", "average")
. = TRUE
if(!(P.buffer in src.links))
src.links.Add(P.buffer)
if("flush")
set_temp("-% Buffer successfully flushed. %-", "average")
P.buffer = null
. = TRUE
temp = "<font color = #666633>-% Successfully linked with \ref[P.buffer] [P.buffer.name] %-</font>"
if("cleartemp")
temp = null
. = TRUE
else
temp = "<font color = #666633>-% Unable to acquire buffer %-</font>"
if(Options_Act(action, params))
. = TRUE
if(href_list["buffer"])
P.buffer = src
temp = "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font>"
if(href_list["flush"])
temp = "<font color = #666633>-% Buffer successfully flushed. %-</font>"
P.buffer = null
src.Options_Topic(href, href_list)
usr.set_machine(src)
src.add_fingerprint(usr)
updateUsrDialog()
add_fingerprint(usr)
/obj/machinery/telecomms/proc/canAccess(var/mob/user)
if(issilicon(user) || in_range(user, src))
return 1
return 0
/obj/machinery/telecomms/proc/set_temp(var/text, var/color = "average")
temp = list("color" = color, "text" = text)
#undef TELECOMM_Z
#undef STATION_Z
@@ -593,6 +593,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
log.parameters["message"] = multilingual_to_message(signal.data["message"])
log.parameters["name"] = signal.data["name"]
log.parameters["realname"] = signal.data["realname"]
log.parameters["timecode"] = worldtime2stationtime(world.time)
var/race = "unknown"
if(ishuman(M))
@@ -672,6 +673,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
log.name = "[input] ([md5(identifier)])"
log.input_type = input
log.parameters["message"] = content
log.parameters["timecode"] = stationtime2text()
log_entries.Add(log)
update_logs()
+74 -80
View File
@@ -6,7 +6,6 @@
and displays a heirarchy of linked machines.
*/
/obj/machinery/computer/telecomms/monitor
name = "Telecommunications Monitor"
desc = "Used to traverse a telecommunication network. Helpful for debugging connection issues."
@@ -19,111 +18,103 @@
var/network = "NULL" // the network to probe
var/temp = "" // temporary feedback messages
var/list/temp = null // temporary feedback messages
attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
user.set_machine(src)
var/dat = "<TITLE>Telecommunications Monitor</TITLE><center><b>Telecommunications Monitor</b></center>"
/obj/machinery/computer/telecomms/monitor/tgui_data(mob/user)
var/list/data = list()
switch(screen)
data["network"] = network
data["temp"] = temp
data["machinelist"] = list()
for(var/obj/machinery/telecomms/T in machinelist)
data["machinelist"].Add(list(list(
"id" = T.id,
"name" = T.name,
)))
// --- Main Menu ---
data["selectedMachine"] = null
if(SelectedMachine)
data["selectedMachine"] = list(
"id" = SelectedMachine.id,
"name" = SelectedMachine.name,
"links" = list(),
)
if(0)
dat += "<br>[temp]<br><br>"
dat += "<br>Current Network: <a href='?src=\ref[src];network=1'>[network]</a><br>"
if(machinelist.len)
dat += "<br>Detected Network Entities:<ul>"
for(var/obj/machinery/telecomms/T in machinelist)
dat += "<li><a href='?src=\ref[src];viewmachine=[T.id]'>\ref[T] [T.name]</a> ([T.id])</li>"
dat += "</ul>"
dat += "<br><a href='?src=\ref[src];operation=release'>\[Flush Buffer\]</a>"
else
dat += "<a href='?src=\ref[src];operation=probe'>\[Probe Network\]</a>"
for(var/obj/machinery/telecomms/T in SelectedMachine.links)
if(!T.hide)
data["selectedMachine"]["links"].Add(list(list(
"id" = T.id,
"name" = T.name
)))
return data
// --- Viewing Machine ---
if(1)
dat += "<br>[temp]<br>"
dat += "<center><a href='?src=\ref[src];operation=mainmenu'>\[Main Menu\]</a></center>"
dat += "<br>Current Network: [network]<br>"
dat += "Selected Network Entity: [SelectedMachine.name] ([SelectedMachine.id])<br>"
dat += "Linked Entities: <ol>"
for(var/obj/machinery/telecomms/T in SelectedMachine.links)
if(!T.hide)
dat += "<li><a href='?src=\ref[src];viewmachine=[T.id]'>\ref[T.id] [T.name]</a> ([T.id])</li>"
dat += "</ol>"
user << browse(dat, "window=comm_monitor;size=575x400")
onclose(user, "server_control")
temp = ""
/obj/machinery/computer/telecomms/monitor/attack_hand(mob/user)
if(stat & (BROKEN|NOPOWER))
return
tgui_interact(user)
/obj/machinery/computer/telecomms/monitor/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TelecommsMachineBrowser", name)
ui.open()
Topic(href, href_list)
if(..())
return
/obj/machinery/computer/telecomms/monitor/tgui_act(action, params)
if(..())
return TRUE
add_fingerprint(usr)
add_fingerprint(usr)
usr.set_machine(src)
if(href_list["viewmachine"])
screen = 1
switch(action)
if("view")
for(var/obj/machinery/telecomms/T in machinelist)
if(T.id == href_list["viewmachine"])
if(T.id == params["id"])
SelectedMachine = T
break
. = TRUE
if(href_list["operation"])
switch(href_list["operation"])
if("mainmenu")
SelectedMachine = null
. = TRUE
if("release")
machinelist = list()
screen = 0
if("release")
machinelist = list()
SelectedMachine = null
. = TRUE
if("mainmenu")
screen = 0
if("scan")
if(machinelist.len > 0)
set_temp("FAILED: CANNOT PROBE WHEN BUFFER FULL", "bad")
return TRUE
if("probe")
if(machinelist.len > 0)
temp = "<font color = #D70B00>- FAILED: CANNOT PROBE WHEN BUFFER FULL -</font>"
for(var/obj/machinery/telecomms/T in range(25, src))
if(T.network == network)
machinelist.Add(T)
else
for(var/obj/machinery/telecomms/T in range(25, src))
if(T.network == network)
machinelist.Add(T)
if(!machinelist.len)
temp = "<font color = #D70B00>- FAILED: UNABLE TO LOCATE NETWORK ENTITIES IN \[[network]\] -</font>"
else
temp = "<font color = #336699>- [machinelist.len] ENTITIES LOCATED & BUFFERED -</font>"
screen = 0
if(href_list["network"])
if(!machinelist.len)
set_temp("FAILED: UNABLE TO LOCATE NETWORK ENTITIES IN \[[network]\]", "bad")
else
set_temp("[machinelist.len] ENTITIES LOCATED & BUFFERED", "good")
. = TRUE
if("network")
var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
if(newnet && ((usr in range(1, src) || issilicon(usr))))
if(length(newnet) > 15)
temp = "<font color = #D70B00>- FAILED: NETWORK TAG STRING TOO LENGHTLY -</font>"
set_temp("FAILED: NETWORK TAG STRING TOO LENGTHY", "bad")
return TRUE
network = newnet
machinelist = list()
set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good")
. = TRUE
else
network = newnet
screen = 0
machinelist = list()
temp = "<font color = #336699>- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -</font>"
if("cleartemp")
temp = null
. = TRUE
updateUsrDialog()
return
/obj/machinery/computer/telecomms/monitor/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
@@ -132,3 +123,6 @@
to_chat(user, "<span class='notice'>You you disable the security protocols</span>")
src.updateUsrDialog()
return 1
/obj/machinery/computer/telecomms/monitor/proc/set_temp(var/text, var/color = "average")
temp = list("color" = color, "text" = text)
+54 -33
View File
@@ -26,6 +26,7 @@
var/vend_delay = 10 //How long does it take to vend?
var/categories = CAT_NORMAL // Bitmask of cats we're currently showing
var/datum/stored_item/vending_product/currently_vending = null // What we're requesting payment for right now
var/tmp/actively_vending = null // Used to allow TGUI to display normal items in-progress being vended
var/status_message = "" // Status screen messages like "insufficient funds", displayed in NanoUI
var/status_error = 0 // Set to 1 if status_message is an error
var/vending_sound = "machines/vending/vending_drop.ogg"
@@ -173,7 +174,7 @@
vend(currently_vending, usr)
return
else if(handled)
SSnanoui.update_uis(src)
SStgui.update_uis(src)
return // don't smack that machine with your 2 thalers
if(I || istype(W, /obj/item/weapon/spacecash))
@@ -184,11 +185,12 @@
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
playsound(src, W.usesound, 50, 1)
if(panel_open)
wires.Interact(user)
add_overlay("[initial(icon_state)]-panel")
else
cut_overlay("[initial(icon_state)]-panel")
SSnanoui.update_uis(src) // Speaker switch is on the main UI, not wires UI
SStgui.update_uis(src) // Speaker switch is on the main UI, not wires UI
return
else if(istype(W, /obj/item/device/multitool) || W.is_wirecutter())
if(panel_open)
@@ -200,7 +202,7 @@
coin = W
categories |= CAT_COIN
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src].</span>")
SSnanoui.update_uis(src)
SStgui.update_uis(src)
return
else if(W.is_wrench())
playsound(src, W.usesound, 100, 1)
@@ -348,6 +350,9 @@
T.time = stationtime2text()
vendor_account.transaction_log.Add(T)
/obj/machinery/vending/attack_ghost(mob/user)
return attack_hand(user)
/obj/machinery/vending/attack_ai(mob/user as mob)
return attack_hand(user)
@@ -360,24 +365,23 @@
return
wires.Interact(user)
ui_interact(user)
tgui_interact(user)
/**
* Display the NanoUI window for the vending machine.
*
* See NanoUI documentation for details.
*/
/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
/obj/machinery/vending/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Vending", name)
ui.open()
/obj/machinery/vending/tgui_data(mob/user)
var/list/data = list()
if(currently_vending)
data["mode"] = 1
data["product"] = currently_vending.item_name
data["price"] = currently_vending.price
data["message_err"] = 0
data["message"] = status_message
data["message_err"] = status_error
data["products"] = null
else
data["mode"] = 0
var/list/listed_products = list()
@@ -399,6 +403,13 @@
if(coin)
data["coin"] = coin.name
else
data["coin"] = FALSE
if(actively_vending)
data["actively_vending"] = actively_vending
else
data["actively_vending"] = null
if(panel_open)
data["panel"] = 1
@@ -406,19 +417,20 @@
else
data["panel"] = 0
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "vending_machine.tmpl", name, 440, 600)
ui.set_initial_data(data)
ui.open()
return data
/obj/machinery/vending/Topic(href, href_list)
/obj/machinery/vending/tgui_act(action, params)
if(stat & (BROKEN|NOPOWER))
return
if(usr.stat || usr.restrained())
return
if(..())
return TRUE
if(action == "remove_coin")
if(issilicon(usr))
return FALSE
if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon))
if(!coin)
to_chat(usr, "There is no coin in this machine.")
return
@@ -426,19 +438,27 @@
coin.forceMove(src.loc)
if(!usr.get_active_hand())
usr.put_in_hands(coin)
to_chat(usr, "<span class='notice'>You remove \the [coin] from \the [src]</span>")
to_chat(usr, "<span class='notice'>You remove \the [coin] from \the [src].</span>")
coin = null
categories &= ~CAT_COIN
return TRUE
if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
if((href_list["vend"]) && (vend_ready) && (!currently_vending))
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
if(!usr.contents.Find(src) && (!in_range(src, usr) && isturf(loc)))
return FALSE
. = TRUE
switch(action)
if("vend")
if(!vend_ready || currently_vending)
return
if(!allowed(usr) && !emagged && scan_id)
to_chat(usr, "<span class='warning'>Access denied.</span>") //Unless emagged of course
flick("[icon_state]-deny",src)
playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0)
return
var/key = text2num(href_list["vend"])
var/key = text2num(params["vend"])
var/datum/stored_item/vending_product/R = product_records[key]
// This should not happen unless the request from NanoUI was bad
@@ -447,7 +467,7 @@
if(R.price <= 0)
vend(R, usr)
else if(istype(usr,/mob/living/silicon)) //If the item is not free, provide feedback if a synth is trying to buy something.
else if(issilicon(usr)) //If the item is not free, provide feedback if a synth is trying to buy something.
to_chat(usr, "<span class='danger'>Lawed unit recognized. Lawed units cannot complete this transaction. Purchase canceled.</span>")
return
else
@@ -459,15 +479,14 @@
status_message = "Please swipe a card or insert cash to pay for the item."
status_error = 0
else if(href_list["cancelpurchase"])
if("cancelpurchase")
currently_vending = null
else if((href_list["togglevoice"]) && (panel_open))
if("togglevoice")
if(!panel_open)
return FALSE
shut_up = !shut_up
add_fingerprint(usr)
SSnanoui.update_uis(src)
/obj/machinery/vending/proc/vend(datum/stored_item/vending_product/R, mob/user)
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
to_chat(usr, "<span class='warning'>Access denied.</span>") //Unless emagged of course
@@ -475,9 +494,10 @@
playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0)
return
vend_ready = 0 //One thing at a time!!
actively_vending = R.item_name
status_message = "Vending..."
status_error = 0
SSnanoui.update_uis(src)
SStgui.update_uis(src)
if(R.category & CAT_COIN)
if(!coin)
@@ -516,8 +536,9 @@
status_message = ""
status_error = 0
vend_ready = 1
actively_vending = null
currently_vending = null
SSnanoui.update_uis(src)
SStgui.update_uis(src)
return 1
@@ -589,7 +610,7 @@
if(has_logs)
do_logging(R, user)
SSnanoui.update_uis(src)
SStgui.update_uis(src)
/obj/machinery/vending/process()
if(stat & (BROKEN|NOPOWER))
+55 -40
View File
@@ -22,15 +22,26 @@
to_chat(user, "<b>ERROR ERROR ERROR</b>")
/obj/item/device/aicard/attack_self(mob/user)
tgui_interact(user)
ui_interact(user)
/obj/item/device/aicard/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AICard", "[name]") // 600, 394
ui.open()
if(custom_state)
ui.set_state(custom_state)
/obj/item/device/aicard/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = inventory_state)
/obj/item/device/aicard/tgui_state(mob/user)
return GLOB.tgui_inventory_state
/obj/item/device/aicard/tgui_data(mob/user)
var/data[0]
data["has_ai"] = carded_ai != null
if(carded_ai)
data["name"] = carded_ai.name
data["hardware_integrity"] = carded_ai.hardware_integrity()
data["integrity"] = carded_ai.hardware_integrity()
data["backup_capacitor"] = carded_ai.backup_capacitor()
data["radio"] = !carded_ai.aiRadio.disabledAi
data["wireless"] = !carded_ai.control_disabled
@@ -38,52 +49,42 @@
data["flushing"] = flush
var/laws[0]
for(var/datum/ai_law/AL in carded_ai.laws.all_laws())
laws[++laws.len] = list("index" = AL.get_index(), "law" = sanitize(AL.law))
for(var/datum/ai_law/law in carded_ai.laws.all_laws())
if(law in carded_ai.laws.ion_laws) // If we're an ion law, give it an ion index code
laws.Add(ionnum() + ". " + law.law)
else
laws.Add(num2text(law.get_index()) + ". " + law.law)
data["laws"] = laws
data["has_laws"] = laws.len
data["has_laws"] = length(carded_ai.laws.all_laws())
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "aicard.tmpl", "[name]", 600, 400, state = state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
return data
/obj/item/device/aicard/Topic(href, href_list, state)
/obj/item/device/aicard/tgui_act(action, params)
if(..())
return 1
return TRUE
if(!carded_ai)
return 1
return
var/user = usr
if (href_list["wipe"])
var/confirm = alert("Are you sure you want to disable this core's power? This cannot be undone once started.", "Confirm Shutdown", "No", "Yes")
if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE))
switch(action)
if("wipe")
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].")
add_attack_logs(user,carded_ai,"Purged from AI Card")
flush = 1
carded_ai.suiciding = 1
to_chat(carded_ai, "Your power has been disabled!")
while (carded_ai && carded_ai.stat != DEAD)
if(carded_ai.deployed_shell && prob(carded_ai.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely.
carded_ai.disconnect_shell("Disconnecting from remote shell due to insufficent power.")
carded_ai.adjustOxyLoss(2)
carded_ai.updatehealth()
sleep(10)
flush = 0
if (href_list["radio"])
carded_ai.aiRadio.disabledAi = text2num(href_list["radio"])
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
if (href_list["wireless"])
carded_ai.control_disabled = text2num(href_list["wireless"])
to_chat(carded_ai, "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
if(carded_ai.control_disabled && carded_ai.deployed_shell)
carded_ai.disconnect_shell("Disconnecting from remote shell due to [src] wireless access interface being disabled.")
update_icon()
return 1
INVOKE_ASYNC(src, .proc/wipe_ai)
if("radio")
carded_ai.aiRadio.disabledAi = !carded_ai.aiRadio.disabledAi
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
if("wireless")
carded_ai.control_disabled = !carded_ai.control_disabled
to_chat(carded_ai, "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
if(carded_ai.control_disabled && carded_ai.deployed_shell)
carded_ai.disconnect_shell("Disconnecting from remote shell due to [src] wireless access interface being disabled.")
update_icon()
return TRUE
/obj/item/device/aicard/update_icon()
overlays.Cut()
@@ -168,3 +169,17 @@
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.forced_move(direction, user)
/obj/item/device/aicard/proc/wipe_ai()
var/mob/living/silicon/ai/AI = carded_ai
flush = TRUE
AI.suiciding = TRUE
to_chat(AI, "Your power has been disabled!")
while(AI && AI.stat != DEAD)
// This is absolutely evil and I love it.
if(AI.deployed_shell && prob(AI.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely.
AI.disconnect_shell("Disconnecting from remote shell due to insufficent power.")
AI.adjustOxyLoss(2)
AI.updatehealth()
sleep(10)
flush = FALSE
@@ -382,7 +382,7 @@
return
/obj/item/device/radio/headset/proc/recalculateChannels(var/setDescription = 0)
/obj/item/device/radio/headset/recalculateChannels(var/setDescription = 0)
src.channels = list()
src.translate_binary = 0
src.translate_hive = 0
+84 -124
View File
@@ -37,12 +37,14 @@ var/global/list/default_medbay_channels = list(
var/frequency = PUB_FREQ //common chat
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
var/canhear_range = 3 // the range which mobs can hear this radio from
var/loudspeaker = TRUE // Allows borgs to disable canhear_range.
var/datum/wires/radio/wires = null
var/b_stat = 0
var/broadcasting = 0
var/listening = 1
var/list/channels = list() //see communications.dm for full list. First channel is a "default" for :h
var/subspace_transmission = 0
var/subspace_switchable = FALSE
var/adhoc_fallback = FALSE //Falls back to 'radio' mode if subspace not available
var/syndie = 0//Holder to see if it's a syndicate encrypted radio
var/centComm = 0//Holder to see if it's a CentCom encrypted radio
@@ -133,6 +135,8 @@ var/global/list/default_medbay_channels = list(
if(!found)
testing("A radio [src] at [x],[y],[z] specified bluespace prelink IDs, but the machines with corresponding IDs ([bs_tx_preload_id], [bs_rx_preload_id]) couldn't be found.")
/obj/item/device/radio/proc/recalculateChannels()
return
/obj/item/device/radio/attack_self(mob/user as mob)
user.set_machine(src)
@@ -145,15 +149,31 @@ var/global/list/default_medbay_channels = list(
if(b_stat)
wires.Interact(user)
return ui_interact(user)
return tgui_interact(user)
/obj/item/device/radio/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/item/device/radio/ui_interact(mob/user, ui_key, datum/nanoui/ui, force_open, datum/nano_ui/master_ui, datum/topic_state/state)
log_runtime(EXCEPTION("Warning: [user] attempted to call ui_interact on radio [src] [type]. This is deprecated. Please update the caller to tgui_interact."))
/obj/item/device/radio/Topic(href, href_list)
if(href_list["track"])
log_runtime(EXCEPTION("Warning: Topic() was improperly called on radio [src] [type], with the track href and \[[href] [json_encode(href_list)]]. Please update the caller to use tgui_act."))
. = ..()
/obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Radio", name)
ui.open()
/obj/item/device/radio/tgui_data(mob/user)
var/data[0]
data["mic_status"] = broadcasting
data["speaker"] = listening
data["freq"] = format_frequency(frequency)
data["rawfreq"] = num2text(frequency)
data["listening"] = listening
data["broadcasting"] = broadcasting
data["subspace"] = subspace_transmission
data["subspaceSwitchable"] = subspace_switchable
data["loudspeaker"] = loudspeaker
data["mic_cut"] = (wires.is_cut(WIRE_RADIO_TRANSMIT) || wires.is_cut(WIRE_RADIO_SIGNAL))
data["spk_cut"] = (wires.is_cut(WIRE_RADIO_RECEIVER) || wires.is_cut(WIRE_RADIO_SIGNAL))
@@ -161,21 +181,16 @@ var/global/list/default_medbay_channels = list(
var/list/chanlist = list_channels(user)
if(islist(chanlist) && chanlist.len)
data["chan_list"] = chanlist
data["chan_list_len"] = chanlist.len
else
data["chan_list"] = null
if(syndie)
data["useSyndMode"] = 1
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430)
ui.set_initial_data(data)
ui.open()
data["minFrequency"] = PUBLIC_LOW_FREQ
data["maxFrequency"] = PUBLIC_HIGH_FREQ
/obj/item/device/radio/CouldUseTopic(var/mob/user)
..()
if(iscarbon(user))
playsound(src, "button", 10)
return data
/obj/item/device/radio/proc/list_channels(var/mob/user)
return list_internal_channels(user)
@@ -187,7 +202,7 @@ var/global/list/default_medbay_channels = list(
var/chan_stat = channels[ch_name]
var/listening = !!(chan_stat & FREQ_LISTENING) != 0
dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "chan_span" = frequency_span_class(radiochannels[ch_name]))))
dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "freq" = radiochannels[ch_name])))
return dat
@@ -195,7 +210,7 @@ var/global/list/default_medbay_channels = list(
var/dat[0]
for(var/internal_chan in internal_channels)
if(has_channel_access(user, internal_chan))
dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "chan_span" = frequency_span_class(text2num(internal_chan)))))
dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "freq" = text2num(internal_chan))))
return dat
@@ -233,50 +248,61 @@ var/global/list/default_medbay_channels = list(
return STATUS_CLOSE
return ..()
/obj/item/device/radio/Topic(href, href_list)
/obj/item/device/radio/tgui_act(action, params)
if(..())
return TRUE
usr.set_machine(src)
if (href_list["track"])
var/mob/target = locate(href_list["track"])
var/mob/living/silicon/ai/A = locate(href_list["track2"])
if(A && target)
A.ai_actual_track(target)
. = 1
else if (href_list["freq"])
var/new_frequency = (frequency + text2num(href_list["freq"]))
if ((new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ))
new_frequency = sanitize_frequency(new_frequency)
set_frequency(new_frequency)
if(hidden_uplink)
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
usr << browse(null, "window=radio")
. = 1
else if (href_list["talk"])
ToggleBroadcast()
. = 1
else if (href_list["listen"])
var/chan_name = href_list["ch_name"]
if (!chan_name)
switch(action)
if("setFrequency")
var/new_frequency = (text2num(params["freq"]))
if((new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ))
new_frequency = sanitize_frequency(new_frequency)
set_frequency(new_frequency)
if(hidden_uplink)
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
usr << browse(null, "window=radio")
. = TRUE
if("broadcast")
ToggleBroadcast()
. = TRUE
if("listen")
ToggleReception()
else
if (channels[chan_name] & FREQ_LISTENING)
. = TRUE
if("channel")
var/chan_name = params["channel"]
if(channels[chan_name] & FREQ_LISTENING)
channels[chan_name] &= ~FREQ_LISTENING
else
channels[chan_name] |= FREQ_LISTENING
. = 1
else if(href_list["spec_freq"])
var freq = href_list["spec_freq"]
if(has_channel_access(usr, freq))
set_frequency(text2num(freq))
. = 1
if(href_list["nowindow"]) // here for pAIs, maybe others will want it, idk
return TRUE
. = TRUE
if("specFreq")
var/freq = params["channel"]
if(has_channel_access(usr, freq))
set_frequency(text2num(freq))
. = TRUE
if("subspace")
if(subspace_switchable)
subspace_transmission = !subspace_transmission
if(!subspace_transmission)
channels = list()
to_chat(usr, "<span class='notice'>Subspace Transmission is disabled</span>")
else
recalculateChannels()
to_chat(usr, "<span class='notice'>Subspace Transmission is enabled</span>")
. = TRUE
if("toggleLoudspeaker")
if(!subspace_switchable)
return
loudspeaker = !loudspeaker
if(.)
SSnanoui.update_uis(src)
if(loudspeaker)
to_chat(usr, "<span class='notice'>Loadspeaker enabled.</span>")
else
to_chat(usr, "<span class='notice'>Loadspeaker disabled.</span>")
. = TRUE
if(. && iscarbon(usr))
playsound(src, "button", 10)
GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels) //BS12 EDIT
@@ -569,10 +595,9 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
return canhear_range
/obj/item/device/radio/proc/send_hear(freq, level)
var/range = receive_range(freq, level)
if(range > -1)
return get_mobs_or_objects_in_view(canhear_range, src)
if(range > -1 && loudspeaker)
return get_mobs_or_objects_in_view(range, src)
/obj/item/device/radio/examine(mob/user)
@@ -616,11 +641,11 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
/obj/item/device/radio/borg
var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks
var/obj/item/device/encryptionkey/keyslot = null//Borg radios can handle a single encryption key
var/shut_up = 1
icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component.
icon_state = "radio"
canhear_range = 0
subspace_transmission = 1
subspace_transmission = TRUE
subspace_switchable = TRUE
/obj/item/device/radio/borg/Destroy()
myborg = null
@@ -678,7 +703,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
return
/obj/item/device/radio/borg/proc/recalculateChannels()
/obj/item/device/radio/borg/recalculateChannels()
src.channels = list()
src.syndie = 0
@@ -710,71 +735,6 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
return
/obj/item/device/radio/borg/Topic(href, href_list)
if(..())
return TRUE
if (href_list["mode"])
var/enable_subspace_transmission = text2num(href_list["mode"])
if(enable_subspace_transmission != subspace_transmission)
subspace_transmission = !subspace_transmission
if(subspace_transmission)
to_chat(usr, "<span class='notice'>Subspace Transmission is enabled</span>")
else
to_chat(usr, "<span class='notice'>Subspace Transmission is disabled</span>")
if(subspace_transmission == 0)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled
channels = list()
else
recalculateChannels()
. = 1
if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio.
var/do_shut_up = text2num(href_list["shutup"])
if(do_shut_up != shut_up)
shut_up = !shut_up
if(shut_up)
canhear_range = 0
to_chat(usr, "<span class='notice'>Loadspeaker disabled.</span>")
else
canhear_range = 3
to_chat(usr, "<span class='notice'>Loadspeaker enabled.</span>")
. = 1
if(.)
SSnanoui.update_uis(src)
/obj/item/device/radio/borg/interact(mob/user as mob)
if(!on)
return
. = ..()
/obj/item/device/radio/borg/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data["mic_status"] = broadcasting
data["speaker"] = listening
data["freq"] = format_frequency(frequency)
data["rawfreq"] = num2text(frequency)
var/list/chanlist = list_channels(user)
if(islist(chanlist) && chanlist.len)
data["chan_list"] = chanlist
data["chan_list_len"] = chanlist.len
if(syndie)
data["useSyndMode"] = 1
data["has_loudspeaker"] = 1
data["loudspeaker"] = !shut_up
data["has_subspace"] = 1
data["subspace"] = subspace_transmission
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430)
ui.set_initial_data(data)
ui.open()
/obj/item/device/radio/proc/config(op)
if(radio_controller)
for (var/ch_name in channels)
+171 -250
View File
@@ -1,8 +1,11 @@
#define PAINT_MODE -2
#define EATING_MODE -1
#define ATMOS_MODE 0
#define DISPOSALS_MODE 1
#define TRANSIT_MODE 2
#define ATMOS_CATEGORY 0
#define DISPOSALS_CATEGORY 1
#define TRANSIT_CATEGORY 2
#define BUILD_MODE (1<<0)
#define WRENCH_MODE (1<<1)
#define DESTROY_MODE (1<<2)
#define PAINT_MODE (1<<3)
/obj/item/weapon/pipe_dispenser
name = "Rapid Piping Device (RPD)"
@@ -22,18 +25,16 @@
w_class = ITEMSIZE_NORMAL
matter = list(MAT_STEEL = 50000, MAT_GLASS = 25000)
var/datum/effect/effect/system/spark_spread/spark_system
var/mode = ATMOS_MODE
var/p_dir = NORTH // Next pipe will be built with this dir
var/p_flipped = FALSE // If the next pipe should be built flipped
var/paint_color = "grey" // Pipe color index for next pipe painted/built.
var/screen = ATMOS_MODE // Starts on the atmos tab.
var/category = ATMOS_CATEGORY
var/piping_layer = PIPING_LAYER_DEFAULT
var/wrench_mode = FALSE
var/obj/item/weapon/tool/wrench/tool
var/datum/pipe_recipe/recipe // pipe recipie selected for display/construction
var/static/datum/pipe_recipe/first_atmos
var/static/datum/pipe_recipe/first_disposal
var/static/datum/asset/spritesheet/pipes/icon_assets
var/mode = BUILD_MODE | DESTROY_MODE | WRENCH_MODE
var/static/list/pipe_layers = list(
"Regular" = PIPING_LAYER_REGULAR,
"Supply" = PIPING_LAYER_SUPPLY,
@@ -51,10 +52,10 @@
/obj/item/weapon/pipe_dispenser/proc/SetupPipes()
if(!first_atmos)
first_atmos = atmos_pipe_recipes[atmos_pipe_recipes[1]][1]
first_atmos = GLOB.atmos_pipe_recipes[GLOB.atmos_pipe_recipes[1]][1]
recipe = first_atmos
if(!first_disposal)
first_disposal = disposal_pipe_recipes[disposal_pipe_recipes[1]][1]
first_disposal = GLOB.disposal_pipe_recipes[GLOB.disposal_pipe_recipes[1]][1]
/obj/item/weapon/pipe_dispenser/Destroy()
qdel_null(spark_system)
@@ -69,170 +70,97 @@
return(BRUTELOSS)
/obj/item/weapon/pipe_dispenser/attack_self(mob/user)
src.interact(user)
tgui_interact(user)
// TODO - Wouldn't it be nice to have nanoui?
/obj/item/weapon/pipe_dispenser/interact(mob/user)
/obj/item/weapon/pipe_dispenser/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/pipes),
)
/obj/item/weapon/pipe_dispenser/tgui_interact(mob/user, datum/tgui/ui)
SetupPipes()
if(!icon_assets)
icon_assets = get_asset_datum(/datum/asset/spritesheet/pipes)
icon_assets.send(user)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "RapidPipeDispenser", name)
ui.open()
var/list/lines = list()
if(mode >= ATMOS_MODE)
lines += "<div class=\"block\"><h3>Direction:</h3><div class=\"item\">"
switch(recipe.dirtype)
/obj/item/weapon/pipe_dispenser/tgui_data(mob/user)
var/list/data = list(
"category" = category,
"piping_layer" = piping_layer,
"pipe_layers" = pipe_layers,
"preview_rows" = recipe.get_preview(p_dir),
"categories" = list(),
"selected_color" = paint_color,
"paint_colors" = pipe_colors,
"mode" = mode
)
if(PIPE_STRAIGHT) // Straight, N-S, W-E
lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","&#8597;")
lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","&harr;")
var/list/recipes
switch(category)
if(ATMOS_CATEGORY)
recipes = GLOB.atmos_pipe_recipes
if(DISPOSALS_CATEGORY)
recipes = GLOB.disposal_pipe_recipes
// if(TRANSIT_CATEGORY)
// recipes = transit_tube_recipes
for(var/c in recipes)
var/list/cat = recipes[c]
var/list/r = list()
for(var/i in 1 to cat.len)
var/datum/pipe_recipe/info = cat[i]
r += list(list("pipe_name" = info.name, "pipe_index" = i, "selected" = (info == recipe)))
data["categories"] += list(list("cat_name" = c, "recipes" = r))
if(PIPE_BENDABLE) // Bent, N-W, N-E etc
lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","&#8597;")
lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","&harr;")
lines += "<br />"
lines += render_dir_img(recipe.icon_state,user,NORTHWEST,"West to North","&#9565;")
lines += render_dir_img(recipe.icon_state,user,NORTHEAST,"North to East","&#9562;")
lines += render_dir_img(recipe.icon_state,user,SOUTHWEST,"South to West","&#9559;")
lines += render_dir_img(recipe.icon_state,user,SOUTHEAST,"East to South","&#9556;")
return data
if(PIPE_TRINARY) // Manifold
lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","&#9574;")
lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","&#9571;")
lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","&#9577;")
lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","&#9568;")
if(PIPE_TRIN_M) // Mirrored ones
//each mirror icon is 45 anticlockwise from it's real direction
lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","&#9574;")
lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","&#9571;")
lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","&#9577;")
lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","&#9568;")
lines += "<br />"
lines += render_dir_img(recipe.icon_state_m,user,SOUTH,"West South East","&#9574;", 1)
lines += render_dir_img(recipe.icon_state_m,user,WEST,"South East North","&#9568;", 1)
lines += render_dir_img(recipe.icon_state_m,user,NORTH,"East North West","&#9577;", 1)
lines += render_dir_img(recipe.icon_state_m,user,EAST,"North West South","&#9571;", 1)
if(PIPE_DIRECTIONAL) // Stuff with four directions - includes pumps etc.
lines += render_dir_img(recipe.icon_state,user,NORTH,"North","&uarr;")
lines += render_dir_img(recipe.icon_state,user,EAST,"East","&rarr;")
lines += render_dir_img(recipe.icon_state,user,SOUTH,"South","&darr;")
lines += render_dir_img(recipe.icon_state,user,WEST,"West","&larr;")
if(PIPE_ONEDIR) // Single icon_state (eg 4-way manifolds)
lines += render_dir_img(recipe.icon_state,user,SOUTH,"Pipe","&#8597;")
lines += "</div></div>"
if(mode == ATMOS_MODE || mode == PAINT_MODE)
lines += "<div class=\"block\"><h3>Color:</h3>"
var/i = 0
for(var/c in pipe_colors)
++i
lines += "<a class='[paint_color == c ? "linkOn" : ""]' href='?src=\ref[src];paint_color=[c]'>[c]</a>"
if(i == 4)
lines += "<br>"
i = 0
lines += "</div>"
lines += "<div class=\"block\"><h3>Mode:</h3>"
lines += "<a class='[mode >= ATMOS_MODE ? "linkOn" : ""]' href='?src=\ref[src];mode=[screen]'>Lay Pipes</a>"
lines += "<a class='[mode == EATING_MODE ? "linkOn" : ""]' href='?src=\ref[src];mode=[EATING_MODE]'>Eat Pipes</a>"
lines += "<a class='[mode == PAINT_MODE ? "linkOn" : ""]' href='?src=\ref[src];mode=[PAINT_MODE]'>Paint Pipes</a>"
lines += "</div>"
lines += "<div class=\"block\"><h3>Category:</h3>"
lines += "<a class='[screen == ATMOS_MODE ? "linkOn" : ""]' href='?src=\ref[src];screen=[ATMOS_MODE]'>Atmospherics</a>"
lines += "<a class='[screen == DISPOSALS_MODE ? "linkOn" : ""]' href='?src=\ref[src];screen=[DISPOSALS_MODE]'>Disposals</a>"
//lines += "<a class='[screen == TRANSIT_MODE ? "linkOn" : ""]' href='?src=\ref[src];screen=[TRANSIT_MODE]'>Transit Tube</a>"
lines += "<br><a class='[wrench_mode ? "linkOn" : ""]' href='?src=\ref[src];switch_wrench=1;wrench_mode=[!wrench_mode]'>Wrench Mode</a>"
lines += "</div>"
if(screen == ATMOS_MODE)
for(var/category in atmos_pipe_recipes)
lines += "<div class=\"block\"><h3>[category]:</h3>"
if(category == "Pipes")
lines += "<div class=\"item\">"
for(var/pipename in pipe_layers)
var/pipelayer = pipe_layers[pipename]
lines += "<a class='[piping_layer == pipelayer ? "linkOn" : "linkOff"]' href='?src=\ref[src];piping_layer=[pipelayer]'>[pipename]</a> "
lines += "</div>"
lines += "<hr>"
for(var/i in 1 to atmos_pipe_recipes[category].len)
var/datum/pipe_recipe/PI = atmos_pipe_recipes[category][i]
lines += "<div class=\"item\">"
lines += "<a class='[recipe == PI ? "linkOn" : ""]' href='?src=\ref[src]&category=[category]&pipe_type=[i]'>[PI.name]</a>"
lines += "</div>"
lines += "</div>"
else if(screen == DISPOSALS_MODE)
for(var/category in disposal_pipe_recipes)
lines += "<div class=\"block\"><h3>[category]:</h3>"
for(var/i in 1 to disposal_pipe_recipes[category].len)
var/datum/pipe_recipe/PI = disposal_pipe_recipes[category][i]
lines += "<div class=\"item\">"
lines += "<a class='[recipe == PI ? "linkOn" : ""]' href='?src=\ref[src]&category=[category]&pipe_type=[i]'>[PI.name]</a>"
lines += "</div>"
lines += "</div>"
var/dat = lines.Join()
var/datum/browser/popup = new(user, "rpd", name, 300, 800, src)
popup.set_content("<TT>[dat]</TT>")
popup.add_head_content(icon_assets.css_tag())
popup.open()
/obj/item/weapon/pipe_dispenser/Topic(href, href_list, state = global.inventory_state)
/obj/item/weapon/pipe_dispenser/tgui_act(action, params)
SetupPipes()
if(..())
return 1
return TRUE
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
return 1
var/playeffect = TRUE // Do we spark the device
var/anyclicked = FALSE // Tells us if we need to refresh the window.
if(href_list["paint_color"])
paint_color = href_list["paint_color"]
playeffect = FALSE
anyclicked = TRUE
if(href_list["mode"])
mode = text2num(href_list["mode"])
anyclicked = TRUE
if(href_list["screen"])
if(mode == screen)
mode = text2num(href_list["screen"])
screen = text2num(href_list["screen"])
switch(screen)
if(DISPOSALS_MODE)
recipe = first_disposal
if(ATMOS_MODE)
recipe = first_atmos
p_dir = NORTH
playeffect = FALSE
anyclicked = TRUE
if(href_list["piping_layer"])
piping_layer = text2num(href_list["piping_layer"])
playeffect = FALSE
anyclicked = TRUE
if(href_list["pipe_type"])
recipe = all_pipe_recipes[href_list["category"]][text2num(href_list["pipe_type"])]
if(recipe.dirtype == PIPE_ONEDIR) // One hell of a hack for the fact that the image previews for the onedir types only show on the south, but the default pipe type is north.
p_dir = SOUTH // Did I fuck this up? Maybe. Or maybe it's just the icon files not being ready for an RPD.
else // If going to try and fix this hack, be aware the pipe dispensers might rely on pipes defaulting south instead of north.
return TRUE
var/playeffect = TRUE
switch(action)
if("color")
paint_color = params["paint_color"]
if("category")
category = text2num(params["category"])
switch(category)
if(DISPOSALS_CATEGORY)
recipe = first_disposal
if(ATMOS_CATEGORY)
recipe = first_atmos
// if(TRANSIT_CATEGORY)
// recipe = first_transit
p_dir = NORTH
p_flipped = FALSE
anyclicked = TRUE
if(href_list["dir"])
p_dir = text2dir(href_list["dir"])
p_flipped = text2num(href_list["flipped"])
playeffect = FALSE
anyclicked = TRUE
if(href_list["switch_wrench"])
wrench_mode = text2num(href_list["wrench_mode"])
anyclicked = TRUE
if(anyclicked)
if(playeffect)
spark_system.start()
playsound(src, 'sound/effects/pop.ogg', 50, 0)
src.interact(usr)
playeffect = FALSE
if("piping_layer")
piping_layer = text2num(params["piping_layer"])
playeffect = FALSE
// if("ducting_layer")
// ducting_layer = text2num(params["ducting_layer"])
// playeffect = FALSE
if("pipe_type")
var/static/list/recipes
if(!recipes)
recipes = GLOB.disposal_pipe_recipes + GLOB.atmos_pipe_recipes
recipe = recipes[params["category"]][text2num(params["pipe_type"])]
p_dir = NORTH
if("setdir")
p_dir = text2dir(params["dir"])
p_flipped = text2num(params["flipped"])
playeffect = FALSE
if("mode")
var/n = text2num(params["mode"])
if(mode & n)
mode &= ~n
else
mode |= n
if(playeffect)
spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, FALSE)
return TRUE
/obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user as mob, proximity)
if(!user.IsAdvancedToolUser() || istype(A, /turf/space/transit) || !proximity)
@@ -249,88 +177,89 @@
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe))
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
. = FALSE
switch(mode) //if we've gotten this var, the target is valid
if(PAINT_MODE) //Paint pipes
if(!istype(A, /obj/machinery/atmospherics/pipe))
return ..()
var/can_destroy_pipe = istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)
. = TRUE
if((mode & DESTROY_MODE) && can_destroy_pipe)
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
animate_deletion(A)
return
if((mode & PAINT_MODE)) //Paint pipes
if(istype(A, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = A
playsound(src, 'sound/machines/click.ogg', 50, 1)
P.change_color(pipe_colors[paint_color])
user.visible_message("<span class='notice'>[user] paints \the [P] [paint_color].</span>", "<span class='notice'>You paint \the [P] [paint_color].</span>")
return
if(EATING_MODE) //Eating pipes
if(!(istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)))
return ..()
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
animate_deletion(A)
if(mode & BUILD_MODE) //Making pipes
switch(category)
if(ATMOS_CATEGORY)
if(!can_make_pipe)
return ..()
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(istype(recipe, /datum/pipe_recipe/meter))
to_chat(user, "<span class='notice'>You start building a meter...</span>")
if(do_after(user, 2, target = A))
activate()
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
PM.setAttachLayer(queued_piping_layer)
if(mode & WRENCH_MODE)
do_wrench(PM, user)
else if(istype(recipe, /datum/pipe_recipe/pipe))
var/datum/pipe_recipe/pipe/R = recipe
to_chat(user, "<span class='notice'>You start building a pipe...</span>")
if(do_after(user, 2, target = A))
activate()
var/obj/machinery/atmospherics/path = R.pipe_type
var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
var/obj/item/pipe/P = new pipe_item_type(get_turf(A), path, queued_p_dir)
if(ATMOS_MODE) //Making pipes
if(!can_make_pipe)
return ..()
playsound(src, 'sound/machines/click.ogg', 50, 1)
if (istype(recipe, /datum/pipe_recipe/meter))
to_chat(user, "<span class='notice'>You start building a meter...</span>")
if(do_after(user, 2, target = A))
activate()
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
PM.setAttachLayer(queued_piping_layer)
if(wrench_mode)
do_wrench(PM, user)
else if(istype(recipe, /datum/pipe_recipe/pipe))
var/datum/pipe_recipe/pipe/R = recipe
to_chat(user, "<span class='notice'>You start building a pipe...</span>")
if(do_after(user, 2, target = A))
activate()
var/obj/machinery/atmospherics/path = R.pipe_type
var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
var/obj/item/pipe/P = new pipe_item_type(get_turf(A), path, queued_p_dir)
P.update()
P.add_fingerprint(usr)
if(R.paintable)
P.color = pipe_colors[paint_color]
P.setPipingLayer(queued_piping_layer)
if(queued_p_flipped)
P.do_a_flip()
if(mode & WRENCH_MODE)
do_wrench(P, user)
else
build_effect(P)
P.update()
P.add_fingerprint(usr)
if (R.paintable)
P.color = pipe_colors[paint_color]
P.setPipingLayer(queued_piping_layer)
if(queued_p_flipped)
P.do_a_flip()
if(wrench_mode)
do_wrench(P, user)
else
build_effect(P)
if(DISPOSALS_MODE) //Making disposals pipes
var/datum/pipe_recipe/disposal/R = recipe
if(!istype(R) || !can_make_pipe)
return ..()
A = get_turf(A)
if(istype(A, /turf/unsimulated))
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
to_chat(user, "<span class='notice'>You start building a disposals pipe...</span>")
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 4, target = A))
var/obj/structure/disposalconstruct/C = new(A, R.pipe_type, queued_p_dir, queued_p_flipped, R.subtype)
if(!C.can_place())
to_chat(user, "<span class='warning'>There's not enough room to build that here!</span>")
qdel(C)
if(DISPOSALS_CATEGORY) //Making disposals pipes
var/datum/pipe_recipe/disposal/R = recipe
if(!istype(R) || !can_make_pipe)
return ..()
A = get_turf(A)
if(istype(A, /turf/unsimulated))
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
to_chat(user, "<span class='notice'>You start building a disposals pipe...</span>")
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 4, target = A))
var/obj/structure/disposalconstruct/C = new(A, R.pipe_type, queued_p_dir, queued_p_flipped, R.subtype)
activate()
if(!C.can_place())
to_chat(user, "<span class='warning'>There's not enough room to build that here!</span>")
qdel(C)
return
C.add_fingerprint(usr)
C.update_icon()
if(wrench_mode)
do_wrench(C, user)
else
build_effect(C)
activate()
else
return ..()
C.add_fingerprint(usr)
C.update_icon()
if(mode & WRENCH_MODE)
do_wrench(C, user)
else
build_effect(C)
else
return ..()
/obj/item/weapon/pipe_dispenser/proc/build_effect(var/obj/P, var/time = 1.5)
set waitfor = FALSE
@@ -359,19 +288,11 @@
if(!resolved && tool && target)
tool.afterattack(target,user,1)
/obj/item/weapon/pipe_dispenser/proc/render_dir_img(icon_state, user, _dir, title, noimg, flipped = FALSE)
var/dirtext = dir2text(_dir)
var/attrs = " style=\"height:34px;width:34px;display:inline-block\""
if(_dir == p_dir && flipped == p_flipped)
attrs += " class=\"linkOn\""
if(icon_state)
var/img_tag = icon_assets.icon_tag("[dirtext]-[icon_state]")
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[attrs]>[img_tag]</a>"
else
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[attrs]>[noimg]</a>"
#undef ATMOS_CATEGORY
#undef DISPOSALS_CATEGORY
#undef TRANSIT_CATEGORY
#undef PAINT_MODE
#undef EATING_MODE
#undef ATMOS_MODE
#undef DISPOSALS_MODE
#undef BUILD_MODE
#undef WRENCH_MODE
#undef DESTROY_MODE
#undef PAINT_MODE
@@ -17,8 +17,7 @@
var/dna_hash = "\[UNSET\]"
var/fingerprint_hash = "\[UNSET\]"
var/sex = "\[UNSET\]"
var/icon/front
var/icon/side
var/front
var/primary_color = rgb(0,0,0) // Obtained by eyedroppering the stripe in the middle of the card
var/secondary_color = rgb(0,0,0) // Likewise for the oval in the top-left corner
@@ -34,30 +33,27 @@
/obj/item/weapon/card/id/examine(mob/user)
. = ..()
if(in_range(user, src))
show(user) //Not chat related
tgui_interact(user) //Not chat related
else
. += "<span class='warning'>It is too far away to read.</span>"
/obj/item/weapon/card/id/proc/prevent_tracking()
return 0
/obj/item/weapon/card/id/proc/show(mob/user as mob)
if(front && side)
user << browse_rsc(front, "front.png")
user << browse_rsc(side, "side.png")
var/datum/browser/popup = new(user, "idcard", name, 600, 250)
popup.set_content(dat())
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/item/weapon/card/id/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "IDCard", name)
ui.open()
/obj/item/weapon/card/id/proc/update_name()
name = "[src.registered_name]'s ID Card ([src.assignment])"
/obj/item/weapon/card/id/proc/set_id_photo(var/mob/M)
var/icon/charicon = cached_character_icon(M)
front = icon(charicon,dir = SOUTH)
side = icon(charicon,dir = WEST)
COMPILE_OVERLAYS(M)
SSoverlays.queue -= M
var/icon/F = getFlatIcon(M, defdir = SOUTH, no_anim = TRUE)
front = "'data:image/png;base64,[icon2base64(F)]'"
/mob/proc/set_id_info(var/obj/item/weapon/card/id/id_card)
id_card.age = 0
@@ -75,19 +71,19 @@
..()
id_card.age = age
/obj/item/weapon/card/id/proc/dat()
var/dat = ("<table><tr><td>")
dat += text("Name: []</A><BR>", registered_name)
dat += text("Sex: []</A><BR>\n", sex)
dat += text("Age: []</A><BR>\n", age)
dat += text("Rank: []</A><BR>\n", assignment)
dat += text("Fingerprint: []</A><BR>\n", fingerprint_hash)
dat += text("Blood Type: []<BR>\n", blood_type)
dat += text("DNA Hash: []<BR><BR>\n", dna_hash)
if(front && side)
dat +="<td align = center valign = top>Photo:<br><img src=front.png height=80 width=80 border=4><img src=side.png height=80 width=80 border=4></td>"
dat += "</tr></table>"
return dat
/obj/item/weapon/card/id/tgui_data(mob/user)
var/list/data = list()
data["registered_name"] = registered_name
data["sex"] = sex
data["age"] = age
data["assignment"] = assignment
data["fingerprint_hash"] = fingerprint_hash
data["blood_type"] = blood_type
data["dna_hash"] = dna_hash
data["photo_front"] = front
return data
/obj/item/weapon/card/id/attack_self(mob/user as mob)
user.visible_message("\The [user] shows you: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\
+51 -68
View File
@@ -1,5 +1,5 @@
#define TANK_MAX_RELEASE_PRESSURE (3*ONE_ATMOSPHERE)
#define TANK_DEFAULT_RELEASE_PRESSURE 24
#define TANK_DEFAULT_RELEASE_PRESSURE 21
#define TANK_IDEAL_PRESSURE 1015 //Arbitrary.
var/list/global/tank_gauge_cache = list()
@@ -217,90 +217,73 @@ var/list/global/tank_gauge_cache = list()
add_fingerprint(user)
if (!(src.air_contents))
return
ui_interact(user)
tgui_interact(user)
// There's GOT to be a better way to do this
if (src.proxyassembly.assembly)
src.proxyassembly.assembly.attack_self(user)
/obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/mob/living/carbon/location = null
/obj/item/weapon/tank/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Tank", name)
ui.open()
if(istype(loc, /obj/item/weapon/rig)) // check for tanks in rigs
if(istype(loc.loc, /mob/living/carbon))
location = loc.loc
else if(istype(loc, /mob/living/carbon))
location = loc
var/using_internal
if(istype(location))
if(location.internal==src)
using_internal = 1
// this is the data which will be sent to the ui
var/data[0]
/obj/item/weapon/tank/tgui_data(mob/user)
var/list/data = list()
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["releasePressure"] = round(distribute_pressure ? distribute_pressure : 0)
data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
data["minReleasePressure"] = 0
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
data["valveOpen"] = using_internal ? 1 : 0
data["maskConnected"] = 0
if(istype(location))
var/mask_check = 0
var/mob/living/carbon/C = user
if(!istype(C))
C = loc.loc
if(!istype(C))
return data
if(location.internal == src) // if tank is current internal
mask_check = 1
else if(src in location) // or if tank is in the mobs possession
if(!location.internal) // and they do not have any active internals
mask_check = 1
else if(istype(src.loc, /obj/item/weapon/rig) && src.loc in location) // or the rig is in the mobs possession
if(!location.internal) // and they do not have any active internals
mask_check = 1
if(C.internal == src)
data["connected"] = TRUE
else
data["connected"] = FALSE
if(mask_check)
if(location.wear_mask && (location.wear_mask.item_flags & AIRTIGHT))
data["maskConnected"] = 1
else if(istype(location, /mob/living/carbon/human))
var/mob/living/carbon/human/H = location
if(H.head && (H.head.item_flags & AIRTIGHT))
data["maskConnected"] = 1
data["maskConnected"] = FALSE
if(C.wear_mask && (C.wear_mask.item_flags & AIRTIGHT))
data["maskConnected"] = TRUE
else if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.head && (H.head.item_flags & AIRTIGHT))
data["maskConnected"] = TRUE
// 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)
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, "tanks.tmpl", "Tank", 500, 300)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
return data
/obj/item/weapon/tank/Topic(href, href_list)
..()
if (usr.stat|| usr.restrained())
return 0
if (src.loc != usr)
return 0
/obj/item/weapon/tank/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("pressure")
var/pressure = params["pressure"]
if(pressure == "reset")
pressure = TANK_DEFAULT_RELEASE_PRESSURE
. = TRUE
else if(pressure == "min")
pressure = 0
. = TRUE
else if(pressure == "max")
pressure = TANK_MAX_RELEASE_PRESSURE
. = TRUE
else if(text2num(pressure) != null)
pressure = text2num(pressure)
. = TRUE
if(.)
distribute_pressure = clamp(round(pressure), 0, TANK_MAX_RELEASE_PRESSURE)
if("toggle")
toggle_valve(usr)
. = TRUE
if (href_list["dist_p"])
if (href_list["dist_p"] == "reset")
src.distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
else if (href_list["dist_p"] == "max")
src.distribute_pressure = TANK_MAX_RELEASE_PRESSURE
else
var/cp = text2num(href_list["dist_p"])
src.distribute_pressure += cp
src.distribute_pressure = min(max(round(src.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE)
if (href_list["stat"])
toggle_valve(usr)
src.add_fingerprint(usr)
return 1
add_fingerprint(usr)
/obj/item/weapon/tank/proc/toggle_valve(var/mob/user)
if(istype(loc,/mob/living/carbon))
+73 -71
View File
@@ -1,3 +1,5 @@
#define TANK_DISPENSER_CAPACITY 10
/obj/structure/dispenser
name = "tank storage unit"
desc = "A simple yet bulky storage device for gas tanks. Has room for up to ten oxygen tanks, and ten phoron tanks."
@@ -6,10 +8,8 @@
density = 1
anchored = 1.0
w_class = ITEMSIZE_HUGE
var/oxygentanks = 10
var/phorontanks = 10
var/list/oxytanks = list() //sorry for the similar var names
var/list/platanks = list()
var/oxygentanks = TANK_DISPENSER_CAPACITY
var/phorontanks = TANK_DISPENSER_CAPACITY
/obj/structure/dispenser/oxygen
@@ -19,10 +19,14 @@
oxygentanks = 0
/obj/structure/dispenser/New()
/obj/structure/dispenser/Initialize()
. = ..()
for(var/i in 1 to oxygentanks)
new /obj/item/weapon/tank/oxygen(src)
for(var/i in 1 to phorontanks)
new /obj/item/weapon/tank/phoron(src)
update_icon()
/obj/structure/dispenser/update_icon()
overlays.Cut()
switch(oxygentanks)
@@ -32,49 +36,44 @@
if(1 to 4) overlays += "phoron-[phorontanks]"
if(5 to INFINITY) overlays += "phoron-5"
/obj/structure/dispenser/attack_ai(mob/user as mob)
/obj/structure/dispenser/attack_ai(mob/user)
// This looks silly, but robots also call attack_ai, and they're allowed physical state stuff.
if(user.Adjacent(src))
return attack_hand(user)
..()
/obj/structure/dispenser/attack_hand(mob/user as mob)
user.set_machine(src)
var/dat = "[src]<br><br>"
dat += "Oxygen tanks: [oxygentanks] - [oxygentanks ? "<A href='?src=\ref[src];oxygen=1'>Dispense</A>" : "empty"]<br>"
dat += "Phoron tanks: [phorontanks] - [phorontanks ? "<A href='?src=\ref[src];phoron=1'>Dispense</A>" : "empty"]"
user << browse(dat, "window=dispenser")
onclose(user, "dispenser")
return
/obj/structure/dispenser/attack_hand(mob/user)
tgui_interact(user)
/obj/structure/dispenser/tgui_state(mob/user)
return GLOB.tgui_physical_state
/obj/structure/dispenser/attackby(obj/item/I as obj, mob/user as mob)
/obj/structure/dispenser/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TankDispenser", name)
ui.open()
/obj/structure/dispenser/tgui_data(mob/user)
var/list/data = list()
data["oxygen"] = oxygentanks
data["plasma"] = phorontanks
return data
/obj/structure/dispenser/attackby(obj/item/I, mob/user)
var/full
if(istype(I, /obj/item/weapon/tank/oxygen) || istype(I, /obj/item/weapon/tank/air) || istype(I, /obj/item/weapon/tank/anesthetic))
if(oxygentanks < 10)
user.drop_item()
I.loc = src
oxytanks.Add(I)
if(oxygentanks < TANK_DISPENSER_CAPACITY)
oxygentanks++
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
if(oxygentanks < 5)
update_icon()
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
updateUsrDialog()
return
if(istype(I, /obj/item/weapon/tank/phoron))
if(phorontanks < 10)
user.drop_item()
I.loc = src
platanks.Add(I)
full = TRUE
else if(istype(I, /obj/item/weapon/tank/phoron))
if(phorontanks < TANK_DISPENSER_CAPACITY)
phorontanks++
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
if(oxygentanks < 6)
update_icon()
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
updateUsrDialog()
return
if(I.is_wrench())
full = TRUE
else if(I.is_wrench())
if(anchored)
to_chat(user, "<span class='notice'>You lean down and unwrench [src].</span>")
anchored = 0
@@ -82,39 +81,42 @@
to_chat(user, "<span class='notice'>You wrench [src] into place.</span>")
anchored = 1
return
/obj/structure/dispenser/Topic(href, href_list)
if(usr.stat || usr.restrained())
else if(user.a_intent != I_HURT)
to_chat(user, "<span class='notice'>[I] does not fit into [src].</span>")
return
if(Adjacent(usr))
usr.set_machine(src)
if(href_list["oxygen"])
if(oxygentanks > 0)
var/obj/item/weapon/tank/oxygen/O
if(oxytanks.len == oxygentanks)
O = oxytanks[1]
oxytanks.Remove(O)
else
O = new /obj/item/weapon/tank/oxygen(loc)
O.loc = loc
to_chat(usr, "<span class='notice'>You take [O] out of [src].</span>")
oxygentanks--
update_icon()
if(href_list["phoron"])
if(phorontanks > 0)
var/obj/item/weapon/tank/phoron/P
if(platanks.len == phorontanks)
P = platanks[1]
platanks.Remove(P)
else
P = new /obj/item/weapon/tank/phoron(loc)
P.loc = loc
to_chat(usr, "<span class='notice'>You take [P] out of [src].</span>")
phorontanks--
update_icon()
add_fingerprint(usr)
updateUsrDialog()
else
usr << browse(null, "window=dispenser")
return ..()
if(full)
to_chat(user, "<span class='notice'>[src] can't hold any more of [I].</span>")
return
return
if(!user.unEquip(I, target = src))
return
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
update_icon()
/obj/structure/dispenser/tgui_act(action, params)
if(..())
return
switch(action)
if("plasma")
var/obj/item/weapon/tank/phoron/tank = locate() in src
if(tank && Adjacent(usr))
usr.put_in_hands(tank)
phorontanks--
. = TRUE
playsound(src, 'sound/machines/vending/vending_drop.ogg', 100, 1, 1)
if("oxygen")
var/obj/item/weapon/tank/tank = null
for(var/obj/item/weapon/tank/T in src)
if(istype(T, /obj/item/weapon/tank/oxygen) || istype(T, /obj/item/weapon/tank/air) || istype(T, /obj/item/weapon/tank/anesthetic))
tank = T
break
if(tank && Adjacent(usr))
usr.put_in_hands(tank)
oxygentanks--
. = TRUE
playsound(src, 'sound/machines/vending/vending_drop.ogg', 100, 1, 1)
update_icon()
+40 -45
View File
@@ -31,58 +31,53 @@
if(holder)
holder.update_icon()
/obj/item/device/assembly/signaler/interact(var/mob/user)
var/t1 = "-------"
var/dat = {"
<TT>
/obj/item/device/assembly/signaler/interact(mob/user)
if(..())
return TRUE
tgui_interact(user)
<A href='byond://?src=\ref[src];send=1'>Send Signal</A><BR>
<B>Frequency/Code</B> for signaler:<BR>
Frequency:
<A href='byond://?src=\ref[src];freq=-10'>-</A>
<A href='byond://?src=\ref[src];freq=-2'>-</A>
[format_frequency(src.frequency)]
<A href='byond://?src=\ref[src];freq=2'>+</A>
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
/obj/item/device/assembly/signaler/tgui_state(mob/user)
return GLOB.tgui_deep_inventory_state
Code:
<A href='byond://?src=\ref[src];code=-5'>-</A>
<A href='byond://?src=\ref[src];code=-1'>-</A>
[src.code]
<A href='byond://?src=\ref[src];code=1'>+</A>
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
[t1]
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
/obj/item/device/assembly/signaler/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Signaler", name)
ui.open()
/obj/item/device/assembly/signaler/Topic(href, href_list, state = deep_inventory_state)
/obj/item/device/assembly/signaler/tgui_data(mob/user)
var/list/data = list()
data["frequency"] = frequency
data["code"] = code
data["minFrequency"] = RADIO_LOW_FREQ
data["maxFrequency"] = RADIO_HIGH_FREQ
return data
/obj/item/device/assembly/signaler/tgui_act(action, params)
if(..())
return TRUE
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=radio")
onclose(usr, "radio")
return
switch(action)
if("signal")
INVOKE_ASYNC(src, .proc/signal)
. = TRUE
if("freq")
frequency = unformat_frequency(params["freq"])
frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(frequency)
. = TRUE
if("code")
code = text2num(params["code"])
code = clamp(round(code), 1, 100)
. = TRUE
if("reset")
if(params["reset"] == "freq")
set_frequency(initial(frequency))
else
code = initial(code)
. = TRUE
if (href_list["freq"])
var/new_frequency = (frequency + text2num(href_list["freq"]))
if(new_frequency < RADIO_LOW_FREQ || new_frequency > RADIO_HIGH_FREQ)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
if(href_list["code"])
src.code += text2num(href_list["code"])
src.code = round(src.code)
src.code = min(100, src.code)
src.code = max(1, src.code)
if(href_list["send"])
spawn( 0 )
signal()
if(usr)
attack_self(usr)
update_icon()
/obj/item/device/assembly/signaler/attackby(var/obj/item/weapon/W, mob/user, params)
if(issignaler(W))
+6 -6
View File
@@ -100,12 +100,12 @@
mode = "sec"
flash_protection = FLASH_PROTECTION_MAJOR
action_button_name = "AR Console (Security Alerts)"
arscreen_path = /datum/nano_module/alarm_monitor/security
tgarscreen_path = /datum/tgui_module/alarm_monitor/security/glasses
enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_WANTED,VIS_AUGMENTED)
ar_interact(var/mob/living/carbon/human/user)
if(arscreen)
arscreen.ui_interact(user,"main",null,1,glasses_state)
if(tgarscreen)
tgarscreen.tgui_interact(user)
return 1
/obj/item/clothing/glasses/omnihud/eng
@@ -115,11 +115,11 @@
mode = "eng"
flash_protection = FLASH_PROTECTION_MAJOR
action_button_name = "AR Console (Station Alerts)"
arscreen_path = /datum/nano_module/alarm_monitor/engineering
tgarscreen_path = /datum/tgui_module/alarm_monitor/engineering/glasses
ar_interact(var/mob/living/carbon/human/user)
if(arscreen)
arscreen.ui_interact(user,"main",null,1,glasses_state)
if(tgarscreen)
tgarscreen.tgui_interact(user)
return 1
/obj/item/clothing/glasses/omnihud/rnd
@@ -15,7 +15,7 @@
to_chat(usr, "Your module is not installed in a hardsuit.")
return
module.holder.ui_interact(usr, nano_state = contained_state)
module.holder.tgui_interact(usr, custom_state = GLOB.tgui_contained_state)
/obj/item/rig_module/ai_container
@@ -134,7 +134,7 @@
if(!target)
if(ai_card)
if(istype(ai_card,/obj/item/device/aicard))
ai_card.ui_interact(H, state = deep_inventory_state)
ai_card.tgui_interact(H, custom_state = deep_inventory_state)
else
eject_ai(H)
update_verb_holder()
+2 -115
View File
@@ -28,8 +28,8 @@
var/suit_state //The string used for the suit's icon_state.
var/interface_path = "hardsuit.tmpl"
var/ai_interface_path = "hardsuit.tmpl"
var/interface_path = "RIGSuit"
var/ai_interface_path = "RIGSuit"
var/interface_title = "Hardsuit Controller"
var/wearer_move_delay //Used for AI moving.
var/ai_controlled_move_delay = 10
@@ -576,81 +576,6 @@
cell.use(cost*10)
return 1
/obj/item/weapon/rig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/nano_state = inventory_state)
if(!user)
return
var/list/data = list()
if(selected_module)
data["primarysystem"] = "[selected_module.interface_name]"
if(src.loc != user)
data["ai"] = 1
data["seals"] = "[src.canremove]"
data["sealing"] = "[src.sealing]"
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
data["boots"] = (boots ? "[boots.name]" : "None.")
data["chest"] = (chest ? "[chest.name]" : "None.")
data["charge"] = cell ? round(cell.charge,1) : 0
data["maxcharge"] = cell ? cell.maxcharge : 0
data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0
data["emagged"] = subverted
data["coverlock"] = locked
data["interfacelock"] = interface_locked
data["aicontrol"] = control_overridden
data["aioverride"] = ai_override_enabled
data["securitycheck"] = security_check_enabled
data["malf"] = malfunction_delay
var/list/module_list = list()
var/i = 1
for(var/obj/item/rig_module/module in installed_modules)
var/list/module_data = list(
"index" = i,
"name" = "[module.interface_name]",
"desc" = "[module.interface_desc]",
"can_use" = "[module.usable]",
"can_select" = "[module.selectable]",
"can_toggle" = "[module.toggleable]",
"is_active" = "[module.active]",
"engagecost" = module.use_power_cost*10,
"activecost" = module.active_power_cost*10,
"passivecost" = module.passive_power_cost*10,
"engagestring" = module.engage_string,
"activatestring" = module.activate_string,
"deactivatestring" = module.deactivate_string,
"damage" = module.damage
)
if(module.charges && module.charges.len)
module_data["charges"] = list()
var/datum/rig_charge/selected = module.charges[module.charge_selected]
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
for(var/chargetype in module.charges)
var/datum/rig_charge/charge = module.charges[chargetype]
module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]"))
module_list += list(module_data)
i++
if(module_list.len)
data["modules"] = module_list
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, state = nano_state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/item/weapon/rig/update_icon(var/update_mob_icon)
//TODO: Maybe consider a cache for this (use mob_icon as blank canvas, use suit icon overlay).
@@ -698,44 +623,6 @@
return 1
//TODO: Fix Topic vulnerabilities for malfunction and AI override.
/obj/item/weapon/rig/Topic(href,href_list)
if(!check_suit_access(usr))
return 0
if(href_list["toggle_piece"])
if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying))
return 0
toggle_piece(href_list["toggle_piece"], usr)
else if(href_list["toggle_seals"])
toggle_seals(usr)
else if(href_list["interact_module"])
var/module_index = text2num(href_list["interact_module"])
if(module_index > 0 && module_index <= installed_modules.len)
var/obj/item/rig_module/module = installed_modules[module_index]
switch(href_list["module_mode"])
if("activate")
module.activate()
if("deactivate")
module.deactivate()
if("engage")
module.engage()
if("select")
selected_module = module
if("select_charge_type")
module.charge_selected = href_list["charge_type"]
else if(href_list["toggle_ai_control"])
ai_override_enabled = !ai_override_enabled
notify_ai("Synthetic suit control has been [ai_override_enabled ? "enabled" : "disabled"].")
else if(href_list["toggle_suit_lock"])
locked = !locked
usr.set_machine(src)
src.add_fingerprint(usr)
return 0
/obj/item/weapon/rig/proc/notify_ai(var/message)
for(var/obj/item/rig_module/ai_container/module in installed_modules)
if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat)
@@ -0,0 +1,164 @@
/*
* This defines the global UI for RIGSuits.
* It has all of the relevant TGUI procs, but it's entry point is in rig_verbs.dm
* as part of rig/proc/hardsuit_interface().
*/
/*
* tgui_interact() is the proc that opens the UI. It doesn't really do anything else, unlike NanoV1.
* We add an extra argument, custom_state, for the things that want a custom state for their UI.
*/
/obj/item/weapon/rig/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, (loc != usr ? ai_interface_path : interface_path), interface_title)
ui.open()
if(custom_state)
ui.set_state(custom_state)
/*
* tgui_state() gives the UI the state to use by default.
*/
/obj/item/weapon/rig/tgui_state()
return GLOB.tgui_inventory_state
/*
* tgui_status() is middlewere for objects to add little exceptions or special cases to the state they use.
* In this case, we're using it in order to make the UI refuse to let the user press any buttons if they're
* not authorized to do so.
* This saves us two lines of code in tgui_act().
*/
/obj/item/weapon/rig/tgui_status(mob/user, datum/tgui_state/state)
. = ..()
if(!check_suit_access(user))
// Forces the UI to never go interactive,
// but doesn't interfere with state saying to close.
. = min(., STATUS_UPDATE)
/*
* tgui_data() is the heavy lifter, it gives the UI it's relevant datastructure every SStgui tick.
*/
/obj/item/weapon/rig/tgui_data(mob/user)
var/list/data = list()
if(selected_module)
data["primarysystem"] = "[selected_module.interface_name]"
else
data["primarysystem"] = null
if(loc != user)
data["ai"] = TRUE
else
data["ai"] = FALSE
data["sealed"] = !canremove
data["sealing"] = sealing
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
data["boots"] = (boots ? "[boots.name]" : "None.")
data["chest"] = (chest ? "[chest.name]" : "None.")
data["helmetDeployed"] = (helmet && helmet.loc == loc)
data["gauntletsDeployed"] = (gloves && gloves.loc == loc)
data["bootsDeployed"] = (boots && boots.loc == loc)
data["chestDeployed"] = (chest && chest.loc == loc)
data["charge"] = cell ? round(cell.charge,1) : 0
data["maxcharge"] = cell ? cell.maxcharge : 0
data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0
data["emagged"] = subverted
data["coverlock"] = locked
data["interfacelock"] = interface_locked
data["aicontrol"] = control_overridden
data["aioverride"] = ai_override_enabled
data["securitycheck"] = security_check_enabled
data["malf"] = malfunction_delay
var/list/module_list = list()
if(!canremove && !sealing)
var/i = 1
for(var/obj/item/rig_module/module in installed_modules)
var/list/module_data = list(
"index" = i,
"name" = "[module.interface_name]",
"desc" = "[module.interface_desc]",
"can_use" = module.usable,
"can_select" = module.selectable,
"can_toggle" = module.toggleable,
"is_active" = module.active,
"engagecost" = module.use_power_cost*10,
"activecost" = module.active_power_cost*10,
"passivecost" = module.passive_power_cost*10,
"engagestring" = module.engage_string,
"activatestring" = module.activate_string,
"deactivatestring" = module.deactivate_string,
"damage" = module.damage
)
if(module.charges && module.charges.len)
module_data["charges"] = list()
var/datum/rig_charge/selected = module.charges[module.charge_selected]
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
for(var/chargetype in module.charges)
var/datum/rig_charge/charge = module.charges[chargetype]
module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]"))
module_list += list(module_data)
i++
if(module_list.len)
data["modules"] = module_list
else
data["modules"] = list()
return data
/*
* tgui_act() is the TGUI equivelent of Topic(). It's responsible for all of the "actions" you can take in the UI.
*/
/obj/item/weapon/rig/tgui_act(action, params)
// This parent call is very important, as it's responsible for invoking tgui_status and checking our state's rules.
if(..())
return TRUE
add_fingerprint(usr)
switch(action)
if("toggle_seals")
toggle_seals(usr)
. = TRUE
if("toggle_ai_control")
ai_override_enabled = !ai_override_enabled
notify_ai("Synthetic suit control has been [ai_override_enabled ? "enabled" : "disabled"].")
. = TRUE
if("toggle_suit_lock")
locked = !locked
. = TRUE
if("toggle_piece")
if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying))
return FALSE
toggle_piece(params["piece"], usr)
. = TRUE
if("interact_module")
var/module_index = text2num(params["module"])
if(module_index > 0 && module_index <= installed_modules.len)
var/obj/item/rig_module/module = installed_modules[module_index]
switch(params["module_mode"])
if("select")
selected_module = module
. = TRUE
if("engage")
module.engage()
. = TRUE
if("toggle")
if(module.active)
module.deactivate()
else
module.activate()
. = TRUE
if("select_charge_type")
module.charge_selected = params["charge_type"]
. = TRUE
@@ -7,7 +7,7 @@
set src = usr.contents
if(wearer && (wearer.back == src || wearer.belt == src))
ui_interact(usr)
tgui_interact(usr)
/obj/item/weapon/rig/verb/toggle_vision()
@@ -14,111 +14,107 @@
/obj/machinery/computer/drone_control/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/drone_control/tgui_status(mob/user)
if(!allowed(user))
return STATUS_CLOSE
return ..()
/obj/machinery/computer/drone_control/attack_hand(var/mob/user as mob)
if(..())
return
if(!allowed(user))
to_chat(user, "<span class='danger'>Access denied.</span>")
return
tgui_interact(user)
user.set_machine(src)
var/dat
dat += "<B>Maintenance Units</B><BR>"
/obj/machinery/computer/drone_control/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "DroneConsole", name)
ui.open()
/obj/machinery/computer/drone_control/tgui_data(mob/user)
var/list/data = list()
data["drones"] = list()
for(var/mob/living/silicon/robot/drone/D in mob_list)
if(D.z != src.z)
if(D.z != z)
continue
if(D.foreign_droid)
continue
data["drones"].Add(list(list(
"name" = D.real_name,
"active" = D.stat != 2,
"charge" = D.cell.charge,
"maxCharge" = D.cell.maxcharge,
"loc" = "[get_area(D)]",
"ref" = "\ref[D]",
)))
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE</FONT>" : "<font color='green'>ACTIVE</FONT>"])"
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
dat += "<BR>Currently located in: [get_area(D)]."
dat += "<BR><A href='?src=\ref[src];resync=\ref[D]'>Resync</A> | <A href='?src=\ref[src];shutdown=\ref[D]'>Shutdown</A></font>"
data["fabricator"] = dronefab
data["fabPower"] = dronefab?.produce_drones
dat += "<BR><BR><B>Request drone presence in area:</B> <A href='?src=\ref[src];setarea=1'>[drone_call_area]</A> (<A href='?src=\ref[src];ping=1'>Send ping</A>)"
data["areas"] = tagger_locations
data["selected_area"] = "[drone_call_area]"
dat += "<BR><BR><B>Drone fabricator</B>: "
dat += "[dronefab ? "<A href='?src=\ref[src];toggle_fab=1'>[(dronefab.produce_drones && !(dronefab.stat & NOPOWER)) ? "ACTIVE" : "INACTIVE"]</A>" : "<font color='red'><b>FABRICATOR NOT DETECTED.</b></font> (<A href='?src=\ref[src];search_fab=1'>search</a>)"]"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
return data
/obj/machinery/computer/drone_control/Topic(href, href_list)
/obj/machinery/computer/drone_control/tgui_act(action, params)
if(..())
return
return TRUE
if(!allowed(usr))
to_chat(usr, "<span class='danger'>Access denied.</span>")
return
switch(action)
if("set_dcall_area")
var/t_area = params["area"]
if(!t_area || !(t_area in tagger_locations))
return
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
drone_call_area = t_area
to_chat(usr, "<span class='notice'>You set the area selector to [drone_call_area].</span>")
if (href_list["setarea"])
if("ping")
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
for(var/mob/living/silicon/robot/drone/D in player_list)
if(D.stat == 0)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
//Probably should consider using another list, but this one will do.
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in tagger_locations
if("resync")
var/mob/living/silicon/robot/drone/D = locate(params["ref"])
if(!t_area)
return
if(D.stat != 2)
to_chat(usr, "<span class='danger'>You issue a law synchronization directive for the drone.</span>")
D.law_resync()
drone_call_area = t_area
to_chat(usr, "<span class='notice'>You set the area selector to [drone_call_area].</span>")
if("shutdown")
var/mob/living/silicon/robot/drone/D = locate(params["ref"])
else if (href_list["ping"])
if(D.stat != 2)
to_chat(usr, "<span class='danger'>You issue a kill command for the unfortunate drone.</span>")
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
D.shut_down()
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
for(var/mob/living/silicon/robot/drone/D in player_list)
if(D.stat == 0)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
if("search_fab")
if(dronefab)
return
else if (href_list["resync"])
for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
if(fab.stat & NOPOWER)
continue
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
dronefab = fab
to_chat(usr, "<span class='notice'>Drone fabricator located.</span>")
return
if(D.stat != 2)
to_chat(usr, "<span class='danger'>You issue a law synchronization directive for the drone.</span>")
D.law_resync()
else if (href_list["shutdown"])
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
if(D.stat != 2)
to_chat(usr, "<span class='danger'>You issue a kill command for the unfortunate drone.</span>")
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
D.shut_down()
else if (href_list["search_fab"])
if(dronefab)
return
for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
if(fab.stat & NOPOWER)
continue
dronefab = fab
to_chat(usr, "<span class='notice'>Drone fabricator located.</span>")
return
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
else if (href_list["toggle_fab"])
if(!dronefab)
return
if(get_dist(src,dronefab) > 3)
dronefab = null
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
return
dronefab.produce_drones = !dronefab.produce_drones
to_chat(usr, "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>")
if("toggle_fab")
if(!dronefab)
return
src.updateUsrDialog()
if(get_dist(src,dronefab) > 3)
dronefab = null
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
return
dronefab.produce_drones = !dronefab.produce_drones
to_chat(usr, "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>")
+8 -8
View File
@@ -1,11 +1,11 @@
/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/datum/tgui_module/alarm_monitor/all/robot/alarm_monitor
var/datum/tgui_module/atmos_control/robot/atmos_control
var/datum/tgui_module/crew_monitor/robot/crew_monitor
var/datum/nano_module/law_manager/law_manager
var/datum/nano_module/power_monitor/power_monitor
var/datum/nano_module/rcon/rcon
var/datum/tgui_module/power_monitor/robot/power_monitor
var/datum/tgui_module/rcon/robot/rcon
/mob/living/silicon
var/list/silicon_subsystems = list(
@@ -49,7 +49,7 @@
set name = "Alarm Monitor"
set category = "Subystems"
alarm_monitor.ui_interact(usr, state = self_state)
alarm_monitor.tgui_interact(usr)
/********************
* Atmos Control *
@@ -58,7 +58,7 @@
set category = "Subystems"
set name = "Atmospherics Control"
atmos_control.ui_interact(usr, state = self_state)
atmos_control.tgui_interact(usr)
/********************
* Crew Monitor *
@@ -85,7 +85,7 @@
set category = "Subystems"
set name = "Power Monitor"
power_monitor.ui_interact(usr, state = self_state)
power_monitor.tgui_interact(usr)
/************
* RCON *
@@ -94,4 +94,4 @@
set category = "Subystems"
set name = "RCON"
rcon.ui_interact(usr, state = self_state)
rcon.tgui_interact(usr)
@@ -582,7 +582,6 @@
// Do the initial caching of the player's body icons.
new_character.force_update_limbs()
new_character.update_icons_body()
new_character.update_eyes()
new_character.key = key //Manually transfer the key to log them in
@@ -57,41 +57,43 @@
ntnet_global.add_log("Quantum relay switched from overload recovery mode to normal operation mode.")
..()
/obj/machinery/ntnet_relay/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
/obj/machinery/ntnet_relay/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "NTNetRelay", src)
ui.open()
/obj/machinery/ntnet_relay/tgui_data(mob/user)
var/list/data = list()
data["enabled"] = enabled
data["dos_capacity"] = dos_capacity
data["dos_overload"] = dos_overload
data["dos_crashed"] = dos_failure
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_relay.tmpl", "NTNet Quantum Relay", 500, 300, state = state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
return data
/obj/machinery/ntnet_relay/attack_hand(var/mob/living/user)
ui_interact(user)
tgui_interact(user)
/obj/machinery/ntnet_relay/Topic(href, href_list)
/obj/machinery/ntnet_relay/tgui_act(action, params)
if(..())
return 1
if(href_list["restart"])
dos_overload = 0
dos_failure = 0
update_icon()
ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.")
return 1
else if(href_list["toggle"])
enabled = !enabled
ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].")
update_icon()
return 1
else if(href_list["purge"])
ntnet_global.banned_nids.Cut()
ntnet_global.add_log("Manual override: Network blacklist cleared.")
return 1
return TRUE
switch(action)
if("restart")
dos_overload = 0
dos_failure = 0
update_icon()
ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.")
. = TRUE
if("toggle")
enabled = !enabled
ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].")
update_icon()
. = TRUE
if("purge")
ntnet_global.banned_nids.Cut()
ntnet_global.add_log("Manual override: Network blacklist cleared.")
. = TRUE
/obj/machinery/ntnet_relay/New()
..()
@@ -1,7 +1,7 @@
/datum/computer_file/program/alarm_monitor
filename = "alarmmonitoreng"
filedesc = "Alarm Monitoring (Engineering)"
nanomodule_path = /datum/nano_module/alarm_monitor/engineering
tguimodule_path = /datum/tgui_module/alarm_monitor/engineering/ntos
ui_header = "alarm_green.gif"
program_icon_state = "alert-green"
program_key_state = "atmos_key"
@@ -15,8 +15,8 @@
/datum/computer_file/program/alarm_monitor/process_tick()
..()
var/datum/nano_module/alarm_monitor/NMA = NM
if(istype(NMA) && NMA.has_major_alarms())
var/datum/tgui_module/alarm_monitor/TMA = TM
if(istype(TMA) && TMA.has_major_alarms())
if(!has_alert)
program_icon_state = "alert-red"
ui_header = "alarm_red.gif"
@@ -29,112 +29,3 @@
update_computer_icon()
has_alert = 0
return 1
/datum/nano_module/alarm_monitor
name = "Alarm monitor"
var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use.
var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user.
//available_to_ai = FALSE
/datum/nano_module/alarm_monitor/New()
..()
alarm_handlers = list()
/datum/nano_module/alarm_monitor/all/New()
..()
alarm_handlers = SSalarm.all_handlers
/datum/nano_module/alarm_monitor/engineering/New()
..()
alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm)
/datum/nano_module/alarm_monitor/security/New()
..()
alarm_handlers = list(camera_alarm, motion_alarm)
/datum/nano_module/alarm_monitor/proc/register_alarm(var/object, var/procName)
for(var/datum/alarm_handler/AH in alarm_handlers)
AH.register_alarm(object, procName)
/datum/nano_module/alarm_monitor/proc/unregister_alarm(var/object)
for(var/datum/alarm_handler/AH in alarm_handlers)
AH.unregister_alarm(object)
/datum/nano_module/alarm_monitor/proc/all_alarms()
var/z = get_z(nano_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.visible_alarms(z)
return all_alarms
/datum/nano_module/alarm_monitor/proc/major_alarms()
var/z = get_z(nano_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.major_alarms(z)
return all_alarms
// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise.
/datum/nano_module/alarm_monitor/proc/has_major_alarms()
var/z = get_z(nano_host())
for(var/datum/alarm_handler/AH in alarm_handlers)
if(AH.has_major_alarms(z))
return 1
return 0
/datum/nano_module/alarm_monitor/proc/minor_alarms()
var/z = get_z(nano_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.minor_alarms(z)
return all_alarms
/datum/nano_module/alarm_monitor/Topic(ref, href_list)
if(..())
return 1
if(href_list["switchTo"])
var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras
if(!C)
return
usr.switch_to_camera(C)
return 1
/datum/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
var/categories[0]
var/z = get_z(nano_host())
for(var/datum/alarm_handler/AH in alarm_handlers)
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
for(var/datum/alarm/A in AH.visible_alarms(z))
var/cameras[0]
var/lost_sources[0]
if(isAI(user))
for(var/obj/machinery/camera/C in A.cameras())
cameras[++cameras.len] = C.nano_structure()
for(var/datum/alarm_source/AS in A.sources)
if(!AS.source)
lost_sources[++lost_sources.len] = AS.source_name
categories[categories.len]["alarms"] += list(list(
"name" = sanitize("[A.alarm_name()]" + "[A.max_severity() > 1 ? "(MAJOR)" : ""]"),
"origin_lost" = A.origin == null,
"has_cameras" = cameras.len,
"cameras" = cameras,
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
data["categories"] = categories
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state)
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
@@ -1,7 +1,7 @@
/datum/computer_file/program/atmos_control
filename = "atmoscontrol"
filedesc = "Atmosphere Control"
nanomodule_path = /datum/nano_module/atmos_control
tguimodule_path = /datum/tgui_module/atmos_control/ntos
program_icon_state = "atmos_control"
program_key_state = "atmos_key"
program_menu_icon = "shuffle"
@@ -12,96 +12,3 @@
requires_ntnet_feature = NTNET_SYSTEMCONTROL
usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE
size = 17
/datum/nano_module/atmos_control
name = "Atmospherics Control"
var/obj/access = new()
var/emagged = 0
var/ui_ref
var/list/monitored_alarms = list()
/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 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.len ? monitored_alarms : machines)
if(alarm)
var/datum/topic_state/TS = generate_state(alarm)
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
return 1
/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 = default_state)
var/list/data = host.initial_data()
var/alarms[0]
var/z = get_z(nano_host())
var/list/map_levels = using_map.get_map_levels(z)
data["map_levels"] = map_levels
// TODO: Move these to a cache, similar to cameras
for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines))
if(!monitored_alarms.len && alarm.alarms_hidden)
continue
if(!(alarm.z in map_levels))
continue
alarms[++alarms.len] = list(
"name" = sanitize(alarm.name),
"ref"= "\ref[alarm]",
"danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm),
"x" = alarm.x,
"y" = alarm.y,
"z" = alarm.z)
data["alarms"] = alarms
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625, state = state)
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
ui.auto_update_layout = 1
// adding a template with the key "mapContent" enables the map ui functionality
ui.add_template("mapContent", "atmos_control_map_content.tmpl")
// adding a template with the key "mapHeader" replaces the map header content
ui.add_template("mapHeader", "atmos_control_map_header.tmpl")
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(0)
ui_ref = ui
/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(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"] = 1
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.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO) || (access_ce in user.GetAccess()))
@@ -1,7 +1,7 @@
/datum/computer_file/program/power_monitor
filename = "powermonitor"
filedesc = "Power Monitoring"
nanomodule_path = /datum/nano_module/power_monitor/
tguimodule_path = /datum/tgui_module/power_monitor/ntos
program_icon_state = "power_monitor"
program_key_state = "power_key"
program_menu_icon = "battery-3"
@@ -15,8 +15,8 @@
/datum/computer_file/program/power_monitor/process_tick()
..()
var/datum/nano_module/power_monitor/NMA = NM
if(istype(NMA) && NMA.has_alarm())
var/datum/tgui_module/power_monitor/TMA = TM
if(istype(TMA) && TMA.has_alarm())
if(!has_alert)
program_icon_state = "power_monitor_warn"
ui_header = "power_warn.gif"
@@ -28,90 +28,3 @@
ui_header = "power_norm.gif"
update_computer_icon()
has_alert = 0
/datum/nano_module/power_monitor
name = "Power monitor"
var/list/grid_sensors
var/active_sensor = null //name_tag of the currently selected sensor
/datum/nano_module/power_monitor/New()
..()
refresh_sensors()
// Checks whether there is an active alarm, if yes, returns 1, otherwise returns 0.
/datum/nano_module/power_monitor/proc/has_alarm()
for(var/obj/machinery/power/sensor/S in grid_sensors)
if(S.check_grid_warning())
return 1
return 0
// If PC is not null header template is loaded. Use PC.get_header_data() to get relevant nanoui data from it. All data entries begin with "PC_...."
// In future it may be expanded to other modular computer devices.
/datum/nano_module/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
var/list/sensors = list()
// Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading.
var/obj/machinery/power/sensor/focus = null
var/z = get_z(nano_host())
var/list/map_levels = using_map.get_map_levels(z)
data["map_levels"] = map_levels
// Build list of data from sensor readings.
for(var/obj/machinery/power/sensor/S in grid_sensors)
if(!(S.z in map_levels))
continue
sensors.Add(list(list(
"name" = S.name_tag,
"alarm" = S.check_grid_warning()
)))
if(S.name_tag == active_sensor)
focus = S
data["all_sensors"] = sensors
if(focus)
data["focus"] = focus.return_reading_data()
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500, state = state)
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
ui.auto_update_layout = 1
// adding a template with the key "mapContent" enables the map ui functionality
ui.add_template("mapContent", "power_monitor_map_content.tmpl")
// adding a template with the key "mapHeader" replaces the map header content
ui.add_template("mapHeader", "power_monitor_map_header.tmpl")
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
// Refreshes list of active sensors kept on this computer.
/datum/nano_module/power_monitor/proc/refresh_sensors()
grid_sensors = list()
var/turf/T = get_turf(nano_host())
var/list/levels = list()
if(!T) // Safety check
return
if(T)
levels += using_map.get_map_levels(T.z, FALSE)
for(var/obj/machinery/power/sensor/S in machines)
if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
else
grid_sensors += S
// Allows us to process UI clicks, which are relayed in form of hrefs.
/datum/nano_module/power_monitor/Topic(href, href_list)
if(..())
return 1
if( href_list["clear"] )
active_sensor = null
. = 1
if( href_list["refresh"] )
refresh_sensors()
. = 1
else if( href_list["setsensor"] )
active_sensor = href_list["setsensor"]
. = 1
@@ -1,7 +1,7 @@
/datum/computer_file/program/rcon_console
filename = "rconconsole"
filedesc = "RCON Remote Control"
nanomodule_path = /datum/nano_module/rcon
tguimodule_path = /datum/tgui_module/rcon/ntos
program_icon_state = "generic"
program_key_state = "rd_key"
program_menu_icon = "power"
@@ -12,129 +12,3 @@
requires_ntnet_feature = NTNET_SYSTEMCONTROL
usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE
size = 19
/datum/nano_module/rcon
name = "Power RCON"
var/list/known_SMESs = null
var/list/known_breakers = null
// Allows you to hide specific parts of the UI
var/hide_SMES = 0
var/hide_SMES_details = 0
var/hide_breakers = 0
/datum/nano_module/rcon/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1, var/datum/topic_state/state = default_state)
FindDevices() // Update our devices list
var/list/data = host.initial_data()
// SMES DATA (simplified view)
var/list/smeslist[0]
for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs)
smeslist.Add(list(list(
"charge" = round(SMES.Percentage()),
"input_set" = SMES.input_attempt,
"input_val" = round(SMES.input_level/1000, 0.1),
"output_set" = SMES.output_attempt,
"output_val" = round(SMES.output_level/1000, 0.1),
"output_load" = round(SMES.output_used/1000, 0.1),
"RCON_tag" = SMES.RCon_tag
)))
data["smes_info"] = sortByKey(smeslist, "RCON_tag")
// BREAKER DATA (simplified view)
var/list/breakerlist[0]
for(var/obj/machinery/power/breakerbox/BR in known_breakers)
breakerlist.Add(list(list(
"RCON_tag" = BR.RCon_tag,
"enabled" = BR.on
)))
data["breaker_info"] = breakerlist
data["hide_smes"] = hide_SMES
data["hide_smes_details"] = hide_SMES_details
data["hide_breakers"] = hide_breakers
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400, state = state)
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
// Proc: Topic()
// Parameters: 2 (href, href_list - allows us to process UI clicks)
// Description: Allows us to process UI clicks, which are relayed in form of hrefs.
/datum/nano_module/rcon/Topic(href, href_list)
if(..())
return
if(href_list["smes_in_toggle"])
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_toggle"])
if(SMES)
SMES.toggle_input()
if(href_list["smes_out_toggle"])
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_toggle"])
if(SMES)
SMES.toggle_output()
if(href_list["smes_in_set"])
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_set"])
if(SMES)
var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000
SMES.set_input(inputset)
if(href_list["smes_out_set"])
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_set"])
if(SMES)
var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000
SMES.set_output(outputset)
if(href_list["toggle_breaker"])
var/obj/machinery/power/breakerbox/toggle = null
for(var/obj/machinery/power/breakerbox/breaker in known_breakers)
if(breaker.RCon_tag == href_list["toggle_breaker"])
toggle = breaker
if(toggle)
if(toggle.update_locked)
to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.")
else
toggle.auto_toggle()
if(href_list["hide_smes"])
hide_SMES = !hide_SMES
if(href_list["hide_smes_details"])
hide_SMES_details = !hide_SMES_details
if(href_list["hide_breakers"])
hide_breakers = !hide_breakers
// Proc: GetSMESByTag()
// Parameters: 1 (tag - RCON tag of SMES we want to look up)
// Description: Looks up and returns SMES which has matching RCON tag
/datum/nano_module/rcon/proc/GetSMESByTag(var/tag)
if(!tag)
return
for(var/obj/machinery/power/smes/buildable/S in known_SMESs)
if(S.RCon_tag == tag)
return S
// Proc: FindDevices()
// Parameters: None
// Description: Refreshes local list of known devices.
/datum/nano_module/rcon/proc/FindDevices()
known_SMESs = new /list()
var/z = get_z(nano_host())
var/list/map_levels = using_map.get_map_levels(z)
for(var/obj/machinery/power/smes/buildable/SMES in GLOB.smeses)
if(!(SMES.z in map_levels))
continue
if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon)
known_SMESs.Add(SMES)
known_breakers = new /list()
for(var/obj/machinery/power/breakerbox/breaker in machines)
if(!(breaker.z in map_levels))
continue
if(breaker.RCon_tag != "NO_TAG")
known_breakers.Add(breaker)
@@ -1,7 +1,7 @@
/datum/computer_file/program/shutoff_monitor
filename = "shutoffmonitor"
filedesc = "Shutoff Valve Monitoring"
nanomodule_path = /datum/nano_module/shutoff_monitor
tguimodule_path = /datum/tgui_module/shutoff_monitor/ntos
program_icon_state = "atmos_control"
program_key_state = "atmos_key"
program_menu_icon = "wrench"
@@ -11,53 +11,3 @@
network_destination = "shutoff valve control computer"
size = 5
var/has_alert = 0
/datum/nano_module/shutoff_monitor
name = "Shutoff Valve Monitoring"
/datum/nano_module/shutoff_monitor/Topic(ref, href_list)
if(..())
return 1
if(href_list["toggle_enable"])
var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_enable"])
if(!istype(S))
return 0
S.close_on_leaks = !S.close_on_leaks
return 1
if(href_list["toggle_open"])
var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_open"])
if(!istype(S))
return 0
if(S.open)
S.close()
else
S.open()
return 1
/datum/nano_module/shutoff_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
var/list/valves = list()
for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves)
valves.Add(list(list(
"name" = S.name,
"enabled" = S.close_on_leaks,
"open" = S.open,
"x" = S.x,
"y" = S.y,
"z" = S.z,
"ref" = "\ref[S]"
)))
data["valves"] = valves
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "shutoff_monitor.tmpl", "Shutoff Valve Monitoring", 627, 700, state = state)
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
@@ -1,7 +1,7 @@
/datum/computer_file/program/supermatter_monitor
filename = "supmon"
filedesc = "Supermatter Monitoring"
nanomodule_path = /datum/nano_module/supermatter_monitor/
tguimodule_path = /datum/tgui_module/supermatter_monitor/ntos
program_icon_state = "smmon_0"
program_key_state = "tech_key"
program_menu_icon = "notice"
@@ -15,119 +15,11 @@
/datum/computer_file/program/supermatter_monitor/process_tick()
..()
var/datum/nano_module/supermatter_monitor/NMS = NM
var/new_status = istype(NMS) ? NMS.get_status() : 0
var/datum/tgui_module/supermatter_monitor/TMS = TM
var/new_status = istype(TMS) ? TMS.get_status() : 0
if(last_status != new_status)
last_status = new_status
ui_header = "smmon_[last_status].gif"
program_icon_state = "smmon_[last_status]"
if(istype(computer))
computer.update_icon()
/datum/nano_module/supermatter_monitor
name = "Supermatter monitor"
var/list/supermatters
var/obj/machinery/power/supermatter/active = null // Currently selected supermatter crystal.
/datum/nano_module/supermatter_monitor/Destroy()
. = ..()
active = null
supermatters = null
/datum/nano_module/supermatter_monitor/New()
..()
refresh()
// Refreshes list of active supermatter crystals
/datum/nano_module/supermatter_monitor/proc/refresh()
supermatters = list()
var/z = get_z(nano_host())
if(!z)
return
var/valid_z_levels = using_map.get_map_levels(z)
for(var/obj/machinery/power/supermatter/S in machines)
// Delaminating, not within coverage, not on a tile.
if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/))
continue
supermatters.Add(S)
if(!(active in supermatters))
active = null
/datum/nano_module/supermatter_monitor/proc/get_status()
. = SUPERMATTER_INACTIVE
for(var/obj/machinery/power/supermatter/S in supermatters)
. = max(., S.get_status())
/datum/nano_module/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
if(istype(active))
var/turf/T = get_turf(active)
if(!T)
active = null
return
var/datum/gas_mixture/air = T.return_air()
if(!istype(air))
active = null
return
data["active"] = 1
data["SM_integrity"] = active.get_integrity()
data["SM_power"] = active.power
data["SM_ambienttemp"] = air.temperature
data["SM_ambientpressure"] = air.return_pressure()
data["SM_EPR"] = active.get_epr()
//data["SM_EPR"] = active.get_epr()
if(air.total_moles)
data["SM_gas_O2"] = round(100*air.gas["oxygen"]/air.total_moles,0.01)
data["SM_gas_CO2"] = round(100*air.gas["carbon_dioxide"]/air.total_moles,0.01)
data["SM_gas_N2"] = round(100*air.gas["nitrogen"]/air.total_moles,0.01)
data["SM_gas_PH"] = round(100*air.gas["phoron"]/air.total_moles,0.01)
data["SM_gas_N2O"] = round(100*air.gas["sleeping_agent"]/air.total_moles,0.01)
else
data["SM_gas_O2"] = 0
data["SM_gas_CO2"] = 0
data["SM_gas_N2"] = 0
data["SM_gas_PH"] = 0
data["SM_gas_N2O"] = 0
else
var/list/SMS = list()
for(var/obj/machinery/power/supermatter/S in supermatters)
var/area/A = get_area(S)
if(!A)
continue
SMS.Add(list(list(
"area_name" = A.name,
"integrity" = S.get_integrity(),
"uid" = S.uid
)))
data["active"] = 0
data["supermatters"] = SMS
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400, state = state)
if(host.update_layout())
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/datum/nano_module/supermatter_monitor/Topic(href, href_list)
if(..())
return 1
if( href_list["clear"] )
active = null
return 1
if( href_list["refresh"] )
refresh()
return 1
if( href_list["set"] )
var/newuid = text2num(href_list["set"])
for(var/obj/machinery/power/supermatter/S in supermatters)
if(S.uid == newuid)
active = S
return 1
@@ -2,5 +2,5 @@
filename = "alarmmonitorsec"
filedesc = "Alarm Monitoring (Security)"
extended_desc = "This program provides visual interface for the security alarm system."
nanomodule_path = /datum/nano_module/alarm_monitor/security
tguimodule_path = /datum/tgui_module/alarm_monitor/security/ntos
required_access = access_security
+4 -4
View File
@@ -34,19 +34,19 @@
access = access_engine
cost = 625
p_drain = 0.025
var/datum/nano_module/alarm_monitor/engineering/arscreen
var/datum/tgui_module/alarm_monitor/engineering/nif/tgarscreen
New()
..()
arscreen = new(nif)
tgarscreen = new(nif)
Destroy()
QDEL_NULL(arscreen)
QDEL_NULL(tgarscreen)
return ..()
activate()
if((. = ..()))
arscreen.ui_interact(nif.human,"main",null,1,nif_state)
tgarscreen.tgui_interact(nif.human)
return TRUE
deactivate()
+214 -234
View File
@@ -27,9 +27,19 @@ GLOBAL_LIST_EMPTY(apcs)
#define APC_UPOVERLAY_LOCKED 4096
#define APC_UPOVERLAY_OPERATING 8192
#define APC_UPDATE_ICON_COOLDOWN 100 // 10 seconds
// main_status var
#define APC_EXTERNAL_POWER_NOTCONNECTED 0
#define APC_EXTERNAL_POWER_NOENERGY 1
#define APC_EXTERNAL_POWER_GOOD 2
// has_electronics var
#define APC_HAS_ELECTRONICS_NONE 0
#define APC_HAS_ELECTRONICS_WIRED 1
#define APC_HAS_ELECTRONICS_SECURED 2
// the Area Power Controller (APC), formerly Power Distribution Unit (PDU)
// one per area, needs wire conection to power network through a terminal
@@ -101,13 +111,13 @@ GLOBAL_LIST_EMPTY(apcs)
var/lastused_environ = 0
var/lastused_charging = 0
var/lastused_total = 0
var/main_status = 0
var/main_status = APC_EXTERNAL_POWER_NOTCONNECTED
var/mob/living/silicon/ai/hacker = null // Malfunction var. If set AI hacked the APC and has full control.
var/wiresexposed = 0
powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :(
var/debug= 0
var/autoflag= 0 // 0 = off, 1= eqp and lights off, 2 = eqp off, 3 = all on.
var/has_electronics = 0 // 0 - none, 1 - plugged in, 2 - secured by screwdriver
var/has_electronics = APC_HAS_ELECTRONICS_NONE // 0 - none, 1 - plugged in, 2 - secured by screwdriver
var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment
var/longtermpower = 10
var/datum/wires/apc/wires = null
@@ -131,7 +141,7 @@ GLOBAL_LIST_EMPTY(apcs)
var/last_nightshift_switch = 0
/obj/machinery/power/apc/updateDialog()
if (stat & (BROKEN|MAINT))
if(stat & (BROKEN|MAINT))
return
..()
@@ -175,12 +185,12 @@ GLOBAL_LIST_EMPTY(apcs)
// offset 24 pixels in direction of dir
// this allows the APC to be embedded in a wall, yet still inside an area
if (building)
if(building)
set_dir(ndir)
pixel_x = (src.dir & 3)? 0 : (src.dir == 4 ? 26 : -26) //VOREStation Edit -> 24 to 26
pixel_y = (src.dir & 3)? (src.dir ==1 ? 26 : -26) : 0 //VOREStation Edit -> 24 to 26
if (building==0)
pixel_x = (dir & 3)? 0 : (dir == 4 ? 26 : -26) //VOREStation Edit -> 24 to 26
pixel_y = (dir & 3)? (dir ==1 ? 26 : -26) : 0 //VOREStation Edit -> 24 to 26
if(building==0)
init()
else
area = get_area(src)
@@ -189,11 +199,11 @@ GLOBAL_LIST_EMPTY(apcs)
operating = 0
name = "[area.name] APC"
stat |= MAINT
src.update_icon()
update_icon()
/obj/machinery/power/apc/Destroy()
GLOB.apcs -= src
src.update()
update()
area.apc = null
area.power_light = 0
area.power_equip = 0
@@ -216,11 +226,11 @@ GLOBAL_LIST_EMPTY(apcs)
// APCs are pixel-shifted, so they need to be updated.
/obj/machinery/power/apc/set_dir(new_dir)
..()
pixel_x = (src.dir & 3)? 0 : (src.dir == 4 ? 24 : -24)
pixel_y = (src.dir & 3)? (src.dir ==1 ? 24 : -24) : 0
pixel_x = (dir & 3)? 0 : (dir == 4 ? 24 : -24)
pixel_y = (dir & 3)? (dir ==1 ? 24 : -24) : 0
if(terminal)
terminal.disconnect_from_network()
terminal.set_dir(src.dir) // Terminal has same dir as master
terminal.set_dir(dir) // Terminal has same dir as master
terminal.connect_to_network() // Refresh the network the terminal is connected to.
return
@@ -230,25 +240,25 @@ GLOBAL_LIST_EMPTY(apcs)
/obj/machinery/power/apc/proc/make_terminal()
// create a terminal object at the same position as original turf loc
// wires will attach to this
terminal = new/obj/machinery/power/terminal(src.loc)
terminal = new/obj/machinery/power/terminal(loc)
terminal.set_dir(dir)
terminal.master = src
/obj/machinery/power/apc/proc/init()
has_electronics = 2 //installed and secured
has_electronics = APC_HAS_ELECTRONICS_SECURED //installed and secured
// is starting with a power cell installed, create it and set its charge level
if(cell_type)
src.cell = new cell_type(src)
cell = new cell_type(src)
cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value)
var/area/A = src.loc.loc
var/area/A = loc.loc
//if area isn't specified use current
if(isarea(A) && src.areastring == null)
src.area = A
if(isarea(A) && !areastring)
area = A
name = "\improper [area.name] APC"
else
src.area = get_area_name(areastring)
area = get_area_name(areastring)
name = "\improper [area.name] APC"
area.apc = src
@@ -260,7 +270,7 @@ GLOBAL_LIST_EMPTY(apcs)
make_terminal()
spawn(5)
src.update()
update()
/obj/machinery/power/apc/examine(mob/user)
. = ..()
@@ -271,17 +281,17 @@ GLOBAL_LIST_EMPTY(apcs)
else if(opened)
if(has_electronics && terminal)
. += "The cover is [opened == 2 ? "removed" : "open"] and [ cell ? "a power cell is installed" : "the power cell is missing"]."
else if (!has_electronics && terminal)
else if(!has_electronics && terminal)
. += "The frame is wired, but the electronics are missing."
else if (has_electronics && !terminal)
else if(has_electronics && !terminal)
. += "The electronics are installed, but not wired."
else /* if (!has_electronics && !terminal) */
else /* if(!has_electronics && !terminal) */
. += "It's just an empty metal frame."
else
if (wiresexposed)
if(wiresexposed)
. += "The cover is closed and the wires are exposed."
else if ((locked && emagged) || hacker) //Some things can cause locked && emagged. Malf AI causes hacker.
else if((locked && emagged) || hacker) //Some things can cause locked && emagged. Malf AI causes hacker.
. += "The cover is closed, but the panel is unresponsive."
else if(!locked && emagged) //Normal emag does this.
. += "The cover is closed, but the panel is flashing an error."
@@ -292,7 +302,7 @@ GLOBAL_LIST_EMPTY(apcs)
// update the APC icon to show the three base states
// also add overlays for indicator lights
/obj/machinery/power/apc/update_icon()
if (!status_overlays)
if(!status_overlays)
status_overlays = 1
status_overlays_lock = new
status_overlays_charging = new
@@ -424,7 +434,7 @@ GLOBAL_LIST_EMPTY(apcs)
else if(charging == 2)
update_overlay |= APC_UPOVERLAY_CHARGEING2
if (!equipment)
if(!equipment)
update_overlay |= APC_UPOVERLAY_EQUIPMENT0
else if(equipment == 1)
update_overlay |= APC_UPOVERLAY_EQUIPMENT1
@@ -468,35 +478,34 @@ GLOBAL_LIST_EMPTY(apcs)
//attack with an item - open/close cover, insert cell, or (un)lock interface
/obj/machinery/power/apc/attackby(obj/item/W, mob/user)
if (istype(user, /mob/living/silicon) && get_dist(src,user)>1)
return src.attack_hand(user)
src.add_fingerprint(user)
if (W.is_crowbar() && opened)
if (has_electronics==1)
if (terminal)
if(issilicon(user) && get_dist(src,user) > 1)
return attack_hand(user)
add_fingerprint(user)
if(W.is_crowbar() && opened)
if(has_electronics == APC_HAS_ELECTRONICS_WIRED)
if(terminal)
to_chat(user, "<span class='warning'>Disconnect the wires first.</span>")
return
playsound(src, W.usesound, 50, 1)
to_chat(user, "You begin to remove the power control board...") //lpeters - fixed grammar issues //Ner - grrrrrr
if(do_after(user, 50 * W.toolspeed))
if (has_electronics==1)
has_electronics = 0
if ((stat & BROKEN))
if(has_electronics == APC_HAS_ELECTRONICS_WIRED)
has_electronics = APC_HAS_ELECTRONICS_NONE
if((stat & BROKEN))
user.visible_message(\
"<span class='warning'>[user.name] has broken the charred power control board inside [src.name]!</span>",\
"<span class='warning'>[user.name] has broken the charred power control board inside [name]!</span>",\
"<span class='notice'>You broke the charred power control board and remove the remains.</span>",
"You hear a crack!")
//ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0
else
user.visible_message(\
"<span class='warning'>[user.name] has removed the power control board from [src.name]!</span>",\
"<span class='warning'>[user.name] has removed the power control board from [name]!</span>",\
"<span class='notice'>You remove the power control board.</span>")
new /obj/item/weapon/module/power_control(loc)
else if (opened!=2) //cover isn't removed
else if(opened != 2) //cover isn't removed
opened = 0
update_icon()
else if (W.is_crowbar() && !(stat & BROKEN) )
else if(W.is_crowbar() && !(stat & BROKEN) )
if(coverlocked && !(stat & MAINT))
to_chat(user, "<span class='warning'>The cover is locked and cannot be opened.</span>")
return
@@ -505,9 +514,9 @@ GLOBAL_LIST_EMPTY(apcs)
update_icon()
else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside
if(cell)
to_chat(user, "The [src.name] already has a power cell installed.")
to_chat(user, "The [name] already has a power cell installed.")
return
if (stat & MAINT)
if(stat & MAINT)
to_chat(user, "<span class='warning'>You need to install the wiring and electronics first.</span>")
return
if(W.w_class != ITEMSIZE_NORMAL)
@@ -518,27 +527,27 @@ GLOBAL_LIST_EMPTY(apcs)
W.forceMove(src)
cell = W
user.visible_message(\
"<span class='warning'>[user.name] has inserted a power cell into [src.name]!</span>",\
"<span class='warning'>[user.name] has inserted a power cell into [name]!</span>",\
"<span class='notice'>You insert the power cell.</span>")
chargecount = 0
update_icon()
else if (W.is_screwdriver()) // haxing
if(opened)
if (cell)
if(cell)
to_chat(user, "<span class='warning'>Remove the power cell first.</span>")
return
else
if (has_electronics==1 && terminal)
has_electronics = 2
if(has_electronics == APC_HAS_ELECTRONICS_WIRED && terminal)
has_electronics = APC_HAS_ELECTRONICS_SECURED
stat &= ~MAINT
playsound(src, W.usesound, 50, 1)
to_chat(user, "You screw the circuit electronics into place.")
else if (has_electronics==2)
has_electronics = 1
else if(has_electronics == APC_HAS_ELECTRONICS_SECURED)
has_electronics = APC_HAS_ELECTRONICS_WIRED
stat |= MAINT
playsound(src, W.usesound, 50, 1)
to_chat(user, "You unfasten the electronics.")
else /* has_electronics==0 */
else /* has_electronics == APC_HAS_ELECTRONICS_NONE */
to_chat(user, "<span class='warning'>There is nothing to secure.</span>")
return
update_icon()
@@ -548,10 +557,10 @@ GLOBAL_LIST_EMPTY(apcs)
playsound(src, W.usesound, 50, 1)
update_icon()
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
togglelock()
else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
togglelock(user)
else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2)
else if(istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
var/turf/T = loc
if(istype(T) && !T.is_plating())
to_chat(user, "<span class='warning'>You must remove the floor plating in front of the APC first.</span>")
@@ -564,9 +573,9 @@ GLOBAL_LIST_EMPTY(apcs)
"You start adding cables to the APC frame...")
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 20))
if (C.amount >= 10 && !terminal && opened && has_electronics != 2)
if(C.amount >= 10 && !terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
var/obj/structure/cable/N = T.get_cable_node()
if (prob(50) && electrocute_mob(usr, N, N))
if(prob(50) && electrocute_mob(usr, N, N))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
@@ -578,7 +587,7 @@ GLOBAL_LIST_EMPTY(apcs)
"You add cables to the APC frame.")
make_terminal()
terminal.connect_to_network()
else if (W.is_wirecutter() && terminal && opened && has_electronics!=2)
else if(W.is_wirecutter() && terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
var/turf/T = loc
if(istype(T) && !T.is_plating())
to_chat(user, "<span class='warning'>You must remove the floor plating in front of the APC first.</span>")
@@ -587,8 +596,8 @@ GLOBAL_LIST_EMPTY(apcs)
"You begin to cut the cables...")
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 50 * W.toolspeed))
if(terminal && opened && has_electronics!=2)
if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal))
if(terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
@@ -597,22 +606,22 @@ GLOBAL_LIST_EMPTY(apcs)
new /obj/item/stack/cable_coil(loc,10)
to_chat(user, "<span class='notice'>You cut the cables and dismantle the power terminal.</span>")
qdel(terminal)
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN)))
else if(istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && !((stat & BROKEN)))
user.visible_message("<span class='warning'>[user.name] inserts the power control board into [src].</span>", \
"You start to insert the power control board into the frame...")
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 10))
if(has_electronics==0)
has_electronics = 1
if(has_electronics == APC_HAS_ELECTRONICS_NONE)
has_electronics = APC_HAS_ELECTRONICS_WIRED
reboot()
to_chat(user, "<span class='notice'>You place the power control board inside the frame.</span>")
qdel(W)
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && ((stat & BROKEN)))
else if(istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && ((stat & BROKEN)))
to_chat(user, "<span class='warning'>The [src] is too broken for that. Repair it first.</span>")
return
else if (istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics==0 && !terminal)
else if(istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && !terminal)
var/obj/item/weapon/weldingtool/WT = W
if (WT.get_fuel() < 3)
if(WT.get_fuel() < 3)
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
return
user.visible_message("<span class='warning'>[user.name] begins cutting apart [src] with the [WT.name].</span>", \
@@ -621,7 +630,7 @@ GLOBAL_LIST_EMPTY(apcs)
playsound(src, WT.usesound, 25, 1)
if(do_after(user, 50 * WT.toolspeed))
if(!src || !WT.remove_fuel(3, user)) return
if (emagged || (stat & BROKEN) || opened==2)
if(emagged || (stat & BROKEN) || opened==2)
new /obj/item/stack/material/steel(loc)
user.visible_message(\
"<span class='warning'>[src] has been cut apart by [user.name] with the [WT.name].</span>",\
@@ -635,8 +644,8 @@ GLOBAL_LIST_EMPTY(apcs)
"You hear welding.")
qdel(src)
return
else if (opened && ((stat & BROKEN) || hacker || emagged))
if (istype(W, /obj/item/frame/apc) && (stat & BROKEN))
else if(opened && ((stat & BROKEN) || hacker || emagged))
if(istype(W, /obj/item/frame/apc) && (stat & BROKEN))
if(cell)
to_chat(user, "<span class='warning'>You need to remove the power cell first.</span>")
return
@@ -648,10 +657,10 @@ GLOBAL_LIST_EMPTY(apcs)
qdel(W)
stat &= ~BROKEN
reboot()
if (opened==2)
if(opened==2)
opened = 1
update_icon()
else if (istype(W, /obj/item/device/multitool) && (hacker || emagged))
else if(istype(W, /obj/item/device/multitool) && (hacker || emagged))
if(cell)
to_chat(user, "<span class='warning'>You need to remove the power cell first.</span>")
return
@@ -663,12 +672,12 @@ GLOBAL_LIST_EMPTY(apcs)
playsound(src, 'sound/machines/chime.ogg', 25, 1)
reboot()
else
if ((stat & BROKEN) \
if((stat & BROKEN) \
&& !opened \
&& W.force >= 5 \
&& W.w_class >= ITEMSIZE_SMALL )
user.visible_message("<span class='danger'>The [src.name] has been hit with the [W.name] by [user.name]!</span>", \
"<span class='danger'>You hit the [src.name] with your [W.name]!</span>", \
user.visible_message("<span class='danger'>The [name] has been hit with the [W.name] by [user.name]!</span>", \
"<span class='danger'>You hit the [name] with your [W.name]!</span>", \
"You hear a bang!")
if(prob(20))
opened = 2
@@ -677,12 +686,12 @@ GLOBAL_LIST_EMPTY(apcs)
"You hear a bang!")
update_icon()
else
if (istype(user, /mob/living/silicon))
return src.attack_hand(user)
if (!opened && wiresexposed && (istype(W, /obj/item/device/multitool) || W.is_wirecutter() || istype(W, /obj/item/device/assembly/signaler)))
return src.attack_hand(user)
if(istype(user, /mob/living/silicon))
return attack_hand(user)
if(!opened && wiresexposed && (istype(W, /obj/item/device/multitool) || W.is_wirecutter() || istype(W, /obj/item/device/assembly/signaler)))
return attack_hand(user)
//Placeholder until someone can do take_damage() for APCs or something.
to_chat(user, "<span class='notice'>The [src.name] looks too sturdy to bash open with \the [W.name].</span>")
to_chat(user, "<span class='notice'>The [name] looks too sturdy to bash open with \the [W.name].</span>")
// attack with hand - remove cell (if cover open) or interact with the APC
@@ -698,7 +707,7 @@ GLOBAL_LIST_EMPTY(apcs)
else if(hacker)
to_chat(user, "<span class='warning'>Access denied.</span>")
else
if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
if(allowed(user) && !wires.is_cut(WIRE_IDSCAN))
locked = !locked
to_chat(user, "You [ locked ? "lock" : "unlock"] the APC interface.")
update_icon()
@@ -707,10 +716,10 @@ GLOBAL_LIST_EMPTY(apcs)
/obj/machinery/power/apc/AltClick(mob/user)
..()
togglelock()
togglelock(user)
/obj/machinery/power/apc/emag_act(var/remaining_charges, var/mob/user)
if (!(emagged || hacker)) // trying to unlock with an emag card
if(!(emagged || hacker)) // trying to unlock with an emag card
if(opened)
to_chat(user, "You must close the cover to do that.")
else if(wiresexposed)
@@ -719,7 +728,7 @@ GLOBAL_LIST_EMPTY(apcs)
to_chat(user, "The [src] isn't working.")
else
flick("apc-spark", src)
if (do_after(user,6))
if(do_after(user,6))
emagged = 1
locked = 0
to_chat(user, "<span class='notice'>You emag the APC interface.</span>")
@@ -733,11 +742,9 @@ GLOBAL_LIST_EMPTY(apcs)
update_icon()
/obj/machinery/power/apc/attack_hand(mob/user)
// if (!can_use(user)) This already gets called in interact() and in topic()
// return
if(!user)
return
src.add_fingerprint(user)
add_fingerprint(user)
//Human mob special interaction goes here.
if(istype(user,/mob/living/carbon/human))
@@ -745,20 +752,20 @@ GLOBAL_LIST_EMPTY(apcs)
if(H.species.can_shred(H))
user.setClickCooldown(user.get_attack_speed())
user.visible_message("<span call='warning'>[user.name] slashes at the [src.name]!</span>", "<span class='notice'>You slash at the [src.name]!</span>")
user.visible_message("<span call='warning'>[user.name] slashes at the [name]!</span>", "<span class='notice'>You slash at the [name]!</span>")
playsound(src, 'sound/weapons/slash.ogg', 100, 1)
var/allcut = wires.is_all_cut()
if(beenhit >= pick(3, 4) && wiresexposed != 1)
wiresexposed = 1
src.update_icon()
src.visible_message("<span call='warning'>The [src.name]'s cover flies open, exposing the wires!</span>")
update_icon()
visible_message("<span call='warning'>The [name]'s cover flies open, exposing the wires!</span>")
else if(wiresexposed == 1 && allcut == 0)
wires.cut_all()
src.update_icon()
src.visible_message("<span call='warning'>The [src.name]'s wires are shredded!</span>")
update_icon()
visible_message("<span call='warning'>The [name]'s wires are shredded!</span>")
else
beenhit += 1
return
@@ -769,16 +776,21 @@ GLOBAL_LIST_EMPTY(apcs)
cell.add_fingerprint(user)
cell.update_icon()
src.cell = null
user.visible_message("<span class='warning'>[user.name] removes the power cell from [src.name]!</span>",\
cell = null
user.visible_message("<span class='warning'>[user.name] removes the power cell from [name]!</span>",\
"<span class='notice'>You remove the power cell.</span>")
charging = 0
src.update_icon()
update_icon()
return
if(stat & (BROKEN|MAINT))
return
// do APC interaction
src.interact(user)
interact(user)
/obj/machinery/power/apc/attack_ghost(mob/user)
if(panel_open)
return wires.Interact(user)
return tgui_interact(user)
/obj/machinery/power/apc/interact(mob/user)
if(!user)
@@ -788,15 +800,18 @@ GLOBAL_LIST_EMPTY(apcs)
wires.Interact(user)
return //The panel is visibly dark when the wires are exposed, so we shouldn't be able to interact with it.
return ui_interact(user)
return tgui_interact(user)
/obj/machinery/power/apc/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "APC", name) // 510, 460
ui.open()
/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/tgui_data(mob/user)
var/list/data = list(
"locked" = locked,
"normallyLocked" = locked,
"emagged" = emagged,
"isOperating" = operating,
"externalPower" = main_status,
@@ -808,7 +823,7 @@ GLOBAL_LIST_EMPTY(apcs)
"failTime" = failure_timer * 2,
"gridCheck" = grid_check,
"coverLocked" = coverlocked,
"siliconUser" = issilicon(user) || isobserver(user), //I add observer here so admins can have more control, even if it makes 'siliconUser' seem inaccurate.
"siliconUser" = issilicon(user) || (isobserver(user) && is_admin(user)), //I add observer here so admins can have more control, even if it makes 'siliconUser' seem inaccurate.
"emergencyLights" = !emergency_lights,
"nightshiftLights" = nightshift_lights,
"nightshiftSetting" = nightshift_setting,
@@ -847,18 +862,7 @@ GLOBAL_LIST_EMPTY(apcs)
)
)
// 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)
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, "apc.tmpl", "[area.name] - APC", 520, data["siliconUser"] ? 490 : 465)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
return data
/obj/machinery/power/apc/proc/report()
return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])"
@@ -868,23 +872,23 @@ GLOBAL_LIST_EMPTY(apcs)
area.power_light = (lighting >= POWERCHAN_ON)
area.power_equip = (equipment >= POWERCHAN_ON)
area.power_environ = (environ >= POWERCHAN_ON)
// if (area.name == "AI Chamber")
// if(area.name == "AI Chamber")
// spawn(10)
// to_world(" [area.name] [area.power_equip]")
else
area.power_light = 0
area.power_equip = 0
area.power_environ = 0
// if (area.name == "AI Chamber")
// if(area.name == "AI Chamber")
// to_world("[area.power_equip]")
area.power_change()
/obj/machinery/power/apc/proc/can_use(mob/user as mob, var/loud = 0) //used by attack_hand() and Topic()
if(!user.client)
return 0
if(isobserver(user) && is_admin(user) ) //This is to allow nanoUI interaction by ghost admins.
if(isobserver(user) && is_admin(user)) //This is to allow nanoUI interaction by ghost admins.
return 1
if (user.stat)
if(user.stat)
return 0
if(inoperable())
return 0
@@ -897,7 +901,7 @@ GLOBAL_LIST_EMPTY(apcs)
to_chat(user, "<span class='warning'>You must stand to use [src]!</span>")
return 0
autoflag = 5
if (istype(user, /mob/living/silicon))
if(istype(user, /mob/living/silicon))
var/permit = 0 // 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
@@ -912,122 +916,90 @@ GLOBAL_LIST_EMPTY(apcs)
to_chat(user, "<span class='danger'>\The AI control for [src] has been disabled!</span>")
return 0
else
if (!in_range(src, user) || !istype(src.loc, /turf))
if(!in_range(src, user) || !istype(loc, /turf))
return 0
var/mob/living/carbon/human/H = user
if (istype(H) && prob(H.getBrainLoss()))
if(istype(H) && prob(H.getBrainLoss()))
to_chat(user, "<span class='danger'>You momentarily forget how to use [src].</span>")
return 0
return 1
/obj/machinery/power/apc/Topic(href, href_list)
if(..())
return 1
/obj/machinery/power/apc/tgui_act(action, params)
if(..() || !can_use(usr, TRUE))
return TRUE
if(!can_use(usr, 1))
return 1
// There's a handful of cases where we want to allow users to bypass the `locked` variable.
// If can_admin_interact() wasn't only defined on observers, this could just be part of a single-line
// conditional.
var/locked_exception = FALSE
if(issilicon(usr) || action == "nightshift")
locked_exception = TRUE
if(isobserver(usr))
var/mob/observer/dead/D = usr
if(D.can_admin_interact())
locked_exception = TRUE
if(href_list["nightshift"])
if(last_nightshift_switch > world.time - 10 SECONDS) // don't spam...
to_chat(usr, "<span class='warning'>[src]'s night lighting circuit breaker is still cycling!</span>")
return 0
last_nightshift_switch = world.time
nightshift_setting = text2num(href_list["nightshift"])
update_nightshift()
return 1
if(locked && !locked_exception)
return
if(locked && !issilicon(usr) )
if(isobserver(usr) )
var/mob/observer/dead/O = usr //Added to allow admin nanoUI interactions.
if(!O.can_admin_interact() ) //NanoUI /should/ make this not needed, but better safe than sorry.
to_chat(usr, "Try as you might, your ghostly fingers can't press the buttons.")
return 1
else
to_chat(usr, "You must unlock the panel to use this!")
return 1
if (href_list["lock"])
coverlocked = !coverlocked
else if (href_list["reboot"])
failure_timer = 0
update_icon()
update()
else if (href_list["emergency_lighting"])
emergency_lights = !emergency_lights
for(var/obj/machinery/light/L in area)
if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override
L.no_emergency = emergency_lights
INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE)
CHECK_TICK
else if (href_list["breaker"])
toggle_breaker()
else if (href_list["cmode"])
chargemode = !chargemode
if(!chargemode)
charging = 0
. = TRUE
switch(action)
if("lock")
if(locked_exception) // Yay code reuse
if(emagged || (stat & (BROKEN|MAINT)))
to_chat(usr, "The APC does not respond to the command.")
return
locked = !locked
update_icon()
if("cover")
coverlocked = !coverlocked
if("breaker")
toggle_breaker()
if("nightshift")
if(last_nightshift_switch > world.time - 10 SECONDS) // don't spam...
to_chat(usr, "<span class='warning'>[src]'s night lighting circuit breaker is still cycling!</span>")
return 0
last_nightshift_switch = world.time
nightshift_setting = params["nightshift"]
update_nightshift()
if("charge")
chargemode = !chargemode
if(!chargemode)
charging = 0
update_icon()
if("channel")
if(params["eqp"])
equipment = setsubsystem(text2num(params["eqp"]))
update_icon()
update()
else if(params["lgt"])
lighting = setsubsystem(text2num(params["lgt"]))
update_icon()
update()
else if(params["env"])
environ = setsubsystem(text2num(params["env"]))
update_icon()
update()
if("reboot")
failure_timer = 0
update_icon()
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)
update_icon()
update()
else if (href_list["overload"])
if(istype(usr, /mob/living/silicon))
src.overload_lighting()
else if (href_list["toggleaccess"])
if(istype(usr, /mob/living/silicon))
if(emagged || (stat & (BROKEN|MAINT)))
to_chat(usr, "The APC does not respond to the command.")
return
locked = !locked
update_icon()
return 0
update()
if("emergency_lighting")
emergency_lights = !emergency_lights
for(var/obj/machinery/light/L in area)
if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override
L.no_emergency = emergency_lights
INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE)
CHECK_TICK
if("overload")
if(locked_exception) // Reusing for simplicity!
overload_lighting()
/obj/machinery/power/apc/proc/toggle_breaker()
operating = !operating
src.update()
update()
update_icon()
//This isn't used for now, so might as well disable it
/*
/obj/machinery/power/apc/proc/ion_act()
if(prob(3))
src.locked = 1
if (src.cell.charge > 0)
src.cell.charge = 0
cell.corrupt()
update_icon()
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
visible_message("<span class='danger'>The [src.name] suddenly lets out a blast of smoke and some sparks!</span>", \
"<span class='danger'>You hear sizzling electronics.</span>")
*/
/obj/machinery/power/apc/surplus()
if(terminal)
return terminal.surplus()
@@ -1083,12 +1055,12 @@ GLOBAL_LIST_EMPTY(apcs)
var/excess = surplus()
if(!src.avail())
main_status = 0
if(!avail())
main_status = APC_EXTERNAL_POWER_NOTCONNECTED
else if(excess < 0)
main_status = 1
main_status = APC_EXTERNAL_POWER_NOENERGY
else
main_status = 2
main_status = APC_EXTERNAL_POWER_GOOD
if(debug)
log_debug("Status: [main_status] - Excess: [excess] - Last Equip: [lastused_equip] - Last Light: [lastused_light] - Longterm: [longtermpower]")
@@ -1122,7 +1094,7 @@ GLOBAL_LIST_EMPTY(apcs)
// now trickle-charge the cell
lastused_charging = 0 // Clear the variable for new use.
if(src.attempt_charging())
if(attempt_charging())
if(excess > 0) // check to make sure we have enough to charge
// Max charge is capped to % per second constant
var/ch = min(excess*CELLRATE, cell.maxcharge*chargelevel)
@@ -1170,7 +1142,7 @@ GLOBAL_LIST_EMPTY(apcs)
force_update = 0
queue_icon_update()
update()
else if (last_ch != charging)
else if(last_ch != charging)
queue_icon_update()
/obj/machinery/power/apc/proc/update_channels()
@@ -1212,7 +1184,7 @@ GLOBAL_LIST_EMPTY(apcs)
// val 0=off, 1=off(auto) 2=on 3=on(auto)
// on 0=off, 1=on, 2=autooff
// defines a state machine, returns the new state
obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
/obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
switch(cur_state)
//if(POWERCHAN_OFF); //autoset will never turn on a channel set to off
if(POWERCHAN_OFF_AUTO)
@@ -1253,24 +1225,24 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
switch(severity)
if(1)
//set_broken() //now qdel() do what we need
if (cell)
if(cell)
cell.ex_act(1) // more lags woohoo
qdel(src)
return
if(2)
if (prob(75))
if(prob(75))
set_broken()
if (cell && prob(50))
if(cell && prob(50))
cell.ex_act(2)
if(3)
if (prob(50))
if(prob(50))
set_broken()
if (cell && prob(50))
if(cell && prob(50))
cell.ex_act(3)
if(4)
if (prob(25))
if(prob(25))
set_broken()
if (cell && prob(50))
if(cell && prob(50))
cell.ex_act(3)
return
@@ -1282,7 +1254,7 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
/obj/machinery/power/apc/proc/set_broken()
// Aesthetically much better!
spawn(rand(2,5))
src.visible_message("<span class='warning'>[src]'s screen flickers suddenly, then explodes in a rain of sparks and small debris!</span>")
visible_message("<span class='warning'>[src]'s screen flickers suddenly, then explodes in a rain of sparks and small debris!</span>")
stat |= BROKEN
operating = 0
update_icon()
@@ -1314,7 +1286,7 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
/obj/machinery/power/apc/proc/ai_hack(var/mob/living/silicon/ai/A = null)
if(!A || !A.hacked_apcs || hacker || aidisabled || A.stat == DEAD)
return 0
src.hacker = A
hacker = A
A.hacked_apcs += src
locked = 1
update_icon()
@@ -1406,3 +1378,11 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
CHECK_TICK
#undef APC_UPDATE_ICON_COOLDOWN
#undef APC_EXTERNAL_POWER_NOTCONNECTED
#undef APC_EXTERNAL_POWER_NOENERGY
#undef APC_EXTERNAL_POWER_GOOD
#undef APC_HAS_ELECTRONICS_NONE
#undef APC_HAS_ELECTRONICS_WIRED
#undef APC_HAS_ELECTRONICS_SECURED
+1 -1
View File
@@ -25,7 +25,7 @@
for(var/obj/structure/cable/C in src.loc)
qdel(C)
. = ..()
for(var/datum/nano_module/rcon/R in world)
for(var/datum/tgui_module/rcon/R in world)
R.FindDevices()
/obj/machinery/power/breakerbox/Initialize()
+29 -39
View File
@@ -192,58 +192,48 @@ GLOBAL_LIST_EMPTY(all_turbines)
if(stat & (BROKEN|NOPOWER) || !anchored) return
if(!circ1 || !circ2) //Just incase the middle part of the TEG was not wrenched last.
reconnect()
ui_interact(user)
tgui_interact(user)
/obj/machinery/power/generator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/power/generator/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TEGenerator", name)
ui.open()
/obj/machinery/power/generator/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/vertical = 0
if (dir == NORTH || dir == SOUTH)
vertical = 1
var/data[0]
data["totalOutput"] = effective_gen/1000
data["maxTotalOutput"] = max_power/1000
data["thermalOutput"] = last_thermal_gen/1000
data["circConnected"] = 0
var/list/data = list()
data["totalOutput"] = effective_gen
data["maxTotalOutput"] = max_power
data["thermalOutput"] = last_thermal_gen
data["primary"] = list()
if(circ1)
//The one on the left (or top)
data["primaryDir"] = vertical ? "top" : "left"
data["primaryOutput"] = last_circ1_gen/1000
data["primaryFlowCapacity"] = circ1.volume_capacity_used*100
data["primaryInletPressure"] = circ1.air1.return_pressure()
data["primaryInletTemperature"] = circ1.air1.temperature
data["primaryOutletPressure"] = circ1.air2.return_pressure()
data["primaryOutletTemperature"] = circ1.air2.temperature
data["primary"]["dir"] = vertical ? "top" : "left"
data["primary"]["output"] = last_circ1_gen
data["primary"]["flowCapacity"] = circ1.volume_capacity_used*100
data["primary"]["inletPressure"] = circ1.air1.return_pressure()
data["primary"]["inletTemperature"] = circ1.air1.temperature
data["primary"]["outletPressure"] = circ1.air2.return_pressure()
data["primary"]["outletTemperature"] = circ1.air2.temperature
data["secondary"] = list()
if(circ2)
//Now for the one on the right (or bottom)
data["secondaryDir"] = vertical ? "bottom" : "right"
data["secondaryOutput"] = last_circ2_gen/1000
data["secondaryFlowCapacity"] = circ2.volume_capacity_used*100
data["secondaryInletPressure"] = circ2.air1.return_pressure()
data["secondaryInletTemperature"] = circ2.air1.temperature
data["secondaryOutletPressure"] = circ2.air2.return_pressure()
data["secondaryOutletTemperature"] = circ2.air2.temperature
data["secondary"]["dir"] = vertical ? "bottom" : "right"
data["secondary"]["output"] = last_circ2_gen
data["secondary"]["flowCapacity"] = circ2.volume_capacity_used*100
data["secondary"]["inletPressure"] = circ2.air1.return_pressure()
data["secondary"]["inletTemperature"] = circ2.air1.temperature
data["secondary"]["outletPressure"] = circ2.air2.return_pressure()
data["secondary"]["outletTemperature"] = circ2.air2.temperature
if(circ1 && circ2)
data["circConnected"] = 1
else
data["circConnected"] = 0
// 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)
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, "generator.tmpl", "Thermoelectric Generator", 450, 500)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
return data
/obj/machinery/power/generator/power_change()
..()
+19 -18
View File
@@ -240,11 +240,16 @@ GLOBAL_LIST_EMPTY(gravity_generators)
/obj/machinery/gravity_generator/main/attack_hand(mob/user)
if((. = ..()))
return
if(CanUseTopic(user, global.default_state) > STATUS_CLOSE)
ui_interact(user)
return TRUE
tgui_interact(user)
return TRUE
/obj/machinery/gravity_generator/main/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/gravity_generator/main/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GravityGenerator", name)
ui.open()
/obj/machinery/gravity_generator/main/tgui_data(mob/user)
var/data[0]
data["breaker"] = breaker
@@ -253,22 +258,18 @@ GLOBAL_LIST_EMPTY(gravity_generators)
data["on"] = on
data["operational"] = (stat & BROKEN) ? FALSE : TRUE
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "gravity_generator.tmpl", src.name, 500, 400)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
return data
/obj/machinery/gravity_generator/main/Topic(href, href_list, datum/topic_state/state = default_state)
if((. = ..()))
return
/obj/machinery/gravity_generator/main/tgui_act(action, params)
if((..()))
return TRUE
if(href_list["gentoggle"])
breaker = !breaker
investigate_log("was toggled [breaker ? "<font color='green'>ON</font>" : "<font color='red'>OFF</font>"] by [key_name(usr)].", "gravity")
set_power()
return TOPIC_REFRESH
switch(action)
if("gentoggle")
breaker = !breaker
investigate_log("was toggled [breaker ? "<font color='green'>ON</font>" : "<font color='red'>OFF</font>"] by [key_name(usr)].", "gravity")
set_power()
return TOPIC_REFRESH
// Power and Icon States
+65 -75
View File
@@ -7,6 +7,7 @@
density = 1
anchored = 0
use_power = USE_POWER_OFF
interact_offline = TRUE
var/active = 0
var/power_gen = 5000
@@ -28,13 +29,22 @@
/obj/machinery/power/port_gen/proc/handleInactive()
return
/obj/machinery/power/port_gen/proc/TogglePower()
if(active)
active = FALSE
icon_state = "[initial(icon_state)]"
// soundloop.stop()
else if(HasFuel())
active = TRUE
icon_state = "[initial(icon_state)]on"
// soundloop.start()
/obj/machinery/power/port_gen/process()
if(active && HasFuel() && !IsBroken() && anchored && powernet)
add_avail(power_gen * power_output)
UseFuel()
src.updateDialog()
else
active = 0
active = FALSE
icon_state = initial(icon_state)
handleInactive()
@@ -121,7 +131,7 @@
return ..()
/obj/machinery/power/port_gen/pacman/dismantle()
while ( sheets > 0 )
while( sheets > 0 )
DropFuel()
return ..()
@@ -212,16 +222,16 @@
/obj/machinery/power/port_gen/pacman/handleInactive()
var/cooling_temperature = 20
var/datum/gas_mixture/environment = loc.return_air()
if (environment)
if(environment)
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
var/ambient = environment.temperature - T20C
cooling_temperature += ambient*ratio
if (temperature > cooling_temperature)
if(temperature > cooling_temperature)
var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR
temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX)
temperature = max(temperature - temp_loss, cooling_temperature)
src.updateDialog()
updateDialog()
if(overheating)
overheating--
@@ -287,97 +297,77 @@
..()
if (!anchored)
return
ui_interact(user)
tgui_interact(user)
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/power/port_gen/pacman/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/power/port_gen/tgui_status(mob/user, datum/tgui_state/state)
if(IsBroken())
return
return STATUS_CLOSE
return ..()
/obj/machinery/power/port_gen/pacman/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortableGenerator", name)
ui.open()
/obj/machinery/power/port_gen/pacman/tgui_data(mob/user)
var/list/data = list()
var/data[0]
data["active"] = active
if(istype(user, /mob/living/silicon/ai))
data["is_ai"] = 1
data["is_ai"] = TRUE
else if(istype(user, /mob/living/silicon/robot) && !Adjacent(user))
data["is_ai"] = 1
data["is_ai"] = TRUE
else
data["is_ai"] = 0
data["output_set"] = power_output
data["output_max"] = max_power_output
data["output_safe"] = max_safe_output
data["output_watts"] = power_output * power_gen
data["temperature_current"] = src.temperature
data["temperature_max"] = src.max_temperature
data["temperature_overheat"] = overheating
// 1 sheet = 1000cm3?
data["is_ai"] = FALSE
data["sheet_name"] = capitalize(sheet_name)
data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000))
data["fuel_capacity"] = round(max_sheets * 1000, 0.1)
data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0
data["fuel_type"] = sheet_name
data["anchored"] = anchored
data["connected"] = (powernet == null ? 0 : 1)
data["ready_to_boot"] = anchored && HasFuel()
data["power_generated"] = DisplayPower(power_gen)
data["power_output"] = DisplayPower(power_gen * power_output)
data["unsafe_output"] = power_output > max_safe_output
data["power_available"] = (powernet == null ? 0 : DisplayPower(avail()))
data["temperature_current"] = temperature
data["temperature_max"] = max_temperature
data["temperature_overheat"] = overheating
// 1 sheet = 1000cm3?
return data
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "pacman.tmpl", src.name, 500, 560)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/*
/obj/machinery/power/port_gen/pacman/interact(mob/user)
if (get_dist(src, user) > 1 )
if (!istype(user, /mob/living/silicon/ai))
user.unset_machine()
user << browse(null, "window=port_gen"
return
user.set_machine(src)
var/dat = text("<b>[name]</b><br>")
if (active)
dat += text("Generator: <A href='?src=\ref[src];action=disable'>On</A><br>")
else
dat += text("Generator: <A href='?src=\ref[src];action=enable'>Off</A><br>")
dat += text("[capitalize(sheet_name)]: [sheets] - <A href='?src=\ref[src];action=eject'>Eject</A><br>")
var/stack_percent = round(sheet_left * 100, 1)
dat += text("Current stack: [stack_percent]% <br>")
dat += text("Power output: <A href='?src=\ref[src];action=lower_power'>-</A> [power_gen * power_output] Watts<A href='?src=\ref[src];action=higher_power'>+</A><br>")
dat += text("Power current: [(powernet == null ? "Unconnected" : "[avail()]")]<br>")
var/tempstr = "Temperature: [temperature]&deg;C<br>"
dat += (overheating)? "<span class='danger'>[tempstr]</span>" : tempstr
dat += "<br><A href='?src=\ref[src];action=close'>Close</A>"
user << browse("[dat]", "window=port_gen")
onclose(user, "port_gen")
*/
/obj/machinery/power/port_gen/pacman/Topic(href, href_list)
/obj/machinery/power/port_gen/pacman/tgui_act(action, params)
if(..())
return
src.add_fingerprint(usr)
if(href_list["action"])
if(href_list["action"] == "enable")
if(!active && HasFuel() && !IsBroken())
active = 1
icon_state = "[initial(icon_state)]on" //VOREStation Edit
if(href_list["action"] == "disable")
if (active)
active = 0
icon_state = initial(icon_state) //VOREStation Edit
if(href_list["action"] == "eject")
add_fingerprint(usr)
switch(action)
if("toggle_power")
TogglePower()
. = TRUE
if("eject")
if(!active)
DropFuel()
if(href_list["action"] == "lower_power")
if (power_output > 1)
. = TRUE
if("lower_power")
if(power_output > 1)
power_output--
if (href_list["action"] == "higher_power")
if (power_output < max_power_output || (emagged && power_output < round(max_power_output*2.5)))
. = TRUE
if("higher_power")
if(power_output < max_power_output || (emagged && power_output < round(max_power_output * 2.5)))
power_output++
. = TRUE
/obj/machinery/power/port_gen/pacman/super
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
+3 -1
View File
@@ -5,6 +5,7 @@
var/load = 0 // the current load on the powernet, increased by each machine at processing
var/newavail = 0 // what available power was gathered last tick, then becomes...
var/avail = 0 //...the current available power in the powernet
var/viewavail = 0 // the availability as it appears on the power console (gradually updated)
var/viewload = 0 // the load as it appears on the power console (gradually updated)
var/number = 0 // Unused //TODEL
@@ -134,7 +135,8 @@
S.restore(perc)
//updates the viewed load (as seen on power computers)
viewload = round(load)
viewavail = round(0.8 * viewavail + 0.2 * avail)
viewload = round(0.8 * viewload + 0.2 * load)
//reset the powernet
load = 0
+71 -2
View File
@@ -19,12 +19,22 @@
var/name_tag = "#UNKN#" // ID tag displayed in list of powernet sensors. Each sensor should have it's own tag!
var/long_range = 0 // If 1, sensor reading will show on all computers, regardless of Zlevel
var/list/history = list()
var/record_size = 60
var/record_interval = 50
var/next_record = 0
var/is_secret_monitor = FALSE
// Proc: New()
// Parameters: None
// Description: Automatically assigns name according to ID tag.
/obj/machinery/power/sensor/New()
..()
auto_set_name()
/obj/machinery/power/sensor/Initialize()
. = ..()
history["supply"] = list()
history["demand"] = list()
// Proc: auto_set_name()
// Parameters: None
@@ -38,6 +48,8 @@
for(var/obj/machinery/computer/power_monitor/PM in machines)
if(PM.power_monitor)
PM.power_monitor.refresh_sensors()
history.Cut()
history = null
// Proc: check_grid_warning()
// Parameters: None
@@ -51,10 +63,67 @@
// Proc: process()
// Parameters: None
// Description: This has to be here because we need sensors to remain in Machines list.
// Description: This tracks historical usage, for TGUI power monitors
/obj/machinery/power/sensor/process()
if(!powernet)
use_power = USE_POWER_IDLE
connect_to_network()
else
use_power = USE_POWER_ACTIVE
record()
return 1
// This tracks historical usage, for TGUI power monitors
/obj/machinery/power/sensor/proc/record()
if(world.time >= next_record)
next_record = world.time + record_interval
var/datum/powernet/connected_powernet = powernet
var/list/supply = history["supply"]
if(connected_powernet)
supply += connected_powernet.viewavail
if(supply.len > record_size)
supply.Cut(1, 2)
var/list/demand = history["demand"]
if(connected_powernet)
demand += connected_powernet.viewload
if(demand.len > record_size)
demand.Cut(1, 2)
/obj/machinery/power/sensor/tgui_data()
var/list/data = list()
data["name"] = name_tag
data["stored"] = record_size
data["interval"] = record_interval / 10
data["attached"] = !!powernet
data["history"] = history
data["areas"] = list()
if(powernet)
for(var/obj/machinery/power/terminal/term in powernet.nodes)
if(istype(term.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = term.master
if(istype(A))
var/cell_charge
if(!A.cell)
cell_charge = 0
else
cell_charge = A.cell.percent()
data["areas"] += list(list(
"name" = A.area.name,
"charge" = cell_charge,
"load" = DisplayPower(A.lastused_total),
"charging" = A.charging,
"eqp" = A.equipment,
"lgt" = A.lighting,
"env" = A.environ,
))
return data
// Proc: reading_to_text()
// Parameters: 1 (amount - Power in Watts to be converted to W, kW or MW)
// Description: Helper proc that converts reading in Watts to kW or MW (returns string version of amount parameter)
@@ -178,7 +247,7 @@
APC_entry["total_load"] = reading_to_text(A.lastused_total)
// Hopefully removes those goddamn \improper s which are screwing up the UI
var/N = A.area.name
if(findtext(N, "ÿ"))
if(findtext(N, ""))
N = copytext(N, 3)
APC_entry["name"] = N
// Add data into main list of APC data.
@@ -18,7 +18,7 @@
use_power = USE_POWER_IDLE
idle_power_usage = 300
active_power_usage = 300
var/datum/nano_module/power_monitor/power_monitor
var/datum/tgui_module/power_monitor/power_monitor
// Checks the sensors for alerts. If change (alerts cleared or detected) occurs, calls for icon update.
/obj/machinery/computer/power_monitor/process()
@@ -47,12 +47,11 @@
if(stat & (BROKEN|NOPOWER))
return
ui_interact(user)
tgui_interact(user)
// Uses dark magic to operate the NanoUI of this computer.
/obj/machinery/computer/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
power_monitor.ui_interact(user, ui_key, ui, force_open)
/obj/machinery/computer/power_monitor/tgui_interact(mob/user, var/datum/tgui/ui = null)
power_monitor.tgui_interact(user, ui)
// Verifies if any warnings were registered by connected sensors.
/obj/machinery/computer/power_monitor/proc/check_warnings()
@@ -36,7 +36,7 @@
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user as mob)
if(construction_state >= 3)
interact(user)
tgui_interact(user)
else if(construction_state == 2) // Wires exposed
wires.Interact(user)
@@ -77,36 +77,6 @@
else
icon_state = "[reference]c"
/obj/machinery/particle_accelerator/control_box/Topic(href, href_list)
..()
//Ignore input if we are broken, !silicon guy cant touch us, or nonai controlling from super far away
if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !istype(usr, /mob/living/silicon)) || (get_dist(src, usr) > 8 && !istype(usr, /mob/living/silicon/ai)))
usr.unset_machine()
usr << browse(null, "window=pacontrol")
return
if( href_list["close"] )
usr << browse(null, "window=pacontrol")
usr.unset_machine()
return
if(href_list["togglep"])
if(!wires.is_cut(WIRE_PARTICLE_POWER))
toggle_power()
else if(href_list["scan"])
part_scan()
else if(href_list["strengthup"])
if(!wires.is_cut(WIRE_PARTICLE_STRENGTH))
add_strength()
else if(href_list["strengthdown"])
if(!wires.is_cut(WIRE_PARTICLE_STRENGTH))
remove_strength()
updateDialog()
update_icon()
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = strength
@@ -230,33 +200,54 @@
part.update_icon()
return 1
/obj/machinery/particle_accelerator/control_box/proc/is_interactive(mob/user)
if(!interface_control)
to_chat(user, "<span class='alert'>ERROR: Request timed out. Check wire contacts.</span>")
return FALSE
if(construction_state != 3)
return FALSE
return TRUE
/obj/machinery/particle_accelerator/control_box/interact(mob/user)
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
if(!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=pacontrol")
return
user.set_machine(src)
/obj/machinery/particle_accelerator/control_box/tgui_status(mob/user)
if(is_interactive(user))
return ..()
return STATUS_CLOSE
var/dat = ""
dat += "Particle Accelerator Control Panel<BR>"
dat += "<A href='?src=\ref[src];close=1'>Close</A><BR><BR>"
dat += "Status:<BR>"
if(!assembled)
dat += "Unable to detect all parts!<BR>"
dat += "<A href='?src=\ref[src];scan=1'>Run Scan</A><BR><BR>"
else
dat += "All parts in place.<BR><BR>"
dat += "Power:"
if(active)
dat += "On<BR>"
else
dat += "Off <BR>"
dat += "<A href='?src=\ref[src];togglep=1'>Toggle Power</A><BR><BR>"
dat += "Particle Strength: [src.strength] "
dat += "<A href='?src=\ref[src];strengthdown=1'>--</A>|<A href='?src=\ref[src];strengthup=1'>++</A><BR><BR>"
/obj/machinery/particle_accelerator/control_box/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ParticleAccelerator", name)
ui.open()
user << browse(dat, "window=pacontrol;size=420x500")
onclose(user, "pacontrol")
return
/obj/machinery/particle_accelerator/control_box/tgui_data(mob/user)
var/list/data = list()
data["assembled"] = assembled
data["power"] = active
data["strength"] = strength
return data
/obj/machinery/particle_accelerator/control_box/tgui_act(action, params)
if(..())
return
switch(action)
if("power")
if(wires.is_cut(WIRE_POWER))
return
toggle_power()
. = TRUE
if("scan")
part_scan()
. = TRUE
if("add_strength")
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
return
add_strength()
. = TRUE
if("remove_strength")
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
return
remove_strength()
. = TRUE
update_icon()
+72 -66
View File
@@ -263,11 +263,11 @@ GLOBAL_LIST_EMPTY(smeses)
/obj/machinery/power/smes/attack_ai(mob/user)
add_hiddenprint(user)
ui_interact(user)
tgui_interact(user)
/obj/machinery/power/smes/attack_hand(mob/user)
add_fingerprint(user)
ui_interact(user)
tgui_interact(user)
/obj/machinery/power/smes/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
@@ -344,78 +344,84 @@ GLOBAL_LIST_EMPTY(smeses)
return FALSE
return TRUE
/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(stat & BROKEN)
return
// this is the data which will be sent to the ui
var/data[0]
data["nameTag"] = name_tag
data["storedCapacity"] = round(100.0*charge/capacity, 0.1)
data["storedCapacityAbs"] = round(charge/(1000*60), 0.1)
data["storedCapacityMax"] = round(capacity/(1000*60))
data["charging"] = inputting
data["chargeMode"] = input_attempt
data["chargeLevel"] = round(input_level/1000, 0.1)
data["chargeMax"] = round(input_level_max/1000)
data["chargeLoad"] = round(input_available/1000, 0.1)
data["outputOnline"] = output_attempt
data["outputLevel"] = round(output_level/1000, 0.1)
data["outputMax"] = round(output_level_max/1000)
data["outputLoad"] = round(output_used/1000, 0.1)
data["outputting"] = outputting
// 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)
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, 380)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
/obj/machinery/power/smes/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Smes", name)
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
/obj/machinery/power/smes/tgui_data()
var/list/data = list(
"capacity" = capacity,
"capacityPercent" = round(100*charge/capacity, 0.1),
"charge" = charge,
"inputAttempt" = input_attempt,
"inputting" = inputting,
"inputLevel" = input_level,
"inputLevel_text" = DisplayPower(input_level),
"inputLevelMax" = input_level_max,
"inputAvailable" = input_available,
"outputAttempt" = output_attempt,
"outputting" = outputting,
"outputLevel" = output_level,
"outputLevel_text" = DisplayPower(output_level),
"outputLevelMax" = output_level_max,
"outputUsed" = output_used,
)
return data
/obj/machinery/power/smes/proc/Percentage()
if(!capacity)
return 0
return round(100.0*charge/capacity, 0.1)
/obj/machinery/power/smes/Topic(href, href_list)
if(..())
return 1
if( href_list["cmode"] )
inputting(!input_attempt)
update_icon()
return 1
else if( href_list["online"] )
outputting(!output_attempt)
update_icon()
return 1
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/1000] kW)", "SMES Input Power Control", input_level/1000) as num) * 1000
input_level = max(0, min(input_level_max, input_level)) // clamp to range
return 1
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/1000] kW)", "SMES Output Power Control", output_level/1000) as num) * 1000
output_level = max(0, min(output_level_max, output_level)) // clamp to range
return 1
/obj/machinery/power/smes/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("tryinput")
inputting(!input_attempt)
update_icon()
. = TRUE
if("tryoutput")
outputting(!output_attempt)
update_icon()
. = TRUE
if("input")
var/target = params["target"]
var/adjust = text2num(params["adjust"])
if(target == "min")
target = 0
. = TRUE
else if(target == "max")
target = input_level_max
. = TRUE
else if(adjust)
target = input_level + adjust
. = TRUE
else if(text2num(target) != null)
target = text2num(target)
. = TRUE
if(.)
input_level = clamp(target, 0, input_level_max)
if("output")
var/target = params["target"]
var/adjust = text2num(params["adjust"])
if(target == "min")
target = 0
. = TRUE
else if(target == "max")
target = output_level_max
. = TRUE
else if(adjust)
target = output_level + adjust
. = TRUE
else if(text2num(target) != null)
target = text2num(target)
. = TRUE
if(.)
output_level = clamp(target, 0, output_level_max)
/obj/machinery/power/smes/proc/inputting(var/do_input)
input_attempt = do_input
+1 -1
View File
@@ -84,7 +84,7 @@
/obj/machinery/power/smes/buildable/Destroy()
qdel(wires)
wires = null
for(var/datum/nano_module/rcon/R in world)
for(var/datum/tgui_module/rcon/R in world)
R.FindDevices()
return ..()
+60 -71
View File
@@ -399,38 +399,32 @@ GLOBAL_LIST_EMPTY(solars_list)
return
/obj/machinery/power/solar_control/attack_hand(mob/user)
if(!..())
interact(user)
if(..())
return TRUE
tgui_interact(user)
/obj/machinery/power/solar_control/interact(mob/user)
/obj/machinery/power/solar_control/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SolarControl", name)
ui.open()
var/t = "<B><span class='highlight'>Generated power</span></B> : [round(lastgen)] W<BR>"
t += "<B><span class='highlight'>Star Orientation</span></B>: [SSsun.sun.angle]&deg ([angle2text(SSsun.sun.angle)])<BR>"
t += "<B><span class='highlight'>Array Orientation</span></B>: [rate_control(src,"cdir","[cdir]&deg",1,15)] ([angle2text(cdir)])<BR>"
t += "<B><span class='highlight'>Tracking:</span></B><div class='statusDisplay'>"
switch(track)
if(0)
t += "<span class='linkOn'>Off</span> <A href='?src=\ref[src];track=1'>Timed</A> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
if(1)
t += "<A href='?src=\ref[src];track=0'>Off</A> <span class='linkOn'>Timed</span> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
if(2)
t += "<A href='?src=\ref[src];track=0'>Off</A> <A href='?src=\ref[src];track=1'>Timed</A> <span class='linkOn'>Auto</span><BR>"
/obj/machinery/power/solar_control/tgui_data()
var/data = list()
t += "Tracking Rate: [rate_control(src,"tdir","[trackrate] deg/h ([trackrate<0 ? "CCW" : "CW"])",1,30,180)]</div><BR>"
data["generated"] = round(lastgen)
data["generated_ratio"] = data["generated"] / round(max(connected_panels.len, 1) * GLOB.solar_gen_rate)
t += "<B><span class='highlight'>Connected devices:</span></B><div class='statusDisplay'>"
data["sun_angle"] = SSsun.sun.angle
data["array_angle"] = cdir
data["rotation_rate"] = trackrate
data["max_rotation_rate"] = 7200
data["tracking_state"] = track
t += "<A href='?src=\ref[src];search_connected=1'>Search for devices</A><BR>"
t += "Solar panels : [connected_panels.len] connected<BR>"
t += "Solar tracker : [connected_tracker ? "<span class='good'>Found</span>" : "<span class='bad'>Not found</span>"]</div><BR>"
data["connected_panels"] = connected_panels.len
data["connected_tracker"] = (connected_tracker ? TRUE : FALSE)
t += "<A href='?src=\ref[src];close=1'>Close</A>"
var/datum/browser/popup = new(user, "solar", name)
popup.set_content(t)
popup.open()
return
return data
/obj/machinery/power/solar_control/attackby(obj/item/I, user as mob)
if(I.is_screwdriver())
@@ -481,51 +475,52 @@ GLOBAL_LIST_EMPTY(solars_list)
updateDialog()
/obj/machinery/power/solar_control/Topic(href, href_list)
/obj/machinery/power/solar_control/tgui_act(action, params)
if(..())
usr << browse(null, "window=solcon")
usr.unset_machine()
return 0
if(href_list["close"] )
usr << browse(null, "window=solcon")
usr.unset_machine()
return 0
return TRUE
if(href_list["rate control"])
if(href_list["cdir"])
src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360)
src.targetdir = src.cdir
if(track == 2) //manual update, so losing auto-tracking
track = 0
spawn(1)
switch(action)
if("azimuth")
var/adjust = text2num(params["adjust"])
var/value = text2num(params["value"])
if(adjust)
value = cdir + adjust
if(value != null)
cdir = value
set_panels(cdir)
if(href_list["tdir"])
src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"]))
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
return TRUE
return FALSE
if("azimuth_rate")
var/adjust = text2num(params["adjust"])
var/value = text2num(params["value"])
if(adjust)
value = trackrate + adjust
if(value != null)
trackrate = round(clamp(value, -7200, 7200), 0.01)
if(trackrate)
nexttime = world.time + 36000 / abs(trackrate)
return TRUE
return TRUE
if("tracking")
var/mode = text2num(params["mode"])
track = mode
if(track == 2)
if(connected_tracker)
connected_tracker.set_angle(SSsun.sun.angle)
set_panels(cdir)
else if(track == 1) //begin manual tracking
targetdir = cdir
if(trackrate)
nexttime = world.time + 36000/abs(trackrate)
set_panels(targetdir)
return TRUE
if(href_list["track"])
track = text2num(href_list["track"])
if(track == 2)
if(connected_tracker)
connected_tracker.set_angle(SSsun.sun.angle)
set_panels(cdir)
else if (track == 1) //begin manual tracking
src.targetdir = src.cdir
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
set_panels(targetdir)
if(href_list["search_connected"])
src.search_for_connected()
if(connected_tracker && track == 2)
connected_tracker.set_angle(SSsun.sun.angle)
src.set_panels(cdir)
interact(usr)
return 1
if("refresh")
search_for_connected()
return TRUE
//rotates the panel to the passed angle
/obj/machinery/power/solar_control/proc/set_panels(var/cdir)
for(var/obj/machinery/power/solar/S in connected_panels)
S.adir = cdir //instantly rotates the panel
S.occlusion()//and
@@ -547,7 +542,7 @@ GLOBAL_LIST_EMPTY(solars_list)
/obj/machinery/power/solar_control/ex_act(severity)
switch(severity)
if(1.0)
//SN src = null
//SN = null
qdel(src)
return
if(2.0)
@@ -565,9 +560,3 @@ GLOBAL_LIST_EMPTY(solars_list)
/obj/item/weapon/paper/solar
name = "paper- 'Going green! Setup your own solar array instructions.'"
info = "<h1>Welcome</h1><p>At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or phoron! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.</p><p>You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!</p><p>Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the SSsun.sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the SSsun.sun's movements and to send commands to the solar panels to change direction with the SSsun.sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.</p><p>Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.</p><p>That's all to it, be safe, be green!</p>"
/proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null) //How not to name vars
var/href = "<A href='?src=\ref[S];rate control=1;[V]"
var/rate = "[href]=-[Max]'>-</A>[href]=-[Min]'>-</A> [(C?C : 0)] [href]=[Min]'>+</A>[href]=[Max]'>+</A>"
if(Limit) return "[href]=-[Limit]'>-</A>"+rate+"[href]=[Limit]'>+</A>"
return rate
+11 -10
View File
@@ -390,11 +390,11 @@
if(Adjacent(user))
return attack_hand(user)
else
ui_interact(user)
tgui_interact(user)
return
/obj/machinery/power/supermatter/attack_ai(mob/user as mob)
ui_interact(user)
tgui_interact(user)
/obj/machinery/power/supermatter/attack_hand(mob/user as mob)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
@@ -404,9 +404,15 @@
Consume(user)
/obj/machinery/power/supermatter/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AiSupermatter", name)
ui.open()
// 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/tgui_data(mob/user)
var/list/data = list()
data["integrity_percentage"] = round(get_integrity())
var/datum/gas_mixture/env = null
@@ -421,12 +427,7 @@
data["ambient_pressure"] = round(env.return_pressure())
data["detonating"] = grav_pulling
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "supermatter_crystal.tmpl", "Supermatter Crystal", 500, 300)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
return data
/obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
+1 -1
View File
@@ -417,7 +417,7 @@ var/list/infomorph_emotions = list(
desc = "Modify the settings on your integrated radio."
if(radio)
radio.ui_interact(src,"main",null,1,conscious_state)
radio.tgui_interact(src)
else
to_chat(src, "<span class='warning'>You don't have a radio!</span>")
+36 -42
View File
@@ -18,6 +18,7 @@
use_power = USE_POWER_OFF //doesn't use APC power
var/charge_rate = 100000 //100 kW
var/obj/machinery/shield_gen/owned_gen
interact_offline = TRUE
/obj/machinery/shield_capacitor/advanced
name = "advanced shield capacitor"
@@ -67,36 +68,30 @@
/obj/machinery/shield_capacitor/attack_hand(mob/user)
if(stat & (BROKEN))
return
interact(user)
tgui_interact(user)
/obj/machinery/shield_capacitor/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
if (!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=shield_capacitor")
return
var/t = "<B>Shield Capacitor Control Console</B><br><br>"
if(locked)
t += "<i>Swipe your ID card to begin.</i>"
else
t += "This capacitor is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
t += "Capacitor Status: [time_since_fail > 2 ? "<font color=green>OK.</font>" : "<font color=red>Discharging!</font>"]<br>"
t += "Stored Energy: [format_SI(stored_charge, "J")] ([100 * round(stored_charge/max_charge, 0.01)]%)<br>"
t += "Charge Rate: \
<a href='?src=\ref[src];charge_rate=-100000'>\[----\]</a> \
<a href='?src=\ref[src];charge_rate=-10000'>\[---\]</a> \
<a href='?src=\ref[src];charge_rate=-1000'>\[--\]</a> \
<a href='?src=\ref[src];charge_rate=-100'>\[-\]</a>[format_SI(charge_rate, "W")]\
<a href='?src=\ref[src];charge_rate=100'>\[+\]</a> \
<a href='?src=\ref[src];charge_rate=1000'>\[++\]</a> \
<a href='?src=\ref[src];charge_rate=10000'>\[+++\]</a> \
<a href='?src=\ref[src];charge_rate=100000'>\[++++\]</a><br>"
t += "<hr>"
t += "<A href='?src=\ref[src]'>Refresh</A> "
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
/obj/machinery/shield_capacitor/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ShieldCapacitor", name)
ui.open()
user << browse(t, "window=shield_capacitor;size=500x400")
user.set_machine(src)
/obj/machinery/shield_capacitor/tgui_status(mob/user)
if(stat & BROKEN)
return STATUS_CLOSE
return ..()
/obj/machinery/shield_capacitor/tgui_data(mob/user)
var/list/data = list()
data["active"] = active
data["time_since_fail"] = time_since_fail
data["stored_charge"] = stored_charge
data["max_charge"] = max_charge
data["charge_rate"] = charge_rate
data["max_charge_rate"] = max_charge_rate
return data
/obj/machinery/shield_capacitor/process()
if (!anchored)
@@ -119,21 +114,20 @@
time_since_fail = 0 //losing charge faster than we can draw from PN
last_stored_charge = stored_charge
/obj/machinery/shield_capacitor/Topic(href, href_list[])
..()
if( href_list["close"] )
usr << browse(null, "window=shield_capacitor")
usr.unset_machine()
return
if( href_list["toggle"] )
if(!active && !anchored)
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
return
active = !active
if( href_list["charge_rate"] )
charge_rate = between(10000, charge_rate + text2num(href_list["charge_rate"]), max_charge_rate)
/obj/machinery/shield_capacitor/tgui_act(action, params)
if(..())
return TRUE
updateDialog()
switch(action)
if("toggle")
if(!active && !anchored)
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
return
active = !active
. = TRUE
if("charge_rate")
charge_rate = clamp(text2num(params["rate"]), 10000, max_charge_rate)
. = TRUE
/obj/machinery/shield_capacitor/power_change()
if(stat & BROKEN)
+67 -73
View File
@@ -23,6 +23,7 @@
var/energy_conversion_rate = 0.0006 //how many renwicks per watt? Higher numbers equals more effiency.
var/z_range = 0 // How far 'up and or down' to extend the shield to, in z-levels. Only works on MultiZ supported z-levels.
use_power = USE_POWER_OFF //doesn't use APC power
interact_offline = TRUE // don't check stat & NOPOWER|BROKEN for our UI. We check BROKEN ourselves.
var/id //for button usage
/obj/machinery/shield_gen/advanced
@@ -95,59 +96,50 @@
/obj/machinery/shield_gen/attack_hand(mob/user)
if(stat & (BROKEN))
return
interact(user)
tgui_interact(user)
/obj/machinery/shield_gen/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
if (!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=shield_generator")
return
var/t = "<B>Shield Generator Control Console</B><BR><br>"
if(locked)
t += "<i>Swipe your ID card to begin.</i>"
else
t += "[capacitors.len ? "<font color=green>Charge capacitor(s) connected.</font>" : "<font color=red>Unable to locate charge capacitor!</font>"]<br>"
var/i = 0
for(var/obj/machinery/shield_capacitor/capacitor in capacitors)
i++
t += "Capacitor #[i]: [capacitor.active ? "<font color=green>Online.</font>" : "<font color=red>Offline.</font>"] \
Charge: [round(capacitor.stored_charge/1000, 0.1)] kJ ([100 * round(capacitor.stored_charge/capacitor.max_charge, 0.01)]%) \
Status: [capacitor.time_since_fail > 2 ? "<font color=green>OK.</font>" : "<font color=red>Discharging!</font>"]<br>"
t += "This generator is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
t += "Field Status: [time_since_fail > 2 ? "<font color=green>Stable</font>" : "<font color=red>Unstable</font>"]<br>"
t += "Coverage Radius (restart required): \
<a href='?src=\ref[src];change_radius=-50'>---</a> \
<a href='?src=\ref[src];change_radius=-5'>--</a> \
<a href='?src=\ref[src];change_radius=-1'>-</a> \
[field_radius] m \
<a href='?src=\ref[src];change_radius=1'>+</a> \
<a href='?src=\ref[src];change_radius=5'>++</a> \
<a href='?src=\ref[src];change_radius=50'>+++</a><br>"
if(HasAbove(src.z) || HasBelow(src.z)) // Won't show up on maps lacking MultiZ support.
t += "Vertical Shielding (restart required): \
<a href='?src=\ref[src];z_range=-1'>-</a> \
[z_range] Vertical Range \
<a href='?src=\ref[src];z_range=1'>+</a><br>"
t += "Overall Field Strength: [round(average_field_strength, 0.01)] Renwick ([target_field_strength ? round(100 * average_field_strength / target_field_strength, 0.1) : "NA"]%)<br>"
t += "Upkeep Power: [format_SI(round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate), "W")]<br>"
t += "Charge Rate: <a href='?src=\ref[src];strengthen_rate=-0.1'>--</a> \
[strengthen_rate] Renwick/s \
<a href='?src=\ref[src];strengthen_rate=0.1'>++</a><br>"
t += "Shield Generation Power: [format_SI(round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate), "W")]<br>"
t += "Maximum Field Strength: \
<a href='?src=\ref[src];target_field_strength=-10'>\[min\]</a> \
<a href='?src=\ref[src];target_field_strength=-5'>--</a> \
<a href='?src=\ref[src];target_field_strength=-1'>-</a> \
[target_field_strength] Renwick \
<a href='?src=\ref[src];target_field_strength=1'>+</a> \
<a href='?src=\ref[src];target_field_strength=5'>++</a> \
<a href='?src=\ref[src];target_field_strength=10'>\[max\]</a><br>"
t += "<hr>"
t += "<A href='?src=\ref[src]'>Refresh</A> "
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=shield_generator;size=500x400")
user.set_machine(src)
/obj/machinery/shield_gen/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ShieldGenerator", name)
ui.open()
/obj/machinery/shield_gen/tgui_status(mob/user)
if(stat & BROKEN)
return STATUS_CLOSE
return ..()
/obj/machinery/shield_gen/tgui_data(mob/user)
var/list/data = list()
data["locked"] = locked
data["lockedData"] = list()
if(!locked)
data["lockedData"]["capacitors"] = list()
for(var/obj/machinery/shield_capacitor/C in capacitors)
data["lockedData"]["capacitors"].Add(list(list(
"active" = C.active,
"stored_charge" = C.stored_charge,
"max_charge" = C.max_charge,
"failing" = (C.time_since_fail <= 2),
)))
data["lockedData"]["active"] = active
data["lockedData"]["failing"] = (time_since_fail <= 2)
data["lockedData"]["radius"] = field_radius
data["lockedData"]["max_radius"] = max_field_radius
data["lockedData"]["z_range"] = z_range
data["lockedData"]["max_z_range"] = 10
data["lockedData"]["average_field_strength"] = average_field_strength
data["lockedData"]["target_field_strength"] = target_field_strength
data["lockedData"]["max_field_strength"] = max_field_strength
data["lockedData"]["shields"] = LAZYLEN(field)
data["lockedData"]["upkeep"] = round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate)
data["lockedData"]["strengthen_rate"] = strengthen_rate
data["lockedData"]["max_strengthen_rate"] = max_strengthen_rate
data["lockedData"]["gen_power"] = round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate)
return data
/obj/machinery/shield_gen/process()
if (!anchored && active)
@@ -206,30 +198,32 @@
else
average_field_strength = 0
/obj/machinery/shield_gen/Topic(href, href_list[])
..()
if( href_list["close"] )
usr << browse(null, "window=shield_generator")
usr.unset_machine()
return
else if( href_list["toggle"] )
if (!active && !anchored)
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
return
toggle()
else if( href_list["change_radius"] )
field_radius = between(0, field_radius + text2num(href_list["change_radius"]), max_field_radius)
else if( href_list["strengthen_rate"] )
strengthen_rate = between(0, strengthen_rate + text2num(href_list["strengthen_rate"]), max_strengthen_rate)
else if( href_list["target_field_strength"] )
target_field_strength = between(1, target_field_strength + text2num(href_list["target_field_strength"]), max_field_strength)
else if( href_list["z_range"] )
z_range = between(0, z_range + text2num(href_list["z_range"]), 10) // Max is extending ten z-levels up and down. Probably too big of a number but it shouldn't matter.
/obj/machinery/shield_gen/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("toggle")
if (!active && !anchored)
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
return
toggle()
. = TRUE
if("change_radius")
field_radius = clamp(text2num(params["val"]), 0, max_field_radius)
. = TRUE
if("strengthen_rate")
strengthen_rate = clamp(text2num(params["val"]), 0, max_strengthen_rate)
. = TRUE
if("target_field_strength")
target_field_strength = clamp(text2num(params["val"]), 1, max_field_strength)
. = TRUE
if("z_range")
z_range = clamp(text2num(params["val"]), 0, 10)
. = TRUE
updateDialog()
/obj/machinery/shield_gen/ex_act(var/severity)
if(active)
toggle()
return ..()
+25 -40
View File
@@ -46,73 +46,58 @@
name = "escape pod controller"
program = /datum/computer/file/embedded_program/docking/simple
var/datum/shuttle/autodock/ferry/escape_pod/pod
valid_actions = list("toggle_override", "force_door")
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/tgui_data(mob/user)
var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type
data = list(
. = list(
"docking_status" = docking_program.get_docking_status(),
"override_enabled" = docking_program.override_enabled,
"door_state" = docking_program.memory["door_status"]["state"],
"door_lock" = docking_program.memory["door_status"]["lock"],
"exterior_status" = docking_program.memory["door_status"],
"can_force" = pod.can_force() || (emergency_shuttle.departed && pod.can_launch()), //allow players to manually launch ahead of time if the shuttle leaves
"is_armed" = pod.arming_controller.armed,
"armed" = pod.arming_controller.armed,
"internalTemplateName" = "EscapePodConsole",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "escape_pod_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/Topic(href, href_list)
if((. = ..()))
return
if("manual_arm")
pod.arming_controller.arm()
return TOPIC_REFRESH
if("force_launch")
if (pod.can_force())
pod.force_launch(src)
else if (emergency_shuttle.departed && pod.can_launch()) //allow players to manually launch ahead of time if the shuttle leaves
pod.launch(src)
return TOPIC_REFRESH
return 0
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("manual_arm")
pod.arming_controller.arm()
. = TRUE
if("force_launch")
if(pod.can_force())
pod.force_launch(src)
else if(emergency_shuttle.departed && pod.can_launch()) //allow players to manually launch ahead of time if the shuttle leaves
pod.launch(src)
. = TRUE
//This controller is for the escape pod berth (station side)
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth
name = "escape pod berth controller"
program = /datum/computer/file/embedded_program/docking/simple/escape_pod_berth
valid_actions = list("toggle_override", "force_door")
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/tgui_data(mob/user)
var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type
var/armed = null
if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod_berth))
if(istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod_berth))
var/datum/computer/file/embedded_program/docking/simple/escape_pod_berth/P = docking_program
armed = P.armed
data = list(
. = list(
"docking_status" = docking_program.get_docking_status(),
"override_enabled" = docking_program.override_enabled,
"exterior_status" = docking_program.memory["door_status"],
"armed" = armed,
"internalTemplateName" = "EscapePodBerthConsole",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "escape_pod_berth_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/emag_act(var/remaining_charges, var/mob/user)
if (!emagged)
to_chat(user, "<span class='notice'>You emag the [src], arming the escape pod!</span>")
+138
View File
@@ -0,0 +1,138 @@
/datum/tgui_module/alarm_monitor
name = "Alarm monitor"
tgui_id = "StationAlertConsole"
var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use.
var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user.
/datum/tgui_module/alarm_monitor/New()
..()
alarm_handlers = list()
/datum/tgui_module/alarm_monitor/all
/datum/tgui_module/alarm_monitor/all/New()
..()
alarm_handlers = SSalarm.all_handlers
/datum/tgui_module/alarm_monitor/all/robot
/datum/tgui_module/alarm_monitor/all/robot/tgui_state(mob/user)
return GLOB.tgui_self_state
/datum/tgui_module/alarm_monitor/engineering
/datum/tgui_module/alarm_monitor/engineering/New()
..()
alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm)
// Subtype for glasses_state
/datum/tgui_module/alarm_monitor/engineering/glasses
/datum/tgui_module/alarm_monitor/engineering/glasses/tgui_state(mob/user)
return GLOB.tgui_glasses_state
// Subtype for nif_state
/datum/tgui_module/alarm_monitor/engineering/nif
/datum/tgui_module/alarm_monitor/engineering/nif/tgui_state(mob/user)
return GLOB.tgui_nif_state
// Subtype for NTOS
/datum/tgui_module/alarm_monitor/engineering/ntos
ntos = TRUE
/datum/tgui_module/alarm_monitor/security
/datum/tgui_module/alarm_monitor/security/New()
..()
alarm_handlers = list(camera_alarm, motion_alarm)
// Subtype for glasses_state
/datum/tgui_module/alarm_monitor/security/glasses
/datum/tgui_module/alarm_monitor/security/glasses/tgui_state(mob/user)
return GLOB.tgui_glasses_state
// Subtype for NTOS
/datum/tgui_module/alarm_monitor/security/ntos
ntos = TRUE
/datum/tgui_module/alarm_monitor/proc/register_alarm(var/object, var/procName)
for(var/datum/alarm_handler/AH in alarm_handlers)
AH.register_alarm(object, procName)
/datum/tgui_module/alarm_monitor/proc/unregister_alarm(var/object)
for(var/datum/alarm_handler/AH in alarm_handlers)
AH.unregister_alarm(object)
/datum/tgui_module/alarm_monitor/proc/all_alarms()
var/z = get_z(tgui_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.visible_alarms(z)
return all_alarms
/datum/tgui_module/alarm_monitor/proc/major_alarms()
var/z = get_z(tgui_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.major_alarms(z)
return all_alarms
// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise.
/datum/tgui_module/alarm_monitor/proc/has_major_alarms()
var/z = get_z(tgui_host())
for(var/datum/alarm_handler/AH in alarm_handlers)
if(AH.has_major_alarms(z))
return 1
return 0
/datum/tgui_module/alarm_monitor/proc/minor_alarms()
var/z = get_z(tgui_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.minor_alarms(z)
return all_alarms
/datum/tgui_module/alarm_monitor/tgui_act(action, params)
if(..())
return TRUE
// Camera stuff is AI only.
// If you're not an AI, this is a read-only UI.
if(!isAI(usr))
return
switch(action)
if("switchTo")
var/obj/machinery/camera/C = locate(params["camera"]) in cameranet.cameras
if(!C)
return
usr.switch_to_camera(C)
return 1
/datum/tgui_module/alarm_monitor/tgui_data(mob/user)
var/list/data = list()
var/categories[0]
var/z = get_z(tgui_host())
for(var/datum/alarm_handler/AH in alarm_handlers)
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
for(var/datum/alarm/A in AH.visible_alarms(z))
var/cameras[0]
var/lost_sources[0]
if(isAI(user))
for(var/obj/machinery/camera/C in A.cameras())
cameras[++cameras.len] = C.tgui_structure()
for(var/datum/alarm_source/AS in A.sources)
if(!AS.source)
lost_sources[++lost_sources.len] = AS.source_name
categories[categories.len]["alarms"] += list(list(
"name" = "[A.alarm_name()]" + "[A.max_severity() > 1 ? "(MAJOR)" : ""]",
"origin_lost" = A.origin == null,
"has_cameras" = cameras.len,
"cameras" = cameras,
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
data["categories"] = categories
return data
+110
View File
@@ -0,0 +1,110 @@
/datum/tgui_module/atmos_control
name = "Atmospherics Control"
tgui_id = "AtmosControl"
var/obj/access = new()
var/emagged = 0
var/ui_ref
var/list/monitored_alarms = list()
/datum/tgui_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 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/tgui_module/atmos_control/tgui_act(action, params, datum/tgui/ui)
if(..())
return TRUE
switch(action)
if("alarm")
if(ui_ref)
var/obj/machinery/alarm/alarm = locate(params["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines)
if(alarm)
var/datum/tgui_state/TS = generate_state(alarm)
alarm.tgui_interact(usr, parent_ui = ui_ref, state = TS)
return 1
if("setZLevel")
ui.set_map_z_level(params["mapZLevel"])
return TRUE
/datum/tgui_module/atmos_control/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, tgui_id, name)
ui.autoupdate = TRUE
ui.open()
ui_ref = ui
/datum/tgui_module/atmos_control/tgui_static_data(mob/user)
. = ..()
var/z = get_z(user)
var/list/map_levels = using_map.get_map_levels(z)
// TODO: Move these to a cache, similar to cameras
var/alarms[0]
for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines))
if(!monitored_alarms.len && alarm.alarms_hidden)
continue
if(!(alarm.z in map_levels))
continue
alarms[++alarms.len] = list(
"name" = sanitize(alarm.name),
"ref"= "\ref[alarm]",
"danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm),
"x" = alarm.x,
"y" = alarm.y,
"z" = alarm.z)
.["alarms"] = alarms
/datum/tgui_module/atmos_control/tgui_data(mob/user)
var/list/data = list()
var/z = get_z(user)
var/list/map_levels = using_map.get_map_levels(z)
data["map_levels"] = map_levels
return data
/datum/tgui_module/atmos_control/tgui_close()
. = ..()
ui_ref = null
/datum/tgui_module/atmos_control/proc/generate_state(air_alarm)
var/datum/tgui_state/air_alarm_remote/state = new()
state.atmos_control = src
state.air_alarm = air_alarm
return state
/datum/tgui_state/air_alarm_remote
var/datum/tgui_module/atmos_control/atmos_control = null
var/obj/machinery/alarm/air_alarm = null
/datum/tgui_state/air_alarm_remote/can_use_topic(src_object, mob/user)
if(!atmos_control.ui_ref)
qdel(src)
return STATUS_CLOSE
if(has_access(user))
return STATUS_INTERACTIVE
return STATUS_UPDATE
/datum/tgui_state/air_alarm_remote/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.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO) || (access_ce in user.GetAccess()))
/datum/tgui_state/air_alarm_remote/Destroy()
atmos_control = null
air_alarm = null
/datum/tgui_module/atmos_control/ntos
ntos = TRUE
/datum/tgui_module/atmos_control/robot
/datum/tgui_module/atmos_control/robot/tgui_state(mob/user)
return GLOB.tgui_self_state
@@ -0,0 +1,85 @@
/datum/tgui_module/power_monitor
name = "Power monitor"
tgui_id = "PowerMonitor"
var/list/grid_sensors
var/active_sensor = null //name_tag of the currently selected sensor
/datum/tgui_module/power_monitor/New()
. = ..()
refresh_sensors()
/datum/tgui_module/power_monitor/tgui_data(mob/user)
var/list/data = list()
var/list/sensors = list()
// Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading.
var/obj/machinery/power/sensor/focus = null
var/z = get_z(user)
var/list/map_levels = using_map.get_map_levels(z)
// Build list of data from sensor readings.
for(var/obj/machinery/power/sensor/S in grid_sensors)
if(!(S.z in map_levels))
continue
sensors.Add(list(list(
"name" = S.name_tag,
"alarm" = S.check_grid_warning()
)))
if(S.name_tag == active_sensor)
focus = S
data["all_sensors"] = sensors
if(focus)
data["focus"] = focus.tgui_data(user)
else
data["focus"] = null
return data
/datum/tgui_module/power_monitor/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("clear")
active_sensor = null
. = TRUE
if("refresh")
refresh_sensors()
. = TRUE
if("setsensor")
active_sensor = params["id"]
. = TRUE
/datum/tgui_module/power_monitor/proc/has_alarm()
for(var/obj/machinery/power/sensor/S in grid_sensors)
if(S.check_grid_warning())
return TRUE
return FALSE
/datum/tgui_module/power_monitor/proc/refresh_sensors()
grid_sensors = list()
// Handle ultranested programs
var/turf/T = get_turf(tgui_host())
var/list/levels = list()
if(!T) // Safety check
return
if(T)
levels += using_map.get_map_levels(T.z, FALSE)
for(var/obj/machinery/power/sensor/S in machines)
if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
else
grid_sensors += S
/datum/tgui_module/power_monitor/ntos
ntos = TRUE
// Subtype for self_state
/datum/tgui_module/power_monitor/robot
/datum/tgui_module/power_monitor/robot/tgui_state(mob/user)
return GLOB.tgui_self_state
+118
View File
@@ -0,0 +1,118 @@
/datum/tgui_module/rcon
name = "Power RCON"
tgui_id = "RCON"
var/list/known_SMESs = null
var/list/known_breakers = null
/datum/tgui_module/rcon/tgui_data(mob/user)
FindDevices() // Update our devices list
var/list/data = ..()
// SMES DATA (simplified view)
var/list/smeslist[0]
for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs)
smeslist.Add(list(list(
"capacity" = SMES.capacity,
"capacityPercent" = round(100*SMES.charge/SMES.capacity, 0.1),
"charge" = SMES.charge,
"input_set" = SMES.input_attempt,
"input_val" = round(SMES.input_level/1000, 0.1),
"output_set" = SMES.output_attempt,
"output_val" = round(SMES.output_level/1000, 0.1),
"output_load" = round(SMES.output_used/1000, 0.1),
"RCON_tag" = SMES.RCon_tag
)))
data["smes_info"] = sortByKey(smeslist, "RCON_tag")
// BREAKER DATA (simplified view)
var/list/breakerlist[0]
for(var/obj/machinery/power/breakerbox/BR in known_breakers)
breakerlist.Add(list(list(
"RCON_tag" = BR.RCon_tag,
"enabled" = BR.on
)))
data["breaker_info"] = breakerlist
return data
/datum/tgui_module/rcon/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("smes_in_toggle")
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
if(SMES)
SMES.toggle_input()
. = TRUE
if("smes_out_toggle")
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
if(SMES)
SMES.toggle_output()
. = TRUE
if("smes_in_set")
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
if(SMES)
var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000
SMES.set_input(inputset)
. = TRUE
if("smes_out_set")
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
if(SMES)
var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000
SMES.set_output(outputset)
. = TRUE
if("toggle_breaker")
var/obj/machinery/power/breakerbox/toggle = null
for(var/obj/machinery/power/breakerbox/breaker in known_breakers)
if(breaker.RCon_tag == params["breaker"])
toggle = breaker
if(toggle)
if(toggle.update_locked)
to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.")
else
toggle.auto_toggle()
. = TRUE
// Proc: GetSMESByTag()
// Parameters: 1 (tag - RCON tag of SMES we want to look up)
// Description: Looks up and returns SMES which has matching RCON tag
/datum/tgui_module/rcon/proc/GetSMESByTag(var/tag)
if(!tag)
return
for(var/obj/machinery/power/smes/buildable/S in known_SMESs)
if(S.RCon_tag == tag)
return S
// Proc: FindDevices()
// Parameters: None
// Description: Refreshes local list of known devices.
/datum/tgui_module/rcon/proc/FindDevices()
known_SMESs = new /list()
var/z = get_z(tgui_host())
var/list/map_levels = using_map.get_map_levels(z)
for(var/obj/machinery/power/smes/buildable/SMES in GLOB.smeses)
if(!(SMES.z in map_levels))
continue
if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon)
known_SMESs.Add(SMES)
known_breakers = new /list()
for(var/obj/machinery/power/breakerbox/breaker in machines)
if(!(breaker.z in map_levels))
continue
if(breaker.RCon_tag != "NO_TAG")
known_breakers.Add(breaker)
/datum/tgui_module/rcon/ntos
ntos = TRUE
/datum/tgui_module/rcon/robot
/datum/tgui_module/rcon/robot/tgui_state(mob/user)
return GLOB.tgui_self_state
@@ -0,0 +1,46 @@
/datum/tgui_module/shutoff_monitor
name = "Shutoff Valve Monitoring"
tgui_id = "ShutoffMonitor"
/datum/tgui_module/shutoff_monitor/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("toggle_enable")
var/obj/machinery/atmospherics/valve/shutoff/S = locate(params["valve"])
if(!istype(S))
return 0
S.close_on_leaks = !S.close_on_leaks
return 1
if("toggle_open")
var/obj/machinery/atmospherics/valve/shutoff/S = locate(params["valve"])
if(!istype(S))
return 0
if(S.open)
S.close()
else
S.open()
return 1
/datum/tgui_module/shutoff_monitor/tgui_data(mob/user)
var/list/data = list()
var/list/valves = list()
for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves)
valves.Add(list(list(
"name" = S.name,
"enabled" = S.close_on_leaks,
"open" = S.open,
"x" = S.x,
"y" = S.y,
"z" = S.z,
"ref" = "\ref[S]"
)))
data["valves"] = valves
return data
/datum/tgui_module/shutoff_monitor/ntos
ntos = TRUE
@@ -0,0 +1,108 @@
/datum/tgui_module/supermatter_monitor
name = "Supermatter monitor"
tgui_id = "SupermatterMonitor"
var/list/supermatters
var/obj/machinery/power/supermatter/active = null // Currently selected supermatter crystal.
/datum/tgui_module/supermatter_monitor/Destroy()
. = ..()
active = null
supermatters = null
/datum/tgui_module/supermatter_monitor/New()
..()
refresh()
// Refreshes list of active supermatter crystals
/datum/tgui_module/supermatter_monitor/proc/refresh()
supermatters = list()
var/z = get_z(tgui_host())
if(!z)
return
var/valid_z_levels = using_map.get_map_levels(z)
for(var/obj/machinery/power/supermatter/S in machines)
// Delaminating, not within coverage, not on a tile.
if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/))
continue
supermatters.Add(S)
if(!(active in supermatters))
active = null
/datum/tgui_module/supermatter_monitor/proc/get_status()
. = SUPERMATTER_INACTIVE
for(var/obj/machinery/power/supermatter/S in supermatters)
. = max(., S.get_status())
/datum/tgui_module/supermatter_monitor/tgui_data(mob/user)
var/list/data = ..()
if(istype(active))
var/turf/T = get_turf(active)
if(!T)
active = null
return
var/datum/gas_mixture/air = T.return_air()
if(!istype(air))
active = null
return
data["active"] = 1
data["SM_area"] = get_area(active)
data["SM_integrity"] = active.get_integrity()
data["SM_power"] = active.power
data["SM_ambienttemp"] = air.temperature
data["SM_ambientpressure"] = air.return_pressure()
data["SM_EPR"] = active.get_epr()
//data["SM_EPR"] = active.get_epr()
if(air.total_moles)
data["SM_gas_O2"] = round(100*air.gas["oxygen"]/air.total_moles,0.01)
data["SM_gas_CO2"] = round(100*air.gas["carbon_dioxide"]/air.total_moles,0.01)
data["SM_gas_N2"] = round(100*air.gas["nitrogen"]/air.total_moles,0.01)
data["SM_gas_PH"] = round(100*air.gas["phoron"]/air.total_moles,0.01)
data["SM_gas_N2O"] = round(100*air.gas["sleeping_agent"]/air.total_moles,0.01)
else
data["SM_gas_O2"] = 0
data["SM_gas_CO2"] = 0
data["SM_gas_N2"] = 0
data["SM_gas_PH"] = 0
data["SM_gas_N2O"] = 0
else
var/list/SMS = list()
for(var/obj/machinery/power/supermatter/S in supermatters)
var/area/A = get_area(S)
if(!A)
continue
SMS.Add(list(list(
"area_name" = A.name,
"integrity" = S.get_integrity(),
"uid" = S.uid
)))
data["active"] = 0
data["supermatters"] = SMS
return data
/datum/tgui_module/supermatter_monitor/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("clear")
active = null
. = TRUE
if("refresh")
refresh()
. = TRUE
if("set")
var/newuid = text2num(params["set"])
for(var/obj/machinery/power/supermatter/S in supermatters)
if(S.uid == newuid)
active = S
. = TRUE
/datum/tgui_module/supermatter_monitor/ntos
ntos = TRUE
+41 -42
View File
@@ -143,57 +143,56 @@
/obj/structure/lift/panel/interact(var/mob/user)
if(!..())
return
tgui_interact(user)
var/dat = list()
dat += "<html><body><hr><b>Lift panel</b><hr>"
/obj/structure/lift/panel/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Turbolift", name)
ui.open()
//the floors list stores levels in order of increasing Z
//therefore, to display upper levels at the top of the menu and
//lower levels at the bottom, we need to go through the list in reverse
/obj/structure/lift/panel/tgui_data(mob/user)
var/list/data = list()
data["doors_open"] = lift.doors_are_open()
data["fire_mode"] = lift.fire_mode
data["floors"] = list()
for(var/i in lift.floors.len to 1 step -1)
var/datum/turbolift_floor/floor = lift.floors[i]
var/label = floor.label? floor.label : "Level #[i]"
dat += "<font color = '[(floor in lift.queued_floors) ? COLOR_YELLOW : COLOR_WHITE]'>"
dat += "<a href='?src=\ref[src];move_to_floor=["\ref[floor]"]'>[label]</a>: [floor.name]</font><br>"
data["floors"].Add(list(list(
"id" = i,
"ref" = "\ref[floor]",
"queued" = (floor in lift.queued_floors),
"target" = (lift.target_floor == floor),
"current" = (lift.current_floor == floor),
"label" = floor.label,
"name" = floor.name,
)))
return data
dat += "<hr>"
if(lift.doors_are_open())
dat += "<a href='?src=\ref[src];close_doors=1'>Close Doors</a><br>"
else
dat += "<a href='?src=\ref[src];open_doors=1'>Open Doors</a><br>"
dat += "<a href='?src=\ref[src];emergency_stop=1'>Emergency Stop</a>"
dat += "<hr></body></html>"
/obj/structure/lift/panel/tgui_act(action, params)
if(..())
return TRUE
user.set_machine(src)
var/datum/browser/popup = new(user, "turbolift_panel", "Lift Panel", 350, 320) //VOREStation Edit - Wider!
popup.set_content(jointext(dat, null))
popup.open()
return
switch(action)
if("move_to_floor")
. = TRUE
lift.queue_move_to(locate(params["ref"]))
if("toggle_doors")
. = TRUE
if(lift.doors_are_open())
lift.close_doors()
else
lift.open_doors()
if("emergency_stop")
. = TRUE
lift.emergency_stop()
/obj/structure/lift/panel/Topic(href, href_list)
. = ..()
if(.)
return
var/panel_interact
if(href_list["move_to_floor"])
lift.queue_move_to(locate(href_list["move_to_floor"]))
panel_interact = 1
if(href_list["open_doors"])
panel_interact = 1
lift.open_doors()
if(href_list["close_doors"])
panel_interact = 1
lift.close_doors()
if(href_list["emergency_stop"])
panel_interact = 1
lift.emergency_stop()
if(panel_interact)
pressed(usr)
updateDialog()
return 0
/obj/structure/lift/panel/update_icon()
if(lift.fire_mode)
+5 -36
View File
@@ -126,49 +126,18 @@ obj/machinery/airlock_sensor/phoron/airlock_exterior
//Advanced airlock controller for when you want a more versatile airlock controller - useful for turning simple access control rooms into airlocks
/obj/machinery/embedded_controller/radio/airlock/phoron
name = "Phoron Lock Controller"
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "secure")
/obj/machinery/embedded_controller/radio/airlock/phoron/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data = list(
/obj/machinery/embedded_controller/radio/airlock/phoron/tgui_data(mob/user)
. = list(
"chamber_pressure" = program.memory["chamber_sensor_pressure"],
"chamber_phoron" = program.memory["chamber_sensor_phoron"],
"exterior_status" = program.memory["exterior_status"],
"interior_status" = program.memory["interior_status"],
"processing" = program.memory["processing"]
"processing" = program.memory["processing"],
"internalTemplateName" = "AirlockConsolePhoron",
)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "phoron_airlock_console.tmpl", name, 470, 290)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/embedded_controller/radio/airlock/phoron/Topic(href, href_list)
if((. = ..()))
return
var/clean = 0
switch(href_list["command"]) //anti-HTML-hacking checks
if("cycle_ext")
clean = 1
if("cycle_int")
clean = 1
if("force_ext")
clean = 1
if("force_int")
clean = 1
if("abort")
clean = 1
if("secure")
clean = 1
if(clean)
program.receive_user_command(href_list["command"])
return 1
//
// PHORON LOCK CONTROLLER PROGRAM
//
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

@@ -1,60 +0,0 @@
<div class="item" style="padding-top: 10px">
<div class="item">
<div class="itemLabel">
External Pressure:
</div>
<div class="itemContent">
{{:helper.displayBar(data.external_pressure, 0, 200, (data.external_pressure < 80 || data.external_pressure > 120) ? 'bad' : (data.external_pressure < 95 || data.external_pressure > 110) ? 'average' : 'good')}}
<div class="statusValue">
{{:data.external_pressure}} kPa
</div>
</div>
</div>
<div class="item">
<div class="itemLabel">
Chamber Pressure:
</div>
<div class="itemContent">
{{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80 || data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95 || data.chamber_pressure > 110) ? 'average' : 'good')}}
<div class="statusValue">
{{:data.chamber_pressure}} kPa
</div>
</div>
</div>
<div class="item">
<div class="itemLabel">
Internal Pressure:
</div>
<div class="itemContent">
{{:helper.displayBar(data.internal_pressure, 0, 200, (data.internal_pressure < 80 || data.internal_pressure > 120) ? 'bad' : (data.internal_pressure < 95 || data.internal_pressure > 110) ? 'average' : 'good')}}
<div class="statusValue">
{{:data.internal_pressure}} kPa
</div>
</div>
</div>
</div>
<div class="item" style="padding-top: 10px">
<div class="item" style="width: auto; float: left">
<div class="itemContent">
{{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, data.processing ? 'disabled' : null)}}
{{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, data.processing ? 'disabled' : null)}}
</div>
<div class="itemContent" style="padding-top: 2px">
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? 'yellowButton' : null)}}
{{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? 'yellowButton' : null)}}
</div>
</div>
<div style="padding-left: 10px; width: 80px; float: left">
<div class="item">
<div class="itemContent" style="padding-bottom: 2px; width: auto">
{{:helper.link('Purge', 'refresh', {'command' : 'purge'}, data.processing ? 'disabled' : null, data.purge ? 'linkOn' : null)}}
</div>
<div class="itemContent" style="width: auto">
{{:helper.link('Secure', data.secure ? 'locked' : 'unlocked', {'command' : 'secure'}, data.processing ? 'disabled' : null, data.secure ? 'linkOn' : null)}}
</div>
</div>
</div>
<div class="item" style="padding-top: 10px">
{{:helper.link('Abort', 'cancel', {'command' : 'abort'}, data.processing ? null : 'disabled', data.processing ? 'redButton' : null)}}
</div>
</div>
-103
View File
@@ -1,103 +0,0 @@
<!--
Title: inteliCore interface
Used In File(s): \code\game\objects\items\devices\aicard.dm
-->
<style type="text/css">
table.borders {
width:95%;
margin-left:2.4%;
margin-right:2.4%;
}
table.borders, table.borders tr {
border: 1px solid White;
}
td.law_index {
width: 50px;
}
td.state {
width: 63px;
text-align:center;
}
td.add {
width: 36px;
}
td.edit {
width: 36px;
text-align:center;
}
td.delete {
width: 53px;
text-align:center;
}
td.law_type {
width: 65px;
}
td.position {
width: 37px;
}
</style>
{{if data.has_ai}}
<div class="item">
<div class="itemLabel">
Hardware Integrity:
</div>
<div class="itemContent">
{{:data.hardware_integrity}}%
</div>
<div class="itemLabel">
Backup Capacitor:
</div>
<div class="itemContent">
{{:data.backup_capacitor}}%
</div>
</div>
{{if data.has_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td></tr>
<div class="itemLabelNarrow">
Laws:
</div>
{{for data.laws}}
<tr><td valign="top">{{:value.index}}.</td><td>{{:value.law}}</td></tr>
{{/for}}
</table>
{{else}}
<span class='notice'>No laws found.</span>
{{/if}}
{{if data.operational}}
<table>
<tr>
<td><span class='itemLabelWidest'>Radio Subspace Transceiver</span></td>
<td>{{:helper.link("Enabled", null, {'radio' : 0}, data.radio ? 'selected' : null)}}</td>
<td>{{:helper.link("Disabled", null, {'radio' : 1}, data.radio ? null : 'redButton' )}}</td>
</tr>
<tr><td><span class='itemLabelWidest'>Wireless Interface</span></td>
<td>{{:helper.link("Enabled", null, {'wireless' : 0}, data.wireless ? 'selected' : null)}}</td>
<td>{{:helper.link("Disabled", null, {'wireless' : 1}, data.wireless ? null : 'redButton' )}}</td>
</tr>
{{if data.flushing}}
<tr><td><span class='notice'>AI shutdown in progress...</span></td></tr>
{{else}}
<tr>
<td><span class='itemLabelWidest'>AI Power</span></td>
<td>{{:helper.link("Shutdown", 'radiation', {'wipe' : 1}, null, 'redButton')}}</td>
</tr>
{{/if}}
</table>
{{/if}}
{{else}}
Stored AI: <span class='notice'>No AI detected.</span>
{{/if}}

Some files were not shown because too many files have changed in this diff Show More