'NetSlime' Initial port finished and working with 2 players (at least)
This commit is contained in:
		| @@ -7,29 +7,34 @@ using namespace Gasa; | ||||
| #pragma region GameFramework | ||||
| // TODO(Ed): Make a NetLog | ||||
|  | ||||
| UGasaGameInstance::UGasaGameInstance() | ||||
| { | ||||
| 	GameFrameworkState = EGameFrameworkState::Uninitialized; | ||||
| } | ||||
|  | ||||
| void UGasaGameInstance::NotifyGameFrameworkClassReady(EGameFrameworkClassFlag ClassReady) | ||||
| { | ||||
| 	switch (ClassReady) | ||||
| 	{ | ||||
| 		case EGameFrameworkClassFlag::GameMode: | ||||
| 			GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::GameMode; | ||||
| 			NetLog("Gameplay Framework class ready: Game State", ELogV::Log, LogGasaNet ); | ||||
| 			NetLog("Game Framework class ready: Game State", ELogV::Log, LogGasaNet ); | ||||
| 		break; | ||||
| 		case EGameFrameworkClassFlag::GameState: | ||||
| 			GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::GameState; | ||||
| 			NetLog("Gameplay Framework class ready: Game State", ELogV::Log, LogGasaNet ); | ||||
| 			NetLog("Game Framework class ready: Game State", ELogV::Log, LogGasaNet ); | ||||
| 		break; | ||||
| 		case EGameFrameworkClassFlag::PlayerController: | ||||
| 			GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::PlayerController; | ||||
| 			NetLog("Gameplay Framework class ready: Player Controller", ELogV::Log, LogGasaNet); | ||||
| 			NetLog("Game Framework class ready: Player Controller", ELogV::Log, LogGasaNet); | ||||
| 		break; | ||||
| 		case EGameFrameworkClassFlag::PlayerState: | ||||
| 			GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::PlayerState; | ||||
| 			NetLog("Gameplay Framework class ready: Player State", ELogV::Log, LogGasaNet); | ||||
| 			NetLog("Game Framework class ready: Player State", ELogV::Log, LogGasaNet); | ||||
| 		break; | ||||
| 		case EGameFrameworkClassFlag::Levels: | ||||
| 			GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::Levels; | ||||
| 			NetLog("Gameplay Framework class ready: Levels", ELogV::Log, LogGasaNet); | ||||
| 			NetLog("Game Framework class ready: Levels", ELogV::Log, LogGasaNet); | ||||
| 		break; | ||||
| 	} | ||||
| 	ProcessGameFrameworkState(); | ||||
| @@ -68,7 +73,7 @@ void UGasaGameInstance::ProcessGameFrameworkState() | ||||
| 			if (GameFrameworkClassesState == InitializedFlags) | ||||
| 			{ | ||||
| 				GameFrameworkState = EGameFrameworkState::Initialized; | ||||
| 				NetLog("Gameplay Framework initialized"); | ||||
| 				NetLog("Game Framework initialized"); | ||||
| 				 | ||||
| 				Event_OnGameFrameworkInitialized.Broadcast(); | ||||
| 			} | ||||
| @@ -84,8 +89,5 @@ void UGasaGameInstance::Init() | ||||
| 	Super::Init(); | ||||
|  | ||||
| 	DevOptionsCache.CachedDevOptions(); | ||||
|  | ||||
| 	using namespace Gasa; | ||||
| 	NetLog(FString::Printf(TEXT("UObject Size:  %d RT: %d"), sizeof(UObject), UObject::StaticClass()->PropertiesSize )); | ||||
| } | ||||
| #pragma region GameInstance | ||||
| #pragma endregion GameInstance | ||||
|   | ||||
| @@ -21,8 +21,8 @@ enum class EGameFrameworkClassFlag : uint8 | ||||
| UENUM(BlueprintType) | ||||
| enum class EGameFrameworkState : uint8 | ||||
| { | ||||
| 	Initialized, | ||||
| 	Uninitialized | ||||
| 	Uninitialized, | ||||
| 	Initialized | ||||
| }; | ||||
|  | ||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnGameFrameworkInitializedSig); | ||||
| @@ -33,6 +33,8 @@ class GASA_API UGasaGameInstance : public UGameInstance | ||||
| 	GENERATED_BODY() | ||||
| public: | ||||
|  | ||||
| 	UGasaGameInstance(); | ||||
|  | ||||
| 	UPROPERTY(VisibleAnywhere, Category="Dev Cache") | ||||
| 	FGasaDevOptionsCache DevOptionsCache; | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| #include "GasaGameMode.h" | ||||
|  | ||||
| #include "Online/CoreOnline.h" | ||||
| #include "GasaGameInstance.h" | ||||
| #include "GasaGameState.h" | ||||
| #include "GasaPlayerController.h" | ||||
| #include "GasaPlayerState.h" | ||||
| #include "Engine/Player.h" | ||||
| #include "GameFramework/GameSession.h" | ||||
| #include "GameFramework/GameState.h" | ||||
| @@ -71,6 +71,33 @@ void AGasaGameMode::EndPlay(const EEndPlayReason::Type EndPlayReason) | ||||
| 	NetLog("EndPlay"); | ||||
| } | ||||
|  | ||||
| void AGasaGameMode::FinishRestartPlayer(AController* NewPlayer, const FRotator& StartRotation) | ||||
| { | ||||
| 	// Super::FinishRestartPlayer(NewPlayer, StartRotation); | ||||
| 	{ | ||||
| 		NewPlayer->Possess(NewPlayer->GetPawn()); | ||||
|  | ||||
| 		// If the Pawn is destroyed as part of possession we have to abort | ||||
| 		if (!IsValid(NewPlayer->GetPawn())) | ||||
| 		{ | ||||
| 			FailedToRestartPlayer(NewPlayer); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Set initial control rotation to starting rotation rotation | ||||
| 			NewPlayer->ClientSetRotation(NewPlayer->GetPawn()->GetActorRotation(), true); | ||||
|  | ||||
| 			FRotator NewControllerRot = StartRotation; | ||||
| 			NewControllerRot.Roll = 0.f; | ||||
| 			NewPlayer->SetControlRotation(NewControllerRot); | ||||
|  | ||||
| 			SetPlayerDefaults(NewPlayer->GetPawn()); | ||||
|  | ||||
| 			K2_OnRestartPlayer(NewPlayer); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaGameMode::GenericPlayerInitialization(AController* C) | ||||
| { | ||||
| 	NetLog("GenericPlayerInitialization: " + C->GetName()); | ||||
| @@ -360,10 +387,10 @@ void AGasaGameMode::PostLogin(APlayerController* NewPlayer) | ||||
| 	{ | ||||
| 		UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>(); | ||||
| 		 | ||||
| 		// int32 numconnections = gi->sessionsettings.bpublicgame | ||||
| 			// ? GI->SessionSettings.PublicConnections : GI->SessionSettings.PrivateConnections; | ||||
|  | ||||
| #if 0 | ||||
| 		int32 numconnections = GI->sessionsettings.bPublicGame | ||||
| 			? GI->SessionSettings.PublicConnections : GI->SessionSettings.PrivateConnections; | ||||
| 		 | ||||
| 		if (GS->OnlinePlayers.Num() < NumConnections) | ||||
| 		{ | ||||
| 			GS->OnlinePlayers.Init( nullptr, NumConnections ); | ||||
| @@ -388,8 +415,8 @@ void AGasaGameMode::PostLogin(APlayerController* NewPlayer) | ||||
| 	} | ||||
|  | ||||
| 	AGasaPlayerController* PC = Cast<AGasaPlayerController>(NewPlayer); | ||||
| 	// if (PC) | ||||
| 	// 	PC->Event_OnNetOwner_GameplayFrameworkInitialized.AddDynamic(this, &ThisClass::OwningClient_OnGameFrameworkInitialized); | ||||
| 	if (PC) | ||||
| 		PC->Event_NetOwner_OnGameFrameworkInitialized.AddDynamic(this, &ThisClass::OwningClient_OnGameFrameworkInitialized); | ||||
| } | ||||
|  | ||||
| void AGasaGameMode::PostSeamlessTravel() | ||||
| @@ -401,11 +428,7 @@ void AGasaGameMode::PostSeamlessTravel() | ||||
| void AGasaGameMode::SetPlayerDefaults(APawn* PlayerPawn) | ||||
| { | ||||
| 	InitializeHUDForPlayer(Cast<APlayerController>(PlayerPawn->GetController())); | ||||
| 	 | ||||
| 	// Super::SetPlayerDefaults(PlayerPawn); | ||||
| 	{ | ||||
| 		PlayerPawn->SetPlayerDefaults(); | ||||
| 	} | ||||
| 	Super::SetPlayerDefaults(PlayerPawn); | ||||
| } | ||||
|  | ||||
| void AGasaGameMode::SetSeamlessTravelViewTarget(APlayerController* PC) | ||||
|   | ||||
| @@ -24,7 +24,7 @@ public: | ||||
| 	UFUNCTION() | ||||
| 	void OwningClient_OnGameFrameworkInitialized(AGasaPlayerController* PC); | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, meta=(DisplayName = "On Game Framework Initialized")) | ||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "On Game Framework Initialized")) | ||||
| 	void BP_OnGameFrameworkInitialized(); | ||||
| #pragma endregion GameFramework | ||||
| 	 | ||||
| @@ -60,6 +60,8 @@ public: | ||||
| #pragma region GameModeBase | ||||
| 	void EndPlay(const EEndPlayReason::Type EndPlayReason) override; | ||||
|  | ||||
| 	void FinishRestartPlayer(AController* NewPlayer, const FRotator& StartRotation) override; | ||||
|  | ||||
| 	void GenericPlayerInitialization(AController* C) override; | ||||
|  | ||||
| 	TSubclassOf<APlayerController> GetPlayerControllerClassToSpawnForSeamlessTravel(APlayerController* PreviousPlayerController) override; | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "GasaPlayerState.h" | ||||
| #include "GasaGameInstance.h" | ||||
| #include "Net/UnrealNetwork.h" | ||||
| #include "Networking/GasaNetLibrary_Inlines.h" | ||||
| using namespace Gasa; | ||||
|  | ||||
| AGasaGameState::AGasaGameState() | ||||
| @@ -15,7 +16,6 @@ AGasaGameState::AGasaGameState() | ||||
|     PrimaryActorTick.bStartWithTickEnabled = true; | ||||
|  | ||||
| 	// Replication | ||||
| 	 | ||||
| 	bReplicates            = true; | ||||
| 	bNetLoadOnClient       = false; | ||||
| 	NetDormancy            = DORM_Awake; | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| #pragma once | ||||
| #include "GameFramework/GameState.h" | ||||
|  | ||||
| #include "GasaCommon.h" | ||||
| @@ -6,10 +7,6 @@ | ||||
|  | ||||
| #include "GasaGameState.generated.h" | ||||
|  | ||||
| DECLARE_MULTICAST_DELEGATE( FOnTravelDelegate ); | ||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE( FOnTravelSig ); | ||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerCharacterReadySig, APlayerCharacter*, Character); | ||||
|  | ||||
| UCLASS( Blueprintable ) | ||||
| class GASA_API AGasaGameState : public AGameState | ||||
| { | ||||
| @@ -29,11 +26,21 @@ public: | ||||
| 	AGasaGameState(); | ||||
|  | ||||
| #pragma region GameFramework | ||||
| 	UPROPERTY(BlueprintAssignable) | ||||
| 	FOnPawnReadySig Event_OnPlayerPawnReady; | ||||
| 	 | ||||
| 	UFUNCTION() | ||||
| 	void OnGameFrameworkInitialized(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "Game Framework Initialized")) | ||||
| 	void BP_OnGameFrameworkInitialized(); | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void NotifyPlayerPawnReady(APawn* Pawn) | ||||
| 	{ | ||||
| 		if (Event_OnPlayerPawnReady.IsBound()) | ||||
| 			Event_OnPlayerPawnReady.Broadcast(Pawn); | ||||
| 	} | ||||
| #pragma endregion GameFramework | ||||
|  | ||||
| #pragma region Networking | ||||
| @@ -41,7 +48,7 @@ public: | ||||
| 	AGasaPlayerState* ListenServerHost; | ||||
|  | ||||
| 	UPROPERTY(ReplicatedUsing = "Client_OnRep_OnlinePlayers", BlueprintReadOnly) | ||||
| 	TArray<AGasaPlayerState> OnlinePlayers; | ||||
| 	TArray<AGasaPlayerState*> OnlinePlayers; | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void Client_OnRep_OnlinePlayers(); | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| #include "Kismet/GameplayStatics.h" | ||||
| #include "Materials/MaterialInstance.h" | ||||
| #include "Materials/MaterialInstanceDynamic.h" | ||||
| #include "Networking/GasaNetLibrary_Inlines.h" | ||||
| using namespace Gasa; | ||||
|  | ||||
| #pragma region Game Framework | ||||
| @@ -54,7 +55,7 @@ void AGasaLevelScriptActor::BeginPlay() | ||||
| 	if(GI) | ||||
| 		GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & ThisClass::OnGameFrameworkInitialized); | ||||
|  | ||||
| 	if (!bOverrideGameplayFrameworkReady) | ||||
| 	if (!bOverrideGameFrameworkReady) | ||||
| 		GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::Levels); | ||||
| } | ||||
| #pragma endregion Actor | ||||
|   | ||||
| @@ -19,7 +19,7 @@ public: | ||||
|  | ||||
| #pragma region GameFramework | ||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) | ||||
| 	bool bOverrideGameplayFrameworkReady = false; | ||||
| 	bool bOverrideGameFrameworkReady = false; | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void OnGameFrameworkInitialized(); | ||||
|   | ||||
| @@ -1,18 +1,26 @@ | ||||
| #include "GasaPlayerController.h" | ||||
| #include "GasaPlayerController_Inlines.h" | ||||
| #include "Networking/GasaNetLibrary_Inlines.h" | ||||
|  | ||||
| #include "AbilitySystemComponent.h" | ||||
| #include "Engine/LocalPlayer.h" | ||||
| #include "EnhancedInputComponent.h" | ||||
| #include "EnhancedInputSubsystems.h" | ||||
| #include "Characters/GasaCharacter.h" | ||||
| #include "Characters/PlayerCharacter.h" | ||||
| #include "Components/CapsuleComponent.h" | ||||
| #include "Interfaces/NetworkPredictionInterface.h" | ||||
| #include "Kismet/KismetSystemLibrary.h" | ||||
| #include "Net/UnrealNetwork.h" | ||||
| #include "GameFramework/PawnMovementComponent.h" | ||||
|  | ||||
| #include "GasaDevOptions.h" | ||||
| #include "GasaGameInstance.h" | ||||
| #include "GasaGameState.h" | ||||
| #include "GasaPlayerState.h" | ||||
| #include "Actors/CameraMount.h" | ||||
| #include "Camera/CameraComponent.h" | ||||
| #include "Characters/GasaCharacter.h" | ||||
| #include "Components/CapsuleComponent.h" | ||||
| #include "GameFramework/SpringArmComponent.h" | ||||
| #include "Kismet/KismetSystemLibrary.h" | ||||
| #include "UI/GasaHUD.h" | ||||
| #include "UI/WidgetController.h" | ||||
| using namespace Gasa; | ||||
|  | ||||
| AGasaPlayerController::AGasaPlayerController() | ||||
| @@ -24,7 +32,143 @@ AGasaPlayerController::AGasaPlayerController() | ||||
| 	bReplicates = true; | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::OnSeamlessTravelStart() | ||||
| { | ||||
| } | ||||
|  | ||||
| #pragma region GameFramework | ||||
| void AGasaPlayerController::Client_CheckIfOwnerReady() | ||||
| { | ||||
| 	if (IsServer()) | ||||
| 		return; | ||||
| 	 | ||||
| 	UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>(); | ||||
| 	if ( ! GI->IsGameFrameworkInitialized() || PlayerState == NULL || ! IsValid(GetPawn())) | ||||
| 		return; | ||||
| 	 | ||||
| 	NetOwner_OnReady(); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::NetOwner_OnReady() | ||||
| { | ||||
| 	NetLog("Net Owner of controller is ready to play."); | ||||
| 	if ( ! IsNetOwner() || bNetOwnerReady) | ||||
| 		return; | ||||
| 	 | ||||
| 	BP_NetOwner_OnReady(); | ||||
| 	Event_NetOwner_OnReady.Broadcast(this); | ||||
| 	bNetOwnerReady = true; | ||||
|  | ||||
| 	AGasaGameState* GS = Cast<AGasaGameState>(GetWorld()->GetGameState()); | ||||
| 	if (GS) | ||||
| 		GS->NotifyPlayerPawnReady(GetPawn()); | ||||
|  | ||||
| 	if (IsClient()) | ||||
| 		ServerRPC_R_NotifyOwningClientReady(); | ||||
|  | ||||
| 	AGasaPlayerState* PS         = GetPlayerState(); | ||||
| 	APlayerCharacter* PlayerChar = GetPawn<APlayerCharacter>(); | ||||
| 	{ | ||||
| 		PlayerChar->AbilitySystem = PS->AbilitySystem; | ||||
| 		PlayerChar->Attributes    = PS->Attributes; | ||||
| 		PlayerChar->AbilitySystem->InitAbilityActorInfo(PS, this); | ||||
| 		Cam->AttachToActor(PlayerChar, FAttachmentTransformRules::KeepRelativeTransform); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::OnGameFrameworkInitialized() | ||||
| { | ||||
| 	NetLog("Received game framework initialization."); | ||||
| 	if (IsNetOwner()) | ||||
| 	{ | ||||
| 		Server_SetNetOwner_GameFrameworkInitialized(); | ||||
| 		Client_CheckIfOwnerReady(); | ||||
| 	} | ||||
|  | ||||
| 	AGasaGameState* GS = GetGameState(this); | ||||
| 	NullGuard_DEV(GS, Log, "OnGameFrameworkInitialized: GS is null"); | ||||
| 	GS->Event_OnSeamlessTravelStart.AddDynamic( this, & ThisClass::OnSeamlessTravelStart ); | ||||
| 	 | ||||
| 	BP_OnGameFrameworkInitialized(); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::OnPawnReady() | ||||
| { | ||||
| 	NetLog("Player is ready."); | ||||
|  | ||||
| 	// Originally: Super::OnPossess(PawnToPossess); | ||||
| 	{ | ||||
| 		ChangeState(NAME_Playing); | ||||
| 		if (bAutoManageActiveCameraTarget) | ||||
| 		{ | ||||
| 			AutoManageActiveCameraTarget(GetPawn()); | ||||
| 			ResetCameraMode(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Override this and add your own conditions... | ||||
| 	BP_OnPawnReady(); | ||||
|  | ||||
| 	if (IsServer() && IsNetOwner()) | ||||
| 	{ | ||||
| 		// The server host doesn't have to wait for the player state to replicate. | ||||
| 		NetOwner_OnReady(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::Server_SetupOnPawnReadyBinds(APawn* PawnToBindTo) | ||||
| { | ||||
| 	if (IsClient()) | ||||
| 		return; | ||||
| #if 0 | ||||
| 	if (PawnToBindTo->IsA(AGasaPawn::StaticClass())) | ||||
| 	{ | ||||
| 		Cast<AGasaPawn>(PawnToBindTo)->Event_OnPawnReady.AddUniqueDynamic(this, & ThisClass::OnPawnReady); | ||||
| 	} | ||||
| 	else | ||||
| #endif | ||||
| 	if (PawnToBindTo->IsA(AGasaCharacter::StaticClass())) | ||||
| 	{ | ||||
| 		Cast<AGasaCharacter>(PawnToBindTo)->Event_OnPawnReady.AddUniqueDynamic(this, & ThisClass::OnPawnReady); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::Server_SetNetOwner_GameFrameworkInitialized() | ||||
| { | ||||
| 	if (IsClient()) | ||||
| 	{ | ||||
| 		ServerRPC_R_SetNetOwner_GameFrameworkInitialized(); | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	bNetOwner_GameFrameworkInitialized = true; | ||||
| 	if (Event_NetOwner_OnGameFrameworkInitialized.IsBound()) | ||||
| 	{ | ||||
| 		Event_NetOwner_OnGameFrameworkInitialized.Broadcast(this); | ||||
| 		Event_NetOwner_OnGameFrameworkInitialized.Clear(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::ServerRPC_R_NotifyOwningClientReady_Implementation() | ||||
| { | ||||
| 	NetLog("Net Owner Ready: Notified via RPC."); | ||||
|  | ||||
| 	BP_NetOwner_OnReady(); | ||||
| 	bNetOwnerReady = true; | ||||
| 	Event_NetOwner_OnReady.Broadcast(this); | ||||
| 	Event_NetOwner_OnReady.Clear(); | ||||
| 	 | ||||
| 	AGasaGameState* GS = GetGameState(this); | ||||
|  | ||||
| 	if (GS) | ||||
| 		GS->NotifyPlayerPawnReady(GetPawn()); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::ServerRPC_R_SetNetOwner_GameFrameworkInitialized_Implementation() | ||||
| { | ||||
| 	Server_SetNetOwner_GameFrameworkInitialized(); | ||||
| } | ||||
| #pragma endregion GameFramework | ||||
|  | ||||
| #pragma region Input | ||||
| void AGasaPlayerController::Move(FInputActionValue const& ActionValue) | ||||
| @@ -72,29 +216,109 @@ void AGasaPlayerController::Move(FInputActionValue const& ActionValue) | ||||
| #pragma endregion Input | ||||
|  | ||||
| #pragma region PlayerController | ||||
| void AGasaPlayerController::SpawnDefaultHUD() | ||||
| bool AGasaPlayerController::CanRestartPlayer() | ||||
| { | ||||
| 	Super::SpawnDefaultHUD(); | ||||
| 	bool BaseCheck =  | ||||
| 			PlayerState &&  | ||||
| 			!PlayerState->IsOnlyASpectator() &&  | ||||
| 			HasClientLoadedCurrentWorld() &&  | ||||
| 			PendingSwapConnection  == NULL | ||||
| 		; | ||||
|  | ||||
| 	return BaseCheck && bNetOwner_GameFrameworkInitialized; | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::ClientSetHUD_Implementation(TSubclassOf<AHUD> NewHUDClass) | ||||
| { | ||||
| 	Super::ClientSetHUD_Implementation(NewHUDClass); | ||||
| 	AGasaPlayerState*      PS   = GetPlayerState(); | ||||
| 	AGasaHUD*              HUD  = GetHUD<AGasaHUD>(); | ||||
| 	FWidgetControllerData  Data = { this, PS, PS->AbilitySystem, PS->Attributes }; | ||||
| 	HUD->InitHostWidget(& Data); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::ClientUpdateLevelStreamingStatus_Implementation(FName PackageName, bool bNewShouldBeLoaded, bool bNewShouldBeVisible, | ||||
|                                                                             bool bNewShouldBlockOnLoad, int32 LODIndex, FNetLevelVisibilityTransactionId TransactionId, bool bNewShouldBlockOnUnload) | ||||
| { | ||||
| 	Super::ClientUpdateLevelStreamingStatus_Implementation(PackageName, bNewShouldBeLoaded, bNewShouldBeVisible, bNewShouldBlockOnLoad, LODIndex, | ||||
| 	                                                       TransactionId, bNewShouldBlockOnUnload); | ||||
|  | ||||
| 	NetLog("ClientUpdateLevelStreamingStatus"); | ||||
| 	NetLog(FString("PackageName            : ") + PackageName.ToString());  | ||||
| 	NetLog(FString("NewShouldBeLoaded      : ") + FString(bNewShouldBeLoaded ? "true" : "false")); | ||||
| 	NetLog(FString("NewShouldBeVisible     : ") + FString(bNewShouldBeVisible ? "true" : "false")); | ||||
| 	NetLog(FString("bNewShouldBlockOnLoad  : ") + FString(bNewShouldBlockOnLoad ? "true" : "false")); | ||||
| 	NetLog(FString("bNewShouldBlockOnUnload: ") + FString(bNewShouldBlockOnUnload ? "true" : "false")); | ||||
| 	NetLog(FString("LODIndex               : ") + FString::FromInt( LODIndex ));	 | ||||
| } | ||||
|  | ||||
| // TODO(Ed): We need to setup Net Slime... | ||||
| void AGasaPlayerController::OnPossess(APawn* InPawn) | ||||
| void AGasaPlayerController::OnPossess(APawn* PawnPossesed) | ||||
| { | ||||
| 	Super::OnPossess(InPawn); | ||||
|  | ||||
| 	Cam->AttachToActor(InPawn, FAttachmentTransformRules::KeepRelativeTransform); | ||||
|  | ||||
| 	AGasaPlayerState* PS      = GetPlayerState(); | ||||
| 	AGasaCharacter* character = Cast<AGasaCharacter>(InPawn); | ||||
| 	// Net Owner setup ability system | ||||
| 	if (0) | ||||
| 	// Super::OnPossess(PawnPossesed); | ||||
| 	{ | ||||
| 		character->AbilitySystem = PS->AbilitySystem; | ||||
| 		character->Attributes    = PS->Attributes; | ||||
| 		character->AbilitySystem->InitAbilityActorInfo(PS, character); | ||||
| 		if (PawnPossesed && (PlayerState == NULL || !PlayerState->IsOnlyASpectator()) ) | ||||
| 		{ | ||||
| 			// ====================================================================Originally: Super::OnPossess(PawnToPossess); | ||||
| 			const bool bNewPawn = (GetPawn() != PawnPossesed); | ||||
| 			if (GetPawn() && bNewPawn) | ||||
| 				UnPossess(); | ||||
|  | ||||
| 			if (PawnPossesed->Controller != NULL) | ||||
| 				PawnPossesed->Controller->UnPossess(); | ||||
| 			 | ||||
| 			PawnPossesed->PossessedBy(this); | ||||
|  | ||||
| 			// update rotation to match possessed pawn's rotation | ||||
| 			SetControlRotation( PawnPossesed->GetActorRotation() ); | ||||
| 			SetPawn(PawnPossesed); | ||||
|  | ||||
| 			check(GetPawn() != NULL); | ||||
| 			if (GetPawn() && GetPawn()->PrimaryActorTick.bStartWithTickEnabled) | ||||
| 				GetPawn()->SetActorTickEnabled(true); | ||||
|  | ||||
| 			INetworkPredictionInterface* NetworkPredictionInterface = GetPawn() | ||||
| 				? Cast<INetworkPredictionInterface>(GetPawn()->GetMovementComponent()) | ||||
| 				: nullptr; | ||||
| 			if (NetworkPredictionInterface) | ||||
| 				NetworkPredictionInterface->ResetPredictionData_Server(); | ||||
|  | ||||
| 			AcknowledgedPawn = NULL; | ||||
|  | ||||
| 			// Local PCs will have the Restart() triggered right away in ClientRestart (via PawnClientRestart()), but the server should call Restart() locally for remote PCs. | ||||
| 			// We're really just trying to avoid calling Restart() multiple times. | ||||
| 			if (!IsLocalPlayerController()) | ||||
| 				GetPawn()->Restart(); | ||||
|  | ||||
| 			ClientRestart(GetPawn()); | ||||
|  | ||||
|  | ||||
| 		// Moved to: void AGasaPlayerController::OnPawnReady | ||||
| 		#if 0 | ||||
| 			ChangeState( NAME_Playing ); | ||||
| 			if (bAutoManageActiveCameraTarget) | ||||
| 			{ | ||||
| 				AutoManageActiveCameraTarget(GetPawn()); | ||||
| 				ResetCameraMode(); | ||||
| 			} | ||||
| 		#endif | ||||
| 			//==========================================================End of=================== Originally: Super::OnPossess(PawnToPossess); | ||||
|  | ||||
| 			NetLog("OnPossess"); | ||||
| 			Server_SetupOnPawnReadyBinds(PawnPossesed); | ||||
| 			Event_OnPawnPossessed.Broadcast(); | ||||
| 		}	 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::OnRep_Pawn() | ||||
| { | ||||
| 	Super::OnRep_Pawn(); | ||||
| 	 | ||||
| 	NetLog("OnRep_Pawn"); | ||||
| 	Client_CheckIfOwnerReady(); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::OnUnPossess() | ||||
| { | ||||
| 	Super::OnUnPossess(); | ||||
| @@ -138,6 +362,11 @@ void AGasaPlayerController::PlayerTick(float DeltaTime) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::PostSeamlessTravel() | ||||
| { | ||||
| 	Super::PostSeamlessTravel(); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::SetupInputComponent() | ||||
| { | ||||
| 	Super::SetupInputComponent(); | ||||
| @@ -148,12 +377,22 @@ void AGasaPlayerController::SetupInputComponent() | ||||
| 		EIC->BindAction(IA_Move, ETriggerEvent::Triggered, this, &ThisClass::Move);	 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::SpawnDefaultHUD() | ||||
| { | ||||
| 	Super::SpawnDefaultHUD(); | ||||
| } | ||||
| #pragma endregion PlayerController | ||||
|  | ||||
| #pragma region Actor | ||||
| void AGasaPlayerController::BeginPlay() | ||||
| { | ||||
| 	Super::BeginPlay(); | ||||
| 	NetLog("BeginPlay"); | ||||
|  | ||||
| 	UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>(); | ||||
| 	GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & AGasaPlayerController::OnGameFrameworkInitialized); | ||||
| 	GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::PlayerController); | ||||
|  | ||||
| 	if (IsLocalController()) | ||||
| 	{ | ||||
| @@ -209,4 +448,11 @@ void AGasaPlayerController::Tick(float DeltaSeconds) | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void AGasaPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const | ||||
| { | ||||
| 	Super::GetLifetimeReplicatedProps(OutLifetimeProps); | ||||
|  | ||||
| 	DOREPLIFETIME(AGasaPlayerController, bNetOwner_GameFrameworkInitialized); | ||||
| } | ||||
| #pragma endregion Actor | ||||
|   | ||||
| @@ -1,17 +1,26 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "GasaCommon.h" | ||||
| #include "GasaPlayerState.h" | ||||
| #include "Networking/GasaNetLibrary.h" | ||||
| #include "Engine/Engine.h" | ||||
| #include "GameFramework/PlayerController.h" | ||||
| #include "Networking/GasaNetLibrary.h" | ||||
|  | ||||
| #include "GasaPlayerController.generated.h" | ||||
|  | ||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGasaPlayerControllerSig, AGasaPlayerController*, PC); | ||||
|  | ||||
| UCLASS(Blueprintable) | ||||
| class GASA_API AGasaPlayerController : public APlayerController | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
| protected: | ||||
| 	friend void AGasaPlayerState::ClientInitialize(AController* NewOwner); | ||||
| public: | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void OnSeamlessTravelStart(); | ||||
| 	 | ||||
| #pragma region Camera | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite) | ||||
| 	TObjectPtr<ACameraMount> Cam; | ||||
| @@ -33,6 +42,55 @@ public: | ||||
| 	FORCEINLINE void Dehighlight() { SetHighlight(EHighlight::Disabled); }; | ||||
| #pragma endregion Highlighting | ||||
| #endif | ||||
|  | ||||
| #pragma region GameFramework | ||||
| 	UPROPERTY(BlueprintAssignable) | ||||
| 	FOnGasaPlayerControllerSig Event_NetOwner_OnGameFrameworkInitialized; | ||||
|  | ||||
| 	UPROPERTY(BlueprintAssignable) | ||||
| 	FOnGasaPlayerControllerSig Event_NetOwner_OnReady; | ||||
|  | ||||
| 	UPROPERTY(BlueprintAssignable) | ||||
| 	FOnPawnSig Event_OnPawnPossessed; | ||||
|  | ||||
| 	UPROPERTY(Replicated, VisibleAnywhere) | ||||
| 	bool bNetOwner_GameFrameworkInitialized = false; | ||||
|  | ||||
| 	UPROPERTY(VisibleAnywhere, Category = "Game Framework") | ||||
| 	bool bNetOwnerReady = false; | ||||
| 	 | ||||
| 	void Client_CheckIfOwnerReady(); | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void NetOwner_OnReady(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta = (DisplayName = "NetOwner: On Ready")) | ||||
| 	void BP_NetOwner_OnReady(); | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void OnGameFrameworkInitialized(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "On Game Framework Initialized")) | ||||
| 	void BP_OnGameFrameworkInitialized(); | ||||
| 	 | ||||
| 	UFUNCTION() | ||||
| 	void OnPawnReady(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "On Pawn Ready")) | ||||
| 	void BP_OnPawnReady(); | ||||
| 	 | ||||
| 	UFUNCTION() | ||||
| 	void Server_SetupOnPawnReadyBinds(APawn* PawnToBindTo); | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void Server_SetNetOwner_GameFrameworkInitialized(); | ||||
| 	 | ||||
| 	UFUNCTION(Server, Reliable) | ||||
| 	void ServerRPC_R_NotifyOwningClientReady(); | ||||
|  | ||||
| 	UFUNCTION(Server, Reliable) | ||||
| 	void ServerRPC_R_SetNetOwner_GameFrameworkInitialized(); | ||||
| #pragma endregion GameFramework | ||||
| 	 | ||||
| #pragma region Input | ||||
| 	UPROPERTY(VisibleAnywhere, BlueprintReadOnly) | ||||
| @@ -50,10 +108,6 @@ public: | ||||
| 	void Move(FInputActionValue const& ActionValue); | ||||
| #pragma endregion Input | ||||
| 	 | ||||
| 	AGasaPlayerController(); | ||||
|  | ||||
| 	inline AGasaPlayerState* GetPlayerState(); | ||||
|  | ||||
| #pragma region NetSlime | ||||
| 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | ||||
| 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | ||||
| @@ -76,24 +130,35 @@ public: | ||||
| 	} | ||||
| #pragma endregion NetSlime | ||||
| 	 | ||||
| 	AGasaPlayerController(); | ||||
|  | ||||
| 	inline AGasaPlayerState* GetPlayerState(); | ||||
| 	 | ||||
| #pragma region PlayerController | ||||
| 	void SpawnDefaultHUD() override; | ||||
| 	 | ||||
| 	void OnPossess(APawn* InPawn) override; | ||||
| 	void OnUnPossess() override; | ||||
| 	 | ||||
| 	bool CanRestartPlayer() override; | ||||
| 	void ClientSetHUD_Implementation(TSubclassOf<AHUD> NewHUDClass) override; | ||||
| 	void ClientUpdateLevelStreamingStatus_Implementation(FName PackageName, bool bNewShouldBeLoaded, bool bNewShouldBeVisible, bool bNewShouldBlockOnLoad, int32 LODIndex, FNetLevelVisibilityTransactionId TransactionId, bool bNewShouldBlockOnUnload) override; | ||||
| 	void PlayerTick(float DeltaTime) override; | ||||
| 	 | ||||
| 	void PostSeamlessTravel() override; | ||||
| 	void SetupInputComponent() override; | ||||
| 	void SpawnDefaultHUD() override; | ||||
| #pragma endregion PlayerController | ||||
|  | ||||
| #pragma region Controller | ||||
| 	void OnPossess(APawn* InPawn) override; | ||||
| 	void OnRep_Pawn() override; | ||||
| 	void OnUnPossess() override; | ||||
| #pragma endregion Controller | ||||
|  | ||||
| #pragma region Actor | ||||
| 	void BeginPlay() override; | ||||
|  | ||||
| 	void PostInitializeComponents() override; | ||||
|  | ||||
| 	void Tick(float DeltaSeconds) override; | ||||
| #pragma endregion Actor | ||||
|  | ||||
| #pragma region UObject | ||||
| 	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; | ||||
| #pragma endregion UObject | ||||
| }; | ||||
|  | ||||
| namespace Gasa | ||||
|   | ||||
| @@ -1,5 +1,8 @@ | ||||
| #include "GasaPlayerState.h" | ||||
|  | ||||
| #include "Networking/GasaNetLibrary_Inlines.h" | ||||
| #include "GasaGameInstance.h" | ||||
| #include "GasaPlayerController.h" | ||||
| #include "AbilitySystem/GasaAbilitySystemComponent.h" | ||||
| #include "AbilitySystem/GasaAttributeSet.h" | ||||
|  | ||||
| @@ -16,3 +19,74 @@ AGasaPlayerState::AGasaPlayerState() | ||||
| 	// Replication | ||||
| 	NetUpdateFrequency = 100.f; | ||||
| } | ||||
|  | ||||
| #pragma region GameFramework | ||||
| void AGasaPlayerState::OnGameFrameworkInitialized() | ||||
| { | ||||
| 	NetLog("Received game framework initialization."); | ||||
| 	BP_OnGameFrameworkInitialized(); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerState::OnNetOwnerReady(AGasaPlayerController* PC) | ||||
| { | ||||
| 	BP_OnNetOwnerReady(); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerState::Reset() | ||||
| { | ||||
| 	Super::Reset(); | ||||
| 	NetLog("Reset"); | ||||
| } | ||||
|  | ||||
| #pragma endregion GameFramework | ||||
|  | ||||
| #pragma region PlayerState | ||||
| void AGasaPlayerState::ClientInitialize(AController* NewOwner) | ||||
| { | ||||
| 	Super::ClientInitialize(NewOwner); | ||||
| 	NetLog("Client Initialization: This is the OnRep for player state."); | ||||
|  | ||||
| 	AGasaPlayerController* GasaPC = Cast<AGasaPlayerController>(NewOwner); | ||||
| 	if (GasaPC) | ||||
| 		GasaPC->Client_CheckIfOwnerReady(); | ||||
| } | ||||
| #pragma endregion PlayerState | ||||
|  | ||||
| #pragma region Actor | ||||
| void AGasaPlayerState::BeginPlay() | ||||
| { | ||||
| 	NetLog("Begin Play"); | ||||
| 	Super::BeginPlay(); | ||||
|  | ||||
| 	UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>(); | ||||
| 	GI->Event_OnGameFrameworkInitialized.AddDynamic(this, & ThisClass::OnGameFrameworkInitialized); | ||||
| 	GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::PlayerState); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerState::PostInitializeComponents() | ||||
| { | ||||
| 	Super::PostInitializeComponents(); | ||||
| 	NetLog("Post Initialization"); | ||||
| } | ||||
|  | ||||
| void AGasaPlayerState::RegisterPlayerWithSession(bool bWasFromInvite) | ||||
| { | ||||
| 	Super::RegisterPlayerWithSession(bWasFromInvite); | ||||
| 	NetLog("RegisterPlayerWithSession"); | ||||
| 	 | ||||
| 	if (IsServer() && GetInstigatorController()) | ||||
| 	{ | ||||
| 		AGasaPlayerController* PC = Cast<AGasaPlayerController>(GetInstigatorController()); | ||||
| 		PC->Event_NetOwner_OnReady.AddDynamic(this, & ThisClass::OnNetOwnerReady); | ||||
| 	} | ||||
| } | ||||
| #pragma endregion Actor | ||||
|  | ||||
| #pragma region UObject | ||||
| void AGasaPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const | ||||
| { | ||||
| 	Super::GetLifetimeReplicatedProps(OutLifetimeProps); | ||||
|  | ||||
| 	 | ||||
| } | ||||
| #pragma endregion UObject | ||||
|   | ||||
| @@ -15,6 +15,8 @@ class GASA_API AGasaPlayerState : public APlayerState | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
| public: | ||||
| 	AGasaPlayerState(); | ||||
| 	 | ||||
| #pragma region Ability System | ||||
| 	UPROPERTY(EditAnywhere, Category="Ability System") | ||||
| 	bool bAutoAbilitySystem; | ||||
| @@ -25,9 +27,31 @@ public: | ||||
| 	UPROPERTY(EditAnywhere, Category="Ability System") | ||||
| 	TObjectPtr<UAttributeSet> Attributes; | ||||
| #pragma endregion Ability System | ||||
| 	 | ||||
| 	AGasaPlayerState(); | ||||
|  | ||||
| #pragma region GameFramework | ||||
| 	UFUNCTION() | ||||
| 	void OnGameFrameworkInitialized(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta = (DisplayName = "On Game Framework Initialized")) | ||||
| 	void BP_OnGameFrameworkInitialized(); | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void OnNetOwnerReady(AGasaPlayerController* PC); | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta = (DisplayName = "On Net Owner Ready")) | ||||
| 	void BP_OnNetOwnerReady(); | ||||
| #pragma endregion GameFramework | ||||
|  | ||||
| #pragma region Networking | ||||
| #if 0 | ||||
| 	UPROPERTY(ReplicatedUsing = Client_OnRep_GasaID) | ||||
| 	int32 GasaID = INDEX_NONE; | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void Client_OnRep_GasaID; | ||||
| #endif | ||||
| #pragma endregion Networking | ||||
| 	 | ||||
| #pragma region NetSlime | ||||
| 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | ||||
| 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | ||||
| @@ -55,7 +79,18 @@ public: | ||||
| 	FORCEINLINE UAbilitySystemComponent* GetAbilitySystemComponent() const override { return AbilitySystem; } | ||||
| #pragma endregion IAbilitySystem | ||||
|  | ||||
| // #pragma region | ||||
| // 	 | ||||
| // #pragma endregion  | ||||
| #pragma region PlayerState | ||||
| 	void ClientInitialize(AController* C) override; | ||||
| #pragma endregion PlayerState | ||||
| 	 | ||||
| #pragma region Actor | ||||
| 	void BeginPlay() override; | ||||
| 	void PostInitializeComponents() override; | ||||
| 	void RegisterPlayerWithSession(bool bWasFromInvite) override; | ||||
| 	void Reset() override; | ||||
| #pragma endregion Actor | ||||
|  | ||||
| #pragma region UObject | ||||
| 	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; | ||||
| #pragma endregion UObject | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user