Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d97ee1d302 | ||
|
|
1b5d2a3ff6 | ||
|
|
ca779b627b | ||
|
|
a885201b81 | ||
|
|
07c5420bc2 | ||
|
|
fe2abe1972 | ||
|
|
e8fb014d29 | ||
|
|
c4e40037ed | ||
|
|
33b3723b82 | ||
|
|
ae1e28a072 | ||
|
|
ef002ccf53 | ||
|
|
035ad8de6f | ||
|
|
a604117e95 | ||
|
|
f17c53a1a9 | ||
|
|
bd0c8a0878 | ||
|
|
22aee515ed | ||
|
|
8f84dcf3d3 | ||
|
|
3a58e90802 | ||
|
|
ad41867dc5 | ||
|
|
cc1636b687 | ||
|
|
eaed6cf337 | ||
|
|
2c11939244 | ||
|
|
811dc33f4a |
+29
-22
@@ -1,31 +1,38 @@
|
|||||||
Project/Binaries
|
*/Binaries/Win64/*.patch_*.*
|
||||||
Project/Intermediate
|
|
||||||
Project/Saved/Crashes
|
Project/.idea
|
||||||
Project/Saved/SourceControl
|
|
||||||
Project/Saved/ShaderDebugInfo
|
|
||||||
Project/Saved/Logs
|
|
||||||
Project/Saved/Autosaves
|
|
||||||
Project/Saved/Config/CrashReportClient
|
|
||||||
Project/Saved/Config/WindowsEditor
|
|
||||||
Project/Saved/Config/WorldState
|
|
||||||
Project/Saved/AutoScreenshot.png
|
|
||||||
Project/Platforms
|
|
||||||
Project/.vs
|
Project/.vs
|
||||||
Project/.vsconfig
|
Project/.vsconfig
|
||||||
*.sln
|
|
||||||
*.target
|
|
||||||
*.modules
|
|
||||||
Project/.idea
|
|
||||||
|
|
||||||
Project/Saved/Screenshots
|
Project/Binaries
|
||||||
*/Binaries/Win64/*.patch_*.*
|
|
||||||
Project/Saved/ImGui
|
|
||||||
Project/Saved/ImGui/imgui.ini
|
|
||||||
GasaGen_*.pdb
|
|
||||||
Project/Binaries/GasaGen.exe
|
Project/Binaries/GasaGen.exe
|
||||||
Project/Binaries/GasaGen.map
|
Project/Binaries/GasaGen.map
|
||||||
Project/Binaries/GasaGen.obj
|
Project/Binaries/GasaGen.obj
|
||||||
Project/Binaries/vc140.pdb
|
Project/Binaries/vc140.pdb
|
||||||
|
|
||||||
|
Project/Intermediate
|
||||||
|
|
||||||
|
Project/Platforms
|
||||||
|
|
||||||
Project/Saved/Config/ConsoleHistory.ini
|
Project/Saved/Config/ConsoleHistory.ini
|
||||||
*.pdb
|
|
||||||
|
Project/Saved/Autosaves
|
||||||
|
Project/Saved/AutoScreenshot.png
|
||||||
|
Project/Saved/Config/CrashReportClient
|
||||||
|
Project/Saved/Config/WindowsEditor
|
||||||
|
Project/Saved/Config/WorldState
|
||||||
|
Project/Saved/Crashes
|
||||||
Project/Saved/Diff
|
Project/Saved/Diff
|
||||||
|
Project/Saved/ImGui
|
||||||
|
Project/Saved/ImGui/imgui.ini
|
||||||
|
Project/Saved/Logs
|
||||||
|
Project/Saved/Screenshots
|
||||||
|
Project/Saved/ShaderDebugInfo
|
||||||
|
Project/Saved/SourceControl
|
||||||
|
|
||||||
|
*.modules
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.target
|
||||||
|
|
||||||
|
GasaGen_*.pdb
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -49,6 +49,15 @@ r.ReflectionMethod=1
|
|||||||
r.Shadow.Virtual.Enable=1
|
r.Shadow.Virtual.Enable=1
|
||||||
r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True
|
r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True
|
||||||
r.CustomDepth=3
|
r.CustomDepth=3
|
||||||
|
r.DefaultFeature.Bloom=False
|
||||||
|
r.DefaultFeature.AmbientOcclusion=False
|
||||||
|
r.DefaultFeature.AmbientOcclusionStaticFraction=False
|
||||||
|
r.DefaultFeature.AutoExposure=False
|
||||||
|
r.DefaultFeature.MotionBlur=False
|
||||||
|
r.AntiAliasingMethod=0
|
||||||
|
r.MSAACount=1
|
||||||
|
r.ScreenPercentage.Default=25.000000
|
||||||
|
r.SupportSkyAtmosphere=False
|
||||||
|
|
||||||
[/Script/WorldPartitionEditor.WorldPartitionEditorSettings]
|
[/Script/WorldPartitionEditor.WorldPartitionEditorSettings]
|
||||||
CommandletClass=Class'/Script/UnrealEd.WorldPartitionConvertCommandlet'
|
CommandletClass=Class'/Script/UnrealEd.WorldPartitionConvertCommandlet'
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ Tag_PPV=Global_PPV
|
|||||||
Tag_GlobalPPV=Global_PPV
|
Tag_GlobalPPV=Global_PPV
|
||||||
Template_PlayerCamera=/Game/Actors/BP_CameraMount.BP_CameraMount_C
|
Template_PlayerCamera=/Game/Actors/BP_CameraMount.BP_CameraMount_C
|
||||||
Template_HUD_HostUI=/Game/UI/UI_Host.UI_Host_C
|
Template_HUD_HostUI=/Game/UI/UI_Host.UI_Host_C
|
||||||
|
Template_HostWidgetController=/Game/UI/BP_HostWidgetController.BP_HostWidgetController_C
|
||||||
|
TaggedMessageTable=/Game/Core/Tables/DT_TaggedMessages.DT_TaggedMessages
|
||||||
|
|
||||||
[/Script/GameplayAbilities.AbilitySystemGlobals]
|
[/Script/GameplayAbilities.AbilitySystemGlobals]
|
||||||
bUseDebugTargetFromHud=true
|
bUseDebugTargetFromHud=true
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
[/Script/GameplayTags.GameplayTagsSettings]
|
||||||
|
ImportTagsFromConfig=True
|
||||||
|
WarnOnInvalidTags=True
|
||||||
|
ClearInvalidTags=False
|
||||||
|
AllowEditorTagUnloading=True
|
||||||
|
AllowGameTagUnloading=False
|
||||||
|
FastReplication=False
|
||||||
|
InvalidTagCharacters="\"\',"
|
||||||
|
+GameplayTagTableList=/Game/Core/Tables/DT_PrimaryAttributes.DT_PrimaryAttributes
|
||||||
|
NumBitsForContainerSize=6
|
||||||
|
NetIndexFirstBitSegment=16
|
||||||
|
+GameplayTagList=(Tag="Attributes.Vital.Health",DevComment="")
|
||||||
|
+GameplayTagList=(Tag="Attributes.Vital.Mana",DevComment="")
|
||||||
|
+GameplayTagList=(Tag="Attributes.Vital.MaxHealth",DevComment="")
|
||||||
|
+GameplayTagList=(Tag="Attributes.Vital.MaxMana",DevComment="")
|
||||||
|
+GameplayTagList=(Tag="Message.Crystal.Health",DevComment="")
|
||||||
|
+GameplayTagList=(Tag="Message.Crystal.Mana",DevComment="")
|
||||||
|
+GameplayTagList=(Tag="Message.Potion.Health",DevComment="")
|
||||||
|
+GameplayTagList=(Tag="Message.Potion.Mana",DevComment="")
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -301,10 +301,6 @@
|
|||||||
"Name": "VisualStudioSourceCodeAccess",
|
"Name": "VisualStudioSourceCodeAccess",
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "GitSourceControl",
|
|
||||||
"Enabled": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "SlateInsights",
|
"Name": "SlateInsights",
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"ColumnWidths":
|
||||||
|
{
|
||||||
|
"DevComment": 405,
|
||||||
|
"Tag": 381
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"ColumnWidths":
|
||||||
|
{
|
||||||
|
"TextStyle": 1099
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ColumnWidths":
|
||||||
|
{
|
||||||
|
"Image": 487,
|
||||||
|
"Tag": 246,
|
||||||
|
"Message": 439,
|
||||||
|
"MessageTemplate": 232
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
|
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
|
||||||
|
<bUsePCHFiles>false</bUsePCHFiles>
|
||||||
|
|
||||||
</Configuration>
|
</Configuration>
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include "EffectProperties.h"
|
||||||
|
|
||||||
|
#include "AbilitySystemComponent.h"
|
||||||
|
#include "AbilitySystemGlobals.h"
|
||||||
|
#include "GameplayEffect.h"
|
||||||
|
#include "GameplayEffectExtension.h"
|
||||||
|
#include "GameFramework/Pawn.h"
|
||||||
|
#include "GameFramework/PlayerController.h"
|
||||||
|
|
||||||
|
void FEffectProperties::Populate(FGameplayEffectModCallbackData const& Data)
|
||||||
|
{
|
||||||
|
Context = Data.EffectSpec.GetContext();
|
||||||
|
SourceAbilitySystem = Context.GetOriginalInstigatorAbilitySystemComponent();
|
||||||
|
|
||||||
|
if (IsValid(SourceAbilitySystem)
|
||||||
|
&& SourceAbilitySystem->AbilityActorInfo.IsValid()
|
||||||
|
&& SourceAbilitySystem->AbilityActorInfo->AvatarActor.IsValid())
|
||||||
|
{
|
||||||
|
FGameplayAbilityActorInfo* AbilityInfo = SourceAbilitySystem->AbilityActorInfo.Get();
|
||||||
|
SourceAvatar = AbilityInfo->AvatarActor.Get();
|
||||||
|
SourceController = AbilityInfo->PlayerController.Get();
|
||||||
|
|
||||||
|
if (SourceController == nullptr && SourceAvatar)
|
||||||
|
{
|
||||||
|
APawn* Pawn = Cast<APawn>(SourceAvatar);
|
||||||
|
if (Pawn)
|
||||||
|
SourceController = Pawn->GetController();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Data.Target.AbilityActorInfo.IsValid() && Data.Target.AbilityActorInfo->AvatarActor.IsValid())
|
||||||
|
{
|
||||||
|
FGameplayAbilityActorInfo* AbilityInfo = Data.Target.AbilityActorInfo.Get();
|
||||||
|
TargetAvatar = AbilityInfo->AvatarActor.Get();
|
||||||
|
TargetController = AbilityInfo->PlayerController.Get();
|
||||||
|
TargetAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(TargetAvatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GameplayEffectTypes.h"
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
|
||||||
|
#include "EffectProperties.generated.h"
|
||||||
|
|
||||||
|
USTRUCT()
|
||||||
|
struct GASA_API FEffectProperties
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
FGameplayEffectContextHandle Context;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
UAbilitySystemComponent* SourceAbilitySystem;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
AActor* SourceAvatar;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
AController* SourceController;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
UAbilitySystemComponent* TargetAbilitySystem;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
AActor* TargetAvatar;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
APlayerController* TargetController;
|
||||||
|
|
||||||
|
void Populate(FGameplayEffectModCallbackData const& Data);
|
||||||
|
};
|
||||||
@@ -1 +1,33 @@
|
|||||||
#include "GasaAbilitySystemComponent.h"
|
#include "GasaAbilitySystemComponent.h"
|
||||||
|
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "Engine/GameViewportClient.h"
|
||||||
|
#include "Game/GasaGameState.h"
|
||||||
|
#include "Game/GasaPlayerController.h"
|
||||||
|
#include "GameFramework/HUD.h"
|
||||||
|
#include "Slate/SceneViewport.h"
|
||||||
|
#include "UI/GasaHUD.h"
|
||||||
|
#include "CogDebugDraw.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Gasa;
|
||||||
|
|
||||||
|
void UGasaAbilitySystemComp::OnAbilityActorInfoSet()
|
||||||
|
{
|
||||||
|
if ( ! OnGameplayEffectAppliedDelegateToSelf.IsBoundToObject(this))
|
||||||
|
OnGameplayEffectAppliedDelegateToSelf.AddUObject(this, & ThisClass::EffectApplied);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGasaAbilitySystemComp::EffectApplied(UAbilitySystemComponent* AbilitySystem, FGameplayEffectSpec const& Spec,
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect)
|
||||||
|
{
|
||||||
|
Log("EFFECT APPLIED?");
|
||||||
|
FGameplayTagContainer Tags;
|
||||||
|
Spec.GetAllAssetTags(Tags);
|
||||||
|
Event_OnEffectAppliedAssetTags.Broadcast(Tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGasaAbilitySystemComp::InitAbilityActorInfo(AActor* InOwnerActor, AActor* InAvatarActor)
|
||||||
|
{
|
||||||
|
Super::InitAbilityActorInfo(InOwnerActor, InAvatarActor);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,29 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AbilitySystemComponent.h"
|
#include "AbilitySystemComponent.h"
|
||||||
#include "AbilitySystemInterface.h"
|
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
|
||||||
#include "GasaAbilitySystemComponent.generated.h"
|
#include "GasaAbilitySystemComponent.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_MULTICAST_DELEGATE_OneParam(FEffectAssetTagsSig, FGameplayTagContainer const& /*Tags*/);
|
||||||
|
|
||||||
|
|
||||||
UCLASS(BlueprintType)
|
UCLASS(BlueprintType)
|
||||||
class GASA_API UGasaAbilitySystemComp : public UAbilitySystemComponent
|
class GASA_API UGasaAbilitySystemComp : public UAbilitySystemComponent
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
};
|
|
||||||
|
|
||||||
namespace Gasa
|
FEffectAssetTagsSig Event_OnEffectAppliedAssetTags;
|
||||||
{
|
|
||||||
inline
|
void OnAbilityActorInfoSet();
|
||||||
UGasaAbilitySystemComp* GetAbilitySystem(UObject* Object)
|
|
||||||
{
|
void EffectApplied(UAbilitySystemComponent* AbilitySystem, FGameplayEffectSpec const& Spec, FActiveGameplayEffectHandle ActiveEffect);
|
||||||
if (Object->Implements<UAbilitySystemInterface>())
|
|
||||||
{
|
#pragma region AbilitySystemComponent
|
||||||
return Cast<UGasaAbilitySystemComp>( Cast<IAbilitySystemInterface>(Object)->GetAbilitySystemComponent() );
|
void InitAbilityActorInfo(AActor* InOwnerActor, AActor* InAvatarActor) override;
|
||||||
}
|
#pragma endregion AbilitySystemComponent
|
||||||
return nullptr;
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "GasaAbilitySystemComponent.h"
|
||||||
|
#include "AbilitySystemInterface.h"
|
||||||
|
#include "AbilitySystemGlobals.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Gasa
|
||||||
|
{
|
||||||
|
inline
|
||||||
|
UGasaAbilitySystemComp* GetAbilitySystem(UObject* Object)
|
||||||
|
{
|
||||||
|
if (Object->Implements<UAbilitySystemInterface>())
|
||||||
|
{
|
||||||
|
return Cast<UGasaAbilitySystemComp>( Cast<IAbilitySystemInterface>(Object)->GetAbilitySystemComponent() );
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From: UAbilitySystemGlobals::GetAbilitySystemComponentFromActor
|
||||||
|
inline
|
||||||
|
UGasaAbilitySystemComp* GetAbilitySystem(AActor* Actor, bool LookForComponent = true)
|
||||||
|
{
|
||||||
|
if (Actor == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(Actor);
|
||||||
|
if (ASI)
|
||||||
|
return Cast<UGasaAbilitySystemComp>(ASI->GetAbilitySystemComponent());
|
||||||
|
|
||||||
|
if (LookForComponent)
|
||||||
|
{
|
||||||
|
// Fall back to a component search to better support BP-only actors
|
||||||
|
return Cast<UGasaAbilitySystemComp>(Actor->FindComponentByClass<UAbilitySystemComponent>());
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
// This was generated by GasaGen/GasaGen.cpp
|
// Generated by GasaGen/GasaGen_UGasaAttributeSet.cpp
|
||||||
#include "GasaAttributeSet.h"
|
#include "GasaAttributeSet.h"
|
||||||
|
#include "GasaAttributeSet_Inlines.h"
|
||||||
|
#include "EffectProperties.h"
|
||||||
|
|
||||||
#include "AbilitySystemComponent.h"
|
#include "AbilitySystemComponent.h"
|
||||||
#include "Net/UnrealNetwork.h"
|
#include "Net/UnrealNetwork.h"
|
||||||
@@ -13,24 +15,60 @@ UGasaAttributeSet::UGasaAttributeSet()
|
|||||||
InitMaxMana( 50.f );
|
InitMaxMana( 50.f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma region Rep Notifies
|
||||||
void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth )
|
void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth )
|
||||||
{
|
{
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, Health, PrevHealth )
|
// From GAMEPLAYATTRIBUTE_REPNOTIFY
|
||||||
|
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) );
|
||||||
|
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Health, PrevHealth );
|
||||||
}
|
}
|
||||||
|
|
||||||
void UGasaAttributeSet::Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth )
|
void UGasaAttributeSet::Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth )
|
||||||
{
|
{
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, MaxHealth, PrevMaxHealth )
|
// From GAMEPLAYATTRIBUTE_REPNOTIFY
|
||||||
|
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) );
|
||||||
|
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxHealth, PrevMaxHealth );
|
||||||
}
|
}
|
||||||
|
|
||||||
void UGasaAttributeSet::Client_OnRep_Mana( FGameplayAttributeData& PrevMana )
|
void UGasaAttributeSet::Client_OnRep_Mana( FGameplayAttributeData& PrevMana )
|
||||||
{
|
{
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, Mana, PrevMana )
|
// From GAMEPLAYATTRIBUTE_REPNOTIFY
|
||||||
|
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) );
|
||||||
|
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Mana, PrevMana );
|
||||||
}
|
}
|
||||||
|
|
||||||
void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana )
|
void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana )
|
||||||
{
|
{
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, MaxMana, PrevMaxMana )
|
// From GAMEPLAYATTRIBUTE_REPNOTIFY
|
||||||
|
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) );
|
||||||
|
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxMana, PrevMaxMana );
|
||||||
|
}
|
||||||
|
#pragma endregion Rep Notifies
|
||||||
|
|
||||||
|
void UGasaAttributeSet::PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data )
|
||||||
|
{
|
||||||
|
Super::PostGameplayEffectExecute( Data );
|
||||||
|
FEffectProperties Props;
|
||||||
|
Props.Populate( Data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGasaAttributeSet::PreAttributeChange( FGameplayAttribute const& Attribute, float& NewValue )
|
||||||
|
{
|
||||||
|
Super::PreAttributeChange( Attribute, NewValue );
|
||||||
|
|
||||||
|
if ( Attribute == GetHealthAttribute() )
|
||||||
|
{
|
||||||
|
NewValue = FMath::Clamp( NewValue, 0, GetMaxHealth() );
|
||||||
|
}
|
||||||
|
if ( Attribute == GetMaxHealthAttribute() )
|
||||||
|
{
|
||||||
|
NewValue = FMath::Clamp( NewValue, 0, 99999.000000 );
|
||||||
|
}
|
||||||
|
if ( Attribute == GetManaAttribute() )
|
||||||
|
{
|
||||||
|
NewValue = FMath::Clamp( NewValue, 0, GetMaxMana() );
|
||||||
|
}
|
||||||
|
if ( Attribute == GetMaxManaAttribute() )
|
||||||
|
{
|
||||||
|
NewValue = FMath::Clamp( NewValue, 0, 99999.000000 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const
|
void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// This was generated by GasaGen/GasaGen.cpp
|
// Generated by GasaGen/GasaGen_UGasaAttributeSet.cpp
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "AttributeSet.h"
|
#include "AttributeSet.h"
|
||||||
#include "AbilitySystemComponent.h"
|
|
||||||
#include "GasaAttributeSet.generated.h"
|
#include "GasaAttributeSet.generated.h"
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
@@ -9,20 +9,17 @@ class GASA_API UGasaAttributeSet : public UAttributeSet
|
|||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
|
UGasaAttributeSet();
|
||||||
|
|
||||||
UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
||||||
FGameplayAttributeData Health;
|
FGameplayAttributeData Health;
|
||||||
|
|
||||||
UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
||||||
FGameplayAttributeData MaxHealth;
|
FGameplayAttributeData MaxHealth;
|
||||||
|
|
||||||
UPROPERTY( ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
UPROPERTY( ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
||||||
FGameplayAttributeData Mana;
|
FGameplayAttributeData Mana;
|
||||||
|
|
||||||
UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
|
||||||
FGameplayAttributeData MaxMana;
|
FGameplayAttributeData MaxMana;
|
||||||
|
|
||||||
UGasaAttributeSet();
|
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
void Client_OnRep_Health( FGameplayAttributeData& PrevHealth );
|
void Client_OnRep_Health( FGameplayAttributeData& PrevHealth );
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
@@ -53,6 +50,7 @@ public:
|
|||||||
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) );
|
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) );
|
||||||
return Prop;
|
return Prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE float GetHealth() const { return Health.GetCurrentValue(); }
|
FORCEINLINE float GetHealth() const { return Health.GetCurrentValue(); }
|
||||||
FORCEINLINE float GetMaxHealth() const { return MaxHealth.GetCurrentValue(); }
|
FORCEINLINE float GetMaxHealth() const { return MaxHealth.GetCurrentValue(); }
|
||||||
FORCEINLINE float GetMana() const { return Mana.GetCurrentValue(); }
|
FORCEINLINE float GetMana() const { return Mana.GetCurrentValue(); }
|
||||||
@@ -61,38 +59,11 @@ public:
|
|||||||
|
|
||||||
#pragma region Setters
|
#pragma region Setters
|
||||||
FORCEINLINE void
|
FORCEINLINE void
|
||||||
SetHealth( float NewVal )
|
SetHealth( float NewVal );
|
||||||
{
|
FORCEINLINE void SetMaxHealth( float NewVal );
|
||||||
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
FORCEINLINE void SetMana( float NewVal );
|
||||||
if ( ensure( AbilityComp ) )
|
FORCEINLINE void SetMaxMana( float NewVal );
|
||||||
{
|
|
||||||
AbilityComp->SetNumericAttributeBase( GetHealthAttribute(), NewVal );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
FORCEINLINE void SetMaxHealth( float NewVal )
|
|
||||||
{
|
|
||||||
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
|
||||||
if ( ensure( AbilityComp ) )
|
|
||||||
{
|
|
||||||
AbilityComp->SetNumericAttributeBase( GetMaxHealthAttribute(), NewVal );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
FORCEINLINE void SetMana( float NewVal )
|
|
||||||
{
|
|
||||||
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
|
||||||
if ( ensure( AbilityComp ) )
|
|
||||||
{
|
|
||||||
AbilityComp->SetNumericAttributeBase( GetManaAttribute(), NewVal );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
FORCEINLINE void SetMaxMana( float NewVal )
|
|
||||||
{
|
|
||||||
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
|
||||||
if ( ensure( AbilityComp ) )
|
|
||||||
{
|
|
||||||
AbilityComp->SetNumericAttributeBase( GetMaxManaAttribute(), NewVal );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
FORCEINLINE void InitHealth( float NewVal )
|
FORCEINLINE void InitHealth( float NewVal )
|
||||||
{
|
{
|
||||||
Health.SetBaseValue( NewVal );
|
Health.SetBaseValue( NewVal );
|
||||||
@@ -115,17 +86,14 @@ public:
|
|||||||
}
|
}
|
||||||
#pragma endregion Setters
|
#pragma endregion Setters
|
||||||
|
|
||||||
#pragma region UObject
|
#pragma region AttributeSet
|
||||||
|
void
|
||||||
|
PreAttributeChange( const FGameplayAttribute& Attribute, float& NewValue ) override;
|
||||||
|
void PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data ) override;
|
||||||
|
#pragma endregion AttributeSet
|
||||||
|
|
||||||
|
#pragma region UObject
|
||||||
void
|
void
|
||||||
GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override;
|
GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override;
|
||||||
#pragma endregion UObject
|
#pragma endregion UObject
|
||||||
};
|
};
|
||||||
namespace Gasa
|
|
||||||
{
|
|
||||||
inline UGasaAttributeSet const* GetAttributeSet( UAbilitySystemComponent* ASC )
|
|
||||||
{
|
|
||||||
return Cast<UGasaAttributeSet>( ASC->GetAttributeSet( UGasaAttributeSet::StaticClass() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
// Generated by GasaGen/GasaGen_UGasaAttributeSet.cpp
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaAttributeSet.h"
|
||||||
|
#include "AbilitySystemComponent.h"
|
||||||
|
|
||||||
|
#pragma region Attribute Setters
|
||||||
|
FORCEINLINE
|
||||||
|
void UGasaAttributeSet::SetHealth( float NewVal )
|
||||||
|
{
|
||||||
|
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
||||||
|
if ( ensure( AbilityComp ) )
|
||||||
|
{
|
||||||
|
AbilityComp->SetNumericAttributeBase( GetHealthAttribute(), NewVal );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
FORCEINLINE
|
||||||
|
void UGasaAttributeSet::SetMaxHealth( float NewVal )
|
||||||
|
{
|
||||||
|
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
||||||
|
if ( ensure( AbilityComp ) )
|
||||||
|
{
|
||||||
|
AbilityComp->SetNumericAttributeBase( GetMaxHealthAttribute(), NewVal );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
FORCEINLINE
|
||||||
|
void UGasaAttributeSet::SetMana( float NewVal )
|
||||||
|
{
|
||||||
|
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
||||||
|
if ( ensure( AbilityComp ) )
|
||||||
|
{
|
||||||
|
AbilityComp->SetNumericAttributeBase( GetManaAttribute(), NewVal );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
FORCEINLINE
|
||||||
|
void UGasaAttributeSet::SetMaxMana( float NewVal )
|
||||||
|
{
|
||||||
|
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
|
||||||
|
if ( ensure( AbilityComp ) )
|
||||||
|
{
|
||||||
|
AbilityComp->SetNumericAttributeBase( GetMaxManaAttribute(), NewVal );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#pragma endregion Attribute Setters
|
||||||
|
|
||||||
|
namespace Gasa
|
||||||
|
{
|
||||||
|
inline UGasaAttributeSet const* GetAttributeSet( UAbilitySystemComponent* ASC )
|
||||||
|
{
|
||||||
|
return Cast<UGasaAttributeSet>( ASC->GetAttributeSet( UGasaAttributeSet::StaticClass() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,61 +1,126 @@
|
|||||||
#include "GasaEffectActor.h"
|
#include "GasaEffectActor.h"
|
||||||
|
|
||||||
#include "AbilitySystemComponent.h"
|
#include "GasaAbilitySystemComponent_Inlines.h"
|
||||||
#include "AbilitySystemInterface.h"
|
#include "GasaContainers.h"
|
||||||
#include "GasaAttributeSet.h"
|
using namespace Gasa;
|
||||||
#include "Components/SphereComponent.h"
|
|
||||||
|
|
||||||
|
|
||||||
AGasaEffectActor::AGasaEffectActor()
|
AGasaEffectActor::AGasaEffectActor()
|
||||||
{
|
{
|
||||||
PrimaryActorTick.bCanEverTick = false;
|
PrimaryActorTick.bCanEverTick = false;
|
||||||
|
|
||||||
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
|
RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
|
||||||
Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
|
|
||||||
|
|
||||||
SetRootComponent(Mesh);
|
Level = 1.f;
|
||||||
Sphere->SetupAttachment(Mesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AGasaEffectActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent
|
|
||||||
, AActor* OtherActor
|
|
||||||
, UPrimitiveComponent* OtherComp
|
|
||||||
, int32 OtherBodyIndex
|
|
||||||
, bool bFromSweep
|
|
||||||
, FHitResult const& SweepResult)
|
|
||||||
{
|
|
||||||
// Demo of "restricted way"
|
|
||||||
if ( ! OtherActor->Implements<UAbilitySystemInterface>())
|
|
||||||
return;
|
|
||||||
|
|
||||||
IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(OtherActor);
|
InstantEffectUsage = EInstantEffectUsagePolicy::DoNotApply;
|
||||||
if (ASI == nullptr)
|
DurationEffectUsage = DefaultEffectUsagePolicy;
|
||||||
return;
|
InfiniteEffectUsage = DefaultEffectUsagePolicy;
|
||||||
|
|
||||||
// TODO(Ed): Change this to use a gameplay effect instead
|
bDestroyOnEffectRemoval = false;
|
||||||
UAbilitySystemComponent* AbilitySystem = ASI->GetAbilitySystemComponent();
|
}
|
||||||
UGasaAttributeSet* MutAttributes = const_cast<UGasaAttributeSet*>(Gasa::GetAttributeSet(AbilitySystem));
|
|
||||||
|
void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap)
|
||||||
|
{
|
||||||
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
||||||
|
FGameplayEffectContextHandle
|
||||||
|
Context = AS->MakeEffectContext();
|
||||||
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, Level, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (bRemoveOnEndOverlap)
|
||||||
|
ActiveEffectsToRemove.Add(ActiveEffect, AS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaEffectActor::OnOverlap(AActor* Actor)
|
||||||
|
{
|
||||||
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
||||||
|
FGameplayEffectContextHandle
|
||||||
|
Context = AS->MakeEffectContext();
|
||||||
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
MutAttributes->SetHealth( MutAttributes->GetHealth() + 25.f );
|
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap)
|
||||||
Destroy();
|
{
|
||||||
|
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
|
||||||
|
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
}
|
||||||
|
if (DurationEffectClass)
|
||||||
|
{
|
||||||
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap))
|
||||||
|
{
|
||||||
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
|
ActiveDuration = ActiveEffect;
|
||||||
|
}
|
||||||
|
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveDuration);
|
||||||
|
}
|
||||||
|
if (InfiniteEffectClass)
|
||||||
|
{
|
||||||
|
bool bApplyOnOverlap = Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnOverlap);
|
||||||
|
if (bApplyOnOverlap)
|
||||||
|
{
|
||||||
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
|
ActiveInfinite = ActiveEffect;
|
||||||
|
}
|
||||||
|
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
|
{
|
||||||
|
if (ActiveInfinite.IsValid())
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveInfinite);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaEffectActor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent
|
void AGasaEffectActor::OnEndOverlap(AActor* Actor)
|
||||||
, AActor* OtherActor
|
|
||||||
, UPrimitiveComponent* OtherComp
|
|
||||||
, int32 OtherBodyIndex)
|
|
||||||
{
|
{
|
||||||
}
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
||||||
|
FGameplayEffectContextHandle
|
||||||
|
Context = AS->MakeEffectContext();
|
||||||
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
|
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnEndOverlap)
|
||||||
|
{
|
||||||
|
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
|
||||||
|
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
}
|
||||||
|
if (DurationEffectClass)
|
||||||
|
{
|
||||||
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
|
||||||
|
{
|
||||||
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
|
ActiveDuration = ActiveEffect;
|
||||||
|
}
|
||||||
|
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveDuration);
|
||||||
|
}
|
||||||
|
if (InfiniteEffectClass)
|
||||||
|
{
|
||||||
|
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
|
||||||
|
{
|
||||||
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
|
ActiveInfinite = ActiveEffect;
|
||||||
|
}
|
||||||
|
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
|
{
|
||||||
|
if (ActiveInfinite.IsValid())
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveInfinite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AGasaEffectActor::BeginPlay()
|
TArray<FActiveGameplayEffectHandle> EffectsRemoved;
|
||||||
{
|
for (ActiveEffectEntry ActiveEffect : ActiveEffectsToRemove)
|
||||||
Super::BeginPlay();
|
{
|
||||||
}
|
if (ActiveEffect.Value != AS)
|
||||||
|
continue;
|
||||||
void AGasaEffectActor::PostInitializeComponents()
|
AS->RemoveActiveGameplayEffect(ActiveEffect.Key, 1);
|
||||||
{
|
EffectsRemoved.Add(ActiveEffect.Key);
|
||||||
Super::PostInitializeComponents();
|
}
|
||||||
|
RemoveKeys(ActiveEffectsToRemove, EffectsRemoved);
|
||||||
Sphere->OnComponentBeginOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapBegin);
|
|
||||||
Sphere->OnComponentEndOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapEnd);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,78 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
#include "Actors/GasaActor.h"
|
||||||
|
#include "ActiveGameplayEffectHandle.h"
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
|
|
||||||
#include "GasaEffectActor.generated.h"
|
#include "GasaEffectActor.generated.h"
|
||||||
|
|
||||||
|
struct FActiveGameplayEffectHandle;
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EInstantEffectUsagePolicy : uint8
|
||||||
|
{
|
||||||
|
DoNotApply,
|
||||||
|
ApplyOnOverlap,
|
||||||
|
ApplyOnEndOverlap,
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
|
||||||
|
enum class EEffectUsagePolicy : uint8
|
||||||
|
{
|
||||||
|
None = 0 UMETA(Hidden),
|
||||||
|
ApplyOnOverlap = bit(0),
|
||||||
|
ApplyOnEndOverlap = bit(1),
|
||||||
|
RemoveOnOverlap = bit(2),
|
||||||
|
RemoveOnEndOverlap = bit(3),
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int32 DefaultEffectUsagePolicy = (int32(EEffectUsagePolicy::RemoveOnEndOverlap));
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class GASA_API AGasaEffectActor : public AActor
|
class GASA_API AGasaEffectActor : public AGasaActor
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere)
|
|
||||||
TObjectPtr<UStaticMeshComponent> Mesh;
|
|
||||||
UPROPERTY(VisibleAnywhere)
|
|
||||||
TObjectPtr<USphereComponent> Sphere;
|
|
||||||
|
|
||||||
AGasaEffectActor();
|
AGasaEffectActor();
|
||||||
|
|
||||||
UFUNCTION()
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent
|
float Level;
|
||||||
, AActor* OtherActor
|
|
||||||
, UPrimitiveComponent* OtherComp
|
|
||||||
, int32 OtherBodyIndex
|
|
||||||
, bool bFromSweep
|
|
||||||
, FHitResult const& SweepResult);
|
|
||||||
|
|
||||||
UFUNCTION()
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent
|
TSubclassOf<UGameplayEffect> InstantEffectClass;
|
||||||
, AActor* OtherActor
|
|
||||||
, UPrimitiveComponent* OtherComp
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
, int32 OtherBodyIndex);
|
EInstantEffectUsagePolicy InstantEffectUsage;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
|
TSubclassOf<UGameplayEffect> DurationEffectClass;
|
||||||
|
|
||||||
#pragma region Actor
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy"))
|
||||||
void BeginPlay() override;
|
int32 DurationEffectUsage;
|
||||||
|
|
||||||
void PostInitializeComponents() override;
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
#pragma endregion Actor
|
TSubclassOf<UGameplayEffect> InfiniteEffectClass;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy"))
|
||||||
|
int32 InfiniteEffectUsage;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
|
bool bDestroyOnEffectRemoval;
|
||||||
|
|
||||||
|
TMap<FActiveGameplayEffectHandle, UAbilitySystemComponent*> ActiveEffectsToRemove;
|
||||||
|
using ActiveEffectEntry = TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*>;
|
||||||
|
|
||||||
|
FActiveGameplayEffectHandle ActiveDuration;
|
||||||
|
FActiveGameplayEffectHandle ActiveInfinite;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Gameplay Effects")
|
||||||
|
void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap = false);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void OnOverlap(AActor* Actor);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void OnEndOverlap(AActor* Actor);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include "GasaEffectActorDemo.h"
|
||||||
|
|
||||||
|
#include "AbilitySystemInterface.h"
|
||||||
|
#include "GasaAttributeSet.h"
|
||||||
|
#include "GasaAttributeSet_Inlines.h"
|
||||||
|
#include "Components/SphereComponent.h"
|
||||||
|
#include "Components/StaticMeshComponent.h"
|
||||||
|
|
||||||
|
|
||||||
|
AGasaEffectActorDemo::AGasaEffectActorDemo()
|
||||||
|
{
|
||||||
|
PrimaryActorTick.bCanEverTick = false;
|
||||||
|
|
||||||
|
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
|
||||||
|
Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
|
||||||
|
|
||||||
|
SetRootComponent(Mesh);
|
||||||
|
Sphere->SetupAttachment(Mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaEffectActorDemo::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent
|
||||||
|
, AActor* OtherActor
|
||||||
|
, UPrimitiveComponent* OtherComp
|
||||||
|
, int32 OtherBodyIndex
|
||||||
|
, bool bFromSweep
|
||||||
|
, FHitResult const& SweepResult)
|
||||||
|
{
|
||||||
|
// Demo of "restricted way"
|
||||||
|
if ( ! OtherActor->Implements<UAbilitySystemInterface>())
|
||||||
|
return;
|
||||||
|
|
||||||
|
IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(OtherActor);
|
||||||
|
if (ASI == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO(Ed): Change this to use a gameplay effect instead
|
||||||
|
UAbilitySystemComponent* AbilitySystem = ASI->GetAbilitySystemComponent();
|
||||||
|
UGasaAttributeSet* MutAttributes = const_cast<UGasaAttributeSet*>(Gasa::GetAttributeSet(AbilitySystem));
|
||||||
|
|
||||||
|
MutAttributes->SetHealth( MutAttributes->GetHealth() + 25.f );
|
||||||
|
MutAttributes->SetMana( MutAttributes->GetMana() - 25.f );
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaEffectActorDemo::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent
|
||||||
|
, AActor* OtherActor
|
||||||
|
, UPrimitiveComponent* OtherComp
|
||||||
|
, int32 OtherBodyIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaEffectActorDemo::BeginPlay()
|
||||||
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaEffectActorDemo::PostInitializeComponents()
|
||||||
|
{
|
||||||
|
Super::PostInitializeComponents();
|
||||||
|
|
||||||
|
Sphere->OnComponentBeginOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapBegin);
|
||||||
|
Sphere->OnComponentEndOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapEnd);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
#include "Actors/GasaActor.h"
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
|
|
||||||
|
#include "GasaEffectActorDemo.generated.h"
|
||||||
|
|
||||||
|
// Old demonstration code used before part 37.
|
||||||
|
UCLASS()
|
||||||
|
class GASA_API AGasaEffectActorDemo : public AGasaActor
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
TObjectPtr<UStaticMeshComponent> Mesh;
|
||||||
|
UPROPERTY(VisibleAnywhere)
|
||||||
|
TObjectPtr<USphereComponent> Sphere;
|
||||||
|
|
||||||
|
AGasaEffectActorDemo();
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent
|
||||||
|
, AActor* OtherActor
|
||||||
|
, UPrimitiveComponent* OtherComp
|
||||||
|
, int32 OtherBodyIndex
|
||||||
|
, bool bFromSweep
|
||||||
|
, FHitResult const& SweepResult);
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent
|
||||||
|
, AActor* OtherActor
|
||||||
|
, UPrimitiveComponent* OtherComp
|
||||||
|
, int32 OtherBodyIndex);
|
||||||
|
|
||||||
|
#pragma region Actor
|
||||||
|
void BeginPlay() override;
|
||||||
|
|
||||||
|
void PostInitializeComponents() override;
|
||||||
|
#pragma endregion Actor
|
||||||
|
};
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaActor.h"
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
#include "CameraMount.generated.h"
|
#include "CameraMount.generated.h"
|
||||||
|
|
||||||
UCLASS(Blueprintable)
|
UCLASS(Blueprintable)
|
||||||
class GASA_API ACameraMount : public AActor
|
class GASA_API ACameraMount : public AGasaActor
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Networking/GasaNetLibrary.h"
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
|
|
||||||
|
#include "GasaActor.generated.h"
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class GASA_API AGasaActor : public AActor
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
};
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "EnemyCharacter.h"
|
#include "EnemyCharacter.h"
|
||||||
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
|
|
||||||
AEnemyCharacter::AEnemyCharacter()
|
AEnemyCharacter::AEnemyCharacter()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,12 +9,14 @@
|
|||||||
|
|
||||||
#include "AbilitySystem/GasaAbilitySystemComponent.h"
|
#include "AbilitySystem/GasaAbilitySystemComponent.h"
|
||||||
#include "AbilitySystem/GasaAttributeSet.h"
|
#include "AbilitySystem/GasaAttributeSet.h"
|
||||||
|
#include "Components/SkeletalMeshComponent.h"
|
||||||
|
#include "Engine/PostProcessVolume.h"
|
||||||
|
#include "Game/GasaGameInstance.h"
|
||||||
#include "Game/GasaLevelScriptActor.h"
|
#include "Game/GasaLevelScriptActor.h"
|
||||||
|
#include "Game/GasaPlayerController.h"
|
||||||
void AGasaCharacter::SetHighlight(EHighlight Desired)
|
#include "Materials/MaterialInstanceDynamic.h"
|
||||||
{
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
HighlightState = Desired;
|
using namespace Gasa;
|
||||||
}
|
|
||||||
|
|
||||||
AGasaCharacter::AGasaCharacter()
|
AGasaCharacter::AGasaCharacter()
|
||||||
{
|
{
|
||||||
@@ -48,24 +50,129 @@ 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::PossessedBy(AController* NewController)
|
|
||||||
{
|
|
||||||
Super::PossessedBy(NewController);
|
|
||||||
|
|
||||||
if (bAutoAbilitySystem)
|
|
||||||
{
|
|
||||||
// TODO(Ed): Do we need to do this for enemies?
|
|
||||||
AbilitySystem->InitAbilityActorInfo(this, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AGasaCharacter::OnRep_PlayerState()
|
void AGasaCharacter::OnRep_PlayerState()
|
||||||
{
|
{
|
||||||
Super::OnRep_PlayerState();
|
Super::OnRep_PlayerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AGasaCharacter::PossessedBy(AController* 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 0
|
||||||
|
if (bAutoAbilitySystem)
|
||||||
|
{
|
||||||
|
AbilitySystem->InitAbilityActorInfo(this, this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaCharacter::SetPlayerDefaults()
|
||||||
|
{
|
||||||
|
Super::SetPlayerDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
||||||
|
{
|
||||||
|
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||||
|
}
|
||||||
#pragma endregion Pawn
|
#pragma endregion Pawn
|
||||||
|
|
||||||
#pragma region Actor
|
#pragma region Actor
|
||||||
@@ -73,10 +180,12 @@ void AGasaCharacter::BeginPlay()
|
|||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
|
|
||||||
|
// TODO(Ed): Find out if this is the best spot todo this
|
||||||
|
// There is also OnPossessed, PostInitializeComponents, etc...
|
||||||
if (bAutoAbilitySystem)
|
if (bAutoAbilitySystem)
|
||||||
{
|
{
|
||||||
// TODO(Ed): Do we need to do this for enemies?
|
|
||||||
AbilitySystem->InitAbilityActorInfo(this, this);
|
AbilitySystem->InitAbilityActorInfo(this, this);
|
||||||
|
Cast<UGasaAbilitySystemComp>(AbilitySystem)->OnAbilityActorInfoSet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
#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 "GasaCharacter.generated.h"
|
#include "GasaCharacter.generated.h"
|
||||||
|
|
||||||
@@ -21,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;
|
||||||
@@ -37,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;
|
||||||
|
|
||||||
@@ -56,9 +74,27 @@ public:
|
|||||||
FORCEINLINE void Dehighlight() { SetHighlight(EHighlight::Disabled); };
|
FORCEINLINE void Dehighlight() { SetHighlight(EHighlight::Disabled); };
|
||||||
#pragma endregion Highlighting
|
#pragma endregion Highlighting
|
||||||
|
|
||||||
AGasaCharacter();
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
FORCEINLINE AGasaPlayerState* GetGasaPlayerState() { return GetPlayerState<AGasaPlayerState>(); }
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
#pragma region IAbilitySystem
|
#pragma region IAbilitySystem
|
||||||
FORCEINLINE UAttributeSet* GetAttributes() { return Attributes; }
|
FORCEINLINE UAttributeSet* GetAttributes() { return Attributes; }
|
||||||
@@ -66,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
|
||||||
};
|
};
|
||||||
@@ -85,3 +121,4 @@ namespace Gasa
|
|||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#include "PlayerCharacter.h"
|
#include "PlayerCharacter.h"
|
||||||
|
|
||||||
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
#include "AbilitySystemComponent.h"
|
#include "AbilitySystemComponent.h"
|
||||||
|
#include "Game/GasaPlayerController.h"
|
||||||
|
#include "UI/GasaHUD.h"
|
||||||
|
#include "UI/WidgetController.h"
|
||||||
|
|
||||||
APlayerCharacter::APlayerCharacter()
|
APlayerCharacter::APlayerCharacter()
|
||||||
{
|
{
|
||||||
@@ -12,25 +16,9 @@ APlayerCharacter::APlayerCharacter()
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,93 @@
|
|||||||
#include "GasaGameInstance.h"
|
#include "GasaGameInstance.h"
|
||||||
|
|
||||||
|
#include "Engine/NetDriver.h"
|
||||||
|
#include "Engine/World.h"
|
||||||
|
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("Game Framework class ready: Game State", ELogV::Log, LogGasaNet );
|
||||||
|
break;
|
||||||
|
case EGameFrameworkClassFlag::GameState:
|
||||||
|
GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::GameState;
|
||||||
|
NetLog("Game Framework class ready: Game State", ELogV::Log, LogGasaNet );
|
||||||
|
break;
|
||||||
|
case EGameFrameworkClassFlag::PlayerController:
|
||||||
|
GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::PlayerController;
|
||||||
|
NetLog("Game Framework class ready: Player Controller", ELogV::Log, LogGasaNet);
|
||||||
|
break;
|
||||||
|
case EGameFrameworkClassFlag::PlayerState:
|
||||||
|
GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::PlayerState;
|
||||||
|
NetLog("Game Framework class ready: Player State", ELogV::Log, LogGasaNet);
|
||||||
|
break;
|
||||||
|
case EGameFrameworkClassFlag::Levels:
|
||||||
|
GameFrameworkClassesState |= (uint32)EGameFrameworkClassFlag::Levels;
|
||||||
|
NetLog("Game Framework class ready: Levels", ELogV::Log, LogGasaNet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ProcessGameFrameworkState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGasaGameInstance::ProcessGameFrameworkState()
|
||||||
|
{
|
||||||
|
switch (GameFrameworkState)
|
||||||
|
{
|
||||||
|
case EGameFrameworkState::Uninitialized:
|
||||||
|
{
|
||||||
|
uint32 InitializedFlags =
|
||||||
|
(uint32)EGameFrameworkClassFlag::GameState |
|
||||||
|
(uint32)EGameFrameworkClassFlag::PlayerController |
|
||||||
|
(uint32)EGameFrameworkClassFlag::PlayerState |
|
||||||
|
(uint32)EGameFrameworkClassFlag::Levels
|
||||||
|
;
|
||||||
|
|
||||||
|
if (GetWorld()->NetDriver == nullptr || GetWorld()->NetDriver->IsServer())
|
||||||
|
{
|
||||||
|
InitializedFlags |= (uint32)EGameFrameworkClassFlag::GameMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString MsgGM = "GameMode : " + FString::FromInt( Bitfield_IsSet( GameFrameworkClassesState, scast(uint32, EGameFrameworkClassFlag::GameMode )) );
|
||||||
|
FString MsgGS = "GameState : " + FString::FromInt( Bitfield_IsSet( GameFrameworkClassesState, scast(uint32, EGameFrameworkClassFlag::GameState )) );
|
||||||
|
FString MsgPC = "PlayerController: " + FString::FromInt( Bitfield_IsSet( GameFrameworkClassesState, scast(uint32, EGameFrameworkClassFlag::PlayerController ) ));
|
||||||
|
FString MsgPS = "PlayerState : " + FString::FromInt( Bitfield_IsSet( GameFrameworkClassesState, scast(uint32, EGameFrameworkClassFlag::PlayerState ) ));
|
||||||
|
FString MsgL = "Levels : " + FString::FromInt( Bitfield_IsSet( GameFrameworkClassesState, scast(uint32, EGameFrameworkClassFlag::Levels ) ));
|
||||||
|
|
||||||
|
NetLog(MsgGM, ELogV::Log, LogGasaNet);
|
||||||
|
NetLog(MsgGS, ELogV::Log, LogGasaNet);
|
||||||
|
NetLog(MsgPC, ELogV::Log, LogGasaNet);
|
||||||
|
NetLog(MsgPS, ELogV::Log, LogGasaNet);
|
||||||
|
NetLog(MsgL, ELogV::Log, LogGasaNet);
|
||||||
|
|
||||||
|
if (GameFrameworkClassesState == InitializedFlags)
|
||||||
|
{
|
||||||
|
GameFrameworkState = EGameFrameworkState::Initialized;
|
||||||
|
NetLog("Game Framework initialized");
|
||||||
|
|
||||||
|
Event_OnGameFrameworkInitialized.Broadcast();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion GameFramework
|
||||||
|
|
||||||
|
#pragma region GameInstance
|
||||||
void UGasaGameInstance::Init()
|
void UGasaGameInstance::Init()
|
||||||
{
|
{
|
||||||
Super::Init();
|
Super::Init();
|
||||||
|
|
||||||
DevOptionsCache.CachedDevOptions();
|
DevOptionsCache.CachedDevOptions();
|
||||||
|
|
||||||
using namespace Gasa;
|
|
||||||
Log(FString::Printf(TEXT("UObject Size: %d RT: %d"), sizeof(UObject), UObject::StaticClass()->PropertiesSize ));
|
|
||||||
}
|
}
|
||||||
|
#pragma endregion GameInstance
|
||||||
|
|||||||
@@ -1,19 +1,92 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "Networking/GasaNetLibrary.h"
|
||||||
#include "GasaDevOptionsCache.h"
|
#include "GasaDevOptionsCache.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
#include "GasaGameInstance.generated.h"
|
#include "GasaGameInstance.generated.h"
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EGameFrameworkClassFlag : uint8
|
||||||
|
{
|
||||||
|
None = 0 UMETA(Hidden),
|
||||||
|
GameMode = 1 << 0,
|
||||||
|
GameState = 1 << 1,
|
||||||
|
PlayerController = 1 << 2,
|
||||||
|
PlayerState = 1 << 3,
|
||||||
|
Levels = 1 << 4
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EGameFrameworkState : uint8
|
||||||
|
{
|
||||||
|
Uninitialized,
|
||||||
|
Initialized
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnGameFrameworkInitializedSig);
|
||||||
|
|
||||||
UCLASS(Blueprintable)
|
UCLASS(Blueprintable)
|
||||||
class GASA_API UGasaGameInstance : public UGameInstance
|
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;
|
||||||
|
|
||||||
|
#pragma region GameFramework
|
||||||
|
UPROPERTY(BlueprintAssignable, Category = "GameFramework")
|
||||||
|
FOnGameFrameworkInitializedSig Event_OnGameFrameworkInitialized;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework")
|
||||||
|
EGameFrameworkState GameFrameworkState;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EGameFrameworkClassFlag"))
|
||||||
|
int32 GameFrameworkClassesState;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="GameFramework")
|
||||||
|
void ClearGameplayFrameworkState() {
|
||||||
|
Gasa::Log("Clearing game framework state", EGasaVerbosity::Log, LogGasaNet ); // TODO(Ed): Make a default NetLog
|
||||||
|
GameFrameworkClassesState = scast(int32, EGameFrameworkClassFlag::None);
|
||||||
|
GameFrameworkState = EGameFrameworkState::Uninitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "GameFramework")
|
||||||
|
FORCEINLINE bool IsGameFrameworkInitialized() { return GameFrameworkState == EGameFrameworkState::Initialized; }
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="GameFramework")
|
||||||
|
void NotifyGameFrameworkClassReady(EGameFrameworkClassFlag ClassReady);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "GameFramework", meta=(BlueprintProtected))
|
||||||
|
void ProcessGameFrameworkState();
|
||||||
|
#pragma endregion GameFramework
|
||||||
|
|
||||||
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
#pragma region GameInstance
|
#pragma region GameInstance
|
||||||
void Init() override;
|
void Init() override;
|
||||||
#pragma endregion GameInstance
|
#pragma endregion GameInstance
|
||||||
|
|||||||
@@ -1,2 +1,476 @@
|
|||||||
#include "GasaGameMode.h"
|
#include "GasaGameMode.h"
|
||||||
|
|
||||||
|
#include "Online/CoreOnline.h"
|
||||||
|
#include "GasaGameInstance.h"
|
||||||
|
#include "GasaGameState.h"
|
||||||
|
#include "GasaPlayerController.h"
|
||||||
|
#include "Engine/Player.h"
|
||||||
|
#include "GameFramework/GameSession.h"
|
||||||
|
#include "GameFramework/GameState.h"
|
||||||
|
#include "GameFramework/PlayerState.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
using namespace Gasa;
|
||||||
|
|
||||||
|
#pragma region Game Framework
|
||||||
|
void AGasaGameMode::OnGameFrameworkInitialized()
|
||||||
|
{
|
||||||
|
NetLog("OnGameFrameworkInitialized");
|
||||||
|
|
||||||
|
BP_OnGameFrameworkInitialized();
|
||||||
|
if (MatchState == MatchState::WaitingToStart && ReadyToStartMatch())
|
||||||
|
StartMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::OwningClient_OnGameFrameworkInitialized(AGasaPlayerController* PC)
|
||||||
|
{
|
||||||
|
NetLog("OwningClient_OnGameFrameworkInitialized");
|
||||||
|
HandleStartingNewPlayer(PC);
|
||||||
|
}
|
||||||
|
#pragma endregion Game Framework
|
||||||
|
|
||||||
|
#pragma region GameMode
|
||||||
|
void AGasaGameMode::HandleStartingNewPlayer_Implementation(APlayerController* NewPlayer)
|
||||||
|
{
|
||||||
|
Super::HandleStartingNewPlayer_Implementation(NewPlayer);
|
||||||
|
if (NewPlayer)
|
||||||
|
NewPlayer->bBlockInput = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AGasaGameMode::ReadyToStartMatch_Implementation()
|
||||||
|
{
|
||||||
|
if ( ! GetGameInstance<UGasaGameInstance>()->IsGameFrameworkInitialized())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Super::ReadyToStartMatch();
|
||||||
|
{
|
||||||
|
// If bDelayed Start is set, wait for a manual match start
|
||||||
|
if (bDelayedStart)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By default start when we have > 0 players
|
||||||
|
if (GetMatchState() == MatchState::WaitingToStart)
|
||||||
|
{
|
||||||
|
if (NumPlayers + NumBots > 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion GameMode
|
||||||
|
|
||||||
|
#pragma region GameModeBase
|
||||||
|
void AGasaGameMode::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||||
|
{
|
||||||
|
Super::EndPlay(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());
|
||||||
|
|
||||||
|
// AGameMode::GenericPlayerInitialization(C);
|
||||||
|
{
|
||||||
|
APlayerController* PC = Cast<APlayerController>(C);
|
||||||
|
if (PC != nullptr)
|
||||||
|
{
|
||||||
|
// Moved to: void AGasaGameMode::SetPlayerDefaults(APawn* PlayerPawn)
|
||||||
|
// InitializeHUDForPlayer(Cast<APlayerController>(C));
|
||||||
|
|
||||||
|
// Notify the game that we can now be muted and mute others
|
||||||
|
UpdateGameplayMuteList(PC);
|
||||||
|
|
||||||
|
if (GameSession != nullptr)
|
||||||
|
{
|
||||||
|
// Tell the player to enable voice by default or use the push to talk method
|
||||||
|
PC->ClientEnableNetworkVoice(!GameSession->RequiresPushToTalk());
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplicateStreamingStatus(PC);
|
||||||
|
|
||||||
|
bool HidePlayer = false, HideHUD = false, DisableMovement = false, DisableTurning = false;
|
||||||
|
|
||||||
|
// Check to see if we should start in cinematic mode (matinee movie capture)
|
||||||
|
if (ShouldStartInCinematicMode(PC, HidePlayer, HideHUD, DisableMovement, DisableTurning))
|
||||||
|
{
|
||||||
|
PC->SetCinematicMode(true, HidePlayer, HideHUD, DisableMovement, DisableTurning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TSubclassOf<APlayerController> AGasaGameMode::GetPlayerControllerClassToSpawnForSeamlessTravel(APlayerController* PreviousPlayerController)
|
||||||
|
{
|
||||||
|
NetLog("GetPlayerControllerClassToSpawnForSeamlessTravel: " + PreviousPlayerController->GetName());
|
||||||
|
return Super::GetPlayerControllerClassToSpawnForSeamlessTravel(PreviousPlayerController);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::HandleSeamlessTravelPlayer(AController*& Controller)
|
||||||
|
{
|
||||||
|
NetLog("HandleSeamlessTravelPlayer: " + Controller->GetName());
|
||||||
|
|
||||||
|
// Super::HandleSeamlessTravelPlayer( C );
|
||||||
|
|
||||||
|
UE_LOG(LogGameMode, Log, TEXT(">> GameMode::HandleSeamlessTravelPlayer: %s "), * Controller->GetName());
|
||||||
|
|
||||||
|
APlayerController* PC = Cast<APlayerController>(Controller);
|
||||||
|
UClass* PCClassToSpawn = GetPlayerControllerClassToSpawnForSeamlessTravel(PC);
|
||||||
|
// FUniqueNetIdRepl StoredNativePlatformUniqueNetId = C->GetPlayerState<AGasaPlayerState>()->NativePlatformUniqueNetId;
|
||||||
|
|
||||||
|
if (PC && PC->GetClass() != PCClassToSpawn)
|
||||||
|
{
|
||||||
|
if (PC->Player != nullptr)
|
||||||
|
{
|
||||||
|
// We need to spawn a new PlayerController to replace the old one
|
||||||
|
APlayerController* const NewPC = SpawnPlayerControllerCommon(PC->IsLocalPlayerController()
|
||||||
|
? ROLE_SimulatedProxy
|
||||||
|
: ROLE_AutonomousProxy, PC->GetFocalLocation(), PC->GetControlRotation(), PCClassToSpawn);
|
||||||
|
if (NewPC == nullptr)
|
||||||
|
{
|
||||||
|
NetLog(FString::Printf(
|
||||||
|
TEXT("Failed to spawn new PlayerController for %s (old class %s)"), *PC->GetHumanReadableName(), *PC->GetClass()->GetName())
|
||||||
|
, ELogV::Warning
|
||||||
|
);
|
||||||
|
PC->Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PC->SeamlessTravelTo(NewPC);
|
||||||
|
NewPC->SeamlessTravelFrom(PC);
|
||||||
|
SwapPlayerControllers(PC, NewPC);
|
||||||
|
PC = NewPC;
|
||||||
|
Controller = NewPC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PC->Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// clear out data that was only for the previous game
|
||||||
|
Controller->PlayerState->Reset();
|
||||||
|
// create a new PlayerState and copy over info; this is necessary because the old GameMode may have used a different PlayerState class
|
||||||
|
APlayerState* OldPlayerState = Controller->PlayerState;
|
||||||
|
Controller->InitPlayerState();
|
||||||
|
OldPlayerState->SeamlessTravelTo( Controller->PlayerState);
|
||||||
|
// we don"t need the old PlayerState anymore
|
||||||
|
//@fixme: need a way to replace PlayerStates that doesn't cause incorrect "player left the game"/"player entered the game" messages
|
||||||
|
OldPlayerState->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
InitSeamlessTravelPlayer(Controller);
|
||||||
|
|
||||||
|
// Initialize hud and other player details, shared with PostLogin
|
||||||
|
GenericPlayerInitialization(Controller);
|
||||||
|
|
||||||
|
if (AGasaGameState* GS = GetGameState<AGasaGameState>())
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
int32 NumConnections = GI->SessionSettings.bPublicGame
|
||||||
|
? GI->SessionSettings.PublicConnections
|
||||||
|
: GI->SessionSettings.PrivateConnections;
|
||||||
|
if (GS->OnlinePlayers.Num() < NumConnections)
|
||||||
|
GS->OnlinePlayers.Init( nullptr, NumConnections );
|
||||||
|
|
||||||
|
for (AGasaPlayerState* & PS : GS->OnlinePlayers)
|
||||||
|
{
|
||||||
|
if (PS == nullptr)
|
||||||
|
{
|
||||||
|
PS = C->GetPlayerState<ASlipgatePlayerState>();
|
||||||
|
PS->SgID = GS->OnlinePlayers.Find( PS );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller->GetPlayerState<AGasaPlayerState>()->NativePlatformUniqueNetId = StoredNativePlatformUniqueNetId;
|
||||||
|
NetLog(FString::Printf(TEXT("HandleSeamlessTravelPlayer: %s"), * Controller->GetName()) );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (PC)
|
||||||
|
PC->Event_NetOwner_OnGameplayFrameworkInitialized.AddDynamic(this, &ThisClass::OwningClient_OnGameFrameworkInitialized);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::InitializeHUDForPlayer_Implementation(APlayerController* NewPlayer)
|
||||||
|
{
|
||||||
|
Super::InitializeHUDForPlayer_Implementation(NewPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::InitSeamlessTravelPlayer(AController* NewController)
|
||||||
|
{
|
||||||
|
if (NewController)
|
||||||
|
NewController->bBlockInput = true;
|
||||||
|
|
||||||
|
// GameMode::InitSeamlessTravelPlayer(NewController);
|
||||||
|
{
|
||||||
|
// AGameModeBase::InitSeamlessTravelPlayer(NewController);
|
||||||
|
{
|
||||||
|
APlayerController* NewPC = Cast<APlayerController>(NewController);
|
||||||
|
|
||||||
|
FString ErrorMessage;
|
||||||
|
if (!UpdatePlayerStartSpot(NewController, TEXT(""), ErrorMessage))
|
||||||
|
NetLog(FString::Printf( TEXT("InitSeamlessTravelPlayer: %s"), *ErrorMessage), ELogV::Warning);
|
||||||
|
|
||||||
|
if (NewPC != nullptr)
|
||||||
|
{
|
||||||
|
NewPC->PostSeamlessTravel();
|
||||||
|
|
||||||
|
if (MustSpectate(NewPC))
|
||||||
|
{
|
||||||
|
NewPC->StartSpectatingOnly();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewPC->bPlayerIsWaiting = true;
|
||||||
|
NewPC->ChangeState(NAME_Spectating);
|
||||||
|
NewPC->ClientGotoState(NAME_Spectating);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
APlayerController* NewPC = Cast<APlayerController>(NewController);
|
||||||
|
|
||||||
|
if (NewPC != nullptr)
|
||||||
|
{
|
||||||
|
SetSeamlessTravelViewTarget(NewPC);
|
||||||
|
|
||||||
|
if (!MustSpectate(NewPC))
|
||||||
|
{
|
||||||
|
NumPlayers++;
|
||||||
|
NumTravellingPlayers--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NumBots++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NetLog("InitSeamlessTravelPlayer: " + NewController->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::HandleMatchAborted()
|
||||||
|
{
|
||||||
|
Super::HandleMatchAborted();
|
||||||
|
NetLog("HandleMatchAborted");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::Logout(AController* Exiting)
|
||||||
|
{
|
||||||
|
Super::Logout(Exiting);
|
||||||
|
|
||||||
|
Event_OnLogout.Broadcast(Cast<AGasaPlayerController>(Exiting));
|
||||||
|
NetLog("User Logged out: " + Exiting->GetName());
|
||||||
|
|
||||||
|
if (AGasaGameState* GS = Cast<AGasaGameState>(GetWorld()->GetGameState()))
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int32 Index = GS->OnlinePlayers.Find(Exiting->GetPlayerState<AGasaGameState>());
|
||||||
|
if (Index == INDEX_NONE)
|
||||||
|
{
|
||||||
|
NetLog("Could not find exiting player state in online players!", ELogV::Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GS->OnlinePlayers[Index] = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
IOnlineSessionPtr const SessionInterface = Online::GetSessionInterface(GetWorld());
|
||||||
|
if ( ! SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
NetLog("DestoryCurrentSession: Could not get the session interface.", ELogV::Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
|
||||||
|
{
|
||||||
|
Super::PreLogin(Options, Address, UniqueId, ErrorMessage);
|
||||||
|
// TODO(Ed): Refuse players if the server is full.
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::PostLogin(APlayerController* NewPlayer)
|
||||||
|
{
|
||||||
|
// AGameMode::PostLogin(NewPlayer);
|
||||||
|
{
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
|
||||||
|
// Update player count
|
||||||
|
if (MustSpectate(NewPlayer))
|
||||||
|
NumSpectators++;
|
||||||
|
else if (World->IsInSeamlessTravel() || NewPlayer->HasClientLoadedCurrentWorld())
|
||||||
|
NumPlayers++;
|
||||||
|
else
|
||||||
|
NumTravellingPlayers++;
|
||||||
|
|
||||||
|
// Save network address for re-associating with reconnecting player, after stripping out port number
|
||||||
|
FString Address = NewPlayer->GetPlayerNetworkAddress();
|
||||||
|
int32 Pos = Address.Find(TEXT(":"), ESearchCase::CaseSensitive);
|
||||||
|
|
||||||
|
NewPlayer->PlayerState->SavedNetworkAddress = (Pos > 0) ? Address.Left(Pos) : Address;
|
||||||
|
|
||||||
|
// Check if this player is reconnecting and already has PlayerState
|
||||||
|
FindInactivePlayer(NewPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AGameModeBase::PostLogin(NewPlayer)
|
||||||
|
{
|
||||||
|
// Runs shared initialization that can happen during seamless travel as well
|
||||||
|
GenericPlayerInitialization(NewPlayer);
|
||||||
|
|
||||||
|
// Perform initialization that only happens on initially joining a server
|
||||||
|
NewPlayer->ClientCapBandwidth(NewPlayer->Player->CurrentNetSpeed);
|
||||||
|
|
||||||
|
if (MustSpectate(NewPlayer))
|
||||||
|
{
|
||||||
|
NewPlayer->ClientGotoState(NAME_Spectating);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If NewPlayer is not only a spectator and has a valid ID, add him as a user to the replay.
|
||||||
|
FUniqueNetIdRepl const&
|
||||||
|
NewPlayerStateUniqueId = NewPlayer->PlayerState->GetUniqueId();
|
||||||
|
if (NewPlayerStateUniqueId.IsValid())
|
||||||
|
{
|
||||||
|
GetGameInstance()->AddUserToReplay(NewPlayerStateUniqueId.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameSession)
|
||||||
|
{
|
||||||
|
GameSession->PostLogin(NewPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AGasaGameState* GS = GetGameState<AGasaGameState>())
|
||||||
|
{
|
||||||
|
UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int32 numconnections = GI->sessionsettings.bPublicGame
|
||||||
|
? GI->SessionSettings.PublicConnections : GI->SessionSettings.PrivateConnections;
|
||||||
|
|
||||||
|
if (GS->OnlinePlayers.Num() < NumConnections)
|
||||||
|
{
|
||||||
|
GS->OnlinePlayers.Init( nullptr, NumConnections );
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AGasaPlayerState* & PS : GS->OnlinePlayers)
|
||||||
|
{
|
||||||
|
if (PS == nullptr)
|
||||||
|
{
|
||||||
|
PS = NewPlayer->GetPlayerState<AGasaPlayerState>();
|
||||||
|
PS->GasaID = GS->OnlinePlayers.Find( PS );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// cont. AGameModeBase::PostLogin(NewPlayer)
|
||||||
|
{
|
||||||
|
// Notify Blueprints that a new player has logged in. Calling it here, because this is the first time that the PlayerController can take RPCs
|
||||||
|
DispatchPostLogin(NewPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
AGasaPlayerController* PC = Cast<AGasaPlayerController>(NewPlayer);
|
||||||
|
if (PC)
|
||||||
|
PC->Event_NetOwner_OnGameFrameworkInitialized.AddDynamic(this, &ThisClass::OwningClient_OnGameFrameworkInitialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::PostSeamlessTravel()
|
||||||
|
{
|
||||||
|
Super::PostSeamlessTravel();
|
||||||
|
NetLog("PostSeamlessTravel");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::SetPlayerDefaults(APawn* PlayerPawn)
|
||||||
|
{
|
||||||
|
InitializeHUDForPlayer(Cast<APlayerController>(PlayerPawn->GetController()));
|
||||||
|
Super::SetPlayerDefaults(PlayerPawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::SetSeamlessTravelViewTarget(APlayerController* PC)
|
||||||
|
{
|
||||||
|
Super::SetSeamlessTravelViewTarget(PC);
|
||||||
|
NetLog("SetSeamlessTravelViewTarget");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::StartPlay()
|
||||||
|
{
|
||||||
|
if (MatchState == MatchState::EnteringMap)
|
||||||
|
SetMatchState(MatchState::WaitingToStart);
|
||||||
|
|
||||||
|
// Start match is deferred until the framework is considered initialized.
|
||||||
|
NetLog("StartPlay");
|
||||||
|
|
||||||
|
UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
GI->Event_OnGameFrameworkInitialized.AddDynamic(this, &ThisClass::OnGameFrameworkInitialized);
|
||||||
|
GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::GameMode);
|
||||||
|
|
||||||
|
// Not called yet, will wait for initialization of the framework.
|
||||||
|
//Super::StartPlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::StartToLeaveMap()
|
||||||
|
{
|
||||||
|
NetLog("StartToLeaveMap");
|
||||||
|
Super::StartToLeaveMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameMode::SwapPlayerControllers(APlayerController* OldPC, APlayerController* NewPC)
|
||||||
|
{
|
||||||
|
NetLog("SwapPlayerControllers");
|
||||||
|
NetLog("Old: " + OldPC->GetName());
|
||||||
|
NetLog("New: " + NewPC->GetName());
|
||||||
|
|
||||||
|
Super::SwapPlayerControllers(OldPC, NewPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
APlayerController* AGasaGameMode::SpawnPlayerControllerCommon(ENetRole InRemoteRole, FVector const& SpawnLocation, FRotator const& SpawnRotation,
|
||||||
|
TSubclassOf<APlayerController> InPlayerControllerClass)
|
||||||
|
{
|
||||||
|
NetLog("SpawnPlayerControllerCommon");
|
||||||
|
return Super::SpawnPlayerControllerCommon(InRemoteRole, SpawnLocation, SpawnRotation, InPlayerControllerClass);
|
||||||
|
}
|
||||||
|
#pragma endregion GameModeBase
|
||||||
|
|||||||
@@ -1,28 +1,104 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "GameFramework/GameMode.h"
|
#include "GameFramework/GameMode.h"
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
|
||||||
#include "GasaGameMode.generated.h"
|
#include "GasaGameMode.generated.h"
|
||||||
|
|
||||||
UCLASS(Blueprintable)
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnLogoutSig, AGasaPlayerController*, PC);
|
||||||
|
|
||||||
|
UCLASS( Blueprintable )
|
||||||
class GASA_API AGasaGameMode : public AGameMode
|
class GASA_API AGasaGameMode : public AGameMode
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintAssignable)
|
||||||
|
FOnLogoutSig Event_OnLogout;
|
||||||
|
|
||||||
|
#pragma region GameFramework
|
||||||
|
UFUNCTION()
|
||||||
|
void OnGameFrameworkInitialized();
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void OwningClient_OnGameFrameworkInitialized(AGasaPlayerController* PC);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName = "On Game Framework Initialized"))
|
||||||
|
void BP_OnGameFrameworkInitialized();
|
||||||
|
#pragma endregion GameFramework
|
||||||
|
|
||||||
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
|
#pragma region GameMode
|
||||||
|
void HandleMatchAborted() override;
|
||||||
|
void HandleStartingNewPlayer_Implementation(APlayerController* NewPlayer) override;
|
||||||
|
|
||||||
|
bool ReadyToStartMatch_Implementation() override;
|
||||||
|
#pragma endregion GameMode
|
||||||
|
|
||||||
|
#pragma region GameModeBase
|
||||||
|
void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||||
|
|
||||||
|
void FinishRestartPlayer(AController* NewPlayer, const FRotator& StartRotation) override;
|
||||||
|
|
||||||
|
void GenericPlayerInitialization(AController* C) override;
|
||||||
|
|
||||||
|
TSubclassOf<APlayerController> GetPlayerControllerClassToSpawnForSeamlessTravel(APlayerController* PreviousPlayerController) override;
|
||||||
|
|
||||||
|
void HandleSeamlessTravelPlayer(AController*& C) override;
|
||||||
|
|
||||||
|
void InitializeHUDForPlayer_Implementation(APlayerController* NewPlayer) override;
|
||||||
|
void InitSeamlessTravelPlayer(AController* NewController) override;
|
||||||
|
|
||||||
|
void Logout(AController* Exiting) override;
|
||||||
|
|
||||||
|
void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage) override;
|
||||||
|
void PostLogin(APlayerController* NewPlayer) override;
|
||||||
|
void PostSeamlessTravel() override;
|
||||||
|
|
||||||
|
void SetPlayerDefaults(APawn* PlayerPawn) override;
|
||||||
|
void SetSeamlessTravelViewTarget(APlayerController* PC) override;
|
||||||
|
|
||||||
|
void StartPlay() override;
|
||||||
|
void StartToLeaveMap() override;
|
||||||
|
|
||||||
|
void SwapPlayerControllers(APlayerController* OldPC, APlayerController* NewPC) override;
|
||||||
|
|
||||||
|
APlayerController* SpawnPlayerControllerCommon(ENetRole InRemoteRole, FVector const& SpawnLocation, FRotator const& SpawnRotation, TSubclassOf<APlayerController> InPlayerControllerClass) override;
|
||||||
|
#pragma endregion GameModeBase
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Gasa
|
namespace Gasa
|
||||||
{
|
{
|
||||||
inline
|
inline AGasaGameMode* GetGameMode( UObject* Context )
|
||||||
AGasaGameMode* GetGameMode(UObject* Context)
|
|
||||||
{
|
{
|
||||||
UWorld* World = GEngine->GetWorldFromContextObject(Context, EGetWorldErrorMode::LogAndReturnNull);
|
UWorld* World = GEngine->GetWorldFromContextObject( Context, EGetWorldErrorMode::LogAndReturnNull );
|
||||||
if (World == nullptr)
|
if ( World == nullptr )
|
||||||
{
|
{
|
||||||
Log("World is null... are you running in a proper context?", ELogV::Error);
|
Log( "World is null... are you running in a proper context?", ELogV::Error );
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return Cast<AGasaGameMode>(World->GetAuthGameMode());
|
return Cast<AGasaGameMode>( World->GetAuthGameMode() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
#include "CogAll.h"
|
#include "CogAll.h"
|
||||||
#include "CogWindowManager.h"
|
#include "CogWindowManager.h"
|
||||||
|
#include "GasaPlayerState.h"
|
||||||
|
#include "GasaGameInstance.h"
|
||||||
|
#include "Net/UnrealNetwork.h"
|
||||||
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
|
using namespace Gasa;
|
||||||
|
|
||||||
AGasaGameState::AGasaGameState()
|
AGasaGameState::AGasaGameState()
|
||||||
{
|
{
|
||||||
@@ -9,26 +14,134 @@ AGasaGameState::AGasaGameState()
|
|||||||
PrimaryActorTick.bCanEverTick = true;
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
PrimaryActorTick.SetTickFunctionEnable(true);
|
PrimaryActorTick.SetTickFunctionEnable(true);
|
||||||
PrimaryActorTick.bStartWithTickEnabled = true;
|
PrimaryActorTick.bStartWithTickEnabled = true;
|
||||||
|
|
||||||
|
// Replication
|
||||||
|
bReplicates = true;
|
||||||
|
bNetLoadOnClient = false;
|
||||||
|
NetDormancy = DORM_Awake;
|
||||||
|
NetCullDistanceSquared = NetCullDist_Default;
|
||||||
|
NetUpdateFrequency = 10.0f;
|
||||||
|
MinNetUpdateFrequency = 1.0f;
|
||||||
|
NetPriority = 5.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma region GameState
|
#pragma region GameFramework
|
||||||
|
void AGasaGameState::OnGameFrameworkInitialized()
|
||||||
|
{
|
||||||
|
NetLog("Received gameplay framework initialization.");
|
||||||
|
if (IsServer())
|
||||||
|
{
|
||||||
|
if (PlayerArray.Num() > 0)
|
||||||
|
{
|
||||||
|
ListenServerHost = Cast<AGasaPlayerState>(PlayerArray[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NetLog("Was not able to assign HostingPlayer!", ELogV::Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BP_OnGameFrameworkInitialized();
|
||||||
|
}
|
||||||
|
#pragma endregion GameFramework
|
||||||
|
|
||||||
|
#pragma region Networking
|
||||||
|
void AGasaGameState::Client_OnRep_OnlinePlayers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#pragma endregion Networking
|
||||||
|
|
||||||
|
#pragma region Seamless Travel
|
||||||
|
void AGasaGameState::Multicast_R_NotifySeamlessTravelEnd_Implementation()
|
||||||
|
{
|
||||||
|
NetLog("Multicast_R_NotifySeamlessTravelEnd_Implementation");
|
||||||
|
BP_Event_OnSeamlessTravelEnd.Broadcast();
|
||||||
|
Event_OnSeamlessTravelEnd.Broadcast();
|
||||||
|
}
|
||||||
|
#pragma endregion Seamless Travel
|
||||||
|
|
||||||
|
#pragma region GameStateBase
|
||||||
|
void AGasaGameState::HandleBeginPlay()
|
||||||
|
{
|
||||||
|
Super::HandleBeginPlay();
|
||||||
|
NetLog("HandleBeginPlay: Directly called from GM");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaGameState::SeamlessTravelTransitionCheckpoint(bool bToTransitionMap)
|
||||||
|
{
|
||||||
|
Super::SeamlessTravelTransitionCheckpoint(bToTransitionMap);
|
||||||
|
NetLog("SeamlessTravelTransitionCheckpoint");
|
||||||
|
NetLog(FString("ToTransitionMap: ") + FString(bToTransitionMap ? "true" : "false"));
|
||||||
|
|
||||||
|
if (bToTransitionMap)
|
||||||
|
{
|
||||||
|
Event_OnSeamlessTravelStart.Broadcast();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Multicast_R_NotifySeamlessTravelEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion GameStateBase
|
||||||
|
|
||||||
|
#pragma region Actor
|
||||||
void AGasaGameState::BeginPlay()
|
void AGasaGameState::BeginPlay()
|
||||||
{
|
{
|
||||||
#if ENABLE_COG
|
Super::BeginPlay();
|
||||||
CogWindowManager = NewObject<UCogWindowManager>(this);
|
NetLog("BeginPlay");
|
||||||
CogWindowManagerRef = CogWindowManager;
|
|
||||||
|
|
||||||
// Add all the built-in windows
|
// Notified as initialized here as any possible components should also be initialized by this point.
|
||||||
Cog::AddAllWindows(*CogWindowManager);
|
UGasaGameInstance*
|
||||||
|
GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
GI->Event_OnGameFrameworkInitialized.AddDynamic(this, & ThisClass::OnGameFrameworkInitialized);
|
||||||
|
GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::GameState);
|
||||||
|
|
||||||
|
#if ENABLE_COG
|
||||||
|
CogWindowManager = NewObject<UCogWindowManager>(this);
|
||||||
|
CogWindowManagerRef = CogWindowManager;
|
||||||
|
|
||||||
|
// Add all the built-in windows
|
||||||
|
Cog::AddAllWindows(*CogWindowManager);
|
||||||
#endif //ENABLE_COG
|
#endif //ENABLE_COG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AGasaGameState::PostInitializeComponents()
|
||||||
|
{
|
||||||
|
NetLog("PostInitializeComponents");
|
||||||
|
Super::PostInitializeComponents();
|
||||||
|
|
||||||
|
if ( ! GetWorld()->IsEditorWorld() && IsServer())
|
||||||
|
{
|
||||||
|
OnlinePlayers.Empty();
|
||||||
|
#if 0
|
||||||
|
const auto GI = Cast<UGasaGameInstance>(GetGameInstance());
|
||||||
|
if (GI != nullptr)
|
||||||
|
{
|
||||||
|
int32 NumConnections = GI->SessionSettings.bPublicGame
|
||||||
|
? GI->SessionSettings.PublicConnections
|
||||||
|
: GI->SessionSettings.PrivateConnections;
|
||||||
|
OnlinePlayers.Init(nullptr, NumConnections);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AGasaGameState::Tick(float DeltaSeconds)
|
void AGasaGameState::Tick(float DeltaSeconds)
|
||||||
{
|
{
|
||||||
Super::Tick(DeltaSeconds);
|
Super::Tick(DeltaSeconds);
|
||||||
|
|
||||||
#if ENABLE_COG
|
#if ENABLE_COG
|
||||||
CogWindowManager->Tick(DeltaSeconds);
|
if (CogWindowManager)
|
||||||
|
CogWindowManager->Tick(DeltaSeconds);
|
||||||
#endif //ENABLE_COG
|
#endif //ENABLE_COG
|
||||||
}
|
}
|
||||||
#pragma endregion GameState
|
#pragma endregion Actor
|
||||||
|
|
||||||
|
#pragma region UObject
|
||||||
|
void AGasaGameState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||||
|
{
|
||||||
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||||
|
|
||||||
|
DOREPLIFETIME(AGasaGameState, ListenServerHost);
|
||||||
|
DOREPLIFETIME(AGasaGameState, OnlinePlayers);
|
||||||
|
}
|
||||||
|
#pragma endregion UObject
|
||||||
|
|||||||
@@ -1,46 +1,123 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GameFramework/GameState.h"
|
#include "GameFramework/GameState.h"
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "Networking/GasaNetLibrary.h"
|
||||||
|
|
||||||
#include "GasaGameState.generated.h"
|
#include "GasaGameState.generated.h"
|
||||||
|
|
||||||
UCLASS(Blueprintable)
|
UCLASS( Blueprintable )
|
||||||
class GASA_API AGasaGameState : public AGameState
|
class GASA_API AGasaGameState : public AGameState
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
#pragma region Cog
|
#pragma region Cog
|
||||||
// To make sure it doesn't get garbage collected.
|
// To make sure it doesn't get garbage collected.
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
TObjectPtr<UObject> CogWindowManagerRef;
|
TObjectPtr<UObject> CogWindowManagerRef;
|
||||||
|
|
||||||
#if ENABLE_COG
|
#if ENABLE_COG
|
||||||
TObjectPtr<UCogWindowManager> CogWindowManager;
|
TObjectPtr<UCogWindowManager> CogWindowManager;
|
||||||
#endif // ENABLE_COG
|
#endif
|
||||||
|
// ENABLE_COG
|
||||||
#pragma endregion Cog
|
#pragma endregion Cog
|
||||||
|
|
||||||
AGasaGameState();
|
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
|
||||||
|
UPROPERTY(Replicated, BlueprintReadOnly)
|
||||||
|
AGasaPlayerState* ListenServerHost;
|
||||||
|
|
||||||
|
UPROPERTY(ReplicatedUsing = "Client_OnRep_OnlinePlayers", BlueprintReadOnly)
|
||||||
|
TArray<AGasaPlayerState*> OnlinePlayers;
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void Client_OnRep_OnlinePlayers();
|
||||||
|
#pragma endregion Networking
|
||||||
|
|
||||||
|
#pragma region Seamless Travel
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FOnTravelSig Event_OnSeamlessTravelStart;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, meta=(DisplayName="Event: On Seamless Travel End"))
|
||||||
|
FOnTravelSig BP_Event_OnSeamlessTravelEnd;
|
||||||
|
|
||||||
|
FOnTravelDelegate Event_OnSeamlessTravelEnd;
|
||||||
|
|
||||||
|
UFUNCTION(NetMulticast, Reliable)
|
||||||
|
void Multicast_R_NotifySeamlessTravelEnd();
|
||||||
|
#pragma endregion Seamless Travel
|
||||||
|
|
||||||
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
#pragma region GameState
|
#pragma region GameState
|
||||||
void BeginPlay() override;
|
void HandleBeginPlay() override;
|
||||||
|
#pragma endregion GameState
|
||||||
|
|
||||||
void Tick(float DeltaSeconds) override;
|
#pragma region GameStateBase
|
||||||
#pragma endregion GameState
|
void SeamlessTravelTransitionCheckpoint(bool bToTransitionMap) override;
|
||||||
|
#pragma endregion GameStateBase
|
||||||
|
|
||||||
|
#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
|
namespace Gasa
|
||||||
{
|
{
|
||||||
inline
|
inline AGasaGameState* GetGameState( UObject* Context )
|
||||||
AGasaGameState* GetGameState(UObject* Context)
|
|
||||||
{
|
{
|
||||||
UWorld* World = GEngine->GetWorldFromContextObject(Context, EGetWorldErrorMode::LogAndReturnNull);
|
UWorld* World = GEngine->GetWorldFromContextObject( Context, EGetWorldErrorMode::LogAndReturnNull );
|
||||||
if (World == nullptr)
|
if ( World == nullptr )
|
||||||
{
|
{
|
||||||
Log("World is null... are you running in a proper context?", ELogV::Error);
|
Log( "World is null... are you running in a proper context?", ELogV::Error );
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return Cast<AGasaGameState>(World->GetGameState());
|
return Cast<AGasaGameState>( World->GetGameState() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,40 @@
|
|||||||
#include "GasaLevelScriptActor.h"
|
#include "GasaLevelScriptActor.h"
|
||||||
|
|
||||||
#include "GasaDevOptions.h"
|
#include "GasaDevOptions.h"
|
||||||
|
#include "GasaGameInstance.h"
|
||||||
|
#include "Engine/PostProcessVolume.h"
|
||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
#include "Materials/MaterialInstance.h"
|
||||||
|
#include "Materials/MaterialInstanceDynamic.h"
|
||||||
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
|
using namespace Gasa;
|
||||||
|
|
||||||
|
#pragma region Game Framework
|
||||||
|
AGasaLevelScriptActor::AGasaLevelScriptActor()
|
||||||
|
{
|
||||||
|
// Replication
|
||||||
|
|
||||||
|
bReplicates = true;
|
||||||
|
bNetLoadOnClient = true;
|
||||||
|
NetDormancy = DORM_Awake;
|
||||||
|
NetCullDistanceSquared = NetCullDist_Default;
|
||||||
|
NetUpdateFrequency = 10.0f;
|
||||||
|
MinNetUpdateFrequency = 1.0f;
|
||||||
|
NetPriority = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaLevelScriptActor::OnGameFrameworkInitialized()
|
||||||
|
{
|
||||||
|
NetLog("Received game framework initialization.");
|
||||||
|
BP_OnGameFrameworkInitialized();
|
||||||
|
}
|
||||||
|
#pragma endregion Game Framework
|
||||||
|
|
||||||
|
#pragma region Actor
|
||||||
void AGasaLevelScriptActor::BeginPlay()
|
void AGasaLevelScriptActor::BeginPlay()
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
|
NetLog("BeginPlay");
|
||||||
|
|
||||||
using namespace Gasa;
|
using namespace Gasa;
|
||||||
|
|
||||||
@@ -21,4 +50,12 @@ void AGasaLevelScriptActor::BeginPlay()
|
|||||||
PPV->Settings.WeightedBlendables.Array[0].Object = MID;
|
PPV->Settings.WeightedBlendables.Array[0].Object = MID;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
if(GI)
|
||||||
|
GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & ThisClass::OnGameFrameworkInitialized);
|
||||||
|
|
||||||
|
if (!bOverrideGameFrameworkReady)
|
||||||
|
GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::Levels);
|
||||||
}
|
}
|
||||||
|
#pragma endregion Actor
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
|
||||||
#include "Engine/LevelScriptActor.h"
|
#include "Engine/LevelScriptActor.h"
|
||||||
|
#include "Networking/GasaNetLibrary.h"
|
||||||
#include "GasaCommon.h"
|
|
||||||
|
|
||||||
#include "GasaLevelScriptActor.generated.h"
|
#include "GasaLevelScriptActor.generated.h"
|
||||||
|
|
||||||
@@ -14,9 +15,44 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Post Process")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Post Process")
|
||||||
TObjectPtr<APostProcessVolume> GlobalPPV;
|
TObjectPtr<APostProcessVolume> GlobalPPV;
|
||||||
|
|
||||||
|
AGasaLevelScriptActor();
|
||||||
|
|
||||||
|
#pragma region GameFramework
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||||
|
bool bOverrideGameFrameworkReady = false;
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void OnGameFrameworkInitialized();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta=(DisplayName="On Game Framework Initialized"))
|
||||||
|
void BP_OnGameFrameworkInitialized();
|
||||||
|
#pragma endregion GameFramework
|
||||||
|
|
||||||
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
#pragma region Actor
|
#pragma region Actor
|
||||||
void BeginPlay() override;
|
void BeginPlay() override;
|
||||||
#pragma region endActor
|
#pragma endregion endActor
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Gasa
|
namespace Gasa
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
#include "GasaPlayerController.h"
|
#include "GasaPlayerController.h"
|
||||||
|
#include "GasaPlayerController_Inlines.h"
|
||||||
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
|
|
||||||
#include "AbilitySystemComponent.h"
|
#include "AbilitySystemComponent.h"
|
||||||
|
#include "DrawDebugHelpers.h"
|
||||||
#include "Engine/LocalPlayer.h"
|
#include "Engine/LocalPlayer.h"
|
||||||
#include "EnhancedInputComponent.h"
|
#include "EnhancedInputComponent.h"
|
||||||
#include "EnhancedInputSubsystems.h"
|
#include "EnhancedInputSubsystems.h"
|
||||||
#include "GasaDevOptions.h"
|
|
||||||
#include "GasaPlayerState.h"
|
|
||||||
#include "Actors/CameraMount.h"
|
|
||||||
#include "Camera/CameraComponent.h"
|
|
||||||
#include "Characters/GasaCharacter.h"
|
#include "Characters/GasaCharacter.h"
|
||||||
|
#include "Characters/PlayerCharacter.h"
|
||||||
#include "Components/CapsuleComponent.h"
|
#include "Components/CapsuleComponent.h"
|
||||||
#include "GameFramework/SpringArmComponent.h"
|
#include "Interfaces/NetworkPredictionInterface.h"
|
||||||
#include "Kismet/KismetSystemLibrary.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 "AbilitySystem/GasaAbilitySystemComponent.h"
|
||||||
|
#include "Actors/CameraMount.h"
|
||||||
|
#include "UI/GasaHUD.h"
|
||||||
|
#include "UI/WidgetController.h"
|
||||||
using namespace Gasa;
|
using namespace Gasa;
|
||||||
|
|
||||||
AGasaPlayerController::AGasaPlayerController()
|
AGasaPlayerController::AGasaPlayerController()
|
||||||
@@ -24,6 +34,148 @@ 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();
|
||||||
|
|
||||||
|
Cam = GetWorld()->SpawnActor<ACameraMount>(GetDevOptions()->Template_PlayerCamera.Get(), FActorSpawnParameters() );
|
||||||
|
SetViewTarget(Cam);
|
||||||
|
|
||||||
|
AGasaPlayerState* PS = GetPlayerState();
|
||||||
|
APlayerCharacter* PlayerChar = GetPawn<APlayerCharacter>();
|
||||||
|
{
|
||||||
|
PlayerChar->AbilitySystem = PS->AbilitySystem;
|
||||||
|
PlayerChar->Attributes = PS->Attributes;
|
||||||
|
PS->AbilitySystem->InitAbilityActorInfo(PS, PlayerChar);
|
||||||
|
Cast<UGasaAbilitySystemComp>(PS->AbilitySystem)->OnAbilityActorInfoSet();
|
||||||
|
}
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
@@ -31,8 +183,6 @@ void AGasaPlayerController::Move(FInputActionValue const& ActionValue)
|
|||||||
if (pawn == nullptr )
|
if (pawn == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Note(Ed): I did the follow optimization for practice, they are completely unnecessary for this context.
|
// Note(Ed): I did the follow optimization for practice, they are completely unnecessary for this context.
|
||||||
#if 0
|
#if 0
|
||||||
FVector2D AxisV = ActionValue.Get<FVector2D>();
|
FVector2D AxisV = ActionValue.Get<FVector2D>();
|
||||||
@@ -72,28 +222,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::OnPossess(APawn* InPawn)
|
void AGasaPlayerController::ClientSetHUD_Implementation(TSubclassOf<AHUD> NewHUDClass)
|
||||||
{
|
{
|
||||||
Super::OnPossess(InPawn);
|
Super::ClientSetHUD_Implementation(NewHUDClass);
|
||||||
|
AGasaPlayerState* PS = GetPlayerState();
|
||||||
|
AGasaHUD* HUD = GetHUD<AGasaHUD>();
|
||||||
|
FWidgetControllerData Data = { this, PS, PS->AbilitySystem, PS->Attributes };
|
||||||
|
HUD->InitHostWidget(& Data);
|
||||||
|
}
|
||||||
|
|
||||||
Cam->AttachToActor(InPawn, FAttachmentTransformRules::KeepRelativeTransform);
|
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);
|
||||||
|
|
||||||
AGasaPlayerState* PS = GetPlayerState();
|
NetLog("ClientUpdateLevelStreamingStatus");
|
||||||
AGasaCharacter* character = Cast<AGasaCharacter>(InPawn);
|
NetLog(FString("PackageName : ") + PackageName.ToString());
|
||||||
// Net Owner setup ability system
|
NetLog(FString("NewShouldBeLoaded : ") + FString(bNewShouldBeLoaded ? "true" : "false"));
|
||||||
if (0)
|
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* PawnPossesed)
|
||||||
|
{
|
||||||
|
// Super::OnPossess(PawnPossesed);
|
||||||
{
|
{
|
||||||
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();
|
||||||
@@ -137,6 +368,11 @@ void AGasaPlayerController::PlayerTick(float DeltaTime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AGasaPlayerController::PostSeamlessTravel()
|
||||||
|
{
|
||||||
|
Super::PostSeamlessTravel();
|
||||||
|
}
|
||||||
|
|
||||||
void AGasaPlayerController::SetupInputComponent()
|
void AGasaPlayerController::SetupInputComponent()
|
||||||
{
|
{
|
||||||
Super::SetupInputComponent();
|
Super::SetupInputComponent();
|
||||||
@@ -147,41 +383,50 @@ 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");
|
||||||
|
|
||||||
check(IMC);
|
UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & AGasaPlayerController::OnGameFrameworkInitialized);
|
||||||
UEnhancedInputLocalPlayerSubsystem*
|
GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::PlayerController);
|
||||||
EILP_Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
|
|
||||||
check(EILP_Subsystem);
|
if (IsLocalController())
|
||||||
EILP_Subsystem->AddMappingContext(IMC, 0);
|
|
||||||
{
|
{
|
||||||
bShowMouseCursor = true;
|
check(IMC);
|
||||||
DefaultMouseCursor = EMouseCursor::Default;
|
|
||||||
FInputModeGameAndUI MouseMode;
|
UEnhancedInputLocalPlayerSubsystem*
|
||||||
MouseMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
|
EILP_Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
|
||||||
MouseMode.SetHideCursorDuringCapture(false);
|
check(EILP_Subsystem);
|
||||||
SetInputMode(MouseMode);
|
EILP_Subsystem->AddMappingContext(IMC, 0);
|
||||||
|
{
|
||||||
|
bShowMouseCursor = true;
|
||||||
|
DefaultMouseCursor = EMouseCursor::Default;
|
||||||
|
FInputModeGameAndUI MouseMode;
|
||||||
|
MouseMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
|
||||||
|
MouseMode.SetHideCursorDuringCapture(false);
|
||||||
|
SetInputMode(MouseMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaPlayerController::PostInitializeComponents()
|
void AGasaPlayerController::PostInitializeComponents()
|
||||||
{
|
{
|
||||||
Super::PostInitializeComponents();
|
Super::PostInitializeComponents();
|
||||||
|
|
||||||
Cam = GetWorld()->SpawnActor<ACameraMount>(GetDevOptions()->Template_PlayerCamera.Get(), FActorSpawnParameters() );
|
|
||||||
SetViewTarget(Cam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaPlayerController::Tick(float DeltaSeconds)
|
void AGasaPlayerController::Tick(float DeltaSeconds)
|
||||||
{
|
{
|
||||||
Super::Tick(DeltaSeconds);
|
Super::Tick(DeltaSeconds);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
switch (HighlightState)
|
switch (HighlightState)
|
||||||
{
|
{
|
||||||
@@ -205,4 +450,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
|
||||||
|
|||||||
@@ -2,15 +2,25 @@
|
|||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
#include "GasaPlayerState.h"
|
#include "GasaPlayerState.h"
|
||||||
|
#include "Networking/GasaNetLibrary.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
#include "GameFramework/PlayerController.h"
|
#include "GameFramework/PlayerController.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;
|
||||||
@@ -32,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)
|
||||||
@@ -49,32 +108,57 @@ public:
|
|||||||
void Move(FInputActionValue const& ActionValue);
|
void Move(FInputActionValue const& ActionValue);
|
||||||
#pragma endregion Input
|
#pragma endregion Input
|
||||||
|
|
||||||
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
AGasaPlayerController();
|
AGasaPlayerController();
|
||||||
|
|
||||||
AGasaPlayerState* GetPlayerState()
|
inline AGasaPlayerState* GetPlayerState();
|
||||||
{
|
|
||||||
return Cast<AGasaPlayerState>( PlayerState );
|
|
||||||
}
|
|
||||||
|
|
||||||
#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
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "GasaPlayerController.h"
|
||||||
|
#include "GasaPlayerState.h"
|
||||||
|
|
||||||
|
inline
|
||||||
|
AGasaPlayerState* AGasaPlayerController::GetPlayerState()
|
||||||
|
{
|
||||||
|
return Cast<AGasaPlayerState>( PlayerState );
|
||||||
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
#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"
|
||||||
|
|
||||||
AGasaPlayerState::AGasaPlayerState()
|
AGasaPlayerState::AGasaPlayerState()
|
||||||
{
|
{
|
||||||
|
bAutoAbilitySystem = true;
|
||||||
|
|
||||||
AbilitySystem = CreateDefaultSubobject<UGasaAbilitySystemComp>("Ability System");
|
AbilitySystem = CreateDefaultSubobject<UGasaAbilitySystemComp>("Ability System");
|
||||||
AbilitySystem->SetIsReplicated(true);
|
AbilitySystem->SetIsReplicated(true);
|
||||||
AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
|
AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
|
||||||
@@ -14,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
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "GameFramework/PlayerState.h"
|
#include "GameFramework/PlayerState.h"
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
#include "Networking/GasaNetLibrary.h"
|
||||||
|
|
||||||
#include "GasaPlayerState.generated.h"
|
#include "GasaPlayerState.generated.h"
|
||||||
|
|
||||||
@@ -14,9 +15,11 @@ 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 = true;
|
bool bAutoAbilitySystem;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, Category="Ability System")
|
UPROPERTY(EditAnywhere, Category="Ability System")
|
||||||
TObjectPtr<UAbilitySystemComponent> AbilitySystem;
|
TObjectPtr<UAbilitySystemComponent> AbilitySystem;
|
||||||
@@ -24,15 +27,70 @@ 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
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
AGasaPlayerState();
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
#pragma region IAbilitySystem
|
#pragma region IAbilitySystem
|
||||||
FORCEINLINE UAttributeSet* GetAttributes() { return Attributes; }
|
FORCEINLINE UAttributeSet* GetAttributes() { return Attributes; }
|
||||||
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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using UnrealBuildTool;
|
||||||
using ModuleRules = UnrealBuildTool.ModuleRules;
|
using ModuleRules = UnrealBuildTool.ModuleRules;
|
||||||
using ReadOnlyTargetRules = UnrealBuildTool.ReadOnlyTargetRules;
|
using ReadOnlyTargetRules = UnrealBuildTool.ReadOnlyTargetRules;
|
||||||
using TargetRules = UnrealBuildTool.TargetRules;
|
using TargetRules = UnrealBuildTool.TargetRules;
|
||||||
@@ -10,7 +10,33 @@ public class Gasa : ModuleRules
|
|||||||
{
|
{
|
||||||
public Gasa(ReadOnlyTargetRules Target) : base(Target)
|
public Gasa(ReadOnlyTargetRules Target) : base(Target)
|
||||||
{
|
{
|
||||||
bUseUnity = false;
|
bUseUnity = false;
|
||||||
|
bMergeUnityFiles = false;
|
||||||
|
IWYUSupport = IWYUSupport.None;
|
||||||
|
PCHUsage = PCHUsageMode.NoPCHs;
|
||||||
|
OptimizeCode = CodeOptimization.Never;
|
||||||
|
MinCpuArchX64 = MinimumCpuArchitectureX64.AVX512;
|
||||||
|
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
|
||||||
|
|
||||||
|
bCodeCoverage = false;
|
||||||
|
bDisableStaticAnalysis = true;
|
||||||
|
bValidateCircularDependencies = true;
|
||||||
|
bValidateFormatStrings = false;
|
||||||
|
bValidateInternalApi = false;
|
||||||
|
bEnableExceptions = false;
|
||||||
|
bEnableBufferSecurityChecks = false;
|
||||||
|
bEnableNonInlinedGenCppWarnings = false;
|
||||||
|
bEnableUndefinedIdentifierWarnings = false;
|
||||||
|
bIgnoreUnresolvedSymbols = false;
|
||||||
|
|
||||||
|
bEnableObjCAutomaticReferenceCounting = false;
|
||||||
|
bEnableObjCExceptions = false;
|
||||||
|
|
||||||
|
var Kilobyte = 1024;
|
||||||
|
NumIncludedBytesPerUnityCPPOverride = Kilobyte * 32;
|
||||||
|
MinFilesUsingPrecompiledHeaderOverride = 1;
|
||||||
|
|
||||||
|
PrivatePCHHeaderFile = "GasaColdHeadersPCH.h";
|
||||||
|
|
||||||
#region Engine
|
#region Engine
|
||||||
PrivateIncludePathModuleNames.AddRange(new string[] {
|
PrivateIncludePathModuleNames.AddRange(new string[] {
|
||||||
@@ -22,6 +48,7 @@ public class Gasa : ModuleRules
|
|||||||
"Core",
|
"Core",
|
||||||
|
|
||||||
"AIModule",
|
"AIModule",
|
||||||
|
"CoreOnline",
|
||||||
"CoreUObject",
|
"CoreUObject",
|
||||||
"DeveloperSettings",
|
"DeveloperSettings",
|
||||||
"Engine",
|
"Engine",
|
||||||
@@ -32,6 +59,7 @@ public class Gasa : ModuleRules
|
|||||||
"InputCore",
|
"InputCore",
|
||||||
"NetCore",
|
"NetCore",
|
||||||
"Niagara",
|
"Niagara",
|
||||||
|
"OnlineSubsystem",
|
||||||
"SlateCore",
|
"SlateCore",
|
||||||
"UMG",
|
"UMG",
|
||||||
});
|
});
|
||||||
@@ -56,6 +84,15 @@ public class Gasa : ModuleRules
|
|||||||
PrivateIncludePathModuleNames.AddRange( new string[]
|
PrivateIncludePathModuleNames.AddRange( new string[]
|
||||||
{
|
{
|
||||||
"CogCommon",
|
"CogCommon",
|
||||||
|
"CogAbility",
|
||||||
|
"CogAI",
|
||||||
|
"CogAll",
|
||||||
|
"CogDebug",
|
||||||
|
"CogDebugEditor",
|
||||||
|
"CogEngine",
|
||||||
|
"CogImgui",
|
||||||
|
"CogInput",
|
||||||
|
"CogWindow",
|
||||||
});
|
});
|
||||||
PrivateDependencyModuleNames.AddRange(new string[]
|
PrivateDependencyModuleNames.AddRange(new string[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaEngineMinimal.h"
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
#include "GasaGameplayTags.h"
|
||||||
|
#include "GasaLibrary.h"
|
||||||
|
#include "GasaModule.h"
|
||||||
|
#include "GasaViewportSubsystem.h"
|
||||||
|
#include "GasaDevOptions.h"
|
||||||
|
#include "GasaDevOptionsCache.h"
|
||||||
|
|
||||||
|
// Ability System
|
||||||
|
// #include "AbilitySystem/"
|
||||||
|
#include "AbilitySystem/GasaAbilitySystem.h"
|
||||||
|
// #include "AbilitySystem/GasaAbilitySystemComponent.h"
|
||||||
|
// #include "AbilitySystem/GasaAttributeSet.h"
|
||||||
|
// #include "GasaEffectActor.h"
|
||||||
|
|
||||||
|
// Actors
|
||||||
|
#include "Actors/CameraMount.h"
|
||||||
|
|
||||||
|
// Characters
|
||||||
|
// #include "Characters/GasaCharacter.h"
|
||||||
|
// #include "Characters/EnemyCharacter.h"
|
||||||
|
// #include "Characters/PlayerCharacter.h"
|
||||||
|
|
||||||
|
// Game
|
||||||
|
// #include "Game/GasaGameInstance.h"
|
||||||
|
// #include "Game/GasaGameMode.h"
|
||||||
|
// #include "Game/GasaGameState.h"
|
||||||
|
// #include "Game/GasaLevelScriptActor.h"
|
||||||
|
// #include "Game/GasaPlayerController.h"
|
||||||
|
// #include "Game/GasaPlayerController_Inlines.h"
|
||||||
|
// #include "Game/GasaPlayerState.h"
|
||||||
|
#include "Game/GasaViewport.h"
|
||||||
|
|
||||||
|
// Networking
|
||||||
|
#include "Networking/GasaNetLibrary.h"
|
||||||
|
#include "Networking/GasaNetLibrary_Inlines.h"
|
||||||
|
|
||||||
|
// UI
|
||||||
|
// #include "UI/GasaCanvas.h"
|
||||||
|
// #include "UI/GasaCanvasPanel.h"
|
||||||
|
// #include "UI/GasaHUD.h"
|
||||||
|
// #include "UI/GasaHUD_Inlines.h"
|
||||||
|
// #include "UI/GasaImage.h"
|
||||||
|
// #include "UI/GasaOverlay.h"
|
||||||
|
// #include "UI/GasaProgressBar.h"
|
||||||
|
// #include "UI/GasaSizeBox.h"
|
||||||
|
// #include "UI/GasaUserWidget.h"
|
||||||
|
// #include "UI/HostWidgetController.h"
|
||||||
|
// #include "UI/HUDHostWidget.h"
|
||||||
|
// #include "UI/WidgetController.h"
|
||||||
@@ -1,30 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "GasaEngineMinimal.h"
|
||||||
// #define private protected
|
|
||||||
|
#include "GasaCommon.generated.h"
|
||||||
|
|
||||||
#define global
|
#define global
|
||||||
#define internal static
|
#define internal static
|
||||||
#define local_persist static
|
#define local_persist static
|
||||||
|
|
||||||
|
#define ccast( Type, Value ) ( *const_cast<(Type)*>( &( Value ) ) )
|
||||||
|
#define pcast( Type, Value ) ( *reinterpret_cast<(Type)*>( &( Value ) ) )
|
||||||
|
#define rcast( Type, Value ) reinterpret_cast<Type>( Value )
|
||||||
|
#define scast( Type, Value ) static_cast<Type>( Value )
|
||||||
|
|
||||||
|
#define bit(position) (1 << position)
|
||||||
|
|
||||||
#pragma region Math
|
#pragma region Math
|
||||||
#define m_pow2( value ) (value * value)
|
#define m_pow2( value ) (value * value)
|
||||||
#pragma endregion Math
|
#pragma endregion Math
|
||||||
|
|
||||||
#pragma region Engine Forwards
|
#pragma region Engine Forwards
|
||||||
struct FInputActionValue;
|
struct FInputActionValue;
|
||||||
|
struct FGameplayEffectContextHandle;
|
||||||
|
struct FGameplayEffectModCallbackData;
|
||||||
|
struct FGameplayTagContainer;
|
||||||
|
struct FOnAttributeChangeData;
|
||||||
|
struct FReplicationFlags;
|
||||||
|
|
||||||
|
class AActor;
|
||||||
|
class APawn;
|
||||||
|
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 UInputAction;
|
class UInputAction;
|
||||||
class UInputMappingContext;
|
class UInputMappingContext;
|
||||||
class USphereComponent;
|
class USphereComponent;
|
||||||
class USpringArmComponent;
|
class USpringArmComponent;
|
||||||
|
class UTexture2D;
|
||||||
#pragma endregion Engine Forwards
|
#pragma endregion Engine Forwards
|
||||||
|
|
||||||
#pragma region Engine Plugin Forwards
|
#pragma region Engine Plugin Forwards
|
||||||
@@ -34,23 +55,63 @@ class UCogWindowManager;
|
|||||||
// Gasa
|
// Gasa
|
||||||
|
|
||||||
#pragma region Forwards
|
#pragma region Forwards
|
||||||
|
struct FWidgetControllerData;
|
||||||
|
|
||||||
class ACameraMount;
|
class ACameraMount;
|
||||||
class AGasaCharacter;
|
class AGasaCharacter;
|
||||||
class AGasaGameInstance;
|
class AGasaGameInstance;
|
||||||
class AGasaGameState;
|
class AGasaGameState;
|
||||||
class AGasaLevelScriptActor;
|
class AGasaLevelScriptActor;
|
||||||
class AGasaPlayerController;
|
class AGasaPlayerController;
|
||||||
|
class AGasaPlayerState;
|
||||||
|
class APlayerCharacter;
|
||||||
|
|
||||||
class UGasaAbilitySystemComp;
|
class UGasaAbilitySystemComp;
|
||||||
class UGasaAttributeSet;
|
class UGasaAttributeSet;
|
||||||
class UGasaDevOptions;
|
class UGasaDevOptions;
|
||||||
class UGasaImage;
|
class UGasaImage;
|
||||||
|
class UGasaObject;
|
||||||
class UGasaOverlay;
|
class UGasaOverlay;
|
||||||
class UGasaProgressBar;
|
class UGasaProgressBar;
|
||||||
class UGasaSizeBox;
|
class UGasaSizeBox;
|
||||||
class UUI_HostWidget;
|
class UGasaUserWidget;
|
||||||
|
class UHostWidgetController;
|
||||||
|
class UHUDHostWidget;
|
||||||
|
class UWidgetController;
|
||||||
#pragma endregion Forwards
|
#pragma endregion Forwards
|
||||||
|
|
||||||
|
#pragma region Bitfields
|
||||||
|
namespace Gasa
|
||||||
|
{
|
||||||
|
inline
|
||||||
|
bool Bitfield_IsSet(int32 Bitfield, int32 Bitmask) {
|
||||||
|
bool Result = Bitmask == (Bitfield & Bitmask);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
inline
|
||||||
|
bool Bitfield_IsSetExactly(int32 Bitfield, int32 Bitmask)
|
||||||
|
{
|
||||||
|
bool Result = Bitfield == (Bitfield & Bitmask);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Bitfield_Set ( int32& Bitfield, int32 BitsToAdd ) { Bitfield |= BitsToAdd; }
|
||||||
|
inline void Bitfield_Remove( int32& Bitfield, int32 BitsToRemove ) { Bitfield &= (! BitsToRemove); }
|
||||||
|
inline void Bitfield_Toggle( int32& Bitfield, int32 Bitmask ) { Bitfield ^= Bitmask; }
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
|
inline
|
||||||
|
bool Bitfield_IsSet(int32 Bitfield, EnumType Mask)
|
||||||
|
{
|
||||||
|
bool Result = int32(Mask) == (Bitfield & int32(Mask));
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
template<typename EnumType> inline void Bitfield_Set ( int32& Bitfield, EnumType BitToAdd ) { Bitfield |= int32(BitToAdd); }
|
||||||
|
template<typename EnumType> inline void Bitfield_Remove( int32& Bitfield, EnumType BitToRemove ) { Bitfield &= (! int32(BitToRemove)); }
|
||||||
|
template<typename EnumType> inline void Bitfield_Toggle( int32& Bitfield, EnumType BitToToggle ) { Bitfield ^= int32(BitToToggle); }
|
||||||
|
}
|
||||||
|
#pragma endregion Bitfields
|
||||||
|
|
||||||
#pragma region Logging
|
#pragma region Logging
|
||||||
// Straight from the Engine
|
// Straight from the Engine
|
||||||
UENUM(BlueprintType)
|
UENUM(BlueprintType)
|
||||||
@@ -100,10 +161,10 @@ namespace Gasa
|
|||||||
{
|
{
|
||||||
using ELogV = EGasaVerbosity;
|
using ELogV = EGasaVerbosity;
|
||||||
|
|
||||||
//◞ ‸ ◟//
|
|
||||||
// Works for Unreal 5.4, Win64 MSVC (untested in other scenarios, for now)
|
// Works for Unreal 5.4, Win64 MSVC (untested in other scenarios, for now)
|
||||||
inline
|
inline
|
||||||
void Log( FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log
|
void Log( FString Message
|
||||||
|
, EGasaVerbosity Verbosity = EGasaVerbosity::Log
|
||||||
, FLogCategoryBase& Category = LogGasa
|
, FLogCategoryBase& Category = LogGasa
|
||||||
, bool DumpStack = false
|
, bool DumpStack = false
|
||||||
, int32 Line = __builtin_LINE()
|
, int32 Line = __builtin_LINE()
|
||||||
@@ -160,3 +221,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
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
|
||||||
|
template<typename RowType>
|
||||||
|
inline
|
||||||
|
RowType* GetDataTableRowByTag(UDataTable* DT, FGameplayTag& Tag)
|
||||||
|
{
|
||||||
|
RowType* Row = DT->FindRow<RowType>(Tag.GetTagName(), TEXT(""));
|
||||||
|
return Row;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename KeyType, typename ValueType>
|
||||||
|
inline
|
||||||
|
void RemoveKeys(TMap<KeyType, ValueType> Map, TArray<KeyType> Keys)
|
||||||
|
{
|
||||||
|
for (KeyType& Key : Keys )
|
||||||
|
{
|
||||||
|
Map.Remove(Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#include "GasaDevOptions.h"
|
#include "GasaDevOptions.h"
|
||||||
|
|
||||||
#include "Actors/CameraMount.h"
|
#include "Actors/CameraMount.h"
|
||||||
#include "UI/UI_HostWidget.h"
|
#include "UI/HUDHostWidget.h"
|
||||||
|
#include "UI/HostWidgetController.h"
|
||||||
|
|
||||||
using namespace Gasa;
|
using namespace Gasa;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Engine/DataTable.h"
|
||||||
#include "Engine/DeveloperSettings.h"
|
#include "Engine/DeveloperSettings.h"
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
|
||||||
#include "GasaDevOptions.generated.h"
|
#include "GasaDevOptions.generated.h"
|
||||||
|
|
||||||
|
|
||||||
UCLASS(Config=Game, DefaultConfig, meta=(DisplayName="Gasa"))
|
UCLASS(Config=Game, DefaultConfig, meta=(DisplayName="Gasa"))
|
||||||
class GASA_API UGasaDevOptions : public UDeveloperSettings
|
class GASA_API UGasaDevOptions : public UDeveloperSettings
|
||||||
{
|
{
|
||||||
@@ -15,11 +16,17 @@ public:
|
|||||||
// NOTE(Ed): Any Soft-References must have their includes defined in GasaDevOptions.cpp
|
// NOTE(Ed): Any Soft-References must have their includes defined in GasaDevOptions.cpp
|
||||||
// They are used by GasaGen for the GasaDevOptionsCache
|
// They are used by GasaGen for the GasaDevOptionsCache
|
||||||
|
|
||||||
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
|
||||||
|
TSoftObjectPtr<UDataTable> TaggedMessageTable;
|
||||||
|
|
||||||
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
|
||||||
TSoftClassPtr<ACameraMount> Template_PlayerCamera;
|
TSoftClassPtr<ACameraMount> Template_PlayerCamera;
|
||||||
|
|
||||||
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
|
||||||
TSoftClassPtr<UUI_HostWidget> Template_HUD_HostUI;
|
TSoftClassPtr<UHUDHostWidget> Template_HUD_HostUI;
|
||||||
|
|
||||||
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
|
||||||
|
TSoftClassPtr<UHostWidgetController> Template_HostWidgetController;
|
||||||
|
|
||||||
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Tags")
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Tags")
|
||||||
FName Tag_GlobalPPV;
|
FName Tag_GlobalPPV;
|
||||||
|
|||||||
@@ -1,17 +1,32 @@
|
|||||||
// This was generated by GasaGen/GasaGen.cpp
|
// Generated by GasaGen/GasaGen_DevOptionsCache.cpp
|
||||||
#include "GasaDevOptionsCache.h"
|
#include "GasaDevOptionsCache.h"
|
||||||
|
|
||||||
#include "GasaDevOptions.h"
|
#include "GasaDevOptions.h"
|
||||||
#include "Actors/CameraMount.h"
|
#include "Actors/CameraMount.h"
|
||||||
#include "UI/UI_HostWidget.h"
|
#include "UI/HUDHostWidget.h"
|
||||||
|
#include "UI/HostWidgetController.h"
|
||||||
using namespace Gasa;
|
using namespace Gasa;
|
||||||
|
|
||||||
void FGasaDevOptionsCache::CachedDevOptions()
|
void FGasaDevOptionsCache::CachedDevOptions()
|
||||||
{
|
{
|
||||||
UGasaDevOptions* DevOpts = GetMutDevOptions();
|
UGasaDevOptions* DevOpts = GetMutDevOptions();
|
||||||
|
|
||||||
|
TaggedMessageTable = DevOpts->TaggedMessageTable.LoadSynchronous();
|
||||||
|
ensureMsgf( TaggedMessageTable != nullptr, TEXT( "TaggedMessageTable is null, DO NOT RUN PIE or else you may get a crash if not handled in BP or C++" ) );
|
||||||
|
|
||||||
Template_PlayerCamera = DevOpts->Template_PlayerCamera.LoadSynchronous();
|
Template_PlayerCamera = DevOpts->Template_PlayerCamera.LoadSynchronous();
|
||||||
Template_HUD_HostUI = DevOpts->Template_HUD_HostUI.LoadSynchronous();
|
ensureMsgf(
|
||||||
|
Template_PlayerCamera != nullptr, TEXT( "Template_PlayerCamera is null, DO NOT RUN PIE or else you may get a crash if not handled in BP or C++" )
|
||||||
|
);
|
||||||
|
|
||||||
|
Template_HUD_HostUI = DevOpts->Template_HUD_HostUI.LoadSynchronous();
|
||||||
|
ensureMsgf( Template_HUD_HostUI != nullptr, TEXT( "Template_HUD_HostUI is null, DO NOT RUN PIE or else you may get a crash if not handled in BP or C++" ) );
|
||||||
|
|
||||||
|
Template_HostWidgetController = DevOpts->Template_HostWidgetController.LoadSynchronous();
|
||||||
|
ensureMsgf(
|
||||||
|
Template_HostWidgetController != nullptr,
|
||||||
|
TEXT( "Template_HostWidgetController is null, DO NOT RUN PIE or else you may get a crash if not handled in BP or C++" )
|
||||||
|
);
|
||||||
|
|
||||||
Tag_GlobalPPV = DevOpts->Tag_GlobalPPV;
|
Tag_GlobalPPV = DevOpts->Tag_GlobalPPV;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// This was generated by GasaGen/GasaGen.cpp
|
// Generated by GasaGen/GasaGen_DevOptionsCache.cpp
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GasaDevOptionsCache.generated.h"
|
#include "GasaDevOptionsCache.generated.h"
|
||||||
@@ -8,10 +8,14 @@ struct GASA_API FGasaDevOptionsCache
|
|||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
UObject* TaggedMessageTable;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
UClass* Template_PlayerCamera;
|
UClass* Template_PlayerCamera;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
UClass* Template_HUD_HostUI;
|
UClass* Template_HUD_HostUI;
|
||||||
|
UPROPERTY()
|
||||||
|
UClass* Template_HostWidgetController;
|
||||||
|
|
||||||
void CachedDevOptions();
|
void CachedDevOptions();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Low level includes.
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "CoreTypes.h"
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Forward declarations
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "CoreFwd.h"
|
||||||
|
#include "UObject/UObjectHierarchyFwd.h"
|
||||||
|
#include "Containers/ContainersFwd.h"
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Commonly used headers
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Misc/VarArgs.h"
|
||||||
|
#include "Logging/LogVerbosity.h"
|
||||||
|
#include "UObject/ObjectMacros.h"
|
||||||
|
#include "Delegates/Delegate.h"
|
||||||
|
#include "Delegates/DelegateCombinations.h"
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "Game/GasaGameState.h"
|
#include "Game/GasaGameState.h"
|
||||||
#include "Game/GasaPlayerController.h"
|
#include "Game/GasaPlayerController.h"
|
||||||
#include "Kismet/KismetSystemLibrary.h"
|
#include "Kismet/KismetSystemLibrary.h"
|
||||||
|
#include "Misc/ConfigCacheIni.h"
|
||||||
|
|
||||||
#pragma region Game
|
#pragma region Game
|
||||||
UGasaDevOptions* UGasaLib::GetGasaDevOptions(UObject* Context) {
|
UGasaDevOptions* UGasaLib::GetGasaDevOptions(UObject* Context) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
|
||||||
#include "GasaLibrary.Generated.h"
|
#include "GasaLibrary.Generated.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Modules/ModuleInterface.h"
|
#include "Modules/ModuleInterface.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
class GASA_API FGasaModule : public IModuleInterface
|
class GASA_API FGasaModule : public IModuleInterface
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#include "GasaObject.h"
|
||||||
|
|
||||||
|
#include "Engine/ActorChannel.h"
|
||||||
|
#include "Engine/BlueprintGeneratedClass.h"
|
||||||
|
#include "Engine/NetDriver.h"
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
|
using namespace Gasa;
|
||||||
|
|
||||||
|
UGasaObject::UGasaObject()
|
||||||
|
{
|
||||||
|
bReplicates = false;
|
||||||
|
bDisconnectOnBadReplication = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGasaObject::Destroy()
|
||||||
|
{
|
||||||
|
if ( ! IsValid(this))
|
||||||
|
{
|
||||||
|
checkf(GetOwningActor()->HasAuthority() == true, TEXT("Destroy:: Object does not have authority to destroy itself!"));
|
||||||
|
OnDestroyed();
|
||||||
|
Event_OnDestroyed.Broadcast();
|
||||||
|
ConditionalBeginDestroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGasaObject::OnDestroyed()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UGasaObject::ReplicateAsSubobject(AActor* ActorResponsible, UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags)
|
||||||
|
{
|
||||||
|
if (!ActorResponsible)
|
||||||
|
{
|
||||||
|
NetLog("Actor reponsible is null", ELogV::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!bDisconnectOnBadReplication && ActorResponsible != GetOuter())
|
||||||
|
{
|
||||||
|
NetLog("Attempted to replicate whose outer was not set to the actor whose responsible for replicating it as a subobject", ELogV::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Channel->ReplicateSubobject(this, *Bunch, *RepFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UGasaObject::CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack)
|
||||||
|
{
|
||||||
|
check(! HasAnyFlags(RF_ClassDefaultObject));
|
||||||
|
AActor* Owner = GetOwningActor();
|
||||||
|
UNetDriver* NetDriver = Owner->GetNetDriver();
|
||||||
|
if (NetDriver)
|
||||||
|
{
|
||||||
|
NetDriver->ProcessRemoteFunction(Owner, Function, Parms, OutParms, Stack, this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 UGasaObject::GetFunctionCallspace(UFunction* Function, FFrame* Stack)
|
||||||
|
{
|
||||||
|
check(GetOuter() != nullptr);
|
||||||
|
return GetOuter()->GetFunctionCallspace(Function, Stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGasaObject::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||||
|
{
|
||||||
|
// Add any Blueprint properties
|
||||||
|
// This is not required if you do not want the class to be "Blueprintable"
|
||||||
|
if (const UBlueprintGeneratedClass* BP = Cast<UBlueprintGeneratedClass>(GetClass()))
|
||||||
|
{
|
||||||
|
BP->GetLifetimeBlueprintReplicationList(OutLifetimeProps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UGasaObject::IsSupportedForNetworking() const
|
||||||
|
{
|
||||||
|
return bReplicates;
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
#include "Networking/GasaNetLibrary.h"
|
||||||
|
#include "UObject/Object.h"
|
||||||
|
#include "GasaObject.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FGasaObjectEventSig);
|
||||||
|
|
||||||
|
// A UObject which supports replication and other features.
|
||||||
|
UCLASS( Blueprintable )
|
||||||
|
class GASA_API UGasaObject : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
|
||||||
|
UGasaObject();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintPure)
|
||||||
|
FORCEINLINE AActor* GetOwningActor() const { return GetTypedOuter<AActor>(); };
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="Lifetime")
|
||||||
|
FGasaObjectEventSig Event_OnDestroyed;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Lifetime")
|
||||||
|
virtual void Destroy();
|
||||||
|
|
||||||
|
virtual void OnDestroyed();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName = "On Destroyed"))
|
||||||
|
void BP_OnDestroyed();
|
||||||
|
|
||||||
|
#pragma region Replication
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Replication")
|
||||||
|
bool bReplicates;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Replication")
|
||||||
|
bool bDisconnectOnBadReplication ;
|
||||||
|
|
||||||
|
virtual bool ReplicateAsSubobject(AActor* ActorResponsible, UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void SetIsReplicated(bool DesiredValue)
|
||||||
|
{
|
||||||
|
bReplicates = DesiredValue;
|
||||||
|
}
|
||||||
|
#pragma endregion Replication
|
||||||
|
|
||||||
|
#pragma region NetSlime
|
||||||
|
// NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp
|
||||||
|
FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode( this ); }
|
||||||
|
FORCEINLINE bool IsClient() const { return Gasa::IsClient( this ); }
|
||||||
|
FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer( this ); }
|
||||||
|
FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner( this ); }
|
||||||
|
FORCEINLINE bool IsServer() const { return Gasa::IsServer( this ); }
|
||||||
|
FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy( this ); }
|
||||||
|
FORCEINLINE void NetLog(
|
||||||
|
FString Message,
|
||||||
|
EGasaVerbosity Verbosity = EGasaVerbosity::Log,
|
||||||
|
FLogCategoryBase& Category = LogGasaNet,
|
||||||
|
bool DumpStack = false,
|
||||||
|
int32 Line = __builtin_LINE(),
|
||||||
|
ANSICHAR const* File = __builtin_FILE(),
|
||||||
|
ANSICHAR const* Func = __builtin_FUNCTION()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Gasa::NetLog( this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||||
|
}
|
||||||
|
#pragma endregion NetSlime
|
||||||
|
|
||||||
|
#pragma region UObject
|
||||||
|
bool CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack) override;
|
||||||
|
|
||||||
|
int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack) override;
|
||||||
|
|
||||||
|
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||||
|
|
||||||
|
bool IsSupportedForNetworking() const override;
|
||||||
|
#pragma endregion UObject
|
||||||
|
};
|
||||||
@@ -1,2 +1,94 @@
|
|||||||
#include "GasaNetLibrary.h"
|
#include "GasaNetLibrary.h"
|
||||||
|
#include "GasaNetLibrary_Inlines.h"
|
||||||
|
#include "GasaObject.h"
|
||||||
|
|
||||||
|
#include "Kismet/KismetMathLibrary.h"
|
||||||
|
#include "Kismet/KismetSystemLibrary.h"
|
||||||
|
|
||||||
|
DEFINE_LOG_CATEGORY(LogGasaNet);
|
||||||
|
|
||||||
|
namespace Gasa
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
AActor const* Actor = nullptr;
|
||||||
|
FString ActorLevel;
|
||||||
|
{
|
||||||
|
if (Context != nullptr)
|
||||||
|
{
|
||||||
|
if (Context->GetClass()->IsChildOf(AActor::StaticClass()))
|
||||||
|
Actor = Cast<AActor>(Context);
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
static UE::Logging::Private::FStaticBasicLogDynamicData LOG_Dynamic;
|
||||||
|
static UE::Logging::Private::FStaticBasicLogRecord
|
||||||
|
LOG_Static(TEXT("%s -- %hs %hs(%d)"), File, Line, EngineVerbosity, LOG_Dynamic);
|
||||||
|
|
||||||
|
// SET_WARN_COLOR(COLOR_PURPLE)
|
||||||
|
|
||||||
|
if (DumpStack)
|
||||||
|
FDebug::DumpStackTraceToLog(EngineVerbosity);
|
||||||
|
BasicLog(Category, &LOG_Static, * FullMsg, File, Func, Line);
|
||||||
|
|
||||||
|
// CLEAR_WARN_COLOR()
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,50 @@
|
|||||||
#pragma once
|
// NetSlime: Ol'Reliable
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
|
||||||
|
#define DOREPLIFETIME_DEFAULT_GAS(Class, ReplicatedVar) \
|
||||||
|
DOREPLIFETIME_CONDITION_NOTIFY(Class, ReplicatedVar, COND_None, REPNOTIFY_Always)
|
||||||
|
|
||||||
|
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)
|
||||||
|
enum class ENetworkMode : uint8
|
||||||
|
{
|
||||||
|
Standalone,
|
||||||
|
DedicatedServer,
|
||||||
|
ListenServer,
|
||||||
|
Client,
|
||||||
|
MAX,
|
||||||
|
};
|
||||||
|
|
||||||
namespace Gasa
|
namespace Gasa
|
||||||
{
|
{
|
||||||
@@ -12,6 +58,31 @@ namespace Gasa
|
|||||||
constexpr float NetCullDist_VeryFar = 10000.0f * 10000.0f;
|
constexpr float NetCullDist_VeryFar = 10000.0f * 10000.0f;
|
||||||
constexpr float NetCullDist_VisualMax = 15000.0f * 15000.0f;
|
constexpr float NetCullDist_VisualMax = 15000.0f * 15000.0f;
|
||||||
|
|
||||||
#define DOREPLIFETIME_DEFAULT_GAS(Class, ReplicatedVar) \
|
void DrawNetCullingSphere(UObject const* Context, float Duration, float Thickness);
|
||||||
DOREPLIFETIME_CONDITION_NOTIFY(Class, ReplicatedVar, COND_None, REPNOTIFY_Always)
|
|
||||||
|
ENetworkMode GetNetworkMode(UObject const* Context);
|
||||||
|
FString GetNetworkModeStr(UObject const* Context);
|
||||||
|
|
||||||
|
bool IsClient(UObject const* Context);
|
||||||
|
bool IsListenServer(UObject const* Context);
|
||||||
|
|
||||||
|
bool IsNetOwner(UObject const* Context);
|
||||||
|
bool IsNetOwner(AActor const* Context);
|
||||||
|
|
||||||
|
bool IsServer(UObject const* Context);
|
||||||
|
|
||||||
|
bool IsSimulatedProxy(UObject const* Context);
|
||||||
|
bool IsSimulatedProxy(AActor const* Context);
|
||||||
|
|
||||||
|
void NetLog( UObject const* Context, FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log
|
||||||
|
, FLogCategoryBase& Category = LogGasaNet
|
||||||
|
, bool DumpStack = false
|
||||||
|
, int32 Line = __builtin_LINE()
|
||||||
|
, const ANSICHAR* File = __builtin_FILE()
|
||||||
|
, const ANSICHAR* Func = __builtin_FUNCTION() );
|
||||||
|
|
||||||
|
bool ServerAuthorized(UObject const* Context);
|
||||||
|
bool ServerAuthorized(AActor const* Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "GasaNetLibrary_Inlines.h"
|
||||||
|
|||||||
@@ -0,0 +1,201 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "GasaNetLibrary.h"
|
||||||
|
#include "Engine/NetDriver.h"
|
||||||
|
#include "Engine/World.h"
|
||||||
|
|
||||||
|
namespace Gasa
|
||||||
|
{
|
||||||
|
// TODO(Ed): Profile these...
|
||||||
|
|
||||||
|
inline
|
||||||
|
ENetworkMode GetNetworkMode(UObject const* Context)
|
||||||
|
{
|
||||||
|
if (Context == nullptr)
|
||||||
|
{
|
||||||
|
Log("Context is null...", ELogV::Error);
|
||||||
|
return scast(ENetworkMode, ENetMode::NM_MAX);
|
||||||
|
}
|
||||||
|
UWorld* World = Context->GetWorld();
|
||||||
|
if (World == nullptr) {
|
||||||
|
Log("World is null... are you running in a proper context?", ELogV::Error);
|
||||||
|
return scast(ENetworkMode, ENetMode::NM_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsValid(World) == false)
|
||||||
|
return ENetworkMode::Standalone;
|
||||||
|
|
||||||
|
ENetworkMode NetMode = scast(ENetworkMode, World->GetNetMode());
|
||||||
|
return NetMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
FString GetNetworkModeStr(UObject const* Context)
|
||||||
|
{
|
||||||
|
FString Str;
|
||||||
|
if (Context == nullptr)
|
||||||
|
return Str;
|
||||||
|
switch (GetNetworkMode(Context))
|
||||||
|
{
|
||||||
|
case ENetworkMode::Standalone:
|
||||||
|
Str = TEXT("Standalone");
|
||||||
|
break;
|
||||||
|
case ENetworkMode::ListenServer:
|
||||||
|
Str = TEXT("ListenServer");
|
||||||
|
break;
|
||||||
|
case ENetworkMode::DedicatedServer:
|
||||||
|
Str = TEXT("DedicatedServer");
|
||||||
|
break;
|
||||||
|
case ENetworkMode::Client:
|
||||||
|
Str = TEXT("Client");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Str;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsClient(UObject const* Context)
|
||||||
|
{
|
||||||
|
if (Context == nullptr || Context->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UNetDriver* NetDriver = Context->GetWorld()->NetDriver;
|
||||||
|
bool Result = NetDriver && ! NetDriver->IsServer();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsListenServer(UObject const* Context)
|
||||||
|
{
|
||||||
|
if (Context == nullptr || Context->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UNetDriver* NetDriver = Context->GetWorld()->NetDriver;
|
||||||
|
bool Result = NetDriver && NetDriver->GetNetMode() == ENetMode::NM_ListenServer;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsNetOwner(UObject const* Context)
|
||||||
|
{
|
||||||
|
if (Context == nullptr || Context->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AActor const* Actor = nullptr;
|
||||||
|
|
||||||
|
if (Context->IsA(AActor::StaticClass()))
|
||||||
|
Actor = Cast<AActor>(Context);
|
||||||
|
else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass()))
|
||||||
|
Actor = Cast<UActorComponent>(Context)->GetOwner();
|
||||||
|
// Its assumed that all GasaObjects have an outer actor
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UObject const* Outermost = Context->GetOutermostObject();
|
||||||
|
if (Outermost->IsA(AActor::StaticClass()))
|
||||||
|
Actor = Cast<AActor>(Outermost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Actor == nullptr)
|
||||||
|
{
|
||||||
|
Log("Could not get actor reference", ELogV::Warning, LogGasaNet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool Result = Actor->HasLocalNetOwner();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsNetOwner(AActor const* Actor)
|
||||||
|
{
|
||||||
|
if (Actor == nullptr || Actor->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
bool Result = Actor->HasLocalNetOwner();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsServer(UObject const* Context)
|
||||||
|
{
|
||||||
|
if (Context == nullptr || Context->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UNetDriver* NetDriver = Context->GetWorld()->NetDriver;
|
||||||
|
bool Result = NetDriver && NetDriver->IsServer();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsSimulatedProxy(UObject const* Context)
|
||||||
|
{
|
||||||
|
if (Context == nullptr || Context->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AActor const* Actor = nullptr;
|
||||||
|
|
||||||
|
if (Context->IsA(AActor::StaticClass()))
|
||||||
|
Actor = Cast<AActor>(Context);
|
||||||
|
else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass()))
|
||||||
|
Actor = Cast<UActorComponent>(Context)->GetOwner();
|
||||||
|
// Its assumed that all GasaObjects have an outer actor
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UObject const* Outermost = Context->GetOutermostObject();
|
||||||
|
if (Outermost->IsA(AActor::StaticClass()))
|
||||||
|
Actor = Cast<AActor>(Outermost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Actor == nullptr)
|
||||||
|
{
|
||||||
|
Log("Could not get actor reference", ELogV::Warning, LogGasaNet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool Result = Actor->GetLocalRole() == ENetRole::ROLE_SimulatedProxy;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsSimulatedProxy(AActor const* Actor)
|
||||||
|
{
|
||||||
|
if (Actor == nullptr || Actor->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
bool Result = Actor->GetLocalRole() == ENetRole::ROLE_SimulatedProxy;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool ServerAuthorized(UObject const* Context)
|
||||||
|
{
|
||||||
|
if (Context == nullptr || Context->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AActor const* Actor = nullptr;
|
||||||
|
|
||||||
|
if (Context->IsA(AActor::StaticClass()))
|
||||||
|
Actor = Cast<AActor>(Context);
|
||||||
|
else if (Context->GetClass()->IsChildOf(UActorComponent::StaticClass()))
|
||||||
|
Actor = Cast<UActorComponent>(Context)->GetOwner();
|
||||||
|
// Its assumed that all GasaObjects have an outer actor
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UObject const* Outermost = Context->GetOutermostObject();
|
||||||
|
if (Outermost->IsA(AActor::StaticClass()))
|
||||||
|
Actor = Cast<AActor>(Outermost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Actor == nullptr)
|
||||||
|
{
|
||||||
|
Log("Could not get actor reference", ELogV::Warning, LogGasaNet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool Result = Actor->HasAuthority();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool ServerAuthorized(AActor const* Actor)
|
||||||
|
{
|
||||||
|
if (Actor == nullptr || Actor->GetWorld() == nullptr)
|
||||||
|
return false;
|
||||||
|
bool Result = Actor->HasAuthority();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user