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>
- 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.