Commit Graph

52 Commits

Author SHA1 Message Date
1794e5d418 feat(ui/progressbar): UProgressBar -> UImage com material custom Primary/Secondary
UUIProgressBar_Base envolve UImage + MID em vez do UProgressBar nativo.
Material UI_M_ProgressBar expoe PrimaryLevel/SecondaryLevel (modelo
assimetrico: Secondary so aparece se > Primary), 5 cores (Primary +
ColourBottom, Secondary + ColourBottom, Empty) e gradient toggle com
bilinear remap controlado por GradientSplit.

Cores e gradient ficam expostos como UPROPERTY com InlineEditConditionToggle:
quando o toggle esta off usa o valor da MI atribuida no Brush, quando on
sobrescreve via MID em PreConstruct. Setters runtime tambem marcam o flag
pra persistir o override no proximo re-construct.

Wrappers semanticos: ShowHealPreview, ShowDamageLag, ShowBuffer, ClearSecondary.
NativeTick com ease-out cubica e duracoes separadas pra Primary e Secondary.

Inclui MI exemplo UI_M_ProgressBar_HP e WBP UI_ProgressBar_Master refatorado
(UProgressBar nativo substituido por UImage FillImage com brush apontando
para o material pai).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 19:29:43 -03:00
7fa10b4cb9 fix(ui/loading): memoiza steps quando widget em async load + draggable status
- UIFrontEndFlowSubsystem: HandlePostLoadMap/HandlePlayerSpawned agora
  registram o StepId em PendingLoadingSteps_ quando ActiveLoadingScreen
  ainda eh null (race com RequestAsyncLoad do WBP_Loading). Lambda do
  callback async drena o set apos criar a tela, fechando o loading
  retroativamente. Servidor rapido (TryFinalizeEnterWorld) deixava o
  cliente preso em "entrando no mundo" quando o async load atrasava.

- UIPlayerStatus_Window: herda de UIDraggableWindow_Base (drag + persist
  via UZMMOUISaveGame). Rename CloseBtn -> Button_Close, adiciona
  Background_Panel/Container_Header/Container_Stats, NativeOnKeyDown
  (Alt+A fecha), NativeGetDesiredFocusTarget=self. Remove bIsBackHandler
  pra parar o "Cannot create action binding" no log (projeto nao tem
  DefaultBackAction no CommonUISettings).

- UIInGameFlowSubsystem.SetState: skip re-push do HUD quando voltando de
  StatusWindow/Inventory/Menu pro Playing (Old != None && != Playing) pra
  evitar Construct novo do HUD e o flicker dos textos HP/SP.

- Novos: UIDraggableWindow_Base (drag generico + persistencia) e
  UIWindowSaveGame (TMap<FName, FVector2D> por WindowId).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 14:50:49 -03:00
079d05c117 feat(ui/loading): tela de loading dinamica data-driven (etapas + dicas)
- UUILoadingScreen_Base (Game/UI/Common/) generica: Configure(Context),
  MarkStepRunning/Done/Failed, OnLoadingComplete delegate, progress bar
  reativa e rotacao automatica de dicas via timer.
- Etapas configuradas por contexto em UZMMOLoadingProfilesDataAsset
  (DA_LoadingProfiles). Perfil inicial FrontEndEnteringWorld:
  Travel -> MapLoaded -> Spawn.
- Dicas em DT_LoadingTips (FText localizavel + filtro por contexto +
  GameplayTag de categoria). 4 dicas seed.
- UIFrontEndFlowSubsystem agora bloqueia a transicao InWorld ate o
  HandlePlayerSpawned (bIsLocal=true) — usuario nao ve mundo vazio.
- WBP_Loading em /UI/Shared/Loading/ (neutro, reusavel pelo InGame futuro);
  DA_FrontEndScreenSet[EnteringWorld] aponta pra ele.
- DefaultGame.ini wire LoadingProfilesAsset + LoadingTipsAsset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:24:48 -03:00
90484876f0 feat(player): CharName do DB no PlayerState + header do Status Window
- PlayerState ganha CharName (Replicated) + SetCharInfo(CharName, GuildName)
- ZMMOPlayerCharacter assina FZeusOnCharInfoReceived; TryApplyCachedCharInfo
  resolve race se S_CHAR_INFO chega antes do pawn possuir
- UIPlayerStatus_Window header le PlayerState->CharName (fallback p/ GetPlayerName)
  em vez do "Mateuus-61E9B19A4FB2" generico

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:24:29 -03:00
87d9ca4dae chore(ui): textura do panel gradient quadrado + ignore /AutoCreated
- Adiciona as 3 texturas que o refactor de panel referencia via
  EUIPanelTexture::Rectangle_Square_Gradient_01 (background gradient,
  outline e outline effect) em /UI/Themes/Default/Panel/.
- Ignora Content/AutoCreated/ no .gitignore: pasta de saida do
  ZeusUMGForge web converter, regenerada sob demanda, nao deve ser
  versionada.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:14:38 -03:00
037aed30ce refactor(ui/base): panel data-driven 3-brush + button via FButtonStyle
UIPanel_Base: substitui PanelType/Padding por bUseTheme + 3 chaves
(Background/Outline/OutlineEffectKey) lidas de FUIStylePanel. Modo manual
(bUseTheme=false) expoe 3 FSlateBrush diretos via FUIPanelBrushSet pra
override por instancia. Adiciona BindWidgetOptional OutlineEffect (3o
Border sobre Outline pra glow/embossing). Defaults NoDrawType (regra
Hyper: brush vazio nao pinta branco).

UIButton_Base: remove auto-config (Variants enum, Number/Icon/Size/
InputAction/Timer). Vira shell minimal com BindWidgetOptional + helpers
GetActiveUIStyle/GetActiveButtonStyle pra leitura de DT_UI_Styles.

UIStyleTokens: FUIStylePanel ganha PanelOutlineEffect map. FUIPanelBrushSet
vira 3 FSlateBrush diretos. FUIStyleButton refatora pra 7 sub-maps por
variante FName (ButtonStyle=FButtonStyle do Slate, ButtonStroke, ButtonFont,
Text/Icon colors). Tudo com defaults NoDrawType.

UIStyleTypes: adiciona enum EUIPanelTexture::Rectangle_Square_Gradient_01.

Content: UI_Panel_Master e UI_Button_Master_New consomem a API nova;
DT_UI_Styles atualizado com rows/keys novas. UIServerCard_Base ajustado
pro consumer da API nova.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:12:58 -03:00
9390ed9da9 feat(ui/status): nova janela com sub-widgets StatRow/BonusRow + cleanup
- 3 novas classes C++ (UUIPlayerStatus_Window/StatRow/BonusRow) substituem
  UZMMOStatusWindowWidget (removida); StatRow/BonusRow sao reutilizaveis
  via BindWidgetOptional + delegate OnPlusClicked(StatId).
