- 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.
52 lines
1.8 KiB
C++
52 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Subsystems/WorldSubsystem.h"
|
|
#include "ZeusAttributesPayload.h"
|
|
#include "ZMMOAttributeNetworkHandler.generated.h"
|
|
|
|
class UZeusNetworkSubsystem;
|
|
|
|
/**
|
|
* Ponte entre o `UZeusNetworkSubsystem` (GameInstanceSubsystem do plugin
|
|
* ZeusNetwork) e os `UZMMOAttributeComponent` ligados aos atores do mundo.
|
|
*
|
|
* Por que UWorldSubsystem (e nao GameInstanceSubsystem)?
|
|
* - O registry de atores (`UZMMOWorldSubsystem::GetActorByEntityId`) e'
|
|
* World-scoped, reset a cada OpenLevel.
|
|
* - World subsystem so existe enquanto ha mundo carregado, o que e' exato
|
|
* quando precisamos rotear snapshots (no front-end nao ha pawn).
|
|
*
|
|
* Lifecycle: `Initialize` binda nos 3 delegates do ZeusNetworkSubsystem;
|
|
* `Deinitialize` unbinda. Conversao `FZeusAttributesPayload ->
|
|
* FZMMOAttributesSnapshot` (USTRUCT Blueprint) acontece aqui.
|
|
*/
|
|
UCLASS()
|
|
class ZMMOATTRIBUTES_API UZMMOAttributeNetworkHandler : public UWorldSubsystem
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
|
virtual void Deinitialize() override;
|
|
|
|
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
|
|
|
|
private:
|
|
void HandleAttributeSnapshotFull(const FZeusAttributesPayload& Payload);
|
|
void HandleHpSpUpdate(int32 EntityId, int32 Hp, int32 Sp);
|
|
void HandleLevelUp(int32 EntityId, int32 NewBaseLevel, int32 StatusPointDelta);
|
|
void HandleStatAllocReply(bool bAccepted, int32 Reason);
|
|
|
|
UZeusNetworkSubsystem* GetZeusNetSubsystem() const;
|
|
|
|
/// Acha o AttributeComponent do player local (Pawn->PlayerState).
|
|
/// Usado pro StatAllocReply (sem EntityId no payload).
|
|
class UZMMOAttributeComponent* FindLocalPlayerAttributeComponent() const;
|
|
|
|
FDelegateHandle SnapshotFullHandle;
|
|
FDelegateHandle HpSpUpdateHandle;
|
|
FDelegateHandle LevelUpHandle;
|
|
FDelegateHandle StatAllocReplyHandle;
|
|
};
|