7 Commits

Author SHA1 Message Date
16de963301 fix(net): S_CHAR_INFO so' aplica em si mesmo (anti name overwrite por proxy)
Bug: handler aceitava qualquer S_CHAR_INFO do server (proprio + catch-up de
proxies pre-existentes) e sobrescrevia o PlayerState local. Resultado: nome
do ultimo proxy recebido virava o nome do char local na tela.

Fix: bail se InEntityId != ZeusEntityId (proxies remotos sao roteados pelo
registry no UZeusWorldSubsystem; nameplate por EntityId fica pra futuro).
2026-06-03 21:56:49 -03:00
8d73cc9df8 feat(gas): SM6 client EntityId u64 + M8 cue assets + UI/data tweaks (sessao 1+2) 2026-06-03 18:18:02 -03:00
d5402216a2 feat(gas): AZeusPlayerState implementa IAbilitySystemInterface
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>
2026-06-03 11:39:37 -03:00
ff75ad92eb feat(gas): Batch 2 - Vertical slice Dash client (input bind + assets)
ZeusCharacter:
- DashAction UPROPERTY + load /Game/Input/Actions/IA_Dash.IA_Dash no ctor.
- SetupPlayerInputComponent: BindAction(DashAction, Triggered) -> OnDashTriggered.
- OnDashTriggered: resolve UZeusGASComponent via PlayerState -> chama
  RequestActivateAbilityByTag(Zeus.Ability.Movement.Dash). Bridge envia
  C_ABILITY_TRY_ACTIVATE pro server (handle, tagHash) e o ASC local executa
  ActivateAbility (LaunchCharacter) quando server confirma S_ABILITY_ACTIVATED.

Assets (criados via MCP):
- DT_Abilities (/Game/ZMMO/Data/Abilities/) — row "Zeus.Ability.Movement.Dash"
  apontando pro BP_GA_Dash_C. Row name = tag canonica (hash bate com server).
- BP_GA_Dash (/Game/ZMMO/GAS/Abilities/) — parent UZeusGameplayAbility_Dash.
- IA_Dash (/Game/Input/Actions/) — Boolean InputAction.
- IMC_Default — bind LeftShift -> IA_Dash com trigger Pressed (13a mapping).

Fluxo completo (apos rebuild + server na branch GameplayAbilitySystem):
  LShift -> OnDashTriggered -> RequestActivateAbilityByTag ->
  C_ABILITY_TRY_ACTIVATE -> server valida cost SP/cooldown ->
  S_ABILITY_ACTIVATED + S_ATTRIBUTE_HP_SP_UPDATE (-10 SP) ->
  ASC.TryActivateAbility(local) -> BP_GA_Dash::ActivateAbility ->
  LaunchCharacter(forward * 2400 cm/s) + HUD SP cai 10 + cooldown 3s.

Branch GameplayAbilitySystem (criada a partir do main pro escopo GAS).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 03:02:51 -03:00
98dce2f855 feat(zeus-gas): M7 - migrate HUD/Status to UZeusGASComponent + delete legacy
- ZeusHudWidget: porta de UZeusAttributeComponent legacy pra UZeusGASComponent
  (delegate OnSnapshotAppliedRaw via AddUObject; FZeusAttributesSnapshot
  construido pelo helper estatico FromPayload do plugin ZeusGAS). Logs
  diagnosticos no bind.
- UIPlayerStatus_Window: mesmo porte (snapshot raw + StatAllocReply). Lock
  de spam-click preservado.
- ZeusHudHpSpWidget: movido do plugin ZeusAttributes (deletado) pra ZMMO
  /Game/UI/InGame/. API preservada (WBP filhos nao precisam mudar).
- ZeusCharacter: tira o dual-seed legacy; so' seedea UZeusGASComponent
  via FindComponentByClass no HandleLocalSpawnReady.
- ZeusPlayerState/ZeusCharacter: comentarios atualizados pra refletir o
  UZeusGASComponent como dono unico.
- ZMMO.Build.cs: remove dep "ZeusAttributes", adiciona "ZeusGAS" +
  "GameplayAbilities".
- ZMMO.uproject: remove module "ZeusAttributes" (delete completo).
- DefaultGame.ini: remove linha legacy comentada do Component Registry.
- DefaultEngine.ini: adiciona [CoreRedirects] pra:
  * ZMMOJobs module + ZMMOJobDataAsset class (Package+Class) — 7 DA_Job_*
  * ZMMO.ZMMOMapDef struct (DT_Maps row)
  * ZMMO.ZMMOLoadingTipRow struct (DT_LoadingTips row)
  * ZMMO.ZMMOLoadingProfile/StepDef structs + EZMMOLoadingContext/StepStatus
    enums (DA_LoadingProfiles)
- DELETE: Source/ZeusAttributes/ inteiro (5 .cpp + 5 .h + Build.cs +
  module.json).

Pegadinha aprendida: ActiveClassRedirects so' renomeia classe (sem
package); CoreRedirects (ClassRedirects/StructRedirects/EnumRedirects/
PackageRedirects) e' obrigatorio quando muda modulo OU quando o asset
referencia USTRUCT/UENUM. Tipo errado nao da erro mas tambem nao funciona.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 01:26:04 -03:00
94442feca5 chore(uproject): rename plugin ZeusAbilities -> ZeusGAS
Servidor-side plugin foi renomeado de ZeusAbilities pra ZeusGAS (vai
absorver atributos + abilities + bridge ZeusNetwork). .uproject precisa
seguir o novo nome senao plugin deixa de carregar.

Server-side commit: ver Server repo branch GameplayAbilitySystem,
commit refactor(plugin): R.7 - rename plugin ZeusAbilities -> ZeusGAS.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 23:23:04 -03:00
6a6a28a086 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>
2026-06-02 17:24:38 -03:00
176 changed files with 1658 additions and 1977 deletions

View File

@@ -2,9 +2,9 @@
GameDefaultMap=/Game/ZMMO/Maps/FrontEnd/L_FrontEnd.L_FrontEnd GameDefaultMap=/Game/ZMMO/Maps/FrontEnd/L_FrontEnd.L_FrontEnd
EditorStartupMap=/Game/ZMMO/Maps/FrontEnd/L_FrontEnd.L_FrontEnd EditorStartupMap=/Game/ZMMO/Maps/FrontEnd/L_FrontEnd.L_FrontEnd
; GameMode/PlayerController/PlayerCharacter agora moram em C++ (Game/Modes/Entity/Controller). ; GameMode/PlayerController/PlayerCharacter agora moram em C++ (Game/Modes/Entity/Controller).
; O motor pode spawnar AZMMOGameMode directamente; um BP filho continua opcional. ; O motor pode spawnar AZeusGameMode directamente; um BP filho continua opcional.
GlobalDefaultGameMode=/Script/ZMMO.ZMMOGameMode GlobalDefaultGameMode=/Script/ZMMO.ZeusGameMode
GameInstanceClass=/Script/ZMMO.ZMMOGameInstance GameInstanceClass=/Script/ZMMO.ZeusGameInstance
[/Script/Engine.RendererSettings] [/Script/Engine.RendererSettings]
r.ReflectionMethod=1 r.ReflectionMethod=1
@@ -80,12 +80,30 @@ GameViewportClientClassName=/Script/CommonUI.CommonGameViewportClient
+ActiveGameNameRedirects=(OldGameName="TP_ThirdPerson",NewGameName="/Script/ZMMO") +ActiveGameNameRedirects=(OldGameName="TP_ThirdPerson",NewGameName="/Script/ZMMO")
+ActiveGameNameRedirects=(OldGameName="/Script/TP_ThirdPerson",NewGameName="/Script/ZMMO") +ActiveGameNameRedirects=(OldGameName="/Script/TP_ThirdPerson",NewGameName="/Script/ZMMO")
; Redirects do template antigo para a nova arquitectura (Game/Modes/Entity/Controller). ; Redirects do template antigo para a nova arquitectura (Game/Modes/Entity/Controller).
; ZMMOCharacter foi reescrito como ZMMOPlayerCharacter (ACharacter local com CMC livre). ; Pipeline: TP_ThirdPerson* -> ZMMO* (legado) -> Zeus* (atual). Os redirects de
+ActiveClassRedirects=(OldClassName="TP_ThirdPersonPlayerController",NewClassName="ZMMOPlayerController") ; ZMMO*->Zeus* preservam asset/BP refs criadas durante o periodo ZMMO* (Batches 1-3).
+ActiveClassRedirects=(OldClassName="TP_ThirdPersonGameMode",NewClassName="ZMMOGameMode") +ActiveClassRedirects=(OldClassName="TP_ThirdPersonPlayerController",NewClassName="ZeusPlayerController")
+ActiveClassRedirects=(OldClassName="TP_ThirdPersonCharacter",NewClassName="ZMMOPlayerCharacter") +ActiveClassRedirects=(OldClassName="TP_ThirdPersonGameMode",NewClassName="ZeusGameMode")
+ActiveClassRedirects=(OldClassName="ZMMOCharacter",NewClassName="ZMMOPlayerCharacter") +ActiveClassRedirects=(OldClassName="TP_ThirdPersonCharacter",NewClassName="ZeusCharacter")
+ActiveClassRedirects=(OldClassName="ZMMOCharacter",NewClassName="ZeusCharacter")
+ActiveClassRedirects=(OldClassName="ZMMOPlayerCharacter",NewClassName="ZeusCharacter")
+ActiveClassRedirects=(OldClassName="ZMMOPlayerController",NewClassName="ZeusPlayerController")
+ActiveClassRedirects=(OldClassName="ZMMOFrontEndPlayerController",NewClassName="ZeusFrontEndPlayerController")
+ActiveClassRedirects=(OldClassName="ZMMOGameMode",NewClassName="ZeusGameMode")
+ActiveClassRedirects=(OldClassName="ZMMOFrontEndGameMode",NewClassName="ZeusFrontEndGameMode")
+ActiveClassRedirects=(OldClassName="ZMMOGameInstance",NewClassName="ZeusGameInstance")
+ActiveClassRedirects=(OldClassName="ZMMOHUD",NewClassName="ZeusHUD")
+ActiveClassRedirects=(OldClassName="ZMMOPlayerState",NewClassName="ZeusPlayerState")
+ActiveClassRedirects=(OldClassName="ZMMOEntity",NewClassName="ZeusEntity")
+ActiveClassRedirects=(OldClassName="ZMMOPlayerProxy",NewClassName="ZeusPlayerProxy")
+ActiveClassRedirects=(OldClassName="ZMMOProxyMovementComponent",NewClassName="ZeusProxyMovementComponent")
+ActiveClassRedirects=(OldClassName="ZMMOWorldSubsystem",NewClassName="ZeusWorldSubsystem")
+ActiveClassRedirects=(OldClassName="ZMMOThemeDataAsset",NewClassName="ZeusThemeDataAsset")
+ActiveClassRedirects=(OldClassName="ZMMOThemeSubsystem",NewClassName="ZeusThemeSubsystem")
+ActiveClassRedirects=(OldClassName="ZMMOLoginSaveGame",NewClassName="ZeusLoginSaveGame")
+ActiveClassRedirects=(OldClassName="ZMMOHudWidget",NewClassName="ZeusHudWidget")
+ActiveClassRedirects=(OldClassName="ZMMOHudPlayerVitalsWidget",NewClassName="ZeusHudPlayerVitalsWidget")
+ActiveClassRedirects=(OldClassName="ZMMOLoadingProfilesDataAsset",NewClassName="ZeusLoadingProfilesDataAsset")
[CoreRedirects] [CoreRedirects]
; Migração v1→v2 do FUIStylePanel: TMap<EUIPanelTexture,...> (Enum) → TMap<FName,...>. ; Migração v1→v2 do FUIStylePanel: TMap<EUIPanelTexture,...> (Enum) → TMap<FName,...>.
; Os campos *_DEPRECATED preservam a leitura do asset antigo; PostSerialize copia ; Os campos *_DEPRECATED preservam a leitura do asset antigo; PostSerialize copia
@@ -95,6 +113,27 @@ GameViewportClientClassName=/Script/CommonUI.CommonGameViewportClient
+PropertyRedirects=(OldName="/Script/ZMMO.UIStylePanel.PanelOutline",NewName="/Script/ZMMO.UIStylePanel.PanelOutline_DEPRECATED") +PropertyRedirects=(OldName="/Script/ZMMO.UIStylePanel.PanelOutline",NewName="/Script/ZMMO.UIStylePanel.PanelOutline_DEPRECATED")
+PropertyRedirects=(OldName="/Script/ZMMO.UIStylePanel.PanelOutlineEffect",NewName="/Script/ZMMO.UIStylePanel.PanelOutlineEffect_DEPRECATED") +PropertyRedirects=(OldName="/Script/ZMMO.UIStylePanel.PanelOutlineEffect",NewName="/Script/ZMMO.UIStylePanel.PanelOutlineEffect_DEPRECATED")
; --- M7: Modulo cliente "ZMMOJobs" foi renomeado pra "ZeusJobs" + classe
; UZMMOJobDataAsset -> UZeusJobDataAsset. Os 7 DA_Job_* em /Game/ZMMO/Data/Jobs/
; foram salvos apontando pra /Script/ZMMOJobs.ZMMOJobDataAsset (modulo + classe
; antigos). ActiveClassRedirects so' troca o NOME da classe, nao o package;
; precisamos de CoreRedirects com path completo + PackageRedirect.
+PackageRedirects=(OldName="/Script/ZMMOJobs",NewName="/Script/ZeusJobs")
+ClassRedirects=(OldName="/Script/ZMMOJobs.ZMMOJobDataAsset",NewName="/Script/ZeusJobs.ZeusJobDataAsset")
; --- M7: USTRUCTs renomeadas (mesmo modulo ZMMO). DTs salvos com Row Structure
; apontando pro nome antigo (ZMMOMapDef, ZMMOLoadingTipRow). USTRUCT usa
; +StructRedirects (nao +ClassRedirects).
+StructRedirects=(OldName="/Script/ZMMO.ZMMOMapDef",NewName="/Script/ZMMO.ZeusMapDef")
+StructRedirects=(OldName="/Script/ZMMO.ZMMOLoadingTipRow",NewName="/Script/ZMMO.ZeusLoadingTipRow")
; DA_LoadingProfiles salvo com TMap<EZMMOLoadingContext, FZMMOLoadingProfile>;
; FZMMOLoadingProfile contem TArray<FZMMOLoadingStepDef>. Precisa de 3 redirects
; (1 enum + 2 struct) pra carregar sem warnings nem perda de dados.
+EnumRedirects=(OldName="/Script/ZMMO.EZMMOLoadingContext",NewName="/Script/ZMMO.EZeusLoadingContext")
+EnumRedirects=(OldName="/Script/ZMMO.EZMMOLoadingStepStatus",NewName="/Script/ZMMO.EZeusLoadingStepStatus")
+StructRedirects=(OldName="/Script/ZMMO.ZMMOLoadingProfile",NewName="/Script/ZMMO.ZeusLoadingProfile")
+StructRedirects=(OldName="/Script/ZMMO.ZMMOLoadingStepDef",NewName="/Script/ZMMO.ZeusLoadingStepDef")
[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings] [/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings]
bEnablePlugin=True bEnablePlugin=True
bAllowNetworkConnection=True bAllowNetworkConnection=True

View File

