(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:
@@ -0,0 +1,114 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "ItemDetailsWidget.generated.h"
|
||||
|
||||
class UImage;
|
||||
class UInventoryComponent;
|
||||
class UProgressBar;
|
||||
class UTextBlock;
|
||||
|
||||
/**
|
||||
* Le panneau qui decrit l'objet survole : icone, nom, description, usure.
|
||||
* Rien d'autre -- volontairement.
|
||||
*
|
||||
* Il ne connait ni la grille ni l'ecran. On lui pousse un couple
|
||||
* (inventaire, index) et il lit -- et NON une copie du FInventorySlot :
|
||||
* le contenu peut changer pendant le survol (une charge consommee, un craft
|
||||
* qui vide la pile), donc le panneau s'abonne a OnInventoryChanged de
|
||||
* l'inventaire affiche et se relit tout seul. Jamais de Tick.
|
||||
*
|
||||
* Aucun texte en dur ici en dehors du format numerique de l'usure : la mise en
|
||||
* page et les libelles appartiennent au Widget Blueprint.
|
||||
*/
|
||||
UCLASS(Abstract)
|
||||
class SURVIVAL_PROJET_API UItemDetailsWidget : public UUserWidget
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void NativeConstruct() override;
|
||||
virtual void NativeDestruct() override;
|
||||
|
||||
/** Affiche la case InSlotIndex de InInventory. Index invalide = etat vide. */
|
||||
void ShowSlot(UInventoryComponent* InInventory, int32 InSlotIndex);
|
||||
|
||||
/** Repasse en etat vide et coupe l'abonnement. */
|
||||
void Clear();
|
||||
|
||||
/**
|
||||
* Efface, mais seulement si c'est bien CETTE case qui est affichee.
|
||||
*
|
||||
* Le panneau est unique et trois conteneurs le nourrissent -- grille, barre
|
||||
* rapide, et la grille elle-meme quand elle se rebranche. Passer de l'un a
|
||||
* l'autre emet "entre dans B" PUIS "sort de A" : un effacement
|
||||
* inconditionnel viderait l'affichage qui vient d'arriver.
|
||||
*/
|
||||
void ClearSlot(const UInventoryComponent* InInventory, int32 InSlotIndex);
|
||||
|
||||
protected:
|
||||
/** A nommer exactement "ItemIcon" dans le Widget Blueprint. */
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
TObjectPtr<UImage> ItemIcon;
|
||||
|
||||
/** A nommer exactement "ItemNameText". */
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
TObjectPtr<UTextBlock> ItemNameText;
|
||||
|
||||
/** Pense a cocher "Auto Wrap Text" dessus, sinon le panneau s'elargit. */
|
||||
UPROPERTY(meta = (BindWidgetOptional))
|
||||
TObjectPtr<UTextBlock> ItemDescriptionText;
|
||||
|
||||
/**
|
||||
* Bloc d'usure entier -- barre et texte ensemble -- replie sur tout objet
|
||||
* qui n'a pas de charges multiples. Sans lui, la barre et son texte
|
||||
* devraient etre replies separement et finiraient un jour desynchronises.
|
||||
*/
|
||||
UPROPERTY(meta = (BindWidgetOptional))
|
||||
TObjectPtr<UWidget> UsesPanel;
|
||||
|
||||
UPROPERTY(meta = (BindWidgetOptional))
|
||||
TObjectPtr<UProgressBar> UsesBar;
|
||||
|
||||
/** "3 / 5", pose par-dessus la barre. */
|
||||
UPROPERTY(meta = (BindWidgetOptional))
|
||||
TObjectPtr<UTextBlock> UsesText;
|
||||
|
||||
/**
|
||||
* Le conteneur qui empile tout le panneau -- a renommer "ContentRoot", ce
|
||||
* n'est pas un widget de plus.
|
||||
*
|
||||
* Il est masque en bloc quand rien n'est survole. Sans lui, la barre de
|
||||
* separation resterait seule a l'ecran : c'est une decoration du Blueprint,
|
||||
* le C++ n'a aucune raison de la connaitre individuellement.
|
||||
*/
|
||||
UPROPERTY(meta = (BindWidgetOptional))
|
||||
TObjectPtr<UWidget> ContentRoot;
|
||||
|
||||
private:
|
||||
UFUNCTION()
|
||||
void HandleInventoryChanged();
|
||||
|
||||
/** Relit la case et repeint tout le panneau. */
|
||||
void Refresh();
|
||||
|
||||
/**
|
||||
* Etat vide : plus rien a l'ecran.
|
||||
*
|
||||
* Le panneau n'a pas de fond, donc vide il est simplement invisible -- et sa
|
||||
* largeur est tenue par le Size Box du Blueprint, pas par son contenu. C'est
|
||||
* ce qui empeche la grille de sauter lateralement quand le curseur quitte
|
||||
* une case.
|
||||
*/
|
||||
void ClearDisplay();
|
||||
|
||||
/** (Re)branche OnInventoryChanged. Un seul abonnement a la fois. */
|
||||
void BindInventory(UInventoryComponent* InInventory);
|
||||
|
||||
TWeakObjectPtr<UInventoryComponent> BoundInventory;
|
||||
|
||||
int32 SlotIndex = INDEX_NONE;
|
||||
};
|
||||
Reference in New Issue
Block a user