#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TTHarvestable.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnHaveBeenHarvest);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnResourceDepleted);
UCLASS(ClassGroup = (Edible), meta = (BlueprintSpawnableComponent))
class GP2_TEAM3_API UTTHarvestable : public UActorComponent
{
GENERATED_BODY()
protected:
virtual void BeginPlay() override;
public:
UFUNCTION(BlueprintCallable, Category = "Harvestabke")
AActor* Harvest();
UPROPERTY(EditAnywhere, BlueprintReadOnly ,Category = "Harvestable")
int32 StartAmount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Harvestable")
int32 CurrentAmount = 0;
UPROPERTY(BlueprintAssignable, Category = "Harvestable")
FOnHaveBeenHarvest OnBeenHarvested;
UPROPERTY(BlueprintAssignable, Category = "Harvestable")
FOnResourceDepleted OnResourceDepleted;
UPROPERTY(EditAnywhere, Category = "Harvestable")
float HarvestDuration = 1;
UPROPERTY(EditAnywhere, Category = "Harvestable")
TSubclassOf<AActor> Resource;
UFUNCTION(BlueprintCallable ,Category = Harvestable)
bool IsAvailableForHarvest();
UFUNCTION(BlueprintCallable, Category = Harvestable)
void UpdateProgression(float deltaTime);
private:
float progression;
};
#include "TTHarvestable.h"
#include "Engine/World.h"
#include "GameFramework/Actor.h"
void UTTHarvestable::BeginPlay()
{
Super::BeginPlay();
CurrentAmount = StartAmount;
}
AActor* UTTHarvestable::Harvest()
{
if(!IsAvailableForHarvest() || CurrentAmount <= 0) return nullptr;
progression = 0;
CurrentAmount--;
OnBeenHarvested.Broadcast();
if (CurrentAmount == 0)
{
OnResourceDepleted.Broadcast();
}
AActor* resource = GetWorld()->SpawnActor(Resource);
return resource;
}
bool UTTHarvestable::IsAvailableForHarvest()
{
return progression >= HarvestDuration && CurrentAmount > 0;
}
void UTTHarvestable::UpdateProgression(float deltaTime)
{
progression += deltaTime;
}
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Map.h"
#include "TTCrafterComponent.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDoneCrafting);
USTRUCT(BlueprintType)
struct FIngredientPair
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Crafter")
FName DispayName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Crafter")
TSubclassOf<AActor> Ingredient;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Crafter")
int Amount;
};
USTRUCT(BlueprintType)
struct FRecipe
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Crafter")
TArray<FName> Name;
bool IsthisMyName(FName name)
{
if(Name.Contains(name)) return true;
return false;
}
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Crafter")
TArray<FIngredientPair> Ingridients;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Crafter")
TSubclassOf<AActor> CraftIntoThisObject;
UPROPERTY()
bool DoesThisCombine = false;
};
UCLASS(ClassGroup = (Crafter), meta = (BlueprintSpawnableComponent))
class GP2_TEAM3_API UTTCrafterComponent : public UActorComponent
{
GENERATED_BODY()
protected:
//virtual void BeginPlay() override;
public:
virtual void BeginPlay() override;
void AddNameToCommandSystem();
UFUNCTION(BlueprintCallable, Category = "Crafter")
TSubclassOf<AActor> CraftByInventory(class UTTInventoryComponent* inventory);
UFUNCTION(BlueprintCallable, Category = "Crafter")
TSubclassOf<AActor> CraftByName(class UTTInventoryComponent* inventory, FName RecipeName, bool consumeItems);
UFUNCTION(BlueprintCallable, Category = "Crafter")
TArray<FIngredientPair> WhatAmIMissing(UTTInventoryComponent* inventory, FName RecipeName);
UPROPERTY(BlueprintAssignable, Category = "Crafter")
FOnDoneCrafting OnDoneCrafting;
UPROPERTY(EditAnywhere, Category = "Crafter")
TArray<FRecipe> Recipes;
int32 NumberOfIngredient(TArray<class UTTStoreableComponent*> listOfIngerdients, TSubclassOf<AActor> Ingredient);
};
#include "TTCrafterComponent.h"
#include "Engine/World.h"
#include "Map.h"
#include "CommandSystem/TTGameMode.h"
#include "CommandSystem/TTCommandSystem.h"
#include "../Equipment/TTStoreableComponent.h"
#include "../Interaction/TTInventoryComponent.h"
#include "SubclassOf.h"
void UTTCrafterComponent::BeginPlay()
{
Super::BeginPlay();
AddNameToCommandSystem();
}
void UTTCrafterComponent::AddNameToCommandSystem()
{
ATTGameMode* correctGameMode = Cast<ATTGameMode>(GetWorld()->GetAuthGameMode());
if (correctGameMode)
{
for (int i = 0; i < Recipes.Num(); i++)
{
for (int k = 0; k < Recipes[i].Name.Num(); k++)
{
correctGameMode->AddExtraWord(Recipes[i].Name[k].ToString());
}
}
}
else
UE_LOG(LogTemp, Warning, TEXT("Using Wrong GameMode!"));
}
TSubclassOf<AActor> UTTCrafterComponent::CraftByInventory(UTTInventoryComponent* inventory)
{
for (FRecipe recipe : Recipes)
{
if(recipe.Ingridients.Num() != inventory->GetInventorySize())
continue;
TArray<FIngredientPair> stuffINeed = WhatAmIMissing(inventory, recipe.Name[0]);
if(stuffINeed.Num() == 0)
return recipe.CraftIntoThisObject;
}
return nullptr;
}
TSubclassOf<AActor> UTTCrafterComponent::CraftByName(UTTInventoryComponent* inventory, FName RecipeName, bool consumeItems)
{
FRecipe theRecipe;
TArray<UTTStoreableComponent*> craftingMaterials = inventory->GetInventoryArray();
TArray<UTTStoreableComponent*> materialToRemove;
bool hasFoundStuff = false;;
for (FRecipe recipe : Recipes)
{
if (recipe.Name.Contains(RecipeName))
{
theRecipe = recipe;
hasFoundStuff = true;
break;
}
}
if(!hasFoundStuff)
return nullptr;
TMap<UClass*, int> materialCompletion;
for (FIngredientPair ingredient : theRecipe.Ingridients)
{
materialCompletion.Add(ingredient.Ingredient->GetDefaultObject()->GetClass(), ingredient.Amount);
}
for (UTTStoreableComponent* craftingMaterial : craftingMaterials)
{
if(craftingMaterial == nullptr || !materialCompletion.Contains(craftingMaterial->GetOwner()->GetClass()) || materialCompletion[craftingMaterial->GetOwner()->GetClass()] <= 0) continue;
materialCompletion[craftingMaterial->GetOwner()->GetClass()]--;
materialToRemove.Add(craftingMaterial);
}
for (TPair<UClass*, int> ingidientPair : materialCompletion)
{
if(ingidientPair.Value > 0) return nullptr;
}
if(!consumeItems) return theRecipe.CraftIntoThisObject;
for (UTTStoreableComponent* usedMaterial : materialToRemove)
{
inventory->RemoveItemFromInventory(usedMaterial);
}
return theRecipe.CraftIntoThisObject;
}
TArray<FIngredientPair&g; UTTCrafterComponent::WhatAmIMissing(UTTInventoryComponent* inventory, FName RecipeName)
{
TArray<FIngredientPair> missingIngredients;
FRecipe theRecipe;
TArray<UTTStoreableComponent*> craftingMaterials = inventory->GetInventoryArray();
bool hasFoundStuff = false;;
for (FRecipe recipe : Recipes)
{
if (recipe.Name.Contains(RecipeName))
{
theRecipe = recipe;
hasFoundStuff = true;
break;
}
}
if (!hasFoundStuff)
return missingIngredients;
TMap<UClass*, FIngredientPair> materialCompletion;
for (FIngredientPair ingredient : theRecipe.Ingridients)
{
materialCompletion.Add(ingredient.Ingredient->GetDefaultObject()->GetClass(), ingredient);
}
for (UTTStoreableComponent* craftingMaterial : craftingMaterials)
{
if (craftingMaterial == nullptr || !materialCompletion.Contains(craftingMaterial->GetOwner()->GetClass()) || materialCompletion[craftingMaterial->GetOwner()->GetClass()].Amount <= 0) continue;
materialCompletion[craftingMaterial->GetOwner()->GetClass()].Amount--;
}
for (TPair<UClass*, FIngredientPair>> ingidientPair : materialCompletion)
{
if (ingidientPair.Value.Amount > 0)
{
TSubclassOf<AActor> storable = ingidientPair.Key;
FIngredientPair pair;
pair.Ingredient = storable;
pair.Amount = ingidientPair.Value.Amount;
pair.DispayName = ingidientPair.Value.DispayName;
missingIngredients.Add(pair);
}
}
return missingIngredients;
}
int32 UTTCrafterComponent::NumberOfIngredient(TArray<UTTStoreableComponent*> listOfIngerdients, TSubclassOf<AActor> Ingredient)
{
int stuff = 0;
for (int i = 0; i < listOfIngerdients.Num(); i++)
{
if (listOfIngerdients[i]->GetOwner()->IsA(Ingredient->GetDefaultObject()->GetClass()))
{
stuff++;
}
}
return stuff;
}