@@ -3,10 +3,10 @@ ProjectID=FC3E256F43B2AFD43009F4949B0814BE
ProjectName=Third Person Game Template ProjectName=Third Person Game Template
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; ZMMO Theme subsystem (see Source/ZMMO/Game/UI/ZMMOThemeSubsystem.h and ; ZMMO Theme subsystem (see Source/ZMMO/Game/UI/ZeusThemeSubsystem.h and
; ARQUITETURA.md §1.10 / §4.7). ; ARQUITETURA.md §1.10 / §4.7).
; ;
; - DefaultThemeAsset is the fallback theme (must define every EZMMOThemeKey). ; - DefaultThemeAsset is the fallback theme (must define every EZeusThemeKey).
; - ThemeRegistry maps ThemeId -> seasonal DA_Theme_* asset. ; - ThemeRegistry maps ThemeId -> seasonal DA_Theme_* asset.
; - CalendarTable points to DT_ThemeCalendar (FThemeCalendarRow rows). ; - CalendarTable points to DT_ThemeCalendar (FThemeCalendarRow rows).
; - UIStyleTable points to DT_UI_Styles (FUIStyleRow rows): tokens de estilo ; - UIStyleTable points to DT_UI_Styles (FUIStyleRow rows): tokens de estilo
@@ -18,7 +18,7 @@ ProjectName=Third Person Game Template
; assets are actually created in the editor. ; assets are actually created in the editor.
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
[/Script/ZMMO.ZMMOThemeSubsystem] [/Script/ZMMO.ZeusThemeSubsystem]
;DefaultThemeAsset=/Game/ZMMO/UI/Themes/DA_Theme_Default.DA_Theme_Default ;DefaultThemeAsset=/Game/ZMMO/UI/Themes/DA_Theme_Default.DA_Theme_Default
;+ThemeRegistry=(("Christmas", "/Game/ZMMO/UI/Themes/DA_Theme_Christmas.DA_Theme_Christmas")) ;+ThemeRegistry=(("Christmas", "/Game/ZMMO/UI/Themes/DA_Theme_Christmas.DA_Theme_Christmas"))
;+ThemeRegistry=(("Halloween", "/Game/ZMMO/UI/Themes/DA_Theme_Halloween.DA_Theme_Halloween")) ;+ThemeRegistry=(("Halloween", "/Game/ZMMO/UI/Themes/DA_Theme_Halloween.DA_Theme_Halloween"))
@@ -33,20 +33,20 @@ ScreenSetAsset=/Game/ZMMO/UI/FrontEnd/DA_FrontEndScreenSet.DA_FrontEndScreenSet
; Fase 4 — char spawn DB-driven. DT_Maps espelha o `maps_config.json` do ; Fase 4 — char spawn DB-driven. DT_Maps espelha o `maps_config.json` do
; server (Server/ZeusServerEngine/Config/DataTables/maps_config.json) — o ; server (Server/ZeusServerEngine/Config/DataTables/maps_config.json) — o
; cliente resolve `mapId -> ClientLevel/spawns` via FZMMOMapDef rows. ; cliente resolve `mapId -> ClientLevel/spawns` via FZeusMapDef rows.
MapsTableAsset=/Game/ZMMO/Data/World/DT_Maps.DT_Maps MapsTableAsset=/Game/ZMMO/Data/World/DT_Maps.DT_Maps
; Loading dinâmico (etapas + dicas). DA_LoadingProfiles tem 1 perfil por ; Loading dinâmico (etapas + dicas). DA_LoadingProfiles tem 1 perfil por
; contexto (EZMMOLoadingContext); DT_LoadingTips rotaciona durante o load. ; contexto (EZeusLoadingContext); DT_LoadingTips rotaciona durante o load.
; Cliente local marca etapas via eventos (sem opcode novo). ; Cliente local marca etapas via eventos (sem opcode novo).
LoadingProfilesAsset=/Game/ZMMO/Data/UI/Loading/DA_LoadingProfiles.DA_LoadingProfiles LoadingProfilesAsset=/Game/ZMMO/Data/UI/Loading/DA_LoadingProfiles.DA_LoadingProfiles
LoadingTipsAsset=/Game/ZMMO/Data/UI/Loading/DT_LoadingTips.DT_LoadingTips LoadingTipsAsset=/Game/ZMMO/Data/UI/Loading/DT_LoadingTips.DT_LoadingTips
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; UI in-game (PR 19+). Espelho do front-end pattern: ; UI in-game (PR 19+). Espelho do front-end pattern:
; - ScreenSetAsset mapeia EZMMOInGameUIState -> WBP (Playing -> WBP_HUD, ; - ScreenSetAsset mapeia EZeusInGameUIState -> WBP (Playing -> WBP_HUD,
; StatusWindow -> WBP_StatusWindow, etc.) ; StatusWindow -> WBP_StatusWindow, etc.)
; - Subsystem orquestra: AZMMOHUD::BeginPlay chama StartInGame que vai pra ; - Subsystem orquestra: AZeusHUD::BeginPlay chama StartInGame que vai pra
; Playing. ; Playing.
; Asset criado via MCP em /Game/ZMMO/UI/InGame/DA_InGameScreenSet. ; Asset criado via MCP em /Game/ZMMO/UI/InGame/DA_InGameScreenSet.
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
@@ -56,16 +56,27 @@ ScreenSetAsset=/Game/ZMMO/UI/InGame/DA_InGameScreenSet.DA_InGameScreenSet
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; PlayerState Component Registry (PR 19+). Cada módulo MMO registra seus ; PlayerState Component Registry (PR 19+). Cada módulo MMO registra seus
; UActorComponent aqui. O AZMMOPlayerState lê esta lista no construtor e ; UActorComponent aqui. O AZeusPlayerState lê esta lista no construtor e
; instancia cada classe como subobject — pattern Open-Closed: adicionar ; instancia cada classe como subobject — pattern Open-Closed: adicionar
; Inventory/Skills/Guild = mais uma linha aqui, sem editar AZMMOPlayerState. ; Inventory/Skills/Guild = mais uma linha aqui, sem editar AZeusPlayerState.
; ;
; Convenção: usa o path /Script/<Module>.<ClassName> (sem o "U" do prefixo ; Convenção: usa o path /Script/<Module>.<ClassName> (sem o "U" do prefixo
; C++; UClass resolve pelo nome curto). ; C++; UClass resolve pelo nome curto).
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
[/Script/ZMMO.ZMMOPlayerState] [/Script/ZMMO.ZeusPlayerState]
+ComponentClasses=/Script/ZMMOAttributes.ZMMOAttributeComponent ; UZeusGASComponent (plugin ZeusGAS) — dono unico dos atributos do char (M7).
; Owns UZeusAbilitySystemComponent + UZeusAttributeSet (26 atributos
; espelhados do server CharAttributeSet). Bridge via UZeusGASNetworkHandler
; (UWorldSubsystem) subscribe nos delegates do UZeusNetworkSubsystem.
+ComponentClasses=/Script/ZeusGAS.ZeusGASComponent
; === GAS Cue paths (Batch 2.5 — S_ABILITY_CUE multicast cosmetico) ===
; UGameplayCueManager scaneia esses paths no boot pra mapear FGameplayTag
; -> AGameplayCueNotify_Actor BP. UZeusGASComponent::DispatchAbilityCue chama
; ASC->ExecuteGameplayCueLocal(CueTag, params) -> manager resolve pelo path.
[/Script/GameplayAbilities.AbilitySystemGlobals]
+GameplayCueNotifyPaths="/Game/ZMMO/GAS/Cues"
[/Script/Engine.AssetManagerSettings] [/Script/Engine.AssetManagerSettings]
-PrimaryAssetTypesToScan=(PrimaryAssetType="Map",AssetBaseClass=/Script/Engine.World,bHasBlueprintClasses=False,bIsEditorOnly=True,Directories=((Path="/Game/Maps")),SpecificAssets=,Rules=(Priority=-1,ChunkId=-1,bApplyRecursively=True,CookRule=Unknown)) -PrimaryAssetTypesToScan=(PrimaryAssetType="Map",AssetBaseClass=/Script/Engine.World,bHasBlueprintClasses=False,bIsEditorOnly=True,Directories=((Path="/Game/Maps")),SpecificAssets=,Rules=(Priority=-1,ChunkId=-1,bApplyRecursively=True,CookRule=Unknown))

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -10,17 +10,17 @@
* *
* Fluxo: Boot → Connecting → Login → ServerSelect → Lobby → EnteringWorld * Fluxo: Boot → Connecting → Login → ServerSelect → Lobby → EnteringWorld
* → InWorld. O Lobby é o hub principal logado; suas páginas internas são * → InWorld. O Lobby é o hub principal logado; suas páginas internas são
* EZMMOLobbyPage (não são estados de topo — ver ARQUITETURA.md §4.8). * EZeusLobbyPage (não são estados de topo — ver ARQUITETURA.md §4.8).
*/ */
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOFrontEndState : uint8 enum class EZeusFrontEndState : uint8
{ {
None, None,
Boot, // splash inicial enquanto subsistemas sobem Boot, // splash inicial enquanto subsistemas sobem
Connecting, // conectando ao servidor Zeus (UDP) Connecting, // conectando ao servidor Zeus (UDP)
Login, // autenticação Login, // autenticação
ServerSelect, // escolha de servidor/realm ServerSelect, // escolha de servidor/realm
Lobby, // hub principal logado (host das EZMMOLobbyPage) Lobby, // hub principal logado (host das EZeusLobbyPage)
EnteringWorld, // loading/handoff: OpenLevel do mapa de mundo EnteringWorld, // loading/handoff: OpenLevel do mapa de mundo
InWorld // no mundo (HUD de gameplay assume) InWorld // no mundo (HUD de gameplay assume)
}; };
@@ -30,7 +30,7 @@ enum class EZMMOFrontEndState : uint8
* de Lobby ("Switch principal"), não pelo fluxo de topo. * de Lobby ("Switch principal"), não pelo fluxo de topo.
*/ */
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOLobbyPage : uint8 enum class EZeusLobbyPage : uint8
{ {
None, None,
CharacterSelect, CharacterSelect,

View File

@@ -7,7 +7,7 @@
* Estados da UI in-game. Dirigidos pelo UUIInGameFlowSubsystem; cada estado * Estados da UI in-game. Dirigidos pelo UUIInGameFlowSubsystem; cada estado
* resolve uma tela (UCommonActivatableWidget) via DA_InGameScreenSet. * resolve uma tela (UCommonActivatableWidget) via DA_InGameScreenSet.
* *
* Espelha simetricamente EZMMOFrontEndState (Data/UI/FrontEndTypes.h): * Espelha simetricamente EZeusFrontEndState (Data/UI/FrontEndTypes.h):
* - Front-end usa estados pra Login/ServerSelect/Lobby (UI.Layer.Menu) * - Front-end usa estados pra Login/ServerSelect/Lobby (UI.Layer.Menu)
* - In-game usa estados pra HUD/Status/Inventory/Skills (UI.Layer.Game + GameMenu) * - In-game usa estados pra HUD/Status/Inventory/Skills (UI.Layer.Game + GameMenu)
* *
@@ -22,7 +22,7 @@
* Layer.GameMenu por cima dele. * Layer.GameMenu por cima dele.
*/ */
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOInGameUIState : uint8 enum class EZeusInGameUIState : uint8
{ {
None, ///< Antes do player local spawnar; UI in-game inativa. None, ///< Antes do player local spawnar; UI in-game inativa.
Playing, ///< HUD principal visivel (HP/SP/level/etc). Playing, ///< HUD principal visivel (HP/SP/level/etc).

View File

@@ -5,14 +5,14 @@
/** /**
* Contexto do loading screen genérico. Cada contexto resolve um perfil * Contexto do loading screen genérico. Cada contexto resolve um perfil
* (lista de etapas) no UZMMOLoadingProfilesDataAsset. * (lista de etapas) no UZeusLoadingProfilesDataAsset.
* *
* Cliente local rastreia o progresso assinando eventos próprios * Cliente local rastreia o progresso assinando eventos próprios
* (HandlePostLoadMap, OnPlayerSpawned, etc) — server não envia opcode de * (HandlePostLoadMap, OnPlayerSpawned, etc) — server não envia opcode de
* progresso, ver decisão em [[project_ui_loading_dynamic]]. * progresso, ver decisão em [[project_ui_loading_dynamic]].
*/ */
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOLoadingContext : uint8 enum class EZeusLoadingContext : uint8
{ {
None, None,
FrontEndEnteringWorld, ///< FrontEnd → mundo (handoff CharServer→WorldServer + spawn). FrontEndEnteringWorld, ///< FrontEnd → mundo (handoff CharServer→WorldServer + spawn).
@@ -21,7 +21,7 @@ enum class EZMMOLoadingContext : uint8
}; };
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOLoadingStepStatus : uint8 enum class EZeusLoadingStepStatus : uint8
{ {
Pending, ///< Ainda não começou. Pending, ///< Ainda não começou.
Running, ///< Em andamento (o "barber pole"). Running, ///< Em andamento (o "barber pole").
@@ -34,7 +34,7 @@ enum class EZMMOLoadingStepStatus : uint8
* pra chamar MarkStepDone(StepId); Label é o texto localizado mostrado. * pra chamar MarkStepDone(StepId); Label é o texto localizado mostrado.
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct FZMMOLoadingStepDef struct FZeusLoadingStepDef
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -52,13 +52,13 @@ struct FZMMOLoadingStepDef
* consulta StepId pra avançar etapa. * consulta StepId pra avançar etapa.
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct FZMMOLoadingProfile struct FZeusLoadingProfile
{ {
GENERATED_BODY() GENERATED_BODY()
/** Etapas em ordem. ProgressBar = #Done / #Steps. */ /** Etapas em ordem. ProgressBar = #Done / #Steps. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading")
TArray<FZMMOLoadingStepDef> Steps; TArray<FZeusLoadingStepDef> Steps;
/** Título da tela (vazio = usa default da classe). */ /** Título da tela (vazio = usa default da classe). */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading")

View File

@@ -4,7 +4,7 @@
#include "ThemeKeys.generated.h" #include "ThemeKeys.generated.h"
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOThemeKey : uint8 enum class EZeusThemeKey : uint8
{ {
// HUD // HUD
HUD_Frame UMETA(DisplayName = "HUD - Frame"), HUD_Frame UMETA(DisplayName = "HUD - Frame"),

View File

@@ -1,6 +1,6 @@
#include "UI/UILayerTags.h" #include "UI/UILayerTags.h"
namespace ZMMOUITags namespace ZeusUITags
{ {
UE_DEFINE_GAMEPLAY_TAG(UI_Layer_Game, "UI.Layer.Game"); UE_DEFINE_GAMEPLAY_TAG(UI_Layer_Game, "UI.Layer.Game");
UE_DEFINE_GAMEPLAY_TAG(UI_Layer_GameMenu, "UI.Layer.GameMenu"); UE_DEFINE_GAMEPLAY_TAG(UI_Layer_GameMenu, "UI.Layer.GameMenu");

View File

@@ -12,7 +12,7 @@
* UI.Layer.Menu — front-end (Boot/Login/ServerSelect/Lobby) * UI.Layer.Menu — front-end (Boot/Login/ServerSelect/Lobby)
* UI.Layer.Modal — diálogos/loading por cima de tudo * UI.Layer.Modal — diálogos/loading por cima de tudo
*/ */
namespace ZMMOUITags namespace ZeusUITags
{ {
ZMMO_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(UI_Layer_Game); ZMMO_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(UI_Layer_Game);
ZMMO_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(UI_Layer_GameMenu); ZMMO_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(UI_Layer_GameMenu);

View File

@@ -73,7 +73,7 @@ struct ZMMO_API FUIStyle
/** /**
* Linha de DT_UI_Styles. O Row Name é o ThemeId (ex.: "Default", "RPG"), * Linha de DT_UI_Styles. O Row Name é o ThemeId (ex.: "Default", "RPG"),
* espelhando DT_ThemeCalendar e ThemeRegistry — assim a camada de estilo * espelhando DT_ThemeCalendar e ThemeRegistry — assim a camada de estilo
* é consumidora do ThemeId já resolvido pelo UZMMOThemeSubsystem. * é consumidora do ThemeId já resolvido pelo UZeusThemeSubsystem.
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct ZMMO_API FUIStyleRow : public FTableRowBase struct ZMMO_API FUIStyleRow : public FTableRowBase
@@ -87,7 +87,7 @@ struct ZMMO_API FUIStyleRow : public FTableRowBase
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style") UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
EUITheme Theme = EUITheme::None; EUITheme Theme = EUITheme::None;
/** Ponte para o ThemeId resolvido pelo UZMMOThemeSubsystem. */ /** Ponte para o ThemeId resolvido pelo UZeusThemeSubsystem. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style") UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
FName ThemeId; FName ThemeId;

View File

@@ -7,7 +7,7 @@
* Enums do sistema de UI Style (tokens de tema visual). * Enums do sistema de UI Style (tokens de tema visual).
* *
* Espelha ThemeKeys.h: enums fortes, BlueprintType, primeiro valor None. * Espelha ThemeKeys.h: enums fortes, BlueprintType, primeiro valor None.
* O conceito de "tema ativo" continua sendo do UZMMOThemeSubsystem * O conceito de "tema ativo" continua sendo do UZeusThemeSubsystem
* (resolvido por FName ThemeId). EUITheme é apenas validação tipada de * (resolvido por FName ThemeId). EUITheme é apenas validação tipada de
* design-time ao preencher DT_UI_Styles — não é a chave de runtime. * design-time ao preencher DT_UI_Styles — não é a chave de runtime.
*/ */

View File

@@ -7,7 +7,7 @@
#include "MapDef.generated.h" #include "MapDef.generated.h"
/** /**
* FZMMOMapSpawn * FZeusMapSpawn
* *
* Ponto de spawn dentro de um mapa, identificado por `Tag`. Usado pelo * Ponto de spawn dentro de um mapa, identificado por `Tag`. Usado pelo
* server pra decidir onde materializar um char quando ele entra: * server pra decidir onde materializar um char quando ele entra:
@@ -15,12 +15,12 @@
* - Char saindo de raid: pode pedir tag="raid_return" * - Char saindo de raid: pode pedir tag="raid_return"
* - Char morto: pode pedir tag="graveyard" * - Char morto: pode pedir tag="graveyard"
* *
* ZeusEditorTools pode auto-popular o `Spawns[]` do FZMMOMapDef varrendo * ZeusEditorTools pode auto-popular o `Spawns[]` do FZeusMapDef varrendo
* todos APlayerStart (ou ator custom AZMMOMapSpawnPoint) presentes no * todos APlayerStart (ou ator custom AZeusMapSpawnPoint) presentes no
* `.umap` do `ClientLevel` — botao "Sync from level". * `.umap` do `ClientLevel` — botao "Sync from level".
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct ZMMO_API FZMMOMapSpawn struct ZMMO_API FZeusMapSpawn
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -38,7 +38,7 @@ struct ZMMO_API FZMMOMapSpawn
}; };
/** /**
* FZMMOMapDef * FZeusMapDef
* *
* Definicao canonica de um mapa do MMO. Linha da DT_Maps no cliente. * Definicao canonica de um mapa do MMO. Linha da DT_Maps no cliente.
* Exportada para `Server/ZeusServerEngine/Config/DataTables/maps_config.json` * Exportada para `Server/ZeusServerEngine/Config/DataTables/maps_config.json`
@@ -55,7 +55,7 @@ struct ZMMO_API FZMMOMapSpawn
* `mapName` (string), evitando ~10-30 bytes por handoff. * `mapName` (string), evitando ~10-30 bytes por handoff.
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct ZMMO_API FZMMOMapDef : public FTableRowBase struct ZMMO_API FZeusMapDef : public FTableRowBase
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -77,7 +77,7 @@ struct ZMMO_API FZMMOMapDef : public FTableRowBase
* Pelo menos um com Tag="default" e esperado. * Pelo menos um com Tag="default" e esperado.
*/ */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Map|Spawns") UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Map|Spawns")
TArray<FZMMOMapSpawn> Spawns; TArray<FZeusMapSpawn> Spawns;
/** Regras PvP/Safe/Dungeon. Reusa enum de FZoneRow. */ /** Regras PvP/Safe/Dungeon. Reusa enum de FZoneRow. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Map") UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Map")

View File

@@ -1,14 +1,14 @@
#include "ZMMOFrontEndPlayerController.h" #include "ZeusFrontEndPlayerController.h"
#include "UIFrontEndFlowSubsystem.h" #include "UIFrontEndFlowSubsystem.h"
#include "Engine/GameInstance.h" #include "Engine/GameInstance.h"
AZMMOFrontEndPlayerController::AZMMOFrontEndPlayerController() AZeusFrontEndPlayerController::AZeusFrontEndPlayerController()
{ {
bShowMouseCursor = true; bShowMouseCursor = true;
} }
void AZMMOFrontEndPlayerController::BeginPlay() void AZeusFrontEndPlayerController::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();

View File

@@ -2,24 +2,24 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#include "ZMMOFrontEndPlayerController.generated.h" #include "ZeusFrontEndPlayerController.generated.h"
/** /**
* AZMMOFrontEndPlayerController * AZeusFrontEndPlayerController
* *
* Controller do mapa de front-end. Não herda de AZMMOPlayerController (sem * Controller do mapa de front-end. Não herda de AZeusPlayerController (sem
* Enhanced Input de gameplay/touch). Em BeginPlay arranca o fluxo de * Enhanced Input de gameplay/touch). Em BeginPlay arranca o fluxo de
* front-end (UUIFrontEndFlowSubsystem) feito aqui, e não no * front-end (UUIFrontEndFlowSubsystem) feito aqui, e não no
* GameInstance::Init, porque os subsistemas existem neste ponto (ver * GameInstance::Init, porque os subsistemas existem neste ponto (ver
* aviso no header do ZeusNetworkSubsystem). * aviso no header do ZeusNetworkSubsystem).
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API AZMMOFrontEndPlayerController : public APlayerController class ZMMO_API AZeusFrontEndPlayerController : public APlayerController
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOFrontEndPlayerController(); AZeusFrontEndPlayerController();
protected: protected:
virtual void BeginPlay() override; virtual void BeginPlay() override;

View File

@@ -1,4 +1,4 @@
#include "ZMMOPlayerController.h" #include "ZeusPlayerController.h"
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "Components/InputComponent.h" #include "Components/InputComponent.h"
@@ -13,11 +13,11 @@
#include "UI/InGame/UIInGameFlowSubsystem.h" #include "UI/InGame/UIInGameFlowSubsystem.h"
#include "UI/InGameTypes.h" #include "UI/InGameTypes.h"
AZMMOPlayerController::AZMMOPlayerController() AZeusPlayerController::AZeusPlayerController()
{ {
// Defaults dos Input Mapping Contexts (alinhados ao ZClientMMO). Permitem // Defaults dos Input Mapping Contexts (alinhados ao ZClientMMO). Permitem
// instanciar AZMMOPlayerController directamente como // instanciar AZeusPlayerController directamente como
// `PlayerControllerClass` do AZMMOGameMode sem exigir um BP filho. Se o // `PlayerControllerClass` do AZeusGameMode sem exigir um BP filho. Se o
// projeto adicionar mais IMCs, podemos extender via BP filho ou via // projeto adicionar mais IMCs, podemos extender via BP filho ou via
// arquivos de Config (UPROPERTY EditAnywhere abaixo). // arquivos de Config (UPROPERTY EditAnywhere abaixo).
static ConstructorHelpers::FObjectFinder<UInputMappingContext> DefaultImc( static ConstructorHelpers::FObjectFinder<UInputMappingContext> DefaultImc(
@@ -35,7 +35,7 @@ AZMMOPlayerController::AZMMOPlayerController()
} }
} }
void AZMMOPlayerController::BeginPlay() void AZeusPlayerController::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
@@ -43,7 +43,7 @@ void AZMMOPlayerController::BeginPlay()
{ {
// Limpa estado de input herdado da UI do FrontEnd (UIManagerSubsystem // Limpa estado de input herdado da UI do FrontEnd (UIManagerSubsystem
// e LocalPlayerSubsystem — sobrevive ao travel, e o controller anterior // e LocalPlayerSubsystem — sobrevive ao travel, e o controller anterior
// (AZMMOFrontEndPlayerController) tinha setado FInputModeUIOnly + // (AZeusFrontEndPlayerController) tinha setado FInputModeUIOnly +
// bShowMouseCursor=true). Sem este reset, WASD/Look podem nao chegar // bShowMouseCursor=true). Sem este reset, WASD/Look podem nao chegar
// ao pawn porque o Slate ainda esta com foco no widget antigo. // ao pawn porque o Slate ainda esta com foco no widget antigo.
FInputModeGameOnly InputMode; FInputModeGameOnly InputMode;
@@ -67,7 +67,7 @@ void AZMMOPlayerController::BeginPlay()
} }
} }
void AZMMOPlayerController::SetupInputComponent() void AZeusPlayerController::SetupInputComponent()
{ {
Super::SetupInputComponent(); Super::SetupInputComponent();
@@ -101,7 +101,7 @@ void AZMMOPlayerController::SetupInputComponent()
FInputKeyBinding& Binding = InputComponent->BindKey( FInputKeyBinding& Binding = InputComponent->BindKey(
FInputChord(EKeys::A, /*bShift*/ false, /*bCtrl*/ false, /*bAlt*/ true, /*bCmd*/ false), FInputChord(EKeys::A, /*bShift*/ false, /*bCtrl*/ false, /*bAlt*/ true, /*bCmd*/ false),
IE_Pressed, IE_Pressed,
this, &AZMMOPlayerController::ToggleStatusWindow); this, &AZeusPlayerController::ToggleStatusWindow);
Binding.bConsumeInput = true; Binding.bConsumeInput = true;
Binding.bExecuteWhenPaused = true; // dispara mesmo com StatusWindow aberto (CommonUI menu mode) Binding.bExecuteWhenPaused = true; // dispara mesmo com StatusWindow aberto (CommonUI menu mode)
@@ -109,35 +109,35 @@ void AZMMOPlayerController::SetupInputComponent()
FInputKeyBinding& JobBinding = InputComponent->BindKey( FInputKeyBinding& JobBinding = InputComponent->BindKey(
FInputChord(EKeys::J, /*bShift*/ false, /*bCtrl*/ false, /*bAlt*/ false, /*bCmd*/ false), FInputChord(EKeys::J, /*bShift*/ false, /*bCtrl*/ false, /*bAlt*/ false, /*bCmd*/ false),
IE_Pressed, IE_Pressed,
this, &AZMMOPlayerController::ToggleJobChangePanel); this, &AZeusPlayerController::ToggleJobChangePanel);
JobBinding.bConsumeInput = true; JobBinding.bConsumeInput = true;
JobBinding.bExecuteWhenPaused = true; JobBinding.bExecuteWhenPaused = true;
} }
} }
void AZMMOPlayerController::ToggleStatusWindow() void AZeusPlayerController::ToggleStatusWindow()
{ {
if (UGameInstance* GI = GetGameInstance()) if (UGameInstance* GI = GetGameInstance())
{ {
if (UUIInGameFlowSubsystem* Flow = GI->GetSubsystem<UUIInGameFlowSubsystem>()) if (UUIInGameFlowSubsystem* Flow = GI->GetSubsystem<UUIInGameFlowSubsystem>())
{ {
Flow->ToggleScreen(EZMMOInGameUIState::StatusWindow); Flow->ToggleScreen(EZeusInGameUIState::StatusWindow);
} }
} }
} }
void AZMMOPlayerController::ToggleJobChangePanel() void AZeusPlayerController::ToggleJobChangePanel()
{ {
if (UGameInstance* GI = GetGameInstance()) if (UGameInstance* GI = GetGameInstance())
{ {
if (UUIInGameFlowSubsystem* Flow = GI->GetSubsystem<UUIInGameFlowSubsystem>()) if (UUIInGameFlowSubsystem* Flow = GI->GetSubsystem<UUIInGameFlowSubsystem>())
{ {
Flow->ToggleScreen(EZMMOInGameUIState::JobChangePanel); Flow->ToggleScreen(EZeusInGameUIState::JobChangePanel);
} }
} }
} }
bool AZMMOPlayerController::ShouldUseTouchControls() const bool AZeusPlayerController::ShouldUseTouchControls() const
{ {
return SVirtualJoystick::ShouldDisplayTouchInterface() || bForceTouchControls; return SVirtualJoystick::ShouldDisplayTouchInterface() || bForceTouchControls;
} }

View File

@@ -2,26 +2,26 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#include "ZMMOPlayerController.generated.h" #include "ZeusPlayerController.generated.h"
class UInputMappingContext; class UInputMappingContext;
class UUserWidget; class UUserWidget;
/** /**
* AZMMOPlayerController * AZeusPlayerController
* *
* Player controller do cliente Zeus MMO. Responsavel apenas pela camada de * Player controller do cliente Zeus MMO. Responsavel apenas pela camada de
* input do Unreal (Enhanced Input Mapping Contexts e widget opcional de * input do Unreal (Enhanced Input Mapping Contexts e widget opcional de
* controlos touch). Toda a logica de identidade Zeus, envio de input e * controlos touch). Toda a logica de identidade Zeus, envio de input e
* reconciliacao vive em `AZMMOPlayerCharacter`. * reconciliacao vive em `AZeusCharacter`.
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API AZMMOPlayerController : public APlayerController class ZMMO_API AZeusPlayerController : public APlayerController
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOPlayerController(); AZeusPlayerController();
protected: protected:
/** Mapping contexts default (sempre adicionados). */ /** Mapping contexts default (sempre adicionados). */

View File

@@ -1,25 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "ZMMOProxyMovementComponent.generated.h"
/**
* CMC customizado para AZMMOPlayerProxy. Expõe escrita direta de Acceleration
* (protected na base) para que o AnimBP veja Acceleration!=0 quando o proxy
* recebe snapshots, alimentando a fórmula ShouldMove e a transição Jump_Start
* do ABP_Unarmed (ambas dependem de aceleração não-nula). Espelha
* UZeusProxyMovementComponent do ZClientMMO.
*/
UCLASS(ClassGroup = (ZMMO), meta = (BlueprintSpawnableComponent))
class ZMMO_API UZMMOProxyMovementComponent : public UCharacterMovementComponent
{
GENERATED_BODY()
public:
void SetZMMOExternalAcceleration(const FVector& InAccelerationCmS2)
{
Acceleration = InAccelerationCmS2;
}
};

View File

@@ -1,4 +1,4 @@
#include "ZMMOPlayerCharacter.h" #include "ZeusCharacter.h"
#include "Animation/AnimInstance.h" #include "Animation/AnimInstance.h"
#include "Camera/CameraComponent.h" #include "Camera/CameraComponent.h"
@@ -17,15 +17,17 @@
#include "Subsystems/WorldSubsystem.h" #include "Subsystems/WorldSubsystem.h"
#include "UObject/ConstructorHelpers.h" #include "UObject/ConstructorHelpers.h"
#include "ZMMO.h" #include "ZMMO.h"
#include "ZMMOAttributeComponent.h" #include "GameplayTagContainer.h"
#include "ZMMOPlayerState.h" #include "GameplayTagsManager.h"
#include "ZMMOWorldSubsystem.h" #include "ZeusGASComponent.h"
#include "ZeusPlayerState.h"
#include "ZeusWorldSubsystem.h"
#include "ZeusNetworkSubsystem.h" #include "ZeusNetworkSubsystem.h"
#include "UI/FrontEnd/UIFrontEndFlowSubsystem.h" #include "UI/FrontEnd/UIFrontEndFlowSubsystem.h"
DEFINE_LOG_CATEGORY(LogZMMOPlayer); DEFINE_LOG_CATEGORY(LogZeusPlayer);
AZMMOPlayerCharacter::AZMMOPlayerCharacter() AZeusCharacter::AZeusCharacter()
{ {
PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true; PrimaryActorTick.bStartWithTickEnabled = true;
@@ -55,13 +57,12 @@ AZMMOPlayerCharacter::AZMMOPlayerCharacter()
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
FollowCamera->bUsePawnControlRotation = false; FollowCamera->bUsePawnControlRotation = false;
// AttributeComponent migrou pro PlayerState (AZMMOPlayerState + Component // AttributeComponent migrou pro PlayerState (AZeusPlayerState + Component
// Registry config-driven). Pawn fica leve — so' movement/input/camera. // Registry config-driven). Pawn fica leve — so' movement/input/camera.
// Defaults visuais (mesh + AnimBP) — alinhados ao ZClientMMO. Permitem ao // Defaults visuais (mesh + AnimBP). Permitem ao motor spawnar AZeusCharacter
// motor spawnar AZMMOPlayerCharacter directamente como DefaultPawnClass do // directamente como DefaultPawnClass do AZeusGameMode sem exigir um BP filho.
// AZMMOGameMode sem exigir um BP filho. Um BP filho continua opcional para // Um BP filho continua opcional para trocar mesh/AnimBP por mapa.
// trocar mesh/AnimBP por mapa.
if (USkeletalMeshComponent* MeshComponent = GetMesh()) if (USkeletalMeshComponent* MeshComponent = GetMesh())
{ {
static ConstructorHelpers::FObjectFinder<USkeletalMesh> QuinnMesh( static ConstructorHelpers::FObjectFinder<USkeletalMesh> QuinnMesh(
@@ -77,7 +78,7 @@ AZMMOPlayerCharacter::AZMMOPlayerCharacter()
} }
else else
{ {
UE_LOG(LogZMMOPlayer, Warning, TEXT("Default mesh SKM_Quinn_Simple not found for AZMMOPlayerCharacter.")); UE_LOG(LogZeusPlayer, Warning, TEXT("Default mesh SKM_Quinn_Simple not found for AZeusCharacter."));
} }
if (QuinnAnimBp.Succeeded()) if (QuinnAnimBp.Succeeded())
@@ -87,12 +88,12 @@ AZMMOPlayerCharacter::AZMMOPlayerCharacter()
} }
else else
{ {
UE_LOG(LogZMMOPlayer, Warning, TEXT("Default anim blueprint ABP_Unarmed not found for AZMMOPlayerCharacter.")); UE_LOG(LogZeusPlayer, Warning, TEXT("Default anim blueprint ABP_Unarmed not found for AZeusCharacter."));
} }
} }
// Input Actions defaults (Enhanced Input) — IMCs sao adicionados pelo // Input Actions defaults (Enhanced Input) — IMCs sao adicionados pelo
// AZMMOPlayerController. As IAs aqui resolvem o asset por path; um BP filho // AZeusPlayerController. As IAs aqui resolvem o asset por path; um BP filho
// pode sobrescrever caso queira inputs custom. // pode sobrescrever caso queira inputs custom.
static ConstructorHelpers::FObjectFinder<UInputAction> MoveActionAsset( static ConstructorHelpers::FObjectFinder<UInputAction> MoveActionAsset(
TEXT("/Game/Input/Actions/IA_Move.IA_Move")); TEXT("/Game/Input/Actions/IA_Move.IA_Move"));
@@ -102,14 +103,17 @@ AZMMOPlayerCharacter::AZMMOPlayerCharacter()
TEXT("/Game/Input/Actions/IA_MouseLook.IA_MouseLook")); TEXT("/Game/Input/Actions/IA_MouseLook.IA_MouseLook"));
static ConstructorHelpers::FObjectFinder<UInputAction> JumpActionAsset( static ConstructorHelpers::FObjectFinder<UInputAction> JumpActionAsset(
TEXT("/Game/Input/Actions/IA_Jump.IA_Jump")); TEXT("/Game/Input/Actions/IA_Jump.IA_Jump"));
static ConstructorHelpers::FObjectFinder<UInputAction> DashActionAsset(
TEXT("/Game/Input/Actions/IA_Dash.IA_Dash"));
if (MoveActionAsset.Succeeded()) { MoveAction = MoveActionAsset.Object; } if (MoveActionAsset.Succeeded()) { MoveAction = MoveActionAsset.Object; }
if (LookActionAsset.Succeeded()) { LookAction = LookActionAsset.Object; } if (LookActionAsset.Succeeded()) { LookAction = LookActionAsset.Object; }
if (MouseLookActionAsset.Succeeded()) { MouseLookAction = MouseLookActionAsset.Object; } if (MouseLookActionAsset.Succeeded()) { MouseLookAction = MouseLookActionAsset.Object; }
if (JumpActionAsset.Succeeded()) { JumpAction = JumpActionAsset.Object; } if (JumpActionAsset.Succeeded()) { JumpAction = JumpActionAsset.Object; }
if (DashActionAsset.Succeeded()) { DashAction = DashActionAsset.Object; }
} }
void AZMMOPlayerCharacter::BeginPlay() void AZeusCharacter::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
ResolveZeusNetworkSubsystem(); ResolveZeusNetworkSubsystem();
@@ -134,77 +138,116 @@ void AZMMOPlayerCharacter::BeginPlay()
{ {
C->SetControlRotation(NewRot); C->SetControlRotation(NewRot);
} }
UE_LOG(LogZMMOPlayer, Log, UE_LOG(LogZeusPlayer, Log,
TEXT("AZMMOPlayerCharacter: pawn reposicionado pra pos do DB (%s) yaw=%.1f"), TEXT("AZeusCharacter: pawn reposicionado pra pos do DB (%s) yaw=%.1f"),
*PosCm.ToString(), YawDeg); *PosCm.ToString(), YawDeg);
} }
} }
} }
} }
void AZMMOPlayerCharacter::EndPlay(const EEndPlayReason::Type EndPlayReason) void AZeusCharacter::EndPlay(const EEndPlayReason::Type EndPlayReason)
{ {
UnbindZeusSpawnDelegate(); UnbindZeusSpawnDelegate();
ZeusNetwork = nullptr; ZeusNetwork = nullptr;
Super::EndPlay(EndPlayReason); Super::EndPlay(EndPlayReason);
} }
void AZMMOPlayerCharacter::Tick(const float DeltaSeconds) void AZeusCharacter::Tick(const float DeltaSeconds)
{ {
Super::Tick(DeltaSeconds); Super::Tick(DeltaSeconds);
FlushInputAxisToServer(DeltaSeconds); FlushInputAxisToServer(DeltaSeconds);
} }
void AZMMOPlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) void AZeusCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{ {
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent)) if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{ {
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &AZMMOPlayerCharacter::OnJumpPressed); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &AZeusCharacter::OnJumpPressed);
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &AZMMOPlayerCharacter::OnJumpReleased); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &AZeusCharacter::OnJumpReleased);
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AZMMOPlayerCharacter::Move); EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AZeusCharacter::Move);
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Completed, this, &AZMMOPlayerCharacter::MoveCompleted); EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Completed, this, &AZeusCharacter::MoveCompleted);
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AZMMOPlayerCharacter::Look); EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AZeusCharacter::Look);
EnhancedInputComponent->BindAction(MouseLookAction, ETriggerEvent::Triggered, this, &AZMMOPlayerCharacter::Look); EnhancedInputComponent->BindAction(MouseLookAction, ETriggerEvent::Triggered, this, &AZeusCharacter::Look);
if (DashAction)
{
EnhancedInputComponent->BindAction(DashAction, ETriggerEvent::Triggered, this, &AZeusCharacter::OnDashTriggered);
}
} }
else else
{ {
UE_LOG(LogZMMOPlayer, Error, TEXT("'%s' Failed to find an Enhanced Input component."), *GetNameSafe(this)); UE_LOG(LogZeusPlayer, Error, TEXT("'%s' Failed to find an Enhanced Input component."), *GetNameSafe(this));
} }
} }
void AZMMOPlayerCharacter::Move(const FInputActionValue& Value) void AZeusCharacter::Move(const FInputActionValue& Value)
{ {
const FVector2D MovementVector = Value.Get<FVector2D>(); const FVector2D MovementVector = Value.Get<FVector2D>();
DoMove(MovementVector.X, MovementVector.Y); DoMove(MovementVector.X, MovementVector.Y);
} }
void AZMMOPlayerCharacter::MoveCompleted(const FInputActionValue& Value) void AZeusCharacter::MoveCompleted(const FInputActionValue& Value)
{ {
(void)Value; (void)Value;
DoMove(0.0f, 0.0f); DoMove(0.0f, 0.0f);
} }
void AZMMOPlayerCharacter::Look(const FInputActionValue& Value) void AZeusCharacter::Look(const FInputActionValue& Value)
{ {
const FVector2D LookAxisVector = Value.Get<FVector2D>(); const FVector2D LookAxisVector = Value.Get<FVector2D>();
DoLook(LookAxisVector.X, LookAxisVector.Y); DoLook(LookAxisVector.X, LookAxisVector.Y);
} }
void AZMMOPlayerCharacter::OnJumpPressed() void AZeusCharacter::OnJumpPressed()
{ {
bPendingJumpPressed = true; bPendingJumpPressed = true;
DoJumpStart(); DoJumpStart();
} }
void AZMMOPlayerCharacter::OnJumpReleased() void AZeusCharacter::OnJumpReleased()
{ {
bPendingJumpReleased = true; bPendingJumpReleased = true;
DoJumpEnd(); DoJumpEnd();
} }
void AZMMOPlayerCharacter::DoMove(const float Right, const float Forward) void AZeusCharacter::OnDashTriggered()
{
// Resolve UZeusGASComponent do PlayerState. Component vive la' via
// AZeusPlayerState Component Registry (config-driven). Sem el, ASC ausente
// e RequestActivateAbilityByTag falha — log warning.
const APlayerState* PS = GetPlayerState();
if (!PS)
{
UE_LOG(LogZeusPlayer, Warning, TEXT("OnDashTriggered: PlayerState nullptr — ignorado"));
return;
}
UZeusGASComponent* Comp = PS->FindComponentByClass<UZeusGASComponent>();
if (!Comp)
{
UE_LOG(LogZeusPlayer, Warning, TEXT("OnDashTriggered: UZeusGASComponent nao achado"));
return;
}
// Tag canonica casa com row do DT + JSON do server. Hash FNV calculado
// dentro do componente (RequestActivateAbilityByTag).
const FGameplayTag DashTag = UGameplayTagsManager::Get().RequestGameplayTag(
FName(TEXT("Zeus.Ability.Movement.Dash")));
if (!DashTag.IsValid())
{
UE_LOG(LogZeusPlayer, Warning,
TEXT("OnDashTriggered: tag Zeus.Ability.Movement.Dash nao registrada no cliente"));
return;
}
const bool bSent = Comp->RequestActivateAbilityByTag(DashTag);
UE_LOG(LogZeusPlayer, Log, TEXT("OnDashTriggered -> RequestActivateAbilityByTag = %s"),
bSent ? TEXT("OK (C_ABILITY_TRY_ACTIVATE enviado)") : TEXT("FALHOU"));
}
void AZeusCharacter::DoMove(const float Right, const float Forward)
{ {
PendingMoveRight = FMath::Clamp(Right, -1.0f, 1.0f); PendingMoveRight = FMath::Clamp(Right, -1.0f, 1.0f);
PendingMoveForward = FMath::Clamp(Forward, -1.0f, 1.0f); PendingMoveForward = FMath::Clamp(Forward, -1.0f, 1.0f);
@@ -220,7 +263,7 @@ void AZMMOPlayerCharacter::DoMove(const float Right, const float Forward)
} }
} }
void AZMMOPlayerCharacter::DoLook(const float Yaw, const float Pitch) void AZeusCharacter::DoLook(const float Yaw, const float Pitch)
{ {
if (GetController() != nullptr) if (GetController() != nullptr)
{ {
@@ -229,29 +272,29 @@ void AZMMOPlayerCharacter::DoLook(const float Yaw, const float Pitch)
} }
} }
void AZMMOPlayerCharacter::DoJumpStart() void AZeusCharacter::DoJumpStart()
{ {
Jump(); Jump();
} }
void AZMMOPlayerCharacter::DoJumpEnd() void AZeusCharacter::DoJumpEnd()
{ {
StopJumping(); StopJumping();
} }
void AZMMOPlayerCharacter::ApplyEntitySnapshot(const FZMMOEntitySnapshot& /*Snapshot*/) void AZeusCharacter::ApplyEntitySnapshot(const FZeusEntitySnapshot& /*Snapshot*/)
{ {
// Cliente local solto: o servidor nao reconcilia posicao em V0 (ADR 0038). // Cliente local solto: o servidor nao reconcilia posicao em V0 (ADR 0038).
// Quando colisao de objetos chegar, podemos ligar uma reconciliacao opcional // Quando colisao de objetos chegar, podemos ligar uma reconciliacao opcional
// horizontal aqui (XY only), preservando o Z do CMC local. // horizontal aqui (XY only), preservando o Z do CMC local.
} }
void AZMMOPlayerCharacter::SetEntityRelevant(bool /*bRelevant*/) void AZeusCharacter::SetEntityRelevant(bool /*bRelevant*/)
{ {
// Nunca despawnamos o jogador local via AOI. // Nunca despawnamos o jogador local via AOI.
} }
void AZMMOPlayerCharacter::ResolveZeusNetworkSubsystem() void AZeusCharacter::ResolveZeusNetworkSubsystem()
{ {
if (ZeusNetwork) if (ZeusNetwork)
{ {
@@ -267,7 +310,7 @@ void AZMMOPlayerCharacter::ResolveZeusNetworkSubsystem()
ZeusNetwork = GI->GetSubsystem<UZeusNetworkSubsystem>(); ZeusNetwork = GI->GetSubsystem<UZeusNetworkSubsystem>();
} }
void AZMMOPlayerCharacter::BindZeusSpawnDelegate() void AZeusCharacter::BindZeusSpawnDelegate()
{ {
if (bSpawnDelegateBound || !IsLocallyControlled()) if (bSpawnDelegateBound || !IsLocallyControlled())
{ {
@@ -278,24 +321,24 @@ void AZMMOPlayerCharacter::BindZeusSpawnDelegate()
return; return;
} }
ZeusNetwork->OnPlayerSpawned.AddDynamic(this, &AZMMOPlayerCharacter::HandleZeusPlayerSpawned); ZeusNetwork->OnPlayerSpawned.AddDynamic(this, &AZeusCharacter::HandleZeusPlayerSpawned);
ZeusNetwork->OnCharInfoReceived.AddDynamic(this, &AZMMOPlayerCharacter::HandleZeusCharInfo); ZeusNetwork->OnCharInfoReceived.AddDynamic(this, &AZeusCharacter::HandleZeusCharInfo);
bSpawnDelegateBound = true; bSpawnDelegateBound = true;
} }
void AZMMOPlayerCharacter::UnbindZeusSpawnDelegate() void AZeusCharacter::UnbindZeusSpawnDelegate()
{ {
if (!bSpawnDelegateBound || !ZeusNetwork) if (!bSpawnDelegateBound || !ZeusNetwork)
{ {
bSpawnDelegateBound = false; bSpawnDelegateBound = false;
return; return;
} }
ZeusNetwork->OnPlayerSpawned.RemoveDynamic(this, &AZMMOPlayerCharacter::HandleZeusPlayerSpawned); ZeusNetwork->OnPlayerSpawned.RemoveDynamic(this, &AZeusCharacter::HandleZeusPlayerSpawned);
ZeusNetwork->OnCharInfoReceived.RemoveDynamic(this, &AZMMOPlayerCharacter::HandleZeusCharInfo); ZeusNetwork->OnCharInfoReceived.RemoveDynamic(this, &AZeusCharacter::HandleZeusCharInfo);
bSpawnDelegateBound = false; bSpawnDelegateBound = false;
} }
void AZMMOPlayerCharacter::TryRegisterLocalEntityFromCachedSpawn() void AZeusCharacter::TryRegisterLocalEntityFromCachedSpawn()
{ {
if (!ZeusNetwork) if (!ZeusNetwork)
{ {
@@ -316,19 +359,19 @@ void AZMMOPlayerCharacter::TryRegisterLocalEntityFromCachedSpawn()
TryApplyCachedCharInfo(); TryApplyCachedCharInfo();
} }
void AZMMOPlayerCharacter::HandleZeusPlayerSpawned(const int64 InEntityId, const bool bIsLocal, void AZeusCharacter::HandleZeusPlayerSpawned(const int64 InEntityId, const bool bIsLocal,
const FVector PosCm, const float YawDeg, const int64 ServerTimeMs) const FVector PosCm, const float YawDeg, const int64 ServerTimeMs)
{ {
if (!bIsLocal) if (!bIsLocal)
{ {
// Remote spawns sao tratados pelo `UZMMOWorldSubsystem`; aqui so reagimos // Remote spawns sao tratados pelo `UZeusWorldSubsystem`; aqui so reagimos
// ao spawn do pawn possessivel local (S_SPAWN_PLAYER com bIsLocal=true). // ao spawn do pawn possessivel local (S_SPAWN_PLAYER com bIsLocal=true).
return; return;
} }
HandleLocalSpawnReady(InEntityId, PosCm, YawDeg, ServerTimeMs); HandleLocalSpawnReady(InEntityId, PosCm, YawDeg, ServerTimeMs);
} }
void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int64 InEntityId, const FVector PosCm, void AZeusCharacter::HandleLocalSpawnReady(const int64 InEntityId, const FVector PosCm,
const float YawDeg, const int64 ServerTimeMs) const float YawDeg, const int64 ServerTimeMs)
{ {
if (InEntityId == 0) if (InEntityId == 0)
@@ -337,57 +380,69 @@ void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int64 InEntityId, const F
} }
// PR-HANDOFF-007 — InEntityId é int64 (era int32) // PR-HANDOFF-007 — InEntityId é int64 (era int32)
if (ZMMOEntityId == InEntityId) if (ZeusEntityId == InEntityId)
{ {
return; return;
} }
ZMMOEntityId = InEntityId; ZeusEntityId = InEntityId;
UE_LOG(LogZMMOPlayer, Log, UE_LOG(LogZeusPlayer, Log,
TEXT("AZMMOPlayerCharacter: local spawn captured EntityId=%lld pos=(%s) yaw=%.1f t=%lld"), TEXT("AZeusCharacter: local spawn captured EntityId=%lld pos=(%s) yaw=%.1f t=%lld"),
InEntityId, *PosCm.ToString(), YawDeg, ServerTimeMs); InEntityId, *PosCm.ToString(), YawDeg, ServerTimeMs);
if (UWorld* World = GetWorld()) if (UWorld* World = GetWorld())
{ {
if (UZMMOWorldSubsystem* WorldSubsystem = World->GetSubsystem<UZMMOWorldSubsystem>()) if (UZeusWorldSubsystem* WorldSubsystem = World->GetSubsystem<UZeusWorldSubsystem>())
{ {
WorldSubsystem->RegisterLocalEntity(InEntityId, this); WorldSubsystem->RegisterLocalEntity(InEntityId, this);
} }
} }
// Identidade publica (EntityId) + seed no AttributeComponent. CharName/Guild // Identidade publica (EntityId) + seed no GAS Component. CharName/Guild
// vem separado via S_CHAR_INFO -> HandleZeusCharInfo. AttributeComponent vive // vem separado via S_CHAR_INFO -> HandleZeusCharInfo. UZeusGASComponent
// como subobject e recebe seed pra que o ZMMOAttributeNetworkHandler consiga // vive como subobject do PlayerState (Component Registry) e recebe seed
// rotear o snapshot por EntityId desde o primeiro pacote. // pra que o UZeusGASNetworkHandler consiga rotear o snapshot por
// EntityId desde o primeiro pacote.
if (APlayerState* PS = GetPlayerState()) if (APlayerState* PS = GetPlayerState())
{ {
if (AZMMOPlayerState* ZMMOPs = Cast<AZMMOPlayerState>(PS)) if (AZeusPlayerState* ZeusPs = Cast<AZeusPlayerState>(PS))
{ {
ZMMOPs->SetPublicIdentity(InEntityId, /*CharId*/ FString(), ZeusPs->SetPublicIdentity(InEntityId, /*CharId*/ FString(),
/*BaseLevel*/ 1, /*ClassId*/ 0); /*BaseLevel*/ 1, /*ClassId*/ 0);
} }
if (UZMMOAttributeComponent* AttrComp = PS->FindComponentByClass<UZMMOAttributeComponent>()) if (UZeusGASComponent* GASComp = PS->FindComponentByClass<UZeusGASComponent>())
{ {
AttrComp->SeedEntityId(InEntityId); GASComp->SeedEntityId(InEntityId);
} }
} }
// Aplica char info cacheada (caso S_CHAR_INFO tenha chegado antes do PS existir). // Aplica char info cacheada (caso S_CHAR_INFO tenha chegado antes do PS existir).
TryApplyCachedCharInfo(); TryApplyCachedCharInfo();
// UI in-game e' responsabilidade do AZMMOHUD (GameMode.HUDClass), nao do // UI in-game e' responsabilidade do AZeusHUD (GameMode.HUDClass), nao do
// Pawn. AHUD::BeginPlay chama UUIInGameFlowSubsystem::StartInGame, que // Pawn. AHUD::BeginPlay chama UUIInGameFlowSubsystem::StartInGame, que
// pushea WBP_HUD em UI.Layer.Game. UZMMOHudWidget::NativeOnActivated auto-binda // pushea WBP_HUD em UI.Layer.Game. UZeusHudWidget::NativeOnActivated auto-binda
// no UZMMOAttributeComponent via PlayerState. // no UZeusGASComponent via PlayerState.
} }
void AZMMOPlayerCharacter::HandleZeusCharInfo(const int64 InEntityId, const FString& CharName, const FString& GuildName) void AZeusCharacter::HandleZeusCharInfo(const int64 InEntityId, const FString& CharName, const FString& GuildName)
{ {
UE_LOG(LogZMMOPlayer, Log, UE_LOG(LogZeusPlayer, Log,
TEXT("AZMMOPlayerCharacter: S_CHAR_INFO recebido EntityId=%lld name=%s guild=%s"), TEXT("AZeusCharacter: S_CHAR_INFO recebido EntityId=%lld name=%s guild=%s"),
InEntityId, *CharName, *GuildName); InEntityId, *CharName, *GuildName);
// 2026-06-03 fix: server envia S_CHAR_INFO de TODOS os players (proprio +
// catch-up de proxies pre-existentes). Sem este filtro, o nome do ultimo
// proxy recebido sobrescrevia o do pawn local (ex: player Mateuus loga e
// ve "Olatudook" em si mesmo porque o catch-up do Olatudook chegou depois
// do S_CHAR_INFO proprio). Proxies remotos sao roteados pelo registry no
// UZeusWorldSubsystem (futuro nameplate por EntityId).
if (ZeusEntityId != 0 && InEntityId != ZeusEntityId)
{
return;
}
APlayerState* PS = GetPlayerState(); APlayerState* PS = GetPlayerState();
if (!PS) if (!PS)
{ {
@@ -396,13 +451,13 @@ void AZMMOPlayerCharacter::HandleZeusCharInfo(const int64 InEntityId, const FStr
// HandleLocalSpawnReady ou em outra oportunidade. // HandleLocalSpawnReady ou em outra oportunidade.
return; return;
} }
if (AZMMOPlayerState* ZMMOPs = Cast<AZMMOPlayerState>(PS)) if (AZeusPlayerState* ZeusPs = Cast<AZeusPlayerState>(PS))
{ {
ZMMOPs->SetCharInfo(CharName, GuildName); ZeusPs->SetCharInfo(CharName, GuildName);
} }
} }
void AZMMOPlayerCharacter::TryApplyCachedCharInfo() void AZeusCharacter::TryApplyCachedCharInfo()
{ {
if (!ZeusNetwork) if (!ZeusNetwork)
{ {
@@ -417,14 +472,14 @@ void AZMMOPlayerCharacter::TryApplyCachedCharInfo()
} }
if (APlayerState* PS = GetPlayerState()) if (APlayerState* PS = GetPlayerState())
{ {
if (AZMMOPlayerState* ZMMOPs = Cast<AZMMOPlayerState>(PS)) if (AZeusPlayerState* ZeusPs = Cast<AZeusPlayerState>(PS))
{ {
ZMMOPs->SetCharInfo(CachedCharName, CachedGuildName); ZeusPs->SetCharInfo(CachedCharName, CachedGuildName);
} }
} }
} }
void AZMMOPlayerCharacter::FlushInputAxisToServer(const float DeltaSeconds) void AZeusCharacter::FlushInputAxisToServer(const float DeltaSeconds)
{ {
ResolveZeusNetworkSubsystem(); ResolveZeusNetworkSubsystem();
if (!ZeusNetwork || !ZeusNetwork->IsConnected()) if (!ZeusNetwork || !ZeusNetwork->IsConnected())

View File

@@ -3,9 +3,9 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Character.h" #include "GameFramework/Character.h"
#include "Logging/LogMacros.h" #include "Logging/LogMacros.h"
#include "ZMMOEntityInterface.h" #include "ZeusEntityInterface.h"
#include "ZMMOEntityTypes.h" #include "ZeusEntityTypes.h"
#include "ZMMOPlayerCharacter.generated.h" #include "ZeusCharacter.generated.h"
class USpringArmComponent; class USpringArmComponent;
class UCameraComponent; class UCameraComponent;
@@ -13,13 +13,12 @@ class UInputAction;
class UZeusNetworkSubsystem; class UZeusNetworkSubsystem;
struct FInputActionValue; struct FInputActionValue;
DECLARE_LOG_CATEGORY_EXTERN(LogZMMOPlayer, Log, All); DECLARE_LOG_CATEGORY_EXTERN(LogZeusPlayer, Log, All);
/** /**
* AZMMOPlayerCharacter * AZeusCharacter
* *
* Personagem do jogador local. Diferente do template `ThirdPersonCharacter` * Personagem do jogador local. Parte do pipeline de rede Zeus:
* e do antigo `AZMMOCharacter`, este ator e parte do pipeline de rede Zeus:
* *
* - Continua a usar o `UCharacterMovementComponent` LIVRE para correr a * - Continua a usar o `UCharacterMovementComponent` LIVRE para correr a
* fisica do landscape (ADR 0038): o cliente e autoritativo localmente * fisica do landscape (ADR 0038): o cliente e autoritativo localmente
@@ -27,15 +26,15 @@ DECLARE_LOG_CATEGORY_EXTERN(LogZMMOPlayer, Log, All);
* - Envia `C_INPUT_AXIS` ao `UZeusNetworkSubsystem` na cadencia * - Envia `C_INPUT_AXIS` ao `UZeusNetworkSubsystem` na cadencia
* `InputSendRateHz` (com heartbeat 5 Hz quando parado para evitar * `InputSendRateHz` (com heartbeat 5 Hz quando parado para evitar
* starvation do `MovementSystem` no servidor). * starvation do `MovementSystem` no servidor).
* - Implementa `IZMMOEntityInterface` para participar do registry do * - Implementa `IZeusEntityInterface` para participar do registry do
* `UZMMOWorldSubsystem`, mas `ApplyEntitySnapshot` e `SetEntityRelevant` * `UZeusWorldSubsystem`, mas `ApplyEntitySnapshot` e `SetEntityRelevant`
* sao no-op em V0 o cliente local nao reconcilia (cliente solto). * sao no-op em V0 o cliente local nao reconcilia (cliente solto).
* *
* TODO V1: reconciliacao opcional XY quando colisao de objetos chegar; AOI * TODO V1: reconciliacao opcional XY quando colisao de objetos chegar; AOI
* debug spheres; visual smoothing apos correcao do servidor. * debug spheres; visual smoothing apos correcao do servidor.
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API AZMMOPlayerCharacter : public ACharacter, public IZMMOEntityInterface class ZMMO_API AZeusCharacter : public ACharacter, public IZeusEntityInterface
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -47,8 +46,8 @@ class ZMMO_API AZMMOPlayerCharacter : public ACharacter, public IZMMOEntityInter
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true")) UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
UCameraComponent* FollowCamera; UCameraComponent* FollowCamera;
// AttributeComponent vive no PlayerState (AZMMOPlayerState + Component Registry). // GAS Component vive no PlayerState (AZeusPlayerState + Component Registry).
// Acesso: GetPlayerState<AZMMOPlayerState>()->GetZMMOComponent<UZMMOAttributeComponent>(). // Acesso: GetPlayerState<AZeusPlayerState>()->GetZeusComponent<UZeusGASComponent>().
protected: protected:
UPROPERTY(EditAnywhere, Category = "Input") UPROPERTY(EditAnywhere, Category = "Input")
@@ -63,8 +62,13 @@ protected:
UPROPERTY(EditAnywhere, Category = "Input") UPROPERTY(EditAnywhere, Category = "Input")
UInputAction* MouseLookAction; UInputAction* MouseLookAction;
/// IA_Dash — dispara C_ABILITY_TRY_ACTIVATE pra Zeus.Ability.Movement.Dash
/// via UZeusGASComponent. Bind padrao no IMC_Default: LeftShift -> Pressed.
UPROPERTY(EditAnywhere, Category = "Input")
UInputAction* DashAction;
/** Cadencia de envio dos pacotes `C_INPUT_AXIS` (Hz). */ /** Cadencia de envio dos pacotes `C_INPUT_AXIS` (Hz). */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ZMMO|Networking", meta = (ClampMin = "1", ClampMax = "120")) UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zeus|Networking", meta = (ClampMin = "1", ClampMax = "120"))
int32 InputSendRateHz = 30; int32 InputSendRateHz = 30;
/** /**
@@ -73,22 +77,22 @@ protected:
* evitar starvation do servidor caso pacotes sejam perdidos. Em movimento * evitar starvation do servidor caso pacotes sejam perdidos. Em movimento
* o envio segue `InputSendRateHz` (30 Hz). * o envio segue `InputSendRateHz` (30 Hz).
*/ */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ZMMO|Networking", meta = (ClampMin = "0.05", ClampMax = "5.0")) UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zeus|Networking", meta = (ClampMin = "0.05", ClampMax = "5.0"))
float HeartbeatIntervalSec = 0.2f; float HeartbeatIntervalSec = 0.2f;
public: public:
AZMMOPlayerCharacter(); AZeusCharacter();
virtual void Tick(float DeltaSeconds) override; virtual void Tick(float DeltaSeconds) override;
// --- IZMMOEntityInterface --- // --- IZeusEntityInterface ---
virtual int64 GetZMMOEntityId() const override { return ZMMOEntityId; } virtual int64 GetZeusEntityId() const override { return ZeusEntityId; }
virtual EZMMOEntityType GetZMMOEntityType() const override { return EZMMOEntityType::Player; } virtual EZeusEntityType GetZeusEntityType() const override { return EZeusEntityType::Player; }
virtual void ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot) override; virtual void ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot) override;
virtual void SetEntityRelevant(bool bRelevant) override; virtual void SetEntityRelevant(bool bRelevant) override;
UFUNCTION(BlueprintCallable, Category = "ZMMO|Entity") UFUNCTION(BlueprintCallable, Category = "Zeus|Entity")
void SetZMMOEntityId(int64 InEntityId) { ZMMOEntityId = InEntityId; } void SetZeusEntityId(int64 InEntityId) { ZeusEntityId = InEntityId; }
FORCEINLINE USpringArmComponent* GetCameraBoom() const { return CameraBoom; } FORCEINLINE USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
FORCEINLINE UCameraComponent* GetFollowCamera() const { return FollowCamera; } FORCEINLINE UCameraComponent* GetFollowCamera() const { return FollowCamera; }
@@ -105,6 +109,11 @@ protected:
void OnJumpPressed(); void OnJumpPressed();
void OnJumpReleased(); void OnJumpReleased();
/// IA_Dash Triggered -> resolve UZeusGASComponent do PlayerState e chama
/// RequestActivateAbilityByTag("Zeus.Ability.Movement.Dash"). Server valida
/// + responde S_ABILITY_ACTIVATED (HP/SP atualizado, montage roda local).
void OnDashTriggered();
public: public:
/** Wrappers expostos a Blueprint (UI / mobile / automation). */ /** Wrappers expostos a Blueprint (UI / mobile / automation). */
UFUNCTION(BlueprintCallable, Category = "Input") UFUNCTION(BlueprintCallable, Category = "Input")
@@ -131,7 +140,7 @@ private:
void TryRegisterLocalEntityFromCachedSpawn(); void TryRegisterLocalEntityFromCachedSpawn();
/** /**
* Memoriza `EntityId` autoritativo e regista o pawn no `UZMMOWorldSubsystem` * Memoriza `EntityId` autoritativo e regista o pawn no `UZeusWorldSubsystem`
* para o registry partilhado por proxies remotos (filtra snapshots locais). * para o registry partilhado por proxies remotos (filtra snapshots locais).
* Metadados publicos do char (Name/Guild) chegam via S_CHAR_INFO em * Metadados publicos do char (Name/Guild) chegam via S_CHAR_INFO em
* HandleZeusCharInfo (servidor envia ANTES de S_SPAWN_PLAYER). * HandleZeusCharInfo (servidor envia ANTES de S_SPAWN_PLAYER).
@@ -152,8 +161,8 @@ private:
bool bSpawnDelegateBound = false; bool bSpawnDelegateBound = false;
/** Identidade autoritativa atribuida quando o servidor envia S_SPAWN_PLAYER local. */ /** Identidade autoritativa atribuida quando o servidor envia S_SPAWN_PLAYER local. */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity", meta = (AllowPrivateAccess = "true")) UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity", meta = (AllowPrivateAccess = "true"))
int64 ZMMOEntityId = 0; int64 ZeusEntityId = 0;
float PendingMoveForward = 0.0f; float PendingMoveForward = 0.0f;
float PendingMoveRight = 0.0f; float PendingMoveRight = 0.0f;

