Files
ZMMO/Source/ZMMO/Game/UI/InGame/ZeusHudWidget.h
Mateus Rodrigues 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

141 lines
5.9 KiB
C++

#pragma once
#include "CommonActivatableWidget.h"
#include "CoreMinimal.h"
#include "Engine/TimerHandle.h"
#include "ZeusAttributesSnapshot.h"
#include "ZeusHudWidget.generated.h"
class UTextBlock;
class UWidget;
class UZeusGASComponent;
class UZeusHudHpSpWidget;
class UZeusHudPlayerVitalsWidget;
struct FZeusAttributesPayload;
/**
* Root da HUD de gameplay. UCommonActivatableWidget pushed pelo
* UUIInGameFlowSubsystem em UI.Layer.Game quando o estado vira `Playing`.
*
* **Vive em ZMMO core** (UI/InGame/) porque o HUD root e' generico pra
* qualquer GameType — sub-widgets vem dos modulos especializados
* (HpSpBar local do ZMMO, Minimap de ZeusMap futuro,
* Chat de ZeusChat futuro, etc.).
*
* Padrao **composite**: o WBP_HUD (filho) declara as PECAS visuais como
* sub-widgets BindWidgetOptional, e este C++ orquestra:
* 1. Em NativeOnActivated: auto-binda no UZeusAttributeComponent do
* player local (vive no PlayerState via Component Registry)
* 2. Subscreve aos delegates do componente (OnAttributesChanged,
* OnHpSpChanged, OnLevelUp)
* 3. Propaga os deltas pros sub-widgets via metodos publicos
* (HpSpBar->ApplySnapshot, HpSpBar->ApplyHpSp, etc.)
*
* Composicao prevista (sub-widgets — todos `BindWidgetOptional` pra
* permitir GameTypes sem modulos opcionais — ex.: Survival sem stats RO):
* - HpSpBar (UZeusHudHpSpWidget — local UI/InGame/) — impl
* - PlayerInfo (futuro — nome/job/level/exp bar)
* - Minimap (futuro)
* - QuickBar (futuro — hotkeys de skills)
* - Buffs (futuro — icones SC ativos)
* - Chat (futuro)
* - TargetInfo (futuro — HP/SP/nome do mob/player targetado)
*
* Adicionar novo sub-widget = adicionar campo BindWidgetOptional aqui +
* setup no NativeOnActivated/handlers + adicionar no WBP_HUD.
*
* Pra mudar o LAYOUT visual ou skin do HUD: edita o WBP_HUD (filho)
* no Designer — sem tocar este C++.
*/
UCLASS(Abstract, Blueprintable, BlueprintType)
class ZMMO_API UZeusHudWidget : public UCommonActivatableWidget
{
GENERATED_BODY()
public:
UZeusHudWidget(const FObjectInitializer& ObjectInitializer);
protected:
virtual void NativeOnActivated() override;
virtual void NativeOnDeactivated() override;
virtual void NativeDestruct() override;
/**
* HUD passa input direto pro Pawn — sem capturar mouse/teclado. Override
* retorna `TOptional<FUIInputConfig>(unset)`. Sem isso, UCommonActivatableWidget
* default usa Menu config (`SetInputMode_GameAndUI` + mouse cursor), o que
* desativa input de gameplay.
*
* Menus (StatusWindow, Inventory, etc.) override e' diferente — eles
* retornam GameAndMenu/Menu pra mostrar cursor + bloquear movement.
*/
virtual TOptional<FUIInputConfig> GetDesiredInputConfig() const override;
/// Sub-widget HP/SP/level (local UI/InGame/). BindWidgetOptional
/// — WBP_HUD pode omitir se o GameType nao usa Attributes (Survival, etc.).
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|HUD")
UZeusHudHpSpWidget* HpSpBar = nullptr;
/// Painel de vitais novo (portrait + nome/job/level + HP/SP/EXP/JOB bars).
/// Substitui o HpSpBar legado. BindWidgetOptional — coexiste durante a
/// migração; o WBP_HUD pode ter um ou outro.
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|HUD")
UZeusHudPlayerVitalsWidget* PlayerVitals = nullptr;
/// Container do toast "LEVEL UP!" (Fase 3). Hidden por default; em
/// `HandleLevelUp` vira visivel por `LevelUpToastDurationSec` segundos
/// (ver `Show/HideLevelUpToast`). WBP_HUD coloca um Border + Image + TextBlock
/// dentro deste container; este C++ controla apenas o lifecycle visivel/hidden.
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|HUD|LevelUp")
UWidget* LevelUpToastContainer = nullptr;
/// Texto exibido no toast — formato "LEVEL UP! Lv X" (X = novo level).
/// Tambem BindWidgetOptional; WBP_HUD pode usar texto estatico no design.
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|HUD|LevelUp")
UTextBlock* LevelUpToastText = nullptr;
/// Duracao do toast em segundos. Configuravel no BP filho.
UPROPERTY(EditDefaultsOnly, Category = "Zeus|HUD|LevelUp")
float LevelUpToastDurationSec = 2.5f;
// === Futuros sub-widgets ===
// UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZeusHudPlayerInfoWidget* PlayerInfo = nullptr;
// UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZeusHudMinimapWidget* Minimap = nullptr;
// UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZeusHudQuickBarWidget* QuickBar = nullptr;
// UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZeusHudBuffsWidget* Buffs = nullptr;
// UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZeusHudChatWidget* Chat = nullptr;
// UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZeusHudTargetInfoWidget* TargetInfo = nullptr;
UFUNCTION(BlueprintPure, Category = "Zeus|HUD")
UZeusGASComponent* GetBoundComponent() const { return BoundComponent.Get(); }
private:
/// Tenta achar o UZeusGASComponent do player local + subscrever nos
/// delegates. Idempotente.
void BindToLocalPlayer();
void UnbindFromComponent();
/// Listener C++ no payload bruto do UZeusGASComponent (nao e' UFUNCTION
/// porque FZeusAttributesPayload nao e' BlueprintType — delegate multicast
/// nativo).
void HandleSnapshotRaw(const FZeusAttributesPayload& Payload);
UFUNCTION()
void HandleHpSpUpdated(float Hp, float Sp);
UFUNCTION()
void HandleLevelUp(int32 NewBaseLevel, int32 StatusPointDelta);
UPROPERTY(Transient)
TWeakObjectPtr<UZeusGASComponent> BoundComponent;
/// Handle do listener nao-dynamic em OnSnapshotAppliedRaw — guardar pra remover
/// em UnbindFromComponent (AddUObject nao auto-cleanup como AddDynamic).
FDelegateHandle SnapshotRawHandle;
void ShowLevelUpToast(int32 NewBaseLevel);
void HideLevelUpToast();
FTimerHandle LevelUpToastHideTimer;
};