Canister, Tank & Tank Transfer Value NanoUIs.

* Added Canister, Tank & Tank Transfer Value NanoUIs.
This commit is contained in:
Mark Aherne (Faerdan)
2014-01-15 01:08:45 +00:00
parent cb72e02f23
commit 024a0baa49
9 changed files with 388 additions and 164 deletions
+2 -2
View File
@@ -272,7 +272,7 @@
I.loc = src
src.disk = I
user << "You insert [I]."
nanomanager.update_uis(src) // update all UIs attached to src()
nanomanager.update_uis(src) // update all UIs attached to src
return
else
src.attack_hand(user)
@@ -342,7 +342,7 @@
W.loc = src
src.disk = W
user << "You insert [W]."
nanomanager.update_uis(src) // update all UIs attached to src()
nanomanager.update_uis(src) // update all UIs attached to src
/*
/obj/machinery/computer/scan_consolenew/process() //not really used right now
if(stat & (NOPOWER|BROKEN))
+81 -79
View File
@@ -138,8 +138,6 @@
if(air_contents.temperature > PLASMA_FLASHPOINT)
air_contents.zburn()
src.updateDialog()
return
/obj/machinery/portable_atmospherics/canister/return_air()
@@ -194,6 +192,10 @@
return
..()
nanomanager.update_uis(src) // Update all NanoUIs attached to src
/obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
@@ -202,94 +204,94 @@
return src.attack_hand(user)
/obj/machinery/portable_atmospherics/canister/attack_hand(var/mob/user as mob)
return src.interact(user)
return src.ui_interact(user)
/obj/machinery/portable_atmospherics/canister/interact(var/mob/user as mob)
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if (src.destroyed)
return
user.set_machine(src)
var/holding_text
if(holding)
holding_text = {"<BR><B>Tank Pressure</B>: [holding.air_contents.return_pressure()] KPa<BR>
<A href='?src=\ref[src];remove_tank=1'>Remove Tank</A><BR>
"}
var/output_text = {"<TT><B>[name]</B>[can_label?" <A href='?src=\ref[src];relabel=1'><small>relabel</small></a>":""]<BR>
Pressure: [air_contents.return_pressure()] KPa<BR>
Port Status: [(connected_port)?("Connected"):("Disconnected")]
[holding_text]
<BR>
Release Valve: <A href='?src=\ref[src];toggle=1'>[valve_open?("Open"):("Closed")]</A><BR>
Release Pressure: <A href='?src=\ref[src];pressure_adj=-1000'>-</A> <A href='?src=\ref[src];pressure_adj=-100'>-</A> <A href='?src=\ref[src];pressure_adj=-10'>-</A> <A href='?src=\ref[src];pressure_adj=-1'>-</A> [release_pressure] <A href='?src=\ref[src];pressure_adj=1'>+</A> <A href='?src=\ref[src];pressure_adj=10'>+</A> <A href='?src=\ref[src];pressure_adj=100'>+</A> <A href='?src=\ref[src];pressure_adj=1000'>+</A><BR>
<HR>
<A href='?src=\ref[user];mach_close=canister'>Close</A><BR>
"}
// this is the data which will be sent to the ui
var/data[0]
data["name"] = name
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["releasePressure"] = round(release_pressure ? release_pressure : 0)
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()))
user << browse("<html><head><title>[src]</title></head><body>[output_text]</body></html>", "window=canister;size=600x300")
onclose(user, "canister")
return
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
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)
/obj/machinery/portable_atmospherics/canister/Topic(href, href_list)
//Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict.
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=canister")
onclose(usr, "canister")
return
if (((get_dist(src, usr) <= 1) && istype(src.loc, /turf)))
usr.set_machine(src)
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>"
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>"
//Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict.
if (!istype(src.loc, /turf))
return 0
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>"
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>"
valve_open = !valve_open
if (href_list["remove_tank"])
if(holding)
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)
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_pressure = max(ONE_ATMOSPHERE/10, release_pressure+diff)
release_log += "Valve was <b>opened</b> by [usr] ([usr.ckey]), starting the transfer into the <font color='red'><b>air</b></font><br>"
valve_open = !valve_open
if (href_list["relabel"])
if (can_label)
var/list/colors = list(\
"\[N2O\]" = "redws", \
"\[N2\]" = "red", \
"\[O2\]" = "blue", \
"\[Toxin (Bio)\]" = "orange", \
"\[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.updateUsrDialog()
src.add_fingerprint(usr)
update_icon()
else
usr << browse(null, "window=canister")
return
return
if (href_list["remove_tank"])
if(holding)
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", \
"\[Toxin (Bio)\]" = "orange", \
"\[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)
update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/toxins/New()
@@ -33,6 +33,7 @@
user << "<span class='notice'>You attach the tank to the transfer valve.</span>"
update_icon()
nanomanager.update_uis(src) // update all UIs attached to src
//TODO: Have this take an assemblyholder
else if(isassembly(item))
var/obj/item/device/assembly/A = item
@@ -53,6 +54,7 @@
message_admins("[key_name_admin(user)] attached a [item] to a transfer valve.")
log_game("[key_name_admin(user)] attached a [item] to a transfer valve.")
attacher = user
nanomanager.update_uis(src) // update all UIs attached to src
return
@@ -63,49 +65,60 @@
/obj/item/device/transfer_valve/attack_self(mob/user as mob)
user.set_machine(src)
var/dat = {"<B> Valve properties: </B>
<BR> <B> Attachment one:</B> [tank_one] [tank_one ? "<A href='?src=\ref[src];tankone=1'>Remove</A>" : ""]
<BR> <B> Attachment two:</B> [tank_two] [tank_two ? "<A href='?src=\ref[src];tanktwo=1'>Remove</A>" : ""]
<BR> <B> Valve attachment:</B> [attached_device ? "<A href='?src=\ref[src];device=1'>[attached_device]</A>" : "None"] [attached_device ? "<A href='?src=\ref[src];rem_device=1'>Remove</A>" : ""]
<BR> <B> Valve status: </B> [ valve_open ? "<A href='?src=\ref[src];open=1'>Closed</A> <B>Open</B>" : "<B>Closed</B> <A href='?src=\ref[src];open=1'>Open</A>"]"}
ui_interact(user)
/obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
user << browse(dat, "window=trans_valve;size=600x300")
onclose(user, "trans_valve")
return
// this is the data which will be sent to the ui
var/data[0]
data["attachmentOne"] = tank_one ? tank_one.name : null
data["attachmentTwo"] = tank_two ? tank_two.name : null
data["valveAttachment"] = attached_device ? attached_device.name : null
data["valveOpen"] = valve_open ? 1 : 0
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
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, "transfer_valve.tmpl", "Tank Transfer Valve", 460, 280)
// 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)
/obj/item/device/transfer_valve/Topic(href, href_list)
..()
if ( usr.stat || usr.restrained() )
return
if (src.loc == usr)
if(tank_one && href_list["tankone"])
split_gases()
valve_open = 0
tank_one.loc = get_turf(src)
tank_one = null
return 0
if (src.loc != usr)
return 0
if(tank_one && href_list["tankone"])
split_gases()
valve_open = 0
tank_one.loc = get_turf(src)
tank_one = null
update_icon()
else if(tank_two && href_list["tanktwo"])
split_gases()
valve_open = 0
tank_two.loc = get_turf(src)
tank_two = null
update_icon()
else if(href_list["open"])
toggle_valve()
else if(attached_device)
if(href_list["rem_device"])
attached_device.loc = get_turf(src)
attached_device:holder = null
attached_device = null
update_icon()
else if(tank_two && href_list["tanktwo"])
split_gases()
valve_open = 0
tank_two.loc = get_turf(src)
tank_two = null
update_icon()
else if(href_list["open"])
toggle_valve()
else if(attached_device)
if(href_list["rem_device"])
attached_device.loc = get_turf(src)
attached_device:holder = null
attached_device = null
update_icon()
if(href_list["device"])
attached_device.attack_self(usr)
src.attack_self(usr)
src.add_fingerprint(usr)
return
return
if(href_list["device"])
attached_device.attack_self(usr)
src.add_fingerprint(usr)
return 1 // Returning 1 sends an update to attached UIs
/obj/item/device/transfer_valve/process_activation(var/obj/item/device/D)
if(toggle)
+61 -44
View File
@@ -1,3 +1,6 @@
#define TANK_MAX_RELEASE_PRESSURE (3*ONE_ATMOSPHERE)
#define TANK_DEFAULT_RELEASE_PRESSURE 24
/obj/item/weapon/tank
name = "tank"
icon = 'icons/obj/tank.dmi'
@@ -24,8 +27,7 @@
src.air_contents.volume = volume //liters
src.air_contents.temperature = T20C
processing_objects.Add(src)
processing_objects.Add(src)
return
/obj/item/weapon/tank/Del()
@@ -121,7 +123,10 @@
/obj/item/weapon/tank/attack_self(mob/user as mob)
if (!(src.air_contents))
return
user.set_machine(src)
ui_interact(user)
/obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
var/using_internal
if(istype(loc,/mob/living/carbon))
@@ -129,57 +134,69 @@
if(location.internal==src)
using_internal = 1
var/message = {"
<b>Tank</b><BR>
<FONT color='blue'><b>Tank Pressure:</b> [air_contents.return_pressure()]</FONT><BR>
<BR>
<b>Mask Release Pressure:</b> <A href='?src=\ref[src];dist_p=-10'>-</A> <A href='?src=\ref[src];dist_p=-1'>-</A> [distribute_pressure] <A href='?src=\ref[src];dist_p=1'>+</A> <A href='?src=\ref[src];dist_p=10'>+</A><BR>
<b>Mask Release Valve:</b> <A href='?src=\ref[src];stat=1'>[using_internal?("Open"):("Closed")]</A>
"}
user << browse(message, "window=tank;size=600x300")
onclose(user, "tank")
return
// this is the data which will be sent to the ui
var/data[0]
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["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
data["valveOpen"] = using_internal ? 1 : 0
data["maskConnected"] = 0
if(istype(loc,/mob/living/carbon))
var/mob/living/carbon/location = loc
if(location.internal == src || (location.wear_mask && (location.wear_mask.flags & MASKINTERNALS)))
data["maskConnected"] = 1
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
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)
/obj/item/weapon/tank/Topic(href, href_list)
..()
if (usr.stat|| usr.restrained())
return
if (src.loc == usr)
usr.set_machine(src)
if (href_list["dist_p"])
return 0
if (src.loc != usr)
return 0
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), 3*ONE_ATMOSPHERE)
if (href_list["stat"])
if(istype(loc,/mob/living/carbon))
var/mob/living/carbon/location = loc
if(location.internal == src)
location.internal = null
src.distribute_pressure = min(max(round(src.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE)
if (href_list["stat"])
if(istype(loc,/mob/living/carbon))
var/mob/living/carbon/location = loc
if(location.internal == src)
location.internal = null
location.internals.icon_state = "internal0"
usr << "\blue You close the tank release valve."
if (location.internals)
location.internals.icon_state = "internal0"
usr << "\blue You close the tank release valve."
else
if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))
location.internal = src
usr << "\blue You open \the [src] valve."
if (location.internals)
location.internals.icon_state = "internal0"
location.internals.icon_state = "internal1"
else
if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))
location.internal = src
usr << "\blue You open \the [src] valve."
if (location.internals)
location.internals.icon_state = "internal1"
else
usr << "\blue You need something to connect to \the [src]."
usr << "\blue You need something to connect to \the [src]."
src.add_fingerprint(usr)
/*
* the following is needed for a tank lying on the floor. But currently we restrict players to use not weared tanks as intrals. --rastaf
for(var/mob/M in viewers(1, src.loc))
if ((M.client && M.machine == src))
src.attack_self(M)
*/
src.attack_self(usr)
else
usr << browse(null, "window=tank")
return
return
src.add_fingerprint(usr)
return 1
/obj/item/weapon/tank/remove_air(amount)
+9 -1
View File
@@ -13,7 +13,7 @@ hr {
}
.link, .linkOn, .linkOff, .selected, .disabled {
float: left;
min-width: 40px;
min-width: 15px;
height: 16px;
text-align: center;
color: #ffffff;
@@ -174,6 +174,14 @@ h4 {
.dark {
color: #272727;
}
.noticePlaceholder {
position: relative;
font-size: 12px;
font-style: italic;
font-weight: bold;
padding: 3px 4px 3px 4px;
margin: 4px 0 4px 0;
}
.notice {
position: relative;
background: url(uiNoticeBackground.jpg) 50% 50%;
+2 -1
View File
@@ -61,10 +61,11 @@
Power cell removed.
</div>
{{else}}
{{:~displayBar(powerCellStatus, 0, 100, powerCellStatus >= 50 ? 'good' : powerCellStatus >= 25 ? 'average' : 'bad')}}
<div class="itemContent" style="width: 60px">
{{:~round(powerCellStatus*10)/10}}%
</div>
{{:~displayBar(powerCellStatus, 0, 100, powerCellStatus >= 50 ? 'good' : powerCellStatus >= 25 ? 'average' : 'bad')}}
{{/if}}
</div>
+83
View File
@@ -0,0 +1,83 @@
<h3>Tank Status</h3>
<div class="item">
<div class="itemLabel">
Tank Label:
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:name}}</div> {{:~link('Relabel', 'pencil', {'relabel' : 1}, (canLabel) ? null : 'disabled')}}
</div>
</div>
<div class="item">
<div class="itemLabel">
Tank Pressure:
</div>
<div class="itemContent">
{{:tankPressure}} kPa
</div>
</div>
<div class="item">
<div class="itemLabel">
Port Status:
</div>
<div class="itemContent">
{{:portConnected ? '<span class="good">Connected</span>' : '<span class="average">Disconnected</span>'}}
</div>
</div>
<h3>Holding Tank Status</h3>
{{if hasHoldingTank}}
<div class="item">
<div class="itemLabel">
Tank Label:
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:holdingTank.name}}</div> {{:~link('Eject', 'eject', {'remove_tank' : 1})}}
</div>
</div>
<div class="item">
<div class="itemLabel">
Tank Pressure:
</div>
<div class="itemContent">
{{:holdingTank.tankPressure}} kPa
</div>
</div>
{{else}}
<div class="item"><span class="average"><i>No holding tank inserted.</i></span></div>
<div class="item">&nbsp;</div>
{{/if}}
<h3>Release Valve Status</h3>
<div class="item">
<div class="itemLabel">
Release Pressure:
</div>
<div class="itemContent">
{{:~displayBar(releasePressure, minReleasePressure, maxReleasePressure)}}
<div style="clear: both; padding-top: 4px;">
{{:~link('-', null, {'pressure_adj' : -1000}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
{{:~link('-', null, {'pressure_adj' : -100}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
{{:~link('-', null, {'pressure_adj' : -10}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
{{:~link('-', null, {'pressure_adj' : -1}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
<div style="float: left; width: 80px; text-align: center;">&nbsp;{{:releasePressure}} kPa&nbsp;</div>
{{:~link('+', null, {'pressure_adj' : 1}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
{{:~link('+', null, {'pressure_adj' : 10}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
{{:~link('+', null, {'pressure_adj' : 100}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
{{:~link('+', null, {'pressure_adj' : 1000}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
</div>
</div>
</div>
<div class="item">
<div class="itemLabel">
Release Valve:
</div>
<div class="itemContent">
{{:~link('Open', 'unlocked', {'toggle' : 1}, valveOpen ? 'selected' : null)}}{{:~link('Close', 'locked', {'toggle' : 1}, valveOpen ? null : 'selected')}}
</div>
</div>
+47
View File
@@ -0,0 +1,47 @@
{{if maskConnected}}
<div class="noticePlaceholder">This tank is connected to a mask.</div>
{{else}}
<div class="notice">This tank is NOT connected to a mask.</div>
{{/if}}
<div class="item">
<div class="itemLabel">
Tank Pressure:
</div>
<div class="itemContent">
{{:~displayBar(tankPressure, 0, 1013, (tankPressure > 200) ? 'good' : (tankPressure > 100) ? 'average' : 'bad'))}}
<div class="statusValue">
{{:tankPressure}} kPa
</div>
</div>
</div>
<div class="item">&nbsp;</div>
<div class="item">
<div class="itemLabel">
Mask Release Pressure:
</div>
<div class="itemContent">
{{:~displayBar(releasePressure, 0, maxReleasePressure, (releasePressure >= 23) ? null : ((releasePressure >= 17) ? 'average' : 'bad'))}}
<div style="clear: both; padding-top: 4px;">
{{:~link('-', null, {'dist_p' : -10}, (releasePressure > 0) ? null : 'disabled')}}
{{:~link('-', null, {'dist_p' : -1}, (releasePressure > 0) ? null : 'disabled')}}
<div style="float: left; width: 80px; text-align: center;">&nbsp;{{:releasePressure}} kPa&nbsp;</div>
{{:~link('+', null, {'dist_p' : 1}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
{{:~link('+', null, {'dist_p' : 10}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
{{:~link('Max', null, {'dist_p' : 'max'}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
{{:~link('Reset', null, {'dist_p' : 'reset'}, (releasePressure != defaultReleasePressure) ? null : 'disabled')}}
</div>
</div>
</div>
<div class="item">
<div class="itemLabel">
Mask Release Valve:
</div>
<div class="itemContent">
{{:~link('Open', 'unlocked', {'stat' : 1}, (!maskConnected) ? 'disabled' : (valveOpen ? 'selected' : null))}}{{:~link('Close', 'locked', {'stat' : 1}, valveOpen ? null : 'selected')}}
</div>
</div>
+53
View File
@@ -0,0 +1,53 @@
<div class="item">
<div class="itemLabel">
Attachment One:
</div>
<div class="itemContent">
{{if attachmentOne}}
{{:attachmentOne}}
{{else}}
<i>None</i>
{{/if}}
{{:~link('Remove', 'eject', {'tankone' : 1}, attachmentOne ? null : 'disabled')}}
</div>
</div>
<div class="item">
<div class="itemLabel">
Attachment Two:
</div>
<div class="itemContent">
{{if attachmentTwo}}
{{:attachmentTwo}}
{{else}}
<i>None</i>
{{/if}}
{{:~link('Remove', 'eject', {'tanktwo' : 1}, attachmentTwo ? null : 'disabled')}}
</div>
</div>
<div class="item">
<div class="itemLabel">
Valve Attachment:
</div>
<div class="itemContent">
{{if valveAttachment}}
{{:valveAttachment}}
{{else}}
<i>None</i>
{{/if}}
{{:~link('Remove', 'eject', {'rem_device' : 1}, valveAttachment ? null : 'disabled')}}
</div>
</div>
<div class="item">&nbsp;</div>
<div class="item">
<div class="itemLabel">
Valve Status:
</div>
<div class="itemContent">
{{:~link('Open', 'unlocked', {'open' : 1}, (!attachmentOne || !attachmentTwo) ? 'disabled' : (valveOpen ? 'selected' : null))}}{{:~link('Close', 'locked', {'open' : 1}, (!attachmentOne || !attachmentTwo) ? 'disabled' : (valveOpen ? null : 'selected'))}}
</div>
</div>