Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TGUIification of TTV menu #17897

Merged
merged 11 commits into from Feb 9, 2024
8 changes: 4 additions & 4 deletions browserassets/tgui/tgui.bundle.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion browserassets/tgui/tgui.bundle.js

Large diffs are not rendered by default.

149 changes: 98 additions & 51 deletions code/obj/item/device/transfer_valve.dm
Expand Up @@ -138,64 +138,103 @@ TYPEINFO(/obj/item/device/transfer_valve)

return

/// Attach the tank the mob is currently holding
proc/attach_tank(mob/user, tank_preference=null)
if (!user) return
var/obj/item/I = user.equipped()
if (!istype(I, /obj/item/tank) || istype(I, /obj/item/clothing/head/butt)) return
var/obj/item/tank/myTank = I
if (!myTank.compatible_with_TTV) return
// Handle UI tank attachment
if (tank_preference == 1)
// This check should always pass
if (!src.tank_one)
src.tank_one = myTank
else if (tank_preference == 2)
// As should this one
if (!src.tank_two)
src.tank_two = myTank
// Handle attackby tank attachment (wherever fits)
else if (!tank_preference && !src.tank_one)
src.tank_one = myTank
else if (!tank_preference && !src.tank_two)
src.tank_two = myTank
else
// it did not fit, clearly. dummy.
boutput(user, SPAN_NOTICE("\the [myTank] cannot fit on the [src]!"))
return
user.drop_item()
myTank.set_loc(src)
boutput(user, SPAN_NOTICE("You attach \the [myTank] to the transfer valve"))
if(src.tank_one && src.tank_two)
var/turf/T = get_turf(src)
var/butt = istype(tank_one, /obj/item/clothing/head/butt) || istype(tank_two, /obj/item/clothing/head/butt)
logTheThing(LOG_BOMBING, user, "made a TTV tank transfer valve [butt ? "butt" : "bomb"] at [log_loc(T)].")
message_admins("[key_name(user)] made a TTV tank transfer valve [butt ? "butt" : "bomb"] at [log_loc(T)].")
UpdateIcon()
attacher = user
if(user.back == src)
user.update_clothing()

attack_self(mob/user as mob)
if (isghostdrone(user))
return
if (user.get_gang())
boutput(user, SPAN_ALERT("You think working with explosives would bring a lot of much heat onto your gang to mess with this. But you do it anyway."))
src.add_dialog(user)
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>"]
<BR> [c_flags & ONBACK ? "<B> Straps: </B> <A href='?src=\ref[src];straps=1'>Remove</A>" : ""]"}

user.Browse(dat, "window=trans_valve;size=600x300")
onclose(user, "trans_valve")
return

Topic(href, href_list)
src.ui_interact(user)

ui_data(mob/user)
var/tank_one_data = (src.tank_one) ? list("name"=src.tank_one.name, "num"=1, "pressure"=MIXTURE_PRESSURE(src.tank_one.air_contents), \
"maxPressure"=TANK_FRAGMENT_PRESSURE) \
: list("name"=null, "num"=1, "pressure"=null, "maxPressure"=null)
var/tank_two_data = (src.tank_two) ? list("name"=src.tank_two.name, "num"=2, "pressure"=MIXTURE_PRESSURE(src.tank_two.air_contents), \
"maxPressure"=TANK_FRAGMENT_PRESSURE) \
: list("name"=null, "num"=2, "pressure"=null, "maxPressure"=null)
return list(
"tank_one" = tank_one_data,
"tank_two" = tank_two_data,
"device" = "[src.attached_device]",
"opened" = src.valve_open,
)

ui_interact(mob/user, datum/tgui/ui)
ui = tgui_process.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "TTV", src.name)
ui.open()

ui_act(action, params)
..()
if (isghostdrone(usr))
if (isghostdrone(usr) || usr.stat || usr.restrained())
return
if (usr.get_gang())
boutput(usr, SPAN_ALERT("You think working with explosives would bring a lot of much heat onto your gang to mess with this. But you do it anyway."))
if (usr.stat|| usr.restrained())
return
if (src.loc == usr)
if(href_list["tankone"])
tank_one.set_loc(get_turf(src))
tank_one = null
UpdateIcon()
if(src.equipped_in_slot)
var/mob/wearer = src.loc
wearer.update_clothing()
if(href_list["tanktwo"])
tank_two.set_loc(get_turf(src))
tank_two = null
UpdateIcon()
if(src.equipped_in_slot)
var/mob/wearer = src.loc
wearer.update_clothing()
if(href_list["open"])
if (valve_open)
var/turf/bombturf = get_turf(src)
logTheThing(LOG_BOMBING, usr, "closed the valve on a TTV tank transfer valve at [log_loc(bombturf)].")
message_admins("[key_name(usr)] closed the valve on a TTV tank transfer valve at [log_loc(bombturf)].")
else
var/turf/bombturf = get_turf(src)
logTheThing(LOG_BOMBING, usr, "opened the valve on a TTV tank transfer valve at [log_loc(bombturf)].")
message_admins("[key_name(usr)] opened the valve on a TTV tank transfer valve at [log_loc(bombturf)].")
switch(action)
if ("add_item")
if (ismob(usr))
MeggalBozale marked this conversation as resolved.
Show resolved Hide resolved
if (params["tank"])
src.attach_tank(usr, params["tank"])
else
var/mob/M = usr
src.Attackby(M.equipped(), M)
if ("remove_tank_one")
src.remove_tank(tank_one)
if ("remove_tank_two")
src.remove_tank(tank_two)
if ("toggle_valve")
var/openorclose = (src.valve_open) ? "opened" : "closed"
var/turf/bombturf = get_turf(src)
logTheThing(LOG_BOMBING, usr, "[openorclose] the valve on a TTV tank transfer valve at [log_loc(bombturf)].")
message_admins("[key_name(usr)] [openorclose] the valve on a TTV tank transfer valve at [log_loc(bombturf)].")
toggle_valve()
if(href_list["rem_device"])
attached_device.set_loc(get_turf(src))
attached_device.master = null
attached_device = null
if ("remove_device")
src.attached_device.set_loc(get_turf(src))
src.attached_device.master = null
src.attached_device = null
UpdateIcon()
if(href_list["device"])
if ("interact_device")
attached_device.attack_self(usr)
if(href_list["straps"])
if ("remove_straps")
MeggalBozale marked this conversation as resolved.
Show resolved Hide resolved
if(usr?.back && usr.back == src)
boutput(usr, SPAN_ALERT("You can't detach the loops of wire while you're wearing [src]!"))
else
Expand All @@ -205,11 +244,19 @@ TYPEINFO(/obj/item/device/transfer_valve)
C.amount = 2
boutput(usr, SPAN_NOTICE("You detach the loops of wire from [src]!"))
UpdateIcon()

