#pragma once #include "GameFramework/GameMode.h" #include "GasaCommon.h" #include "Networking/GasaNetLibrary_Inlines.h" #include "Engine/Engine.h" #include "GasaGameMode.generated.h" DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnLogoutSig, AGasaPlayerController*, PC); UCLASS( Blueprintable ) class GASA_API AGasaGameMode : public AGameMode { GENERATED_BODY() public: UPROPERTY(EditAnywhere, BlueprintAssignable) FOnLogoutSig Event_OnLogout; #pragma region GameFramework UFUNCTION() void OnGameFrameworkInitialized(); UFUNCTION() void OwningClient_OnGameFrameworkInitialized(AGasaPlayerController* PC); UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "On Game Framework Initialized")) void BP_OnGameFrameworkInitialized(); #pragma endregion GameFramework #pragma region NetSlime // NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); } FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); } FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); } FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); } FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); } FORCEINLINE void NetLog( FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log, FLogCategoryBase& Category = LogGasaNet, bool DumpStack = false, int32 Line = __builtin_LINE(), ANSICHAR const* File = __builtin_FILE(), ANSICHAR const* Func = __builtin_FUNCTION() ) { Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func ); } #pragma endregion NetSlime #pragma region GameMode void HandleMatchAborted() override; void HandleStartingNewPlayer_Implementation(APlayerController* NewPlayer) override; bool ReadyToStartMatch_Implementation() override; #pragma endregion GameMode #pragma region GameModeBase void EndPlay(const EEndPlayReason::Type EndPlayReason) override; void FinishRestartPlayer(AController* NewPlayer, const FRotator& StartRotation) override; void GenericPlayerInitialization(AController* C) override; TSubclassOf GetPlayerControllerClassToSpawnForSeamlessTravel(APlayerController* PreviousPlayerController) override; void HandleSeamlessTravelPlayer(AController*& C) override; void InitializeHUDForPlayer_Implementation(APlayerController* NewPlayer) override; void InitSeamlessTravelPlayer(AController* NewController) override; void Logout(AController* Exiting) override; void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage) override; void PostLogin(APlayerController* NewPlayer) override; void PostSeamlessTravel() override; void SetPlayerDefaults(APawn* PlayerPawn) override; void SetSeamlessTravelViewTarget(APlayerController* PC) override; void StartPlay() override; void StartToLeaveMap() override; void SwapPlayerControllers(APlayerController* OldPC, APlayerController* NewPC) override; APlayerController* SpawnPlayerControllerCommon(ENetRole InRemoteRole, FVector const& SpawnLocation, FRotator const& SpawnRotation, TSubclassOf InPlayerControllerClass) override; #pragma endregion GameModeBase }; namespace Gasa { inline AGasaGameMode* GetGameMode( UObject* Context ) { UWorld* World = GEngine->GetWorldFromContextObject( Context, EGetWorldErrorMode::LogAndReturnNull ); if ( World == nullptr ) { Log( "World is null... are you running in a proper context?", ELogV::Error ); return nullptr; } return Cast( World->GetAuthGameMode() ); } }