UE5 GAS nodes BP ("Get Ability System Component", "Apply Gameplay Effect To
Target", etc.) precisam que o PlayerState exponha o ASC via
IAbilitySystemInterface. Pattern Lyra: PlayerState dona a interface; ASC vive
como subobject do UZeusGASComponent (Component Registry).
Tres acessos:
- GetAbilitySystemComponent (interface, retorna base UAbilitySystemComponent)
- GetZeusAbilitySystemComponent (BlueprintPure, retorna UZeusAbilitySystemComponent
custom com 12 overrides ZeusNetwork)
- GetZeusAttributeSet (BlueprintPure, helper pro AttributeSet tipado)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
134 lines
4.1 KiB
C++
134 lines
4.1 KiB
C++
#include "ZeusPlayerState.h"
|
|
|
|
#include "AbilitySystemComponent.h"
|
|
#include "Components/ActorComponent.h"
|
|
#include "Misc/ConfigCacheIni.h"
|
|
#include "Net/UnrealNetwork.h"
|
|
#include "ZMMO.h"
|
|
#include "ZeusAbilitySystemComponent.h"
|
|
#include "ZeusAttributeSet.h"
|
|
#include "ZeusGASComponent.h"
|
|
|
|
AZeusPlayerState::AZeusPlayerState()
|
|
{
|
|
// Component Registry: instancia cada classe declarada em
|
|
// DefaultGame.ini::[/Script/ZMMO.ZeusPlayerState]+ComponentClasses=...
|
|
//
|
|
// Le manualmente via GConfig para evitar timing do UPROPERTY(Config),
|
|
// que requer LoadConfig() ja ter rodado no CDO antes da instance ser
|
|
// construida. Pra propriedades em arrays config com `+` syntax, lendo
|
|
// direto e mais previsivel.
|
|
if (ComponentClasses.Num() == 0 && GConfig)
|
|
{
|
|
TArray<FString> ClassPaths;
|
|
GConfig->GetArray(TEXT("/Script/ZMMO.ZeusPlayerState"),
|
|
TEXT("ComponentClasses"),
|
|
ClassPaths,
|
|
GGameIni);
|
|
for (const FString& Path : ClassPaths)
|
|
{
|
|
if (UClass* C = LoadClass<UActorComponent>(nullptr, *Path))
|
|
{
|
|
ComponentClasses.Add(C);
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogZMMO, Warning,
|
|
TEXT("ZeusPlayerState: ComponentClasses path nao resolveu: %s"), *Path);
|
|
}
|
|
}
|
|
}
|
|
|
|
UE_LOG(LogZMMO, Log,
|
|
TEXT("AZeusPlayerState ctor: %d componente(s) no registry (instance=%s)"),
|
|
ComponentClasses.Num(), *GetName());
|
|
|
|
int32 SubobjectIndex = 0;
|
|
for (const TSubclassOf<UActorComponent>& CompClassRef : ComponentClasses)
|
|
{
|
|
UClass* CompClass = CompClassRef.Get();
|
|
if (!CompClass)
|
|
{
|
|
UE_LOG(LogZMMO, Warning,
|
|
TEXT("ZeusPlayerState: ComponentClass null em ComponentClasses[%d]"),
|
|
SubobjectIndex);
|
|
++SubobjectIndex;
|
|
continue;
|
|
}
|
|
const FName CompName = MakeUniqueObjectName(this, CompClass,
|
|
FName(*FString::Printf(TEXT("ZeusComp_%d_%s"), SubobjectIndex, *CompClass->GetName())));
|
|
// Overload runtime de CreateDefaultSubobject retorna UObject* (sem template) —
|
|
// precisa cast para UActorComponent.
|
|
UActorComponent* Comp = Cast<UActorComponent>(CreateDefaultSubobject(CompName, CompClass, CompClass,
|
|
/*bIsRequired*/ false, /*bIsTransient*/ false));
|
|
if (Comp)
|
|
{
|
|
UE_LOG(LogZMMO, Log,
|
|
TEXT("ZeusPlayerState: componente registrado [%d] %s"),
|
|
SubobjectIndex, *CompClass->GetName());
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogZMMO, Warning,
|
|
TEXT("ZeusPlayerState: CreateDefaultSubobject falhou para %s"),
|
|
*CompClass->GetName());
|
|
}
|
|
++SubobjectIndex;
|
|
}
|
|
}
|
|
|
|
void AZeusPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
|
{
|
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
|
DOREPLIFETIME(AZeusPlayerState, ZeusEntityId);
|
|
DOREPLIFETIME(AZeusPlayerState, CharId);
|
|
DOREPLIFETIME(AZeusPlayerState, CharName);
|
|
DOREPLIFETIME(AZeusPlayerState, BaseLevel);
|
|
DOREPLIFETIME(AZeusPlayerState, ClassId);
|
|
DOREPLIFETIME(AZeusPlayerState, GuildName);
|
|
}
|
|
|
|
void AZeusPlayerState::SetPublicIdentity(int64 InEntityId, const FString& InCharId,
|
|
int32 InBaseLevel, int32 InClassId)
|
|
{
|
|
ZeusEntityId = InEntityId;
|
|
CharId = InCharId;
|
|
BaseLevel = InBaseLevel;
|
|
ClassId = InClassId;
|
|
}
|
|
|
|
void AZeusPlayerState::SetCharInfo(const FString& InCharName, const FString& InGuildName)
|
|
{
|
|
CharName = InCharName;
|
|
GuildName = InGuildName;
|
|
}
|
|
|
|
UAbilitySystemComponent* AZeusPlayerState::GetAbilitySystemComponent() const
|
|
{
|
|
// ASC vive como subobject do UZeusGASComponent (que esta no Component
|
|
// Registry). UE5 GAS nodes BP ("Get Ability System Component", "Apply
|
|
// Gameplay Effect To Target", etc.) chamam isto via IAbilitySystemInterface.
|
|
// O retorno e o ponteiro upcastado pra UAbilitySystemComponent (base) —
|
|
// mas em runtime e' UZeusAbilitySystemComponent (cast tipado via
|
|
// GetZeusAbilitySystemComponent abaixo).
|
|
return GetZeusAbilitySystemComponent();
|
|
}
|
|
|
|
UZeusAbilitySystemComponent* AZeusPlayerState::GetZeusAbilitySystemComponent() const
|
|
{
|
|
if (UZeusGASComponent* GAS = GetZeusComponent<UZeusGASComponent>())
|
|
{
|
|
return GAS->AbilitySystemComponent.Get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
UZeusAttributeSet* AZeusPlayerState::GetZeusAttributeSet() const
|
|
{
|
|
if (UZeusGASComponent* GAS = GetZeusComponent<UZeusGASComponent>())
|
|
{
|
|
return GAS->AttributeSet.Get();
|
|
}
|
|
return nullptr;
|
|
}
|