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
AgrarianGameArchive/Source/AgrarianGame/AgrarianResourceNode.cpp
T
2026-05-17 16:49:52 -07:00

167 lines
4.1 KiB
C++

// Copyright Pacificao. All Rights Reserved.
#include "AgrarianResourceNode.h"
#include "AgrarianGameCharacter.h"
#include "AgrarianInventoryComponent.h"
#include "AgrarianItemDefinitionAsset.h"
#include "Components/StaticMeshComponent.h"
#include "TimerManager.h"
#include "Net/UnrealNetwork.h"
AAgrarianResourceNode::AAgrarianResourceNode()
{
bReplicates = true;
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
RootComponent = Mesh;
Mesh->SetCollisionProfileName(TEXT("BlockAll"));
YieldItem.ItemId = TEXT("wood");
YieldItem.DisplayName = FText::FromString(TEXT("Wood"));
YieldItem.Quantity = 1;
YieldItem.UnitWeight = 1.0f;
}
void AAgrarianResourceNode::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority())
{
MaxHarvests = FMath::Max(1, MaxHarvests);
if (RemainingHarvests > MaxHarvests)
{
MaxHarvests = RemainingHarvests;
}
}
UpdateDepletedState();
ScheduleRespawnIfNeeded();
}
void AAgrarianResourceNode::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AAgrarianResourceNode, RemainingHarvests);
}
FText AAgrarianResourceNode::GetInteractionText_Implementation(const AAgrarianGameCharacter* Interactor) const
{
if (RemainingHarvests <= 0)
{
return FText::FromString(TEXT("Depleted"));
}
if (RequiredToolItemId != NAME_None && !HasRequiredTool(Interactor) && bAllowBareHandGathering)
{
return FText::FromString(TEXT("Gather by hand"));
}
return FText::FromString(TEXT("Gather"));
}
bool AAgrarianResourceNode::CanInteract_Implementation(const AAgrarianGameCharacter* Interactor) const
{
if (RemainingHarvests <= 0 || !Interactor)
{
return false;
}
return RequiredToolItemId == NAME_None || bAllowBareHandGathering || HasRequiredTool(Interactor);
}
void AAgrarianResourceNode::Interact_Implementation(AAgrarianGameCharacter* Interactor)
{
if (!HasAuthority() || !Interactor || RemainingHarvests <= 0)
{
return;
}
if (UAgrarianInventoryComponent* Inventory = Interactor->GetInventoryComponent())
{
const FAgrarianItemStack Granted = MakeYieldStack(Interactor);
if (Inventory->AddItem(Granted))
{
RemainingHarvests--;
UpdateDepletedState();
ScheduleRespawnIfNeeded();
}
}
}
void AAgrarianResourceNode::OnRep_RemainingHarvests()
{
UpdateDepletedState();
}
bool AAgrarianResourceNode::HasRequiredTool(const AAgrarianGameCharacter* Interactor) const
{
if (RequiredToolItemId == NAME_None)
{
return true;
}
const UAgrarianInventoryComponent* Inventory = Interactor ? Interactor->GetInventoryComponent() : nullptr;
return Inventory && Inventory->HasItem(RequiredToolItemId, 1);
}
int32 AAgrarianResourceNode::GetHarvestQuantityFor(const AAgrarianGameCharacter* Interactor) const
{
const int32 ToolBonus = HasRequiredTool(Interactor) ? FMath::Max(0, ToolQuantityBonus) : 0;
return FMath::Max(1, QuantityPerHarvest + ToolBonus);
}
FAgrarianItemStack AAgrarianResourceNode::MakeYieldStack(const AAgrarianGameCharacter* Interactor) const
{
const int32 HarvestQuantity = GetHarvestQuantityFor(Interactor);
if (YieldItemDefinition)
{
return YieldItemDefinition->MakeStack(HarvestQuantity);
}
FAgrarianItemStack Granted = YieldItem;
Granted.Quantity = HarvestQuantity;
return Granted;
}
void AAgrarianResourceNode::UpdateDepletedState()
{
if (Mesh)
{
Mesh->SetVisibility(RemainingHarvests > 0, true);
Mesh->SetCollisionEnabled(RemainingHarvests > 0 ? ECollisionEnabled::QueryAndPhysics : ECollisionEnabled::NoCollision);
}
}
void AAgrarianResourceNode::ScheduleRespawnIfNeeded()
{
if (!HasAuthority() || !bRespawnsForMvp || RemainingHarvests > 0)
{
return;
}
UWorld* World = GetWorld();
if (!World || World->GetTimerManager().IsTimerActive(RespawnTimerHandle))
{
return;
}
World->GetTimerManager().SetTimer(
RespawnTimerHandle,
this,
&AAgrarianResourceNode::RespawnNode,
FMath::Max(1.0f, RespawnDelaySeconds),
false);
}
void AAgrarianResourceNode::RespawnNode()
{
if (!HasAuthority() || !bRespawnsForMvp)
{
return;
}
RemainingHarvests = FMath::Max(1, MaxHarvests);
UpdateDepletedState();
}