View File

@@ -1,31 +1,31 @@
#include "ZMMOEntity.h" #include "ZeusEntity.h"
AZMMOEntity::AZMMOEntity() AZeusEntity::AZeusEntity()
{ {
PrimaryActorTick.bCanEverTick = false; PrimaryActorTick.bCanEverTick = false;
bReplicates = false; bReplicates = false;
} }
void AZMMOEntity::SetZMMOIdentity(const int64 InEntityId, const EZMMOEntityType InEntityType) void AZeusEntity::SetZeusIdentity(const int64 InEntityId, const EZeusEntityType InEntityType)
{ {
EntityId = InEntityId; EntityId = InEntityId;
EntityType = InEntityType; EntityType = InEntityType;
} }
void AZMMOEntity::ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot) void AZeusEntity::ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot)
{ {
const FRotator NewRotation(0.0f, Snapshot.YawDeg, 0.0f); const FRotator NewRotation(0.0f, Snapshot.YawDeg, 0.0f);
SetActorLocationAndRotation(Snapshot.PositionCm, NewRotation); SetActorLocationAndRotation(Snapshot.PositionCm, NewRotation);
} }
void AZMMOEntity::SetEntityRelevant(const bool bRelevant) void AZeusEntity::SetEntityRelevant(const bool bRelevant)
{ {
if (bIsZMMORelevant == bRelevant) if (bIsZeusRelevant == bRelevant)
{ {
return; return;
} }
bIsZMMORelevant = bRelevant; bIsZeusRelevant = bRelevant;
SetActorHiddenInGame(!bRelevant); SetActorHiddenInGame(!bRelevant);
SetActorEnableCollision(bRelevant); SetActorEnableCollision(bRelevant);
SetActorTickEnabled(bRelevant); SetActorTickEnabled(bRelevant);

View File

@@ -2,22 +2,22 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "ZMMOEntityInterface.h" #include "ZeusEntityInterface.h"
#include "ZMMOEntityTypes.h" #include "ZeusEntityTypes.h"
#include "ZMMOEntity.generated.h" #include "ZeusEntity.generated.h"
/** /**
* AZMMOEntity * AZeusEntity
* *
* Classe base para entidades replicadas pelo servidor que NAO precisam de * Classe base para entidades replicadas pelo servidor que NAO precisam de
* capsula + `UCharacterMovementComponent` tipicamente NPCs estaticos, * capsula + `UCharacterMovementComponent` tipicamente NPCs estaticos,
* objetos dinamicos do mundo, mobs simples sem locomotion fisica. * objetos dinamicos do mundo, mobs simples sem locomotion fisica.
* *
* Para personagens com capsula + CMC (proxy de jogador, mobs com locomotion * Para personagens com capsula + CMC (proxy de jogador, mobs com locomotion
* por capsula), use `AZMMOPlayerProxy` ou uma futura `AZMMOMob` que herde * por capsula), use `AZeusPlayerProxy` ou uma futura `AZeusMob` que herde
* de `ACharacter`. * de `ACharacter`.
* *
* Implementa `IZMMOEntityInterface` com: * Implementa `IZeusEntityInterface` com:
* - getters para `EntityId` / `EntityType`; * - getters para `EntityId` / `EntityType`;
* - `ApplyEntitySnapshot` default: `SetActorLocationAndRotation` (sem * - `ApplyEntitySnapshot` default: `SetActorLocationAndRotation` (sem
* interpolacao temporal V1 podera adicionar ring-buffer + lerp); * interpolacao temporal V1 podera adicionar ring-buffer + lerp);
@@ -25,33 +25,33 @@
* desativa tick (preserva o ator no mundo para futuro pooling). * desativa tick (preserva o ator no mundo para futuro pooling).
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API AZMMOEntity : public AActor, public IZMMOEntityInterface class ZMMO_API AZeusEntity : public AActor, public IZeusEntityInterface
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOEntity(); AZeusEntity();
// --- IZMMOEntityInterface --- // --- IZeusEntityInterface ---
virtual int64 GetZMMOEntityId() const override { return EntityId; } virtual int64 GetZeusEntityId() const override { return EntityId; }
virtual EZMMOEntityType GetZMMOEntityType() const override { return EntityType; } virtual EZeusEntityType GetZeusEntityType() const override { return EntityType; }
virtual void ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot) override; virtual void ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot) override;
virtual void SetEntityRelevant(bool bRelevant) override; virtual void SetEntityRelevant(bool bRelevant) override;
/** Setter usado pelo `UZMMOWorldSubsystem` apos o spawn para registrar a identidade. */ /** Setter usado pelo `UZeusWorldSubsystem` apos o spawn para registrar a identidade. */
UFUNCTION(BlueprintCallable, Category = "ZMMO|Entity") UFUNCTION(BlueprintCallable, Category = "Zeus|Entity")
void SetZMMOIdentity(int64 InEntityId, EZMMOEntityType InEntityType); void SetZeusIdentity(int64 InEntityId, EZeusEntityType InEntityType);
protected: protected:
/** Identificador autoritativo do servidor. Atribuido em `SetZMMOIdentity`. */ /** Identificador autoritativo do servidor. Atribuido em `SetZeusIdentity`. */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
int64 EntityId = 0; int64 EntityId = 0;
/** Categoria autoritativa (Player/Mob/NPC/Object). */ /** Categoria autoritativa (Player/Mob/NPC/Object). */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
EZMMOEntityType EntityType = EZMMOEntityType::Object; EZeusEntityType EntityType = EZeusEntityType::Object;
/** Estado de relevancia atual (espelha as transicoes Hidden<->Relevant do servidor). */ /** Estado de relevancia atual (espelha as transicoes Hidden<->Relevant do servidor). */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
bool bIsZMMORelevant = true; bool bIsZeusRelevant = true;
}; };

