// Copyright Pacificao. All Rights Reserved. #include "AgrarianCraftingComponent.h" #include "AgrarianInventoryComponent.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 FAgrarianRecipe& Recipe : KnownRecipes) { if (Recipe.RecipeId == RecipeId) { OutRecipe = Recipe; return true; } } return false; } UAgrarianInventoryComponent* UAgrarianCraftingComponent::GetInventory() const { return GetOwner() ? GetOwner()->FindComponentByClass() : nullptr; } void UAgrarianCraftingComponent::FailCraft(FName RecipeId, const FText& Reason) const { OnCraftFailed.Broadcast(RecipeId, Reason); }