refactor: prefixo ZMMO -> Zeus em classes/módulos C++ do cliente

- Renomeia ~50 classes UCLASS/USTRUCT/UENUM/UINTERFACE pra Zeus*
  (AZeusGameMode, AZeusCharacter, UZeusGameInstance, IZeusEntityInterface,
  UZeusWorldSubsystem, FZeusEntitySnapshot, etc.)
- Encurta AZMMOPlayerCharacter -> AZeusCharacter
- Renomeia módulos satélite ZMMOAttributes -> ZeusAttributes e
  ZMMOJobs -> ZeusJobs (pasta + .Build.cs + .uproject)
- Mantém módulo principal ZMMO (renomeia depois quando jogo ganhar nome)
- DefaultEngine.ini: ActiveClassRedirects ZMMOX -> ZeusX (preserva BPs/assets)
- DefaultGame.ini: sections atualizadas pra ZeusThemeSubsystem/ZeusPlayerState
- Category="ZMMO|..." -> "Zeus|..." em UPROPERTYs
- Preserva LogZMMO, ZMMO_API, /Script/ZMMO., /Game/ZMMO/, classes Target

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 17:24:38 -03:00
parent bd1dab25ca
commit 6a6a28a086
128 changed files with 1224 additions and 1210 deletions

View File

@@ -0,0 +1,55 @@
#include "ZeusAttributeComponent.h"
#include "Engine/GameInstance.h"
#include "ZeusNetworkSubsystem.h"
UZeusAttributeComponent::UZeusAttributeComponent()
{
PrimaryComponentTick.bCanEverTick = false;
}
void UZeusAttributeComponent::ApplySnapshot(const FZeusAttributesSnapshot& InSnapshot)
{
const int32 OldHp = Current.Hp;
const int32 OldSp = Current.Sp;
Current = InSnapshot;
OnAttributesChanged.Broadcast(Current);
if (OldHp != Current.Hp || OldSp != Current.Sp)
{
OnHpSpChanged.Broadcast(Current.Hp, Current.Sp);
}
}
void UZeusAttributeComponent::ApplyHpSpUpdate(int32 NewHp, int32 NewSp)
{
if (Current.Hp == NewHp && Current.Sp == NewSp)
{
return;
}
Current.Hp = NewHp;
Current.Sp = NewSp;
OnHpSpChanged.Broadcast(Current.Hp, Current.Sp);
}
void UZeusAttributeComponent::NotifyLevelUp(int32 NewBaseLevel, int32 StatusPointDelta)
{
// O snapshot subsequente vai trazer todos os outros campos atualizados —
// aqui apenas dispara o delegate para efeitos visuais imediatos.
OnLevelUp.Broadcast(NewBaseLevel, StatusPointDelta);
}
void UZeusAttributeComponent::NotifyStatAllocReply(bool bAccepted, int32 Reason)
{
OnStatAllocReply.Broadcast(bAccepted, Reason);
}
void UZeusAttributeComponent::RequestStatAlloc(int32 StatId, int32 Amount)
{
UWorld* World = GetWorld();
if (!World) { return; }
UGameInstance* GI = World->GetGameInstance();
if (!GI) { return; }
UZeusNetworkSubsystem* Net = GI->GetSubsystem<UZeusNetworkSubsystem>();
if (!Net) { return; }
Net->SendStatAlloc(StatId, Amount);
}

View File