- Window bindea no UZMMOAttributeComponent (PlayerState) e popula header
  (CharName, Job via UZMMOJobsSubsystem, BaseLevel/JobLevel) + 14 rows
  (6 primarios em StatRow com botao "+", 8 derivados em BonusRow).
- Fix spam-click do "+": bPlusButtonsLocked desabilita botoes ate
  OnStatAllocReply do server ou proximo snapshot.
- WBPs movidos pra /UI/Screens/PlayerStatus/, material pra /UI/Materials/.
- 58 widgets renomeados seguindo convencao
  (Frame_/Layout_/Panel_/Container_/Border_/Text_/Image_/Spacer_/List_).
- DA_InGameScreenSet auto-atualizado pelo move.
- Remove WBP_StatusWindow inline (legado).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:09:28 -03:00
28bfa9a567 feat(attributes): MATK range min~max no snapshot + display
Espelha breaking change do server (S_ATTRIBUTE_SNAPSHOT_FULL agora envia
matkBaseMin/matkBaseMax em vez de matkBase unico) para suportar MATK
pre-renewal puro (rathena status_base_matk_min/max).

- FZeusAttributesPayload: MatkBaseMin/Max em vez de MatkBase
- FZMMOAttributesSnapshot: idem (BlueprintReadOnly)
- ZMMOStatusWindowWidget: exibe "MATK min ~ max + equip"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 01:52:48 -03:00
6391372f00 feat(jobs): Jobs.1 client UI infra (handler + library + tecla J) + UI tweaks
Infraestrutura cliente da promocao de classe (Jobs.1). WBP_JobChangePanel
NAO esta neste commit — foi exploracao descartada (criar UI dinamica de
botoes via MCP BP graph esbarrou em limites do CreateWidget node). A
fundacao C++ fica pronta pra ser usada quando voltarmos pra UI.

INFRA C++ NOVA (Source/ZMMOJobs/)
* UZMMOJobChangeNetworkHandler (WorldSubsystem novo) — bind no
  OnJobChangeResult do plugin e re-broadcast via FZMMOOnJobChangeResultBP
  (dynamic multicast assignavel em BP). WBP futura escuta direto.
* UZMMOJobsSubsystem helpers: GetJobsByTier(EZMMOJobTier) +
  GetEligibleNextJobs(currentClassId) — filtra por ParentClassId. Pure.
* UZMMOJobsLibrary BPFL wrappers + SendJobChangeRequest convenience
  (delega pro UZeusNetworkSubsystem). Dep ZeusNetwork adicionada no
  Build.cs.

ENUM + INPUT
* EZMMOInGameUIState ganha JobChangePanel (entre StatusWindow e
  Inventory). DA_InGameScreenSet pendente de receber entry quando
  WBP for criada (tecla J vai falhar silenciosamente ate la).
* ZMMOPlayerController: tecla J -> ToggleJobChangePanel ->
  Flow->ToggleScreen(JobChangePanel). Espelha pattern do Alt+A do
  StatusWindow (InputComponent legacy BindKey + FInputChord).

UI TWEAKS
* WBP_StatusWindow + DT_UI_Styles: ajustes visuais no Editor durante a
  sessao (sem mudanca funcional documentavel — provavelmente fontes/
  spacing/cores).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 01:37:04 -03:00
f832c1a4df fix(log): remove HandleZeusNetworkLog forwarder (duplicava LogZMMO)
UZMMOGameInstance assinava OnNetworkLog do plugin e re-logava em LogZMMO
com prefix [Zeus]. Resultado: cada linha do plugin aparecia 2x no console
(LogZeusNetwork + LogZMMO). Era diagnostico inicial da fase de bring-up
(sessao 2026-05-07); agora so' polui o log.

Bind removido em BindZeusDelegates. Funcao HandleZeusNetworkLog mantida no
.h/.cpp (UFUNCTION dynamic delegate target) com comentario explicando como
reativar via descomentar a linha do AddDynamic.

Plugin continua logando em LogZeusNetwork (console) + Saved/Logs/ZeusNetwork/
(arquivo proprio) — diagnostico nao foi perdido, so' deduplicado.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 01:36:34 -03:00
c3df705a7a feat(jobs): Jobs.1 client — DA expandido + 7 DA_Job assets organizados por tier
* UZMMOJobDataAsset (Source/ZMMOJobs/Public/) ganha 3 campos novos
  espelhando o JobDef do server:
    - Tier             (EZMMOJobTier)
    - ParentClassId    (int32)
    - AllowedWeapons   (TArray<EZMMOWeaponType>)

* Novo header ZMMOJobTypes.h com 2 UENUM(BlueprintType):
    - EZMMOJobTier      (6 valores: Beginner..Mastery)
    - EZMMOWeaponType   (19 valores: Fist..Gun)
  Todos com UMETA(DisplayName="pt-BR") pro Editor mostrar nomes
  amigaveis em dropdowns. Ordem casa byte-a-byte com EJobTier/
  EWeaponType do server (necessario pq snapshot carrega tier u8 + mask).

* 7 DA_Job_*.uasset criados via MCP Python, organizados por tier:
    Content/ZMMO/Data/Jobs/Beginner/
      DA_Job_Novice    (ClassId=0, AllowedWeapons=[Fist,Dagger])
    Content/ZMMO/Data/Jobs/Vocation/
      DA_Job_Warrior   (ClassId=1, 8 armas: Sword+Spear+Axe variations)
      DA_Job_Arcanist  (ClassId=2, 5 armas: Staff+Book)
      DA_Job_Ranger    (ClassId=3, 5 armas: Bow+Musical+Whip)
      DA_Job_Artisan   (ClassId=4, 5 armas: Sword1H+Mace1H+Axe1H)
      DA_Job_Rogue     (ClassId=5, 5 armas: Sword1H+Bow+Katar)
      DA_Job_Devout    (ClassId=6, 5 armas: Mace+Staff1H+Knuckle)
  ParentClassId=0 (Novice) em todas Vocacoes. Tier=Vocation.
  JobIcon/Sound/Anim ficam None — preencher conforme arte for produzida.

  ZMMOJobsSubsystem busca por classe (GetAssetsByClass), entao a
  reorganizacao em subpastas NAO requer mudanca em .cpp/.h.

* ZMMOAttributeTypes.h: comentario de opcode 1200 -> 1500 (espelha
  refactor Open-Closed do server ranges; valores wire format mudaram).

