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>
87 lines
3.4 KiB
C++
87 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Components/ActorComponent.h"
|
|
#include "ZMMOAttributeTypes.h"
|
|
#include "ZMMOAttributeComponent.generated.h"
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FZMMOOnAttributesChanged, const FZMMOAttributesSnapshot&, Snapshot);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FZMMOOnHpSpChanged, int32, Hp, int32, Sp);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FZMMOOnLevelUp, int32, NewBaseLevel, int32, StatusPointDelta);
|
|
|
|
/**
|
|
* Componente de atributos do MMO ligado ao ator que o representa em-jogo
|
|
* (player local, proxies remotos, NPCs futuros).
|
|
*
|
|
* Estado authoritative vive no servidor (CharRuntimeStatus em
|
|
* Game/MMO/Modules/AttributeSystem). Cliente apenas armazena o ultimo
|
|
* snapshot recebido e expoe delegates para UI/HUD reagir.
|
|
*
|
|
* Roteamento server → componente: `UZMMOAttributeNetworkHandler`
|
|
* (UWorldSubsystem) liga em `UZeusNetworkSubsystem::OnAttributeSnapshotFull`,
|
|
* resolve `EntityId -> AActor*` via `UZMMOWorldSubsystem` e chama
|
|
* `ApplySnapshot` no componente do ator.
|
|
*/
|
|
UCLASS(ClassGroup=(ZMMO), meta=(BlueprintSpawnableComponent),
|
|
hidecategories=(Activation, Collision, Cooking, Object, Replication))
|
|
class ZMMOATTRIBUTES_API UZMMOAttributeComponent : public UActorComponent
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UZMMOAttributeComponent();
|
|
|
|
/// Aplica snapshot full recebido do servidor. Substitui `Current` e
|
|
/// dispara `OnAttributesChanged` + `OnHpSpChanged` (se hp/sp mudaram).
|
|
UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes")
|
|
void ApplySnapshot(const FZMMOAttributesSnapshot& InSnapshot);
|
|
|
|
/// Aplica apenas delta de HP/SP (sem mexer em outros campos).
|
|
UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes")
|
|
void ApplyHpSpUpdate(int32 NewHp, int32 NewSp);
|
|
|
|
/// Notifica level up — o snapshot subsequente atualiza demais campos.
|
|
UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes")
|
|
void NotifyLevelUp(int32 NewBaseLevel, int32 StatusPointDelta);
|
|
|
|
/// Seed do EntityId vindo de S_SPAWN_PLAYER local. Chamado pelo
|
|
/// `AZMMOPlayerCharacter` antes do primeiro S_ATTRIBUTE_SNAPSHOT_FULL
|
|
/// chegar, garantindo que o NetworkHandler consiga rotear via lookup
|
|
/// por EntityId desde o inicio.
|
|
UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes")
|
|
void SeedEntityId(int32 InEntityId) { Current.EntityId = InEntityId; }
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Zeus|Attributes")
|
|
const FZMMOAttributesSnapshot& GetSnapshot() const { return Current; }
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Zeus|Attributes")
|
|
float GetHpRatio() const
|
|
{
|
|
return Current.MaxHp > 0 ? static_cast<float>(Current.Hp) / static_cast<float>(Current.MaxHp) : 0.f;
|
|
}
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Zeus|Attributes")
|
|
float GetSpRatio() const
|
|
{
|
|
return Current.MaxSp > 0 ? static_cast<float>(Current.Sp) / static_cast<float>(Current.MaxSp) : 0.f;
|
|
}
|
|
|
|
// === Delegates Blueprint ===
|
|
|
|
/** Snapshot novo aplicado. Use isto na UI para refresh geral. */
|
|
UPROPERTY(BlueprintAssignable, Category = "Zeus|Attributes")
|
|
FZMMOOnAttributesChanged OnAttributesChanged;
|
|
|
|
/** HP ou SP mudou (efêmero ou via snapshot). Para barras animadas. */
|
|
UPROPERTY(BlueprintAssignable, Category = "Zeus|Attributes")
|
|
FZMMOOnHpSpChanged OnHpSpChanged;
|
|
|
|
/** Subiu de nível. Para efeitos visuais ("LEVEL UP!" toast). */
|
|
UPROPERTY(BlueprintAssignable, Category = "Zeus|Attributes")
|
|
FZMMOOnLevelUp OnLevelUp;
|
|
|
|
protected:
|
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes")
|
|
FZMMOAttributesSnapshot Current;
|
|
};
|