From 0db890840f5e8b434b4341f02fd296d37b2f8d64 Mon Sep 17 00:00:00 2001 From: ShadowLarkens Date: Thu, 12 Jun 2025 07:37:24 -0700 Subject: [PATCH] Port /tg/ stripping panel (#17842) --- code/modules/asset_cache/assets/inventory.dm | 20 ++ code/modules/mob/living/inventory.dm | 22 +- icons/ui/inventory/back.png | Bin 0 -> 394 bytes icons/ui/inventory/belt.png | Bin 0 -> 282 bytes icons/ui/inventory/collar.png | Bin 0 -> 353 bytes icons/ui/inventory/ears.png | Bin 0 -> 340 bytes icons/ui/inventory/glasses.png | Bin 0 -> 236 bytes icons/ui/inventory/gloves.png | Bin 0 -> 389 bytes icons/ui/inventory/hand_l.png | Bin 0 -> 283 bytes icons/ui/inventory/hand_r.png | Bin 0 -> 265 bytes icons/ui/inventory/head.png | Bin 0 -> 380 bytes icons/ui/inventory/id.png | Bin 0 -> 393 bytes icons/ui/inventory/mask.png | Bin 0 -> 448 bytes icons/ui/inventory/neck.png | Bin 0 -> 362 bytes icons/ui/inventory/pocket.png | Bin 0 -> 275 bytes icons/ui/inventory/shoes.png | Bin 0 -> 264 bytes icons/ui/inventory/suit.png | Bin 0 -> 409 bytes icons/ui/inventory/suit_storage.png | Bin 0 -> 424 bytes icons/ui/inventory/uniform.png | Bin 0 -> 349 bytes .../tgui/interfaces/InventoryPanelHuman.tsx | 201 +++++++++++++++--- vorestation.dme | 1 + 21 files changed, 205 insertions(+), 39 deletions(-) create mode 100644 code/modules/asset_cache/assets/inventory.dm create mode 100644 icons/ui/inventory/back.png create mode 100644 icons/ui/inventory/belt.png create mode 100644 icons/ui/inventory/collar.png create mode 100644 icons/ui/inventory/ears.png create mode 100644 icons/ui/inventory/glasses.png create mode 100644 icons/ui/inventory/gloves.png create mode 100644 icons/ui/inventory/hand_l.png create mode 100644 icons/ui/inventory/hand_r.png create mode 100644 icons/ui/inventory/head.png create mode 100644 icons/ui/inventory/id.png create mode 100644 icons/ui/inventory/mask.png create mode 100644 icons/ui/inventory/neck.png create mode 100644 icons/ui/inventory/pocket.png create mode 100644 icons/ui/inventory/shoes.png create mode 100644 icons/ui/inventory/suit.png create mode 100644 icons/ui/inventory/suit_storage.png create mode 100644 icons/ui/inventory/uniform.png diff --git a/code/modules/asset_cache/assets/inventory.dm b/code/modules/asset_cache/assets/inventory.dm new file mode 100644 index 0000000000..0883dbd751 --- /dev/null +++ b/code/modules/asset_cache/assets/inventory.dm @@ -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', + ) diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index 594967fccb..c6456d8d9a 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -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 diff --git a/icons/ui/inventory/back.png b/icons/ui/inventory/back.png new file mode 100644 index 0000000000000000000000000000000000000000..e8226bc55e32adb4bb3cb0633ea9fc423874305d GIT binary patch literal 394 zcmV;50d@X~P)Px$L`g(JR9J=WRk3QrFciF$E=G_Lu!edPT{{=D<_og>C-N=*3GexWu7S>3gC=#5 zAS56>xw*Y|K#U{Cd6MmDzBgF#Xj7Hrk%7inTmE}4B0F{uGurnH! zkhFnhP&T`Es2hdlTH<{AKqX|fz2WWo~K6;p<9hfuE zIa-q=$ergLjY$JJ`#e{JK19p~oWspp!yI82(GDCB-Qq8T*n2y94XOX^&8{7Q?<2$@ o1TS@lX#-;;DKLc#3JLR07*qoM6N<$f|X{g>;M1& literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/belt.png b/icons/ui/inventory/belt.png new file mode 100644 index 0000000000000000000000000000000000000000..ef3e5586e476ee9d90a14893557a86cb0b8e8a89 GIT binary patch literal 282 zcmV+#0pPx#)Ja4^R9J=Wl)VarFcgJPOBcCNDd?b6=-Rp9Te$mx-TM}Oj7&O25QX4qHyib; z>Ev=h2;}GFZZs7uYRaiK1p@cwvC#$973rioJQ0hRt~qEz8}i{}9rd(L}CZoe)ydTUT=JvNSj z;!PhH_6FPv6Q$5K1_8yOkYHQ8dINht-T}JCEarM^Kp_EGuV$|0e7pjzJt6>Oh&{GE gTn_&S1VIplFG^KdZOW@F1poj507*qoM6N<$fPx$8%ab#R9J=Wl)X;FFcgKq+m`UVGIWbtsY~WcUHb&x^Add)HlCmZ8!G}KF(Gx% zf<%?ALpG$45<)Kn*vi0Q2QlGqvaIWKj;^l_fj}S-`0t4CfqA;rVH~r~bB1vYVAtC` z2ax;K#oq*In^$GQ@##5$U3Ur5>uN5&fqXP?0!Y7qC{7+Yw4PY?lx^H;6 zy0rVVMJiQUD8ycR&K;=A0)SC6MfZ*VP@c_0u71OPq(wg_=}Pr+Ee00000NkvXXu0mjfC&!g^ literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/ears.png b/icons/ui/inventory/ears.png new file mode 100644 index 0000000000000000000000000000000000000000..19752ed10d713f64da676fd93b24c6f2c0af063a GIT binary patch literal 340 zcmV-a0jvIrP)Px$4oO5oR9J=Wl`#&2FcgM=j2nr@!GW!Dbv9w;1nj*8XW(5;6R8;f1wmh#At9NlTHuT zDU>pjSS<-}suE3APWl2N5XN$HJfB!o2kJCciOp_5JOdcoCXlv@vh`yj0Jz_-xSX@E z>ywXQF0fE)QoVj06xaf7-NN7cgA5n8Kp+I#x&`p8o^uCC0(q8t{d;a3_6`(E!Qc9` z)l)CvB7yPwbGCl5K#v}7QaxMX-G|3CoGcK=^5sKhBb+RtV=J63U@IIj_#KC_><-71 m)o>$$USix{8t!m7eu4**7Jd~!{#-Hu0000|CfKJhi9kr zOZer)9P9AyYiwlH^Y3Dg=m=!l%<#-0rs&2KNr?~bJi?mO7E8D3u}^;fL@d<;WDrks zu?UZV53^Db7Y`55jDy`e?Y{R6wf_JAmns~1C7GME=_6~gt=ZWVcFO9EeITc}9n_Fu cZDwL%s9zI)M4oeT7tqBFp00i_>zopr05>&IA^-pY literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/gloves.png b/icons/ui/inventory/gloves.png new file mode 100644 index 0000000000000000000000000000000000000000..f5c9de27b8efb975719865f48883bf199cd48dd1 GIT binary patch literal 389 zcmV;00eb$4P)Px$KS@MER9J=Wma)o%FcgK4rL!RD;v`)=7kmqMAJE;m5S(4b$)!S}FOYxfDQO$c zO|)Hp&lE7p`MkND1lYCfzblYT%8OEQ+|-q5&1L|3QK~r25Jm~^w=1S`*c9R@H3xt& zN;p=)Hr1HjATLUFI$stS_g#y%Ad3~SNdr{A5QjAYI*8t=KL=O?F$>VtRlqa0iSv9Q z7As(b(2ezZc~L4Uh|>}DU5mbJalc(Zj5&_e45#x2ahi#$;oJjFT?NxP7$J0pQ6hp6 z0np3@!EgL~h87`geId$$X&j6ZJdFbYAWpNVp{uL_rhs8YQ$EIG0F${bqFv$7U~8;Fxa(;N_CC%KI)bnfu&`&P~WF&=`Qx{5?D7wCY8} jfO$9n<{NU?uFdra9@@Qa5>=h<00000NkvXXu0mjf->s#& literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/hand_l.png b/icons/ui/inventory/hand_l.png new file mode 100644 index 0000000000000000000000000000000000000000..8923d81b5b754338240b4c4d422595eab3cd797f GIT binary patch literal 283 zcmV+$0p$LPP)Px#)k#D_R9J=Wld%eeFc5~%(m4=lmQKahS@12~^MLNYh2ZQenX(uVe1UW*5wWq} z#j*EI;W+Yt$t3^`!!Z9&Mrp2U?f12=ZAg103sklCkLL@7RBLUSCvetW61k^_0{{rA zwl$w3f)WT}zsQSn6`@Gnu#L++q5ATojJ}o20vLiMMFJ(zwN2)%IlP5X7gCWW&^Hhy z_M!XW?Ha?S5sX704HiPx#!%0LzR9J=Wlrai}KoCX8kXjJ5v68f@1Kz^k1KN8FkFnJ@SqS6;rbs5pCZm7M zc9~ZWGVe2fB{B@d_;<2j7qneJ$Fpf1;Jv#8u(+%n%8Tkfzu&GDyn{oi1F-mXzKG9g zLL9a7H8GPH6$S60orlzNqUQxrpa4s`W_gkTv78Gh1<{reeg&~SZa$-t69FZBEfcR0 zyrZ&iP~Qje1tj@24jDIoPd}i~kgu?u#ivePPLa0j=WoAXX>J&XVQldLP_}dK+S&<2 P00000NkvXXu0mjf@oH-J literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/head.png b/icons/ui/inventory/head.png new file mode 100644 index 0000000000000000000000000000000000000000..650be20fe6307fcb2f9049c94e44cca0ff1d4096 GIT binary patch literal 380 zcmV-?0fYXDP)Px$Hc3Q5R9J=WmAz`iFce0=mTZQELOL{)A<(63hlEUd0`GnaKTBUCd)JVXH80?$ z5XhFngRwzmbO&>dVr1!FrKK74Eyk9ub9D7%AS5K@pYw3b$Llm}Owae54|cy^0t9}E zV`KaIbYhE$1=eZS41rA|E{Vs#f&*=Z7D;NHCb57NPMOZ^5-b5G@aSfN%{Eye)!&RlM{fR3;5&*D#UtK{>@QW&N z_}mO`MW?_bNt@{`hN@IIn*8|PNl@tUk-!1R6c8K$qDi|5cVFACy)Pk!1D2CehYvw? zF;yuIQ|86g4rrTk&c`tz!mX@vjuD-x4^{$eG!T;JR~IK aF7g9msi`AKPx$LrFwIR9J=WmA`7kFc8MSmM%dM6Nrao(nDlu$P^l~cK1uxpsir% zI@`4~DN&ai<4JlG2kKG>op|Y6U@G%(!?Z_Zba0$?z}!MPBTOJ3s~- zqcNRJG)7}2Qiw#rRK_axhd3RSbs{hJI2}}Q-ZOWC?&TASz<82+O3b9RN^O_rV&z4| zg-t;>|McBe05~e;Dd4BzE)j5}0KluByG5YeCi)@}bbu}#a6SoVd?eCf&Vh3o6U)U4 zc@dn(M}Q31rS5$VT|*pK-+{(x9F?-=NGGPe4pBEnrZQ}~4tj`4xl~-zzK4wc8NI$| n?Iq`~;rIKCwH1j(A`j&c3l6>Ypmxg300000NkvXXu0mjf_2{YP literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/mask.png b/icons/ui/inventory/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3690e6eca76c07bbe0d7d404090f4030f1298e26 GIT binary patch literal 448 zcmV;x0YCnUP)Px$dPzh#-|}+ez+o)$wptte z^>RjAt4WDCFWzi-w=k9f&@zMpbWfOk)t5J?FU z2vlVO0I13WA`pn==l@|W2Q@OrtLs7z4&0BRQL3YdNXm!mJmYBv?6Y^prwU#gV4?Bz znf==d*t-yc0BP!|T?E3k-}Q0^X@UsEp#KpnxRn&?{qe2ZND>Zt*{hpL{gfW z!0#;9vDO@|00%$j`;KEIC6Y7)X)?bg&5S^qW4>QBN+C%z{|ayw?5tUgb`_ZZ?)!dU z4JPkV9L5rDeQ!Sw%Jv@{#r-7SR%=vcfh5fackYVwAhID%Mrc)8U@0E&23NfAg3}>i qa2MFmU%8HL>>i&Qd}e0mPw)X%F5qzP)p7v<0000Px$BuPX;R9J=Wld%fIFc^eSaVdfz*g>b@>RjksbngSY`xb(;t7NK!1*s4m>mVsV zN!qk&0)oA*q~yE1{|_)}(!XmK;?gwBYx;dY9a}l`5C#BXe@L)DB-a0e8K6egMuHkh zv%Kz;JeUDhujixl-0KpiSzbrW7+c0Pcv)}&`a*hdV9OZpoHx+2;1HF-X2%dMV{IS2 zHK5M^cD*!dWixN_&>HY!z!eU77=a3>bC-3u!GRGC$jj9yN7MJw!Ubvq1NJ9pQZJ`% zX;pYx@ImRV1|)d1W7^qj9gl_s9V1Ayyf%R;l$vmr(XkD#$~8SOa0#hICGZyCrE`S? zh6ZfuMI``qzwIIF-2hDtj7x1bAX7^DsCtkAnlu!6(xji!2TEF>CYvKf82|tP07*qo IM6N<$g5HUjHUIzs literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/pocket.png b/icons/ui/inventory/pocket.png new file mode 100644 index 0000000000000000000000000000000000000000..0d31594a5a5533b67024a5024a4baa6aaa898563 GIT binary patch literal 275 zcmV+u0qp*XP)Px#%}GQ-R9J=Wl(7oJFc5}+#YF_6Ui^r?iVS z|AA73`_^3k`*I-x48t%MX2lj3Wi@DmANL!TO%)YoH5^V((;vYLC6O$M&4U+}K-`m( z*f3%HEJyGHb_&7ExF-cA008I96>U?~wJfwiCqf5zA~-ttU4a-30R8LvaeceXHF0`@ z=~Ql}Y7%9jpP}Yn0ibPa>KU$8sXt(G0o7N`UIROR;GZS{a8uBnUM&zM=GHaM4Z|=1 Z;0??cNnrV#{o()s002ovPDHLkV1fZ|ZQuX^ literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/shoes.png b/icons/ui/inventory/shoes.png new file mode 100644 index 0000000000000000000000000000000000000000..170f81b5daa5a4c0e5b2919b92116d8f1aab127c GIT binary patch literal 264 zcmV+j0r&oiP)Px#!bwCyR9J=WlCcegKnz8FQJTmSCkl#mtil>B!7MDn8Vp1cCDMtKR2MnM_MOtC z@hj~w|Nl7v9LI4S=g)*%;V@1IpRLOrti7cBDZnsJ$Gz{rX0OKv>6u_%<{<5}1^_-f z>Gq{2fJD=FfDz5+P1_ak6a#4OD5brH`UJTdMiiUS&#P&uR(po4W{we0X4!Px$Q%OWYR9J=WmN84iKorM+6_;{g5SpQ#LJM88T8KD_;v{s>H*j+I1Gsnc8)O%p zN70{ z2c`dcV?Svt8-Q6b5&7Pe23M9sS&F_p!W;WZS@6C)BDG5s{*8T!QOd!gT?klZ^YI>w zeTpjZJ$PE?wz3P~Wwu*OU{{DmczJb`93P!z<1m_{ECqmB8_v%zvbDu>&cog9_C&Z# z#3D3n!_&(%04uH8m^iDz#>9ltl&<4swo=5$Fm*1W>p0?LSo;>#o`6UL%2K$4VK#OL zLl(<T6o6#IStT~IZ@6TGpXRJ{kPT69B0!=L68fcSpi>w%qA00000NkvXXu0mjf Dl0>pW literal 0 HcmV?d00001 diff --git a/icons/ui/inventory/suit_storage.png b/icons/ui/inventory/suit_storage.png new file mode 100644 index 0000000000000000000000000000000000000000..f35bd3783f7a70e2f69e0c52020e21d1c7bfa0bd GIT binary patch literal 424 zcmV;Z0ayNsP)Px$Vo5|nR9J=WR6T3MFciF&F6Kdu!5ZR8bnRU5zwquKm_7d@kU4A6WDhc!7=%Z6 zC~9p-lAm3=`6eNq?w#~LfE_z_Fp(GKkQe3fSI!)-+~5%jq?v>-KwgwXnn^??yqrx2 ztT4rdLn6Gqhy)Ia0L2tEI>#H=sSUpL!b2j^wVEr-H(+s;618&gZ@~+Plo#dj{_)8c zz2C05oKGxmRuTRuR;A#6yDoCp{1m`Qfo;LwXr!536l^L5%jcwFLRe~@G?Oq7<2|RC z&{S&CXU64x`dK@Ra4a@nHPx$7fD1xR9J=Wl)Y`kFc5`51!)2SF;b*Z$1&1sg7jKKvv>*hp1`fgxXLPMK(GKp zrCbPeGi9{mt&t#h7vZ}{?ljF{ge3Q@L{kuCm_RUt+GrHIh ze|>ugpcR>i7RCV3cUCRpNu$;e2e{`%`2V2-%Bmg { + return { gridRow: `${row}`, gridColumn: `${col}` }; +}; + +const KNOWN_SLOTS: Record = { + // 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 ( + + ); +}; + export const InventoryPanelHuman = (props) => { const { act, data } = useBackend(); @@ -39,38 +189,27 @@ export const InventoryPanelHuman = (props) => { } = data; return ( - +
- - {slots && - slots.length && - slots.map((slot) => ( - - - - ))} - - {specialSlots && - specialSlots.length && - specialSlots.map((slot) => ( - - - - ))} - + + {slots?.length + ? slots.map((slot) => ) + : null} + {specialSlots?.length + ? specialSlots.map((slot) => ( + + )) + : null} +