View File

@@ -2,27 +2,27 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "UObject/Interface.h" #include "UObject/Interface.h"
#include "ZMMOEntityTypes.h" #include "ZeusEntityTypes.h"
#include "ZMMOEntityInterface.generated.h" #include "ZeusEntityInterface.generated.h"
/** /**
* UZMMOEntityInterface * UZeusEntityInterface
* *
* Marcador `UInterface` necessario para o sistema de reflexao da Unreal. Todo o * Marcador `UInterface` necessario para o sistema de reflexao da Unreal. Todo o
* contrato vive em `IZMMOEntityInterface` (puro C++). * contrato vive em `IZeusEntityInterface` (puro C++).
*/ */
UINTERFACE(BlueprintType, MinimalAPI, meta = (CannotImplementInterfaceInBlueprint)) UINTERFACE(BlueprintType, MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
class UZMMOEntityInterface : public UInterface class UZeusEntityInterface : public UInterface
{ {
GENERATED_BODY() GENERATED_BODY()
}; };
/** /**
* IZMMOEntityInterface * IZeusEntityInterface
* *
* Contrato comum de todas as entidades replicadas pelo Zeus Server (player * Contrato comum de todas as entidades replicadas pelo Zeus Server (player
* local, players remotos, mobs, NPCs, objetos). Inspirado em `IZeusEntityInterface` * local, players remotos, mobs, NPCs, objetos). Adaptado para o nosso modelo
* (ZeusV1) e adaptado para o nosso modelo "cliente solto + servidor valida input". * "cliente solto + servidor valida input".
* *
* Decisoes: * Decisoes:
* 1. **Identidade autoritativa**: `EntityId` e `EntityType` vem do servidor; o * 1. **Identidade autoritativa**: `EntityId` e `EntityType` vem do servidor; o
@@ -30,28 +30,28 @@ class UZMMOEntityInterface : public UInterface
* 2. **Visibilidade gated por AOI**: o servidor envia spawn/despawn quando o * 2. **Visibilidade gated por AOI**: o servidor envia spawn/despawn quando o
* target entra/sai da area de interesse. O cliente reage via * target entra/sai da area de interesse. O cliente reage via
* `SetEntityRelevant(bool)`. * `SetEntityRelevant(bool)`.
* 3. **Player local nao reconcilia em V0**: para o `AZMMOPlayerCharacter` o * 3. **Player local nao reconcilia em V0**: para o `AZeusCharacter` o
* `ApplyEntitySnapshot` e no-op (cliente solto controla landscape). Quando * `ApplyEntitySnapshot` e no-op (cliente solto controla landscape). Quando
* a colisao de objetos chegar no servidor podemos ligar reconciliacao * a colisao de objetos chegar no servidor podemos ligar reconciliacao
* horizontal opcional. * horizontal opcional.
* *
* Por que UInterface (e nao heranca classica)? * Por que UInterface (e nao heranca classica)?
* - `AZMMOPlayerCharacter` ja herda de `ACharacter`. Forcar uma classe base * - `AZeusCharacter` ja herda de `ACharacter`. Forcar uma classe base
* `AZMMOEntity : AActor` para todos perderia o `ACharacter` gratuito. * `AZeusEntity : AActor` para todos perderia o `ACharacter` gratuito.
* A interface permite que o player local (`ACharacter`), o proxy remoto * A interface permite que o player local (`ACharacter`), o proxy remoto
* (`ACharacter`) e entidades genericas (`AActor`) implementem o mesmo * (`ACharacter`) e entidades genericas (`AActor`) implementem o mesmo
* contrato sem heranca multipla concreta. * contrato sem heranca multipla concreta.
*/ */
class ZMMO_API IZMMOEntityInterface class ZMMO_API IZeusEntityInterface
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
/** Identificador autoritativo da entidade no servidor. */ /** Identificador autoritativo da entidade no servidor. */
virtual int64 GetZMMOEntityId() const = 0; virtual int64 GetZeusEntityId() const = 0;
/** Categoria da entidade (Player, Mob, NPC, Object). */ /** Categoria da entidade (Player, Mob, NPC, Object). */
virtual EZMMOEntityType GetZMMOEntityType() const = 0; virtual EZeusEntityType GetZeusEntityType() const = 0;
/** /**
* Aplica um snapshot autoritativo. Implementacoes podem extender com * Aplica um snapshot autoritativo. Implementacoes podem extender com
@@ -61,7 +61,7 @@ public:
* fisica do landscape de forma autoritativa local, e o servidor apenas * fisica do landscape de forma autoritativa local, e o servidor apenas
* valida input/velocidade (ADR 0038). * valida input/velocidade (ADR 0038).
*/ */
virtual void ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot) = 0; virtual void ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot) = 0;
/** /**
* Alterna entre estado visivel/ativo (`true`) e oculto/desativado (`false`). * Alterna entre estado visivel/ativo (`true`) e oculto/desativado (`false`).

View File

@@ -1,14 +1,14 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "ZMMOEntityTypes.generated.h" #include "ZeusEntityTypes.generated.h"
/** /**
* Categoria autoritativa replicada pelo servidor. Determina que classe de ator * Categoria autoritativa replicada pelo servidor. Determina que classe de ator
* o `UZMMOWorldSubsystem` deve spawnar para um snapshot recebido. * o `UZeusWorldSubsystem` deve spawnar para um snapshot recebido.
*/ */
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOEntityType : uint8 enum class EZeusEntityType : uint8
{ {
Player UMETA(DisplayName = "Player"), Player UMETA(DisplayName = "Player"),
Mob UMETA(DisplayName = "Mob"), Mob UMETA(DisplayName = "Mob"),
@@ -17,48 +17,48 @@ enum class EZMMOEntityType : uint8
}; };
/** /**
* Snapshot autoritativo aplicado por `IZMMOEntityInterface::ApplyEntitySnapshot`. * Snapshot autoritativo aplicado por `IZeusEntityInterface::ApplyEntitySnapshot`.
* *
* Construido pelo `UZMMOWorldSubsystem` a partir dos delegates do * Construido pelo `UZeusWorldSubsystem` a partir dos delegates do
* `UZeusNetworkSubsystem` (`OnPlayerStateUpdate` em V0; opcodes para mobs/NPCs * `UZeusNetworkSubsystem` (`OnPlayerStateUpdate` em V0; opcodes para mobs/NPCs
* em V1+). Mantemos os campos minimos que o servidor ja replica hoje * em V1+). Mantemos os campos minimos que o servidor ja replica hoje
* (`S_PLAYER_STATE`); novos campos sao adicionados aqui sempre que o protocolo * (`S_PLAYER_STATE`); novos campos sao adicionados aqui sempre que o protocolo
* evoluir, sem mexer nas classes de proxy. * evoluir, sem mexer nas classes de proxy.
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct FZMMOEntitySnapshot struct FZeusEntitySnapshot
{ {
GENERATED_BODY() GENERATED_BODY()
/** EntityId autoritativo do servidor. */ /** EntityId autoritativo do servidor. */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
int64 EntityId = 0; int64 EntityId = 0;
/** Categoria do ator (define qual proxy class spawnar). */ /** Categoria do ator (define qual proxy class spawnar). */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
EZMMOEntityType EntityType = EZMMOEntityType::Player; EZeusEntityType EntityType = EZeusEntityType::Player;
/** Sequencia de input processada no servidor (so faz sentido para players). */ /** Sequencia de input processada no servidor (so faz sentido para players). */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
int32 LastProcessedInputSeq = 0; int32 LastProcessedInputSeq = 0;
/** Posicao mundo (cm). */ /** Posicao mundo (cm). */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
FVector PositionCm = FVector::ZeroVector; FVector PositionCm = FVector::ZeroVector;
/** Velocidade mundo (cm/s) — usada para network smoothing e drivers de animacao. */ /** Velocidade mundo (cm/s) — usada para network smoothing e drivers de animacao. */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
FVector VelocityCmS = FVector::ZeroVector; FVector VelocityCmS = FVector::ZeroVector;
/** Yaw em graus (orientacao visual). */ /** Yaw em graus (orientacao visual). */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
float YawDeg = 0.0f; float YawDeg = 0.0f;
/** Indica se o servidor considera o ator em solo. */ /** Indica se o servidor considera o ator em solo. */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
bool bGrounded = false; bool bGrounded = false;
/** Tempo do servidor (ms desde epoch) quando este snapshot foi gerado. */ /** Tempo do servidor (ms desde epoch) quando este snapshot foi gerado. */
UPROPERTY(BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(BlueprintReadOnly, Category = "Zeus|Entity")
int64 ServerTimeMs = 0; int64 ServerTimeMs = 0;
}; };

View File

@@ -1,4 +1,4 @@
#include "ZMMOPlayerProxy.h" #include "ZeusPlayerProxy.h"
#include "Animation/AnimInstance.h" #include "Animation/AnimInstance.h"
#include "Components/CapsuleComponent.h" #include "Components/CapsuleComponent.h"
@@ -8,10 +8,10 @@
#include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/CharacterMovementComponent.h"
#include "UObject/ConstructorHelpers.h" #include "UObject/ConstructorHelpers.h"
#include "ZMMO.h" #include "ZMMO.h"
#include "ZMMOProxyMovementComponent.h" #include "ZeusProxyMovementComponent.h"
AZMMOPlayerProxy::AZMMOPlayerProxy(const FObjectInitializer& ObjectInitializer) AZeusPlayerProxy::AZeusPlayerProxy(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<UZMMOProxyMovementComponent>(ACharacter::CharacterMovementComponentName)) : Super(ObjectInitializer.SetDefaultSubobjectClass<UZeusProxyMovementComponent>(ACharacter::CharacterMovementComponentName))
{ {
PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true; PrimaryActorTick.bStartWithTickEnabled = true;
@@ -43,7 +43,7 @@ AZMMOPlayerProxy::AZMMOPlayerProxy(const FObjectInitializer& ObjectInitializer)
CMC->BrakingFrictionFactor = 0.0f; CMC->BrakingFrictionFactor = 0.0f;
} }
// Defaults visuais (mesh + AnimBP) em paridade com `AZMMOPlayerCharacter`. // Defaults visuais (mesh + AnimBP) em paridade com `AZeusCharacter`.
if (USkeletalMeshComponent* MeshComponent = GetMesh()) if (USkeletalMeshComponent* MeshComponent = GetMesh())
{ {
static ConstructorHelpers::FObjectFinder<USkeletalMesh> QuinnMesh( static ConstructorHelpers::FObjectFinder<USkeletalMesh> QuinnMesh(
@@ -60,7 +60,7 @@ AZMMOPlayerProxy::AZMMOPlayerProxy(const FObjectInitializer& ObjectInitializer)
else else
{ {
UE_LOG(LogZMMO, Warning, UE_LOG(LogZMMO, Warning,
TEXT("AZMMOPlayerProxy: SKM_Quinn_Simple nao encontrado em /Game/Characters/Mannequins/Meshes.")); TEXT("AZeusPlayerProxy: SKM_Quinn_Simple nao encontrado em /Game/Characters/Mannequins/Meshes."));
} }
if (QuinnAnimBp.Succeeded()) if (QuinnAnimBp.Succeeded())
@@ -71,7 +71,7 @@ AZMMOPlayerProxy::AZMMOPlayerProxy(const FObjectInitializer& ObjectInitializer)
else else
{ {
UE_LOG(LogZMMO, Warning, UE_LOG(LogZMMO, Warning,
TEXT("AZMMOPlayerProxy: ABP_Unarmed nao encontrado em /Game/Characters/Mannequins/Anims/Unarmed.")); TEXT("AZeusPlayerProxy: ABP_Unarmed nao encontrado em /Game/Characters/Mannequins/Anims/Unarmed."));
} }
} }
@@ -80,7 +80,7 @@ AZMMOPlayerProxy::AZMMOPlayerProxy(const FObjectInitializer& ObjectInitializer)
bUseControllerRotationRoll = false; bUseControllerRotationRoll = false;
} }
void AZMMOPlayerProxy::BeginPlay() void AZeusPlayerProxy::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
@@ -94,7 +94,7 @@ void AZMMOPlayerProxy::BeginPlay()
} }
} }
void AZMMOPlayerProxy::Tick(const float DeltaSeconds) void AZeusPlayerProxy::Tick(const float DeltaSeconds)
{ {
Super::Tick(DeltaSeconds); Super::Tick(DeltaSeconds);
@@ -131,7 +131,7 @@ void AZMMOPlayerProxy::Tick(const float DeltaSeconds)
// Sem snapshot futuro: extrapolacao curta com a ultima velocidade // Sem snapshot futuro: extrapolacao curta com a ultima velocidade
// conhecida, clampada por `MaxExtrapolationSeconds` para nao deixar // conhecida, clampada por `MaxExtrapolationSeconds` para nao deixar
// o proxy fugir se a rede ficar muda. // o proxy fugir se a rede ficar muda.
const FZMMOProxySnapshot& Last = SnapshotBuffer.Last(); const FZeusProxySnapshot& Last = SnapshotBuffer.Last();
const float ExtrapSec = FMath::Clamp( const float ExtrapSec = FMath::Clamp(
static_cast<float>(RenderMs - Last.ServerTimeMs) / 1000.0f, static_cast<float>(RenderMs - Last.ServerTimeMs) / 1000.0f,
0.0f, MaxExtrapolationSeconds); 0.0f, MaxExtrapolationSeconds);
@@ -141,8 +141,8 @@ void AZMMOPlayerProxy::Tick(const float DeltaSeconds)
} }
else else
{ {
const FZMMOProxySnapshot& A = SnapshotBuffer[IdxB - 1]; const FZeusProxySnapshot& A = SnapshotBuffer[IdxB - 1];
const FZMMOProxySnapshot& B = SnapshotBuffer[IdxB]; const FZeusProxySnapshot& B = SnapshotBuffer[IdxB];
const double Span = FMath::Max<double>(1.0, static_cast<double>(B.ServerTimeMs - A.ServerTimeMs)); const double Span = FMath::Max<double>(1.0, static_cast<double>(B.ServerTimeMs - A.ServerTimeMs));
InterpAlpha = static_cast<float>(FMath::Clamp( InterpAlpha = static_cast<float>(FMath::Clamp(
static_cast<double>(RenderMs - A.ServerTimeMs) / Span, 0.0, 1.0)); static_cast<double>(RenderMs - A.ServerTimeMs) / Span, 0.0, 1.0));
@@ -208,19 +208,19 @@ void AZMMOPlayerProxy::Tick(const float DeltaSeconds)
const int64 NewestMs = SnapshotBuffer.Last().ServerTimeMs; const int64 NewestMs = SnapshotBuffer.Last().ServerTimeMs;
const int64 RenderLagMs = ServerNowMs - NewestMs; const int64 RenderLagMs = ServerNowMs - NewestMs;
UE_LOG(LogZMMO, Verbose, UE_LOG(LogZMMO, Verbose,
TEXT("ZMMOPlayerProxy[%lld] buffer=%d renderLagMs=%lld interpAlpha=%.2f extrap=%d delayMs=%.0f"), TEXT("ZeusPlayerProxy[%lld] buffer=%d renderLagMs=%lld interpAlpha=%.2f extrap=%d delayMs=%.0f"),
EntityId, SnapshotBuffer.Num(), RenderLagMs, InterpAlpha, EntityId, SnapshotBuffer.Num(), RenderLagMs, InterpAlpha,
bExtrapolating ? 1 : 0, InterpolationDelayMs); bExtrapolating ? 1 : 0, InterpolationDelayMs);
} }
} }
void AZMMOPlayerProxy::SetZMMOIdentity(const int64 InEntityId, const EZMMOEntityType InEntityType) void AZeusPlayerProxy::SetZeusIdentity(const int64 InEntityId, const EZeusEntityType InEntityType)
{ {
EntityId = InEntityId; EntityId = InEntityId;
EntityType = InEntityType; EntityType = InEntityType;
} }
void AZMMOPlayerProxy::ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot) void AZeusPlayerProxy::ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot)
{ {
// Estabiliza o offset de relogio na primeira amostra. Subsequente nao // Estabiliza o offset de relogio na primeira amostra. Subsequente nao
// re-sincroniza para evitar saltos visuais; um esquema mais sofisticado // re-sincroniza para evitar saltos visuais; um esquema mais sofisticado
@@ -231,7 +231,7 @@ void AZMMOPlayerProxy::ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot)
ServerClockOffsetMs = LocalNowMs - Snapshot.ServerTimeMs; ServerClockOffsetMs = LocalNowMs - Snapshot.ServerTimeMs;
} }
FZMMOProxySnapshot S; FZeusProxySnapshot S;
S.PosCm = Snapshot.PositionCm; S.PosCm = Snapshot.PositionCm;
S.VelCmS = Snapshot.VelocityCmS; S.VelCmS = Snapshot.VelocityCmS;
S.bGrounded = Snapshot.bGrounded; S.bGrounded = Snapshot.bGrounded;
@@ -282,20 +282,20 @@ void AZMMOPlayerProxy::ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot)
ApplyCollisionPolicy(); ApplyCollisionPolicy();
} }
void AZMMOPlayerProxy::SetEntityRelevant(const bool bRelevant) void AZeusPlayerProxy::SetEntityRelevant(const bool bRelevant)
{ {
if (bIsZMMORelevant == bRelevant) if (bIsZeusRelevant == bRelevant)
{ {
return; return;
} }
bIsZMMORelevant = bRelevant; bIsZeusRelevant = bRelevant;
SetActorHiddenInGame(!bRelevant); SetActorHiddenInGame(!bRelevant);
SetActorTickEnabled(bRelevant); SetActorTickEnabled(bRelevant);
ApplyCollisionPolicy(); ApplyCollisionPolicy();
} }
void AZMMOPlayerProxy::RefreshAnimationDrivers() void AZeusPlayerProxy::RefreshAnimationDrivers()
{ {
UCharacterMovementComponent* CMC = GetCharacterMovement(); UCharacterMovementComponent* CMC = GetCharacterMovement();
if (!CMC) if (!CMC)
@@ -314,13 +314,13 @@ void AZMMOPlayerProxy::RefreshAnimationDrivers()
// Acceleration externa via CMC custom — alimenta `Get Current Acceleration` // Acceleration externa via CMC custom — alimenta `Get Current Acceleration`
// que o AnimBP do Quinn usa em `ShouldMove` e nas transições de Jump_Start. // que o AnimBP do Quinn usa em `ShouldMove` e nas transições de Jump_Start.
if (UZMMOProxyMovementComponent* ProxyCMC = Cast<UZMMOProxyMovementComponent>(CMC)) if (UZeusProxyMovementComponent* ProxyCMC = Cast<UZeusProxyMovementComponent>(CMC))
{ {
ProxyCMC->SetZMMOExternalAcceleration(LastDerivedAccelerationCmS2); ProxyCMC->SetZeusExternalAcceleration(LastDerivedAccelerationCmS2);
} }
} }
void AZMMOPlayerProxy::ApplyCollisionPolicy() void AZeusPlayerProxy::ApplyCollisionPolicy()
{ {
UCapsuleComponent* Capsule = GetCapsuleComponent(); UCapsuleComponent* Capsule = GetCapsuleComponent();
if (!Capsule) if (!Capsule)
@@ -328,6 +328,6 @@ void AZMMOPlayerProxy::ApplyCollisionPolicy()
return; return;
} }
const bool bShouldCollide = bIsZMMORelevant && bHasFirstSnapshot; const bool bShouldCollide = bIsZeusRelevant && bHasFirstSnapshot;
Capsule->SetCollisionEnabled(bShouldCollide ? ECollisionEnabled::QueryOnly : ECollisionEnabled::NoCollision); Capsule->SetCollisionEnabled(bShouldCollide ? ECollisionEnabled::QueryOnly : ECollisionEnabled::NoCollision);
} }

