161 lines
5.0 KiB
C++
161 lines
5.0 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Blueprint/UserWidget.h"
|
|
#include "CraftingRecipeDataAsset.h"
|
|
#include "CraftingWidget.generated.h"
|
|
|
|
class UButton;
|
|
class UCraftingComponent;
|
|
class UCraftingIngredientRowWidget;
|
|
class UCraftingRecipeSlotWidget;
|
|
class UImage;
|
|
class UInventoryComponent;
|
|
class UPanelWidget;
|
|
class UTextBlock;
|
|
class UUniformGridPanel;
|
|
|
|
/**
|
|
* La page de fabrication : la grille de recettes a gauche, le detail de la
|
|
* recette choisie a droite.
|
|
*
|
|
* Elle ne calcule rien. UCraftingComponent lui dit quelles recettes afficher,
|
|
* lesquelles sont realisables, et fabrique quand on clique. Elle s'abonne a
|
|
* l'inventaire et aux postes accessibles pour se rafraichir -- jamais de Tick
|
|
* pour relire un etat.
|
|
*/
|
|
UCLASS(Abstract)
|
|
class SURVIVAL_PROJET_API UCraftingWidget : public UUserWidget
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
virtual void NativeConstruct() override;
|
|
virtual void NativeDestruct() override;
|
|
|
|
/**
|
|
* (Re)branche la page sur le pawn actuellement possede.
|
|
* Indispensable apres un respawn : le nouveau pawn a de nouveaux composants,
|
|
* et les anciens abonnements pointeraient vers des objets detruits.
|
|
*/
|
|
void BindToOwningPawn();
|
|
|
|
/** Relit la liste, l'etat de chaque case et le panneau de detail. */
|
|
UFUNCTION(BlueprintCallable, Category = "Crafting")
|
|
void Refresh();
|
|
|
|
/** Appele par une case quand on clique dessus. */
|
|
void NotifyRecipeClicked(UCraftingRecipeDataAsset* InRecipe);
|
|
|
|
/**
|
|
* Restreint l'affichage a un seul poste. Count = tout ce qui est accessible.
|
|
* Purement visuel : ce filtre ne peut jamais rendre une recette realisable.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Crafting")
|
|
void SetStationFilter(ECraftingStation InFilter);
|
|
|
|
protected:
|
|
/** A nommer exactement "RecipeGrid" dans le Widget Blueprint. */
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UUniformGridPanel> RecipeGrid;
|
|
|
|
/** L'icone du resultat, dans le panneau de droite. */
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UImage> ResultIcon;
|
|
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UTextBlock> ResultNameText;
|
|
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UButton> CraftButton;
|
|
|
|
/** Facultatif : la description de l'objet produit. */
|
|
UPROPERTY(meta = (BindWidgetOptional))
|
|
TObjectPtr<UTextBlock> ResultDescriptionText;
|
|
|
|
/** Facultatif : "x2" quand la recette produit plusieurs exemplaires. Masque sinon. */
|
|
UPROPERTY(meta = (BindWidgetOptional))
|
|
TObjectPtr<UTextBlock> ResultQuantityText;
|
|
|
|
/**
|
|
* Facultatif : le panneau de droite dans son ensemble. Masque tant qu'aucune
|
|
* recette n'est choisie, pour ne pas afficher un cadre vide au premier
|
|
* affichage.
|
|
*/
|
|
UPROPERTY(meta = (BindWidgetOptional))
|
|
TObjectPtr<UWidget> DetailsPanel;
|
|
|
|
/** Facultatif : message affiche quand aucune recette n'est disponible ici. */
|
|
UPROPERTY(meta = (BindWidgetOptional))
|
|
TObjectPtr<UWidget> EmptyGridMessage;
|
|
|
|
/**
|
|
* Le conteneur des lignes de cout. Declare en UPanelWidget et non en
|
|
* UVerticalBox : ca laisse le choix d'un Wrap Box ou d'un Grid Panel dans le
|
|
* Blueprint sans toucher au C++, puisqu'on ne fait qu'y ajouter des enfants.
|
|
*/
|
|
UPROPERTY(meta = (BindWidgetOptional))
|
|
TObjectPtr<UPanelWidget> IngredientList;
|
|
|
|
/** Ton WBP_RecipeSlot. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Crafting")
|
|
TSubclassOf<UCraftingRecipeSlotWidget> RecipeSlotClass;
|
|
|
|
/** Ton WBP_IngredientRow. Sans elle, la liste de cout reste vide. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Crafting")
|
|
TSubclassOf<UCraftingIngredientRowWidget> IngredientRowClass;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Crafting", meta = (ClampMin = "1"))
|
|
int32 ColumnCount = 5;
|
|
|
|
private:
|
|
UFUNCTION()
|
|
void HandleInventoryChanged();
|
|
|
|
UFUNCTION()
|
|
void HandleStationsChanged();
|
|
|
|
UFUNCTION()
|
|
void HandleCraftClicked();
|
|
|
|
/** Recree les cases uniquement si la liste affichee a change. */
|
|
void RebuildGrid(const TArray<UCraftingRecipeDataAsset*>& NewRecipes);
|
|
|
|
/** Pousse l'etat realisable/non a chaque case et met a jour le panneau. */
|
|
void RefreshStates();
|
|
|
|
void RefreshDetails();
|
|
|
|
/**
|
|
* Remplit la liste de cout de la recette choisie.
|
|
*
|
|
* Les lignes sont RECYCLEES et non recreees : cette fonction repasse a
|
|
* chaque changement d'inventaire, donc a chaque ramassage. Detruire puis
|
|
* reconstruire trois widgets par branche ramassee serait du gaspillage.
|
|
*/
|
|
void RefreshIngredients();
|
|
|
|
UCraftingComponent* ResolveCrafting() const;
|
|
|
|
/** Detache les deux abonnements. Appele avant de rebrancher, et a la destruction. */
|
|
void UnbindDelegates();
|
|
|
|
TWeakObjectPtr<UCraftingComponent> BoundCrafting;
|
|
|
|
TWeakObjectPtr<UInventoryComponent> BoundInventory;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UCraftingRecipeDataAsset> SelectedRecipe;
|
|
|
|
/** UPROPERTY obligatoire : sans ca le GC collecterait les cases. */
|
|
UPROPERTY(Transient)
|
|
TArray<TObjectPtr<UCraftingRecipeSlotWidget>> RecipeSlots;
|
|
|
|
UPROPERTY(Transient)
|
|
TArray<TObjectPtr<UCraftingIngredientRowWidget>> IngredientRows;
|
|
|
|
ECraftingStation StationFilter = ECraftingStation::Count;
|
|
};
|