Boot esperado: [ZMMOJobsSubsystem] Initialize: 7 job(s) carregados.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 23:53:34 -03:00
a354d9eefc chore(jobs): renomeia display "Aprendiz" -> "Novato"
DA_Job_Novice DisplayName e docs de arquitetura (3 ARQUITETURA*.md)
sincronizados com a nova terminologia PT-BR. Server (Novice.json +
JobsDatabase.cpp) sera commitado separado no repo do ZeusServerEngine.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 21:29:12 -03:00
ca304a99dd Merge pull request 'feat(client): AttributeSystem (Fase 1-3) + ZMMOJobs + UI in-game' (#3) from feat/attribute-system-mmo into main
Reviewed-on: #3
2026-05-23 21:06:47 -03:00
bacf987e0b feat(jobs): novo módulo ZMMOJobs (peer de ZMMOAttributes) + DA_Job_Novice
Sub-módulo cliente do JobsSystem do server. Pavimenta dados visuais/UI por
job (DisplayName localizado, ícone, anim override, som de level up) sem
acoplar ao ZMMOAttributes.

ARQUITETURA — espelha o peer-module pattern do server (PR #9):
  Server: Game/MMO/Modules/JobsSystem (módulo núcleo, LoadOrder=50)
  Client: Source/ZMMOJobs/ (LoadingPhase=PreDefault, peer de ZMMOAttributes)

ZMMOAttributes NÃO depende de ZMMOJobs — server envia classId no snapshot,
cliente faz lookup local via Library/Subsystem.

NOVOS ARQUIVOS

C++ module (Source/ZMMOJobs/):
- module.json + ZMMOJobs.Build.cs (deps: Core/Engine/AssetRegistry)
- ZMMOJobsModule.h/.cpp                 — IMPLEMENT_MODULE
- ZMMOJobDataAsset.h/.cpp               — UPrimaryDataAsset (BlueprintType)
                                          campos: ClassId, TechnicalName,
                                          DisplayName, JobIcon (soft),
                                          DefaultAnimInstanceClass,
                                          JobChangeMontage (soft),
                                          LevelUpSoundCue (soft)
- ZMMOJobsSubsystem.h/.cpp              — UGameInstanceSubsystem
                                          scan AssetRegistry no Initialize +
                                          cache TMap<int32, DA*> por ClassId
                                          O(1) GetJobData(ClassId)
- ZMMOJobsLibrary.h/.cpp                — UBlueprintFunctionLibrary
                                          GetJobDisplayName/GetJobData/IsJobRegistered
                                          fallback "Classe N" se ClassId desconhecido

Content:
- Content/ZMMO/Data/Jobs/DA_Job_Novice.uasset
  (ClassId=0, TechnicalName="Novice", DisplayName="Aprendiz")

MODIFICADOS

- ZMMO.uproject: + Module "ZMMOJobs" (LoadingPhase PreDefault)
- Source/ZMMO/ZMMO.Build.cs: + "ZMMOJobs" em PublicDependencyModuleNames
- Source/ZMMO/Game/UI/FrontEnd/UICharCard_Base.cpp:51 — primeiro consumer
  do Library: "Classe %d" hardcoded → UZMMOJobsLibrary::GetJobDisplayName(this, ClassId)
  Card da seleção de personagem agora mostra "Aprendiz" via DA lookup.

BLUEPRINT ACCESS

Toda a API exposta pra BP via UFUNCTION(BlueprintPure):
- UZMMOJobsLibrary::GetJobDisplayName(Self, ClassId) → FText
- UZMMOJobsLibrary::GetJobData(Self, ClassId) → UZMMOJobDataAsset*
- UZMMOJobsSubsystem::GetJobData(ClassId)
- UZMMOJobDataAsset propriedades BlueprintReadOnly (UMG binding direto)

LOOKUP

AssetRegistry varre /Game/ por UZMMOJobDataAsset no boot do GameInstance.
Chave = campo ClassId do asset (não nome do arquivo — renomear .uasset OK).
Lookup O(1) via TMap. Custo de scan amortizado em 1 vez por sessão (~50ms
pra 50 jobs futuro).

VALIDAÇÃO

Editor:
  [Log] DA class found: <class 'ZMMOJobDataAsset'>
  [Log] Subsystem class found: <class 'ZMMOJobsSubsystem'>
  [Log] Library class found: <class 'ZMMOJobsLibrary'>
  [Log] AssetRegistry encontrou 1 ZMMOJobDataAsset(s):
    - DA_Job_Novice @ /Game/ZMMO/Data/Jobs/DA_Job_Novice

Próximo módulo cliente: 1 linha no .uproject + .Build.cs + ZMMOJobs.Build.cs
não muda. Pattern estabelecido.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 19:19:41 -03:00
dbc2898a4b feat(attributes/ui): toast "LEVEL UP!" no HUD via S_LEVEL_UP delegate
- UZMMOHudWidget ganha LevelUpToastContainer (BindWidgetOptional UWidget)
  e LevelUpToastText (BindWidgetOptional UTextBlock) — both Collapsed por
  default; HandleLevelUp os mostra com text "LEVEL UP!  Lv N" e dispara
  timer FTimerHandle pra esconder após LevelUpToastDurationSec (2.5s).
- WBP_HUD: Border escuro semi-transparente (R=0.05,G=0.04,B=0.10,A=0.85)
  com TextBlock dourado (R=1.0,G=0.85,B=0.30) fonte 32, slot top-center
  com padding top=120, visibility default Collapsed.
- Snapshot pós-level-up (vem logo após S_LEVEL_UP) atualiza HP/SP/level via
  HpSpBar automaticamente — toast é só feedback visual instantâneo.

Polish futuro (não desta frente): SFX cue + particle aura dourada +
animação de fade in/out via UMG.
2026-05-23 12:55:57 -03:00
5418da185e feat(attributes/ui): display "ATK base + bonus" igual RO + ASPD único
- FZMMOAttributesSnapshot ganha 7 pares (AtkBase/AtkEquipBonus, ...) +
  Aspd único, espelhando split do server.
- ZMMOAttributeNetworkHandler::ToSnapshot mapeia campos novos do
  FZeusAttributesPayload.
- WBP_StatusWindow / RefreshFromSnapshot agora formata derivados como
  "ATK  51 + 0", "CRIT 1.3 + 0.0", "ASPD 150" (este sem split — cálculo
  não-linear no server via aspd_base × stats).

Quando InventorySystem entrar, equipar arma muda `currentWeapon` no server,
Recalculate roda, e UI mostra ATK/MATK/DEF/etc com bonus > 0 e ASPD
ajustado pela aspd_base da arma equipada. Sem código de migração — schema
do snapshot já está estabilizado.
2026-05-23 11:47:10 -03:00
f585b0d2b9 feat(attributes/ui): Status Window com alocação STR/AGI/VIT/INT/DEX/LUK + derivados
- ZMMOStatusWindowWidget (UCommonActivatableWidget, modo Menu): grid 2 colunas
  estilo RO. Esquerda: stats primários com botões + por stat (RequestStatAlloc).
  Direita: derivados ATK/MATK/DEF/MDEF/HIT/FLEE/CRIT/ASPD vindos do snapshot
  do server — cliente NUNCA recalcula (anti-cheat foundation).
- Botão + envia C_STAT_ALLOC → server valida cost RO (floor((stat-1)/10)+2),
  aplica + recalcula derivados + SaveCharFull async, manda
  S_ATTRIBUTE_SNAPSHOT_FULL + reply. UI atualiza em tempo real via
  OnAttributesChanged.
- ZMMOAttributeComponent ganha RequestStatAlloc + NotifyStatAllocReply +
  delegate OnStatAllocReply para feedback de rejeição.
- ZMMOAttributeNetworkHandler: HandleStatAllocReply roteia pro componente do
  player local (reply não traz EntityId — sempre quem fez o request).
- PlayerController: hotkey Alt+A (FInputChord legacy + BindKey, sem precisar
  de IA asset). ToggleStatusWindow via UUIInGameFlowSubsystem.
- WBP_StatusWindow: layout 2 colunas via MCP set_widget_tree (43 widgets) +
  BgBorder escuro semi-transparente + centralizado no overlay.
- DA_InGameScreenSet: StatusWindow → WBP_StatusWindow.
2026-05-23 11:22:58 -03:00
396223e2a8 feat(ui-ingame): UI in-game system + PlayerState + Component Registry + HUD composite
Espelho simétrico do front-end pattern (UUIFrontEndFlowSubsystem +
DA_FrontEndScreenSet + UUIPrimaryGameLayout_Base) para a UI in-game.
Pavimenta caminho pra Inventory, Skills, StatusWindow, EscapeMenu, etc.

## UI in-game system (Source/ZMMO/Game/UI/InGame/)

- EZMMOInGameUIState enum (None, Playing, StatusWindow, Inventory,
  SkillTree, EscapeMenu, Loading) em Data/UI/InGameTypes.h
- UUIInGameScreenSet DataAsset: TMap<EZMMOInGameUIState, TSoftClassPtr<...>>
- UUIInGameFlowSubsystem (GameInstanceSubsystem) com SetState/ToggleScreen
- DA_InGameScreenSet em Content/ZMMO/UI/InGame/ mapeia Playing->WBP_HUD
- Layer routing: Playing -> UI.Layer.Game | menus -> GameMenu | loading -> Modal

## AHUD pattern (idiomatic UE5)

- AZMMOHUD : AHUD em Source/ZMMO/Game/Modes/
- AZMMOGameMode::HUDClass = AZMMOHUD::StaticClass()
- AZMMOHUD::BeginPlay chama UIInGameFlowSubsystem::StartInGame
- Pawn não cria mais HUD (separação de responsabilidades)

## PlayerState + Component Registry (Open-Closed)

- AZMMOPlayerState : APlayerState em Source/ZMMO/Game/Modes/
- AZMMOGameMode::PlayerStateClass = AZMMOPlayerState::StaticClass()
- UPROPERTY Config TArray<TSubclassOf<UActorComponent>> ComponentClasses
- DefaultGame.ini: +ComponentClasses=/Script/ZMMOAttributes.ZMMOAttributeComponent
- Ctor lê via GConfig (mais robusto que UPROPERTY Config + parsing) e
  instancia cada componente como CreateDefaultSubobject

Por que componentes no PlayerState e não no Pawn:
- Sobrevive ao despawn (morte/respawn)
- Spectator-friendly
- 1:1 com player (Pawn pode trocar: vehicle, mount, possession)
- Padrão MMO clássico (rathena, TrinityCore)

Adicionar novo módulo (Inventory, Skills, Guild) = 1 linha no
DefaultGame.ini, sem editar AZMMOPlayerState.cpp.

## HUD composite

- UZMMOHudWidget : UCommonActivatableWidget em ZMMO core (UI/InGame/)
- WBP_HUD em Content/ZMMO/UI/HUD/ herda UZMMOHudWidget
- HpSpBar (UZMMOHudHpSpWidget — sub-modulo ZMMOAttributes) embedded via
  BindWidgetOptional. Sub-widgets futuros: PlayerInfo, Minimap, QuickBar,
  Buffs, Chat, TargetInfo
- UZMMOHudHpSpWidget volta a ser UUserWidget puro (sub-widget, não root)
- UZMMOHudWidget::NativeOnActivated:
  - SetVisibility(HitTestInvisible) — mouse passa direto pro Pawn
  - BindToLocalPlayer: busca AttributeComponent no PC->PlayerState
  - Subscreve OnAttributesChanged/OnHpSpChanged/OnLevelUp
  - Propaga snapshots pra sub-widgets via HpSpBar->ApplySnapshot
- GetDesiredInputConfig override: ECommonInputMode::Game (sem cursor,
  movimento livre). Menus override pra GameAndMenu/Menu.

## NetworkHandler refatorado (AttributeComponent agora no PlayerState)

- ZMMOAttributeNetworkHandler::FindComponentForEntity: busca via
  GameState->PlayerArray (O(N_players)), não TActorIterator (O(N_actors))
- ZMMOAttributes.Build.cs += CommonUI, CommonInput

## EnsureRootLayout (fix crítico)

- OpenLevel invalida widgets no viewport ("InvalidateAllWidgets")
- RootLayout (criado pelo FrontEndFlow no boot) sobrevive como UObject
  (LocalPlayerSubsystem) mas fica órfão fora do viewport
- Push do WBP_HUD no Stack_Game funcionava mas widget pai (RootLayout)
  estava fora do viewport → invisível
- UUIFrontEndFlowSubsystem::EnsureRootLayout (público) recria via
  UIManagerSubsystem (idempotente)
- UUIInGameFlowSubsystem::StartInGame chama EnsureRootLayout antes do push

## PlayerCharacter simplificado

- Removido AttributeComponent (vai pro PlayerState via Registry)
- Removido HudHpSpWidgetClass + spawn manual de HUD
- HandleLocalSpawnReady só faz seed do EntityId via PlayerState
- UI lifecycle agora é responsabilidade do AZMMOHUD::BeginPlay

## Verificação (smoke test)

PIE: Login -> CharSelect -> Lobby -> EnterWorld
  ↓
LogZMMO: AZMMOPlayerState ctor: 1 componente(s) no registry
LogZMMO: ZMMOPlayerState: componente registrado [0] ZMMOAttributeComponent
LogZMMO: FrontEndFlow::EnsureRootLayout: RootLayout recriado
LogZMMO: InGameFlow: state None -> Playing
LogZMMO: InGameFlow: tela Playing pushed em UI.Layer.Game (widget=WBP_HUD_C_0)
LogZMMO: ZMMOHudWidget activated (HpSpBar=WBP_HUD_HpSpBar_C_0)
  ↓
HUD aparece com Lv 5 / HP 10/200 / SP 5/20 (valores do DB)
Regen funciona (HP/SP enchem a cada 6s/8s)
Movimento normal (input flui pro Pawn)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 05:27:41 -03:00
7d83dd800f feat(attributes): cliente Fase 1 — sub-modulo ZMMOAttributes + HUD HP/SP
Espelho do AttributeSystem do servidor (Game/MMO/Modules/AttributeSystem).
Sub-modulo C++ Source/ZMMOAttributes/ (Runtime, LoadingPhase=PreDefault)
isolando o cliente do AttributeSystem em pasta propria — pavimentando o
caminho para futuros Inventory/Skills/Combat virem como sub-modulos peer.

Componentes:
  - FZMMOAttributesSnapshot (USTRUCT Blueprint, espelha
    FZeusAttributesPayload do plugin ZeusNetwork)
  - UZMMOAttributeComponent (UActorComponent ligado ao player):
    ApplySnapshot / ApplyHpSpUpdate / NotifyLevelUp + 3 delegates
    dinamicos (OnAttributesChanged / OnHpSpChanged / OnLevelUp) +
    helpers GetHpRatio / GetSpRatio
  - UZMMOAttributeNetworkHandler (UWorldSubsystem): ponte
    UZeusNetworkSubsystem -> componente via lookup por EntityId
  - UZMMOHudHpSpWidget (UUserWidget base): BindWidget (HpBar, SpBar) +
    BindWidgetOptional (HpText, SpText, LevelText). NativeConstruct
    binda nos delegates do componente; NativeDestruct desliga.
    OnSnapshotApplied / OnHpSpDelta (BlueprintNativeEvent) com impl
    C++ atualizando progress bars e textos.

Integracao no PlayerCharacter:
  - CreateDefaultSubobject<UZMMOAttributeComponent> no ctor
  - HudHpSpWidgetClass (TSubclassOf) resolvido via
    ConstructorHelpers::FClassFinder em /Game/ZMMO/UI/HUD/WBP_HUD_HpSpBar
  - HandleLocalSpawnReady seed do EntityId no componente + spawn do HUD
    (CreateWidget + AddToViewport + BindToAttributeComponent)
  - EndPlay remove widget do parent

WBP_HUD_HpSpBar (UMG, criado via MCP):
  - Overlay root + SizeBox (320x120) + VerticalBox
  - 5 widgets BindWidget: LevelText, HpBar (vermelho), HpText,
    SpBar (azul), SpText
  - Herda de UZMMOHudHpSpWidget

Verificacao (smoke test):
  - PIE login -> server envia S_ATTRIBUTE_SNAPSHOT_FULL
  - Cliente recebe via OnAttributeSnapshotFull -> handler roteia pra
    componente do entity -> ApplySnapshot dispara OnAttributesChanged ->
    widget atualiza ProgressBars + TextBlocks
  - HUD aparece no canto inferior esquerdo da tela com valores
    correspondentes ao DB

Refs:
  - Plano: C:/Users/mateu/.claude/plans/temos-uma-lab-input-nested-diffie.md
  - Server companion commit: feat(attributes): AttributeSystem modular

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 04:00:32 -03:00
0e96956a17 feat(char-spawn): Fase 4 client + UI WBPs paralelo (#2)
Co-authored-by: Mateus Rodrigues <mateuus27@outlook.com>
Co-committed-by: Mateus Rodrigues <mateuus27@outlook.com>
2026-05-23 02:16:27 -03:00
2cd8b3b2bb Merge pull request 'feat/frontend-mainmenu-skeleton' (#1) from feat/frontend-mainmenu-skeleton into main
Reviewed-on: #1
2026-05-19 02:06:46 -03:00
3889680469 feat(ui): painel como o Hyper — texturas reais + Panels editável + fixes
- Realoca as 13 texturas de painel do Hyper p/ /Game/ZMMO/UI/CommonUI/Textures/Panels/ (remove as procedurais)
- DT_UI_Styles.PanelBackground com as 9 entradas fiéis ao Hyper Survival_Gold (DrawAs=Image, Margin 0, tint por chave); PanelOutline vazio como no Hyper
- FUIPanelBrushSet (espelha Struct_UI_Style_Panels): só os 2 mapas
- UUIPanel_Base expõe Panels EditAnywhere (Details como no Hyper), semeado do tema; modo-textura só SetBrush (sem padding/visibility inventados)
- Design-time carrega DT_UI_Styles direto (Designer pinta igual ao runtime)
- Fix: outline ausente usa NoDrawType (antes pintava centro branco com FSlateBrush default)
- Remove membro morto Content/UNamedSlot (Hyper não usa NamedSlot)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 02:03:09 -03:00
bc07c47557 feat(frontend): esqueleto CommonUI de MainMenu (boot→login→lobby)
Estrutura principal de front-end estilo Lyra portada para C++ proprio do
ZMMO (sem CommonGame), seguindo o padrao C++ Abstract -> WBP concreto:

- EZMMOFrontEndState / EZMMOLobbyPage e GameplayTags UI.Layer.* nativos
- UUIActivatableScreen_Base: base de tela (input config, hook de tema,
  voltar) espelhando o padrao de UUIButton_Base
- UUIPrimaryGameLayout_Base: switch principal (4 stacks CommonUI/camada)
- UUIManagerSubsystem (LocalPlayer): dono do root layout, idempotente
- UUIFrontEndFlowSubsystem (GameInstance): maquina de estados + driver
  de rede (Boot->Connecting->Login->ServerSelect->Lobby->EnteringWorld
  ->InWorld); Lobby e o hub logado, paginas internas = EZMMOLobbyPage
- UUIFrontEndScreenSet (DataAsset): mapa estado->tela, forge-ready
- AZMMOFrontEndGameMode + AZMMOFrontEndPlayerController
- GameInstance: bAutoConnectOnStart=false (conexao dirigida pelo fluxo)
- Build.cs: +GameplayTags; ARQUITETURA.md PR-first (s2.1/2.2/3.3/4.8/5)
- Assets: L_FrontEnd (GameMode via World Settings), WBP_PrimaryGameLayout,
  DA_FrontEndScreenSet; Config wiring

WBPs de pagina (Boot/Login/...) virao do Zeus UMG Forge depois (s4.8).
Smoke test PIE OK: root layout no viewport, fluxo Boot->Connecting,
no-op+log para telas nao configuradas, sem crash.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 01:56:16 -03:00
ca781eff83 feat(ui): texturas grunge Aurora Arcana + painel texturizado wired (DT+WBP+teste)
4 UTexture2D procedurais (grunge: base escura + value-noise 2 oitavas + vinheta + manchas + moldura arcana) em Content/ZMMO/UI/CommonUI/Textures/Panels (Square/Horizontal/Vertical + Outline_Gold; sRGB, UI, no-mip). DT_UI_Styles linha Default: Style.Panel.PanelBackground/PanelOutline com FSlateBrush (DrawAs Box/9-slice, Margin 0.22) -> ResourceObject resolvido p/ as texturas (verificado via read_data_table). UI_Panel_Master tree = Background(Border)->Outline(Border) (identico ao Hyper, sem NamedSlot). UI_Test_Panel: PanelA/B/Wide com PanelTexture (Square/Horizontal/Vertical_01). Play L_Test_UI mostra paineis texturizados (modo textura usa FUIStyle do subsystem em runtime).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 01:04:30 -03:00
ca117a559e feat(ui): painel texturizado (padrao Hyper) coexistindo com modo cor
EUIPanelTexture (None, Rectangle_Horizontal_01/02/03, Vertical_01..04, Square_01, Vertical_Footer_01) - espelha o enum Panel do Hyper. FUIStylePanel ganha TMap<EUIPanelTexture,FSlateBrush> PanelBackground + PanelOutline (modelo Struct_UI_Style_Panels), mantendo os tokens de cor. UUIPanel_Base: prop PanelTexture + border Outline; RefreshUIStyle tenta modo TEXTURA (Find brush nos mapas -> SetBrush em Background/Outline) e cai no modo COR (RoundedBox) se nao houver brush. Compila OK. Texturas Aurora Arcana proprias serao geradas (nao importadas do Hyper).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:52:10 -03:00
22fc0fbcc6 test(ui): UI_Test_Panel - SizeBox->UI_Panel_Master direto (paineis preenchem a celula)
Border do painel encolhia (NamedSlot vazio + slot Overlay nao-Fill). Agora cada SizeBox tem o UI_Panel_Master como filho unico -> SizeBox forca 360x200 / 740x160 -> Background preenche a celula e mostra o tema. Botoes (Confirmar/Cancelar Danger/Fechar Ghost) em BtnRow separada. Limite MCP: slot Fill / NamedSlot exigem o Designer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:42:24 -03:00
78f2dd4144 test(ui): salva BP_TestUIHUD religado (BeginPlay->Create UI_Test_Panel->AddToViewport)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:39:02 -03:00
1d363caa96 test(ui): UI_Test_Panel mock de conteudo (SizeBox [ ][ ]/[ ]) + HUD repontado
Layout: Row1 = CellA/CellB (SizeBox 380x240, Overlay = UI_Panel_Master + botoes por cima); CellWide (SizeBox 780x180, painel Secondary + 3 botoes). PanelB=Card, PanelWide=Secondary. BP_TestUIHUD religado (BeginPlay->Create(UI_Test_Panel)->AddToViewport via GetOwningPlayerController). Layout e mock grosseiro (limite do MCP p/ slots) - ajuste fino no Designer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:38:44 -03:00
c6b0be92cc feat(ui): WBP UI_Panel_Master (parent UUIPanel_Base) Background->Content(NamedSlot)
Padrao replicado p/ 2a familia: C++ Abstract (UUIPanel_Base) -> WBP concreto. Arvore: Background(Border) -> Content(NamedSlot) via set_widget_tree; binds casam (Background/Content). Compila 0 erros, parent UUIPanel_Base. Designers injetam conteudo no NamedSlot Content; visual data-driven por FUIStyle.Panel/PanelType.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:29:17 -03:00
01c74c7683 feat(ui): UUIPanel_Base (UCommonUserWidget Abstract) data-driven por FUIStyle.Panel
Mesmo padrao do botao: C++ Abstract -> WBP concreto. PanelType (Primary/Secondary/Tertiary/Card) escolhe Bg/BgRaised/BgSunken/CardSelected; bRoundedBackground (RoundedBox + borda do tema); bUseSmallPadding. Background(UBorder) + Content(UNamedSlot) BindWidgetOptional. RefreshUIStyle resolve FUIStyle.Panel via UZMMOThemeSubsystem, reage a OnThemeChanged; BP_ApplyPanelStyle como hook. Compila OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:26:41 -03:00
f77223cfdb test(ui): setup PIE autocontido p/ UI_Test_Buttons (HUD+PC+GameMode+mapa)
BP_TestUIHUD: BeginPlay -> CreateWidget(UI_Test_Buttons, ctx/owner=GetOwningPlayerController) -> AddToViewport. BP_TestPC: bShowMouseCursor + click/mouseover events (p/ Hover/Pressed). GM_BP_TestGM: HUDClass=BP_TestUIHUD, PlayerControllerClass=BP_TestPC. L_Test_UI (Content/ZMMO/Debug/Maps): basic level com GameMode override = GM_BP_TestGM. Abrir L_Test_UI e dar Play exibe os botoes e permite testar estados. PIE confirmou HUD spawnado.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:22:27 -03:00
1ca546c9e9 test(ui): UI_Test_Buttons (variantes/estados/alinhamento) para smoke test
WBP em /Game/ZMMO/UI/Debug com 6 UI_Button_Master: Primary, Secondary, Danger, Ghost (so borda), Disabled (bIsEnabled=false), AlignLeft+Square (TextAlign=Left, bRoundedBackground=false). Compila 0 erros. Use o botao Play do WBP / PIE p/ exercitar Hover/Pressed/Disabled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:12:32 -03:00
69fe754e34 feat(ui): estados Hover/Pressed/Disabled no botao (ApplyVisualState + NativeOn*)
ApplyVisualState(estado) re-resolve o tema e pinta o Background (RoundedBox/Box) com fill+borda do estado: Normal=BgNormal/BorderNormal, Hovered=BgHover/BorderHover, Pressed=BgPressed/BorderHover, Disabled=BgDisabled/BorderNormal. Overrides do UCommonButtonBase: NativeOnHovered/Unhovered/Pressed/Released(volta p/ Hovered se IsHovered senao Normal)/Enabled/Disabled. RefreshUIStyle agora chama ApplyVisualState(Normal). Compila OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:01:18 -03:00
2da2bc7101 feat(ui): UI_Button_Master tree com widget Background (rename de Bg) + CDO
set_widget_tree renomeia o Border Bg->Background (casa o BindWidgetOptional novo); CDO reaplicado (Style=BSB_Button_Transparent_C, ButtonTextValue, bRoundedBackground=true). Compila 0 erros.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:55:07 -03:00
c974efdbc8 feat(ui): Background (rename Bg) com RoundedBox + borda na cor da variante
- Bg -> Background (nome descritivo). - RefreshUIStyle: monta o brush do Background como RoundedBox quando bRoundedBackground (default true): TintColor=BgNormal, OutlineSettings(CornerRadii=Button.CornerRadius, Color=BorderNormal, Width=Button.BorderWidth, RoundingType=FixedRadius). 'So borda com a cor' = variante com BgNormal transparente + BorderNormal na cor (data-driven, como o Hyper). bRoundedBackground=false -> caixa reta. Compila OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:48:35 -03:00
98aaac57aa feat(ui): text style CommonTextStyle por variante + reorg assets CommonUI/Style
- BST_Button (UCommonTextStyle, Rajdhani Bold 15) + BSB_Button_Transparent (UCommonButtonStyle) movidos p/ Content/ZMMO/UI/CommonUI/Style/{Text,Button}/ (espelha Hyper). - UI_Button_Master: arvore CommonTextBlock dentro de TextScaleBox (auto-size) via set_widget_tree; Style->BSB_Button_Transparent_C. - DT_UI_Styles linha Default: Style.Button.<variante>.TextStyle -> BST_Button_C (por variante). - ARQUITETURA.md: prefixos BSB_/BST_ (§3.2) + pasta UI/CommonUI/Style + UI/Shared + UI/Fonts (§2.1). Pipeline conferido via read_data_table (4 variantes apontam BST_Button no path novo, cores Aurora Arcana intactas).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:39:24 -03:00
2064c37bc3 feat(ui): text style via CommonTextStyle por variante (padrao Hyper) + align + auto-size
FUIStyleButtonVariant.Font (FSlateFontInfo) -> TSubclassOf<UCommonTextStyle> TextStyle (idiomatico CommonUI, como BP_Style_Text_* do Hyper; theme-driven via DT_UI_Styles por variante). ButtonText volta a UCommonTextBlock; RefreshUIStyle: SetStyle(variante.TextStyle) + cor do FUIStyle por cima (FUIStyle manda na cor por tema). Mantidos TextAlign (ETextJustify L/C/R via SetJustification + slot do Overlay) e bAutoSizeText (TextScaleBox ScaleToFit/None) — ortogonais ao CommonTextStyle. ButtonTextValue default 'Button Text' agora no header.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:12:14 -03:00
abeec244d5 feat(ui): UI_Button_Master estilizado (FUIStyle gold) + style transparente; remove WBP base redundante
- UMG nao permite WBP-com-arvore herdar de WBP-com-arvore: a base abstrata e SO a classe C++ UUIButton_Base. UI_Button_Master reparentado direto p/ /Script/ZMMO.UIButton_Base; WBP UI_Button_Base (redundante) deletado. - UI_Button_Master: arvore propria (SizeBox_Master/Bg/ContentOverlay/ButtonText/Number_Text/Image_Icon/InputActionWidget) via set_widget_tree; ButtonTextValue='Button Text'. - BS_Button_Transparent (novo CommonButtonStyle: brushes NoDraw + padding 0) atribuido ao Style -> remove o fundo branco padrao do UCommonButtonBase; so o Bg (FUIStyle) aparece. - DT_UI_Styles linha Default: Button agora com cores Aurora Arcana (Primary dourado etc.). - ARQUITETURA.md §3.3 corrigido (regra UMG: C++ abstrato -> WBP concreto, variantes sao WBPs irmaos). Compila 0 erros; visual confirmado (dourado + BUTTON TEXT, sem moldura).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 22:58:10 -03:00
5a8dd796de fix(ui): defaults reais de cor das variantes do botao (Aurora Arcana)
FUIStyleButton ganha construtor que preenche Primary/Secondary/Danger/Ghost com as cores do styles.css (.btn-*). Antes as variantes vinham Transparent/White (placeholder) -> botao saia branco no designer (sem GameInstance usa defaults do struct). Agora ja sai estilizado (Primary=dourado, texto ~#0A0A12) mesmo sem DataTable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 22:42:22 -03:00
f8f00f9b9d feat(ui): UI_Button_Base tree reconstruida via set_widget_tree (casa BindWidget)
Arvore: SizeBox_Master(SizeBox) -> Bg(Border) -> ContentOverlay(Overlay) -> [ButtonText, Number_Text, Image_Icon (TextBlock/TextBlock/Image), InputActionWidget (CommonActionWidget)]. Todos como variaveis -> ligam nos BindWidgetOptional do UUIButton_Base + InputActionWidget do UCommonButtonBase. UI_Button_Base Abstract + parent UUIButton_Base preservados; UI_Button_Master (concreto) herda; ambos compilam UpToDate 0 erros. Montado pela nova tool set_widget_tree do NwiroIntegrationKit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 22:32:30 -03:00
4992a56eff fix(ui): ButtonText usa UTextBlock (CommonTextBlock desnecessario; estilo via FUIStyle)
Como o estilo do botao e dirigido pelo FUIStyle (nao pelo CommonTextStyle), trocar UCommonTextBlock->UTextBlock no BindWidgetOptional simplifica e casa com as tools de WBP. Sem perda de comportamento.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 22:11:31 -03:00
91b080aa68 feat(ui): porte 1:1 do UI_Button_Master (Hyper) para C++ auto-configuravel
UUIButton_Base enriquecido com a logica do UI_Button_Master do Hyper, lida via MCP hyperpro e convertida para C++ (Struct_Style_Button do Hyper substituido pela camada FUIStyle por tema): SetButtonText/SetNumberText/SetIcon/ApplySizeBox/ApplyInputActionStyle/InitializeButton + timeout (delegates OnButtonActivatedByTimeout/OnButtonTimerUpdated). UPROPERTYs editaveis (Button/Text/Number/Icon/Size/InputActionStyle/Timer) auto-aplicados em NativePreConstruct/NativeConstruct. BindWidgetOptional: SizeBox_Master/ButtonText(CommonTextBlock)/Number_Text/Image_Icon/Bg. InputActionWidget acessado por GetWidgetFromName (privado no UCommonButtonBase). Compila+linka OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:58:10 -03:00
4ea5131475 feat(ui): WBP UI_Button_Base (Abstract) + UI_Button_Master
UI_Button_Base: WidgetBlueprint abstrato, parent = UUIButton_Base (C++); arvore RootPanel(Overlay) -> Bg(Border) -> Label(TextBlock), Bg/Label como variaveis (ligam no BindWidgetOptional do C++). UI_Button_Master: child concreto de UI_Button_Base (botao reutilizavel do jogo). Ambos compilam UpToDate, 0 erros. Em /Game/ZMMO/UI/Shared, prefixo UI_ conforme convencao.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:45:40 -03:00
ab74ef8b17 feat(ui): fundacao CommonUI + UUIButton_Base (Abstract)
Habilita CommonUI como base da UI do ZMMO (decisao de arquitetura): modulos CommonUI/CommonInput no Build.cs + include path Game/UI/Widgets; CommonGameViewportClient no DefaultEngine.ini. Adiciona EUIButtonVariant (Primary/Secondary/Danger/Ghost). Cria UUIButton_Base (UCLASS Abstract : UCommonButtonBase): CommonUI cuida de input/foco/click; o C++ resolve os tokens via UZMMOThemeSubsystem::GetActiveUIStyle() e reage a OnThemeChanged; entrega ao WBP por BP_ApplyUIStyle (split contrato C++ / visual Blueprint). CommonInput data/settings deferido p/ a fiacao de input.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:28:45 -03:00
1c06d69174 feat(ui): sistema de UI Style (tokens C++ por tema) + fontes Aurora Arcana
Camada de estilo data-driven do cliente ZMMO, portando o nucleo do projeto de referencia (Hyper) para C++ conforme ARQUITETURA.md (BP Struct proibido):

- Source/ZMMO/Data/UI: UIStyleTypes.h (enums EUI*), UIStyleTokens.h (tokens primitive/semantic/component), UIStyleRow.h (FUIStyle + FUIStyleRow). - ZMMOThemeSubsystem: GetActiveUIStyle() resolve DT_UI_Styles por ThemeId com fallback Default. - Fontes: 8 UFontFace Inline (Cinzel/Rajdhani) em Content/ZMMO/UI/Fonts + DT_UI_Styles preenchido. - ARQUITETURA.md: prefixo de widget UI_, classes base UUI*_Base (UCLASS Abstract) sem prefixo ZMMO. - Config/DefaultGame.ini: UIStyleTable apontando DT_UI_Styles. - Scripts/import_fonts.py (importador idempotente). Inclui tambem o scaffolding do modulo ZMMO ainda nao versionado (Source/ZMMO/Data, Game/UI, Content/ZMMO, uproject, Build.cs).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:21:32 -03:00
50471831a2 chore: remove conteudo template da Epic (Variant_*)
Remove os pacotes de exemplo Variant_Combat, Variant_Platforming e Variant_SideScrolling (mais os External Actors/Objects associados) que vieram do template Third Person e nao fazem parte do cliente ZMMO. Ajusta Config/DefaultEditor.ini de acordo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:21:01 -03:00
1fe5109c0d feat(client): consumir yaw do snapshot quantizado v3 (Etapa 7)
Etapa 7 do refactor de networking server-side bumpou o protocolo para
v3 e passou a enviar yaw no S_PLAYER_STATE (campo novo no payload).
Cliente agora consome esse yaw via TryGetLastPlayerStateExtended do
plugin ZeusNetwork (cache local com YawDeg + Flags).

Antes (v2):
- S_PLAYER_STATE nao tinha yaw. Comentario do codigo dizia exatamente
  "Yaw nao chega no opcode S_PLAYER_STATE actual; derivamos do XY da
  velocidade quando significativo, caso contrario mantemos rotacao
  do ator." Resultado: proxy parado nao girava, e proxy em movimento
  ficava com yaw inferido (impreciso quando vel pequena).

Depois (v3):
- HandlePlayerStateUpdate consulta TryGetLastPlayerStateExtended para
  pegar YawDeg + Flags do cache do plugin (populado pelo parser v3).
- Se PSF_HasYaw esta set, usa o YawDeg autoritativo do servidor.
- Caso contrario, fallback antigo (atan2 da vel ou rotacao do ator),
  preservando comportamento se algum dia o flag vier desligado.

Validacao runtime (~5 min, 2 clients UE conectados ao server v3):
- Connected sessionId=1 e =2 (handshake v3 OK).
- parseRej=0 no servidor (cliente fala v3).
- Proxies giram conforme yaw autoritativo (visual; nao tem metrica
  numerica para isso).

Depende de:
- ZeusNetwork plugin v3 (commit 3b97500 no repo ZeusServerEngine).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 03:32:36 -03:00
86df9478d4 feat(client): snapshot interpolation no proxy remoto para suavizar movimento
Implementa o padrao Source/Quake/Unreal: o proxy nao aplica mais a posicao
recebida diretamente — empurra para um buffer ordenado de snapshots e o Tick
interpola entre os dois snapshots que cercam (server_now - InterpolationDelayMs).

- Novo USTRUCT FZMMOProxySnapshot guardado em TArray ordenado por ServerTimeMs
  (insercao defensiva + dedupe; UDP pode trocar ordem).
- ApplyEntitySnapshot vira "push to buffer"; estabelece o offset de relogio
  na primeira amostra (local_now - server_time). Mudanca de bGrounded
  continua aplicada imediatamente (MovementMode) para o pulo nao herdar o
  delay de interpolacao.
- Tick acha o par (A,B), faz Lerp em pos/vel/yaw; extrapolacao curta
  clampada por MaxExtrapolationSeconds quando faltam snapshots futuros.
- Aceleracao derivada agora vem da curva interpolada (mais estavel que a
  derivada snapshot-a-snapshot anterior). Fallback sintetico de accel para
  o AnimBP do Quinn preservado.
- Removido o line-trace de Z (causava oscilacao apos a interpolacao; a Z
  autoritativa do dono ja vem no snapshot, ADR 0041).
- Separacao explicita AuthoritativePosCm vs InterpolatedPosCm, com
  LastSnapshotPosition mantido como alias para compat de Blueprint.
- Defaults: InterpolationDelayMs=100, SnapshotBufferCapacity=8,
  MaxExtrapolationSeconds=0.1 (UPROPERTY EditAnywhere para tunar em PIE).
- Log Verbose 1x/s com renderLagMs, interpAlpha, flag de extrapolacao.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 23:31:42 -03:00
385ebf6a7b feat(client): proxy animation via custom CMC + injected acceleration
Porta a estratégia do ZClientMMO para o ZMMO: novo
UZMMOProxyMovementComponent expõe escrita externa de Acceleration,
e AZMMOPlayerProxy deriva accel a partir da variação de velocidade
entre snapshots (com smoothing e fallback sintético em locomotion
constante). Tick do proxy roda antes do mesh para alimentar
Velocity+Acceleration antes do NativeUpdateAnimation. Cliente local
agora também envia Vel.Z e bIsFalling para que proxies vejam pulo
completo (subida + queda).
2026-05-08 22:54:54 -03:00
1744383f6f feat(client): cliente autoritativo da pose + proxy visivel (ADR 0040/0041)
ZMMOPlayerCharacter: SendInputAxis agora envia viewYawDeg
(GetController()->GetControlRotation().Yaw, fallback para
GetActorRotation().Yaw) + posicao autoritativa (GetActorLocation)
+ velocidade XY (GetVelocity) — bate com o C_INPUT_AXIS de 41
bytes do servidor (ADR 0041).

ZMMOPlayerProxy:
- MOVE_Walking + RotationRate=0 + bRunPhysicsWithNoController=false
  para o AnimBP do Quinn transitar entre Idle/Run sem o CMC
  integrar fisica.
- Defaults visuais SKM_Quinn_Simple + ABP_Unarmed no construtor
  para o proxy ser visivel em PIE sem precisar de BP filha.
- Line trace local de fallback (ECC_Visibility, 5m down) ajusta Z
  quando o snapshot Z vier estranho. Armadilha conhecida: Landscape
  do UE5 esta em ECC_WorldStatic — quando o trace falhar,
  AdjustedPos.Z fica igual ao snapshot. Fix do canal fica no backlog
  (bug do proxy sumir ao encostar parede).

ZMMO.uproject: indentacao tabs + plugin "meshy" registrado disabled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 18:20:49 -03:00