View File

@@ -2,19 +2,18 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Character.h" #include "GameFramework/Character.h"
#include "ZMMOEntityInterface.h" #include "ZeusEntityInterface.h"
#include "ZMMOEntityTypes.h" #include "ZeusEntityTypes.h"
#include "ZMMOPlayerProxy.generated.h" #include "ZeusPlayerProxy.generated.h"
/** /**
* AZMMOPlayerProxy * AZeusPlayerProxy
* *
* Proxy visual para jogadores remotos (e, no futuro, mobs com locomotion * Proxy visual para jogadores remotos (e, no futuro, mobs com locomotion
* por capsula) cuja posicao vem 100% do servidor via snapshots * por capsula) cuja posicao vem 100% do servidor via snapshots
* (`UZeusNetworkSubsystem::OnPlayerStateUpdate`). * (`UZeusNetworkSubsystem::OnPlayerStateUpdate`).
* *
* Inspirado em `AZeusRemoteCharacter` (ZeusV1). Diferencas chave vs. * Diferencas chave vs. `AZeusCharacter` (jogador local):
* `AZMMOPlayerCharacter` (jogador local):
* - SEM `EnhancedInput`, sem envio de `C_INPUT_AXIS`. * - SEM `EnhancedInput`, sem envio de `C_INPUT_AXIS`.
* - SEM buffer de pending inputs nem reconciliacao. * - SEM buffer de pending inputs nem reconciliacao.
* - Posicao aplicada por snapshot (`ApplyEntitySnapshot`); a `ACharacter` * - Posicao aplicada por snapshot (`ApplyEntitySnapshot`); a `ACharacter`
@@ -22,19 +21,18 @@
* mas o CMC fica em modo "kinematic-ish" (nao integra fisica). * mas o CMC fica em modo "kinematic-ish" (nao integra fisica).
* *
* Animacao no AnimBP do Quinn (`ABP_Unarmed`): a formula `ShouldMove` exige * Animacao no AnimBP do Quinn (`ABP_Unarmed`): a formula `ShouldMove` exige
* `Acceleration != 0`. Como proxies nao tem input, adoptamos a mesma * `Acceleration != 0`. Como proxies nao tem input, adoptamos a estrategia
* estrategia do ZClientMMO: CMC custom (`UZMMOProxyMovementComponent`) com * de CMC custom (`UZeusProxyMovementComponent`) com escrita externa de
* escrita externa de `Acceleration`, alimentada pela derivada da velocidade * `Acceleration`, alimentada pela derivada da velocidade entre snapshots.
* entre snapshots. Tick do proxy roda **antes** do mesh tick para que * Tick do proxy roda **antes** do mesh tick para que Velocity+Acceleration
* Velocity+Acceleration estejam populados quando o `NativeUpdateAnimation` * estejam populados quando o `NativeUpdateAnimation` do AnimBP os ler.
* do AnimBP os ler.
*/ */
/** /**
* Snapshot bruto guardado no buffer de interpolacao. Mantido como struct privada * Snapshot bruto guardado no buffer de interpolacao. Mantido como struct privada
* ao .h porque so o proxy (e debugging local) precisa olhar para ele. * ao .h porque so o proxy (e debugging local) precisa olhar para ele.
*/ */
USTRUCT() USTRUCT()
struct FZMMOProxySnapshot struct FZeusProxySnapshot
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -53,37 +51,37 @@ struct FZMMOProxySnapshot
}; };
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API AZMMOPlayerProxy : public ACharacter, public IZMMOEntityInterface class ZMMO_API AZeusPlayerProxy : public ACharacter, public IZeusEntityInterface
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOPlayerProxy(const FObjectInitializer& ObjectInitializer); AZeusPlayerProxy(const FObjectInitializer& ObjectInitializer);
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override; virtual void Tick(float DeltaSeconds) override;
// --- IZMMOEntityInterface --- // --- IZeusEntityInterface ---
virtual int64 GetZMMOEntityId() const override { return EntityId; } virtual int64 GetZeusEntityId() const override { return EntityId; }
virtual EZMMOEntityType GetZMMOEntityType() const override { return EntityType; } virtual EZeusEntityType GetZeusEntityType() const override { return EntityType; }
virtual void ApplyEntitySnapshot(const FZMMOEntitySnapshot& Snapshot) override; virtual void ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot) override;
virtual void SetEntityRelevant(bool bRelevant) override; virtual void SetEntityRelevant(bool bRelevant) override;
UFUNCTION(BlueprintCallable, Category = "ZMMO|Entity") UFUNCTION(BlueprintCallable, Category = "Zeus|Entity")
void SetZMMOIdentity(int64 InEntityId, EZMMOEntityType InEntityType); void SetZeusIdentity(int64 InEntityId, EZeusEntityType InEntityType);
protected: protected:
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
int64 EntityId = 0; int64 EntityId = 0;
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
EZMMOEntityType EntityType = EZMMOEntityType::Player; EZeusEntityType EntityType = EZeusEntityType::Player;
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
bool bIsZMMORelevant = true; bool bIsZeusRelevant = true;
/** True apos o primeiro snapshot ser aplicado — antes disso o ator pode ficar oculto. */ /** True apos o primeiro snapshot ser aplicado — antes disso o ator pode ficar oculto. */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
bool bHasFirstSnapshot = false; bool bHasFirstSnapshot = false;
/** /**
@@ -91,15 +89,15 @@ protected:
* de `InterpolatedPosCm` (visual) separar os dois e essencial para * de `InterpolatedPosCm` (visual) separar os dois e essencial para
* comparar drift autoritativo vs visual via debug overlay/logs. * comparar drift autoritativo vs visual via debug overlay/logs.
*/ */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
FVector AuthoritativePosCm = FVector::ZeroVector; FVector AuthoritativePosCm = FVector::ZeroVector;
/** Posicao **visual** atual (resultado da interpolacao do tick). */ /** Posicao **visual** atual (resultado da interpolacao do tick). */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
FVector InterpolatedPosCm = FVector::ZeroVector; FVector InterpolatedPosCm = FVector::ZeroVector;
/** Compat: alias para `AuthoritativePosCm` (preserva binding de Blueprint, se houver). */ /** Compat: alias para `AuthoritativePosCm` (preserva binding de Blueprint, se houver). */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
FVector LastSnapshotPosition = FVector::ZeroVector; FVector LastSnapshotPosition = FVector::ZeroVector;
/** /**
@@ -108,7 +106,7 @@ protected:
* em cada `Tick` para manter os drivers de animacao alimentados entre * em cada `Tick` para manter os drivers de animacao alimentados entre
* updates de rede. * updates de rede.
*/ */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Entity") UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity")
FVector VisualVelocity = FVector::ZeroVector; FVector VisualVelocity = FVector::ZeroVector;
/** /**
@@ -116,23 +114,23 @@ protected:
* expresso no dominio do tempo do servidor. Padrao 100 ms (~3 snapshots a 30 Hz) * expresso no dominio do tempo do servidor. Padrao 100 ms (~3 snapshots a 30 Hz)
* cobre 1 perda + 1 jitter sem extrapolar. * cobre 1 perda + 1 jitter sem extrapolar.
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ZMMO|Network", UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|Network",
meta = (ClampMin = "0.0", ClampMax = "500.0")) meta = (ClampMin = "0.0", ClampMax = "500.0"))
double InterpolationDelayMs = 100.0; double InterpolationDelayMs = 100.0;
/** Tamanho maximo do buffer (em snapshots). Cobre ~270 ms a 30 Hz. */ /** Tamanho maximo do buffer (em snapshots). Cobre ~270 ms a 30 Hz. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ZMMO|Network", UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|Network",
meta = (ClampMin = "2", ClampMax = "32")) meta = (ClampMin = "2", ClampMax = "32"))
int32 SnapshotBufferCapacity = 8; int32 SnapshotBufferCapacity = 8;
/** Limite duro de extrapolacao (s) quando nao ha snapshot futuro. */ /** Limite duro de extrapolacao (s) quando nao ha snapshot futuro. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ZMMO|Network", UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|Network",
meta = (ClampMin = "0.0", ClampMax = "0.5")) meta = (ClampMin = "0.0", ClampMax = "0.5"))
float MaxExtrapolationSeconds = 0.1f; float MaxExtrapolationSeconds = 0.1f;
/** Buffer ordenado por `ServerTimeMs` ascendente. */ /** Buffer ordenado por `ServerTimeMs` ascendente. */
UPROPERTY() UPROPERTY()
TArray<FZMMOProxySnapshot> SnapshotBuffer; TArray<FZeusProxySnapshot> SnapshotBuffer;
/** /**
* Offset entre o relogio local (`FPlatformTime::Seconds * 1000`) e o * Offset entre o relogio local (`FPlatformTime::Seconds * 1000`) e o

View File

@@ -0,0 +1,24 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "ZeusProxyMovementComponent.generated.h"
/**
* CMC customizado para AZeusPlayerProxy. Expõe escrita direta de Acceleration
* (protected na base) para que o AnimBP veja Acceleration!=0 quando o proxy
* recebe snapshots, alimentando a fórmula ShouldMove e a transição Jump_Start
* do ABP_Unarmed (ambas dependem de aceleração não-nula).
*/
UCLASS(ClassGroup = (Zeus), meta = (BlueprintSpawnableComponent))
class ZMMO_API UZeusProxyMovementComponent : public UCharacterMovementComponent
{
GENERATED_BODY()
public:
void SetZeusExternalAcceleration(const FVector& InAccelerationCmS2)
{
Acceleration = InAccelerationCmS2;
}
};

View File

@@ -1,10 +0,0 @@
#include "ZMMOFrontEndGameMode.h"
#include "ZMMOFrontEndPlayerController.h"
AZMMOFrontEndGameMode::AZMMOFrontEndGameMode()
{
// UI pura: sem pawn. O controller cria o root layout e arranca o fluxo.
DefaultPawnClass = nullptr;
PlayerControllerClass = AZMMOFrontEndPlayerController::StaticClass();
}

View File

@@ -1,14 +0,0 @@
#include "ZMMOGameMode.h"
#include "ZMMOHUD.h"
#include "ZMMOPlayerCharacter.h"
#include "ZMMOPlayerController.h"
#include "ZMMOPlayerState.h"
AZMMOGameMode::AZMMOGameMode()
{
DefaultPawnClass = AZMMOPlayerCharacter::StaticClass();
PlayerControllerClass = AZMMOPlayerController::StaticClass();
PlayerStateClass = AZMMOPlayerState::StaticClass();
HUDClass = AZMMOHUD::StaticClass();
}

View File

@@ -1,100 +0,0 @@
#include "ZMMOPlayerState.h"
#include "Components/ActorComponent.h"
#include "Misc/ConfigCacheIni.h"
#include "Net/UnrealNetwork.h"
#include "ZMMO.h"
AZMMOPlayerState::AZMMOPlayerState()
{
// Component Registry: instancia cada classe declarada em
// DefaultGame.ini::[/Script/ZMMO.ZMMOPlayerState]+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.ZMMOPlayerState"),
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("ZMMOPlayerState: ComponentClasses path nao resolveu: %s"), *Path);
}
}
}
UE_LOG(LogZMMO, Log,
TEXT("AZMMOPlayerState 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("ZMMOPlayerState: ComponentClass null em ComponentClasses[%d]"),
SubobjectIndex);
++SubobjectIndex;
continue;
}
const FName CompName = MakeUniqueObjectName(this, CompClass,
FName(*FString::Printf(TEXT("ZMMOComp_%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("ZMMOPlayerState: componente registrado [%d] %s"),
SubobjectIndex, *CompClass->GetName());
}
else
{
UE_LOG(LogZMMO, Warning,
TEXT("ZMMOPlayerState: CreateDefaultSubobject falhou para %s"),
*CompClass->GetName());
}
++SubobjectIndex;
}
}
void AZMMOPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AZMMOPlayerState, ZMMOEntityId);
DOREPLIFETIME(AZMMOPlayerState, CharId);
DOREPLIFETIME(AZMMOPlayerState, CharName);
DOREPLIFETIME(AZMMOPlayerState, BaseLevel);
DOREPLIFETIME(AZMMOPlayerState, ClassId);
DOREPLIFETIME(AZMMOPlayerState, GuildName);
}
void AZMMOPlayerState::SetPublicIdentity(int64 InEntityId, const FString& InCharId,
int32 InBaseLevel, int32 InClassId)
{
ZMMOEntityId = InEntityId;
CharId = InCharId;
BaseLevel = InBaseLevel;
ClassId = InClassId;
}
void AZMMOPlayerState::SetCharInfo(const FString& InCharName, const FString& InGuildName)
{
CharName = InCharName;
GuildName = InGuildName;
}

View File

@@ -0,0 +1,10 @@
#include "ZeusFrontEndGameMode.h"
#include "ZeusFrontEndPlayerController.h"
AZeusFrontEndGameMode::AZeusFrontEndGameMode()
{
// UI pura: sem pawn. O controller cria o root layout e arranca o fluxo.
DefaultPawnClass = nullptr;
PlayerControllerClass = AZeusFrontEndPlayerController::StaticClass();
}

View File

@@ -2,21 +2,21 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h" #include "GameFramework/GameModeBase.h"
#include "ZMMOFrontEndGameMode.generated.h" #include "ZeusFrontEndGameMode.generated.h"
/** /**
* AZMMOFrontEndGameMode * AZeusFrontEndGameMode
* *
* GameMode do mapa de front-end (L_FrontEnd): UI, sem pawn nem network * GameMode do mapa de front-end (L_FrontEnd): UI, sem pawn nem network
* play. NÃO é o GameMode global (esse continua AZMMOGameMode para mapas de * play. NÃO é o GameMode global (esse continua AZeusGameMode para mapas de
* mundo) aplicado via override no World Settings de L_FrontEnd * mundo) aplicado via override no World Settings de L_FrontEnd
* (ARQUITETURA.md §3.3 / decisão de mapa dedicado). * (ARQUITETURA.md §3.3 / decisão de mapa dedicado).
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API AZMMOFrontEndGameMode : public AGameModeBase class ZMMO_API AZeusFrontEndGameMode : public AGameModeBase
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOFrontEndGameMode(); AZeusFrontEndGameMode();
}; };

View File

@@ -1,13 +1,13 @@
#include "ZMMOGameInstance.h" #include "ZeusGameInstance.h"
#include "ZMMO.h" #include "ZMMO.h"
#include "ZeusNetworkSubsystem.h" #include "ZeusNetworkSubsystem.h"
void UZMMOGameInstance::Init() void UZeusGameInstance::Init()
{ {
Super::Init(); Super::Init();
UE_LOG(LogZMMO, Log, TEXT("ZMMOGameInstance::Init AutoConnect=%s Host=%s Port=%d"), UE_LOG(LogZMMO, Log, TEXT("ZeusGameInstance::Init AutoConnect=%s Host=%s Port=%d"),
bAutoConnectOnStart ? TEXT("true") : TEXT("false"), bAutoConnectOnStart ? TEXT("true") : TEXT("false"),
*ZeusServerHost, *ZeusServerHost,
ZeusServerPort); ZeusServerPort);
@@ -15,7 +15,7 @@ void UZMMOGameInstance::Init()
UZeusNetworkSubsystem* ZeusNet = GetZeusNetwork(); UZeusNetworkSubsystem* ZeusNet = GetZeusNetwork();
if (!ZeusNet) if (!ZeusNet)
{ {
UE_LOG(LogZMMO, Warning, TEXT("ZMMOGameInstance: ZeusNetworkSubsystem unavailable; ZeusNetwork plugin enabled?")); UE_LOG(LogZMMO, Warning, TEXT("ZeusGameInstance: ZeusNetworkSubsystem unavailable; ZeusNetwork plugin enabled?"));
return; return;
} }
@@ -29,7 +29,7 @@ void UZMMOGameInstance::Init()
ZeusNet->ConnectToZeusServer(ZeusServerHost, ZeusServerPort); ZeusNet->ConnectToZeusServer(ZeusServerHost, ZeusServerPort);
} }
void UZMMOGameInstance::Shutdown() void UZeusGameInstance::Shutdown()
{ {
if (UZeusNetworkSubsystem* ZeusNet = GetZeusNetwork()) if (UZeusNetworkSubsystem* ZeusNet = GetZeusNetwork())
{ {
@@ -43,55 +43,55 @@ void UZMMOGameInstance::Shutdown()
Super::Shutdown(); Super::Shutdown();
} }
UZeusNetworkSubsystem* UZMMOGameInstance::GetZeusNetwork() const UZeusNetworkSubsystem* UZeusGameInstance::GetZeusNetwork() const
{ {
return GetSubsystem<UZeusNetworkSubsystem>(); return GetSubsystem<UZeusNetworkSubsystem>();
} }
void UZMMOGameInstance::BindZeusDelegates(UZeusNetworkSubsystem* Zeus) void UZeusGameInstance::BindZeusDelegates(UZeusNetworkSubsystem* Zeus)
{ {
if (!Zeus) if (!Zeus)
{ {
return; return;
} }
Zeus->OnConnected.AddDynamic(this, &UZMMOGameInstance::HandleZeusConnected); Zeus->OnConnected.AddDynamic(this, &UZeusGameInstance::HandleZeusConnected);
Zeus->OnConnectionFailed.AddDynamic(this, &UZMMOGameInstance::HandleZeusConnectionFailed); Zeus->OnConnectionFailed.AddDynamic(this, &UZeusGameInstance::HandleZeusConnectionFailed);
Zeus->OnDisconnected.AddDynamic(this, &UZMMOGameInstance::HandleZeusDisconnected); Zeus->OnDisconnected.AddDynamic(this, &UZeusGameInstance::HandleZeusDisconnected);
// OnNetworkLog: NAO assinamos. Plugin ja loga em LogZeusNetwork (console) // OnNetworkLog: NAO assinamos. Plugin ja loga em LogZeusNetwork (console)
// + arquivo proprio em Saved/Logs/ZeusNetwork/. Forwarding em LogZMMO era // + arquivo proprio em Saved/Logs/ZeusNetwork/. Forwarding em LogZMMO era
// diagnostico inicial (sessao 2026-05-07); agora gera duplicacao de cada // diagnostico inicial (sessao 2026-05-07); agora gera duplicacao de cada
// linha. Remova esta nota e descomente abaixo se quiser ver no LogZMMO: // linha. Remova esta nota e descomente abaixo se quiser ver no LogZMMO:
// Zeus->OnNetworkLog.AddDynamic(this, &UZMMOGameInstance::HandleZeusNetworkLog); // Zeus->OnNetworkLog.AddDynamic(this, &UZeusGameInstance::HandleZeusNetworkLog);
} }
void UZMMOGameInstance::UnbindZeusDelegates(UZeusNetworkSubsystem* Zeus) void UZeusGameInstance::UnbindZeusDelegates(UZeusNetworkSubsystem* Zeus)
{ {
if (!Zeus) if (!Zeus)
{ {
return; return;
} }
Zeus->OnConnected.RemoveDynamic(this, &UZMMOGameInstance::HandleZeusConnected); Zeus->OnConnected.RemoveDynamic(this, &UZeusGameInstance::HandleZeusConnected);
Zeus->OnConnectionFailed.RemoveDynamic(this, &UZMMOGameInstance::HandleZeusConnectionFailed); Zeus->OnConnectionFailed.RemoveDynamic(this, &UZeusGameInstance::HandleZeusConnectionFailed);
Zeus->OnDisconnected.RemoveDynamic(this, &UZMMOGameInstance::HandleZeusDisconnected); Zeus->OnDisconnected.RemoveDynamic(this, &UZeusGameInstance::HandleZeusDisconnected);
// OnNetworkLog: nao foi assinado (ver BindZeusDelegates) — nada a remover. // OnNetworkLog: nao foi assinado (ver BindZeusDelegates) — nada a remover.
} }
void UZMMOGameInstance::HandleZeusConnected() void UZeusGameInstance::HandleZeusConnected()
{ {
UE_LOG(LogZMMO, Log, TEXT("[Zeus] Connected to server %s:%d"), *ZeusServerHost, ZeusServerPort); UE_LOG(LogZMMO, Log, TEXT("[Zeus] Connected to server %s:%d"), *ZeusServerHost, ZeusServerPort);
} }
void UZMMOGameInstance::HandleZeusConnectionFailed(FString Reason) void UZeusGameInstance::HandleZeusConnectionFailed(FString Reason)
{ {
UE_LOG(LogZMMO, Warning, TEXT("[Zeus] Connection failed: %s"), *Reason); UE_LOG(LogZMMO, Warning, TEXT("[Zeus] Connection failed: %s"), *Reason);
} }
void UZMMOGameInstance::HandleZeusDisconnected() void UZeusGameInstance::HandleZeusDisconnected()
{ {
UE_LOG(LogZMMO, Log, TEXT("[Zeus] Disconnected.")); UE_LOG(LogZMMO, Log, TEXT("[Zeus] Disconnected."));
} }
void UZMMOGameInstance::HandleZeusNetworkLog(FString Message) void UZeusGameInstance::HandleZeusNetworkLog(FString Message)
{ {
UE_LOG(LogZMMO, Log, TEXT("[Zeus] %s"), *Message); UE_LOG(LogZMMO, Log, TEXT("[Zeus] %s"), *Message);
} }

View File

@@ -2,12 +2,12 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Engine/GameInstance.h" #include "Engine/GameInstance.h"
#include "ZMMOGameInstance.generated.h" #include "ZeusGameInstance.generated.h"
class UZeusNetworkSubsystem; class UZeusNetworkSubsystem;
/** /**
* UZMMOGameInstance * UZeusGameInstance
* *
* Game instance do cliente Zeus MMO. O `UZeusNetworkSubsystem` (do plugin * Game instance do cliente Zeus MMO. O `UZeusNetworkSubsystem` (do plugin
* `ZeusNetwork`) e um `UGameInstanceSubsystem` e portanto e criado * `ZeusNetwork`) e um `UGameInstanceSubsystem` e portanto e criado
@@ -22,7 +22,7 @@ class UZeusNetworkSubsystem;
* overrides de configuracao por build (dev / staging / prod). * overrides de configuracao por build (dev / staging / prod).
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API UZMMOGameInstance : public UGameInstance class ZMMO_API UZeusGameInstance : public UGameInstance
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -36,20 +36,20 @@ public:
* dirigida pelo `UUIFrontEndFlowSubsystem` (fluxo BootConnectingLogin). * dirigida pelo `UUIFrontEndFlowSubsystem` (fluxo BootConnectingLogin).
* Pôr `true` apenas para smoke test legado sem front-end. * Pôr `true` apenas para smoke test legado sem front-end.
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Config, Category = "ZMMO|Network") UPROPERTY(EditAnywhere, BlueprintReadWrite, Config, Category = "Zeus|Network")
bool bAutoConnectOnStart = false; bool bAutoConnectOnStart = false;
/** Host (IPv4 ou hostname) do servidor Zeus. */ /** Host (IPv4 ou hostname) do servidor Zeus. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Config, Category = "ZMMO|Network") UPROPERTY(EditAnywhere, BlueprintReadWrite, Config, Category = "Zeus|Network")
FString ZeusServerHost = TEXT("127.0.0.1"); FString ZeusServerHost = TEXT("127.0.0.1");
/** Porta UDP do servidor Zeus (1..65535). */ /** Porta UDP do servidor Zeus (1..65535). */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Config, Category = "ZMMO|Network", meta = (ClampMin = "1", ClampMax = "65535")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Config, Category = "Zeus|Network", meta = (ClampMin = "1", ClampMax = "65535"))
int32 ZeusServerPort = 27777; int32 ZeusServerPort = 27777;
protected: protected:
/** Devolve o subsystem Zeus desta game instance (criado automaticamente pelo plugin). */ /** Devolve o subsystem Zeus desta game instance (criado automaticamente pelo plugin). */
UFUNCTION(BlueprintPure, Category = "ZMMO|Network") UFUNCTION(BlueprintPure, Category = "Zeus|Network")
UZeusNetworkSubsystem* GetZeusNetwork() const; UZeusNetworkSubsystem* GetZeusNetwork() const;
void BindZeusDelegates(UZeusNetworkSubsystem* Zeus); void BindZeusDelegates(UZeusNetworkSubsystem* Zeus);

