Files
MaybeThisTime/Source/MaybeThisTime/Public/ZoneActor.h
T
2026-08-15 13:52:59 +02:00

131 lines
3.8 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "InventoryInterface.h"
#include "OutlinerTypes.h"
#include "ZoneActor.generated.h"
class AModuleActor;
class UInventoryComponent;
class USphereComponent;
USTRUCT(BlueprintType)
struct FFactionInfluence
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite) FName FactionID;
UPROPERTY(EditAnywhere, BlueprintReadWrite) float Influence = 0.f;
};
UENUM(BlueprintType)
enum class EBuildPermission : uint8
{
Denied,
Allowed,
AllowedWithReputation
};
USTRUCT(BlueprintType)
struct FResourcePrice
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
FName ResourceID;
UPROPERTY(EditAnywhere)
float BasePrice = 1.f; // price per unit at neutral reputation
};
UCLASS()
class MAYBETHISTIME_API AZoneActor : public AActor, public IInventoryInterface
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AZoneActor();
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(Replicated, BlueprintReadOnly)
float ZoneAccount = 10000.f;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
bool bInfiniteZoneMoney = true; // for now
// --- Identity ---
UPROPERTY(ReplicatedUsing = OnRep_ZoneData, EditAnywhere, BlueprintReadOnly) FName ZoneID;
UPROPERTY(ReplicatedUsing = OnRep_ZoneData, EditAnywhere, BlueprintReadOnly) FText ZoneName;
UPROPERTY(ReplicatedUsing = OnRep_ZoneData, EditAnywhere, BlueprintReadOnly) FName OwningFaction;
UFUNCTION(BlueprintCallable, BlueprintPure) EOutlinerStatus GetOutlinerStatus() const;
// --- Geometry ---
UPROPERTY(ReplicatedUsing = OnRep_Radius, EditAnywhere, BlueprintReadOnly) float Radius = 2000.f; // unreal units
UPROPERTY(VisibleAnywhere, BlueprintReadOnly) USphereComponent* ZoneVolume;
// --- Modules ---
UPROPERTY(Replicated, BlueprintReadWrite) TArray<AModuleActor*> Modules;
// --- Storage ---
UPROPERTY(VisibleAnywhere, BlueprintReadOnly) UInventoryComponent* ZoneStorage;
// --- Influence ---
UPROPERTY(ReplicatedUsing = OnRep_ZoneData, BlueprintReadOnly) TArray<FFactionInfluence> FactionInfluences;
// --- Delegates ---
// Delegate for UI/AI to react to faction changes
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnZoneChanged, FName, ZoneID);
UPROPERTY(BlueprintAssignable) FOnZoneChanged OnZoneChanged;
// --- Module management ---
UFUNCTION(BlueprintCallable) bool CanFactionBuildHere(FName FactionID, float Reputation) const;
UFUNCTION(BlueprintCallable) void RegisterModule(AModuleActor* Module);
UFUNCTION(BlueprintCallable) void UnregisterModule(AModuleActor* Module);
UFUNCTION(BlueprintCallable) bool IsLocationInsideZone(FVector Location) const;
// --- Radius ---
UFUNCTION(BlueprintCallable) void SetRadius(float NewRadius);
// --- Ownership ---
UFUNCTION(BlueprintCallable) void SetOwningFaction(FName NewFaction);
UFUNCTION(BlueprintCallable) void ModifyInfluence(FName FactionID, float Delta);
FName GetDominantFaction() const;
// --- Tick (called by GameState) ---
void TickZone(float GameHoursDelta);
UPROPERTY(EditAnywhere, BlueprintReadOnly) TArray<FResourcePrice> ResourcePrices;
// Price scales with reputation - better standing = cheaper
float GetPriceForFaction(FName ResourceID, FName FactionID, float Reputation) const;
bool CanFactionUseResources(FName FactionID, float Reputation) const;
virtual UInventoryComponent* GetInventoryComponent_Implementation() const override;
private:
UFUNCTION()
void OnRep_ZoneData();
UFUNCTION()
void OnRep_Radius();
void UpdateVolumeSize();
void TickModuleProduction(float GameHoursDelta);
void TickZoneInfluence(float GameHoursDelta);
void SupplyUnitsInZone(float GameHoursDelta);
};