Skip to content

Commit

Permalink
New TGUI for ore box (#8320)
Browse files Browse the repository at this point in the history
* Enable legacy TGUI interface

* Working on buttons for specific ores

* Debug interface

* Update interface to use Stacks instead of Tabs

* Remove debug log

* Format with Prettier

* Fix linter
  • Loading branch information
hyperioo authored Sep 29, 2023
1 parent 0965c6c commit 0a84ce2
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 34 deletions.
65 changes: 65 additions & 0 deletions code/modules/mining/satchel_ore_boxdm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,68 @@
O.take_damage(damage)
return 0

/obj/structure/ore_box/attack_hand(mob/user, list/modifiers)
. = ..()
if(.)
return
if(Adjacent(user))
ui_interact(user)

/obj/structure/ore_box/attack_robot(mob/user)
if(Adjacent(user))
ui_interact(user)

/obj/structure/ore_box/proc/dump_box_contents(ore_name, ore_amount=-1)
var/drop = drop_location()
for(var/obj/item/ore/O in src)
if(ore_amount == 0)
break
if(QDELETED(O))
continue
if(QDELETED(src))
break
if(ore_name && O.name != ore_name)
continue
ore_amount--
O.forceMove(drop)

/obj/structure/ore_box/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "OreBox", name)
ui.open()

/obj/structure/ore_box/ui_data()
var/data = list()
data["materials"] = list()
for(var/ore in stored_ore)
data["materials"] += list(list("name" = ore, "amount" = stored_ore[ore], "type" = ore))

return data

/obj/structure/ore_box/ui_act(action, params)
. = ..()
if(.)
return
if(!Adjacent(usr))
return
add_fingerprint(usr)
switch(action)
if("ejectallores")
dump_box_contents()
to_chat(usr, span_notice("You release all the content of the box."))
update_ore_count()
return TRUE
if("ejectall")
var/ore_name = params["type"]
dump_box_contents(ore_name)
to_chat(usr, span_notice("You release all the [ore_name] ores."))
update_ore_count()
return TRUE
if("eject")
var/ore_name = params["type"]
var/ore_amount = params["qty"]
dump_box_contents(ore_name, ore_amount)
to_chat(usr, span_notice("You release [ore_amount] [ore_name] ores."))
update_ore_count()
return TRUE
125 changes: 92 additions & 33 deletions tgui/packages/tgui/interfaces/OreBox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { toTitleCase } from 'common/string';
import { Box, Button, Section, Table } from '../components';
import { useBackend } from '../backend';
import { Box, Button, NumberInput, Section, Stack } from '../components';
import { useBackend, useLocalState } from '../backend';
import { Window } from '../layouts';

type Data = {
Expand All @@ -13,46 +13,105 @@ type Material = {
amount: number;
};

const OREBOX_INFO = `All ores will be placed in here when you are wearing a
mining stachel on your belt or in a pocket while dragging the ore box.`;

export const OreBox = (props, context) => {
const { act, data } = useBackend<Data>(context);
const { materials } = data;

return (
<Window width={335} height={415}>
<Window.Content scrollable>
<Window width={460} height={265}>
<Window.Content>
<Section
fill
scrollable
title="Ores"
buttons={<Button content="Empty" onClick={() => act('removeall')} />}>
<Table>
<Table.Row header>
<Table.Cell>Ore</Table.Cell>
<Table.Cell collapsing textAlign="right">
Amount
</Table.Cell>
</Table.Row>
{materials.map((material) => (
<Table.Row key={material.type}>
<Table.Cell>{toTitleCase(material.name)}</Table.Cell>
<Table.Cell collapsing textAlign="right">
<Box color="label" inline>
{material.amount}
</Box>
</Table.Cell>
</Table.Row>
))}
</Table>
</Section>
<Section>
<Box>
{OREBOX_INFO}
<br />
Gibtonite is not accepted.
</Box>
buttons={
<Button
content="Eject All Ores"
onClick={() => act('ejectallores')}
/>
}>
<Stack direction="column">
<Stack.Item>
<Section>
<Stack vertical>
<Stack align="start">
<Stack.Item basis="30%">
<Box bold>Ore</Box>
</Stack.Item>
<Stack.Item basis="20%">
<Section align="center">
<Box bold>Amount</Box>
</Section>
</Stack.Item>
</Stack>
{materials.map((material) => (
<OreRow
key={material.type}
material={material}
onRelease={(type, amount) =>
act('eject', {
type: type,
qty: amount,
})
}
onReleaseAll={(type) =>
act('ejectall', {
type: type,
})
}
/>
))}
</Stack>
</Section>
</Stack.Item>
</Stack>
</Section>
</Window.Content>
</Window>
);
};

const OreRow = (props, context) => {
const { material, onRelease, onReleaseAll } = props;

const [amount, setAmount] = useLocalState(
context,
'amount' + material.name,
1
);

const amountAvailable = Math.floor(material.amount);
return (
<Stack.Item>
<Stack align="center">
<Stack.Item basis="30%">{toTitleCase(material.name)}</Stack.Item>
<Stack.Item basis="20%">
<Section align="center">
<Box mr={0} color="label" inline>
{amountAvailable}
</Box>
</Section>
</Stack.Item>
<Stack.Item basis="50%">
<NumberInput
width="32px"
step={1}
stepPixelSize={5}
minValue={1}
maxValue={100}
value={amount}
onChange={(e, value) => setAmount(value)}
/>
<Button
content="Eject Amount"
onClick={() => onRelease(material.type, amount)}
/>
<Button
content="Eject All"
onClick={() => onReleaseAll(material.type)}
/>
</Stack.Item>
</Stack>
</Stack.Item>
);
};
2 changes: 1 addition & 1 deletion tgui/public/tgui.bundle.js

Large diffs are not rendered by default.

0 comments on commit 0a84ce2

Please sign in to comment.