View File

@@ -0,0 +1,14 @@
#include "ZeusGameMode.h"
#include "ZeusHUD.h"
#include "ZeusCharacter.h"
#include "ZeusPlayerController.h"
#include "ZeusPlayerState.h"
AZeusGameMode::AZeusGameMode()
{
DefaultPawnClass = AZeusCharacter::StaticClass();
PlayerControllerClass = AZeusPlayerController::StaticClass();
PlayerStateClass = AZeusPlayerState::StaticClass();
HUDClass = AZeusHUD::StaticClass();
}

View File

@@ -2,24 +2,24 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h" #include "GameFramework/GameModeBase.h"
#include "ZMMOGameMode.generated.h" #include "ZeusGameMode.generated.h"
/** /**
* AZMMOGameMode * AZeusGameMode
* *
* Game mode do cliente Zeus MMO. Configura `AZMMOPlayerCharacter` como * Game mode do cliente Zeus MMO. Configura `AZeusCharacter` como
* `DefaultPawnClass` e `AZMMOPlayerController` como `PlayerControllerClass`. * `DefaultPawnClass` e `AZeusPlayerController` como `PlayerControllerClass`.
* *
* A classe e instanciavel directamente (apontada por * A classe e instanciavel directamente (apontada por
* `GlobalDefaultGameMode=/Script/ZMMO.ZMMOGameMode` em * `GlobalDefaultGameMode=/Script/ZMMO.ZeusGameMode` em
* `Config/DefaultEngine.ini`); um BP filho e opcional para overrides * `Config/DefaultEngine.ini`); um BP filho e opcional para overrides
* por mapa / build (skeletal mesh, AnimBP custom, etc.). * por mapa / build (skeletal mesh, AnimBP custom, etc.).
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class ZMMO_API AZMMOGameMode : public AGameModeBase class ZMMO_API AZeusGameMode : public AGameModeBase
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOGameMode(); AZeusGameMode();
}; };

View File

@@ -1,16 +1,16 @@
#include "ZMMOHUD.h" #include "ZeusHUD.h"
#include "Engine/GameInstance.h" #include "Engine/GameInstance.h"
#include "ZMMO.h" #include "ZMMO.h"
#include "UI/InGame/UIInGameFlowSubsystem.h" #include "UI/InGame/UIInGameFlowSubsystem.h"
AZMMOHUD::AZMMOHUD() AZeusHUD::AZeusHUD()
{ {
// AHUD nao precisa tick — toda atualizacao vem via UMG (delegates + // AHUD nao precisa tick — toda atualizacao vem via UMG (delegates +
// CommonUI). PrimaryActorTick default e' off; mantemos. // CommonUI). PrimaryActorTick default e' off; mantemos.
} }
void AZMMOHUD::BeginPlay() void AZeusHUD::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
@@ -25,12 +25,12 @@ void AZMMOHUD::BeginPlay()
else else
{ {
UE_LOG(LogZMMO, Warning, UE_LOG(LogZMMO, Warning,
TEXT("AZMMOHUD: UUIInGameFlowSubsystem nao encontrado — HUD nao sera spawnado")); TEXT("AZeusHUD: UUIInGameFlowSubsystem nao encontrado — HUD nao sera spawnado"));
} }
} }
} }
void AZMMOHUD::EndPlay(const EEndPlayReason::Type EndPlayReason) void AZeusHUD::EndPlay(const EEndPlayReason::Type EndPlayReason)
{ {
// UUIInGameFlowSubsystem persiste no GameInstance entre OpenLevel — nao // UUIInGameFlowSubsystem persiste no GameInstance entre OpenLevel — nao
// limpamos UI in-game aqui (o front-end flow vai tomar conta na proxima // limpamos UI in-game aqui (o front-end flow vai tomar conta na proxima

View File

@@ -2,7 +2,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/HUD.h" #include "GameFramework/HUD.h"
#include "ZMMOHUD.generated.h" #include "ZeusHUD.generated.h"
/** /**
* HUD do MMO. Pattern UE5 idiomatico: o GameMode atribui `HUDClass`, o * HUD do MMO. Pattern UE5 idiomatico: o GameMode atribui `HUDClass`, o
@@ -14,21 +14,21 @@
* subsystem cuida do cleanup. * subsystem cuida do cleanup.
* *
* Separacao de responsabilidades: * Separacao de responsabilidades:
* - AZMMOPlayerCharacter (Pawn) movimento, input, AttributeComponent * - AZeusCharacter (Pawn) movimento, input, AttributeComponent
* - AZMMOPlayerController input mapping, mouse * - AZeusPlayerController input mapping, mouse
* - AZMMOHUD UI lifecycle * - AZeusHUD UI lifecycle
* - AZMMOGameMode wires tudo via class slots * - AZeusGameMode wires tudo via class slots
* *
* NAO desenha nada via canvas (AHUD::DrawHUD). UI inteira vive em UMG + * NAO desenha nada via canvas (AHUD::DrawHUD). UI inteira vive em UMG +
* CommonUI (UI.Layer.Game / GameMenu / Modal). * CommonUI (UI.Layer.Game / GameMenu / Modal).
*/ */
UCLASS() UCLASS()
class ZMMO_API AZMMOHUD : public AHUD class ZMMO_API AZeusHUD : public AHUD
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOHUD(); AZeusHUD();
protected: protected:
virtual void BeginPlay() override; virtual void BeginPlay() override;

View File

@@ -0,0 +1,133 @@
#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;
}

View File

@@ -1,12 +1,15 @@
#pragma once #pragma once
#include "AbilitySystemInterface.h"
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/PlayerState.h" #include "GameFramework/PlayerState.h"
#include "Templates/SubclassOf.h" #include "Templates/SubclassOf.h"
#include "ZMMOPlayerState.generated.h" #include "ZeusPlayerState.generated.h"
class FLifetimeProperty; class FLifetimeProperty;
class UActorComponent; class UActorComponent;
class UZeusAbilitySystemComponent;
class UZeusAttributeSet;
/** /**
* PlayerState do MMO. Pattern UE5 idiomatico: o GameMode atribui * PlayerState do MMO. Pattern UE5 idiomatico: o GameMode atribui
@@ -28,29 +31,52 @@ class UActorComponent;
* *
* ## Component Registry (Open-Closed) * ## Component Registry (Open-Closed)
* *
* Cada modulo (ZMMOAttributes, ZMMOInventory, ZMMOSkills futuros) declara * Cada modulo (ZeusGAS, ZeusInventory, ZeusSkills futuros) declara
* sua component class em DefaultGame.ini: * sua component class em DefaultGame.ini:
* *
* [/Script/ZMMO.ZMMOPlayerState] * [/Script/ZMMO.ZeusPlayerState]
* +ComponentClasses=/Script/ZMMOAttributes.ZMMOAttributeComponent * +ComponentClasses=/Script/ZeusGAS.ZeusGASComponent
* +ComponentClasses=/Script/ZMMOInventory.ZMMOInventoryComponent * +ComponentClasses=/Script/ZeusInventory.ZeusInventoryComponent
* +ComponentClasses=/Script/ZMMOSkills.ZMMOSkillComponent * +ComponentClasses=/Script/ZeusSkills.ZeusSkillComponent
* *
* O construtor de AZMMOPlayerState le essa lista (Config) e instancia * O construtor de AZeusPlayerState le essa lista (Config) e instancia
* cada classe como subobject. PlayerState fica fechado pra modificacao, * cada classe como subobject. PlayerState fica fechado pra modificacao,
* modulos abertos pra extensao adicionar Inventory NAO requer * modulos abertos pra extensao adicionar Inventory NAO requer
* recompilar/editar AZMMOPlayerState. * recompilar/editar AZeusPlayerState.
* *
* Acesso: `PlayerState->FindComponentByClass<UZMMOAttributeComponent>()` * Acesso: `PlayerState->FindComponentByClass<UZeusGASComponent>()`
* ou o helper `GetZMMOComponent<T>()`. * ou o helper `GetZeusComponent<T>()`.
*/ */
UCLASS(Config = Game, BlueprintType) UCLASS(Config = Game, BlueprintType)
class ZMMO_API AZMMOPlayerState : public APlayerState class ZMMO_API AZeusPlayerState : public APlayerState, public IAbilitySystemInterface
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
AZMMOPlayerState(); AZeusPlayerState();
// === IAbilitySystemInterface (UE5 GAS) ===
//
// Padrao Lyra: PlayerState implementa a interface; o ASC vive como
// subobject do UZeusGASComponent (Component Registry). Isso permite que
// qualquer Actor que receba este PlayerState resolva o ASC via cast
// pra IAbilitySystemInterface OU via node BP "Get Ability System
// Component" (que faz o mesmo internamente).
//
// Acesso BP: "Get Ability System Component" + pin do PlayerState.
// Acesso C++: `Cast<IAbilitySystemInterface>(PlayerState)->GetAbilitySystemComponent()`.
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
/// Versao tipada do ASC custom — retorna direto UZeusAbilitySystemComponent
/// (os 12 overrides que falam com o servidor custom via opcodes ZeusNetwork).
/// Prefira este sobre o getter da interface no BP — evita cast + expoe a API
/// do ASC custom (RequestActivateAbility, etc.).
UFUNCTION(BlueprintPure, Category = "Zeus|GAS")
UZeusAbilitySystemComponent* GetZeusAbilitySystemComponent() const;
/// Helper BP-friendly pro AttributeSet tipado (template C++ nao expoe pra BP).
UFUNCTION(BlueprintPure, Category = "Zeus|GAS")
UZeusAttributeSet* GetZeusAttributeSet() const;
// === Identidade publica === // === Identidade publica ===
// //
@@ -60,51 +86,51 @@ public:
// passe a usar dedicated UE5 no futuro. // passe a usar dedicated UE5 no futuro.
/** EntityId autoritativo do server. 0 ate o spawn local confirmar. */ /** EntityId autoritativo do server. 0 ate o spawn local confirmar. */
UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Identity") UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Identity")
int64 ZMMOEntityId = 0; int64 ZeusEntityId = 0;
/** CharId (BIGINT no DB; FString pra preservar 64 bits em Blueprint). */ /** CharId (BIGINT no DB; FString pra preservar 64 bits em Blueprint). */
UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Identity") UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Identity")
FString CharId; FString CharId;
/** Nome do char vindo do DB (`characters.name`). Setado por /** Nome do char vindo do DB (`characters.name`). Setado por
* AZMMOPlayerCharacter::HandleLocalSpawnReady com o payload do * AZeusCharacter::HandleLocalSpawnReady com o payload do
* S_SPAWN_PLAYER. UI prefere isto a APlayerState::GetPlayerName(). */ * S_SPAWN_PLAYER. UI prefere isto a APlayerState::GetPlayerName(). */
UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Identity") UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Identity")
FString CharName; FString CharName;
// === Progressao publica === // === Progressao publica ===
UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Progress") UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Progress")
int32 BaseLevel = 1; int32 BaseLevel = 1;
UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Progress") UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Progress")
int32 ClassId = 0; int32 ClassId = 0;
// === Guild (futuro) === // === Guild (futuro) ===
UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "ZMMO|Guild") UPROPERTY(Replicated, VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Guild")
FString GuildName; FString GuildName;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
// === Helpers === // === Helpers ===
/// Setado por AZMMOPlayerCharacter::HandleLocalSpawnReady (pose/EntityId) /// Setado por AZeusCharacter::HandleLocalSpawnReady (pose/EntityId)
/// e atualizado por handlers de snapshot/level up para refletir dados /// e atualizado por handlers de snapshot/level up para refletir dados
/// publicos do char no PlayerState. /// publicos do char no PlayerState.
UFUNCTION(BlueprintCallable, Category = "ZMMO|Identity") UFUNCTION(BlueprintCallable, Category = "Zeus|Identity")
void SetPublicIdentity(int64 InEntityId, const FString& InCharId, void SetPublicIdentity(int64 InEntityId, const FString& InCharId,
int32 InBaseLevel, int32 InClassId); int32 InBaseLevel, int32 InClassId);
/// Setado pelo handler do S_CHAR_INFO (chega antes de S_SPAWN_PLAYER) — /// Setado pelo handler do S_CHAR_INFO (chega antes de S_SPAWN_PLAYER) —
/// metadados publicos do char vindos do servidor. /// metadados publicos do char vindos do servidor.
UFUNCTION(BlueprintCallable, Category = "ZMMO|Identity") UFUNCTION(BlueprintCallable, Category = "Zeus|Identity")
void SetCharInfo(const FString& InCharName, const FString& InGuildName); void SetCharInfo(const FString& InCharName, const FString& InGuildName);
/// Template helper: PS->GetZMMOComponent<UZMMOAttributeComponent>() /// Template helper: PS->GetZeusComponent<UZeusGASComponent>()
template <typename T> template <typename T>
T* GetZMMOComponent() const T* GetZeusComponent() const
{ {
return Cast<T>(FindComponentByClass(T::StaticClass())); return Cast<T>(FindComponentByClass(T::StaticClass()));
} }
@@ -119,6 +145,6 @@ protected:
* diretamente. Modulos C++ precisam estar carregados antes do CDO ser * diretamente. Modulos C++ precisam estar carregados antes do CDO ser
* instanciado garantido por LoadingPhase=PreDefault no .uproject. * instanciado garantido por LoadingPhase=PreDefault no .uproject.
*/ */
UPROPERTY(Config, EditDefaultsOnly, Category = "ZMMO|Components") UPROPERTY(Config, EditDefaultsOnly, Category = "Zeus|Components")
TArray<TSubclassOf<UActorComponent>> ComponentClasses; TArray<TSubclassOf<UActorComponent>> ComponentClasses;
}; };

View File