src.attack_self(usr)

src.add_fingerprint(usr)
return
src.attack_self(usr)
src.add_fingerprint(usr)

proc/remove_tank(var/T)
if (!istype(T, /obj/item/tank)) return
var/obj/item/tank/removed = T
boutput(usr, SPAN_NOTICE("You remove the [removed] from [src]."))
removed.set_loc(get_turf(src))
removed = null
UpdateIcon()
if(src.equipped_in_slot)
var/mob/wearer = src.loc
wearer.update_clothing()

receive_signal(signal)
if(toggle)
Expand Down
107 changes: 107 additions & 0 deletions tgui/packages/tgui/interfaces/TTV.tsx
@@ -0,0 +1,107 @@
/**
* @file
* @copyright 2024
* @author Romayne (https://github.com/MeggalBozale)
* @license ISC
*/

import { useBackend } from '../backend';
import { Button, LabeledList, RoundGauge, Section, Stack } from '../components';
import { Window } from '../layouts';
import { toTitleCase } from '../../common/string';
import { formatPressure } from '../format';
interface AirVendorParams {
MeggalBozale marked this conversation as resolved.
Show resolved Hide resolved
opened: boolean;
tank_one: TankData;
tank_two: TankData;
device: string;
}

interface TankData {
name: string;
num: number;
pressure: number;
maxPressure: number;
}

const TankInfo = (_props, context) => {
const { act, data } = useBackend<AirVendorParams>(context);
const { tank, height } = _props;
let button_eject = <Button width={5} textAlign={"center"} disabled={tank.name===null} icon="eject" onClick={() => act(tank.num === 1 ? "remove_tank_one" : "remove_tank_two")}>Eject</Button>;
let button_add = <Button width={5} textAlign={"center"} icon="add" onClick={() => act("add_item", { "tank": tank.num })}>Add</Button>;
let maxPressure = (tank.maxPressure !== null) ? tank.maxPressure : 999;
return (
<Section
title={tank.num === 1 ? "Tank One" : "Tank Two"}
buttons={tank.name !== null ? button_eject : button_add}
height={height}
>
<LabeledList>
<LabeledList.Item label={"Holding"}>
{tank.name !== null ? toTitleCase(tank.name) : "None"}
</LabeledList.Item>
<LabeledList.Item
label="Pressure">
<RoundGauge
size={1.75}
value={tank.pressure !== null ? tank.pressure : 0}
minValue={0}
maxValue={maxPressure}
alertAfter={maxPressure * 0.70}
ranges={{
"good": [0, maxPressure * 0.70],
"average": [maxPressure * 0.70, maxPressure * 0.85],
"bad": [maxPressure * 0.85, maxPressure],
}}
format={formatPressure}
/>
</LabeledList.Item>
</LabeledList>
</Section>
);
};

export const TTV = (_props, context) => {
const { act, data } = useBackend<AirVendorParams>(context);
const {
opened,
tank_one,
tank_two,
} = data;
let windowWidth = 650;
let windowHeight = 160;
return (
<Window width={windowWidth} height={windowHeight}>
<Window.Content>
<Stack>
<Stack.Item width={windowWidth/3}>
MeggalBozale marked this conversation as resolved.
Show resolved Hide resolved
<TankInfo height={windowHeight/16.666} tank={tank_one} />
MeggalBozale marked this conversation as resolved.
Show resolved Hide resolved
</Stack.Item>

<Stack.Item width={windowWidth/3}>
<Section title="Valve" height={windowHeight/16.666} px={1}>
<Stack vertical textAlign="center">
<Stack.Item color={opened ? "red" : "green"}>
Valve is {opened ? "open" : "closed"}
</Stack.Item>
<Stack.Item>
<Button icon="repeat" onClick={() => act("toggle_valve")}>
Toggle Valve
</Button>
</Stack.Item>
<Stack.Item>
{(data.device === '') ? "No Device " : ''}
{(data.device === '') ? <Button icon="add" onClick={() => act("add_item")}>Add</Button>
: <><Button onClick={() => act("interact_device")}>Device</Button><Button icon="eject" onClick={() => act("remove_device")}>Eject</Button></>}
</Stack.Item>
</Stack>
</Section>
</Stack.Item>
<Stack.Item width={windowWidth/3}>
<TankInfo height={windowHeight/16.666} tank={tank_two} />
</Stack.Item>
</Stack>
</Window.Content>
</Window>
);
};