@@ -0,0 +1,218 @@
#include "ZeusAttributeNetworkHandler.h"
#include "Engine/GameInstance.h"
#include "Engine/World.h"
#include "GameFramework/GameStateBase.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/PlayerState.h"
#include "ZeusAttributeComponent.h"
#include "ZeusAttributeTypes.h"
#include "ZeusNetworkSubsystem.h"
namespace
{
// Helper privado — converte o payload binario do plugin pra USTRUCT
// Blueprint que o componente exibe.
FZeusAttributesSnapshot ToSnapshot(const FZeusAttributesPayload& P)
{
FZeusAttributesSnapshot S;
S.EntityId = P.EntityId;
S.ClassId = P.ClassId;
S.BaseLevel = P.BaseLevel;
S.BaseExp = P.BaseExp;
S.BaseExpToNext = P.BaseExpToNext;
S.JobLevel = P.JobLevel;
S.JobExp = P.JobExp;
S.JobExpToNext = P.JobExpToNext;
S.Str = P.Str;
S.Agi = P.Agi;
S.Vit = P.Vit;
S.Int = P.Int;
S.Dex = P.Dex;
S.Luk = P.Luk;
S.StatusPoint = P.StatusPoint;
S.SkillPoint = P.SkillPoint;
S.Hp = P.Hp;
S.MaxHp = P.MaxHp;
S.Sp = P.Sp;
S.MaxSp = P.MaxSp;
S.Money = P.Money;
S.AtkBase = P.AtkBase;
S.AtkEquipBonus = P.AtkEquipBonus;
S.MatkBaseMin = P.MatkBaseMin;
S.MatkBaseMax = P.MatkBaseMax;
S.MatkEquipBonus = P.MatkEquipBonus;
S.DefBase = P.DefBase;
S.DefEquipBonus = P.DefEquipBonus;
S.MdefBase = P.MdefBase;
S.MdefEquipBonus = P.MdefEquipBonus;
S.HitBase = P.HitBase;
S.HitEquipBonus = P.HitEquipBonus;
S.FleeBase = P.FleeBase;
S.FleeEquipBonus = P.FleeEquipBonus;
S.CritBaseX10 = P.CritBaseX10;
S.CritEquipBonusX10 = P.CritEquipBonusX10;
S.Aspd = P.Aspd;
return S;
}
// Resolve `EntityId -> UZeusAttributeComponent` via PlayerArray do GameState.
// AttributeComponent agora vive no PlayerState (vide AZeusPlayerState +
// Component Registry em DefaultGame.ini). Itera apenas players (1 por
// conexao), nao 1000+ atores — O(N_players).
//
// Cada UZeusAttributeComponent carrega seu proprio EntityId (seed em
// AZeusCharacter::HandleLocalSpawnReady ou no primeiro snapshot).
UZeusAttributeComponent* FindComponentForEntity(UWorld* World, int64 EntityId) // PR-HANDOFF-007 int64
{
if (!World || EntityId == 0) { return nullptr; }
const AGameStateBase* GS = World->GetGameState();
if (!GS) { return nullptr; }
for (APlayerState* PS : GS->PlayerArray)
{
if (!PS) { continue; }
UZeusAttributeComponent* Comp = PS->FindComponentByClass<UZeusAttributeComponent>();
if (!Comp) { continue; }
if (Comp->GetSnapshot().EntityId == EntityId)
{
return Comp;
}
}
return nullptr;
}
}
bool UZeusAttributeNetworkHandler::ShouldCreateSubsystem(UObject* Outer) const
{
// Cria apenas para mundos de gameplay (PIE/Game), nao para editor preview.
UWorld* World = Cast<UWorld>(Outer);
if (!World) { return false; }
return World->WorldType == EWorldType::Game || World->WorldType == EWorldType::PIE;
}
void UZeusAttributeNetworkHandler::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
if (UZeusNetworkSubsystem* Net = GetZeusNetSubsystem())
{
SnapshotFullHandle = Net->OnAttributeSnapshotFull.AddUObject(
this, &UZeusAttributeNetworkHandler::HandleAttributeSnapshotFull);
HpSpUpdateHandle = Net->OnHpSpUpdate.AddUObject(
this, &UZeusAttributeNetworkHandler::HandleHpSpUpdate);
LevelUpHandle = Net->OnLevelUp.AddUObject(
this, &UZeusAttributeNetworkHandler::HandleLevelUp);
StatAllocReplyHandle = Net->OnStatAllocReply.AddUObject(
this, &UZeusAttributeNetworkHandler::HandleStatAllocReply);
}
}
void UZeusAttributeNetworkHandler::Deinitialize()
{
if (UZeusNetworkSubsystem* Net = GetZeusNetSubsystem())
{
if (SnapshotFullHandle.IsValid())
{
Net->OnAttributeSnapshotFull.Remove(SnapshotFullHandle);
SnapshotFullHandle.Reset();
}
if (HpSpUpdateHandle.IsValid())
{
Net->OnHpSpUpdate.Remove(HpSpUpdateHandle);
HpSpUpdateHandle.Reset();
}
if (LevelUpHandle.IsValid())
{
Net->OnLevelUp.Remove(LevelUpHandle);
LevelUpHandle.Reset();
}
if (StatAllocReplyHandle.IsValid())
{
Net->OnStatAllocReply.Remove(StatAllocReplyHandle);
StatAllocReplyHandle.Reset();
}
}
Super::Deinitialize();
}
UZeusNetworkSubsystem* UZeusAttributeNetworkHandler::GetZeusNetSubsystem() const
{
const UWorld* World = GetWorld();
if (!World) { return nullptr; }
UGameInstance* GI = World->GetGameInstance();
if (!GI) { return nullptr; }
return GI->GetSubsystem<UZeusNetworkSubsystem>();
}
void UZeusAttributeNetworkHandler::HandleAttributeSnapshotFull(const FZeusAttributesPayload& Payload)
{
UWorld* World = GetWorld();
if (!World) { return; }
UZeusAttributeComponent* Comp = FindComponentForEntity(World, Payload.EntityId);
if (!Comp)
{
// Fallback chicken-and-egg: primeiro snapshot chega antes do EntityId
// estar seeded no componente. Aplica ao primeiro componente do
// PlayerArray que ainda tem EntityId=0. Apos o primeiro apply, o
// caminho normal por lookup funciona.
const AGameStateBase* GS = World->GetGameState();
if (GS)
{
for (APlayerState* PS : GS->PlayerArray)
{
if (!PS) { continue; }
UZeusAttributeComponent* Candidate = PS->FindComponentByClass<UZeusAttributeComponent>();
if (Candidate && Candidate->GetSnapshot().EntityId == 0)
{
Comp = Candidate;
break;
}
}
}
}
if (Comp)
{
Comp->ApplySnapshot(ToSnapshot(Payload));
}
}
void UZeusAttributeNetworkHandler::HandleHpSpUpdate(int64 EntityId, int32 Hp, int32 Sp)
{
UWorld* World = GetWorld();
if (!World) { return; }
UZeusAttributeComponent* Comp = FindComponentForEntity(World, EntityId);
if (Comp)
{
Comp->ApplyHpSpUpdate(Hp, Sp);
}
}
void UZeusAttributeNetworkHandler::HandleLevelUp(int64 EntityId, int32 NewBaseLevel, int32 StatusPointDelta)
{
UWorld* World = GetWorld();
if (!World) { return; }
UZeusAttributeComponent* Comp = FindComponentForEntity(World, EntityId);
if (Comp)
{
Comp->NotifyLevelUp(NewBaseLevel, StatusPointDelta);
}
}
void UZeusAttributeNetworkHandler::HandleStatAllocReply(bool bAccepted, int32 Reason)
{
// S_ATTRIBUTE_STAT_ALLOC_OK nao traz EntityId no payload — sempre do
// player local que fez o request. Busca o AttributeComponent via PC.
if (UZeusAttributeComponent* Comp = FindLocalPlayerAttributeComponent())
{
Comp->NotifyStatAllocReply(bAccepted, Reason);
}
}
UZeusAttributeComponent* UZeusAttributeNetworkHandler::FindLocalPlayerAttributeComponent() const
{
UWorld* World = GetWorld();
if (!World) { return nullptr; }
APlayerController* PC = World->GetFirstPlayerController();
if (!PC || !PC->PlayerState) { return nullptr; }
return PC->PlayerState->FindComponentByClass<UZeusAttributeComponent>();
}

