#pragma once #include "CoreMinimal.h" #include "Subsystems/WorldSubsystem.h" #include "ZeusJobChangeNetworkHandler.generated.h" class UZeusNetworkSubsystem; /** * Multicast dinamico assignable em Blueprint. WBP de promocao binda no * OnJobChangeResult pra reagir ao S_JOB_CHANGE_RESULT (1520) do server. * * Parametros: * - bAccepted : true = promocao aplicada (S_ATTRIBUTE_SNAPSHOT_FULL * chega logo apos com state novo). * - Reason : EJobChangeRejectReason (None/NoSession/UnknownJob/ * NotParent/WrongTier/JobLevelTooLow/AlreadyAtTarget/ * JobsDbUnavailable). Significativo apenas se !bAccepted. * - NewClassId : significativo apenas se bAccepted=true (redundante com * snapshot que vem junto, mas util pra triggers/toasts). */ DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FZeusOnJobChangeResultBP, bool, bAccepted, int32, Reason, int32, NewClassId); /** * Bridge entre o `UZeusNetworkSubsystem` (do plugin ZeusNetwork) e a UI * Blueprint (WBP de promocao). Mesmo pattern do `UZeusAttributeNetworkHandler` * — converte o delegate C++-only `FZeusOnJobChangeResult` num dynamic * multicast (`FZeusOnJobChangeResultBP`) assignavel em BP. * * Por que UWorldSubsystem? Player so' faz promocao quando ja' esta no * WorldServer (com mundo carregado). No front-end / lobby, esse subsystem * nao existe — economiza memoria. */ UCLASS() class ZEUSJOBS_API UZeusJobChangeNetworkHandler : public UWorldSubsystem { GENERATED_BODY() public: virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; virtual bool ShouldCreateSubsystem(UObject* Outer) const override; /// Assignavel em BP: WBP_JobChangePanel.OnEvent_OnJobChangeResult. UPROPERTY(BlueprintAssignable, Category = "Zeus|Jobs") FZeusOnJobChangeResultBP OnJobChangeResult; private: void HandleJobChangeResult(bool bAccepted, int32 Reason, int32 NewClassId); UZeusNetworkSubsystem* GetZeusNetSubsystem() const; FDelegateHandle JobChangeResultHandle; };