OLS/Source/ols/Private/Player/OLSPlayerState.cpp
2025-01-16 12:05:19 -07:00

143 lines
4.6 KiB
C++

// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
#include "Player/OLSPlayerState.h"
#include "AbilitySystem/OLSAbilitySystemComponent.h"
#include "AbilitySystem/Attributes/OLSCombatAttributeSet.h"
#include "AbilitySystem/Attributes/OLSHealthAttributeSet.h"
#include "Components/GameFrameworkComponentManager.h"
#include "DataAssets/OLSAbilitySetDataAsset.h"
#include "GameModes/OLSExperienceManagerComponent.h"
#include "GameModes/OLSGameMode.h"
#include "Net/UnrealNetwork.h"
#include "Player/OLSPlayerController.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(OLSPlayerState)
const FName AOLSPlayerState::NAME_OLSAbilityReady("OLSAbilitiesReady");
AOLSPlayerState::AOLSPlayerState(const FObjectInitializer& objectInitializer) : Super(objectInitializer)
{
// Create attribute sets here.
AbilitySystemComponent = objectInitializer.CreateDefaultSubobject<UOLSAbilitySystemComponent>(this, TEXT("AbilitySystemComponent"));
AbilitySystemComponent->SetIsReplicated(true);
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
// These attribute sets will be detected by AbilitySystemComponent::InitializeComponent. Keeping a reference so that the sets don't get garbage collected before that.
HealthSet = CreateDefaultSubobject<UOLSHealthAttributeSet>(TEXT("HealthSet"));
CombatSet = CreateDefaultSubobject<UOLSCombatAttributeSet>(TEXT("CombatSet"));
// AbilitySystemComponent needs to be updated at a high frequency.
SetNetUpdateFrequency(100.0f);
}
void AOLSPlayerState::SetPawnData(const UOLSPawnDataAsset* pawnData)
{
check(pawnData);
if (!HasAuthority())
{
return;
}
if (PawnData)
{
// @Todo: replace this by our custom log.
// UE_LOG(LogLyra, Error, TEXT("Trying to set PawnData [%s] on player state [%s] that already has valid PawnData [%s]."), *GetNameSafe(InPawnData), *GetNameSafe(this), *GetNameSafe(PawnData));
return;
}
MARK_PROPERTY_DIRTY_FROM_NAME(ThisClass, PawnData, this);
for (const UOLSAbilitySetDataAsset* abilityDataAsset : PawnData->AbilitySets)
{
if (abilityDataAsset)
{
abilityDataAsset->GiveToAbilitySystem(AbilitySystemComponent, nullptr);
}
}
UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, NAME_OLSAbilityReady);
ForceNetUpdate();
}
void AOLSPlayerState::AddStatTagStack(FGameplayTag tag, int32 stackCount)
{
StatTags.AddStack(tag, stackCount);
}
void AOLSPlayerState::RemoveStatTagStack(FGameplayTag tag, int32 stackCount)
{
StatTags.RemoveStack(tag, stackCount);
}
int32 AOLSPlayerState::GetStatTagStackCount(FGameplayTag tag) const
{
return StatTags.GetStackCount(tag);
}
bool AOLSPlayerState::HasStatTag(FGameplayTag tag) const
{
return StatTags.ContainsTag(tag);
}
void AOLSPlayerState::OnExperienceLoaded(const UOLSExperienceDefinitionDataAsset* currentExperience)
{
if (AOLSGameMode* gameMode = GetWorld()->GetAuthGameMode<AOLSGameMode>())
{
if (const UOLSPawnDataAsset* newPawnData = gameMode->GetPawnDataForController(GetOwningController()))
{
SetPawnData(newPawnData);
}
else
{
// @T ODO: Replace this with our custom.
// UE_LOG(LogLyra, Error, TEXT("ALyraPlayerState::OnExperienceLoaded(): Unable to find PawnData to initialize player state [%s]!"), *GetNameSafe(this));
}
}
}
void AOLSPlayerState::OnRep_PawnData()
{
}
void AOLSPlayerState::PostInitializeComponents()
{
Super::PostInitializeComponents();
check(AbilitySystemComponent);
AbilitySystemComponent->InitAbilityActorInfo(this, GetPawn());
const TObjectPtr<UWorld> world = GetWorld();
if (world && world->IsGameWorld() && world->GetNetMode() != NM_Client)
{
const TObjectPtr<AGameStateBase> gameState = GetWorld()->GetGameState();
check(gameState);
UOLSExperienceManagerComponent* ExperienceComponent = gameState->FindComponentByClass<UOLSExperienceManagerComponent>();
check(ExperienceComponent);
ExperienceComponent->CallOrRegister_OnExperienceLoaded(FOLSExperienceLoadedNativeDelegate::FDelegate::CreateUObject(this, &ThisClass::OnExperienceLoaded));
}
}
void AOLSPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
FDoRepLifetimeParams SharedParams;
SharedParams.bIsPushBased = true;
DOREPLIFETIME_WITH_PARAMS_FAST(ThisClass, PawnData, SharedParams);
}
AOLSPlayerController* AOLSPlayerState::GetOLSPlayerController() const
{
return Cast<AOLSPlayerController>(GetOwner());
}
UOLSAbilitySystemComponent* AOLSPlayerState::GetOLSAbilitySystemComponent() const
{
return AbilitySystemComponent;
}