// Copyright (c) 2026 Reignance Studios. MIT License, see LICENSE. #include "GKLPlayerState.h" #include "AbilitySystemComponent.h" #include "Abilities/GKLSampleAbilities.h" #include "GKLAttributeSet.h" #include "GKLGameplayTags.h" #include "Misc/EngineVersionComparison.h" AGKLPlayerState::AGKLPlayerState(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { AbilitySystemComponent = CreateDefaultSubobject(TEXT("AbilitySystemComponent")); AbilitySystemComponent->SetIsReplicated(true); AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed); // Created as a subobject of the ASC's owner, so the ASC finds and replicates it. AttributeSet = CreateDefaultSubobject(TEXT("AttributeSet")); #if UE_VERSION_NEWER_THAN(5, 4, 99) SetNetUpdateFrequency(100.f); #else NetUpdateFrequency = 100.f; #endif StartupAbilities = { UGKLAbility_Jump::StaticClass(), UGKLAbility_Heal::StaticClass(), UGKLAbility_Strike::StaticClass(), UGKLAbility_Regen::StaticClass(), UGKLAbility_Death::StaticClass() }; } UAbilitySystemComponent* AGKLPlayerState::GetAbilitySystemComponent() const { return AbilitySystemComponent; } void AGKLPlayerState::BeginPlay() { Super::BeginPlay(); if (!HasAuthority() || bStartupAbilitiesGranted) { return; } for (const TSubclassOf& Ability : StartupAbilities) { if (Ability) { AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(Ability, 1, INDEX_NONE, this)); } } bStartupAbilitiesGranted = true; } void AGKLPlayerState::ResetForRespawn() { if (!HasAuthority()) { return; } GKLTags::RemoveReplicatedLooseTag(AbilitySystemComponent, GKLTags::State_Dead); AttributeSet->ResetToMax(); // Death cancelled the passives; State.Dead is gone now, so they can start again. FGameplayTagContainer Passives; Passives.AddTag(GKLTags::Ability_Passive); AbilitySystemComponent->TryActivateAbilitiesByTag(Passives); }