[MIRROR] Port /tg/ stripping panel (#11052)

Co-authored-by: ShadowLarkens <shadowlarkens@gmail.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-06-12 16:24:26 -07:00
committed by GitHub
parent 5c6fd7dbd2
commit ff899ff038
21 changed files with 205 additions and 39 deletions

View File

@@ -0,0 +1,20 @@
/datum/asset/simple/inventory
assets = list(
"inventory-glasses.png" = 'icons/ui/inventory/glasses.png',
"inventory-head.png" = 'icons/ui/inventory/head.png',
"inventory-neck.png" = 'icons/ui/inventory/neck.png',
"inventory-mask.png" = 'icons/ui/inventory/mask.png',
"inventory-ears.png" = 'icons/ui/inventory/ears.png',
"inventory-uniform.png" = 'icons/ui/inventory/uniform.png',
"inventory-suit.png" = 'icons/ui/inventory/suit.png',
"inventory-gloves.png" = 'icons/ui/inventory/gloves.png',
"inventory-hand_l.png" = 'icons/ui/inventory/hand_l.png',
"inventory-hand_r.png" = 'icons/ui/inventory/hand_r.png',
"inventory-shoes.png" = 'icons/ui/inventory/shoes.png',
"inventory-suit_storage.png" = 'icons/ui/inventory/suit_storage.png',
"inventory-id.png" = 'icons/ui/inventory/id.png',
"inventory-belt.png" = 'icons/ui/inventory/belt.png',
"inventory-back.png" = 'icons/ui/inventory/back.png',
"inventory-pocket.png" = 'icons/ui/inventory/pocket.png',
"inventory-collar.png" = 'icons/ui/inventory/collar.png',
)

View File

@@ -311,6 +311,11 @@
return TRUE
/datum/inventory_panel/human/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/simple/inventory)
)
/datum/inventory_panel/human/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = list() // We don't inherit TGUI data because humans are soooo different.
@@ -320,36 +325,37 @@
if(istype(H.w_uniform, /obj/item/clothing/under))
suit = H.w_uniform
var/list/slots = list()
for(var/entry in H.species.hud.gear)
var/list/slot_ref = H.species.hud.gear[entry]
if((slot_ref["slot"] in list(slot_l_store, slot_r_store)))
continue
var/obj/item/thing_in_slot = H.get_equipped_item(slot_ref["slot"])
slots.Add(list(list(
UNTYPED_LIST_ADD(slots, list(
"name" = slot_ref["name"],
"item" = thing_in_slot,
"icon" = thing_in_slot ? icon2base64(icon(thing_in_slot.icon, thing_in_slot.icon_state, frame = 1)) : null,
"act" = "targetSlot",
"params" = list("slot" = slot_ref["slot"]),
)))
))
data["slots"] = slots
var/list/specialSlots = list()
if(H.species.hud.has_hands)
specialSlots.Add(list(list(
UNTYPED_LIST_ADD(specialSlots, list(
"name" = "Left Hand",
"item" = H.l_hand,
"icon" = H.l_hand ? icon2base64(icon(H.l_hand.icon, H.l_hand.icon_state, frame = 1)) : null,
"act" = "targetSlot",
"params" = list("slot" = slot_l_hand),
)))
specialSlots.Add(list(list(
))
UNTYPED_LIST_ADD(specialSlots, list(
"name" = "Right Hand",
"item" = H.r_hand,
"icon" = H.r_hand ? icon2base64(icon(H.r_hand.icon, H.r_hand.icon_state, frame = 1)) : null,
"act" = "targetSlot",
"params" = list("slot" = slot_r_hand),
)))
))
data["specialSlots"] = specialSlots
data["internals"] = H.internals

BIN
icons/ui/inventory/back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

BIN
icons/ui/inventory/belt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

BIN
icons/ui/inventory/ears.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

BIN
icons/ui/inventory/head.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

BIN
icons/ui/inventory/id.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

BIN
icons/ui/inventory/mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

BIN
icons/ui/inventory/neck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

BIN
icons/ui/inventory/suit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

View File

