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:
54
Source/ZeusJobs/Public/ZeusJobChangeNetworkHandler.h
Normal file
54
Source/ZeusJobs/Public/ZeusJobChangeNetworkHandler.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Subsystems/WorldSubsystem.h"
|
||||
#include "ZeusJobChangeNetworkHandler.generated.h"
|
||||
|
||||
class UZeusNetworkSubsystem;
|
||||
|
||||
/**
|
||||
* Multicast dinamico assignable em Blueprint. WBP de promocao binda no
|
||||
* OnJobChangeResult pra reagir ao S_JOB_CHANGE_RESULT (1520) do server.
|
||||
*
|
||||
* Parametros:
|
||||
* - bAccepted : true = promocao aplicada (S_ATTRIBUTE_SNAPSHOT_FULL
|
||||
* chega logo apos com state novo).
|
||||
* - Reason : EJobChangeRejectReason (None/NoSession/UnknownJob/
|
||||
* NotParent/WrongTier/JobLevelTooLow/AlreadyAtTarget/
|
||||
* JobsDbUnavailable). Significativo apenas se !bAccepted.
|
||||
* - NewClassId : significativo apenas se bAccepted=true (redundante com
|
||||
* snapshot que vem junto, mas util pra triggers/toasts).
|
||||
*/
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FZeusOnJobChangeResultBP,
|
||||
bool, bAccepted, int32, Reason, int32, NewClassId);
|
||||
|
||||
/**
|
||||
* Bridge entre o `UZeusNetworkSubsystem` (do plugin ZeusNetwork) e a UI
|
||||
* Blueprint (WBP de promocao). Mesmo pattern do `UZeusAttributeNetworkHandler`
|
||||
* — converte o delegate C++-only `FZeusOnJobChangeResult` num dynamic
|
||||
* multicast (`FZeusOnJobChangeResultBP`) assignavel em BP.
|
||||
*
|
||||
* Por que UWorldSubsystem? Player so' faz promocao quando ja' esta no
|
||||
* WorldServer (com mundo carregado). No front-end / lobby, esse subsystem
|
||||
* nao existe — economiza memoria.
|
||||
*/
|
||||
UCLASS()
|
||||
class ZEUSJOBS_API UZeusJobChangeNetworkHandler : public UWorldSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
|
||||
|
||||
/// Assignavel em BP: WBP_JobChangePanel.OnEvent_OnJobChangeResult.
|
||||
UPROPERTY(BlueprintAssignable, Category = "Zeus|Jobs")
|
||||
FZeusOnJobChangeResultBP OnJobChangeResult;
|
||||
|
||||
private:
|
||||
void HandleJobChangeResult(bool bAccepted, int32 Reason, int32 NewClassId);
|
||||
UZeusNetworkSubsystem* GetZeusNetSubsystem() const;
|
||||
|
||||
FDelegateHandle JobChangeResultHandle;
|
||||
};
|
||||
93
Source/ZeusJobs/Public/ZeusJobDataAsset.h
Normal file
93
Source/ZeusJobs/Public/ZeusJobDataAsset.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "ZeusJobTypes.h"
|
||||
#include "ZeusJobDataAsset.generated.h"
|
||||
|
||||
class UTexture2D;
|
||||
class USoundBase;
|
||||
class UAnimInstance;
|
||||
class UAnimMontage;
|
||||
|
||||
/**
|
||||
* Dados visuais/UI de UM job (classe). 1 .uasset por job em
|
||||
* `Content/ZMMO/Data/Jobs/DA_Job_<Nome>.uasset`.
|
||||
*
|
||||
* ClassId eh a CHAVE — bate com `classId` do snapshot do server (rathena
|
||||
* pc.hpp `job_class`, ex: Novice=0, Swordsman=1, Mage=2, ...).
|
||||
*
|
||||
* Soft pointers (TSoftObjectPtr) sao usados pra assets pesados (textures,
|
||||
* sounds) — lazy-loaded quando precisar (level up, hover icon). DataAsset
|
||||
* em si fica em memoria depois do scan do Subsystem.
|
||||
*
|
||||
* Async pointers (TSubclassOf) sao sync — anim BP precisa estar carregada
|
||||
* quando o player spawna.
|
||||
*/
|
||||
UCLASS(BlueprintType)
|
||||
class ZEUSJOBS_API UZeusJobDataAsset : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/// Chave estavel (bate com `Config/Jobs/<Name>.json:Id` no server e com
|
||||
/// `FZeusAttributesSnapshot::ClassId` recebido do server).
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
|
||||
int32 ClassId = 0;
|
||||
|
||||
/// Nome tecnico estavel (en-US). Ex: "Novice", "Swordsman". Aparece em
|
||||
/// logs e telemetria — NUNCA exibido pro player.
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
|
||||
FString TechnicalName;
|
||||
|
||||
/// Nome localizado exibido na UI (pt-BR no projeto base). Ex: "Novato".
|
||||
/// Pode usar FText Localization tables pra multi-idioma futuro.
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
|
||||
FText DisplayName;
|
||||
|
||||
/// Tier hierarquico — espelha `JobDef::tier` do server. UI usa pra agrupar
|
||||
/// jobs (ex: lista de Vocacoes possiveis quando promovendo Novato).
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
|
||||
EZeusJobTier Tier = EZeusJobTier::Beginner;
|
||||
|
||||
/// ClassId do parent na arvore de promocao. 0 = sem parent (Novato eh root).
|
||||
/// Espelha `JobDef::parentJobId` do server. UI usa pra filtrar destinos
|
||||
/// possiveis ao mostrar painel de promocao.
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
|
||||
int32 ParentClassId = 0;
|
||||
|
||||
/// Lista de armas que o job pode equipar. Espelha `JobDef::allowedWeaponsMask`
|
||||
/// do server (mas como TArray pra editor visual em vez de bitmask cru).
|
||||
/// Inventory UI usa pra hint "nao pode equipar" + filtro de catalogo.
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
|
||||
TArray<EZeusWeaponType> AllowedWeapons;
|
||||
|
||||
/// Icone do job — usado em StatusWindow, CharacterCard, JobChangeUI.
|
||||
/// Soft ptr: nao carrega ate alguem chamar LoadSynchronous() ou async load.
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job|Assets")
|
||||
TSoftObjectPtr<UTexture2D> JobIcon;
|
||||
|
||||
/// AnimInstance class override (opcional). Quando nao-null, AnimBP
|
||||
/// padrao do PlayerCharacter eh substituido por esta classe no spawn
|
||||
/// (jobs com move set diferente — Monge bate, Assassin furtivo, etc.).
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job|Anim")
|
||||
TSubclassOf<UAnimInstance> DefaultAnimInstanceClass;
|
||||
|
||||
/// Montage de "job change" (animacao de transformacao). Tocada quando
|
||||
/// player promove de Novice → 1a classe. V1 nao implementado.
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job|Anim")
|
||||
TSoftObjectPtr<UAnimMontage> JobChangeMontage;
|
||||
|
||||
/// Som de level up override. Quando null, HUD usa som generico do projeto.
|
||||
/// Soft ptr: lazy load no primeiro level up.
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job|Audio")
|
||||
TSoftObjectPtr<USoundBase> LevelUpSoundCue;
|
||||
|
||||
/// PrimaryAssetType pro AssetManager (precisa pra GetPrimaryAssetIdList).
|
||||
/// Hardcoded "ZeusJob" — registry classifica todos os DAs deste tipo.
|
||||
virtual FPrimaryAssetId GetPrimaryAssetId() const override
|
||||
{
|
||||
return FPrimaryAssetId(FPrimaryAssetType(TEXT("ZeusJob")),
|
||||
*FString::Printf(TEXT("Job_%d_%s"), ClassId, *TechnicalName));
|
||||
}
|
||||
};
|
||||
57
Source/ZeusJobs/Public/ZeusJobTypes.h
Normal file
57
Source/ZeusJobs/Public/ZeusJobTypes.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "ZeusJobTypes.generated.h"
|
||||
|
||||
/**
|
||||
* Tier hierarquico de um job. Espelha `EJobTier` do server em
|
||||
* `Server/.../JobsSystem/Public/JobTypes.hpp`. Valores TEM que bater
|
||||
* byte-a-byte com a enum do server porque o snapshot pode carregar
|
||||
* tier como uint8 no futuro.
|
||||
*
|
||||
* Renascer (RO pre-renewal): char no Tier 2 (Specialization) que cumpre
|
||||
* condicao volta pra Tier 3 (RebornBeginner) com bonus permanente,
|
||||
* abrindo path paralelo RebornVocation → Mastery (coroa final).
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class EZeusJobTier : uint8
|
||||
{
|
||||
Beginner = 0 UMETA(DisplayName = "Iniciante"),
|
||||
Vocation = 1 UMETA(DisplayName = "Vocacao"),
|
||||
Specialization = 2 UMETA(DisplayName = "Especializacao"),
|
||||
RebornBeginner = 3 UMETA(DisplayName = "Iniciante Renascido"),
|
||||
RebornVocation = 4 UMETA(DisplayName = "Vocacao Renascida"),
|
||||
Mastery = 5 UMETA(DisplayName = "Mestria"),
|
||||
};
|
||||
|
||||
/**
|
||||
* Tipos de arma. Espelha `EWeaponType` do server. Usado em `AllowedWeapons`
|
||||
* do DA pra UI (filtrar items equipaveis) + validacao server-side futura
|
||||
* quando InventorySystem entrar.
|
||||
*
|
||||
* Ordem TEM que bater com server porque o bitmask `allowedWeaponsMask` no
|
||||
* JobDef usa bit N = EWeaponType(N).
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class EZeusWeaponType : uint8
|
||||
{
|
||||
Fist = 0 UMETA(DisplayName = "Punho"),
|
||||
Dagger = 1 UMETA(DisplayName = "Adaga"),
|
||||
Sword1H = 2 UMETA(DisplayName = "Espada 1M"),
|
||||
Sword2H = 3 UMETA(DisplayName = "Espada 2M"),
|
||||
Spear1H = 4 UMETA(DisplayName = "Lanca 1M"),
|
||||
Spear2H = 5 UMETA(DisplayName = "Lanca 2M"),
|
||||
Axe1H = 6 UMETA(DisplayName = "Machado 1M"),
|
||||
Axe2H = 7 UMETA(DisplayName = "Machado 2M"),
|
||||
Mace1H = 8 UMETA(DisplayName = "Maca 1M"),
|
||||
Mace2H = 9 UMETA(DisplayName = "Maca 2M"),
|
||||
Staff1H = 10 UMETA(DisplayName = "Cajado 1M"),
|
||||
Staff2H = 11 UMETA(DisplayName = "Cajado 2M"),
|
||||
Bow = 12 UMETA(DisplayName = "Arco"),
|
||||
Knuckle = 13 UMETA(DisplayName = "Soqueira"),
|
||||
Musical = 14 UMETA(DisplayName = "Instrumento Musical"),
|
||||
Whip = 15 UMETA(DisplayName = "Chicote"),
|
||||
Book = 16 UMETA(DisplayName = "Livro"),
|
||||
Katar = 17 UMETA(DisplayName = "Katar"),
|
||||
Gun = 18 UMETA(DisplayName = "Arma de Fogo"),
|
||||
};
|
||||
62
Source/ZeusJobs/Public/ZeusJobsLibrary.h
Normal file
62
Source/ZeusJobs/Public/ZeusJobsLibrary.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "ZeusJobTypes.h"
|
||||
#include "ZeusJobsLibrary.generated.h"
|
||||
|
||||
class UZeusJobDataAsset;
|
||||
|
||||
/**
|
||||
* Helpers Blueprint pra UI/HUD acessar dados de job sem precisar pegar o
|
||||
* Subsystem manualmente. Todos usam WorldContextObject pra resolver
|
||||
* GameInstance → Subsystem internamente.
|
||||
*
|
||||
* Padrao de uso em UMG:
|
||||
* - Text binding: `JobsLibrary::GetJobDisplayName(Self, AttrComp.Current.ClassId)`
|
||||
* - Image binding: `JobsLibrary::GetJobIcon(Self, ClassId).LoadSynchronous()`
|
||||
*/
|
||||
UCLASS()
|
||||
class ZEUSJOBS_API UZeusJobsLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/// Nome localizado do job. Fallback "Classe N" se ClassId nao tem DA
|
||||
/// correspondente (job nao registrado no Content/ZMMO/Data/Jobs/).
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs",
|
||||
meta = (WorldContext = "WorldContextObject"))
|
||||
static FText GetJobDisplayName(const UObject* WorldContextObject, int32 ClassId);
|
||||
|
||||
/// DataAsset completo (pode ser nullptr — caller checa).
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs",
|
||||
meta = (WorldContext = "WorldContextObject"))
|
||||
static UZeusJobDataAsset* GetJobData(const UObject* WorldContextObject, int32 ClassId);
|
||||
|
||||
/// Helper de UI: retorna true se ClassId tem DA registrado.
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs",
|
||||
meta = (WorldContext = "WorldContextObject"))
|
||||
static bool IsJobRegistered(const UObject* WorldContextObject, int32 ClassId);
|
||||
|
||||
/// Lista jobs num tier (UI dropdown). Vazio se subsystem indisponivel.
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs",
|
||||
meta = (WorldContext = "WorldContextObject"))
|
||||
static TArray<UZeusJobDataAsset*> GetJobsByTier(
|
||||
const UObject* WorldContextObject, EZeusJobTier Tier);
|
||||
|
||||
/// Destinos de promocao a partir do char atual. WBP de promocao consome
|
||||
/// direto. Vazio se nao houver filhos (ex: char ja' esta em Tier 3
|
||||
/// Mastery — Jobs.4 introduzira terminal de progressao).
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs",
|
||||
meta = (WorldContext = "WorldContextObject"))
|
||||
static TArray<UZeusJobDataAsset*> GetEligibleNextJobs(
|
||||
const UObject* WorldContextObject, int32 CurrentClassId);
|
||||
|
||||
/// Helper de send via ZeusNetworkSubsystem. Conveniencia pra WBP nao
|
||||
/// precisar pegar o subsystem manualmente. Idempotente: rejeitado
|
||||
/// silenciosamente se nao conectado.
|
||||
UFUNCTION(BlueprintCallable, Category = "Zeus|Jobs",
|
||||
meta = (WorldContext = "WorldContextObject"))
|
||||
static void SendJobChangeRequest(
|
||||
const UObject* WorldContextObject, int32 TargetClassId);
|
||||
};
|
||||
23
Source/ZeusJobs/Public/ZeusJobsModule.h
Normal file
23
Source/ZeusJobs/Public/ZeusJobsModule.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleInterface.h"
|
||||
|
||||
/**
|
||||
* Sub-modulo cliente do JobsSystem.
|
||||
*
|
||||
* Espelho de `Server/ZeusServerEngine/Game/MMO/Modules/JobsSystem/`. Roda
|
||||
* como modulo Runtime em LoadingPhase PreDefault para que o
|
||||
* `UZeusJobsSubsystem` esteja registrado antes do ZMMO core spawnar a HUD.
|
||||
*
|
||||
* Responsabilidades:
|
||||
* - Dados visuais por job: DisplayName localizado, JobIcon, anim override
|
||||
* - Lookup classId → UZeusJobDataAsset via Subsystem
|
||||
* - Library Blueprint pra HUD/UI consumir
|
||||
*/
|
||||
class FZeusJobsModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
69
Source/ZeusJobs/Public/ZeusJobsSubsystem.h
Normal file
69
Source/ZeusJobs/Public/ZeusJobsSubsystem.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Subsystems/GameInstanceSubsystem.h"
|
||||
#include "ZeusJobTypes.h"
|
||||
#include "ZeusJobsSubsystem.generated.h"
|
||||
|
||||
class UZeusJobDataAsset;
|
||||
|
||||
/**
|
||||
* Cache central de UZeusJobDataAsset por ClassId. Vive como GameInstance
|
||||
* Subsystem — startup automatico quando GameInstance inicializa (PIE,
|
||||
* standalone, packaged). Sobrevive a map transitions.
|
||||
*
|
||||
* Initialize:
|
||||
* 1. Carrega via AssetRegistry: scan de UZeusJobDataAsset em todo Content
|
||||
* 2. Cacheia em TMap<int32, UZeusJobDataAsset*> por ClassId
|
||||
* 3. Log: quantos jobs encontrou
|
||||
*
|
||||
* Uso:
|
||||
* - C++: GameInstance->GetSubsystem<UZeusJobsSubsystem>()->GetJobData(0)
|
||||
* - BP: UZeusJobsLibrary::GetJobData(WorldContext, 0)
|
||||
*
|
||||
* Fase 7+ (Mod support): SCANEAR PrimaryAssetType="ZeusJob" do AssetManager
|
||||
* permite mods adicionarem DAs proprios sem mexer no source.
|
||||
*/
|
||||
UCLASS()
|
||||
class ZEUSJOBS_API UZeusJobsSubsystem : public UGameInstanceSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
|
||||
/// Lookup por classId. Retorna nullptr se ClassId nao tem DA correspondente
|
||||
/// (caller usa Library com fallback FText).
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs")
|
||||
UZeusJobDataAsset* GetJobData(int32 ClassId) const;
|
||||
|
||||
/// Total de jobs cacheados (diagnostico).
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs")
|
||||
int32 GetJobCount() const { return CachedJobs.Num(); }
|
||||
|
||||
/// Lista jobs num tier especifico (UI agrupa por tier — ex: dropdown
|
||||
/// "Vocacoes possiveis"). Ordem do retorno e' a do AssetRegistry scan
|
||||
/// — UI pode reordenar por ClassId/DisplayName se precisar.
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs")
|
||||
TArray<UZeusJobDataAsset*> GetJobsByTier(EZeusJobTier Tier) const;
|
||||
|
||||
/// Destinos de promocao validos a partir do `CurrentClassId`. Filtra
|
||||
/// pelos jobs que tem `ParentClassId == CurrentClassId`. WBP de
|
||||
/// promocao consome direto pra montar botoes "Tornar-se X".
|
||||
///
|
||||
/// NOTA: condicao de elegibilidade real (jobLevel >= cap, quest, item)
|
||||
/// e' do server — UI apenas LISTA opcoes possiveis pelo schema. Server
|
||||
/// reponde rejeicao via S_JOB_CHANGE_RESULT (Jobs::EJobChangeRejectReason).
|
||||
UFUNCTION(BlueprintPure, Category = "Zeus|Jobs")
|
||||
TArray<UZeusJobDataAsset*> GetEligibleNextJobs(int32 CurrentClassId) const;
|
||||
|
||||
private:
|
||||
/// Scan AssetRegistry + popula CachedJobs. Sincronizo (V1) — chamado UMA
|
||||
/// vez no Initialize. Pra 50 jobs eh aceitavel; se crescer pra 200+ pode
|
||||
/// virar async no futuro.
|
||||
void LoadJobsFromAssetRegistry();
|
||||
|
||||
UPROPERTY()
|
||||
TMap<int32, TObjectPtr<UZeusJobDataAsset>> CachedJobs;
|
||||
};
|
||||
Reference in New Issue
Block a user