mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-25 04:57:12 +01:00
WIP v1, TGUI gas canisters
This commit is contained in:
@@ -130,7 +130,7 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
|
||||
for(i=1;i<=L.len;i++)
|
||||
var/list/LL = L[i]
|
||||
LL = LL.Copy() //make sure we don't edit the datum list
|
||||
LL.Add(list("active" = decals[LL["icon"]])) //"active" used by nanoUI
|
||||
LL.Add(list("active" = decals[LL["icon"]]))
|
||||
possibledecals.Add(LL)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/check_change()
|
||||
@@ -216,7 +216,7 @@ update_flag
|
||||
update_flag &= ~196 //the flags 128 and 64 represent change, not states. As such, we have to reset them to be able to detect a change on the next go.
|
||||
return
|
||||
|
||||
//template modification exploit prevention, used in Topic()
|
||||
//template modification exploit prevention
|
||||
/obj/machinery/portable_atmospherics/canister/proc/is_a_color(var/inputVar, var/checkColor = "all")
|
||||
if(checkColor == "prim" || checkColor == "all")
|
||||
for(var/list/L in GLOB.canister_icon_container.possiblemaincolor)
|
||||
@@ -344,14 +344,20 @@ update_flag
|
||||
investigate_log("[key_name(user)] started a transfer into [holding].<br>", "atmos")
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob)
|
||||
src.add_hiddenprint(user)
|
||||
return src.attack_hand(user)
|
||||
add_hiddenprint(user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/attack_ghost(var/mob/user as mob)
|
||||
return src.ui_interact(user)
|
||||
return tgui_interact(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/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Canister", name, 600, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.physical_state)
|
||||
if(src.destroyed)
|
||||
@@ -369,115 +375,102 @@ update_flag
|
||||
ui.set_auto_update(1)
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_data(mob/user, datum/topic_state/state)
|
||||
/obj/machinery/portable_atmospherics/canister/tgui_data()
|
||||
init_data_vars() //set up var/colorcontainer and var/possibledecals
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
data["name"] = name
|
||||
data["menu"] = menu ? 1 : 0
|
||||
data["canLabel"] = can_label ? 1 : 0
|
||||
data["canister_color"] = canister_color
|
||||
data["colorContainer"] = colorcontainer.Copy()
|
||||
colorcontainer.Cut()
|
||||
data["possibleDecals"] = possibledecals.Copy()
|
||||
possibledecals.Cut()
|
||||
var/data = list()
|
||||
data["portConnected"] = connected_port ? 1 : 0
|
||||
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
||||
data["releasePressure"] = round(release_pressure ? release_pressure : 0)
|
||||
data["defaultReleasePressure"] = ONE_ATMOSPHERE
|
||||
data["minReleasePressure"] = round(ONE_ATMOSPHERE/10)
|
||||
data["maxReleasePressure"] = round(10*ONE_ATMOSPHERE)
|
||||
data["valveOpen"] = valve_open ? 1 : 0
|
||||
|
||||
data["name"] = name
|
||||
data["canLabel"] = can_label ? 1 : 0
|
||||
data["colorContainer"] = colorcontainer.Copy()
|
||||
data["possibleDecals"] = possibledecals.Copy()
|
||||
data["primColor"] = canister_color["prim"]
|
||||
data["secColor"] = canister_color["sec"]
|
||||
data["terColor"] = canister_color["ter"]
|
||||
data["quartColor"] = canister_color["quart"]
|
||||
data["hasHoldingTank"] = holding ? 1 : 0
|
||||
if(holding)
|
||||
data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure()))
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/Topic(href, href_list)
|
||||
/obj/machinery/portable_atmospherics/canister/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
init_data_vars()
|
||||
var/can_min_release_pressure = round(ONE_ATMOSPHERE/10)
|
||||
var/can_max_release_pressure = round(10*ONE_ATMOSPHERE)
|
||||
. = TRUE
|
||||
switch(action)
|
||||
|
||||
if(href_list["choice"] == "menu")
|
||||
menu = text2num(href_list["mode_target"])
|
||||
|
||||
if(href_list["toggle"])
|
||||
var/logmsg
|
||||
if(valve_open)
|
||||
if(holding)
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into the [holding]<br>"
|
||||
else
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into the <font color='red'><b>air</b></font><br>"
|
||||
else
|
||||
if(holding)
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting the transfer into the [holding]<br>"
|
||||
else
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting the transfer into the <font color='red'><b>air</b></font><br>"
|
||||
if(air_contents.toxins > 0)
|
||||
message_admins("[key_name_admin(usr)] opened a canister that contains plasma in [get_area(src)]! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains plasma at [get_area(src)]: [x], [y], [z]")
|
||||
if(air_contents.sleeping_agent > 0)
|
||||
message_admins("[key_name_admin(usr)] opened a canister that contains N2O in [get_area(src)]! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains N2O at [get_area(src)]: [x], [y], [z]")
|
||||
investigate_log(logmsg, "atmos")
|
||||
release_log += logmsg
|
||||
valve_open = !valve_open
|
||||
|
||||
if(href_list["remove_tank"])
|
||||
if(holding)
|
||||
if(valve_open)
|
||||
valve_open = 0
|
||||
release_log += "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into the [holding]<br>"
|
||||
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["rename"])
|
||||
if(can_label)
|
||||
var/T = sanitize(copytext(input("Choose canister label", "Name", name) as text|null,1,MAX_NAME_LEN))
|
||||
if(can_label) //Exploit prevention
|
||||
if(T)
|
||||
name = T
|
||||
if("relabel")
|
||||
if(can_label)
|
||||
var/T = sanitize(copytext(input("Choose canister label", "Name", name) as text|null, 1, MAX_NAME_LEN))
|
||||
if(can_label) //Exploit prevention
|
||||
if(T)
|
||||
name = T
|
||||
else
|
||||
name = "canister"
|
||||
else
|
||||
name = "canister"
|
||||
to_chat(usr, "<span class='warning'>As you attempted to rename it the pressure rose!</span>")
|
||||
. = FALSE
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "reset")
|
||||
pressure = ONE_ATMOSPHERE
|
||||
else if(pressure == "min")
|
||||
pressure = can_min_release_pressure
|
||||
else if(pressure == "max")
|
||||
pressure = can_max_release_pressure
|
||||
else if(pressure == "input")
|
||||
pressure = input("New release pressure ([can_min_release_pressure]-[can_max_release_pressure] kPa):", name, release_pressure) as num|null
|
||||
if(isnull(pressure))
|
||||
. = FALSE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
release_pressure = clamp(round(pressure), can_min_release_pressure, can_max_release_pressure)
|
||||
investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", "atmos")
|
||||
if("valve")
|
||||
var/logmsg
|
||||
valve_open = !valve_open
|
||||
if(valve_open)
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting a transfer into \the [holding || "air"].<br>"
|
||||
if(!holding)
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting the transfer into the <font color='red'><b>air</b></font><br>"
|
||||
if(air_contents.toxins > 0)
|
||||
message_admins("[key_name_admin(usr)] opened a canister that contains plasma in [get_area(src)]! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains plasma at [get_area(src)]: [x], [y], [z]")
|
||||
if(air_contents.sleeping_agent > 0)
|
||||
message_admins("[key_name_admin(usr)] opened a canister that contains N2O in [get_area(src)]! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] opened a canister that contains N2O at [get_area(src)]: [x], [y], [z]")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>As you attempted to rename it the pressure rose!</span>")
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into \the [holding || "air"].<br>"
|
||||
investigate_log(logmsg, "atmos")
|
||||
release_log += logmsg
|
||||
if("eject")
|
||||
if(holding)
|
||||
if(valve_open)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] removed [holding] from [src] with valve still open at [ADMIN_VERBOSEJMP(src)] releasing contents into the <span class='boldannounce'>air</span>.")
|
||||
investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transferring into the <span class='boldannounce'>air</span>.", "atmos")
|
||||
replace_tank(usr, FALSE)
|
||||
if("recolor")
|
||||
var/ctype = params["ctype"]
|
||||
var/cnum = text2num(params["nc"])
|
||||
if(isnull(colorcontainer[ctype]))
|
||||
message_admins("[key_name_admin(usr)] passed an invalid ctype var [ctype] to a canister.")
|
||||
return
|
||||
|
||||
if(href_list["choice"] == "Primary color")
|
||||
if(is_a_color(href_list["icon"],"prim"))
|
||||
canister_color["prim"] = href_list["icon"]
|
||||
if(href_list["choice"] == "Secondary color")
|
||||
if(href_list["icon"] == "none")
|
||||
canister_color["sec"] = "none"
|
||||
else if(is_a_color(href_list["icon"],"sec"))
|
||||
canister_color["sec"] = href_list["icon"]
|
||||
if(href_list["choice"] == "Tertiary color")
|
||||
if(href_list["icon"] == "none")
|
||||
canister_color["ter"] = "none"
|
||||
else if(is_a_color(href_list["icon"],"ter"))
|
||||
canister_color["ter"] = href_list["icon"]
|
||||
if(href_list["choice"] == "Quaternary color")
|
||||
if(href_list["icon"] == "none")
|
||||
canister_color["quart"] = "none"
|
||||
else if(is_a_color(href_list["icon"],"quart"))
|
||||
canister_color["quart"] = href_list["icon"]
|
||||
|
||||
if(href_list["choice"] == "decals")
|
||||
if(is_a_decal(href_list["icon"]))
|
||||
decals[href_list["icon"]] = (decals[href_list["icon"]] == 0)
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
var/cclen = colorcontainer[ctype]["options"].len
|
||||
var/newcolor = sanitize_integer(cnum, 0, cclen)
|
||||
newcolor++
|
||||
message_admins("[key_name_admin(usr)] passed: [ctype], [cnum] => [newcolor], [cclen]")
|
||||
canister_color[ctype] = colorcontainer[ctype]["options"][newcolor]["icon"]
|
||||
update_icon()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/toxins
|
||||
name = "Canister \[Toxin (Plasma)\]"
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
import { toFixed } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { AnimatedNumber, Box, Button, Dropdown, Icon, Knob, LabeledControls, LabeledList, Section, Tooltip } from '../components';
|
||||
import { formatSiUnit } from '../format';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
export const Canister = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
portConnected,
|
||||
tankPressure,
|
||||
releasePressure,
|
||||
defaultReleasePressure,
|
||||
minReleasePressure,
|
||||
maxReleasePressure,
|
||||
valveOpen,
|
||||
name,
|
||||
canLabel,
|
||||
colorContainer,
|
||||
possibleDecals,
|
||||
primColor,
|
||||
secColor,
|
||||
terColor,
|
||||
quartColor,
|
||||
hasHoldingTank,
|
||||
holdingTank,
|
||||
} = data;
|
||||
|
||||
let array_prim = [];
|
||||
let array_sec = [];
|
||||
let array_ter = [];
|
||||
let array_quart = [];
|
||||
let i = 0;
|
||||
|
||||
for (i = 0; i < colorContainer.prim.options.length; i++) {
|
||||
array_prim.push(colorContainer.prim.options[i]["name"]);
|
||||
}
|
||||
|
||||
for (i = 0; i < colorContainer.sec.options.length; i++) {
|
||||
array_sec.push(colorContainer.sec.options[i]["name"]);
|
||||
}
|
||||
for (i = 0; i < colorContainer.ter.options.length; i++) {
|
||||
array_ter.push(colorContainer.ter.options[i]["name"]);
|
||||
}
|
||||
|
||||
for (i = 0; i < colorContainer.quart.options.length; i++) {
|
||||
array_quart.push(colorContainer.quart.options[i]["name"]);
|
||||
}
|
||||
|
||||
return (
|
||||
<Window
|
||||
width={300}
|
||||
height={232}>
|
||||
<Window.Content>
|
||||
<Section
|
||||
title={name}
|
||||
buttons={(
|
||||
<Button
|
||||
icon="pencil-alt"
|
||||
content="Relabel"
|
||||
disabled={!canLabel}
|
||||
onClick={() => act('relabel')} />
|
||||
)}>
|
||||
<LabeledControls>
|
||||
<LabeledControls.Item
|
||||
minWidth="66px"
|
||||
label="Pressure">
|
||||
<AnimatedNumber
|
||||
value={tankPressure}
|
||||
format={value => {
|
||||
if (value < 10000) {
|
||||
return toFixed(value) + ' kPa';
|
||||
}
|
||||
return formatSiUnit(value * 1000, 1, 'Pa');
|
||||
}} />
|
||||
</LabeledControls.Item>
|
||||
<LabeledControls.Item label="Regulator">
|
||||
<Box
|
||||
position="relative"
|
||||
left="-8px">
|
||||
<Knob
|
||||
size={1.25}
|
||||
color={!!valveOpen && 'yellow'}
|
||||
value={releasePressure}
|
||||
unit="kPa"
|
||||
minValue={minReleasePressure}
|
||||
maxValue={maxReleasePressure}
|
||||
step={5}
|
||||
stepPixelSize={1}
|
||||
onDrag={(e, value) => act('pressure', {
|
||||
pressure: value,
|
||||
})} />
|
||||
<Button
|
||||
fluid
|
||||
position="absolute"
|
||||
top="-2px"
|
||||
right="-20px"
|
||||
color="transparent"
|
||||
icon="fast-forward"
|
||||
onClick={() => act('pressure', {
|
||||
pressure: maxReleasePressure,
|
||||
})} />
|
||||
<Button
|
||||
fluid
|
||||
position="absolute"
|
||||
top="16px"
|
||||
right="-20px"
|
||||
color="transparent"
|
||||
icon="undo"
|
||||
onClick={() => act('pressure', {
|
||||
pressure: defaultReleasePressure,
|
||||
})} />
|
||||
</Box>
|
||||
</LabeledControls.Item>
|
||||
<LabeledControls.Item label="Valve">
|
||||
<Button
|
||||
my={0.5}
|
||||
width="50px"
|
||||
lineHeight={2}
|
||||
fontSize="11px"
|
||||
color={valveOpen
|
||||
? (hasHoldingTank ? 'caution' : 'danger')
|
||||
: null}
|
||||
content={valveOpen ? 'Open' : 'Closed'}
|
||||
onClick={() => act('valve')} />
|
||||
</LabeledControls.Item>
|
||||
<LabeledControls.Item
|
||||
mr={1}
|
||||
label="Port">
|
||||
<Box position="relative">
|
||||
<Icon
|
||||
size={1.25}
|
||||
name={portConnected ? 'plug' : 'times'}
|
||||
color={portConnected ? 'good' : 'bad'} />
|
||||
<Tooltip
|
||||
content={portConnected
|
||||
? 'Connected'
|
||||
: 'Disconnected'}
|
||||
position="top" />
|
||||
</Box>
|
||||
</LabeledControls.Item>
|
||||
</LabeledControls>
|
||||
</Section>
|
||||
<Section
|
||||
title="Holding Tank"
|
||||
buttons={!!hasHoldingTank && (
|
||||
<Button
|
||||
icon="eject"
|
||||
color={valveOpen && 'danger'}
|
||||
content="Eject"
|
||||
onClick={() => act('eject')} />
|
||||
)}>
|
||||
{!!hasHoldingTank && (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Label">
|
||||
{holdingTank.name}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Pressure">
|
||||
<AnimatedNumber value={holdingTank.tankPressure} /> kPa
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
)}
|
||||
{!hasHoldingTank && (
|
||||
<Box color="average">
|
||||
No Holding Tank
|
||||
</Box>
|
||||
)}
|
||||
</Section>
|
||||
|
||||
<Section title="Paint">
|
||||
<LabeledControls>
|
||||
<LabeledControls.Item
|
||||
minWidth="100px"
|
||||
label={colorContainer.prim.name}>
|
||||
<Dropdown
|
||||
over
|
||||
selected=""
|
||||
disabled={!canLabel}
|
||||
options={array_prim}
|
||||
width="100px"
|
||||
onSelected={value => act('recolor',
|
||||
{ nc: array_prim.indexOf(value),
|
||||
ctype: "prim" })} />
|
||||
</LabeledControls.Item>
|
||||
<LabeledControls.Item
|
||||
minWidth="100px"
|
||||
label={colorContainer.sec.name}>
|
||||
<Dropdown
|
||||
over
|
||||
selected=""
|
||||
disabled={!canLabel}
|
||||
options={array_sec}
|
||||
width="100px"
|
||||
onSelected={value => act('recolor',
|
||||
{ nc: array_sec.indexOf(value),
|
||||
ctype: "sec" })} />
|
||||
</LabeledControls.Item>
|
||||
<LabeledControls.Item
|
||||
minWidth="100px"
|
||||
label={colorContainer.ter.name}>
|
||||
<Dropdown
|
||||
over
|
||||
selected=""
|
||||
disabled={!canLabel}
|
||||
options={array_ter}
|
||||
width="100px"
|
||||
onSelected={value => act('recolor',
|
||||
{ nc: array_ter.indexOf(value),
|
||||
ctype: "ter" })} />
|
||||
</LabeledControls.Item>
|
||||
<LabeledControls.Item
|
||||
minWidth="100px"
|
||||
label={colorContainer.quart.name}>
|
||||
<Dropdown
|
||||
over
|
||||
selected=""
|
||||
disabled={!canLabel}
|
||||
options={array_quart}
|
||||
width="100px"
|
||||
onSelected={value => act('recolor',
|
||||
{ nc: array_quart.indexOf(value),
|
||||
ctype: "quart" })} />
|
||||
</LabeledControls.Item>
|
||||
</LabeledControls>
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user