@@ -1,8 +1,10 @@
import { useBackend } from 'tgui/backend';
import { Window } from 'tgui/layouts';
import { Button, LabeledList, Section } from 'tgui-core/components';
import { Box, Button, Image, Section, Stack } from 'tgui-core/components';
import type { BooleanLike } from 'tgui-core/react';
import { resolveAsset } from '../assets';
type Data = {
slots: slot[];
specialSlots: slot[];
@@ -19,10 +21,158 @@ type Data = {
type slot = {
name: string;
item: string;
icon: string;
act: string;
params: { slot: number };
};
type GridInfo = {
gridRow: string;
gridColumn: string;
};
type SlotInfo = {
grid: GridInfo;
image: string;
};
const gridAt = (row: number, col: number): GridInfo => {
return { gridRow: `${row}`, gridColumn: `${col}` };
};
const KNOWN_SLOTS: Record<string, SlotInfo> = {
// Row 1
Glasses: {
grid: gridAt(1, 2),
image: 'inventory-glasses.png',
},
Hat: {
grid: gridAt(1, 3),
image: 'inventory-head.png',
},
'Left Ear': {
grid: gridAt(1, 4),
image: 'inventory-ears.png',
},
// Row 2
Mask: {
grid: gridAt(2, 3),
image: 'inventory-mask.png',
},
'Right Ear': {
grid: gridAt(2, 4),
image: 'inventory-ears.png',
},
// Row 3
Uniform: {
grid: gridAt(3, 2),
image: 'inventory-uniform.png',
},
Suit: {
grid: gridAt(3, 3),
image: 'inventory-suit.png',
},
Gloves: {
grid: gridAt(3, 4),
image: 'inventory-gloves.png',
},
'Left Hand': {
grid: gridAt(3, 5),
image: 'inventory-hand_l.png',
},
'Right Hand': {
grid: gridAt(3, 6),
image: 'inventory-hand_r.png',
},
// Row 4
Shoes: {
grid: gridAt(4, 3),
image: 'inventory-shoes.png',
},
// Row 5
ID: {
grid: gridAt(5, 1),
image: 'inventory-id.png',
},
'Suit Storage': {
grid: gridAt(5, 2),
image: 'inventory-suit_storage.png',
},
Belt: {
grid: gridAt(5, 3),
image: 'inventory-belt.png',
},
Back: {
grid: gridAt(5, 4),
image: 'inventory-back.png',
},
};
const getSlot = (slot: slot): SlotInfo => {
if (KNOWN_SLOTS[slot.name]) {
return KNOWN_SLOTS[slot.name];
}
return {
grid: gridAt(1, 1),
image: 'inventory-pocket.png',
};
};
export const SlotButton = (props: { slot: slot }) => {
const { slot } = props;
const { act } = useBackend();
const data = getSlot(slot);
return (
<Button
key={slot.name}
style={{ ...data.grid }}
width="64px"
height="64px"
position="relative"
onClick={() => act(slot.act, slot.params)}
>
<Stack
align="center"
justify="center"
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
>
<Stack.Item>
<Image
fixErrors
src={resolveAsset(data.image)}
width="64px"
height="64px"
/>
</Stack.Item>
</Stack>
{slot.icon ? (
<Stack
align="center"
justify="center"
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
>
<Stack.Item>
<Image
src={`data:image/jpeg;base64,${slot.icon}`}
width="64px"
height="64px"
/>
</Stack.Item>
</Stack>
) : null}
</Button>
);
};
export const InventoryPanelHuman = (props) => {
const { act, data } = useBackend<Data>();
@@ -39,38 +189,27 @@ export const InventoryPanelHuman = (props) => {
} = data;
return (
<Window width={400} height={600}>
<Window width={435} height={550}>
<Window.Content scrollable>
<Section>
<LabeledList>
{slots &&
slots.length &&
slots.map((slot) => (
<LabeledList.Item key={slot.name} label={slot.name}>
<Button
mb={-1}
icon={slot.item ? 'hand-paper' : 'gift'}
onClick={() => act(slot.act, slot.params)}
>
{slot.item || 'Nothing'}
</Button>
</LabeledList.Item>
))}
<LabeledList.Divider />
{specialSlots &&
specialSlots.length &&
specialSlots.map((slot) => (
<LabeledList.Item key={slot.name} label={slot.name}>
<Button
mb={-1}
icon={slot.item ? 'hand-paper' : 'gift'}
onClick={() => act(slot.act, slot.params)}
>
{slot.item || 'Nothing'}
</Button>
</LabeledList.Item>
))}
</LabeledList>
<Box
style={{
display: 'grid',
gridTemplateColumns: '1fr 1fr 1fr 1fr 1fr 1fr',
gridTemplateRows: '1fr 1fr 1fr 1fr 1fr',
}}
height="100%"
width="100%"
>
{slots?.length
? slots.map((slot) => <SlotButton key={slot.name} slot={slot} />)
: null}
{specialSlots?.length
? specialSlots.map((slot) => (
<SlotButton key={slot.name} slot={slot} />
))
: null}
</Box>
</Section>
<Section title="Actions">
<Button

View File

@@ -2169,6 +2169,7 @@
#include "code\modules\asset_cache\assets\common.dm"
#include "code\modules\asset_cache\assets\fontawesome.dm"
#include "code\modules\asset_cache\assets\icon_ref_map.dm"
#include "code\modules\asset_cache\assets\inventory.dm"
#include "code\modules\asset_cache\assets\jquery.dm"
#include "code\modules\asset_cache\assets\lobby.dm"
#include "code\modules\asset_cache\assets\microwave.dm"