(Feat) Add Storage Chests + Item Details Panel

Coffres : AStorageContainer, un UInventoryComponent configure en conteneur,
affiche comme panneau de WBP_InventoryScreen plutot que dans un ecran a lui.
Deplacement unifie par UInventoryComponent::TransferSlot / TransferAllTo.

Panneau de detail : UItemDetailsWidget, pose DANS WBP_Inventory a droite de la
grille. Icone, nom, separation, description, barre d'usure. Il recoit un couple
(inventaire, index) et s'abonne a OnInventoryChanged, donc une charge consommee
sous le curseur se voit.

Une case ne connait plus sa grille : elle diffuse OnHoverChanged. La barre
rapide s'y abonne aussi et relaie par le PlayerController, seul a posseder a la
fois le HUD et l'ecran. Le panneau efface la case qu'on QUITTE et non lui-meme,
sinon passer de la barre a la grille viderait ce qui vient d'etre affiche.

L'ecran allume et eteint le panneau (SetItemDetailsEnabled) : WBP_Inventory
etant instancie deux fois en mode coffre, une case a cocher par instance serait
un bug qui attend qu'on oublie de la decocher.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-01 22:51:24 +02:00
parent d50ef564ba
commit 41d6e6a7f3
50 changed files with 2947 additions and 167 deletions
+13 -3
View File
@@ -540,6 +540,16 @@ APickupItem* AFpsPlayer::SpawnPickup(const FInventorySlot& Slot, const FVector&
bool AFpsPlayer::DropSlot(int32 SlotIndex, int32 Quantity)
{
return DropFromInventory(InventoryComponent, SlotIndex, Quantity);
}
bool AFpsPlayer::DropFromInventory(UInventoryComponent* Inventory, int32 SlotIndex, int32 Quantity)
{
if (!Inventory)
{
return false;
}
if (!DroppedPickupClass)
{
UE_LOG(LogTemp, Warning, TEXT("AFpsPlayer : DroppedPickupClass n'est pas assignee, impossible de jeter un objet."));
@@ -547,7 +557,7 @@ bool AFpsPlayer::DropSlot(int32 SlotIndex, int32 Quantity)
}
FInventorySlot Taken;
if (!InventoryComponent->TakeFromSlot(SlotIndex, Quantity, Taken) || Taken.IsEmpty())
if (!Inventory->TakeFromSlot(SlotIndex, Quantity, Taken) || Taken.IsEmpty())
{
return false;
}
@@ -567,8 +577,8 @@ bool AFpsPlayer::DropSlot(int32 SlotIndex, int32 Quantity)
if (!SpawnPickup(Taken, PlaceOnGround(DropLocation)))
{
// On ne perd pas l'objet : il retourne dans l'inventaire, usure comprise.
InventoryComponent->AddItem(Taken.Item, Taken.Quantity, Taken.RemainingUses);
// On ne perd pas l'objet : il retourne d'ou il vient, usure comprise.
Inventory->AddItem(Taken.Item, Taken.Quantity, Taken.RemainingUses);
return false;
}