View File

@@ -0,0 +1,13 @@
#include "ZeusAttributesModule.h"
#include "Modules/ModuleManager.h"
void FZeusAttributesModule::StartupModule()
{
}
void FZeusAttributesModule::ShutdownModule()
{
}
IMPLEMENT_MODULE(FZeusAttributesModule, ZeusAttributes)

View File

@@ -0,0 +1,45 @@
#include "ZeusHudHpSpWidget.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
#include "Internationalization/Text.h"
void UZeusHudHpSpWidget::ApplySnapshot(const FZeusAttributesSnapshot& Snapshot)
{
LastSnapshot = Snapshot;
OnSnapshotApplied(Snapshot);
}
void UZeusHudHpSpWidget::ApplyHpSp(int32 Hp, int32 MaxHp, int32 Sp, int32 MaxSp)
{
LastSnapshot.Hp = Hp;
LastSnapshot.MaxHp = MaxHp;
LastSnapshot.Sp = Sp;
LastSnapshot.MaxSp = MaxSp;
if (HpBar)
{
HpBar->SetPercent(MaxHp > 0 ? static_cast<float>(Hp) / static_cast<float>(MaxHp) : 0.f);
}
if (SpBar)
{
SpBar->SetPercent(MaxSp > 0 ? static_cast<float>(Sp) / static_cast<float>(MaxSp) : 0.f);
}
if (HpText)
{
HpText->SetText(FText::FromString(FString::Printf(TEXT("%d / %d"), Hp, MaxHp)));
}
if (SpText)
{
SpText->SetText(FText::FromString(FString::Printf(TEXT("%d / %d"), Sp, MaxSp)));
}
}
void UZeusHudHpSpWidget::OnSnapshotApplied_Implementation(const FZeusAttributesSnapshot& Snapshot)
{
ApplyHpSp(Snapshot.Hp, Snapshot.MaxHp, Snapshot.Sp, Snapshot.MaxSp);
if (LevelText)
{
LevelText->SetText(FText::FromString(FString::Printf(TEXT("Lv %d"), Snapshot.BaseLevel)));
}
}