@@ -1,23 +1,26 @@
#include "ZMMOWorldSubsystem.h" #include "ZeusWorldSubsystem.h"
#include "Engine/GameInstance.h" #include "Engine/GameInstance.h"
#include "Engine/World.h" #include "Engine/World.h"
#include "GameFramework/GameStateBase.h"
#include "ZMMO.h" #include "ZMMO.h"
#include "ZMMOEntity.h" #include "ZeusEntity.h"
#include "ZMMOEntityInterface.h" #include "ZeusEntityInterface.h"
#include "ZMMOPlayerProxy.h" #include "ZeusGASComponent.h"
#include "ZeusPlayerProxy.h"
#include "ZeusPlayerState.h"
#include "ZeusNetworkSubsystem.h" #include "ZeusNetworkSubsystem.h"
void UZMMOWorldSubsystem::Initialize(FSubsystemCollectionBase& Collection) void UZeusWorldSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{ {
Super::Initialize(Collection); Super::Initialize(Collection);
if (RemoteEntityClasses.IsEmpty()) if (RemoteEntityClasses.IsEmpty())
{ {
RemoteEntityClasses.Add(EZMMOEntityType::Player, AZMMOPlayerProxy::StaticClass()); RemoteEntityClasses.Add(EZeusEntityType::Player, AZeusPlayerProxy::StaticClass());
RemoteEntityClasses.Add(EZMMOEntityType::Mob, AZMMOEntity::StaticClass()); RemoteEntityClasses.Add(EZeusEntityType::Mob, AZeusEntity::StaticClass());
RemoteEntityClasses.Add(EZMMOEntityType::NPC, AZMMOEntity::StaticClass()); RemoteEntityClasses.Add(EZeusEntityType::NPC, AZeusEntity::StaticClass());
RemoteEntityClasses.Add(EZMMOEntityType::Object, AZMMOEntity::StaticClass()); RemoteEntityClasses.Add(EZeusEntityType::Object, AZeusEntity::StaticClass());
} }
// Bind + replay vivem em OnWorldBeginPlay (mundo pronto). Initialize roda // Bind + replay vivem em OnWorldBeginPlay (mundo pronto). Initialize roda
// MUITO cedo no pipeline de LoadMap — antes do GameMode ser instanciado // MUITO cedo no pipeline de LoadMap — antes do GameMode ser instanciado
@@ -25,16 +28,16 @@ void UZMMOWorldSubsystem::Initialize(FSubsystemCollectionBase& Collection)
// feitos aqui podem ser perdidos durante a fase de setup posterior. // feitos aqui podem ser perdidos durante a fase de setup posterior.
} }
void UZMMOWorldSubsystem::OnWorldBeginPlay(UWorld& InWorld) void UZeusWorldSubsystem::OnWorldBeginPlay(UWorld& InWorld)
{ {
Super::OnWorldBeginPlay(InWorld); Super::OnWorldBeginPlay(InWorld);
if (UZeusNetworkSubsystem* ZeusNet = ResolveZeusNetworkSubsystem()) if (UZeusNetworkSubsystem* ZeusNet = ResolveZeusNetworkSubsystem())
{ {
ZeusNet->OnPlayerSpawned.AddDynamic(this, &UZMMOWorldSubsystem::HandlePlayerSpawned); ZeusNet->OnPlayerSpawned.AddDynamic(this, &UZeusWorldSubsystem::HandlePlayerSpawned);
ZeusNet->OnPlayerDespawned.AddDynamic(this, &UZMMOWorldSubsystem::HandlePlayerDespawned); ZeusNet->OnPlayerDespawned.AddDynamic(this, &UZeusWorldSubsystem::HandlePlayerDespawned);
ZeusNet->OnPlayerStateUpdate.AddDynamic(this, &UZMMOWorldSubsystem::HandlePlayerStateUpdate); ZeusNet->OnPlayerStateUpdate.AddDynamic(this, &UZeusWorldSubsystem::HandlePlayerStateUpdate);
UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem bound to ZeusNetworkSubsystem delegates.")); UE_LOG(LogZMMO, Log, TEXT("ZeusWorldSubsystem bound to ZeusNetworkSubsystem delegates."));
// Catch-up race fix (Fase 3): broadcasts de proxies remotos chegam // Catch-up race fix (Fase 3): broadcasts de proxies remotos chegam
// enquanto o cliente novo ainda esta em OpenLevel. UZeusNetworkSubsystem // enquanto o cliente novo ainda esta em OpenLevel. UZeusNetworkSubsystem
@@ -49,22 +52,22 @@ void UZMMOWorldSubsystem::OnWorldBeginPlay(UWorld& InWorld)
}); });
if (ReplayCount > 0) if (ReplayCount > 0)
{ {
UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem: replay de %d proxy(ies) cacheados."), ReplayCount); UE_LOG(LogZMMO, Log, TEXT("ZeusWorldSubsystem: replay de %d proxy(ies) cacheados."), ReplayCount);
} }
} }
else else
{ {
UE_LOG(LogZMMO, Warning, TEXT("ZMMOWorldSubsystem: ZeusNetworkSubsystem not found at OnWorldBeginPlay.")); UE_LOG(LogZMMO, Warning, TEXT("ZeusWorldSubsystem: ZeusNetworkSubsystem not found at OnWorldBeginPlay."));
} }
} }
void UZMMOWorldSubsystem::Deinitialize() void UZeusWorldSubsystem::Deinitialize()
{ {
if (UZeusNetworkSubsystem* ZeusNet = ResolveZeusNetworkSubsystem()) if (UZeusNetworkSubsystem* ZeusNet = ResolveZeusNetworkSubsystem())
{ {
ZeusNet->OnPlayerSpawned.RemoveDynamic(this, &UZMMOWorldSubsystem::HandlePlayerSpawned); ZeusNet->OnPlayerSpawned.RemoveDynamic(this, &UZeusWorldSubsystem::HandlePlayerSpawned);
ZeusNet->OnPlayerDespawned.RemoveDynamic(this, &UZMMOWorldSubsystem::HandlePlayerDespawned); ZeusNet->OnPlayerDespawned.RemoveDynamic(this, &UZeusWorldSubsystem::HandlePlayerDespawned);
ZeusNet->OnPlayerStateUpdate.RemoveDynamic(this, &UZMMOWorldSubsystem::HandlePlayerStateUpdate); ZeusNet->OnPlayerStateUpdate.RemoveDynamic(this, &UZeusWorldSubsystem::HandlePlayerStateUpdate);
} }
RemoteEntities.Reset(); RemoteEntities.Reset();
@@ -72,7 +75,7 @@ void UZMMOWorldSubsystem::Deinitialize()
Super::Deinitialize(); Super::Deinitialize();
} }
void UZMMOWorldSubsystem::RegisterLocalEntity(const int64 EntityId, AActor* LocalActor) void UZeusWorldSubsystem::RegisterLocalEntity(const int64 EntityId, AActor* LocalActor)
{ {
if (EntityId == 0 || LocalActor == nullptr) if (EntityId == 0 || LocalActor == nullptr)
{ {
@@ -81,11 +84,11 @@ void UZMMOWorldSubsystem::RegisterLocalEntity(const int64 EntityId, AActor* Loca
LocalEntityId = EntityId; LocalEntityId = EntityId;
RemoteEntities.Add(EntityId, TWeakObjectPtr<AActor>(LocalActor)); RemoteEntities.Add(EntityId, TWeakObjectPtr<AActor>(LocalActor));
UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem: local entity registered EntityId=%lld actor=%s"), UE_LOG(LogZMMO, Log, TEXT("ZeusWorldSubsystem: local entity registered EntityId=%lld actor=%s"),
EntityId, *GetNameSafe(LocalActor)); EntityId, *GetNameSafe(LocalActor));
} }
void UZMMOWorldSubsystem::HandlePlayerSpawned(const int64 EntityId, const bool bIsLocal, void UZeusWorldSubsystem::HandlePlayerSpawned(const int64 EntityId, const bool bIsLocal,
const FVector PosCm, const float YawDeg, const int64 ServerTimeMs) const FVector PosCm, const float YawDeg, const int64 ServerTimeMs)
{ {
if (EntityId == 0) if (EntityId == 0)
@@ -95,7 +98,7 @@ void UZMMOWorldSubsystem::HandlePlayerSpawned(const int64 EntityId, const bool b
if (bIsLocal) if (bIsLocal)
{ {
// O proprio AZMMOPlayerCharacter cuida da sua identidade quando recebe o // O proprio AZeusCharacter cuida da sua identidade quando recebe o
// delegate por outro caminho. Aqui apenas memorizamos para filtrar // delegate por outro caminho. Aqui apenas memorizamos para filtrar
// snapshots locais (cliente solto, sem reconciliacao em V0). // snapshots locais (cliente solto, sem reconciliacao em V0).
LocalEntityId = EntityId; LocalEntityId = EntityId;
@@ -110,17 +113,17 @@ void UZMMOWorldSubsystem::HandlePlayerSpawned(const int64 EntityId, const bool b
// silenciosamente ignorado depois de oscilacoes na AOI. // silenciosamente ignorado depois de oscilacoes na AOI.
if (AActor* Existing = RemoteEntities[EntityId].Get()) if (AActor* Existing = RemoteEntities[EntityId].Get())
{ {
if (IZMMOEntityInterface* AsEntity = Cast<IZMMOEntityInterface>(Existing)) if (IZeusEntityInterface* AsEntity = Cast<IZeusEntityInterface>(Existing))
{ {
AsEntity->SetEntityRelevant(true); AsEntity->SetEntityRelevant(true);
} }
Existing->SetActorLocationAndRotation(PosCm, FRotator(0.0f, YawDeg, 0.0f)); Existing->SetActorLocationAndRotation(PosCm, FRotator(0.0f, YawDeg, 0.0f));
UE_LOG(LogZMMO, Verbose, TEXT("ZMMOWorldSubsystem: re-snap EntityId=%d"), EntityId); UE_LOG(LogZMMO, Verbose, TEXT("ZeusWorldSubsystem: re-snap EntityId=%d"), EntityId);
return; return;
} }
// weak ptr stale — limpa entry e cai pro spawn novo abaixo. // weak ptr stale — limpa entry e cai pro spawn novo abaixo.
RemoteEntities.Remove(EntityId); RemoteEntities.Remove(EntityId);
UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem: stale entry para EntityId=%d, respawnando"), EntityId); UE_LOG(LogZMMO, Log, TEXT("ZeusWorldSubsystem: stale entry para EntityId=%d, respawnando"), EntityId);
} }
UWorld* World = GetWorld(); UWorld* World = GetWorld();
@@ -129,10 +132,10 @@ void UZMMOWorldSubsystem::HandlePlayerSpawned(const int64 EntityId, const bool b
return; return;
} }
UClass* ProxyClass = ResolveActorClass(EZMMOEntityType::Player); UClass* ProxyClass = ResolveActorClass(EZeusEntityType::Player);
if (!ProxyClass) if (!ProxyClass)
{ {
UE_LOG(LogZMMO, Warning, TEXT("ZMMOWorldSubsystem: no class registered for Player; spawn aborted.")); UE_LOG(LogZMMO, Warning, TEXT("ZeusWorldSubsystem: no class registered for Player; spawn aborted."));
return; return;
} }
@@ -142,30 +145,78 @@ void UZMMOWorldSubsystem::HandlePlayerSpawned(const int64 EntityId, const bool b
AActor* SpawnedActor = World->SpawnActor<AActor>(ProxyClass, PosCm, SpawnRot, Params); AActor* SpawnedActor = World->SpawnActor<AActor>(ProxyClass, PosCm, SpawnRot, Params);
if (!SpawnedActor) if (!SpawnedActor)
{ {
UE_LOG(LogZMMO, Warning, TEXT("ZMMOWorldSubsystem: SpawnActor failed for EntityId=%d"), EntityId); UE_LOG(LogZMMO, Warning, TEXT("ZeusWorldSubsystem: SpawnActor failed for EntityId=%d"), EntityId);
return; return;
} }
if (IZMMOEntityInterface* AsEntity = Cast<IZMMOEntityInterface>(SpawnedActor)) if (IZeusEntityInterface* AsEntity = Cast<IZeusEntityInterface>(SpawnedActor))
{ {
// Inject identity via dedicated setter when the spawned actor exposes one. // Inject identity via dedicated setter when the spawned actor exposes one.
if (AZMMOPlayerProxy* Proxy = Cast<AZMMOPlayerProxy>(SpawnedActor)) if (AZeusPlayerProxy* Proxy = Cast<AZeusPlayerProxy>(SpawnedActor))
{ {
Proxy->SetZMMOIdentity(EntityId, EZMMOEntityType::Player); Proxy->SetZeusIdentity(EntityId, EZeusEntityType::Player);
} }
else if (AZMMOEntity* Entity = Cast<AZMMOEntity>(SpawnedActor)) else if (AZeusEntity* Entity = Cast<AZeusEntity>(SpawnedActor))
{ {
Entity->SetZMMOIdentity(EntityId, EZMMOEntityType::Player); Entity->SetZeusIdentity(EntityId, EZeusEntityType::Player);
} }
AsEntity->SetEntityRelevant(true); AsEntity->SetEntityRelevant(true);
} }
// === PlayerState pra proxies (Batch 2.5+) ===
//
// Sem PlayerState, o proxy fica fora do GameState->PlayerArray. Daqui pra
// cima, qualquer sistema que itera PlayerArray (UZeusGASNetworkHandler::
// FindGASComponentForEntity, HUD, chat, friend list) NAO consegue achar o
// proxy -> fallback ao local player -> efeito apareceria no char errado
// (bug do cue do Dash). Criar PS replicado-fake permite que o pipeline GAS
// trate proxies igual a local players.
//
// PlayerState tem o UZeusGASComponent via DefaultGame.ini Component Registry,
// entao GASComp e' auto-instanciado. So' precisamos seed o EntityId.
if (APawn* ProxyPawn = Cast<APawn>(SpawnedActor))
{
FActorSpawnParameters PSParams;
PSParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
PSParams.Owner = ProxyPawn;
AZeusPlayerState* ProxyPS = World->SpawnActor<AZeusPlayerState>(
AZeusPlayerState::StaticClass(), FVector::ZeroVector, FRotator::ZeroRotator, PSParams);
if (ProxyPS)
{
ProxyPawn->SetPlayerState(ProxyPS); // tambem chama ProxyPS->SetPawn(ProxyPawn)
// Add ao PlayerArray do GameState (replicacao UE faria isso automatico,
// mas no nosso pipeline custom o PS local-fake precisa ser inserido).
if (AGameStateBase* GS = World->GetGameState())
{
GS->AddPlayerState(ProxyPS);
}
// Seed EntityId no GASComp do PS (criado via Component Registry).
// FindGASComponentForEntity vai resolver via PS->FindComponentByClass.
if (UZeusGASComponent* GASComp = ProxyPS->FindComponentByClass<UZeusGASComponent>())
{
GASComp->SeedEntityId(EntityId);
}
UE_LOG(LogZMMO, Log,
TEXT("ZeusWorldSubsystem: PlayerState criado p/ proxy EntityId=%lld PS=%s"),
EntityId, *ProxyPS->GetName());
}
else
{
UE_LOG(LogZMMO, Warning,
TEXT("ZeusWorldSubsystem: SpawnActor<AZeusPlayerState> falhou pra proxy EntityId=%lld"),
EntityId);
}
}
RemoteEntities.Add(EntityId, TWeakObjectPtr<AActor>(SpawnedActor)); RemoteEntities.Add(EntityId, TWeakObjectPtr<AActor>(SpawnedActor));
UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem: spawned remote EntityId=%d at (%s) yaw=%.1f t=%lld"), UE_LOG(LogZMMO, Log, TEXT("ZeusWorldSubsystem: spawned remote EntityId=%d at (%s) yaw=%.1f t=%lld"),
EntityId, *PosCm.ToString(), YawDeg, ServerTimeMs); EntityId, *PosCm.ToString(), YawDeg, ServerTimeMs);
} }
void UZMMOWorldSubsystem::HandlePlayerDespawned(const int64 EntityId) void UZeusWorldSubsystem::HandlePlayerDespawned(const int64 EntityId)
{ {
const TWeakObjectPtr<AActor>* Entry = RemoteEntities.Find(EntityId); const TWeakObjectPtr<AActor>* Entry = RemoteEntities.Find(EntityId);
if (!Entry) if (!Entry)
@@ -181,18 +232,34 @@ void UZMMOWorldSubsystem::HandlePlayerDespawned(const int64 EntityId)
// confirmado nos logs do AOI ao oscilar entrada/saida da ZI/ZD. // confirmado nos logs do AOI ao oscilar entrada/saida da ZI/ZD.
if (AActor* Actor = Entry->Get()) if (AActor* Actor = Entry->Get())
{ {
if (IZMMOEntityInterface* AsEntity = Cast<IZMMOEntityInterface>(Actor)) if (IZeusEntityInterface* AsEntity = Cast<IZeusEntityInterface>(Actor))
{ {
AsEntity->SetEntityRelevant(false); AsEntity->SetEntityRelevant(false);
} }
// Destrui PS proxy linkado (Batch 2.5+). Sem isso o GameState->PlayerArray
// fica com PS orfa apos o proxy ser destruido.
if (APawn* Pawn = Cast<APawn>(Actor))
{
if (APlayerState* PS = Pawn->GetPlayerState())
{
if (UWorld* World = GetWorld())
{
if (AGameStateBase* GS = World->GetGameState())
{
GS->RemovePlayerState(PS);
}
}
PS->Destroy();
}
}
Actor->Destroy(); Actor->Destroy();
} }
RemoteEntities.Remove(EntityId); RemoteEntities.Remove(EntityId);
UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem: despawn EntityId=%d (destroyed)"), EntityId); UE_LOG(LogZMMO, Log, TEXT("ZeusWorldSubsystem: despawn EntityId=%d (destroyed)"), EntityId);
} }
void UZMMOWorldSubsystem::HandlePlayerStateUpdate(const int64 EntityId, const int32 InputSeq, void UZeusWorldSubsystem::HandlePlayerStateUpdate(const int64 EntityId, const int32 InputSeq,
const FVector PosCm, const FVector VelCmS, const bool bGrounded, const int64 ServerTimeMs) const FVector PosCm, const FVector VelCmS, const bool bGrounded, const int64 ServerTimeMs)
{ {
if (EntityId == 0) if (EntityId == 0)
@@ -204,7 +271,7 @@ void UZMMOWorldSubsystem::HandlePlayerStateUpdate(const int64 EntityId, const in
{ {
// Cliente local solto: ignoramos snapshots autoritativos para o nosso // Cliente local solto: ignoramos snapshots autoritativos para o nosso
// proprio personagem em V0 (ADR 0038). Reconciliacao opcional pode ser // proprio personagem em V0 (ADR 0038). Reconciliacao opcional pode ser
// activada por flag em `AZMMOPlayerCharacter` quando colisao de objetos // activada por flag em `AZeusCharacter` quando colisao de objetos
// chegar. // chegar.
return; return;
} }
@@ -223,15 +290,15 @@ void UZMMOWorldSubsystem::HandlePlayerStateUpdate(const int64 EntityId, const in
return; return;
} }
IZMMOEntityInterface* AsEntity = Cast<IZMMOEntityInterface>(Actor); IZeusEntityInterface* AsEntity = Cast<IZeusEntityInterface>(Actor);
if (!AsEntity) if (!AsEntity)
{ {
return; return;
} }
FZMMOEntitySnapshot Snapshot; FZeusEntitySnapshot Snapshot;
Snapshot.EntityId = EntityId; Snapshot.EntityId = EntityId;
Snapshot.EntityType = AsEntity->GetZMMOEntityType(); Snapshot.EntityType = AsEntity->GetZeusEntityType();
Snapshot.LastProcessedInputSeq = InputSeq; Snapshot.LastProcessedInputSeq = InputSeq;
Snapshot.PositionCm = PosCm; Snapshot.PositionCm = PosCm;
Snapshot.VelocityCmS = VelCmS; Snapshot.VelocityCmS = VelCmS;
@@ -281,7 +348,7 @@ void UZMMOWorldSubsystem::HandlePlayerStateUpdate(const int64 EntityId, const in
AsEntity->ApplyEntitySnapshot(Snapshot); AsEntity->ApplyEntitySnapshot(Snapshot);
} }
UClass* UZMMOWorldSubsystem::ResolveActorClass(const EZMMOEntityType EntityType) const UClass* UZeusWorldSubsystem::ResolveActorClass(const EZeusEntityType EntityType) const
{ {
if (const TSubclassOf<AActor>* Found = RemoteEntityClasses.Find(EntityType)) if (const TSubclassOf<AActor>* Found = RemoteEntityClasses.Find(EntityType))
{ {
@@ -290,10 +357,10 @@ UClass* UZMMOWorldSubsystem::ResolveActorClass(const EZMMOEntityType EntityType)
return Found->Get(); return Found->Get();
} }
} }
return AZMMOEntity::StaticClass(); return AZeusEntity::StaticClass();
} }
UZeusNetworkSubsystem* UZMMOWorldSubsystem::ResolveZeusNetworkSubsystem() const UZeusNetworkSubsystem* UZeusWorldSubsystem::ResolveZeusNetworkSubsystem() const
{ {
const UWorld* World = GetWorld(); const UWorld* World = GetWorld();
if (!World) if (!World)

View File

@@ -2,16 +2,16 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Subsystems/WorldSubsystem.h" #include "Subsystems/WorldSubsystem.h"
#include "ZMMOEntityTypes.h" #include "ZeusEntityTypes.h"
#include "ZMMOWorldSubsystem.generated.h" #include "ZeusWorldSubsystem.generated.h"
class AActor; class AActor;
class AZMMOPlayerCharacter; class AZeusCharacter;
class AZMMOPlayerProxy; class AZeusPlayerProxy;
class UZeusNetworkSubsystem; class UZeusNetworkSubsystem;
/** /**
* UZMMOWorldSubsystem * UZeusWorldSubsystem
* *
* Subsistema por-mundo que orquestra a aplicacao de pacotes de replicacao * Subsistema por-mundo que orquestra a aplicacao de pacotes de replicacao
* recebidos do servidor (`S_SPAWN_PLAYER`, `S_DESPAWN_PLAYER`, * recebidos do servidor (`S_SPAWN_PLAYER`, `S_DESPAWN_PLAYER`,
@@ -26,19 +26,19 @@ class UZeusNetworkSubsystem;
* conexao UDP e dos delegates; este subsistema apenas escuta os * conexao UDP e dos delegates; este subsistema apenas escuta os
* delegates e materializa atores na cena atual. * delegates e materializa atores na cena atual.
* *
* Resolucao de classe por `EZMMOEntityType`: * Resolucao de classe por `EZeusEntityType`:
* - `RemoteEntityClasses` e um TMap configuravel (BlueprintReadWrite) * - `RemoteEntityClasses` e um TMap configuravel (BlueprintReadWrite)
* com defaults seguros em `Initialize`. Permite trocar * com defaults seguros em `Initialize`. Permite trocar
* `AZMMOPlayerProxy` por um BP filho com mesh customizada sem * `AZeusPlayerProxy` por um BP filho com mesh customizada sem
* recompilar C++. * recompilar C++.
* *
* Despawn: * Despawn:
* - V0: chama `IZMMOEntityInterface::SetEntityRelevant(false)` (preserva * - V0: chama `IZeusEntityInterface::SetEntityRelevant(false)` (preserva
* o ator para futuro pooling). * o ator para futuro pooling).
* - V1: pool real por `EntityType`, limites de memoria, expiracao. * - V1: pool real por `EntityType`, limites de memoria, expiracao.
*/ */
UCLASS() UCLASS()
class ZMMO_API UZMMOWorldSubsystem : public UWorldSubsystem class ZMMO_API UZeusWorldSubsystem : public UWorldSubsystem
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -48,27 +48,27 @@ public:
virtual void Deinitialize() override; virtual void Deinitialize() override;
/** /**
* Regista o jogador local no registry. Chamado por `AZMMOPlayerCharacter` * Regista o jogador local no registry. Chamado por `AZeusCharacter`
* apos receber o `EntityId` autoritativo do servidor (delegate * apos receber o `EntityId` autoritativo do servidor (delegate
* `OnPlayerSpawned` com `bIsLocal=true`). * `OnPlayerSpawned` com `bIsLocal=true`).
*/ */
UFUNCTION(BlueprintCallable, Category = "ZMMO|World") UFUNCTION(BlueprintCallable, Category = "Zeus|World")
void RegisterLocalEntity(int64 EntityId, AActor* LocalActor); void RegisterLocalEntity(int64 EntityId, AActor* LocalActor);
/** Numero de entidades remotas actualmente trackeadas. Util em debug overlays. */ /** Numero de entidades remotas actualmente trackeadas. Util em debug overlays. */
UFUNCTION(BlueprintPure, Category = "ZMMO|World") UFUNCTION(BlueprintPure, Category = "Zeus|World")
int32 GetTrackedEntityCount() const { return RemoteEntities.Num(); } int32 GetTrackedEntityCount() const { return RemoteEntities.Num(); }
protected: protected:
/** /**
* Mapa configuravel de classe a usar por `EZMMOEntityType`. Caso vazio, * Mapa configuravel de classe a usar por `EZeusEntityType`. Caso vazio,
* usamos defaults seguros (`AZMMOPlayerProxy` para Player, `AZMMOEntity` * usamos defaults seguros (`AZeusPlayerProxy` para Player, `AZeusEntity`
* para Mob/NPC/Object actualizado quando classes especificas existirem). * para Mob/NPC/Object actualizado quando classes especificas existirem).
* *
* Pode ser preenchido via Blueprint subclassing ou em runtime. * Pode ser preenchido via Blueprint subclassing ou em runtime.
*/ */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "ZMMO|World") UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|World")
TMap<EZMMOEntityType, TSubclassOf<AActor>> RemoteEntityClasses; TMap<EZeusEntityType, TSubclassOf<AActor>> RemoteEntityClasses;
private: private:
UFUNCTION() UFUNCTION()
@@ -80,7 +80,7 @@ private:
UFUNCTION() UFUNCTION()
void HandlePlayerStateUpdate(int64 EntityId, int32 InputSeq, FVector PosCm, FVector VelCmS, bool bGrounded, int64 ServerTimeMs); void HandlePlayerStateUpdate(int64 EntityId, int32 InputSeq, FVector PosCm, FVector VelCmS, bool bGrounded, int64 ServerTimeMs);
UClass* ResolveActorClass(EZMMOEntityType EntityType) const; UClass* ResolveActorClass(EZeusEntityType EntityType) const;
UZeusNetworkSubsystem* ResolveZeusNetworkSubsystem() const; UZeusNetworkSubsystem* ResolveZeusNetworkSubsystem() const;
/** /**

View File

@@ -20,7 +20,7 @@ void UUIDraggableWindow_Base::ApplySavedPosition()
const FName Id = GetWindowId(); const FName Id = GetWindowId();
if (Id.IsNone()) return; if (Id.IsNone()) return;
UZMMOUISaveGame* Save = UZMMOUISaveGame::LoadOrCreate(); UZeusUISaveGame* Save = UZeusUISaveGame::LoadOrCreate();
FVector2D Pos; FVector2D Pos;
if (Save && Save->TryGetWindowPosition(Id, Pos)) if (Save && Save->TryGetWindowPosition(Id, Pos))
{ {
@@ -33,10 +33,10 @@ void UUIDraggableWindow_Base::PersistCurrentPosition()
const FName Id = GetWindowId(); const FName Id = GetWindowId();
if (Id.IsNone()) return; if (Id.IsNone()) return;
UZMMOUISaveGame* Save = UZMMOUISaveGame::LoadOrCreate(); UZeusUISaveGame* Save = UZeusUISaveGame::LoadOrCreate();
if (!Save) return; if (!Save) return;
Save->SetWindowPosition(Id, GetRenderTransform().Translation); Save->SetWindowPosition(Id, GetRenderTransform().Translation);
UZMMOUISaveGame::SaveNow(Save); UZeusUISaveGame::SaveNow(Save);
} }
bool UUIDraggableWindow_Base::IsDragHandleHit(const FPointerEvent& MouseEvent) const bool UUIDraggableWindow_Base::IsDragHandleHit(const FPointerEvent& MouseEvent) const

View File

@@ -5,12 +5,12 @@
#include "UIDraggableWindow_Base.generated.h" #include "UIDraggableWindow_Base.generated.h"
class UBorder; class UBorder;
class UZMMOUISaveGame; class UZeusUISaveGame;
/** /**
* Base de janelas in-game movel + persistente. Subclasse define WindowId * Base de janelas in-game movel + persistente. Subclasse define WindowId
* (FName estavel) via override de GetWindowId(); a Base cuida do drag * (FName estavel) via override de GetWindowId(); a Base cuida do drag
* (RenderTransform.Translation) e da persistencia (UZMMOUISaveGame). * (RenderTransform.Translation) e da persistencia (UZeusUISaveGame).
* *
* Convencao do WBP: * Convencao do WBP:
* - Bind opcional `Border_DragHandle` cobrindo a area arrastavel (header). * - Bind opcional `Border_DragHandle` cobrindo a area arrastavel (header).

View File

@@ -1,10 +1,10 @@
#include "UILoadingProfilesDataAsset.h" #include "UILoadingProfilesDataAsset.h"
FZMMOLoadingProfile UZMMOLoadingProfilesDataAsset::GetProfile(EZMMOLoadingContext Context) const FZeusLoadingProfile UZeusLoadingProfilesDataAsset::GetProfile(EZeusLoadingContext Context) const
{ {
if (const FZMMOLoadingProfile* Found = Profiles.Find(Context)) if (const FZeusLoadingProfile* Found = Profiles.Find(Context))
{ {
return *Found; return *Found;
} }
return FZMMOLoadingProfile(); return FZeusLoadingProfile();
} }

View File

@@ -7,7 +7,7 @@
/** /**
* Mapa data-driven contexto → perfil (etapas + título). Designer edita o * Mapa data-driven contexto → perfil (etapas + título). Designer edita o
* asset; código consulta por EZMMOLoadingContext na hora de configurar a * asset; código consulta por EZeusLoadingContext na hora de configurar a
* tela. Asset canônico: DA_LoadingProfiles em /Game/ZMMO/Data/UI/Loading/. * tela. Asset canônico: DA_LoadingProfiles em /Game/ZMMO/Data/UI/Loading/.
* *
* Configurado em DefaultGame.ini: * Configurado em DefaultGame.ini:
@@ -15,15 +15,15 @@
* LoadingProfilesAsset=/Game/ZMMO/Data/UI/Loading/DA_LoadingProfiles.DA_LoadingProfiles * LoadingProfilesAsset=/Game/ZMMO/Data/UI/Loading/DA_LoadingProfiles.DA_LoadingProfiles
*/ */
UCLASS(BlueprintType) UCLASS(BlueprintType)
class ZMMO_API UZMMOLoadingProfilesDataAsset : public UDataAsset class ZMMO_API UZeusLoadingProfilesDataAsset : public UDataAsset
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Loading") UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Loading")
TMap<EZMMOLoadingContext, FZMMOLoadingProfile> Profiles; TMap<EZeusLoadingContext, FZeusLoadingProfile> Profiles;
/** Retorna o perfil do contexto ou um perfil vazio (sem etapas). */ /** Retorna o perfil do contexto ou um perfil vazio (sem etapas). */
UFUNCTION(BlueprintCallable, Category = "Loading") UFUNCTION(BlueprintCallable, Category = "Loading")
FZMMOLoadingProfile GetProfile(EZMMOLoadingContext Context) const; FZeusLoadingProfile GetProfile(EZeusLoadingContext Context) const;
}; };

View File

