#pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "ZeusAttributeTypes.h" #include "ZeusAttributeComponent.generated.h" DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FZeusOnAttributesChanged, const FZeusAttributesSnapshot&, Snapshot); DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FZeusOnHpSpChanged, int32, Hp, int32, Sp); DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FZeusOnLevelUp, int32, NewBaseLevel, int32, StatusPointDelta); /// Resposta server ao C_STAT_ALLOC. Reason e' EAllocRejectReason (None=0, /// InvalidStat=1, InvalidAmount=2, NotEnoughPoints=3, StatCapped=4, NoSession=5). DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FZeusOnStatAllocReply, bool, bAccepted, int32, Reason); /** * 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: `UZeusAttributeNetworkHandler` * (UWorldSubsystem) liga em `UZeusNetworkSubsystem::OnAttributeSnapshotFull`, * resolve `EntityId -> AActor*` via `UZeusWorldSubsystem` e chama * `ApplySnapshot` no componente do ator. */ UCLASS(ClassGroup=(Zeus), meta=(BlueprintSpawnableComponent), hidecategories=(Activation, Collision, Cooking, Object, Replication)) class ZEUSATTRIBUTES_API UZeusAttributeComponent : public UActorComponent { GENERATED_BODY() public: UZeusAttributeComponent(); /// Aplica snapshot full recebido do servidor. Substitui `Current` e /// dispara `OnAttributesChanged` + `OnHpSpChanged` (se hp/sp mudaram). UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes") void ApplySnapshot(const FZeusAttributesSnapshot& 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); /// Notifica resposta server ao C_STAT_ALLOC. UI pode reagir (toast/SFX /// quando aceito, erro vermelho quando rejeitado). UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes") void NotifyStatAllocReply(bool bAccepted, int32 Reason); /// Envia C_STAT_ALLOC pro server. Wrapper conveniente — busca o /// UZeusNetworkSubsystem via GameInstance + chama SendStatAlloc. /// `StatId`: 0=STR, 1=AGI, 2=VIT, 3=INT, 4=DEX, 5=LUK. `Amount`: 1..10. UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes") void RequestStatAlloc(int32 StatId, int32 Amount = 1); /// Seed do EntityId vindo de S_SPAWN_PLAYER local. Chamado pelo /// `AZeusCharacter` 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(int64 InEntityId) { Current.EntityId = InEntityId; } UFUNCTION(BlueprintPure, Category = "Zeus|Attributes") const FZeusAttributesSnapshot& GetSnapshot() const { return Current; } UFUNCTION(BlueprintPure, Category = "Zeus|Attributes") float GetHpRatio() const { return Current.MaxHp > 0 ? static_cast(Current.Hp) / static_cast(Current.MaxHp) : 0.f; } UFUNCTION(BlueprintPure, Category = "Zeus|Attributes") float GetSpRatio() const { return Current.MaxSp > 0 ? static_cast(Current.Sp) / static_cast(Current.MaxSp) : 0.f; } // === Delegates Blueprint === /** Snapshot novo aplicado. Use isto na UI para refresh geral. */ UPROPERTY(BlueprintAssignable, Category = "Zeus|Attributes") FZeusOnAttributesChanged OnAttributesChanged; /** HP ou SP mudou (efêmero ou via snapshot). Para barras animadas. */ UPROPERTY(BlueprintAssignable, Category = "Zeus|Attributes") FZeusOnHpSpChanged OnHpSpChanged; /** Subiu de nível. Para efeitos visuais ("LEVEL UP!" toast). */ UPROPERTY(BlueprintAssignable, Category = "Zeus|Attributes") FZeusOnLevelUp OnLevelUp; /** Resposta ao C_STAT_ALLOC (aceito ou rejeitado). UI reage. */ UPROPERTY(BlueprintAssignable, Category = "Zeus|Attributes") FZeusOnStatAllocReply OnStatAllocReply; protected: UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes") FZeusAttributesSnapshot Current; };