#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(int64 EntityId, int32 Hp, int32 Sp); void HandleLevelUp(int64 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; };