@@ -8,8 +8,8 @@
#include "UILoadingProfilesDataAsset.h" #include "UILoadingProfilesDataAsset.h"
#include "UILoadingTipRow.h" #include "UILoadingTipRow.h"
void UUILoadingScreen_Base::Configure(EZMMOLoadingContext InContext, void UUILoadingScreen_Base::Configure(EZeusLoadingContext InContext,
UZMMOLoadingProfilesDataAsset* Profiles, UZeusLoadingProfilesDataAsset* Profiles,
UDataTable* TipsTable) UDataTable* TipsTable)
{ {
Context_ = InContext; Context_ = InContext;
@@ -18,22 +18,22 @@ void UUILoadingScreen_Base::Configure(EZMMOLoadingContext InContext,
// Perfil (etapas + título). // Perfil (etapas + título).
Profile_ = (Profiles != nullptr) Profile_ = (Profiles != nullptr)
? Profiles->GetProfile(InContext) ? Profiles->GetProfile(InContext)
: FZMMOLoadingProfile(); : FZeusLoadingProfile();
StepStatus_.Reset(); StepStatus_.Reset();
for (const FZMMOLoadingStepDef& Step : Profile_.Steps) for (const FZeusLoadingStepDef& Step : Profile_.Steps)
{ {
StepStatus_.Add(Step.StepId, EZMMOLoadingStepStatus::Pending); StepStatus_.Add(Step.StepId, EZeusLoadingStepStatus::Pending);
} }
// Pool de dicas filtrada por contexto (None = qualquer). // Pool de dicas filtrada por contexto (None = qualquer).
TipPool_.Reset(); TipPool_.Reset();
if (TipsTable != nullptr) if (TipsTable != nullptr)
{ {
TipsTable->ForeachRow<FZMMOLoadingTipRow>(TEXT("UUILoadingScreen_Base::Configure"), TipsTable->ForeachRow<FZeusLoadingTipRow>(TEXT("UUILoadingScreen_Base::Configure"),
[this](const FName& /*Key*/, const FZMMOLoadingTipRow& Row) [this](const FName& /*Key*/, const FZeusLoadingTipRow& Row)
{ {
if (Row.Context == EZMMOLoadingContext::None || Row.Context == Context_) if (Row.Context == EZeusLoadingContext::None || Row.Context == Context_)
{ {
if (!Row.Tip.IsEmpty()) if (!Row.Tip.IsEmpty())
{ {
@@ -67,12 +67,12 @@ void UUILoadingScreen_Base::NativeOnDeactivated()
void UUILoadingScreen_Base::MarkStepRunning(FName StepId) void UUILoadingScreen_Base::MarkStepRunning(FName StepId)
{ {
if (EZMMOLoadingStepStatus* Status = StepStatus_.Find(StepId)) if (EZeusLoadingStepStatus* Status = StepStatus_.Find(StepId))
{ {
// Já Done não regride. // Já Done não regride.
if (*Status != EZMMOLoadingStepStatus::Done && *Status != EZMMOLoadingStepStatus::Failed) if (*Status != EZeusLoadingStepStatus::Done && *Status != EZeusLoadingStepStatus::Failed)
{ {
*Status = EZMMOLoadingStepStatus::Running; *Status = EZeusLoadingStepStatus::Running;
RefreshUI(); RefreshUI();
} }
} }
@@ -80,9 +80,9 @@ void UUILoadingScreen_Base::MarkStepRunning(FName StepId)
void UUILoadingScreen_Base::MarkStepDone(FName StepId) void UUILoadingScreen_Base::MarkStepDone(FName StepId)
{ {
if (EZMMOLoadingStepStatus* Status = StepStatus_.Find(StepId)) if (EZeusLoadingStepStatus* Status = StepStatus_.Find(StepId))
{ {
*Status = EZMMOLoadingStepStatus::Done; *Status = EZeusLoadingStepStatus::Done;
RefreshUI(); RefreshUI();
if (!bCompleteFired_ && AreAllStepsDone()) if (!bCompleteFired_ && AreAllStepsDone())
@@ -95,9 +95,9 @@ void UUILoadingScreen_Base::MarkStepDone(FName StepId)
void UUILoadingScreen_Base::MarkStepFailed(FName StepId, const FText& Reason) void UUILoadingScreen_Base::MarkStepFailed(FName StepId, const FText& Reason)
{ {
if (EZMMOLoadingStepStatus* Status = StepStatus_.Find(StepId)) if (EZeusLoadingStepStatus* Status = StepStatus_.Find(StepId))
{ {
*Status = EZMMOLoadingStepStatus::Failed; *Status = EZeusLoadingStepStatus::Failed;
if (Text_Status && !Reason.IsEmpty()) if (Text_Status && !Reason.IsEmpty())
{ {
Text_Status->SetText(Reason); Text_Status->SetText(Reason);
@@ -112,10 +112,10 @@ bool UUILoadingScreen_Base::AreAllStepsDone() const
{ {
return false; return false;
} }
for (const FZMMOLoadingStepDef& Step : Profile_.Steps) for (const FZeusLoadingStepDef& Step : Profile_.Steps)
{ {
const EZMMOLoadingStepStatus* Status = StepStatus_.Find(Step.StepId); const EZeusLoadingStepStatus* Status = StepStatus_.Find(Step.StepId);
if (Status == nullptr || *Status != EZMMOLoadingStepStatus::Done) if (Status == nullptr || *Status != EZeusLoadingStepStatus::Done)
{ {
return false; return false;
} }
@@ -135,11 +135,11 @@ int32 UUILoadingScreen_Base::FindStepIndex(FName StepId) const
return INDEX_NONE; return INDEX_NONE;
} }
EZMMOLoadingStepStatus UUILoadingScreen_Base::GetStepStatus(int32 Index) const EZeusLoadingStepStatus UUILoadingScreen_Base::GetStepStatus(int32 Index) const
{ {
if (!Profile_.Steps.IsValidIndex(Index)) return EZMMOLoadingStepStatus::Pending; if (!Profile_.Steps.IsValidIndex(Index)) return EZeusLoadingStepStatus::Pending;
const EZMMOLoadingStepStatus* Status = StepStatus_.Find(Profile_.Steps[Index].StepId); const EZeusLoadingStepStatus* Status = StepStatus_.Find(Profile_.Steps[Index].StepId);
return Status ? *Status : EZMMOLoadingStepStatus::Pending; return Status ? *Status : EZeusLoadingStepStatus::Pending;
} }
FText UUILoadingScreen_Base::ComputeCurrentStatusText() const FText UUILoadingScreen_Base::ComputeCurrentStatusText() const
@@ -148,12 +148,12 @@ FText UUILoadingScreen_Base::ComputeCurrentStatusText() const
int32 LastDone = INDEX_NONE; int32 LastDone = INDEX_NONE;
for (int32 i = 0; i < Profile_.Steps.Num(); ++i) for (int32 i = 0; i < Profile_.Steps.Num(); ++i)
{ {
const EZMMOLoadingStepStatus St = GetStepStatus(i); const EZeusLoadingStepStatus St = GetStepStatus(i);
if (St == EZMMOLoadingStepStatus::Running) if (St == EZeusLoadingStepStatus::Running)
{ {
return Profile_.Steps[i].Label; return Profile_.Steps[i].Label;
} }
if (St == EZMMOLoadingStepStatus::Done) if (St == EZeusLoadingStepStatus::Done)
{ {
LastDone = i; LastDone = i;
} }
@@ -176,9 +176,9 @@ float UUILoadingScreen_Base::ComputeProgress01() const
float Acc = 0.f; float Acc = 0.f;
for (int32 i = 0; i < N; ++i) for (int32 i = 0; i < N; ++i)
{ {
const EZMMOLoadingStepStatus St = GetStepStatus(i); const EZeusLoadingStepStatus St = GetStepStatus(i);
if (St == EZMMOLoadingStepStatus::Done) Acc += 1.f; if (St == EZeusLoadingStepStatus::Done) Acc += 1.f;
else if (St == EZMMOLoadingStepStatus::Running) Acc += 0.5f; else if (St == EZeusLoadingStepStatus::Running) Acc += 0.5f;
} }
return FMath::Clamp(Acc / static_cast<float>(N), 0.f, 1.f); return FMath::Clamp(Acc / static_cast<float>(N), 0.f, 1.f);
} }

View File

@@ -8,15 +8,15 @@
class UCommonTextBlock; class UCommonTextBlock;
class UProgressBar; class UProgressBar;
class UDataTable; class UDataTable;
class UZMMOLoadingProfilesDataAsset; class UZeusLoadingProfilesDataAsset;
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FZMMOOnLoadingComplete); DECLARE_DYNAMIC_MULTICAST_DELEGATE(FZeusOnLoadingComplete);
/** /**
* Tela de loading genérica. Reusada pelo FrontEnd (handoff CharServer → * Tela de loading genérica. Reusada pelo FrontEnd (handoff CharServer →
* WorldServer) e pelo InGame (entrada em instance/dungeon, respawn). Cada * WorldServer) e pelo InGame (entrada em instance/dungeon, respawn). Cada
* uso passa um EZMMOLoadingContext em Configure(), que resolve o perfil * uso passa um EZeusLoadingContext em Configure(), que resolve o perfil
* no UZMMOLoadingProfilesDataAsset (lista de etapas + título). * no UZeusLoadingProfilesDataAsset (lista de etapas + título).
* *
* Quem orquestra (UIFrontEndFlowSubsystem, futuro UIInGameFlowSubsystem) * Quem orquestra (UIFrontEndFlowSubsystem, futuro UIInGameFlowSubsystem)
* assina os próprios eventos (HandlePostLoadMap, OnPlayerSpawned, etc) e * assina os próprios eventos (HandlePostLoadMap, OnPlayerSpawned, etc) e
@@ -41,8 +41,8 @@ public:
* de NativeOnActivated (estado é reaplicado em RefreshUI). * de NativeOnActivated (estado é reaplicado em RefreshUI).
*/ */
UFUNCTION(BlueprintCallable, Category = "Loading") UFUNCTION(BlueprintCallable, Category = "Loading")
void Configure(EZMMOLoadingContext InContext, void Configure(EZeusLoadingContext InContext,
UZMMOLoadingProfilesDataAsset* Profiles, UZeusLoadingProfilesDataAsset* Profiles,
UDataTable* TipsTable); UDataTable* TipsTable);
UFUNCTION(BlueprintCallable, Category = "Loading") UFUNCTION(BlueprintCallable, Category = "Loading")
@@ -59,7 +59,7 @@ public:
/** Disparado UMA vez quando todas as etapas viram Done. */ /** Disparado UMA vez quando todas as etapas viram Done. */
UPROPERTY(BlueprintAssignable, Category = "Loading") UPROPERTY(BlueprintAssignable, Category = "Loading")
FZMMOOnLoadingComplete OnLoadingComplete; FZeusOnLoadingComplete OnLoadingComplete;
protected: protected:
virtual void NativeOnActivated() override; virtual void NativeOnActivated() override;
@@ -75,7 +75,7 @@ protected:
int32 FindStepIndex(FName StepId) const; int32 FindStepIndex(FName StepId) const;
/** Status atual da etapa em [Steps_]; Pending se não rastreada. */ /** Status atual da etapa em [Steps_]; Pending se não rastreada. */
EZMMOLoadingStepStatus GetStepStatus(int32 Index) const; EZeusLoadingStepStatus GetStepStatus(int32 Index) const;
/** Texto exibido em Text_Status — etapa Running atual ou última Done. */ /** Texto exibido em Text_Status — etapa Running atual ou última Done. */
FText ComputeCurrentStatusText() const; FText ComputeCurrentStatusText() const;
@@ -107,13 +107,13 @@ protected:
float TipRotationIntervalSeconds = 6.f; float TipRotationIntervalSeconds = 6.f;
private: private:
EZMMOLoadingContext Context_ = EZMMOLoadingContext::None; EZeusLoadingContext Context_ = EZeusLoadingContext::None;
UPROPERTY(Transient) UPROPERTY(Transient)
FZMMOLoadingProfile Profile_; FZeusLoadingProfile Profile_;
UPROPERTY(Transient) UPROPERTY(Transient)
TMap<FName, EZMMOLoadingStepStatus> StepStatus_; TMap<FName, EZeusLoadingStepStatus> StepStatus_;
UPROPERTY(Transient) UPROPERTY(Transient)
TArray<FText> TipPool_; TArray<FText> TipPool_;

View File

@@ -12,7 +12,7 @@
* UE). Filtra por contexto: Context=None significa "qualquer loading". * UE). Filtra por contexto: Context=None significa "qualquer loading".
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct FZMMOLoadingTipRow : public FTableRowBase struct FZeusLoadingTipRow : public FTableRowBase
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -22,7 +22,7 @@ struct FZMMOLoadingTipRow : public FTableRowBase
/** Restringe a dica a um contexto. None = todos. */ /** Restringe a dica a um contexto. None = todos. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading")
EZMMOLoadingContext Context = EZMMOLoadingContext::None; EZeusLoadingContext Context = EZeusLoadingContext::None;
/** Tag opcional pra categorizar (PvE/PvP/Crafting...) — futuro filtro. */ /** Tag opcional pra categorizar (PvE/PvP/Crafting...) — futuro filtro. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Loading")

View File

@@ -2,23 +2,23 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
const FString UZMMOUISaveGame::SlotName = TEXT("UIPrefs"); const FString UZeusUISaveGame::SlotName = TEXT("UIPrefs");
UZMMOUISaveGame* UZMMOUISaveGame::LoadOrCreate() UZeusUISaveGame* UZeusUISaveGame::LoadOrCreate()
{ {
if (UGameplayStatics::DoesSaveGameExist(SlotName, UserIndex)) if (UGameplayStatics::DoesSaveGameExist(SlotName, UserIndex))
{ {
if (UZMMOUISaveGame* Loaded = Cast<UZMMOUISaveGame>( if (UZeusUISaveGame* Loaded = Cast<UZeusUISaveGame>(
UGameplayStatics::LoadGameFromSlot(SlotName, UserIndex))) UGameplayStatics::LoadGameFromSlot(SlotName, UserIndex)))
{ {
return Loaded; return Loaded;
} }
} }
return Cast<UZMMOUISaveGame>( return Cast<UZeusUISaveGame>(
UGameplayStatics::CreateSaveGameObject(UZMMOUISaveGame::StaticClass())); UGameplayStatics::CreateSaveGameObject(UZeusUISaveGame::StaticClass()));
} }
void UZMMOUISaveGame::SaveNow(UZMMOUISaveGame* Save) void UZeusUISaveGame::SaveNow(UZeusUISaveGame* Save)
{ {
if (Save) if (Save)
{ {
@@ -26,7 +26,7 @@ void UZMMOUISaveGame::SaveNow(UZMMOUISaveGame* Save)
} }
} }
bool UZMMOUISaveGame::TryGetWindowPosition(FName WindowId, FVector2D& OutPos) const bool UZeusUISaveGame::TryGetWindowPosition(FName WindowId, FVector2D& OutPos) const
{ {
if (const FVector2D* Found = WindowPositions.Find(WindowId)) if (const FVector2D* Found = WindowPositions.Find(WindowId))
{ {
@@ -37,7 +37,7 @@ bool UZMMOUISaveGame::TryGetWindowPosition(FName WindowId, FVector2D& OutPos) co
return false; return false;
} }
void UZMMOUISaveGame::SetWindowPosition(FName WindowId, FVector2D Pos) void UZeusUISaveGame::SetWindowPosition(FName WindowId, FVector2D Pos)
{ {
WindowPositions.Add(WindowId, Pos); WindowPositions.Add(WindowId, Pos);
} }

View File

@@ -10,13 +10,13 @@
* movel registra uma chave (FName WindowId) e grava aqui ao soltar o drag. * movel registra uma chave (FName WindowId) e grava aqui ao soltar o drag.
* *
* Arquivo: [Project]/Saved/SaveGames/UIPrefs_0.sav (binary blob via * Arquivo: [Project]/Saved/SaveGames/UIPrefs_0.sav (binary blob via
* UE serializer). Mesmo padrao do [[ZMMOLoginSaveGame]]. * UE serializer). Mesmo padrao do [[ZeusLoginSaveGame]].
* *
* Helpers static abaixo encapsulam load-or-create do slot e Get/Set/Save * Helpers static abaixo encapsulam load-or-create do slot e Get/Set/Save
* pra que a Base nao precise repetir a cerimonia. * pra que a Base nao precise repetir a cerimonia.
*/ */
UCLASS() UCLASS()
class ZMMO_API UZMMOUISaveGame : public USaveGame class ZMMO_API UZeusUISaveGame : public USaveGame
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -32,10 +32,10 @@ public:
* Carrega o save existente ou cria um novo (nao salva ainda). * Carrega o save existente ou cria um novo (nao salva ainda).
* Sempre retorna instancia valida. * Sempre retorna instancia valida.
*/ */
static UZMMOUISaveGame* LoadOrCreate(); static UZeusUISaveGame* LoadOrCreate();
/** Salva o slot atual (sincrono — chamado on-mouse-up, custo baixo). */ /** Salva o slot atual (sincrono — chamado on-mouse-up, custo baixo). */
static void SaveNow(UZMMOUISaveGame* Save); static void SaveNow(UZeusUISaveGame* Save);
/** Get com default — se WindowId nao foi gravado retorna FVector2D::ZeroVector. */ /** Get com default — se WindowId nao foi gravado retorna FVector2D::ZeroVector. */
UFUNCTION(BlueprintCallable, Category = "UI|Prefs") UFUNCTION(BlueprintCallable, Category = "UI|Prefs")

View File

@@ -10,9 +10,9 @@
* é responsabilidade do UZeusCharServerSubsystem (Send/OnRawMessage operam * é responsabilidade do UZeusCharServerSubsystem (Send/OnRawMessage operam
* sobre o payload já sem header). * sobre o payload já sem header).
*/ */
namespace ZMMOCharOp namespace ZeusCharOp
{ {
// Autenticação — payload começa com uint8 method (ver ZMMOCharAuthMethod) // Autenticação — payload começa com uint8 method (ver ZeusCharAuthMethod)
constexpr int32 C_CHAR_AUTH_REQUEST = 2000; constexpr int32 C_CHAR_AUTH_REQUEST = 2000;
constexpr int32 S_CHAR_AUTH_OK = 2001; // string(accountId)+string(user)+uint64(expiresMs) constexpr int32 S_CHAR_AUTH_OK = 2001; // string(accountId)+string(user)+uint64(expiresMs)
constexpr int32 S_CHAR_AUTH_REJECT = 2002; // uint16(reason) constexpr int32 S_CHAR_AUTH_REJECT = 2002; // uint16(reason)
@@ -52,14 +52,14 @@ namespace ZMMOCharOp
* Método de autenticação enviado como uint8 prefix no payload do * Método de autenticação enviado como uint8 prefix no payload do
* C_CHAR_AUTH_REQUEST. * C_CHAR_AUTH_REQUEST.
*/ */
namespace ZMMOCharAuthMethod namespace ZeusCharAuthMethod
{ {
constexpr uint8 TOKEN = 0; constexpr uint8 TOKEN = 0;
constexpr uint8 PASSWORD = 1; constexpr uint8 PASSWORD = 1;
} }
/** Espelha `CharRejectReason` em CharOpcodes.ts. */ /** Espelha `CharRejectReason` em CharOpcodes.ts. */
namespace ZMMOCharRejectReason namespace ZeusCharRejectReason
{ {
constexpr uint16 Unknown = 0; constexpr uint16 Unknown = 0;
constexpr uint16 InvalidToken = 1; constexpr uint16 InvalidToken = 1;
@@ -85,7 +85,7 @@ namespace ZMMOCharRejectReason
} }
/** Estado do Realm no wire (uint8). Espelha `WireRealmState` em CharOpcodes.ts. */ /** Estado do Realm no wire (uint8). Espelha `WireRealmState` em CharOpcodes.ts. */
namespace ZMMOWireRealmState namespace ZeusWireRealmState
{ {
constexpr uint8 Offline = 0; constexpr uint8 Offline = 0;
constexpr uint8 Online = 1; constexpr uint8 Online = 1;

View File

@@ -1,6 +1,6 @@
#include "UIActivatableScreen_Base.h" #include "UIActivatableScreen_Base.h"
#include "ZMMOThemeSubsystem.h" #include "ZeusThemeSubsystem.h"
#include "UIFrontEndFlowSubsystem.h" #include "UIFrontEndFlowSubsystem.h"
#include "Engine/GameInstance.h" #include "Engine/GameInstance.h"
#include "Input/UIActionBindingHandle.h" #include "Input/UIActionBindingHandle.h"
@@ -10,13 +10,13 @@ TOptional<FUIInputConfig> UUIActivatableScreen_Base::GetDesiredInputConfig() con
{ {
switch (InputConfig) switch (InputConfig)
{ {
case EZMMOScreenInputMode::GameAndMenu: case EZeusScreenInputMode::GameAndMenu:
return FUIInputConfig(ECommonInputMode::All, GameMouseCaptureMode); return FUIInputConfig(ECommonInputMode::All, GameMouseCaptureMode);
case EZMMOScreenInputMode::Game: case EZeusScreenInputMode::Game:
return FUIInputConfig(ECommonInputMode::Game, GameMouseCaptureMode); return FUIInputConfig(ECommonInputMode::Game, GameMouseCaptureMode);
case EZMMOScreenInputMode::Menu: case EZeusScreenInputMode::Menu:
return FUIInputConfig(ECommonInputMode::Menu, EMouseCaptureMode::NoCapture); return FUIInputConfig(ECommonInputMode::Menu, EMouseCaptureMode::NoCapture);
case EZMMOScreenInputMode::Default: case EZeusScreenInputMode::Default:
default: default:
return TOptional<FUIInputConfig>(); return TOptional<FUIInputConfig>();
} }
@@ -25,7 +25,7 @@ TOptional<FUIInputConfig> UUIActivatableScreen_Base::GetDesiredInputConfig() con
void UUIActivatableScreen_Base::RefreshUIStyle_Implementation() void UUIActivatableScreen_Base::RefreshUIStyle_Implementation()
{ {
// Base no-op: cada WBP/filho sobrescreve para reaplicar tokens do tema // Base no-op: cada WBP/filho sobrescreve para reaplicar tokens do tema
// ativo (via UZMMOThemeSubsystem). Mantém o contrato igual a // ativo (via UZeusThemeSubsystem). Mantém o contrato igual a
// UUIButton_Base::RefreshUIStyle / UUIPanel_Base::RefreshUIStyle. // UUIButton_Base::RefreshUIStyle / UUIPanel_Base::RefreshUIStyle.
} }
@@ -37,7 +37,7 @@ void UUIActivatableScreen_Base::NativeConstruct()
{ {
if (const UGameInstance* GI = GetGameInstance()) if (const UGameInstance* GI = GetGameInstance())
{ {
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>()) if (UZeusThemeSubsystem* Theme = GI->GetSubsystem<UZeusThemeSubsystem>())
{ {
Theme->OnThemeChanged.AddDynamic(this, &UUIActivatableScreen_Base::HandleThemeChanged); Theme->OnThemeChanged.AddDynamic(this, &UUIActivatableScreen_Base::HandleThemeChanged);
bThemeBound = true; bThemeBound = true;
@@ -54,7 +54,7 @@ void UUIActivatableScreen_Base::NativeDestruct()
{ {
if (const UGameInstance* GI = GetGameInstance()) if (const UGameInstance* GI = GetGameInstance())
{ {
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>()) if (UZeusThemeSubsystem* Theme = GI->GetSubsystem<UZeusThemeSubsystem>())
{ {
Theme->OnThemeChanged.RemoveDynamic(this, &UUIActivatableScreen_Base::HandleThemeChanged); Theme->OnThemeChanged.RemoveDynamic(this, &UUIActivatableScreen_Base::HandleThemeChanged);
} }

View File

@@ -11,7 +11,7 @@
* GetDesiredInputConfig. * GetDesiredInputConfig.
*/ */
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EZMMOScreenInputMode : uint8 enum class EZeusScreenInputMode : uint8
{ {
Default, // não força nada (herda do CommonUI) Default, // não força nada (herda do CommonUI)
GameAndMenu, // jogo + UI (ex.: HUD com cursor) GameAndMenu, // jogo + UI (ex.: HUD com cursor)
@@ -27,7 +27,7 @@ enum class EZMMOScreenInputMode : uint8
* desta classe C++ (UMG não encadeia árvores — ARQUITETURA.md §3.3). Os WBPs * desta classe C++ (UMG não encadeia árvores — ARQUITETURA.md §3.3). Os WBPs
* gerados pelo Zeus UMG Forge são reparented para cá (§4.8). * gerados pelo Zeus UMG Forge são reparented para cá (§4.8).
* *
* Reage à troca de tema via UZMMOThemeSubsystem (mesmo padrão de * Reage à troca de tema via UZeusThemeSubsystem (mesmo padrão de
* UUIButton_Base) e encaminha o "voltar" ao UUIFrontEndFlowSubsystem. * UUIButton_Base) e encaminha o "voltar" ao UUIFrontEndFlowSubsystem.
*/ */
UCLASS(Abstract, Blueprintable) UCLASS(Abstract, Blueprintable)
@@ -44,7 +44,7 @@ public:
protected: protected:
// ---- Input config (desktop/gamepad) ---- // ---- Input config (desktop/gamepad) ----
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Input") UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Input")
EZMMOScreenInputMode InputConfig = EZMMOScreenInputMode::Menu; EZeusScreenInputMode InputConfig = EZeusScreenInputMode::Menu;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Input") UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Input")
EMouseCaptureMode GameMouseCaptureMode = EMouseCaptureMode::CapturePermanently; EMouseCaptureMode GameMouseCaptureMode = EMouseCaptureMode::CapturePermanently;

View File

@@ -4,7 +4,7 @@
#include "UIButton_Base.h" #include "UIButton_Base.h"
#include "UISpinner_Base.h" #include "UISpinner_Base.h"
#include "UIFrontEndFlowSubsystem.h" #include "UIFrontEndFlowSubsystem.h"
#include "ZMMOThemeSubsystem.h" #include "ZeusThemeSubsystem.h"
#include "ZeusCharServerSubsystem.h" #include "ZeusCharServerSubsystem.h"
#include "CommonTextBlock.h" #include "CommonTextBlock.h"
#include "Components/Border.h" #include "Components/Border.h"
@@ -22,7 +22,7 @@ namespace
{ {
if (const UGameInstance* GI = Widget->GetGameInstance()) if (const UGameInstance* GI = Widget->GetGameInstance())
{ {
if (const UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>()) if (const UZeusThemeSubsystem* Theme = GI->GetSubsystem<UZeusThemeSubsystem>())
{ {
return Theme->GetActiveUIStyle(); return Theme->GetActiveUIStyle();
} }

Some files were not shown because too many files have changed in this diff Show More