125 lines
4.6 KiB
C++
125 lines
4.6 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Engine/DataAsset.h"
|
|
#include "CraftingRecipeDataAsset.generated.h"
|
|
|
|
class UItemDataAsset;
|
|
class UTexture2D;
|
|
|
|
/**
|
|
* Poste de travail necessaire pour realiser une recette.
|
|
*
|
|
* Ce n'est PAS un filtre d'affichage : c'est une condition de realisation.
|
|
* Le UCraftingComponent tient la liste des stations dont le joueur dispose a
|
|
* l'instant t -- {Hands} tout seul, {Hands, Workbench} devant un etabli -- et
|
|
* une recette n'est realisable que si la sienne s'y trouve. Le filtre de
|
|
* l'interface est une notion separee, purement visuelle : melanger les deux
|
|
* finirait par rendre un craft impossible parce qu'un bouton d'affichage est
|
|
* mal positionne, et ce genre de bug ne se comprend jamais sur le moment.
|
|
*
|
|
* Fourneau et feu de cuisson n'ont volontairement PAS leur entree ici : ils ne
|
|
* passent par aucun menu. Ce sont des acteurs poses dans le monde, facon Raft,
|
|
* ou l'on depose une ressource et ou l'on voit le mesh changer d'etat. Leur
|
|
* donnee et leur file d'attente leur appartiendront, une recette de menu n'a
|
|
* rien a y faire.
|
|
*/
|
|
UENUM(BlueprintType)
|
|
enum class ECraftingStation : uint8
|
|
{
|
|
Hands,
|
|
Workbench,
|
|
|
|
// Sentinelle, jamais assignee a une recette. Elle sert a parcourir l'enum
|
|
// pour construire les boutons de filtre sans avoir a les enumerer a la main.
|
|
Count UMETA(Hidden)
|
|
};
|
|
|
|
/** Une ligne de cout : tant d'exemplaires de tel objet. */
|
|
USTRUCT(BlueprintType)
|
|
struct FCraftIngredient
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe")
|
|
TObjectPtr<UItemDataAsset> Item = nullptr;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe", meta = (ClampMin = "1"))
|
|
int32 Quantity = 1;
|
|
};
|
|
|
|
/**
|
|
* Une recette : ce qu'il faut, ce que ca donne, ou ca se fabrique.
|
|
*
|
|
* Un asset par recette, comme un DataAsset par objet. Trois comportements de
|
|
* craft n'existeront jamais : la recette est de la donnee pure, c'est le
|
|
* composant qui l'execute.
|
|
*
|
|
* Elle ne contient aucun etat -- ni "deja decouverte", ni "en cours de
|
|
* fabrication". Le jour ou les recettes se debloqueront en jeu, la liste des
|
|
* RecipeId connus vivra dans la sauvegarde, pas ici : sinon decouvrir une
|
|
* recette la debloquerait pour toutes les parties a la fois.
|
|
*/
|
|
UCLASS(BlueprintType)
|
|
class EMBERWILD_API UCraftingRecipeDataAsset : public UPrimaryDataAsset
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
/**
|
|
* Identifiant stable, independant du nom de l'asset.
|
|
* Servira a la sauvegarde des recettes decouvertes : renommer un asset ne
|
|
* doit pas faire oublier au joueur ce qu'il avait debloque.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe")
|
|
FName RecipeId;
|
|
|
|
/** Ce que la fabrication consomme. Une recette sans cout est acceptee (objet gratuit). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe")
|
|
TArray<FCraftIngredient> Ingredients;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe")
|
|
TObjectPtr<UItemDataAsset> ResultItem;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe", meta = (ClampMin = "1"))
|
|
int32 ResultQuantity = 1;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe")
|
|
ECraftingStation RequiredStation = ECraftingStation::Hands;
|
|
|
|
// Pas de duree de fabrication ici : le craft de menu est instantane, comme
|
|
// dans Valheim ou Raft. La fabrication qui prend du temps est celle des
|
|
// postes qui travaillent SANS le joueur, et ceux-la ne sont pas des recettes.
|
|
|
|
/**
|
|
* Nom affiche, quand celui du resultat ne suffit pas.
|
|
* Laisse vide dans l'immense majorite des cas : dupliquer le nom de l'objet
|
|
* dans la recette, c'est se garantir deux textes qui divergeront un jour.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe|Display")
|
|
FText DisplayNameOverride;
|
|
|
|
/** Icone affichee dans la grille de craft. Vide = celle du resultat. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Recipe|Display")
|
|
TObjectPtr<UTexture2D> IconOverride;
|
|
|
|
/** Le nom a afficher, override compris. Passe toujours par ici, jamais par ResultItem directement. */
|
|
UFUNCTION(BlueprintPure, Category = "Recipe")
|
|
FText GetDisplayName() const;
|
|
|
|
/** L'icone a afficher, override compris. */
|
|
UFUNCTION(BlueprintPure, Category = "Recipe")
|
|
UTexture2D* GetIcon() const;
|
|
|
|
#if WITH_EDITOR
|
|
/**
|
|
* Une recette sans resultat ne planterait pas : elle ne ferait simplement
|
|
* RIEN, en consommant les ingredients. C'est exactement le genre de bug qu'on
|
|
* cherche pendant une heure -- autant que l'editeur le refuse a la sauvegarde.
|
|
*/
|
|
virtual EDataValidationResult IsDataValid(class FDataValidationContext& Context) const override;
|
|
#endif
|
|
};
|