This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2026-05-17 17:57:17 -07:00

166 lines
3.6 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;
}
void UAgrarianCraftingComponent::GetKnownRecipes(TArray<FAgrarianRecipe>& OutRecipes) const
{
OutRecipes.Reset();
for (const UAgrarianRecipeDataAsset* RecipeAsset : KnownRecipeAssets)
{
if (RecipeAsset && RecipeAsset->Recipe.RecipeId != NAME_None)
{
OutRecipes.Add(RecipeAsset->Recipe);
}
}
for (const FAgrarianRecipe& Recipe : KnownRecipes)
{
if (Recipe.RecipeId != NAME_None)
{
OutRecipes.Add(Recipe);
}
}
}
UAgrarianInventoryComponent* UAgrarianCraftingComponent::GetInventory() const
{
return GetOwner() ? GetOwner()->FindComponentByClass<UAgrarianInventoryComponent>() : nullptr;
}
void UAgrarianCraftingComponent::FailCraft(FName RecipeId, const FText& Reason)
{
OnCraftFailed.Broadcast(RecipeId, Reason);
}