145 lines
3.1 KiB
C++
145 lines
3.1 KiB
C++
// Copyright Pacificao. All Rights Reserved.
|
|
|
|
#include "AgrarianCraftingComponent.h"
|
|
#include "AgrarianInventoryComponent.h"
|
|
#include "AgrarianRecipeDataAsset.h"
|
|
|
|
UAgrarianCraftingComponent::UAgrarianCraftingComponent()
|
|
{
|
|
PrimaryComponentTick.bCanEverTick = false;
|
|
SetIsReplicatedByDefault(true);
|
|
}
|
|
|
|
bool UAgrarianCraftingComponent::CanCraft(FName RecipeId, FText& FailureReason) const
|
|
{
|
|
FAgrarianRecipe Recipe;
|
|
if (!FindRecipe(RecipeId, Recipe))
|
|
{
|
|
FailureReason = FText::FromString(TEXT("Recipe is not known."));
|
|
return false;
|
|
}
|
|
|
|
const UAgrarianInventoryComponent* Inventory = GetInventory();
|
|
if (!Inventory)
|
|
{
|
|
FailureReason = FText::FromString(TEXT("No inventory is available."));
|
|
return false;
|
|
}
|
|
|
|
for (const FAgrarianItemStack& Ingredient : Recipe.Ingredients)
|
|
{
|
|
if (!Inventory->HasItem(Ingredient.ItemId, Ingredient.Quantity))
|
|
{
|
|
FailureReason = FText::Format(
|
|
FText::FromString(TEXT("Missing ingredient: {0}")),
|
|
Ingredient.DisplayName.IsEmpty() ? FText::FromName(Ingredient.ItemId) : Ingredient.DisplayName);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool UAgrarianCraftingComponent::Craft(FName RecipeId)
|
|
{
|
|
if (!GetOwner())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!GetOwner()->HasAuthority())
|
|
{
|
|
ServerCraft(RecipeId);
|
|
return true;
|
|
}
|
|
|
|
FText FailureReason;
|
|
if (!CanCraft(RecipeId, FailureReason))
|
|
{
|
|
FailCraft(RecipeId, FailureReason);
|
|
return false;
|
|
}
|
|
|
|
FAgrarianRecipe Recipe;
|
|
FindRecipe(RecipeId, Recipe);
|
|
|
|
UAgrarianInventoryComponent* Inventory = GetInventory();
|
|
if (!Inventory)
|
|
{
|
|
FailCraft(RecipeId, FText::FromString(TEXT("No inventory is available.")));
|
|
return false;
|
|
}
|
|
|
|
for (const FAgrarianItemStack& Ingredient : Recipe.Ingredients)
|
|
{
|
|
Inventory->RemoveItem(Ingredient.ItemId, Ingredient.Quantity);
|
|
}
|
|
|
|
if (!Inventory->AddItem(Recipe.Result))
|
|
{
|
|
FailCraft(RecipeId, FText::FromString(TEXT("Inventory is full.")));
|
|
return false;
|
|
}
|
|
|
|
OnCraftCompleted.Broadcast(Recipe.RecipeId, Recipe.Result);
|
|
return true;
|
|
}
|
|
|
|
void UAgrarianCraftingComponent::ServerCraft_Implementation(FName RecipeId)
|
|
{
|
|
Craft(RecipeId);
|
|
}
|
|
|
|
bool UAgrarianCraftingComponent::AddKnownRecipe(const FAgrarianRecipe& Recipe)
|
|
{
|
|
if (Recipe.RecipeId == NAME_None || !Recipe.Result.IsValidStack())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (FAgrarianRecipe& Existing : KnownRecipes)
|
|
{
|
|
if (Existing.RecipeId == Recipe.RecipeId)
|
|
{
|
|
Existing = Recipe;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
KnownRecipes.Add(Recipe);
|
|
return true;
|
|
}
|
|
|
|
bool UAgrarianCraftingComponent::FindRecipe(FName RecipeId, FAgrarianRecipe& OutRecipe) const
|
|
{
|
|
for (const UAgrarianRecipeDataAsset* RecipeAsset : KnownRecipeAssets)
|
|
{
|
|
if (RecipeAsset && RecipeAsset->Recipe.RecipeId == RecipeId)
|
|
{
|
|
OutRecipe = RecipeAsset->Recipe;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
for (const FAgrarianRecipe& Recipe : KnownRecipes)
|
|
{
|
|
if (Recipe.RecipeId == RecipeId)
|
|
{
|
|
OutRecipe = Recipe;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
UAgrarianInventoryComponent* UAgrarianCraftingComponent::GetInventory() const
|
|
{
|
|
return GetOwner() ? GetOwner()->FindComponentByClass<UAgrarianInventoryComponent>() : nullptr;
|
|
}
|
|
|
|
void UAgrarianCraftingComponent::FailCraft(FName RecipeId, const FText& Reason)
|
|
{
|
|
OnCraftFailed.Broadcast(RecipeId, Reason);
|
|
}
|