- 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.
107 lines
5.5 KiB
C++
107 lines
5.5 KiB
C++
#pragma once
|
|
|
|
#include "CommonActivatableWidget.h"
|
|
#include "CoreMinimal.h"
|
|
#include "ZMMOAttributeTypes.h"
|
|
#include "ZMMOStatusWindowWidget.generated.h"
|
|
|
|
class UButton;
|
|
class UTextBlock;
|
|
class UCommonButtonBase;
|
|
class UZMMOAttributeComponent;
|
|
|
|
/**
|
|
* Tela "Status" — atributos do jogador + alocacao via botões `+`.
|
|
*
|
|
* Modo Menu: cursor visível, movimento bloqueado, Esc fecha. Push em
|
|
* UI.Layer.GameMenu pelo `UUIInGameFlowSubsystem::ToggleScreen(StatusWindow)`.
|
|
* HUD continua visível em UI.Layer.Game por baixo.
|
|
*
|
|
* Composicao do WBP_StatusWindow (BindWidgetOptional pra permitir variantes):
|
|
* - Labels de stats primarios: StrText / AgiText / VitText / IntText / DexText / LukText
|
|
* - Botões +: PlusBtn_Str / PlusBtn_Agi / PlusBtn_Vit / PlusBtn_Int / PlusBtn_Dex / PlusBtn_Luk
|
|
* - Derivados (server-authoritative): AtkText / MatkText / DefText / MdefText /
|
|
* HitText / FleeText / CritText / AspdText
|
|
* - StatusPointText (pontos disponíveis pra alocar)
|
|
* - CloseBtn (fecha — fallback do Esc/back handler)
|
|
*
|
|
* Workflow:
|
|
* 1. NativeOnActivated: busca AttributeComponent (PlayerState do player local)
|
|
* 2. Subscreve OnAttributesChanged + OnStatAllocReply
|
|
* 3. Refresh inicial via snapshot atual
|
|
* 4. Clique no `+X` chama `Comp->RequestStatAlloc(X, 1)` → server valida
|
|
* 5. Server responde com S_ATTRIBUTE_STAT_ALLOC_OK + (se ok) snapshot novo
|
|
* 6. UI atualiza via delegate
|
|
*/
|
|
UCLASS(Abstract, Blueprintable, BlueprintType)
|
|
class ZMMO_API UZMMOStatusWindowWidget : public UCommonActivatableWidget
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UZMMOStatusWindowWidget(const FObjectInitializer& ObjectInitializer);
|
|
|
|
protected:
|
|
virtual void NativeOnActivated() override;
|
|
virtual void NativeOnDeactivated() override;
|
|
|
|
/// Modo Menu: cursor visível + bloqueia input de gameplay (movimento).
|
|
virtual TOptional<FUIInputConfig> GetDesiredInputConfig() const override;
|
|
|
|
/// Texto dos stats (label + valor). BindWidgetOptional pra permitir
|
|
/// WBPs custom (ex.: sem display de SP em variantes).
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* StrText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* AgiText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* VitText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* IntText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* DexText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* LukText = nullptr;
|
|
|
|
/// Pontos restantes pra alocar + label "Status Points: N".
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* StatusPointText = nullptr;
|
|
|
|
/// Derivados (sempre calculados pelo servidor — cliente NUNCA recalcula).
|
|
/// Mostra `base + bonus` quando aplicavel (camadas equip/buff vem do server
|
|
/// pre-somadas no snapshot). BindWidgetOptional pra suportar HUDs minimalistas.
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* AtkText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* MatkText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* DefText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* MdefText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* HitText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* FleeText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* CritText = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* AspdText = nullptr;
|
|
|
|
/// Botoes + por stat.
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Str = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Agi = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Vit = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Int = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Dex = nullptr;
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Luk = nullptr;
|
|
|
|
/// Botao Close (fallback do Esc/back).
|
|
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* CloseBtn = nullptr;
|
|
|
|
private:
|
|
void BindToLocalPlayer();
|
|
void UnbindFromComponent();
|
|
void RefreshFromSnapshot(const FZMMOAttributesSnapshot& Snap);
|
|
|
|
UFUNCTION() void HandleAttributesChanged(const FZMMOAttributesSnapshot& Snapshot);
|
|
UFUNCTION() void HandleStatAllocReply(bool bAccepted, int32 Reason);
|
|
|
|
UFUNCTION() void OnPlusStr();
|
|
UFUNCTION() void OnPlusAgi();
|
|
UFUNCTION() void OnPlusVit();
|
|
UFUNCTION() void OnPlusInt();
|
|
UFUNCTION() void OnPlusDex();
|
|
UFUNCTION() void OnPlusLuk();
|
|
UFUNCTION() void OnCloseClicked();
|
|
|
|
void RequestAlloc(int32 StatId);
|
|
|
|
UPROPERTY(Transient)
|
|
TWeakObjectPtr<UZMMOAttributeComponent> BoundComponent;
|
|
};
|