From a900208273a03edabd14307dc7d953d11cbc8b77 Mon Sep 17 00:00:00 2001 From: Dolobarsch Date: Mon, 14 Sep 2026 16:26:35 +0200 Subject: [PATCH] =?UTF-8?q?F=C3=BCge=20neues=20Inventar-=20und=20Ausr?= =?UTF-8?q?=C3=BCstungs-UI-System=20hinzu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ein neues modulares Inventar- und Ausrüstungs-UI-System wurde implementiert, das folgende Hauptfunktionen bietet: - Unterstützung für Ausrüstungs-Slots (`UEquipmentWidget`, `UEquipmentSlotWidget`). - Darstellung von Inventargegenständen in Listen- oder Rasteransicht (`UInventoryItemListWidget`, `UInventoryGridWidget`). - Schnellzugriffsleiste für große und kleine Slots (`UQuickSlotListWidget`). - Verwaltung von Inventarbehältern mit zusammenklappbaren Bereichen (`UInventoryContainerListWidget`). Neue Datenstrukturen (`InventoryTypes.h`) definieren Enums und Strukturen für Gegenstände, Ausrüstungs-Slots und Behälter. Der `PlayerController` wurde erweitert, um das Inventar-UI zu öffnen/schließen (`ToggleInventory`). Neue `.uasset`-Dateien wurden hinzugefügt, um die UI-Komponenten zu unterstützen. --- Content/Input/Actions/IA_Inventory.uasset | Bin 0 -> 1179 bytes Content/Input/IMC_Default.uasset | Bin 10048 -> 10509 bytes .../BP_ThirdPersonPlayerController.uasset | Bin 22420 -> 22846 bytes Content/UI/Inventory/WBP_Equipment.uasset | Bin 0 -> 26072 bytes .../WBP_EquipmentInventoryTAB.uasset | Bin 0 -> 53049 bytes Content/UI/Inventory/WBP_EquipmentSlot.uasset | Bin 0 -> 32390 bytes .../WBP_InventoryContainerList.uasset | Bin 0 -> 37853 bytes Content/UI/Inventory/WBP_InventoryGrid.uasset | Bin 0 -> 25871 bytes Content/UI/Inventory/WBP_Item.uasset | Bin 0 -> 32140 bytes Content/UI/Inventory/WBP_ItemList.uasset | Bin 0 -> 25623 bytes Content/UI/Inventory/WBP_QuickSlotList.uasset | Bin 0 -> 26667 bytes .../Inventory/InventoryTypes.h | 104 ++++++++++++++++++ .../KingshearthLegacy.Build.cs | 2 + .../KingshearthLegacyPlayerController.cpp | 30 +++++ .../KingshearthLegacyPlayerController.h | 13 +++ .../Inventory/EquipmentInventoryTabWidget.cpp | 86 +++++++++++++++ .../Inventory/EquipmentInventoryTabWidget.h | 87 +++++++++++++++ .../UI/Inventory/EquipmentSlotListEntry.h | 24 ++++ .../UI/Inventory/EquipmentSlotWidget.cpp | 58 ++++++++++ .../UI/Inventory/EquipmentSlotWidget.h | 57 ++++++++++ .../UI/Inventory/EquipmentWidget.cpp | 29 +++++ .../UI/Inventory/EquipmentWidget.h | 38 +++++++ .../InventoryContainerListWidget.cpp | 42 +++++++ .../Inventory/InventoryContainerListWidget.h | 67 +++++++++++ .../UI/Inventory/InventoryGridWidget.cpp | 35 ++++++ .../UI/Inventory/InventoryGridWidget.h | 49 +++++++++ .../UI/Inventory/InventoryItemListEntry.h | 25 +++++ .../UI/Inventory/InventoryItemListWidget.cpp | 29 +++++ .../UI/Inventory/InventoryItemListWidget.h | 41 +++++++ .../UI/Inventory/InventoryItemWidget.cpp | 75 +++++++++++++ .../UI/Inventory/InventoryItemWidget.h | 63 +++++++++++ .../UI/Inventory/QuickSlotListWidget.cpp | 35 ++++++ .../UI/Inventory/QuickSlotListWidget.h | 55 +++++++++ 33 files changed, 1044 insertions(+) create mode 100644 Content/Input/Actions/IA_Inventory.uasset create mode 100644 Content/UI/Inventory/WBP_Equipment.uasset create mode 100644 Content/UI/Inventory/WBP_EquipmentInventoryTAB.uasset create mode 100644 Content/UI/Inventory/WBP_EquipmentSlot.uasset create mode 100644 Content/UI/Inventory/WBP_InventoryContainerList.uasset create mode 100644 Content/UI/Inventory/WBP_InventoryGrid.uasset create mode 100644 Content/UI/Inventory/WBP_Item.uasset create mode 100644 Content/UI/Inventory/WBP_ItemList.uasset create mode 100644 Content/UI/Inventory/WBP_QuickSlotList.uasset create mode 100644 Source/KingshearthLegacy/Inventory/InventoryTypes.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/EquipmentSlotListEntry.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryItemListEntry.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.h create mode 100644 Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.h diff --git a/Content/Input/Actions/IA_Inventory.uasset b/Content/Input/Actions/IA_Inventory.uasset new file mode 100644 index 0000000000000000000000000000000000000000..0044fb982ce3344a4253778da769dc27e667218f GIT binary patch literal 1179 zcmX@utTpfZ|Ns9Jm>C$jm>3v-0cj8@{Z+rce$N8Ozq=>A-K?N<_1oj`=b~5`7#M+a zZ!Lp81I=^mYP?R zUsMTH!oa`@#BCr`fFKEIAxNXMi;0u7iG{hNv7@D>v5T3pshg>@i>b4to4KKZlZiQ8 zF-YHYpe7(ZiN&e9rg|1&d7uP~Ck}a_92oG;C>8}VW&rI= z2Zk6j00#7bP$+_&o{c2O3gr9c=cO`yVLr+$3*-bOCTAz6r~2e4C+1{UC4$1z4;Z+` z1&PV23_>N99iU(%7~W;OS+0nH6b2_3Wfqj^JLearhWaOEr6!j!{P5JZ6GM`7&C5v4 zOHNGzM<2u0b*JC30cD+Y5{ru&O3EuH@&b7%k?E%_^^6B32#Rk=bTbG^B=B$m#h}h- zD0c4vhXpL0fl|apI5f_Hfer!xfC0x2Wg}BCbs$S&04ZEyLJXjQhjV}okl#Rn8;C(Z z0|8LP-~z}VKsO6n4=5qw10ZwI0}Uf&lYzeSf;tAI0YiZjP!JZUDDkF;92uZQ2C~Z! zn0(4oAu(x-q!TGM=z(R`37VLg?nN(+(Hb$YnKro;7t{^R8Kx9JA>q8p(>sMGswgD2zX2hI(X!5Q5#VmFI0gJ|Bv-C9DV9^{{djf6Z z4%t-2PNU$OEbDXC8ZMECt5H22Wv9)W3PBSGe~mUp@8_s2S$up{+#g;_(#ftR8g)X< z;epEz9kf`(HG4#P1rMGD5Wz(=LvfgKuv@~cE3%e4WsUL-*?>cd9F&nVTa<6Xu(ryH zT%bjAKvWuRE9z~bX2Qarvf8~^9Z zDy)VXCOpB_ESFcA)!~z}IDa;4)UV9yD$Qm+EtR-y0Y5Z`1Xv1)b?7qG`MV($6n&`m g3(!}t^u|Jx7Z1M>PyL`mS`BdmtzajHQunRqe5T#}>K7`YEc6RnM;|!cV^Z$Rp?{Z+zjP<^f zZV3GK>G_%UC3o9o=BfBHxzr>$4s@hl<2xnCenQANgFpC8SwXf&t}3sD*zx6`jSw&H zpRLp-BTjYpSygLkKMX|_{p<3WNgDbOuNvUw55fx#6*7X9x%I6 zMWe?LwnuwYgQTc+;1xi$3nHnim z56jf2G9{O(*Hs>PC)(k5m6P9_?_GsE?^8tD1+&h25JNcxzBuhBx9_H%=i?Zse-92< zwZf7s;T(LXt^mW3UC5y(4LYhvzarX&n6~O2W7MpvI%$knXwb*TD7`qP$9kbhCmaHw z*ksnXdel)P@JU3q11uP$7R>-ZjL}LBx@L@Ok0tBT_s$EJ^LUR>z#-Q?EB%Vdat*Az z_LvsD5Oa6hfO>eLNeE^`XJIHJ!4A(Qrl|V8is}Kmj)U#K2Kd+_L8e}H7aKV^%{S%T zIbL-sJ5j5!oS@dDnenK9O=9XYIsMhNDOYpo&Rq>z%tIegVWvi;#&Uc diff --git a/Content/ThirdPerson/Blueprints/BP_ThirdPersonPlayerController.uasset b/Content/ThirdPerson/Blueprints/BP_ThirdPersonPlayerController.uasset index bb6f4e5cfd4c6d084e3765ada7d215658e644952..a96ba83ff09628f1240105cd68fda45cac17578e 100644 GIT binary patch delta 3248 zcmb`KYfPI}7{||H=qQ7&KwC;%Xkm=OWb1G+Ww5o-wWVB23$zSH5C^l&QSPug2h7Vz zjLAkGvzRzz_Q6{;(OL9^Gk(!8CX1KEOX3G*5hruQffrn&2A}i3=WSZ(3(4Y1dY*I6 z@BcjKIhXf+;rX}eNAJ>eT21+9^PQ8QkNKy|PPSbb{X)NFNVl|BUD}mOlP3uwzBob> z(S8ecw6L;1g^(od1@wgEpw()y!t%OFFoHFvihYVh3pjoof7)!3|6_v7R7WS_8`_w2 z9tRU!L?G46SX!$HX~TidEuosYw!2D{*mea+x`IQ!11BmD4|Vqj$ zuAuE$$KW6dy#L&`&>I_r8w%L8W@krFm)RBU8y+%?-h*aWMSD0R8Mz$)6{K%ETe35( z_PNl3&uDJ0^t9Xihr9cFFop1NQ$;0t(K0;{dUewks!nFPLBv;a010vZF z?KaX;{zo@VZ=R!#@Y0q7ti8H4_-;!OTP|f5Z43pJUsGy<1E~eHB@{@#5bl6k1rmUH z)xER|OzL8F4^GI+HQdVqu}SPOrA~_?kIRyiG09ID?Nm%Mi{z**c}$iZlO_GKWL%a^ z$dZOgGA`}TkC^on65*DaM|t}=x4)uph_~(BGP6=QkGkPCbSFgCMsA{TWPKsIfx6Kc zx&R-Ol4lF)m2|=}kMSNe>_K8hya17;T?8@6!?L79mOK(k=on{EWJ1BpobfnB!Wj;8uMWSalv+1pRs=yrU~u2f3saZGeiMmyz0bb@JYA48%o* z4Gr>60^0X@dt)8+8}r}=eX*uB0$<|o4@I0{DAur71B=4E{ToEy;}*P+bBtdF0UwDM z@yA{P&l!r)PmNG!k*48} zBtT)7RXu@YQuG_5fcz==f0Cuuut!~@QuLWaLTXy$r|~445IB`&0BYKHcM^6ER)q>p zZ{_8%Z&_e@`CqnJ=FfgYadGQ_B}b7$dXqR{w^KzQgre#+>VOt!A=YP{g?U!4W=6#- zwoTHF+Rg^B+%LHK;ij{g`eDYI4z2E_RJM<7zezo-u=wG6)o$tmoy(9SgE``$Yv9!gwH*8&;T}2o1H$rXC_d~$+~1Ji7fpqp0A~>Hm4m+{d_WE+B5=z> zD5){r6Sb3GIW11Ie2`z7b2a<EIPO|LV25WtCTOY~RaEd1A2_`MMJ4Zv7pupu#CwCUVVH8~QztAo zWGFJj5mNLjSa8R~RsD9DFeXEL<4*9^=hH)|%SOL`qgJT*Frp#<_fqP@iQrPG4c_#? znv0q7vc)WV%j6b9*;|t(TLf1ca$_#zyrPEBx+A>2t+21joxJLR>hJ7;q}RE03!)Ds z-^bQ~-%zOa$!s(z{kl}in6ej!sLC;mj3|RF;f8m delta 2727 zcmb`IZA_b06oBt#FhSU$^n(^&Xjv94Yy-Ddqzu-Lc2HV63jG|)vN*n~$YkOam9fP| zlSPw~L!yaG#E5N4v+z9)ZELU* zaxA7eiavua-ATx!I4~4T`SXqzq^{pLv586$D6WKL@l?uL@(oQ@Ztb9Ort~K5gC9%l zv8R$AE|yK$`go*bl>NiUhZCoU!-?Zhi1>XehweK{+u>V7J&mOt`U`6c+%Uoo=@{_Td{mHI65Oipr2lib8;&uNlhkc{LcqdCb~PV!_<@_bJ6LQWFY zBtK);&#sX*cO)kT;gX3V{w-!=vx==%_GDUR&CU>O z8_A#oG{{jkq0_Kx*3*st$JSXLv}jp9w$2LAj7BWHU~-dZX;#ObBbSbGNYq zFLLgN8(8-qxgH=s==}t(-Y9MJXgpaDcc~`n&Qc~3IlEd^k zw{@ayWcM9glMim#>d;!E4X`Lxm`*6;q!8uD{Cm(Z8|7C!Oam&s$iK^bWITnKT`U%v zc}F)X{7VHdbIfYO@JPObEkW5kT;njY%O||&c!ING8GnU%TyY@vC>!{9SyaXjtHUG; zTTk+dj^oxSoVE^_*!>WJZ*k;TJPkI7iCq$bMd0R`9Qd5=YTmpRdTZUA7w}cQ)|q;v z_EKF9drikOU$~eTPn3`@9@zsU-rYsw=6PVjYoJHqZNHv+;Hq~g_IJEH>-KYNCJd}& zg%OA60XBfGnYqD*?h+X7uHO@L z39H2bWC9E4qs-dYBKYkDI&=J`UV){qXBWF0O@OwSTPW0N2=Nx8Oe7gZtO&8HjHy6GMRM^OnkQSB_dc8DmvJony`wE^X<6XJnPOu|=4ic2&C&bYJa5pJVg?swy6 Xx*tA|o3mp|+-SpvEJomlOx*PkOzZyI diff --git a/Content/UI/Inventory/WBP_Equipment.uasset b/Content/UI/Inventory/WBP_Equipment.uasset new file mode 100644 index 0000000000000000000000000000000000000000..0e2b114b525dc66d0bff0d0c5ccb1bcbc6d61cd2 GIT binary patch literal 26072 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 mZS?F%mm@2dA+y{ew+ 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 literal 0 HcmV?d00001 diff --git a/Content/UI/Inventory/WBP_EquipmentSlot.uasset b/Content/UI/Inventory/WBP_EquipmentSlot.uasset new file mode 100644 index 0000000000000000000000000000000000000000..d965150c40b2e1ed9e32238992d5726bbe0563e0 GIT binary patch literal 32390 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 literal 0 HcmV?d00001 diff --git a/Content/UI/Inventory/WBP_InventoryContainerList.uasset b/Content/UI/Inventory/WBP_InventoryContainerList.uasset new file mode 100644 index 0000000000000000000000000000000000000000..855f4861e5267680177c36ec3f53e295eb513a44 GIT binary patch literal 37853 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 G{{I2A*kY{! literal 0 HcmV?d00001 diff --git a/Content/UI/Inventory/WBP_ItemList.uasset b/Content/UI/Inventory/WBP_ItemList.uasset new file mode 100644 index 0000000000000000000000000000000000000000..b5b9a31ee1c59da571b56bce91aed2d5ced24762 GIT binary patch literal 25623 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 literal 0 HcmV?d00001 diff --git a/Source/KingshearthLegacy/Inventory/InventoryTypes.h b/Source/KingshearthLegacy/Inventory/InventoryTypes.h new file mode 100644 index 0000000..97c922b --- /dev/null +++ b/Source/KingshearthLegacy/Inventory/InventoryTypes.h @@ -0,0 +1,104 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "InventoryTypes.generated.h" + +class UTexture2D; + +/** + * Where an equipped item is displayed. Purely a display label for WBP_EquipmentSlot - there is + * no attachment-point/socket hierarchy and no validation that an item is appropriate for the + * slot it's put in. Multiple slots can share the same type (e.g. two Back slots, two Belt + * slots) - disambiguate those via FEquipmentSlotData::SlotDisplayNameOverride. + */ +UENUM(BlueprintType) +enum class EEquipmentSlotType : uint8 +{ + Head, + Body, + Hands, + Legs, + Feet, + Back, + Belt +}; + +/** + * A single inventory/equipment/quick-slot item as far as the UI is concerned. Mass and Volume + * describe the item's physical footprint for weight/capacity tracking - they never affect how + * large the item appears on screen, since every item always renders at the same fixed 2x2 UI + * size (see UInventoryItemWidget). An ItemID of NAME_None means the slot is empty. + */ +USTRUCT(BlueprintType) +struct FItemData +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item") + FName ItemID; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item") + FText DisplayName; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item") + TObjectPtr Icon = nullptr; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item") + int32 Quantity = 1; + + /** Physical mass in kg, used for carry-weight totals - not UI size. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item") + float Mass = 0.0f; + + /** Physical volume in liters, used for carry-capacity totals - not UI size. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item") + float Volume = 0.0f; + + /** Optional basic state label shown alongside the item (e.g. "Broken", "New", "Equipped"). Empty means no state to show. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item") + FText StateText; + + bool IsEmpty() const { return ItemID.IsNone(); } +}; + +/** + * One equipment slot's contents. SlotType is a display label only - WBP_EquipmentSlot shows + * whatever it's given here and does not validate that EquippedItem actually belongs in SlotType. + */ +USTRUCT(BlueprintType) +struct FEquipmentSlotData +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Equipment") + EEquipmentSlotType SlotType = EEquipmentSlotType::Head; + + /** Optional override shown instead of SlotType's enum name - use this to tell apart slots that share a type (e.g. "Back 1"/"Back 2", "Belt 1"/"Belt 2"). Empty falls back to the SlotType display name. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Equipment") + FText SlotDisplayNameOverride; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Equipment") + FItemData EquippedItem; +}; + +/** + * One inventory container's contents (the player's own bag, a chest being looted, ...). Items + * are a flat, ordered list - there is no physical/spatial grid position per item, only UI-list + * ordering (no Tetris-style placement). + */ +USTRUCT(BlueprintType) +struct FInventoryContainerInfo +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inventory") + FName ContainerID; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inventory") + FText DisplayName; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inventory") + TArray Items; +}; diff --git a/Source/KingshearthLegacy/KingshearthLegacy.Build.cs b/Source/KingshearthLegacy/KingshearthLegacy.Build.cs index d53dece..f6f756b 100644 --- a/Source/KingshearthLegacy/KingshearthLegacy.Build.cs +++ b/Source/KingshearthLegacy/KingshearthLegacy.Build.cs @@ -32,7 +32,9 @@ public class KingshearthLegacy : ModuleRules "KingshearthLegacy/AttributeSets", "KingshearthLegacy/GameplayEffects", "KingshearthLegacy/Interaction", + "KingshearthLegacy/Inventory", "KingshearthLegacy/UI/Menu", + "KingshearthLegacy/UI/Inventory", "KingshearthLegacy/Variant_Platforming", "KingshearthLegacy/Variant_Platforming/Animation", "KingshearthLegacy/Variant_Combat", diff --git a/Source/KingshearthLegacy/KingshearthLegacyPlayerController.cpp b/Source/KingshearthLegacy/KingshearthLegacyPlayerController.cpp index 603d216..d128f50 100644 --- a/Source/KingshearthLegacy/KingshearthLegacyPlayerController.cpp +++ b/Source/KingshearthLegacy/KingshearthLegacyPlayerController.cpp @@ -13,6 +13,7 @@ #include "UI/PlayerHUDWidget.h" #include "UI/Menu/InGameMenuWidget.h" #include "UI/Menu/MenuManagerSubsystem.h" +#include "UI/Inventory/EquipmentInventoryTabWidget.h" #include "KingshearthLegacyCharacter.h" void AKingshearthLegacyPlayerController::BeginPlay() @@ -70,6 +71,11 @@ void AKingshearthLegacyPlayerController::SetupInputComponent() { EnhancedInputComponent->BindAction(MenuAction, ETriggerEvent::Started, this, &AKingshearthLegacyPlayerController::ToggleInGameMenu); } + + if (InventoryAction) + { + EnhancedInputComponent->BindAction(InventoryAction, ETriggerEvent::Started, this, &AKingshearthLegacyPlayerController::ToggleInventory); + } } } } @@ -137,3 +143,27 @@ void AKingshearthLegacyPlayerController::ToggleInGameMenu() MenuManager->PushScreen(InGameMenuClass); } } + +void AKingshearthLegacyPlayerController::ToggleInventory() +{ + if (!IsLocalPlayerController() || !InventoryScreenClass) + { + return; + } + + UGameInstance* GI = GetGameInstance(); + UMenuManagerSubsystem* MenuManager = GI ? GI->GetSubsystem() : nullptr; + if (!MenuManager) + { + return; + } + + if (MenuManager->IsAnyScreenOpen()) + { + MenuManager->PopScreen(); + } + else + { + MenuManager->PushScreen(InventoryScreenClass); + } +} diff --git a/Source/KingshearthLegacy/KingshearthLegacyPlayerController.h b/Source/KingshearthLegacy/KingshearthLegacyPlayerController.h index e35931c..a3695ed 100644 --- a/Source/KingshearthLegacy/KingshearthLegacyPlayerController.h +++ b/Source/KingshearthLegacy/KingshearthLegacyPlayerController.h @@ -11,6 +11,7 @@ class UInputAction; class UUserWidget; class UPlayerHUDWidget; class UInGameMenuWidget; +class UEquipmentInventoryTabWidget; /** * Basic PlayerController class for a third person game @@ -59,6 +60,14 @@ protected: UPROPERTY(EditAnywhere, Category = "Input|Input Mappings") TObjectPtr MenuAction; + /** Inventory/equipment screen, pushed/popped through the menu manager by ToggleInventory */ + UPROPERTY(EditAnywhere, Category = "UI") + TSubclassOf InventoryScreenClass; + + /** Input action that opens the inventory screen, or closes the top menu screen if one is already open */ + UPROPERTY(EditAnywhere, Category = "Input|Input Mappings") + TObjectPtr InventoryAction; + /** Gameplay initialization */ virtual void BeginPlay() override; @@ -75,4 +84,8 @@ protected: UFUNCTION(BlueprintCallable, Category = "UI") void ToggleInGameMenu(); + /** Opens InventoryScreenClass, or closes the top menu screen if one is already open */ + UFUNCTION(BlueprintCallable, Category = "UI") + void ToggleInventory(); + }; diff --git a/Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.cpp new file mode 100644 index 0000000..b2811d6 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.cpp @@ -0,0 +1,86 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "EquipmentInventoryTabWidget.h" +#include "UI/Inventory/EquipmentWidget.h" +#include "UI/Inventory/QuickSlotListWidget.h" +#include "UI/Inventory/InventoryItemListWidget.h" +#include "UI/Inventory/InventoryGridWidget.h" +#include "KingshearthLegacy.h" +#include "InputCoreTypes.h" + +UEquipmentInventoryTabWidget::UEquipmentInventoryTabWidget(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + // Needed so the menu manager's SetWidgetToFocus (see UMenuManagerSubsystem::RefreshInputMode) + // can actually give this screen keyboard focus - otherwise NativeOnPreviewKeyDown below never fires. + // Only takes effect set here, at construction - UUserWidget::SetIsFocusable asserts if called later. + SetIsFocusable(true); +} + +FReply UEquipmentInventoryTabWidget::NativeOnPreviewKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) +{ + if (InKeyEvent.GetKey() == EKeys::Tab) + { + Close(); + return FReply::Handled(); + } + + return Super::NativeOnPreviewKeyDown(InGeometry, InKeyEvent); +} + +void UEquipmentInventoryTabWidget::InitializeInventory(const TArray& InEquipmentSlots, const TArray& InBigQuickSlots, const TArray& InSmallQuickSlots, const TArray& InInventoryItems) +{ + UE_LOG(LogKingshearthLegacy, Log, TEXT("[Inventory] EquipmentInventoryTab InitializeInventory: WBP_Equipment bound: %s, WBP_QuickSlotList bound: %s, WBP_ItemList bound: %s, WBP_InventoryGrid bound: %s"), + WBP_Equipment ? TEXT("yes") : TEXT("NO - check its Name in the Designer tree matches the native property, and that it's reparented to UEquipmentWidget"), + WBP_QuickSlotList ? TEXT("yes") : TEXT("NO - check its Name in the Designer tree matches the native property, and that it's reparented to UQuickSlotListWidget"), + WBP_ItemList ? TEXT("yes") : TEXT("NO - check its Name in the Designer tree matches the native property, and that it's reparented to UInventoryItemListWidget"), + WBP_InventoryGrid ? TEXT("yes") : TEXT("NO - check its Name in the Designer tree matches the native property, and that it's reparented to UInventoryGridWidget")); + + if (WBP_Equipment) + { + WBP_Equipment->SetEquipmentSlots(InEquipmentSlots); + } + + if (WBP_QuickSlotList) + { + WBP_QuickSlotList->SetQuickSlots(InBigQuickSlots, InSmallQuickSlots); + } + + if (WBP_ItemList) + { + WBP_ItemList->SetItems(InInventoryItems); + } + + if (WBP_InventoryGrid) + { + WBP_InventoryGrid->SetItems(InInventoryItems); + } + + ShowInventoryGridView(); +} + +void UEquipmentInventoryTabWidget::ShowItemListView() +{ + if (WBP_ItemList) + { + WBP_ItemList->SetVisibility(ESlateVisibility::Visible); + } + + if (WBP_InventoryGrid) + { + WBP_InventoryGrid->SetVisibility(ESlateVisibility::Collapsed); + } +} + +void UEquipmentInventoryTabWidget::ShowInventoryGridView() +{ + if (WBP_ItemList) + { + WBP_ItemList->SetVisibility(ESlateVisibility::Collapsed); + } + + if (WBP_InventoryGrid) + { + WBP_InventoryGrid->SetVisibility(ESlateVisibility::Visible); + } +} diff --git a/Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.h b/Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.h new file mode 100644 index 0000000..0f7c1b5 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/EquipmentInventoryTabWidget.h @@ -0,0 +1,87 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "UI/Menu/MenuScreenWidget.h" +#include "Inventory/InventoryTypes.h" +#include "EquipmentInventoryTabWidget.generated.h" + +class UEquipmentWidget; +class UQuickSlotListWidget; +class UInventoryItemListWidget; +class UInventoryGridWidget; + +/** + * Main inventory screen - a shallow wrapper coordinating its child widgets. Pushed/popped + * through the menu manager like any other UMenuScreenWidget (see + * AKingshearthLegacyPlayerController::ToggleInventory), so opening/closing it gets the usual UI + * input mode + cursor handling for free, and an optional "BackButton" (inherited from + * UMenuScreenWidget) closes it the same way any other menu screen closes: + * + * WBP_EquipmentInventoryTAB + * |-- WBP_Equipment + * | `-- WBP_EquipmentSlot + * |-- WBP_QuickSlotList + * `-- Inventory View + * |-- WBP_ItemList + * `-- WBP_InventoryGrid + * + * Owns no inventory logic itself - it only forwards data supplied by the inventory/equipment + * system to its children, and switches which of WBP_ItemList / WBP_InventoryGrid is visible for + * the "Inventory View" section (both are kept populated with the same items; only one is shown + * at a time). + * + * Nest instances named exactly "WBP_Equipment", "WBP_QuickSlotList", "WBP_ItemList" and + * "WBP_InventoryGrid" in the Designer tree, reparented to their respective C++ base classes. + */ +UCLASS(abstract) +class UEquipmentInventoryTabWidget : public UMenuScreenWidget +{ + GENERATED_BODY() + +public: + + UEquipmentInventoryTabWidget(const FObjectInitializer& ObjectInitializer); + + /** Populates every child widget. Call once the inventory/equipment system has data ready (e.g. right after this screen is pushed). */ + UFUNCTION(BlueprintCallable, Category = "Inventory") + void InitializeInventory(const TArray& InEquipmentSlots, const TArray& InBigQuickSlots, const TArray& InSmallQuickSlots, const TArray& InInventoryItems); + + UFUNCTION(BlueprintCallable, Category = "Inventory") + void ShowItemListView(); + + UFUNCTION(BlueprintCallable, Category = "Inventory") + void ShowInventoryGridView(); + +protected: + + /** + * While this screen is open, the menu manager puts input in UI-only mode - the PlayerController + * stops receiving Tab presses entirely, so re-pressing Tab can only be caught here, at the + * focused widget itself. Requires bIsFocusable (set true in the constructor) so the menu + * manager's SetWidgetToFocus call actually succeeds. + * + * Uses the Preview (tunneling) pass rather than NativeOnKeyDown (bubbling) - Tab is Slate's + * default "focus next widget" navigation key, and that default navigation runs as a fallback + * once the bubbling pass goes unhandled, which pre-empts NativeOnKeyDown ever getting a + * chance to close the screen. Intercepting in Preview, which runs before that fallback, avoids it. + */ + virtual FReply NativeOnPreviewKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override; + + /** Nested WBP_Equipment instance - named exactly "WBP_Equipment" in the Designer tree. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr WBP_Equipment; + + /** Nested WBP_QuickSlotList instance - named exactly "WBP_QuickSlotList" in the Designer tree. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr WBP_QuickSlotList; + + /** Nested WBP_ItemList instance - named exactly "WBP_ItemList" in the Designer tree, part of the Inventory View toggle. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr WBP_ItemList; + + /** Nested WBP_InventoryGrid instance - named exactly "WBP_InventoryGrid" in the Designer tree, part of the Inventory View toggle. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr WBP_InventoryGrid; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotListEntry.h b/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotListEntry.h new file mode 100644 index 0000000..3964bf8 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotListEntry.h @@ -0,0 +1,24 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/Object.h" +#include "Inventory/InventoryTypes.h" +#include "EquipmentSlotListEntry.generated.h" + +/** + * Plain UObject wrapper around one FEquipmentSlotData - UListView items must be UObjects, not + * structs. Used by WBP_Equipment before calling SetListItems, so each row's UEquipmentSlotWidget + * receives one of these via IUserObjectListEntry. + */ +UCLASS() +class UEquipmentSlotListEntry : public UObject +{ + GENERATED_BODY() + +public: + + UPROPERTY(BlueprintReadOnly, Category = "Equipment") + FEquipmentSlotData Slot; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.cpp new file mode 100644 index 0000000..abec3a1 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.cpp @@ -0,0 +1,58 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "EquipmentSlotWidget.h" +#include "UI/Inventory/EquipmentSlotListEntry.h" +#include "Components/Image.h" +#include "Components/TextBlock.h" + +void UEquipmentSlotWidget::SetSlotData(const FEquipmentSlotData& InSlotData) +{ + SlotData = InSlotData; + ApplySlotVisuals(); +} + +void UEquipmentSlotWidget::NativeOnListItemObjectSet(UObject* ListItemObject) +{ + if (const UEquipmentSlotListEntry* ListItem = Cast(ListItemObject)) + { + SetSlotData(ListItem->Slot); + } +} + +void UEquipmentSlotWidget::ApplySlotVisuals() +{ + const bool bHasItem = !SlotData.EquippedItem.IsEmpty(); + + if (Icon) + { + if (bHasItem && SlotData.EquippedItem.Icon) + { + Icon->SetBrushFromTexture(SlotData.EquippedItem.Icon); + Icon->SetVisibility(ESlateVisibility::HitTestInvisible); + } + else + { + Icon->SetVisibility(ESlateVisibility::Collapsed); + } + } + + if (QuantityText) + { + if (bHasItem && SlotData.EquippedItem.Quantity > 1) + { + QuantityText->SetText(FText::AsNumber(SlotData.EquippedItem.Quantity)); + QuantityText->SetVisibility(ESlateVisibility::HitTestInvisible); + } + else + { + QuantityText->SetVisibility(ESlateVisibility::Collapsed); + } + } + + if (SlotLabel) + { + SlotLabel->SetText(!SlotData.SlotDisplayNameOverride.IsEmpty() + ? SlotData.SlotDisplayNameOverride + : UEnum::GetDisplayValueAsText(SlotData.SlotType)); + } +} diff --git a/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.h b/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.h new file mode 100644 index 0000000..5922b37 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/EquipmentSlotWidget.h @@ -0,0 +1,57 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Blueprint/IUserObjectListEntry.h" +#include "Inventory/InventoryTypes.h" +#include "EquipmentSlotWidget.generated.h" + +class UImage; +class UTextBlock; + +/** + * A single equipment slot's visuals. This is a display slot only - it shows whatever + * FEquipmentSlotData it is given and does not validate that the item is appropriate for the + * slot, and does not represent an attachment point/socket on the character mesh. + * + * Name your widgets exactly "Icon" (Image), "QuantityText" (TextBlock) and "SlotLabel" + * (TextBlock) in the Designer and population is handled here in C++; no BP event graph logic + * needed. + */ +UCLASS(abstract) +class UEquipmentSlotWidget : public UUserWidget, public IUserObjectListEntry +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Equipment") + void SetSlotData(const FEquipmentSlotData& InSlotData); + + UFUNCTION(BlueprintPure, Category = "Equipment") + const FEquipmentSlotData& GetSlotData() const { return SlotData; } + +protected: + + /** IUserObjectListEntry - called by the owning ListView (WBP_Equipment) when this row is assigned an UEquipmentSlotListEntry. */ + virtual void NativeOnListItemObjectSet(UObject* ListItemObject) override; + + void ApplySlotVisuals(); + + /** Equipped item's icon - bind an Image named exactly "Icon" in the Designer. Hidden automatically when the slot is empty. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr Icon; + + /** Equipped item's stack count - bind a TextBlock named exactly "QuantityText" in the Designer. Hidden automatically when Quantity <= 1. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr QuantityText; + + /** Slot type label (e.g. "Head", "Back 1") - bind a TextBlock named exactly "SlotLabel" in the Designer. Prefers SlotData.SlotDisplayNameOverride when set, falling back to the SlotType enum name. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr SlotLabel; + + UPROPERTY(BlueprintReadOnly, Category = "Equipment") + FEquipmentSlotData SlotData; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.cpp new file mode 100644 index 0000000..fa70084 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.cpp @@ -0,0 +1,29 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "EquipmentWidget.h" +#include "UI/Inventory/EquipmentSlotListEntry.h" +#include "Components/ListView.h" + +void UEquipmentWidget::SetEquipmentSlots(const TArray& InSlots) +{ + if (!SlotsList) + { + return; + } + + SlotsList->ClearListItems(); + ListItems.Reset(InSlots.Num()); + + TArray SlotObjects; + SlotObjects.Reserve(InSlots.Num()); + + for (const FEquipmentSlotData& SlotData : InSlots) + { + UEquipmentSlotListEntry* Entry = NewObject(this); + Entry->Slot = SlotData; + ListItems.Add(Entry); + SlotObjects.Add(Entry); + } + + SlotsList->SetListItems(SlotObjects); +} diff --git a/Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.h b/Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.h new file mode 100644 index 0000000..fc6f3ad --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/EquipmentWidget.h @@ -0,0 +1,38 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Inventory/InventoryTypes.h" +#include "EquipmentWidget.generated.h" + +class UEquipmentSlotListEntry; +class UListView; + +/** + * The character's full set of equipment slots. + * + * Name a ListView exactly "SlotsList" in the Designer, with its Entry Widget Class set to a WBP + * subclass of UEquipmentSlotWidget, and population is handled here in C++. + */ +UCLASS(abstract) +class UEquipmentWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Equipment") + void SetEquipmentSlots(const TArray& InSlots); + +protected: + + /** Named exactly "SlotsList" in the Designer, Entry Widget Class set to a WBP subclass of UEquipmentSlotWidget. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr SlotsList; + + /** UObject wrappers backing SlotsList - kept alive here so the ListView's UObjects don't get GC'd. */ + UPROPERTY() + TArray> ListItems; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.cpp new file mode 100644 index 0000000..411a59a --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.cpp @@ -0,0 +1,42 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "InventoryContainerListWidget.h" +#include "UI/Inventory/InventoryGridWidget.h" +#include "Components/TextBlock.h" + +void UInventoryContainerListWidget::NativeConstruct() +{ + Super::NativeConstruct(); + + SetExpanded(bExpanded); +} + +void UInventoryContainerListWidget::SetContainerData(const FInventoryContainerInfo& InContainerData) +{ + ContainerData = InContainerData; + + if (ContainerLabel) + { + ContainerLabel->SetText(ContainerData.DisplayName); + } + + if (WBP_InventoryGrid) + { + WBP_InventoryGrid->SetItems(ContainerData.Items); + } +} + +void UInventoryContainerListWidget::SetExpanded(bool bInExpanded) +{ + bExpanded = bInExpanded; + + if (WBP_InventoryGrid) + { + WBP_InventoryGrid->SetVisibility(bExpanded ? ESlateVisibility::Visible : ESlateVisibility::Collapsed); + } +} + +void UInventoryContainerListWidget::ToggleExpanded() +{ + SetExpanded(!bExpanded); +} diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.h b/Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.h new file mode 100644 index 0000000..9c49d23 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryContainerListWidget.h @@ -0,0 +1,67 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Inventory/InventoryTypes.h" +#include "InventoryContainerListWidget.generated.h" + +class UInventoryGridWidget; +class UTextBlock; + +/** + * A labeled, collapsible view of one inventory container (the player's own bag, a chest being + * looted, ...): + * + * WBP_InventoryContainerList + * |-- Container Label + * `-- Collapsible Inventory Grid + * `-- WBP_InventoryGrid + * `-- WBP_Item + * + * Name a TextBlock exactly "ContainerLabel" in the Designer, and nest a WBP subclass of + * UInventoryGridWidget named exactly "WBP_InventoryGrid". SetContainerData populates the label + * and forwards the container's items to the nested grid; SetExpanded/ToggleExpanded show or + * collapse it. Wire an expand/collapse button to ToggleExpanded in the Designer/event graph. + */ +UCLASS(abstract) +class UInventoryContainerListWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Inventory") + void SetContainerData(const FInventoryContainerInfo& InContainerData); + + UFUNCTION(BlueprintPure, Category = "Inventory") + const FInventoryContainerInfo& GetContainerData() const { return ContainerData; } + + UFUNCTION(BlueprintCallable, Category = "Inventory") + void SetExpanded(bool bInExpanded); + + UFUNCTION(BlueprintCallable, Category = "Inventory") + void ToggleExpanded(); + + UFUNCTION(BlueprintPure, Category = "Inventory") + bool IsExpanded() const { return bExpanded; } + +protected: + + virtual void NativeConstruct() override; + + /** Named exactly "ContainerLabel" in the Designer. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr ContainerLabel; + + /** Nested WBP_InventoryGrid instance - named exactly "WBP_InventoryGrid" in the Designer tree, reparented to a UInventoryGridWidget subclass. Collapsed/shown by SetExpanded. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr WBP_InventoryGrid; + + UPROPERTY(BlueprintReadOnly, Category = "Inventory") + FInventoryContainerInfo ContainerData; + + UPROPERTY(EditAnywhere, Category = "Inventory") + bool bExpanded = true; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.cpp new file mode 100644 index 0000000..0565717 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.cpp @@ -0,0 +1,35 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "InventoryGridWidget.h" +#include "UI/Inventory/InventoryItemListEntry.h" +#include "Components/TileView.h" + +void UInventoryGridWidget::SetItems(const TArray& InItems) +{ + Items = InItems; + PopulateGrid(); +} + +void UInventoryGridWidget::PopulateGrid() +{ + if (!ItemsGrid) + { + return; + } + + ItemsGrid->ClearListItems(); + ListItems.Reset(Items.Num()); + + TArray ItemObjects; + ItemObjects.Reserve(Items.Num()); + + for (const FItemData& Item : Items) + { + UInventoryItemListEntry* Entry = NewObject(this); + Entry->Item = Item; + ListItems.Add(Entry); + ItemObjects.Add(Entry); + } + + ItemsGrid->SetListItems(ItemObjects); +} diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.h b/Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.h new file mode 100644 index 0000000..70d4825 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryGridWidget.h @@ -0,0 +1,49 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Inventory/InventoryTypes.h" +#include "InventoryGridWidget.generated.h" + +class UInventoryItemListEntry; +class UTileView; + +/** + * A UI grid of items. This is purely a tiled layout - every item occupies the same fixed-size + * 2x2 tile no matter its Mass/Volume, and items have no spatial position of their own (no + * physical/Tetris-style grid placement). Carries no container/label concept of its own - that's + * WBP_InventoryContainerList's job when a labeled, collapsible section is needed. + * + * Name a TileView exactly "ItemsGrid" in the Designer, with its Entry Widget Class set to a WBP + * subclass of UInventoryItemWidget, and population is handled here in C++. + */ +UCLASS(abstract) +class UInventoryGridWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Inventory") + void SetItems(const TArray& InItems); + + UFUNCTION(BlueprintPure, Category = "Inventory") + const TArray& GetItems() const { return Items; } + +protected: + + void PopulateGrid(); + + /** Named exactly "ItemsGrid" in the Designer, Entry Widget Class set to a WBP subclass of UInventoryItemWidget. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr ItemsGrid; + + UPROPERTY(BlueprintReadOnly, Category = "Inventory") + TArray Items; + + /** UObject wrappers backing ItemsGrid - kept alive here so the TileView's UObjects don't get GC'd. */ + UPROPERTY() + TArray> ListItems; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryItemListEntry.h b/Source/KingshearthLegacy/UI/Inventory/InventoryItemListEntry.h new file mode 100644 index 0000000..a3b26ae --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryItemListEntry.h @@ -0,0 +1,25 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/Object.h" +#include "Inventory/InventoryTypes.h" +#include "InventoryItemListEntry.generated.h" + +/** + * Plain UObject wrapper around one FItemData - UListView/UTileView items must be UObjects, not + * structs. Used by WBP_ItemList, WBP_InventoryGrid and WBP_QuickSlotList before calling + * SetListItems, so each row's UInventoryItemWidget receives one of these via + * IUserObjectListEntry. + */ +UCLASS() +class UInventoryItemListEntry : public UObject +{ + GENERATED_BODY() + +public: + + UPROPERTY(BlueprintReadOnly, Category = "Item") + FItemData Item; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.cpp new file mode 100644 index 0000000..b719e18 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.cpp @@ -0,0 +1,29 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "InventoryItemListWidget.h" +#include "UI/Inventory/InventoryItemListEntry.h" +#include "Components/ListView.h" + +void UInventoryItemListWidget::SetItems(const TArray& InItems) +{ + if (!ItemsList) + { + return; + } + + ItemsList->ClearListItems(); + ListItems.Reset(InItems.Num()); + + TArray ItemObjects; + ItemObjects.Reserve(InItems.Num()); + + for (const FItemData& Item : InItems) + { + UInventoryItemListEntry* Entry = NewObject(this); + Entry->Item = Item; + ListItems.Add(Entry); + ItemObjects.Add(Entry); + } + + ItemsList->SetListItems(ItemObjects); +} diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.h b/Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.h new file mode 100644 index 0000000..5574d76 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryItemListWidget.h @@ -0,0 +1,41 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Inventory/InventoryTypes.h" +#include "InventoryItemListWidget.generated.h" + +class UInventoryItemListEntry; +class UListView; + +/** + * A simple vertical list of items - not a physical/spatial grid, just an ordered list. Used as + * the list-view alternative to UInventoryGridWidget inside WBP_EquipmentInventoryTAB's Inventory + * View (see UEquipmentInventoryTabWidget::ShowItemListView), and reusable standalone anywhere + * else that only needs a plain item list (a crafting recipe's ingredients, a shop's stock, ...). + * + * Name a ListView exactly "ItemsList" in the Designer, with its Entry Widget Class set to a WBP + * subclass of UInventoryItemWidget, and population is handled here in C++. + */ +UCLASS(abstract) +class UInventoryItemListWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Item List") + void SetItems(const TArray& InItems); + +protected: + + /** Named exactly "ItemsList" in the Designer, Entry Widget Class set to a WBP subclass of UInventoryItemWidget. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr ItemsList; + + /** UObject wrappers backing ItemsList - kept alive here so the ListView's UObjects don't get GC'd. */ + UPROPERTY() + TArray> ListItems; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.cpp new file mode 100644 index 0000000..7de6c05 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.cpp @@ -0,0 +1,75 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "InventoryItemWidget.h" +#include "UI/Inventory/InventoryItemListEntry.h" +#include "Components/Image.h" +#include "Components/TextBlock.h" + +void UInventoryItemWidget::SetItemData(const FItemData& InItemData) +{ + ItemData = InItemData; + ApplyItemVisuals(); +} + +void UInventoryItemWidget::NativeOnListItemObjectSet(UObject* ListItemObject) +{ + if (const UInventoryItemListEntry* ListItem = Cast(ListItemObject)) + { + SetItemData(ListItem->Item); + } +} + +void UInventoryItemWidget::ApplyItemVisuals() +{ + if (Icon) + { + if (!ItemData.IsEmpty() && ItemData.Icon) + { + Icon->SetBrushFromTexture(ItemData.Icon); + Icon->SetVisibility(ESlateVisibility::HitTestInvisible); + } + else + { + Icon->SetVisibility(ESlateVisibility::Collapsed); + } + } + + if (ItemNameText) + { + if (!ItemData.IsEmpty()) + { + ItemNameText->SetText(ItemData.DisplayName); + ItemNameText->SetVisibility(ESlateVisibility::HitTestInvisible); + } + else + { + ItemNameText->SetVisibility(ESlateVisibility::Collapsed); + } + } + + if (QuantityText) + { + if (!ItemData.IsEmpty() && ItemData.Quantity > 1) + { + QuantityText->SetText(FText::AsNumber(ItemData.Quantity)); + QuantityText->SetVisibility(ESlateVisibility::HitTestInvisible); + } + else + { + QuantityText->SetVisibility(ESlateVisibility::Collapsed); + } + } + + if (StateText) + { + if (!ItemData.IsEmpty() && !ItemData.StateText.IsEmpty()) + { + StateText->SetText(ItemData.StateText); + StateText->SetVisibility(ESlateVisibility::HitTestInvisible); + } + else + { + StateText->SetVisibility(ESlateVisibility::Collapsed); + } + } +} diff --git a/Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.h b/Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.h new file mode 100644 index 0000000..0825546 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/InventoryItemWidget.h @@ -0,0 +1,63 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Blueprint/IUserObjectListEntry.h" +#include "Inventory/InventoryTypes.h" +#include "InventoryItemWidget.generated.h" + +class UImage; +class UTextBlock; + +/** + * A single inventory/equipment/quick-slot item. Always renders at the same fixed UI size + * regardless of the item's Mass/Volume - physical footprint is inventory-property data, not a + * UI dimension. Reused as the entry widget class for WBP_ItemList, WBP_InventoryGrid and + * WBP_QuickSlotList (via IUserObjectListEntry), and can also be placed directly and driven with + * SetItemData. + * + * Name your widgets exactly "Icon" (Image), "ItemNameText" (TextBlock), "QuantityText" + * (TextBlock) and "StateText" (TextBlock) in the Designer and population is handled here in + * C++; no BP event graph logic needed. + */ +UCLASS(abstract) +class UInventoryItemWidget : public UUserWidget, public IUserObjectListEntry +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Item") + void SetItemData(const FItemData& InItemData); + + UFUNCTION(BlueprintPure, Category = "Item") + const FItemData& GetItemData() const { return ItemData; } + +protected: + + /** IUserObjectListEntry - called by the owning ListView/TileView when this row is assigned an UInventoryItemListEntry. */ + virtual void NativeOnListItemObjectSet(UObject* ListItemObject) override; + + void ApplyItemVisuals(); + + /** Item icon - bind an Image named exactly "Icon" in the Designer. Hidden automatically when the item slot is empty. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr Icon; + + /** Item name - bind a TextBlock named exactly "ItemNameText" in the Designer. Hidden automatically when the item slot is empty. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr ItemNameText; + + /** Stack count - bind a TextBlock named exactly "QuantityText" in the Designer. Hidden automatically when Quantity <= 1. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr QuantityText; + + /** Basic item state (e.g. "Broken", "New") - bind a TextBlock named exactly "StateText" in the Designer. Hidden automatically when the item has no StateText set. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr StateText; + + UPROPERTY(BlueprintReadOnly, Category = "Item") + FItemData ItemData; +}; diff --git a/Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.cpp b/Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.cpp new file mode 100644 index 0000000..97611a7 --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.cpp @@ -0,0 +1,35 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "QuickSlotListWidget.h" +#include "UI/Inventory/InventoryItemListEntry.h" +#include "Components/TileView.h" + +void UQuickSlotListWidget::SetQuickSlots(const TArray& InBigQuickSlots, const TArray& InSmallQuickSlots) +{ + PopulateSlots(BigQuickSlotsView, InBigQuickSlots, BigListItems); + PopulateSlots(SmallQuickSlotsView, InSmallQuickSlots, SmallListItems); +} + +void UQuickSlotListWidget::PopulateSlots(UTileView* TargetView, const TArray& InSlots, TArray>& OutListItems) +{ + if (!TargetView) + { + return; + } + + TargetView->ClearListItems(); + OutListItems.Reset(InSlots.Num()); + + TArray ItemObjects; + ItemObjects.Reserve(InSlots.Num()); + + for (const FItemData& Item : InSlots) + { + UInventoryItemListEntry* Entry = NewObject(this); + Entry->Item = Item; + OutListItems.Add(Entry); + ItemObjects.Add(Entry); + } + + TargetView->SetListItems(ItemObjects); +} diff --git a/Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.h b/Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.h new file mode 100644 index 0000000..ab76d0e --- /dev/null +++ b/Source/KingshearthLegacy/UI/Inventory/QuickSlotListWidget.h @@ -0,0 +1,55 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Inventory/InventoryTypes.h" +#include "QuickSlotListWidget.generated.h" + +class UInventoryItemListEntry; +class UTileView; + +/** + * The player's quick-access hotbar: a row of "big" slots (primary, keybound actions) and a row + * of "small" slots (secondary/utility). Both still render items at the standard fixed 2x2 size - + * "big"/"small" describes the slot's role and on-screen footprint, not item icon scaling. Pass + * an entry with an empty FItemData (see FItemData::IsEmpty) for slots that have nothing + * assigned. The slot arrays may include slots granted by equipped items (e.g. a backpack) - + * that's the inventory/equipment system's decision, this widget just displays whatever it's + * given. + * + * Name two TileViews exactly "BigQuickSlotsView" and "SmallQuickSlotsView" in the Designer, both + * with their Entry Widget Class set to a WBP subclass of UInventoryItemWidget (the same class + * used by WBP_ItemList/WBP_InventoryGrid), and population is handled here in C++. + */ +UCLASS(abstract) +class UQuickSlotListWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Quick Slots") + void SetQuickSlots(const TArray& InBigQuickSlots, const TArray& InSmallQuickSlots); + +protected: + + void PopulateSlots(UTileView* TargetView, const TArray& InSlots, TArray>& OutListItems); + + /** Named exactly "BigQuickSlotsView" in the Designer, Entry Widget Class set to a WBP subclass of UInventoryItemWidget. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr BigQuickSlotsView; + + /** Named exactly "SmallQuickSlotsView" in the Designer, Entry Widget Class set to a WBP subclass of UInventoryItemWidget. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr SmallQuickSlotsView; + + /** UObject wrappers backing BigQuickSlotsView - kept alive here so the TileView's UObjects don't get GC'd. */ + UPROPERTY() + TArray> BigListItems; + + /** UObject wrappers backing SmallQuickSlotsView - kept alive here so the TileView's UObjects don't get GC'd. */ + UPROPERTY() + TArray> SmallListItems; +};