(Feat) Add Animation Fps Charater
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "CraftingRecipeDataAsset.h"
|
||||
#include "CraftingComponent.generated.h"
|
||||
|
||||
class UCraftingRecipeBook;
|
||||
class UInventoryComponent;
|
||||
class UItemDataAsset;
|
||||
|
||||
/**
|
||||
* Pourquoi une fabrication a echoue. Sert a l'interface, pour dire au joueur
|
||||
* ce qui manque au lieu de laisser un bouton grise sans explication.
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class ECraftFailureReason : uint8
|
||||
{
|
||||
None,
|
||||
InvalidRecipe,
|
||||
NoRecipeBook,
|
||||
StationUnavailable,
|
||||
MissingIngredients
|
||||
};
|
||||
|
||||
/**
|
||||
* Etat d'un ingredient pour une recette donnee : ce qu'il faut, ce qu'on a.
|
||||
*
|
||||
* C'est le composant qui fait le rapprochement, pas le widget. Une ligne
|
||||
* d'ingredient n'a plus qu'a afficher deux nombres et choisir une couleur --
|
||||
* elle n'interroge jamais l'inventaire elle-meme.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCraftIngredientStatus
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Crafting")
|
||||
TObjectPtr<UItemDataAsset> Item = nullptr;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Crafting")
|
||||
int32 RequiredQuantity = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Crafting")
|
||||
int32 OwnedQuantity = 0;
|
||||
|
||||
bool IsSatisfied() const { return OwnedQuantity >= RequiredQuantity; }
|
||||
};
|
||||
|
||||
/** Une fabrication vient d'aboutir. Pour le son, l'animation, une notification. */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCraftSucceeded, UCraftingRecipeDataAsset*, Recipe);
|
||||
|
||||
/** Les postes accessibles ont change : l'interface doit revoir sa liste. */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnAvailableStationsChanged);
|
||||
|
||||
/**
|
||||
* Le resultat n'est pas entre dans l'inventaire. A quelqu'un de le poser
|
||||
* dans le monde -- voir le commentaire de Craft().
|
||||
*/
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnCraftOverflow, UItemDataAsset*, Item, int32, Quantity, int32, RemainingUses);
|
||||
|
||||
/**
|
||||
* Fabrication d'objets a partir d'un livre de recettes et de l'inventaire du
|
||||
* meme acteur.
|
||||
*
|
||||
* Sur le pawn : fabriquer est une capacite du corps, au meme titre que porter
|
||||
* un sac. Le composant ne connait ni l'interface ni la classe du pawn -- un
|
||||
* futur etabli pourra porter le meme composant avec son propre livre.
|
||||
*/
|
||||
UCLASS(ClassGroup = (Survival), meta = (BlueprintSpawnableComponent))
|
||||
class EMBERWILD_API UCraftingComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCraftingComponent();
|
||||
|
||||
virtual void InitializeComponent() override;
|
||||
|
||||
/**
|
||||
* Recettes a afficher, dans l'ordre du livre.
|
||||
*
|
||||
* Ne renvoie que celles dont le poste est ACCESSIBLE : les mains vides, on
|
||||
* ne voit pas les recettes d'etabli. C'est le modele choisi -- une seule
|
||||
* fenetre de craft dont le contenu depend d'ou l'on se trouve.
|
||||
*
|
||||
* @param StationFilter filtre d'affichage supplementaire, purement visuel.
|
||||
* Passe Count pour tout voir. Un poste demande ici mais non
|
||||
* accessible ne fait rien apparaitre : le filtre restreint, il
|
||||
* n'autorise jamais.
|
||||
*
|
||||
* Pas de valeur par defaut sur StationFilter : UHT refuse une entree
|
||||
* UMETA(Hidden) comme defaut, et dé-cacher Count le rendrait selectionnable
|
||||
* dans le champ Required Station d'une recette. L'appelant l'ecrit.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Crafting")
|
||||
void GatherRecipes(TArray<UCraftingRecipeDataAsset*>& OutRecipes, ECraftingStation StationFilter) const;
|
||||
|
||||
/** Peut-on fabriquer cette recette maintenant, et sinon pourquoi. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Crafting")
|
||||
bool CanCraft(const UCraftingRecipeDataAsset* Recipe, ECraftFailureReason& OutReason) const;
|
||||
|
||||
/** Le detail requis / possede de chaque ingredient, dans l'ordre de la recette. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Crafting")
|
||||
void GatherIngredientStatus(const UCraftingRecipeDataAsset* Recipe, TArray<FCraftIngredientStatus>& OutStatus) const;
|
||||
|
||||
/**
|
||||
* Consomme les ingredients et ajoute le resultat a l'inventaire.
|
||||
*
|
||||
* L'ordre compte : on consomme AVANT d'ajouter. Refuser une fabrication
|
||||
* parce que l'inventaire est plein serait faux -- consommer trois branches
|
||||
* libere justement la case ou poser le resultat. Et si malgre tout il ne
|
||||
* rentre pas, l'objet part dans OnCraftOverflow pour etre pose au sol :
|
||||
* aucune ressource ne disparait jamais, ni a l'entree ni a la sortie.
|
||||
*
|
||||
* @return true si la fabrication a eu lieu.
|
||||
*/
|
||||
/**
|
||||
* Fabrique la recette. Chez un client, envoie la demande au serveur et rend
|
||||
* true : le resultat redescendra par la replication de l'inventaire.
|
||||
*
|
||||
* Le serveur refait TOUJOURS CanCraft de son cote, avec sa propre liste de
|
||||
* postes accessibles -- celle que le controller tient a jour par
|
||||
* Client_OpenCraftingAtStation et Server_ReleaseStation.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Crafting")
|
||||
bool Craft(UCraftingRecipeDataAsset* Recipe);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Postes accessibles
|
||||
//
|
||||
// Etat courant, pas de la configuration : {Hands} en permanence, plus
|
||||
// Workbench tant qu'on est devant un etabli. C'est une CONDITION de
|
||||
// fabrication, a ne pas confondre avec le filtre d'affichage de
|
||||
// GatherRecipes -- melanger les deux rendrait un jour un craft impossible
|
||||
// a cause d'un bouton d'interface.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Crafting|Stations")
|
||||
bool HasStation(ECraftingStation Station) const;
|
||||
|
||||
/**
|
||||
* A appeler quand le joueur entre dans le rayon d'un poste.
|
||||
*
|
||||
* Les appels se COMPTENT : deux etablis dont les portees se chevauchent, ce
|
||||
* qui arrive des qu'on construit une base un peu dense, s'ajoutent tous les
|
||||
* deux. Sortir du premier ne doit pas retirer l'acces alors qu'on est encore
|
||||
* devant le second.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Crafting|Stations")
|
||||
void AddAvailableStation(ECraftingStation Station);
|
||||
|
||||
/** A appeler quand il s'en eloigne. Hands ne peut pas etre retire. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Crafting|Stations")
|
||||
void RemoveAvailableStation(ECraftingStation Station);
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Crafting")
|
||||
FOnCraftSucceeded OnCraftSucceeded;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Crafting")
|
||||
FOnAvailableStationsChanged OnAvailableStationsChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Crafting")
|
||||
FOnCraftOverflow OnCraftOverflow;
|
||||
|
||||
protected:
|
||||
/** Ton DA_RecipeBook. Sans lui le composant ne connait aucune recette. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Crafting")
|
||||
TObjectPtr<UCraftingRecipeBook> RecipeBook;
|
||||
|
||||
/** Resolu une fois a l'initialisation : chercher le composant a chaque clic serait absurde. */
|
||||
UPROPERTY(Transient, BlueprintReadOnly, Category = "Crafting")
|
||||
TObjectPtr<UInventoryComponent> Inventory;
|
||||
|
||||
private:
|
||||
/** La fabrication demandee par un client, arbitree par le serveur. */
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_Craft(UCraftingRecipeDataAsset* Recipe);
|
||||
|
||||
/**
|
||||
* Combien de postes de chaque type sont a portee, et non un simple
|
||||
* "present / absent" -- voir AddAvailableStation.
|
||||
*
|
||||
* Pas une UPROPERTY : ni la cle ni la valeur ne sont des references a
|
||||
* collecter, et cet etat n'a rien a regler dans l'editeur.
|
||||
*/
|
||||
TMap<ECraftingStation, int32> StationRefCounts;
|
||||
};
|
||||
Reference in New Issue
Block a user