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/AgrarianWildlifeBase.h
T
2026-05-19 12:33:01 -07:00

190 lines
7.4 KiB
C++

// Copyright Pacificao. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "AgrarianInteractable.h"
#include "AgrarianTypes.h"
#include "AgrarianWildlifeBase.generated.h"
class AAgrarianGameCharacter;
class UAudioComponent;
class USoundBase;
class UStaticMeshComponent;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAgrarianWildlifeStateChangedSignature, EAgrarianWildlifeState, NewState);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FAgrarianWildlifeHealthChangedSignature, float, Health, float, MaxHealth);
UCLASS(Blueprintable)
class AAgrarianWildlifeBase : public ACharacter, public IAgrarianInteractable
{
GENERATED_BODY()
public:
AAgrarianWildlifeBase();
virtual void Tick(float DeltaSeconds) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(BlueprintAssignable, Category = "Agrarian|Wildlife")
FAgrarianWildlifeStateChangedSignature OnWildlifeStateChanged;
UPROPERTY(BlueprintAssignable, Category = "Agrarian|Wildlife")
FAgrarianWildlifeHealthChangedSignature OnWildlifeHealthChanged;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Wildlife|Visuals")
TObjectPtr<UStaticMeshComponent> WildlifeBodyProxy;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Wildlife|Visuals")
TObjectPtr<UStaticMeshComponent> WildlifeHeadProxy;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Wildlife|Visuals")
TObjectPtr<UStaticMeshComponent> WildlifeEarProxyA;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Wildlife|Visuals")
TObjectPtr<UStaticMeshComponent> WildlifeEarProxyB;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Wildlife|Visuals")
TObjectPtr<UStaticMeshComponent> WildlifeTailProxy;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Wildlife|Audio")
TObjectPtr<UAudioComponent> WildlifeAudioComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife")
FName WildlifeId = TEXT("wildlife");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife")
FText DisplayName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife")
EAgrarianWildlifeDisposition Disposition = EAgrarianWildlifeDisposition::Passive;
UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing = OnRep_WildlifeState, Category = "Agrarian|Wildlife")
EAgrarianWildlifeState WildlifeState = EAgrarianWildlifeState::Idle;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife", meta = (ClampMin = "1"))
float MaxHealth = 25.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing = OnRep_Health, Category = "Agrarian|Wildlife", meta = (ClampMin = "0"))
float Health = 25.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "0"))
float WanderRadius = 1200.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "0"))
float WanderSpeed = 180.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "0"))
float FleeSpeed = 420.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "0"))
float AggroRadius = 650.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "0"))
float FleeRadius = 700.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "0.1"))
float DecisionIntervalSeconds = 2.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement")
bool bUseNavigationMovement = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "1"))
float NavigationAcceptanceRadius = 85.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement", meta = (ClampMin = "1"))
float NavigationRepathDistance = 175.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement")
FVector NavigationProjectionExtent = FVector(500.0f, 500.0f, 900.0f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Performance")
bool bEnablePerformanceLimits = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Performance", meta = (ClampMin = "0"))
float FullUpdateRadius = 6500.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Performance", meta = (ClampMin = "0.1"))
float FarUpdateIntervalSeconds = 2.5f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Harvest")
TArray<FAgrarianItemStack> HarvestYields;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "Agrarian|Wildlife|Harvest")
bool bHarvested = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Audio")
TObjectPtr<USoundBase> IdleWildlifeSound;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Audio")
TObjectPtr<USoundBase> FleeWildlifeSound;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Audio")
TObjectPtr<USoundBase> DeathWildlifeSound;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Audio")
TObjectPtr<USoundBase> HarvestWildlifeSound;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Wildlife")
bool IsAlive() const;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Wildlife")
void ApplyWildlifeDamage(float Amount, AActor* InstigatorActor);
UFUNCTION(BlueprintCallable, Category = "Agrarian|Wildlife")
void SetWildlifeState(EAgrarianWildlifeState NewState);
virtual FText GetInteractionText_Implementation(const AAgrarianGameCharacter* Interactor) const override;
virtual bool CanInteract_Implementation(const AAgrarianGameCharacter* Interactor) const override;
virtual void Interact_Implementation(AAgrarianGameCharacter* Interactor) override;
protected:
virtual void BeginPlay() override;
UFUNCTION()
void OnRep_Health();
UFUNCTION()
void OnRep_WildlifeState();
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayWildlifeStateSound(EAgrarianWildlifeState NewState);
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayWildlifeHarvestSound();
bool ShouldRunServerThink(float DeltaSeconds);
void ServerThink(float DeltaSeconds);
void ChooseWanderTarget();
void MoveTowardTarget();
bool ChooseReachableWanderTarget(FVector& OutTarget) const;
bool ProjectPointToNavigation(const FVector& CandidateLocation, FVector& OutProjectedLocation) const;
bool RequestNavigationMove(const FVector& TargetLocation);
void ClearNavigationMove();
void DirectMoveTowardLocation(const FVector& TargetLocation, float MovementSpeed);
void EnterDeadState();
AAgrarianGameCharacter* FindNearestPlayer(float Radius) const;
float GetNearestPlayerDistanceSquared() const;
bool Harvest(AAgrarianGameCharacter* Interactor);
void BroadcastHealthChanged();
void BroadcastStateChanged();
USoundBase* GetSoundForWildlifeState(EAgrarianWildlifeState State) const;
UPROPERTY()
FVector SpawnLocation = FVector::ZeroVector;
UPROPERTY()
FVector CurrentMoveTarget = FVector::ZeroVector;
UPROPERTY()
TObjectPtr<AActor> FocusActor;
UPROPERTY()
FVector LastNavigationMoveTarget = FVector::ZeroVector;
bool bHasNavigationMoveTarget = false;
float DecisionTimer = 0.0f;
float ServerThinkAccumulator = 0.0f;
};