[MIRROR] Port /tg/ stripping panel (#11052)
Co-authored-by: ShadowLarkens <shadowlarkens@gmail.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
20
code/modules/asset_cache/assets/inventory.dm
Normal 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',
|
||||
)
|
||||
@@ -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
|
After Width: | Height: | Size: 394 B |
BIN
icons/ui/inventory/belt.png
Normal file
|
After Width: | Height: | Size: 282 B |
BIN
icons/ui/inventory/collar.png
Normal file
|
After Width: | Height: | Size: 353 B |
BIN
icons/ui/inventory/ears.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
icons/ui/inventory/glasses.png
Normal file
|
After Width: | Height: | Size: 236 B |
BIN
icons/ui/inventory/gloves.png
Normal file
|
After Width: | Height: | Size: 389 B |
BIN
icons/ui/inventory/hand_l.png
Normal file
|
After Width: | Height: | Size: 283 B |
BIN
icons/ui/inventory/hand_r.png
Normal file
|
After Width: | Height: | Size: 265 B |
BIN
icons/ui/inventory/head.png
Normal file
|
After Width: | Height: | Size: 380 B |
BIN
icons/ui/inventory/id.png
Normal file
|
After Width: | Height: | Size: 393 B |
BIN
icons/ui/inventory/mask.png
Normal file
|
After Width: | Height: | Size: 448 B |
BIN
icons/ui/inventory/neck.png
Normal file
|
After Width: | Height: | Size: 362 B |
BIN
icons/ui/inventory/pocket.png
Normal file
|
After Width: | Height: | Size: 275 B |
BIN
icons/ui/inventory/shoes.png
Normal file
|
After Width: | Height: | Size: 264 B |
BIN
icons/ui/inventory/suit.png
Normal file
|
After Width: | Height: | Size: 409 B |
BIN
icons/ui/inventory/suit_storage.png
Normal file
|
After Width: | Height: | Size: 424 B |
BIN
icons/ui/inventory/uniform.png
Normal file
|
After Width: | Height: | Size: 349 B |
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||