'NetSlime' Initial port finished and working with 2 players (at least)
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-Gasa.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-Gasa.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,4 +1,5 @@ | |||||||
| #include "EnemyCharacter.h" | #include "EnemyCharacter.h" | ||||||
|  | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
|  |  | ||||||
| AEnemyCharacter::AEnemyCharacter() | AEnemyCharacter::AEnemyCharacter() | ||||||
| { | { | ||||||
|   | |||||||
| @@ -11,13 +11,12 @@ | |||||||
| #include "AbilitySystem/GasaAttributeSet.h" | #include "AbilitySystem/GasaAttributeSet.h" | ||||||
| #include "Components/SkeletalMeshComponent.h" | #include "Components/SkeletalMeshComponent.h" | ||||||
| #include "Engine/PostProcessVolume.h" | #include "Engine/PostProcessVolume.h" | ||||||
|  | #include "Game/GasaGameInstance.h" | ||||||
| #include "Game/GasaLevelScriptActor.h" | #include "Game/GasaLevelScriptActor.h" | ||||||
|  | #include "Game/GasaPlayerController.h" | ||||||
| #include "Materials/MaterialInstanceDynamic.h" | #include "Materials/MaterialInstanceDynamic.h" | ||||||
|  | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
| void AGasaCharacter::SetHighlight(EHighlight Desired) | using namespace Gasa; | ||||||
| { |  | ||||||
| 	HighlightState = Desired; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| AGasaCharacter::AGasaCharacter() | AGasaCharacter::AGasaCharacter() | ||||||
| { | { | ||||||
| @@ -51,13 +50,112 @@ AGasaCharacter::AGasaCharacter() | |||||||
| 		 | 		 | ||||||
| 		Attributes = CreateDefaultSubobject<UGasaAttributeSet>("Attributes"); | 		Attributes = CreateDefaultSubobject<UGasaAttributeSet>("Attributes"); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// Replication | ||||||
|  | 	 | ||||||
|  | 	bReplicates            = false; | ||||||
|  | 	bNetLoadOnClient       = true; | ||||||
|  | 	NetDormancy            = DORM_Awake; | ||||||
|  | 	NetCullDistanceSquared = NetCullDist_Medium; | ||||||
|  | 	NetUpdateFrequency     = 30.0f; | ||||||
|  | 	MinNetUpdateFrequency  = 5.0f; | ||||||
|  | 	NetPriority            = 2.0f; | ||||||
|  |  | ||||||
|  | 	ACharacter::SetReplicateMovement(true); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #pragma region GameFramework | ||||||
|  | void AGasaCharacter::Controller_OnPawnPossessed() | ||||||
|  | { | ||||||
|  | 	NetLog("Controller confirmed possession."); | ||||||
|  |  | ||||||
|  | 	// Do stuff here that you needed to wait for the player controller be aware of you for. | ||||||
|  | 	BP_Controller_OnPawnPossessed(); | ||||||
|  |  | ||||||
|  | 	if (Event_OnPawnReady.IsBound()) | ||||||
|  | 		Event_OnPawnReady.Broadcast();	 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void AGasaCharacter::ServerRPC_R_NotifyClientPawnReady_Implementation() | ||||||
|  | { | ||||||
|  | 	Event_OnPawnReady.Broadcast(); | ||||||
|  | } | ||||||
|  | #pragma endregion GameFramework | ||||||
|  |  | ||||||
|  | #pragma region Highlight | ||||||
|  | void AGasaCharacter::SetHighlight(EHighlight Desired) | ||||||
|  | { | ||||||
|  | 	HighlightState = Desired; | ||||||
|  | } | ||||||
|  | #pragma endregion Highlight | ||||||
|  |  | ||||||
| #pragma region Pawn | #pragma region Pawn | ||||||
|  | void AGasaCharacter::OnRep_PlayerState() | ||||||
|  | { | ||||||
|  | 	Super::OnRep_PlayerState(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void AGasaCharacter::PossessedBy(AController* NewController) | void AGasaCharacter::PossessedBy(AController* NewController) | ||||||
| { | { | ||||||
| 	Super::PossessedBy(NewController); | 	NetLog("Pawn possessed."); | ||||||
|  |  | ||||||
|  | 	AController* OldController; | ||||||
|  | 	 | ||||||
|  | 	// APawn::PossessedBy | ||||||
|  | 	{ | ||||||
|  | 		SetOwner(NewController); | ||||||
|  | 		OldController = Controller; | ||||||
|  | 		Controller = NewController; | ||||||
|  |  | ||||||
|  | 		ForceNetUpdate(); | ||||||
|  |  | ||||||
|  | 	#if UE_WITH_IRIS | ||||||
|  | 		// The owning connection depends on the Controller having the new value. | ||||||
|  | 		UpdateOwningNetConnection(); | ||||||
|  | 	#endif | ||||||
|  | 		 | ||||||
|  | 		if (Controller->PlayerState != nullptr) | ||||||
|  | 			SetPlayerState(Controller->PlayerState); | ||||||
|  |  | ||||||
|  | 		if (APlayerController* PlayerController = Cast<APlayerController>(Controller)) | ||||||
|  | 		{ | ||||||
|  | 			if (GetNetMode() != NM_Standalone) | ||||||
|  | 			{ | ||||||
|  | 				SetReplicates(true); | ||||||
|  | 				SetAutonomousProxy(true); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 			CopyRemoteRoleFrom(GetDefault<APawn>()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (AGasaPlayerController* PC = Cast<AGasaPlayerController>(NewController)) | ||||||
|  | 	{ | ||||||
|  | 		PC->Event_OnPawnPossessed.AddUniqueDynamic(this, & ThisClass::Controller_OnPawnPossessed); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		NetLog("Controller assigned to GasaCharacter is not derived from GasaPlayerController.", ELogV::Warning); | ||||||
|  | 		NetLog("Controller: Name: " + NewController->GetName() + " Class: " + NewController->GetClass()->GetName(), ELogV::Warning); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// cont. APawn::PossessedBy | ||||||
|  | 	{ | ||||||
|  | 		// Dispatch Blueprint event if necessary | ||||||
|  | 		if (OldController != NewController) | ||||||
|  | 		{ | ||||||
|  | 			ReceivePossessed(Controller); | ||||||
|  | 			NotifyControllerChanged(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// ACharacter::PossessedBy | ||||||
|  | 	{ | ||||||
|  | 		// If we are controlled remotely, set animation timing to be driven by client's network updates. So timing and events remain in sync. | ||||||
|  | 		if (GetMesh() && IsReplicatingMovement() && (GetRemoteRole() == ROLE_AutonomousProxy && GetNetConnection() != nullptr)) | ||||||
|  | 			GetMesh()->bOnlyAllowAutonomousTickPose = true; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
| 	if (bAutoAbilitySystem) | 	if (bAutoAbilitySystem) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO(Ed): Do we need to do this for enemies? | 		// TODO(Ed): Do we need to do this for enemies? | ||||||
| @@ -65,9 +163,14 @@ void AGasaCharacter::PossessedBy(AController* NewController) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void AGasaCharacter::OnRep_PlayerState() | void AGasaCharacter::SetPlayerDefaults() | ||||||
| { | { | ||||||
| 	Super::OnRep_PlayerState(); | 	Super::SetPlayerDefaults(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void AGasaCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) | ||||||
|  | { | ||||||
|  | 	Super::SetupPlayerInputComponent(PlayerInputComponent); | ||||||
| } | } | ||||||
| #pragma endregion Pawn | #pragma endregion Pawn | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
| #include "GameFramework/Character.h" | #include "GameFramework/Character.h" | ||||||
|  |  | ||||||
| #include "GasaCommon.h" | #include "GasaCommon.h" | ||||||
| #include "Game/GasaPlayerState.h" | #include "Game/GasaGameState.h" | ||||||
| #include "Networking/GasaNetLibrary.h" | #include "Networking/GasaNetLibrary.h" | ||||||
|  |  | ||||||
| #include "GasaCharacter.generated.h" | #include "GasaCharacter.generated.h" | ||||||
| @@ -22,6 +22,9 @@ class GASA_API AGasaCharacter : public ACharacter | |||||||
| { | { | ||||||
| 	GENERATED_BODY() | 	GENERATED_BODY() | ||||||
| public: | public: | ||||||
|  | 	 | ||||||
|  | 	AGasaCharacter(); | ||||||
|  |  | ||||||
| #pragma region Ability System | #pragma region Ability System | ||||||
| 	UPROPERTY(EditAnywhere, Category="Ability System") | 	UPROPERTY(EditAnywhere, Category="Ability System") | ||||||
| 	bool bAutoAbilitySystem = true; | 	bool bAutoAbilitySystem = true; | ||||||
| @@ -38,6 +41,20 @@ public: | |||||||
| 	TObjectPtr<USkeletalMeshComponent> Weapon; | 	TObjectPtr<USkeletalMeshComponent> Weapon; | ||||||
| #pragma endregion Combat | #pragma endregion Combat | ||||||
|  |  | ||||||
|  | #pragma region GameFramework | ||||||
|  | 	UPROPERTY(BlueprintAssignable) | ||||||
|  | 	FOnPawnSig Event_OnPawnReady; | ||||||
|  | 	 | ||||||
|  | 	UFUNCTION() | ||||||
|  | 	void Controller_OnPawnPossessed(); | ||||||
|  |  | ||||||
|  | 	UFUNCTION(BlueprintImplementableEvent) | ||||||
|  | 	void BP_Controller_OnPawnPossessed(); | ||||||
|  |  | ||||||
|  | 	UFUNCTION(Server, Reliable) | ||||||
|  | 	void ServerRPC_R_NotifyClientPawnReady(); | ||||||
|  | #pragma endregion GameFramework | ||||||
|  |  | ||||||
| #pragma region Highlighting | #pragma region Highlighting | ||||||
| 	static constexpr float HighlightStencilDepth = 256.0; | 	static constexpr float HighlightStencilDepth = 256.0; | ||||||
| 	 | 	 | ||||||
| @@ -57,10 +74,6 @@ public: | |||||||
| 	FORCEINLINE void Dehighlight() { SetHighlight(EHighlight::Disabled); }; | 	FORCEINLINE void Dehighlight() { SetHighlight(EHighlight::Disabled); }; | ||||||
| #pragma endregion Highlighting | #pragma endregion Highlighting | ||||||
|  |  | ||||||
| 	AGasaCharacter(); |  | ||||||
|  |  | ||||||
| 	FORCEINLINE AGasaPlayerState* GetGasaPlayerState() { return GetPlayerState<AGasaPlayerState>(); } |  | ||||||
|  |  | ||||||
| #pragma region NetSlime | #pragma region NetSlime | ||||||
| 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | ||||||
| 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | ||||||
| @@ -89,14 +102,14 @@ public: | |||||||
| #pragma endregion IAbilitySystem | #pragma endregion IAbilitySystem | ||||||
|  |  | ||||||
| #pragma region Pawn | #pragma region Pawn | ||||||
| 	void PossessedBy(AController* NewController) override; |  | ||||||
|  |  | ||||||
| 	void OnRep_PlayerState() override; | 	void OnRep_PlayerState() override; | ||||||
|  | 	void PossessedBy(AController* NewController) override; | ||||||
|  | 	void SetPlayerDefaults() override; | ||||||
|  | 	void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override; | ||||||
| #pragma endregion Pawn | #pragma endregion Pawn | ||||||
| 	 | 	 | ||||||
| #pragma region Actor | #pragma region Actor | ||||||
| 	void BeginPlay() override; | 	void BeginPlay() override; | ||||||
|  |  | ||||||
| 	void Tick(float DeltaSeconds) override; | 	void Tick(float DeltaSeconds) override; | ||||||
| #pragma endregion Actor | #pragma endregion Actor | ||||||
| }; | }; | ||||||
| @@ -108,3 +121,4 @@ namespace Gasa | |||||||
| 	// 	 | 	// 	 | ||||||
| 	// } | 	// } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "PlayerCharacter.h" | #include "PlayerCharacter.h" | ||||||
|  |  | ||||||
|  | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
| #include "AbilitySystemComponent.h" | #include "AbilitySystemComponent.h" | ||||||
| #include "Game/GasaPlayerController.h" | #include "Game/GasaPlayerController.h" | ||||||
| #include "UI/GasaHUD.h" | #include "UI/GasaHUD.h" | ||||||
| @@ -12,46 +13,12 @@ APlayerCharacter::APlayerCharacter() | |||||||
| 	bAutoAbilitySystem = false; | 	bAutoAbilitySystem = false; | ||||||
| } | } | ||||||
|  |  | ||||||
| // TODO(Ed): We need to setup Net Slime... |  | ||||||
| void APlayerCharacter::PossessedBy(AController* NewController) | void APlayerCharacter::PossessedBy(AController* NewController) | ||||||
| { | { | ||||||
| 	Super::PossessedBy(NewController); | 	Super::PossessedBy(NewController); | ||||||
|  |  | ||||||
| 	AGasaPlayerState* PS = GetGasaPlayerState(); |  | ||||||
| 	// Server setup ability system (character side) |  | ||||||
| 	{ |  | ||||||
| 		AbilitySystem = PS->AbilitySystem; |  | ||||||
| 		Attributes    = PS->Attributes; |  | ||||||
| 		AbilitySystem->InitAbilityActorInfo(PS, this); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (IsLocallyControlled()) |  | ||||||
| 	{ |  | ||||||
| 		AGasaPlayerController* PC   = GetController<AGasaPlayerController>(); |  | ||||||
| 		AGasaHUD*              HUD  = PC->GetHUD<AGasaHUD>(); |  | ||||||
| 		FWidgetControllerData  Data = { PC, PS, AbilitySystem, Attributes }; |  | ||||||
| 		HUD->InitHostWidget(& Data); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // TODO(Ed): We need to setup Net Slime... |  | ||||||
| void APlayerCharacter::OnRep_PlayerState() | void APlayerCharacter::OnRep_PlayerState() | ||||||
| { | { | ||||||
| 	Super::OnRep_PlayerState(); | 	Super::OnRep_PlayerState(); | ||||||
| 	 |  | ||||||
| 	AGasaPlayerState* PS = GetGasaPlayerState(); |  | ||||||
| 	// Client setup ability system |  | ||||||
| 	{ |  | ||||||
| 		AbilitySystem = PS->AbilitySystem; |  | ||||||
| 		Attributes    = PS->Attributes; |  | ||||||
| 		AbilitySystem->InitAbilityActorInfo(PS, this); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (IsLocallyControlled()) |  | ||||||
| 	{ |  | ||||||
| 		AGasaPlayerController* PC   = GetController<AGasaPlayerController>(); |  | ||||||
| 		AGasaHUD*              HUD  = PC->GetHUD<AGasaHUD>(); |  | ||||||
| 		FWidgetControllerData  Data = { PC, PS, AbilitySystem, Attributes }; |  | ||||||
| 		HUD->InitHostWidget(& Data); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,29 +7,34 @@ using namespace Gasa; | |||||||
| #pragma region GameFramework | #pragma region GameFramework | ||||||
| // TODO(Ed): Make a NetLog | // TODO(Ed): Make a NetLog | ||||||
|  |  | ||||||
|  | UGasaGameInstance::UGasaGameInstance() | ||||||
|  | { | ||||||
|  | 	GameFrameworkState = EGameFrameworkState::Uninitialized; | ||||||
|  | } | ||||||
|  |  | ||||||
| void UGasaGameInstance::NotifyGameFrameworkClassReady(EGameFrameworkClassFlag ClassReady) | void UGasaGameInstance::NotifyGameFrameworkClassReady(EGameFrameworkClassFlag ClassReady) | ||||||
| { | { | ||||||
| 	switch (ClassReady) | 	switch (ClassReady) | ||||||
| 	{ | 	{ | ||||||
| 		case EGameFrameworkClassFlag::GameMode: | 		case EGameFrameworkClassFlag::GameMode: | ||||||
| 			GameFrameworkClassesState |= (uint32)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; | 		break; | ||||||
| 		case EGameFrameworkClassFlag::GameState: | 		case EGameFrameworkClassFlag::GameState: | ||||||
| 			GameFrameworkClassesState |= (uint32)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; | 		break; | ||||||
| 		case EGameFrameworkClassFlag::PlayerController: | 		case EGameFrameworkClassFlag::PlayerController: | ||||||
| 			GameFrameworkClassesState |= (uint32)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; | 		break; | ||||||
| 		case EGameFrameworkClassFlag::PlayerState: | 		case EGameFrameworkClassFlag::PlayerState: | ||||||
| 			GameFrameworkClassesState |= (uint32)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; | 		break; | ||||||
| 		case EGameFrameworkClassFlag::Levels: | 		case EGameFrameworkClassFlag::Levels: | ||||||
| 			GameFrameworkClassesState |= (uint32)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; | 		break; | ||||||
| 	} | 	} | ||||||
| 	ProcessGameFrameworkState(); | 	ProcessGameFrameworkState(); | ||||||
| @@ -68,7 +73,7 @@ void UGasaGameInstance::ProcessGameFrameworkState() | |||||||
| 			if (GameFrameworkClassesState == InitializedFlags) | 			if (GameFrameworkClassesState == InitializedFlags) | ||||||
| 			{ | 			{ | ||||||
| 				GameFrameworkState = EGameFrameworkState::Initialized; | 				GameFrameworkState = EGameFrameworkState::Initialized; | ||||||
| 				NetLog("Gameplay Framework initialized"); | 				NetLog("Game Framework initialized"); | ||||||
| 				 | 				 | ||||||
| 				Event_OnGameFrameworkInitialized.Broadcast(); | 				Event_OnGameFrameworkInitialized.Broadcast(); | ||||||
| 			} | 			} | ||||||
| @@ -84,8 +89,5 @@ void UGasaGameInstance::Init() | |||||||
| 	Super::Init(); | 	Super::Init(); | ||||||
|  |  | ||||||
| 	DevOptionsCache.CachedDevOptions(); | 	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) | UENUM(BlueprintType) | ||||||
| enum class EGameFrameworkState : uint8 | enum class EGameFrameworkState : uint8 | ||||||
| { | { | ||||||
| 	Initialized, | 	Uninitialized, | ||||||
| 	Uninitialized | 	Initialized | ||||||
| }; | }; | ||||||
|  |  | ||||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnGameFrameworkInitializedSig); | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnGameFrameworkInitializedSig); | ||||||
| @@ -33,6 +33,8 @@ class GASA_API UGasaGameInstance : public UGameInstance | |||||||
| 	GENERATED_BODY() | 	GENERATED_BODY() | ||||||
| public: | public: | ||||||
|  |  | ||||||
|  | 	UGasaGameInstance(); | ||||||
|  |  | ||||||
| 	UPROPERTY(VisibleAnywhere, Category="Dev Cache") | 	UPROPERTY(VisibleAnywhere, Category="Dev Cache") | ||||||
| 	FGasaDevOptionsCache DevOptionsCache; | 	FGasaDevOptionsCache DevOptionsCache; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| #include "GasaGameMode.h" | #include "GasaGameMode.h" | ||||||
|  |  | ||||||
|  | #include "Online/CoreOnline.h" | ||||||
| #include "GasaGameInstance.h" | #include "GasaGameInstance.h" | ||||||
| #include "GasaGameState.h" | #include "GasaGameState.h" | ||||||
| #include "GasaPlayerController.h" | #include "GasaPlayerController.h" | ||||||
| #include "GasaPlayerState.h" |  | ||||||
| #include "Engine/Player.h" | #include "Engine/Player.h" | ||||||
| #include "GameFramework/GameSession.h" | #include "GameFramework/GameSession.h" | ||||||
| #include "GameFramework/GameState.h" | #include "GameFramework/GameState.h" | ||||||
| @@ -71,6 +71,33 @@ void AGasaGameMode::EndPlay(const EEndPlayReason::Type EndPlayReason) | |||||||
| 	NetLog("EndPlay"); | 	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) | void AGasaGameMode::GenericPlayerInitialization(AController* C) | ||||||
| { | { | ||||||
| 	NetLog("GenericPlayerInitialization: " + C->GetName()); | 	NetLog("GenericPlayerInitialization: " + C->GetName()); | ||||||
| @@ -360,10 +387,10 @@ void AGasaGameMode::PostLogin(APlayerController* NewPlayer) | |||||||
| 	{ | 	{ | ||||||
| 		UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>(); | 		UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>(); | ||||||
| 		 | 		 | ||||||
| 		// int32 numconnections = gi->sessionsettings.bpublicgame |  | ||||||
| 			// ? GI->SessionSettings.PublicConnections : GI->SessionSettings.PrivateConnections; |  | ||||||
|  |  | ||||||
| #if 0 | #if 0 | ||||||
|  | 		int32 numconnections = GI->sessionsettings.bPublicGame | ||||||
|  | 			? GI->SessionSettings.PublicConnections : GI->SessionSettings.PrivateConnections; | ||||||
|  | 		 | ||||||
| 		if (GS->OnlinePlayers.Num() < NumConnections) | 		if (GS->OnlinePlayers.Num() < NumConnections) | ||||||
| 		{ | 		{ | ||||||
| 			GS->OnlinePlayers.Init( nullptr, NumConnections ); | 			GS->OnlinePlayers.Init( nullptr, NumConnections ); | ||||||
| @@ -388,8 +415,8 @@ void AGasaGameMode::PostLogin(APlayerController* NewPlayer) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	AGasaPlayerController* PC = Cast<AGasaPlayerController>(NewPlayer); | 	AGasaPlayerController* PC = Cast<AGasaPlayerController>(NewPlayer); | ||||||
| 	// if (PC) | 	if (PC) | ||||||
| 	// 	PC->Event_OnNetOwner_GameplayFrameworkInitialized.AddDynamic(this, &ThisClass::OwningClient_OnGameFrameworkInitialized); | 		PC->Event_NetOwner_OnGameFrameworkInitialized.AddDynamic(this, &ThisClass::OwningClient_OnGameFrameworkInitialized); | ||||||
| } | } | ||||||
|  |  | ||||||
| void AGasaGameMode::PostSeamlessTravel() | void AGasaGameMode::PostSeamlessTravel() | ||||||
| @@ -401,11 +428,7 @@ void AGasaGameMode::PostSeamlessTravel() | |||||||
| void AGasaGameMode::SetPlayerDefaults(APawn* PlayerPawn) | void AGasaGameMode::SetPlayerDefaults(APawn* PlayerPawn) | ||||||
| { | { | ||||||
| 	InitializeHUDForPlayer(Cast<APlayerController>(PlayerPawn->GetController())); | 	InitializeHUDForPlayer(Cast<APlayerController>(PlayerPawn->GetController())); | ||||||
| 	 | 	Super::SetPlayerDefaults(PlayerPawn); | ||||||
| 	// Super::SetPlayerDefaults(PlayerPawn); |  | ||||||
| 	{ |  | ||||||
| 		PlayerPawn->SetPlayerDefaults(); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void AGasaGameMode::SetSeamlessTravelViewTarget(APlayerController* PC) | void AGasaGameMode::SetSeamlessTravelViewTarget(APlayerController* PC) | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ public: | |||||||
| 	UFUNCTION() | 	UFUNCTION() | ||||||
| 	void OwningClient_OnGameFrameworkInitialized(AGasaPlayerController* PC); | 	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(); | 	void BP_OnGameFrameworkInitialized(); | ||||||
| #pragma endregion GameFramework | #pragma endregion GameFramework | ||||||
| 	 | 	 | ||||||
| @@ -60,6 +60,8 @@ public: | |||||||
| #pragma region GameModeBase | #pragma region GameModeBase | ||||||
| 	void EndPlay(const EEndPlayReason::Type EndPlayReason) override; | 	void EndPlay(const EEndPlayReason::Type EndPlayReason) override; | ||||||
|  |  | ||||||
|  | 	void FinishRestartPlayer(AController* NewPlayer, const FRotator& StartRotation) override; | ||||||
|  |  | ||||||
| 	void GenericPlayerInitialization(AController* C) override; | 	void GenericPlayerInitialization(AController* C) override; | ||||||
|  |  | ||||||
| 	TSubclassOf<APlayerController> GetPlayerControllerClassToSpawnForSeamlessTravel(APlayerController* PreviousPlayerController) override; | 	TSubclassOf<APlayerController> GetPlayerControllerClassToSpawnForSeamlessTravel(APlayerController* PreviousPlayerController) override; | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #include "GasaPlayerState.h" | #include "GasaPlayerState.h" | ||||||
| #include "GasaGameInstance.h" | #include "GasaGameInstance.h" | ||||||
| #include "Net/UnrealNetwork.h" | #include "Net/UnrealNetwork.h" | ||||||
|  | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
| using namespace Gasa; | using namespace Gasa; | ||||||
|  |  | ||||||
| AGasaGameState::AGasaGameState() | AGasaGameState::AGasaGameState() | ||||||
| @@ -15,7 +16,6 @@ AGasaGameState::AGasaGameState() | |||||||
|     PrimaryActorTick.bStartWithTickEnabled = true; |     PrimaryActorTick.bStartWithTickEnabled = true; | ||||||
|  |  | ||||||
| 	// Replication | 	// Replication | ||||||
| 	 |  | ||||||
| 	bReplicates            = true; | 	bReplicates            = true; | ||||||
| 	bNetLoadOnClient       = false; | 	bNetLoadOnClient       = false; | ||||||
| 	NetDormancy            = DORM_Awake; | 	NetDormancy            = DORM_Awake; | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | #pragma once | ||||||
| #include "GameFramework/GameState.h" | #include "GameFramework/GameState.h" | ||||||
|  |  | ||||||
| #include "GasaCommon.h" | #include "GasaCommon.h" | ||||||
| @@ -6,10 +7,6 @@ | |||||||
|  |  | ||||||
| #include "GasaGameState.generated.h" | #include "GasaGameState.generated.h" | ||||||
|  |  | ||||||
| DECLARE_MULTICAST_DELEGATE( FOnTravelDelegate ); |  | ||||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE( FOnTravelSig ); |  | ||||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerCharacterReadySig, APlayerCharacter*, Character); |  | ||||||
|  |  | ||||||
| UCLASS( Blueprintable ) | UCLASS( Blueprintable ) | ||||||
| class GASA_API AGasaGameState : public AGameState | class GASA_API AGasaGameState : public AGameState | ||||||
| { | { | ||||||
| @@ -29,11 +26,21 @@ public: | |||||||
| 	AGasaGameState(); | 	AGasaGameState(); | ||||||
|  |  | ||||||
| #pragma region GameFramework | #pragma region GameFramework | ||||||
|  | 	UPROPERTY(BlueprintAssignable) | ||||||
|  | 	FOnPawnReadySig Event_OnPlayerPawnReady; | ||||||
|  | 	 | ||||||
| 	UFUNCTION() | 	UFUNCTION() | ||||||
| 	void OnGameFrameworkInitialized(); | 	void OnGameFrameworkInitialized(); | ||||||
|  |  | ||||||
| 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "Game Framework Initialized")) | 	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "Game Framework Initialized")) | ||||||
| 	void BP_OnGameFrameworkInitialized(); | 	void BP_OnGameFrameworkInitialized(); | ||||||
|  |  | ||||||
|  | 	UFUNCTION() | ||||||
|  | 	void NotifyPlayerPawnReady(APawn* Pawn) | ||||||
|  | 	{ | ||||||
|  | 		if (Event_OnPlayerPawnReady.IsBound()) | ||||||
|  | 			Event_OnPlayerPawnReady.Broadcast(Pawn); | ||||||
|  | 	} | ||||||
| #pragma endregion GameFramework | #pragma endregion GameFramework | ||||||
|  |  | ||||||
| #pragma region Networking | #pragma region Networking | ||||||
| @@ -41,7 +48,7 @@ public: | |||||||
| 	AGasaPlayerState* ListenServerHost; | 	AGasaPlayerState* ListenServerHost; | ||||||
|  |  | ||||||
| 	UPROPERTY(ReplicatedUsing = "Client_OnRep_OnlinePlayers", BlueprintReadOnly) | 	UPROPERTY(ReplicatedUsing = "Client_OnRep_OnlinePlayers", BlueprintReadOnly) | ||||||
| 	TArray<AGasaPlayerState> OnlinePlayers; | 	TArray<AGasaPlayerState*> OnlinePlayers; | ||||||
|  |  | ||||||
| 	UFUNCTION() | 	UFUNCTION() | ||||||
| 	void Client_OnRep_OnlinePlayers(); | 	void Client_OnRep_OnlinePlayers(); | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
| #include "Kismet/GameplayStatics.h" | #include "Kismet/GameplayStatics.h" | ||||||
| #include "Materials/MaterialInstance.h" | #include "Materials/MaterialInstance.h" | ||||||
| #include "Materials/MaterialInstanceDynamic.h" | #include "Materials/MaterialInstanceDynamic.h" | ||||||
|  | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
| using namespace Gasa; | using namespace Gasa; | ||||||
|  |  | ||||||
| #pragma region Game Framework | #pragma region Game Framework | ||||||
| @@ -54,7 +55,7 @@ void AGasaLevelScriptActor::BeginPlay() | |||||||
| 	if(GI) | 	if(GI) | ||||||
| 		GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & ThisClass::OnGameFrameworkInitialized); | 		GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & ThisClass::OnGameFrameworkInitialized); | ||||||
|  |  | ||||||
| 	if (!bOverrideGameplayFrameworkReady) | 	if (!bOverrideGameFrameworkReady) | ||||||
| 		GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::Levels); | 		GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::Levels); | ||||||
| } | } | ||||||
| #pragma endregion Actor | #pragma endregion Actor | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ public: | |||||||
|  |  | ||||||
| #pragma region GameFramework | #pragma region GameFramework | ||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) | 	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) | ||||||
| 	bool bOverrideGameplayFrameworkReady = false; | 	bool bOverrideGameFrameworkReady = false; | ||||||
|  |  | ||||||
| 	UFUNCTION() | 	UFUNCTION() | ||||||
| 	void OnGameFrameworkInitialized(); | 	void OnGameFrameworkInitialized(); | ||||||
|   | |||||||
| @@ -1,18 +1,26 @@ | |||||||
| #include "GasaPlayerController.h" | #include "GasaPlayerController.h" | ||||||
| #include "GasaPlayerController_Inlines.h" | #include "GasaPlayerController_Inlines.h" | ||||||
|  | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
|  |  | ||||||
| #include "AbilitySystemComponent.h" | #include "AbilitySystemComponent.h" | ||||||
| #include "Engine/LocalPlayer.h" | #include "Engine/LocalPlayer.h" | ||||||
| #include "EnhancedInputComponent.h" | #include "EnhancedInputComponent.h" | ||||||
| #include "EnhancedInputSubsystems.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 "GasaDevOptions.h" | ||||||
|  | #include "GasaGameInstance.h" | ||||||
|  | #include "GasaGameState.h" | ||||||
| #include "GasaPlayerState.h" | #include "GasaPlayerState.h" | ||||||
| #include "Actors/CameraMount.h" | #include "Actors/CameraMount.h" | ||||||
| #include "Camera/CameraComponent.h" | #include "UI/GasaHUD.h" | ||||||
| #include "Characters/GasaCharacter.h" | #include "UI/WidgetController.h" | ||||||
| #include "Components/CapsuleComponent.h" |  | ||||||
| #include "GameFramework/SpringArmComponent.h" |  | ||||||
| #include "Kismet/KismetSystemLibrary.h" |  | ||||||
| using namespace Gasa; | using namespace Gasa; | ||||||
|  |  | ||||||
| AGasaPlayerController::AGasaPlayerController() | AGasaPlayerController::AGasaPlayerController() | ||||||
| @@ -24,7 +32,143 @@ AGasaPlayerController::AGasaPlayerController() | |||||||
| 	bReplicates = true; | 	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 | #pragma region Input | ||||||
| void AGasaPlayerController::Move(FInputActionValue const& ActionValue) | void AGasaPlayerController::Move(FInputActionValue const& ActionValue) | ||||||
| @@ -72,29 +216,109 @@ void AGasaPlayerController::Move(FInputActionValue const& ActionValue) | |||||||
| #pragma endregion Input | #pragma endregion Input | ||||||
|  |  | ||||||
| #pragma region PlayerController | #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... | // TODO(Ed): We need to setup Net Slime... | ||||||
| void AGasaPlayerController::OnPossess(APawn* InPawn) | void AGasaPlayerController::OnPossess(APawn* PawnPossesed) | ||||||
| { | { | ||||||
| 	Super::OnPossess(InPawn); | 	// Super::OnPossess(PawnPossesed); | ||||||
|  |  | ||||||
| 	Cam->AttachToActor(InPawn, FAttachmentTransformRules::KeepRelativeTransform); |  | ||||||
|  |  | ||||||
| 	AGasaPlayerState* PS      = GetPlayerState(); |  | ||||||
| 	AGasaCharacter* character = Cast<AGasaCharacter>(InPawn); |  | ||||||
| 	// Net Owner setup ability system |  | ||||||
| 	if (0) |  | ||||||
| 	{ | 	{ | ||||||
| 		character->AbilitySystem = PS->AbilitySystem; | 		if (PawnPossesed && (PlayerState == NULL || !PlayerState->IsOnlyASpectator()) ) | ||||||
| 		character->Attributes    = PS->Attributes; | 		{ | ||||||
| 		character->AbilitySystem->InitAbilityActorInfo(PS, character); | 			// ====================================================================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() | void AGasaPlayerController::OnUnPossess() | ||||||
| { | { | ||||||
| 	Super::OnUnPossess(); | 	Super::OnUnPossess(); | ||||||
| @@ -138,6 +362,11 @@ void AGasaPlayerController::PlayerTick(float DeltaTime) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void AGasaPlayerController::PostSeamlessTravel() | ||||||
|  | { | ||||||
|  | 	Super::PostSeamlessTravel(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void AGasaPlayerController::SetupInputComponent() | void AGasaPlayerController::SetupInputComponent() | ||||||
| { | { | ||||||
| 	Super::SetupInputComponent(); | 	Super::SetupInputComponent(); | ||||||
| @@ -148,12 +377,22 @@ void AGasaPlayerController::SetupInputComponent() | |||||||
| 		EIC->BindAction(IA_Move, ETriggerEvent::Triggered, this, &ThisClass::Move);	 | 		EIC->BindAction(IA_Move, ETriggerEvent::Triggered, this, &ThisClass::Move);	 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void AGasaPlayerController::SpawnDefaultHUD() | ||||||
|  | { | ||||||
|  | 	Super::SpawnDefaultHUD(); | ||||||
|  | } | ||||||
| #pragma endregion PlayerController | #pragma endregion PlayerController | ||||||
|  |  | ||||||
| #pragma region Actor | #pragma region Actor | ||||||
| void AGasaPlayerController::BeginPlay() | void AGasaPlayerController::BeginPlay() | ||||||
| { | { | ||||||
| 	Super::BeginPlay(); | 	Super::BeginPlay(); | ||||||
|  | 	NetLog("BeginPlay"); | ||||||
|  |  | ||||||
|  | 	UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>(); | ||||||
|  | 	GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & AGasaPlayerController::OnGameFrameworkInitialized); | ||||||
|  | 	GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::PlayerController); | ||||||
|  |  | ||||||
| 	if (IsLocalController()) | 	if (IsLocalController()) | ||||||
| 	{ | 	{ | ||||||
| @@ -209,4 +448,11 @@ void AGasaPlayerController::Tick(float DeltaSeconds) | |||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void AGasaPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const | ||||||
|  | { | ||||||
|  | 	Super::GetLifetimeReplicatedProps(OutLifetimeProps); | ||||||
|  |  | ||||||
|  | 	DOREPLIFETIME(AGasaPlayerController, bNetOwner_GameFrameworkInitialized); | ||||||
|  | } | ||||||
| #pragma endregion Actor | #pragma endregion Actor | ||||||
|   | |||||||
| @@ -1,17 +1,26 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "GasaCommon.h" | #include "GasaCommon.h" | ||||||
|  | #include "GasaPlayerState.h" | ||||||
|  | #include "Networking/GasaNetLibrary.h" | ||||||
| #include "Engine/Engine.h" | #include "Engine/Engine.h" | ||||||
| #include "GameFramework/PlayerController.h" | #include "GameFramework/PlayerController.h" | ||||||
| #include "Networking/GasaNetLibrary.h" |  | ||||||
|  |  | ||||||
| #include "GasaPlayerController.generated.h" | #include "GasaPlayerController.generated.h" | ||||||
|  |  | ||||||
|  | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGasaPlayerControllerSig, AGasaPlayerController*, PC); | ||||||
|  |  | ||||||
| UCLASS(Blueprintable) | UCLASS(Blueprintable) | ||||||
| class GASA_API AGasaPlayerController : public APlayerController | class GASA_API AGasaPlayerController : public APlayerController | ||||||
| { | { | ||||||
| 	GENERATED_BODY() | 	GENERATED_BODY() | ||||||
|  | protected: | ||||||
|  | 	friend void AGasaPlayerState::ClientInitialize(AController* NewOwner); | ||||||
| public: | public: | ||||||
|  |  | ||||||
|  | 	UFUNCTION() | ||||||
|  | 	void OnSeamlessTravelStart(); | ||||||
|  | 	 | ||||||
| #pragma region Camera | #pragma region Camera | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite) | 	UPROPERTY(EditAnywhere, BlueprintReadWrite) | ||||||
| 	TObjectPtr<ACameraMount> Cam; | 	TObjectPtr<ACameraMount> Cam; | ||||||
| @@ -33,6 +42,55 @@ public: | |||||||
| 	FORCEINLINE void Dehighlight() { SetHighlight(EHighlight::Disabled); }; | 	FORCEINLINE void Dehighlight() { SetHighlight(EHighlight::Disabled); }; | ||||||
| #pragma endregion Highlighting | #pragma endregion Highlighting | ||||||
| #endif | #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 | #pragma region Input | ||||||
| 	UPROPERTY(VisibleAnywhere, BlueprintReadOnly) | 	UPROPERTY(VisibleAnywhere, BlueprintReadOnly) | ||||||
| @@ -50,10 +108,6 @@ public: | |||||||
| 	void Move(FInputActionValue const& ActionValue); | 	void Move(FInputActionValue const& ActionValue); | ||||||
| #pragma endregion Input | #pragma endregion Input | ||||||
| 	 | 	 | ||||||
| 	AGasaPlayerController(); |  | ||||||
|  |  | ||||||
| 	inline AGasaPlayerState* GetPlayerState(); |  | ||||||
|  |  | ||||||
| #pragma region NetSlime | #pragma region NetSlime | ||||||
| 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | ||||||
| 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | ||||||
| @@ -76,24 +130,35 @@ public: | |||||||
| 	} | 	} | ||||||
| #pragma endregion NetSlime | #pragma endregion NetSlime | ||||||
| 	 | 	 | ||||||
|  | 	AGasaPlayerController(); | ||||||
|  |  | ||||||
|  | 	inline AGasaPlayerState* GetPlayerState(); | ||||||
|  | 	 | ||||||
| #pragma region PlayerController | #pragma region PlayerController | ||||||
| 	void SpawnDefaultHUD() override; | 	bool CanRestartPlayer() override; | ||||||
| 	 | 	void ClientSetHUD_Implementation(TSubclassOf<AHUD> NewHUDClass) override; | ||||||
| 	void OnPossess(APawn* InPawn) override; | 	void ClientUpdateLevelStreamingStatus_Implementation(FName PackageName, bool bNewShouldBeLoaded, bool bNewShouldBeVisible, bool bNewShouldBlockOnLoad, int32 LODIndex, FNetLevelVisibilityTransactionId TransactionId, bool bNewShouldBlockOnUnload) override; | ||||||
| 	void OnUnPossess() override; |  | ||||||
| 	 |  | ||||||
| 	void PlayerTick(float DeltaTime) override; | 	void PlayerTick(float DeltaTime) override; | ||||||
| 	 | 	void PostSeamlessTravel() override; | ||||||
| 	void SetupInputComponent() override; | 	void SetupInputComponent() override; | ||||||
|  | 	void SpawnDefaultHUD() override; | ||||||
| #pragma endregion PlayerController | #pragma endregion PlayerController | ||||||
|  |  | ||||||
|  | #pragma region Controller | ||||||
|  | 	void OnPossess(APawn* InPawn) override; | ||||||
|  | 	void OnRep_Pawn() override; | ||||||
|  | 	void OnUnPossess() override; | ||||||
|  | #pragma endregion Controller | ||||||
|  |  | ||||||
| #pragma region Actor | #pragma region Actor | ||||||
| 	void BeginPlay() override; | 	void BeginPlay() override; | ||||||
|  |  | ||||||
| 	void PostInitializeComponents() override; | 	void PostInitializeComponents() override; | ||||||
|  |  | ||||||
| 	void Tick(float DeltaSeconds) override; | 	void Tick(float DeltaSeconds) override; | ||||||
| #pragma endregion Actor | #pragma endregion Actor | ||||||
|  |  | ||||||
|  | #pragma region UObject | ||||||
|  | 	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; | ||||||
|  | #pragma endregion UObject | ||||||
| }; | }; | ||||||
|  |  | ||||||
| namespace Gasa | namespace Gasa | ||||||
|   | |||||||
| @@ -1,5 +1,8 @@ | |||||||
| #include "GasaPlayerState.h" | #include "GasaPlayerState.h" | ||||||
|  |  | ||||||
|  | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
|  | #include "GasaGameInstance.h" | ||||||
|  | #include "GasaPlayerController.h" | ||||||
| #include "AbilitySystem/GasaAbilitySystemComponent.h" | #include "AbilitySystem/GasaAbilitySystemComponent.h" | ||||||
| #include "AbilitySystem/GasaAttributeSet.h" | #include "AbilitySystem/GasaAttributeSet.h" | ||||||
|  |  | ||||||
| @@ -16,3 +19,74 @@ AGasaPlayerState::AGasaPlayerState() | |||||||
| 	// Replication | 	// Replication | ||||||
| 	NetUpdateFrequency = 100.f; | 	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() | 	GENERATED_BODY() | ||||||
| public: | public: | ||||||
|  | 	AGasaPlayerState(); | ||||||
|  | 	 | ||||||
| #pragma region Ability System | #pragma region Ability System | ||||||
| 	UPROPERTY(EditAnywhere, Category="Ability System") | 	UPROPERTY(EditAnywhere, Category="Ability System") | ||||||
| 	bool bAutoAbilitySystem; | 	bool bAutoAbilitySystem; | ||||||
| @@ -25,9 +27,31 @@ public: | |||||||
| 	UPROPERTY(EditAnywhere, Category="Ability System") | 	UPROPERTY(EditAnywhere, Category="Ability System") | ||||||
| 	TObjectPtr<UAttributeSet> Attributes; | 	TObjectPtr<UAttributeSet> Attributes; | ||||||
| #pragma endregion Ability System | #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 | #pragma region NetSlime | ||||||
| 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | 	// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp | ||||||
| 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | 	FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); } | ||||||
| @@ -55,7 +79,18 @@ public: | |||||||
| 	FORCEINLINE UAbilitySystemComponent* GetAbilitySystemComponent() const override { return AbilitySystem; } | 	FORCEINLINE UAbilitySystemComponent* GetAbilitySystemComponent() const override { return AbilitySystem; } | ||||||
| #pragma endregion IAbilitySystem | #pragma endregion IAbilitySystem | ||||||
|  |  | ||||||
| // #pragma region | #pragma region PlayerState | ||||||
| // 	 | 	void ClientInitialize(AController* C) override; | ||||||
| // #pragma endregion  | #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 | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -48,6 +48,7 @@ public class Gasa : ModuleRules | |||||||
|             "Core", |             "Core", | ||||||
|              |              | ||||||
|             "AIModule", |             "AIModule", | ||||||
|  |             "CoreOnline", | ||||||
|             "CoreUObject",  |             "CoreUObject",  | ||||||
|             "DeveloperSettings", |             "DeveloperSettings", | ||||||
|             "Engine",  |             "Engine",  | ||||||
|   | |||||||
| @@ -35,8 +35,8 @@ | |||||||
| #include "Game/GasaViewport.h" | #include "Game/GasaViewport.h" | ||||||
|  |  | ||||||
| // Networking | // Networking | ||||||
| // #include "Networking/GasaNetLibrary.h" | #include "Networking/GasaNetLibrary.h" | ||||||
| // #include "Networking/GasaNetLibrary_Inlines.h" | #include "Networking/GasaNetLibrary_Inlines.h" | ||||||
|  |  | ||||||
| // UI | // UI | ||||||
| // #include "UI/GasaCanvas.h" | // #include "UI/GasaCanvas.h" | ||||||
|   | |||||||
| @@ -2,6 +2,8 @@ | |||||||
|  |  | ||||||
| #include "GasaEngineMinimal.h" | #include "GasaEngineMinimal.h" | ||||||
|  |  | ||||||
|  | #include "GasaCommon.generated.h" | ||||||
|  |  | ||||||
| #define global         | #define global         | ||||||
| #define internal      static | #define internal      static | ||||||
| #define local_persist static | #define local_persist static | ||||||
| @@ -18,14 +20,19 @@ | |||||||
| #pragma region Engine Forwards | #pragma region Engine Forwards | ||||||
| struct FInputActionValue; | struct FInputActionValue; | ||||||
| struct FOnAttributeChangeData; | struct FOnAttributeChangeData; | ||||||
|  | struct FReplicationFlags; | ||||||
|  |  | ||||||
| class AActor; | class AActor; | ||||||
|  | class APawn; | ||||||
| class APostProcessVolume; | class APostProcessVolume; | ||||||
|  |  | ||||||
|  | class FOutBunch; | ||||||
|  |  | ||||||
| class IAbilitySystemInterface; | class IAbilitySystemInterface; | ||||||
|  |  | ||||||
| class UAbilitySystemComponent; | class UAbilitySystemComponent; | ||||||
| class UAbilitySystemInterface; | class UAbilitySystemInterface; | ||||||
|  | class UActorChannel; | ||||||
| class UAttributeSet; | class UAttributeSet; | ||||||
| class UCameraComponent; | class UCameraComponent; | ||||||
| class UGameplayEffect; | class UGameplayEffect; | ||||||
| @@ -189,3 +196,12 @@ namespace Gasa | |||||||
| 	constexpr float _480Hz = .002f; | 	constexpr float _480Hz = .002f; | ||||||
| } | } | ||||||
| #pragma endregion Timing | #pragma endregion Timing | ||||||
|  |  | ||||||
|  | #pragma region Delegates | ||||||
|  | DECLARE_MULTICAST_DELEGATE(FOnTravelDelegate); | ||||||
|  | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnTravelSig); | ||||||
|  | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnPawnSig); | ||||||
|  | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerCharacterReadySig, APlayerCharacter*, Character); | ||||||
|  | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPawnReadySig, APawn*, Pawn); | ||||||
|  | #pragma endregion Delegates | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,140 +21,5 @@ | |||||||
| #include "Misc/VarArgs.h" | #include "Misc/VarArgs.h" | ||||||
| #include "Logging/LogVerbosity.h" | #include "Logging/LogVerbosity.h" | ||||||
| #include "UObject/ObjectMacros.h" | #include "UObject/ObjectMacros.h" | ||||||
|  | #include "Delegates/Delegate.h" | ||||||
| // #include "Misc/OutputDevice.h" | #include "Delegates/DelegateCombinations.h" | ||||||
| // #include "HAL/PlatformCrt.h" |  | ||||||
| // #include "HAL/PlatformMisc.h" |  | ||||||
| // #include "Misc/AssertionMacros.h" |  | ||||||
| // #include "Templates/IsPointer.h" |  | ||||||
| // #include "HAL/PlatformMemory.h" |  | ||||||
| // #include "HAL/PlatformAtomics.h" |  | ||||||
| // #include "Misc/Exec.h" |  | ||||||
| // #include "HAL/MemoryBase.h" |  | ||||||
| // #include "HAL/UnrealMemory.h" |  | ||||||
| // #include "Templates/IsArithmetic.h" |  | ||||||
| // #include "Templates/AndOrNot.h" |  | ||||||
| // #include "Templates/IsPODType.h" |  | ||||||
| // #include "Templates/IsUECoreType.h" |  | ||||||
| // #include "Templates/IsTriviallyCopyConstructible.h" |  | ||||||
| // #include "Templates/UnrealTypeTraits.h" |  | ||||||
| // #include "Templates/EnableIf.h" |  | ||||||
| // #include "Templates/RemoveReference.h" |  | ||||||
| // #include "Templates/IntegralConstant.h" |  | ||||||
| // #include "Templates/IsClass.h" |  | ||||||
| // #include "Templates/TypeCompatibleBytes.h" |  | ||||||
| // #include "Traits/IsContiguousContainer.h" |  | ||||||
| // #include "Templates/UnrealTemplate.h" |  | ||||||
| // #include "Math/NumericLimits.h" |  | ||||||
| // #include "HAL/PlatformMath.h" |  | ||||||
| // #include "Templates/IsTriviallyCopyAssignable.h" |  | ||||||
| // #include "Templates/IsTriviallyDestructible.h" |  | ||||||
| // #include "Templates/MemoryOps.h" |  | ||||||
| // #include "Containers/ContainerAllocationPolicies.h" |  | ||||||
| // #include "Templates/IsEnumClass.h" |  | ||||||
| // #include "HAL/PlatformProperties.h" |  | ||||||
| // #include "Misc/EngineVersionBase.h" |  | ||||||
| // #include "Internationalization/TextNamespaceFwd.h" |  | ||||||
| // #include "Serialization/Archive.h" |  | ||||||
| // #include "Templates/Less.h" |  | ||||||
| // #include "Templates/Sorting.h" |  | ||||||
| // #include "Misc/Char.h" |  | ||||||
| // #include "GenericPlatform/GenericPlatformStricmp.h" |  | ||||||
| // #include "GenericPlatform/GenericPlatformString.h" |  | ||||||
| // #include "HAL/PlatformString.h" |  | ||||||
| // #include "Misc/CString.h" |  | ||||||
| // #include "Misc/Crc.h" |  | ||||||
| // #include "Math/UnrealMathUtility.h" |  | ||||||
| // #include "Containers/UnrealString.h" |  | ||||||
| // #include "Containers/Array.h" |  | ||||||
| // #include "Misc/FrameNumber.h" |  | ||||||
| // #include "Misc/Timespan.h" |  | ||||||
| // #include "Containers/StringConv.h" |  | ||||||
| // #include "UObject/UnrealNames.h" |  | ||||||
| // #include "UObject/NameTypes.h" |  | ||||||
| // #include "Misc/Parse.h" |  | ||||||
| // #include "Templates/AlignmentTemplates.h" |  | ||||||
| // #include "Misc/StructBuilder.h" |  | ||||||
| // #include "Templates/Decay.h" |  | ||||||
| // #include "Templates/PointerIsConvertibleFromTo.h" |  | ||||||
| // #include "Templates/Invoke.h" |  | ||||||
| // #include "Templates/Function.h" |  | ||||||
| // #include "Templates/TypeHash.h" |  | ||||||
|  |  | ||||||
| // #include "Containers/ScriptArray.h" |  | ||||||
| // #include "Containers/BitArray.h" |  | ||||||
| // #include "Containers/SparseArray.h" |  | ||||||
| // #include "Containers/Set.h" |  | ||||||
|  |  | ||||||
| // #include "Algo/Reverse.h" |  | ||||||
| // #include "Containers/Map.h" |  | ||||||
| // #include "Math/IntPoint.h" |  | ||||||
| // #include "Math/IntVector.h" |  | ||||||
|  |  | ||||||
| // #include "Logging/LogCategory.h" |  | ||||||
| // #include "Logging/LogMacros.h" |  | ||||||
|  |  | ||||||
| // #include "Math/Vector2D.h" |  | ||||||
| // #include "Math/IntRect.h" |  | ||||||
| // #include "Misc/ByteSwap.h" |  | ||||||
| // #include "Containers/EnumAsByte.h" |  | ||||||
| // #include "HAL/PlatformTLS.h" |  | ||||||
| // #include "CoreGlobals.h" |  | ||||||
|  |  | ||||||
| // #include "Templates/SharedPointer.h" |  | ||||||
| // #include "Internationalization/CulturePointer.h" |  | ||||||
| // #include "UObject/WeakObjectPtrTemplates.h" |  | ||||||
| // #include "Delegates/DelegateSettings.h" |  | ||||||
| // #include "Delegates/IDelegateInstance.h" |  | ||||||
| // #include "Delegates/DelegateBase.h" |  | ||||||
| // #include "Delegates/MulticastDelegateBase.h" |  | ||||||
| // #include "Delegates/IntegerSequence.h" |  | ||||||
| // #include "Templates/Tuple.h" |  | ||||||
| // #include "UObject/ScriptDelegates.h" |  | ||||||
| // #include "Delegates/Delegate.h" |  | ||||||
| // #include "Internationalization/TextLocalizationManager.h" |  | ||||||
| // #include "Misc/Optional.h" |  | ||||||
| // #include "Templates/IsArray.h" |  | ||||||
| // #include "Templates/RemoveExtent.h" |  | ||||||
| // #include "Templates/UniquePtr.h" |  | ||||||
| // #include "Internationalization/Text.h" |  | ||||||
| // #include "Templates/UniqueObj.h" |  | ||||||
| // #include "Internationalization/Internationalization.h" |  | ||||||
| // #include "Math/Vector.h" |  | ||||||
| // #include "Math/Vector4.h" |  | ||||||
| // #include "Math/VectorRegister.h" |  | ||||||
| // #include "Math/TwoVectors.h" |  | ||||||
| // #include "Math/Edge.h" |  | ||||||
| // #include "UObject/ObjectVersion.h" |  | ||||||
| // #include "Math/CapsuleShape.h" |  | ||||||
| // #include "Math/Rotator.h" |  | ||||||
| // #include "Misc/DateTime.h" |  | ||||||
| // #include "Math/RangeBound.h" |  | ||||||
| // #include "Misc/AutomationEvent.h" |  | ||||||
| // #include "Math/Range.h" |  | ||||||
| // #include "Math/RangeSet.h" |  | ||||||
| // #include "Math/Interval.h" |  | ||||||
| // #include "Math/Box.h" |  | ||||||
| // #include "Math/Box2D.h" |  | ||||||
| // #include "Math/BoxSphereBounds.h" |  | ||||||
| // #include "Math/OrientedBox.h" |  | ||||||
| // #include "Math/Axis.h" |  | ||||||
| // #include "Math/Matrix.h" |  | ||||||
| // #include "Math/RotationTranslationMatrix.h" |  | ||||||
| // #include "Math/RotationAboutPointMatrix.h" |  | ||||||
| // #include "Math/ScaleRotationTranslationMatrix.h" |  | ||||||
| // #include "Math/RotationMatrix.h" |  | ||||||
| // #include "Math/Quat.h" |  | ||||||
| // #include "Math/PerspectiveMatrix.h" |  | ||||||
| // #include "Math/OrthoMatrix.h" |  | ||||||
| // #include "Math/TranslationMatrix.h" |  | ||||||
| // #include "Math/QuatRotationTranslationMatrix.h" |  | ||||||
| // #include "Math/InverseRotationMatrix.h" |  | ||||||
| // #include "Math/ScaleMatrix.h" |  | ||||||
| // #include "Math/MirrorMatrix.h" |  | ||||||
| // #include "Math/ClipProjectionMatrix.h" |  | ||||||
| // #include "Math/Float32.h" |  | ||||||
| // #include "Math/Float16.h" |  | ||||||
| // #include "Math/Transform.h" |  | ||||||
| // #include "Math/ConvexHull2d.h" |  | ||||||
| // #include "Math/UnrealMath.h" |  | ||||||
|   | |||||||
| @@ -1,67 +1,94 @@ | |||||||
| #include "GasaNetLibrary.h" | #include "GasaNetLibrary.h" | ||||||
| #include "GasaNetLibrary_Inlines.h" | #include "GasaNetLibrary_Inlines.h" | ||||||
|  | #include "GasaObject.h" | ||||||
|  |  | ||||||
|  | #include "Kismet/KismetMathLibrary.h" | ||||||
|  | #include "Kismet/KismetSystemLibrary.h" | ||||||
|  |  | ||||||
| DEFINE_LOG_CATEGORY(LogGasaNet); | DEFINE_LOG_CATEGORY(LogGasaNet); | ||||||
|  |  | ||||||
| void NetLog( UObject const* Context, FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log | namespace Gasa | ||||||
| 		, FLogCategoryBase& Category  = LogGasaNet |  | ||||||
| 		, bool              DumpStack = false |  | ||||||
| 		, int32             Line      = __builtin_LINE() |  | ||||||
| 		, const ANSICHAR*   File      = __builtin_FILE() |  | ||||||
| 		, const ANSICHAR*   Func      = __builtin_FUNCTION() ) |  | ||||||
| { | { | ||||||
| #if !UE_BUILD_SHIPPING && !NO_LOGGING | 	void DrawNetCullingSphere(const UObject* Context, float Duration, float Thickness) | ||||||
| 	ELogVerbosity::Type EngineVerbosity = (ELogVerbosity::Type) Verbosity; |  | ||||||
| 	if ((EngineVerbosity & ELogVerbosity::VerbosityMask) > ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY) |  | ||||||
| 		return; |  | ||||||
| 	if ((EngineVerbosity & ELogVerbosity::VerbosityMask) > Category.GetVerbosity()) |  | ||||||
| 		return; |  | ||||||
| 	if ( Category.IsSuppressed(EngineVerbosity)) |  | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	AActor const* Actor = nullptr; |  | ||||||
| 	FString       ActorLevel; |  | ||||||
| 	{ | 	{ | ||||||
| 		if (Context != nullptr) | 		const AActor* actor = nullptr; | ||||||
| 		{ | 	 | ||||||
| 			if (Context->GetClass()->IsChildOf(AActor::StaticClass())) | 		if (Context->IsA(UGasaObject::StaticClass())) | ||||||
| 				Actor = Cast<AActor>(Context); | 			actor = Cast<AActor>(Context->GetOuter()); | ||||||
| 			else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | 		 | ||||||
| 				Actor = Cast<UActorComponent>(Context)->GetOwner(); | 		else if (Context->IsA(AActor::StaticClass())) | ||||||
| 			// Its assumed that all GasaObjects have an outer actor | 			actor = Cast<AActor>(Context);	 | ||||||
| 			else if (Context->IsA(UGasaObject::StaticClass())) |  | ||||||
| 				Actor = Cast<AActor>(Context->GetOuter()); | 		if (actor) | ||||||
| 		} | 			UKismetSystemLibrary::DrawDebugSphere(actor | ||||||
| 		if (Actor) | 				, actor->GetActorLocation() | ||||||
| 		{ | 				, UKismetMathLibrary::Sqrt(actor->NetCullDistanceSquared) * 2 | ||||||
| 			if (Actor->HasLocalNetOwner()) | 				, 12 | ||||||
| 				ActorLevel = TEXT("Net Owner"); | 				, FLinearColor(FColor::Emerald) | ||||||
| 			 | 				, Duration | ||||||
| 			else if (Actor->HasAuthority()) | 				, Thickness); | ||||||
| 				ActorLevel = TEXT("Server Authorized"); |  | ||||||
| 				 |  | ||||||
| 			else |  | ||||||
| 				ActorLevel = TEXT("No Authority"); |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 			ActorLevel = TEXT("Local"); |  | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
|  | 	void NetLog( UObject const* Context, FString Message, EGasaVerbosity Verbosity | ||||||
|  | 			, FLogCategoryBase& Category | ||||||
|  | 			, bool              DumpStack | ||||||
|  | 			, int32             Line | ||||||
|  | 			, const ANSICHAR*   File | ||||||
|  | 			, const ANSICHAR*   Func ) | ||||||
|  | 	{ | ||||||
|  | #if !UE_BUILD_SHIPPING && !NO_LOGGING | ||||||
|  | 		ELogVerbosity::Type EngineVerbosity = (ELogVerbosity::Type) Verbosity; | ||||||
|  | 		if ((EngineVerbosity & ELogVerbosity::VerbosityMask) > ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY) | ||||||
|  | 			return; | ||||||
|  | 		if ((EngineVerbosity & ELogVerbosity::VerbosityMask) > Category.GetVerbosity()) | ||||||
|  | 			return; | ||||||
|  | 		if ( Category.IsSuppressed(EngineVerbosity)) | ||||||
|  | 			return; | ||||||
|  |  | ||||||
| 	FString NetMode = FString::Printf(TEXT("%-16s"), * GetNetworkModeStr(Context)); | 		AActor const* Actor = nullptr; | ||||||
| 	ActorLevel      = FString::Printf(TEXT("%-18s"), * ActorLevel); | 		FString       ActorLevel; | ||||||
| 	FString Name    = FString::Printf(TEXT("%-40s"), * Context->GetName()); | 		{ | ||||||
| 	FString FullMsg = NetMode + " " + ActorLevel + " " + Name + " : " + Message; | 			if (Context != nullptr) | ||||||
| 	 | 			{ | ||||||
| 	static UE::Logging::Private::FStaticBasicLogDynamicData LOG_Dynamic; | 				if (Context->GetClass()->IsChildOf(AActor::StaticClass())) | ||||||
| 	static UE::Logging::Private::FStaticBasicLogRecord | 					Actor = Cast<AActor>(Context); | ||||||
| 	LOG_Static(TEXT("%s -- %hs %hs(%d)"), File, Line, EngineVerbosity, LOG_Dynamic); | 				else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | ||||||
|  | 					Actor = Cast<UActorComponent>(Context)->GetOwner(); | ||||||
|  | 				// Its assumed that all GasaObjects have an outer actor | ||||||
|  | 				else if (Context->IsA(UGasaObject::StaticClass())) | ||||||
|  | 					Actor = Cast<AActor>(Context->GetOuter()); | ||||||
|  | 			} | ||||||
|  | 			if (Actor) | ||||||
|  | 			{ | ||||||
|  | 				if (Actor->HasLocalNetOwner()) | ||||||
|  | 					ActorLevel = TEXT("Net Owner"); | ||||||
|  | 			 | ||||||
|  | 				else if (Actor->HasAuthority()) | ||||||
|  | 					ActorLevel = TEXT("Server Authorized"); | ||||||
|  | 				 | ||||||
|  | 				else | ||||||
|  | 					ActorLevel = TEXT("No Authority"); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 				ActorLevel = TEXT("Local"); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 	SET_WARN_COLOR(COLOR_PURPLE) | 		FString NetMode = FString::Printf(TEXT("%-16s"), * GetNetworkModeStr(Context)); | ||||||
|  | 		ActorLevel      = FString::Printf(TEXT("%-18s"), * ActorLevel); | ||||||
|  | 		FString Name    = FString::Printf(TEXT("%-40s"), * Context->GetName()); | ||||||
|  | 		FString FullMsg = NetMode + " " + ActorLevel + " " + Name + " : " + Message; | ||||||
| 	 | 	 | ||||||
| 	if (DumpStack) | 		static UE::Logging::Private::FStaticBasicLogDynamicData LOG_Dynamic; | ||||||
| 		FDebug::DumpStackTraceToLog(EngineVerbosity); | 		static UE::Logging::Private::FStaticBasicLogRecord | ||||||
| 	BasicLog(Category, &LOG_Static, * FullMsg, File, Func, Line); | 		LOG_Static(TEXT("%s -- %hs %hs(%d)"), File, Line, EngineVerbosity, LOG_Dynamic); | ||||||
|  |  | ||||||
|  | 		// SET_WARN_COLOR(COLOR_PURPLE) | ||||||
| 	 | 	 | ||||||
| 	CLEAR_WARN_COLOR() | 		if (DumpStack) | ||||||
| #endif | 			FDebug::DumpStackTraceToLog(EngineVerbosity); | ||||||
| } | 		BasicLog(Category, &LOG_Static, * FullMsg, File, Func, Line); | ||||||
|  | 	 | ||||||
|  | 		// CLEAR_WARN_COLOR() | ||||||
|  | 	#endif | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -8,6 +8,34 @@ | |||||||
|  |  | ||||||
| DECLARE_LOG_CATEGORY_EXTERN(LogGasaNet, Log, All); | DECLARE_LOG_CATEGORY_EXTERN(LogGasaNet, Log, All); | ||||||
|  |  | ||||||
|  | #define NullGuard( Object_, Logger_, Message_ )		\ | ||||||
|  | do {												\ | ||||||
|  | 	if ( ! IsValid(Object_) )						\ | ||||||
|  | 	{												\ | ||||||
|  | 		Logger_( (Message_) , ELogV::Error );		\ | ||||||
|  | 		ensure( IsValid(Object_) );				    \ | ||||||
|  | 		return;										\ | ||||||
|  | 	}												\ | ||||||
|  | } while (0) | ||||||
|  |  | ||||||
|  | #define NetGuard( Condition_, Logger_, Message_ )	\ | ||||||
|  | do {												\ | ||||||
|  | 	if ( Condition_ )								\ | ||||||
|  | 	{												\ | ||||||
|  | 		Logger_( (Message_) , ELogV::Error );		\ | ||||||
|  | 		ensure( Condition_ );						\ | ||||||
|  | 		return;										\ | ||||||
|  | 	}												\ | ||||||
|  | } while (0) | ||||||
|  |  | ||||||
|  | #if UE_BUILD_DEVELOPMENT | ||||||
|  | #			define NullGuard_DEV	NullGuard | ||||||
|  | #			define NetGuard_DEV		NetGuard | ||||||
|  | #else | ||||||
|  | #			define NullGuard_DEV( Object_, Logger_, Message_) | ||||||
|  | #			define NetGuard_DEV( Object_, Logger_, Message_) | ||||||
|  | #endif | ||||||
|  |  | ||||||
| UENUM(BlueprintType) | UENUM(BlueprintType) | ||||||
| enum class ENetworkMode : uint8 | enum class ENetworkMode : uint8 | ||||||
| { | { | ||||||
| @@ -39,13 +67,11 @@ namespace Gasa | |||||||
| 	bool IsListenServer(UObject const* Context); | 	bool IsListenServer(UObject const* Context); | ||||||
|  |  | ||||||
| 	bool IsNetOwner(UObject const* Context); | 	bool IsNetOwner(UObject const* Context); | ||||||
| 	bool IsNetOwner(UGasaObject const* Context); |  | ||||||
| 	bool IsNetOwner(AActor const* Context); | 	bool IsNetOwner(AActor const* Context); | ||||||
|  |  | ||||||
| 	bool IsServer(UObject const* Context); | 	bool IsServer(UObject const* Context); | ||||||
| 	 | 	 | ||||||
| 	bool IsSimulatedProxy(UObject const* Context); | 	bool IsSimulatedProxy(UObject const* Context); | ||||||
| 	bool IsSimulatedProxy(UGasaObject const* Context); |  | ||||||
| 	bool IsSimulatedProxy(AActor const* Context); | 	bool IsSimulatedProxy(AActor const* Context); | ||||||
| 	 | 	 | ||||||
| 	void NetLog( UObject const* Context, FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log | 	void NetLog( UObject const* Context, FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log | ||||||
| @@ -56,6 +82,7 @@ namespace Gasa | |||||||
| 		, const ANSICHAR*   Func      = __builtin_FUNCTION() ); | 		, const ANSICHAR*   Func      = __builtin_FUNCTION() ); | ||||||
| 	 | 	 | ||||||
| 	bool ServerAuthorized(UObject const* Context); | 	bool ServerAuthorized(UObject const* Context); | ||||||
| 	bool ServerAuthorized(UGasaObject const* Context); |  | ||||||
| 	bool ServerAuthorized(AActor const* Context); | 	bool ServerAuthorized(AActor const* Context); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #include "GasaNetLibrary_Inlines.h" | ||||||
|   | |||||||
| @@ -1,35 +1,12 @@ | |||||||
| #include "GasaNetLibrary.h" | #pragma once | ||||||
| #include "GasaObject.h" | #include "GasaNetLibrary.h" | ||||||
| #include "Engine/NetDriver.h" | #include "Engine/NetDriver.h" | ||||||
| #include "Game/GasaGameMode.h" | #include "Engine/World.h" | ||||||
| #include "Kismet/KismetMathLibrary.h" |  | ||||||
| #include "Kismet/KismetSystemLibrary.h" |  | ||||||
|  |  | ||||||
| namespace Gasa | namespace Gasa | ||||||
| { | { | ||||||
| 	// TODO(Ed): Profile these... | 	// TODO(Ed): Profile these... | ||||||
|  |  | ||||||
| 	inline |  | ||||||
| 	void DrawNetCullingSphere(const UObject* Context, float Duration, float Thickness) |  | ||||||
| 	{ |  | ||||||
| 		const AActor* actor = nullptr; |  | ||||||
| 	 |  | ||||||
| 		if (Context->IsA(UGasaObject::StaticClass())) |  | ||||||
| 			actor = Cast<AActor>(Context->GetOuter()); |  | ||||||
| 		 |  | ||||||
| 		else if (Context->IsA(AActor::StaticClass())) |  | ||||||
| 			actor = Cast<AActor>(Context);	 |  | ||||||
|  |  | ||||||
| 		if (actor) |  | ||||||
| 			UKismetSystemLibrary::DrawDebugSphere(actor |  | ||||||
| 				, actor->GetActorLocation() |  | ||||||
| 				, UKismetMathLibrary::Sqrt(actor->NetCullDistanceSquared) * 2 |  | ||||||
| 				, 12 |  | ||||||
| 				, FLinearColor(FColor::Emerald) |  | ||||||
| 				, Duration |  | ||||||
| 				, Thickness); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	inline | 	inline | ||||||
| 	ENetworkMode GetNetworkMode(UObject const* Context) | 	ENetworkMode GetNetworkMode(UObject const* Context) | ||||||
| 	{ | 	{ | ||||||
| @@ -110,8 +87,6 @@ namespace Gasa | |||||||
| 		else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | 		else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | ||||||
| 			Actor = Cast<UActorComponent>(Context)->GetOwner(); | 			Actor = Cast<UActorComponent>(Context)->GetOwner(); | ||||||
| 		// Its assumed that all GasaObjects have an outer actor | 		// Its assumed that all GasaObjects have an outer actor | ||||||
| 		else if (Context->IsA(UGasaObject::StaticClass())) |  | ||||||
| 			Actor = Cast<AActor>(Context->GetOuter()); |  | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			UObject const* Outermost = Context->GetOutermostObject(); | 			UObject const* Outermost = Context->GetOutermostObject(); | ||||||
| @@ -127,23 +102,7 @@ namespace Gasa | |||||||
| 		bool Result = Actor->HasLocalNetOwner(); | 		bool Result = Actor->HasLocalNetOwner(); | ||||||
| 		return Result; | 		return Result; | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
| 	inline |  | ||||||
| 	bool IsNetOwner(UGasaObject const* Context) |  | ||||||
| 	{ |  | ||||||
| 		if (Context == nullptr || Context->GetWorld() == nullptr) |  | ||||||
| 			return false; |  | ||||||
|  |  | ||||||
| 		AActor const* Actor = Cast<AActor>(Context->GetOuter()); |  | ||||||
| 		if (Actor == nullptr) |  | ||||||
| 		{ |  | ||||||
| 			Log("Could not get actor reference", ELogV::Warning, LogGasaNet); |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		bool Result = Actor->HasLocalNetOwner(); |  | ||||||
| 		return Result;	 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	inline | 	inline | ||||||
| 	bool IsNetOwner(AActor const* Actor) | 	bool IsNetOwner(AActor const* Actor) | ||||||
| 	{ | 	{ | ||||||
| @@ -177,8 +136,6 @@ namespace Gasa | |||||||
| 		else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | 		else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | ||||||
| 			Actor = Cast<UActorComponent>(Context)->GetOwner(); | 			Actor = Cast<UActorComponent>(Context)->GetOwner(); | ||||||
| 		// Its assumed that all GasaObjects have an outer actor | 		// Its assumed that all GasaObjects have an outer actor | ||||||
| 		else if (Context->IsA(UGasaObject::StaticClass())) |  | ||||||
| 			Actor = Cast<AActor>(Context->GetOuter()); |  | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			UObject const* Outermost = Context->GetOutermostObject(); | 			UObject const* Outermost = Context->GetOutermostObject(); | ||||||
| @@ -194,22 +151,6 @@ namespace Gasa | |||||||
| 		bool Result = Actor->GetLocalRole() == ENetRole::ROLE_SimulatedProxy; | 		bool Result = Actor->GetLocalRole() == ENetRole::ROLE_SimulatedProxy; | ||||||
| 		return Result;	 | 		return Result;	 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	inline |  | ||||||
| 	bool IsSimulatedProxy(UGasaObject const* Context) |  | ||||||
| 	{ |  | ||||||
| 		if (Context == nullptr || Context->GetWorld() == nullptr) |  | ||||||
| 			return false; |  | ||||||
|  |  | ||||||
| 		AActor const* Actor = Cast<AActor>(Context->GetOuter()); |  | ||||||
| 		if (Actor == nullptr) |  | ||||||
| 		{ |  | ||||||
| 			Log("Could not get actor reference", ELogV::Warning, LogGasaNet); |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		bool Result = Actor->GetLocalRole() == ENetRole::ROLE_SimulatedProxy; |  | ||||||
| 		return Result;	 |  | ||||||
| 	} |  | ||||||
| 	 | 	 | ||||||
| 	inline | 	inline | ||||||
| 	bool IsSimulatedProxy(AActor const* Actor) | 	bool IsSimulatedProxy(AActor const* Actor) | ||||||
| @@ -233,8 +174,6 @@ namespace Gasa | |||||||
| 		else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | 		else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass())) | ||||||
| 			Actor = Cast<UActorComponent>(Context)->GetOwner(); | 			Actor = Cast<UActorComponent>(Context)->GetOwner(); | ||||||
| 		// Its assumed that all GasaObjects have an outer actor | 		// Its assumed that all GasaObjects have an outer actor | ||||||
| 		else if (Context->IsA(UGasaObject::StaticClass())) |  | ||||||
| 			Actor = Cast<AActor>(Context->GetOuter()); |  | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			UObject const* Outermost = Context->GetOutermostObject(); | 			UObject const* Outermost = Context->GetOutermostObject(); | ||||||
| @@ -251,22 +190,6 @@ namespace Gasa | |||||||
| 		return Result; | 		return Result; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	inline |  | ||||||
| 	bool ServerAuthorized(UGasaObject const* Context) |  | ||||||
| 	{ |  | ||||||
| 		if (Context == nullptr || Context->GetWorld() == nullptr) |  | ||||||
| 			return false; |  | ||||||
|  |  | ||||||
| 		AActor const* Actor = Cast<AActor>(Context->GetOuter()); |  | ||||||
| 		if (Actor == nullptr) |  | ||||||
| 		{ |  | ||||||
| 			Log("Could not get actor reference", ELogV::Warning, LogGasaNet); |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		bool Result = Actor->HasAuthority(); |  | ||||||
| 		return Result; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	inline | 	inline | ||||||
| 	bool ServerAuthorized(AActor const* Actor) | 	bool ServerAuthorized(AActor const* Actor) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user