Compare commits
27 Commits
18bb578c97
...
old_repo_o
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 | |||
adfb17b7df | |||
6c011ac657 | |||
c517cbd45e | |||
b26e02d582 |
50
.gitignore
vendored
50
.gitignore
vendored
@ -1,30 +1,38 @@
|
|||||||
Project/Intermediate
|
*/Binaries/Win64/*.patch_*.*
|
||||||
Project/Saved/Crashes
|
|
||||||
Project/Saved/SourceControl
|
Project/.idea
|
||||||
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
|
||||||
|
BIN
Project/Binaries/Win64/UnrealEditor-Gasa.dll
(Stored with Git LFS)
BIN
Project/Binaries/Win64/UnrealEditor-Gasa.dll
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
(Stored with Git LFS)
BIN
Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
(Stored with Git LFS)
Binary file not shown.
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
|
||||||
|
20
Project/Config/DefaultGameplayTags.ini
Normal file
20
Project/Config/DefaultGameplayTags.ini
Normal file
@ -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="")
|
||||||
|
|
BIN
Project/Content/Core/AbilitySystem/GE_AreaFire.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/AbilitySystem/GE_AreaFire.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/AbilitySystem/GE_CrystalHeal.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/AbilitySystem/GE_CrystalHeal.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/AbilitySystem/GE_CrystalMana.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/AbilitySystem/GE_CrystalMana.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/AbilitySystem/GE_PotionHealth.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/AbilitySystem/GE_PotionHealth.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/AbilitySystem/GE_PotionMana.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/AbilitySystem/GE_PotionMana.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Actors/BP_PlayerCharacter.uasset
(Stored with Git LFS)
BIN
Project/Content/Core/Actors/BP_PlayerCharacter.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/Core/BP_AreaFire_RawEffect.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/BP_AreaFire_RawEffect.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/BP_AttributesTest.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/BP_AttributesTest.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/DT_PrimaryAttributes.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/DT_PrimaryAttributes.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/DT_TaggedMessages.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/DT_TaggedMessages.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Game/BP_HUD.uasset
(Stored with Git LFS)
BIN
Project/Content/Core/Game/BP_HUD.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/Core/Game/BP_PlayerController.uasset
(Stored with Git LFS)
BIN
Project/Content/Core/Game/BP_PlayerController.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/Core/Pickups/BP_HealthCrystal_RawEffect.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Pickups/BP_HealthCrystal_RawEffect.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Pickups/BP_HealthPotion.uasset
(Stored with Git LFS)
BIN
Project/Content/Core/Pickups/BP_HealthPotion.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/Core/Pickups/BP_HealthPotionDemo.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Pickups/BP_HealthPotionDemo.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Pickups/BP_HealthPotion_RawEffect.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Pickups/BP_HealthPotion_RawEffect.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Pickups/BP_ManaCrystal_RawEffect.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Pickups/BP_ManaCrystal_RawEffect.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Pickups/BP_ManaPotion_RawEffect.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Pickups/BP_ManaPotion_RawEffect.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Tables/CT_Potion.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Tables/CT_Potion.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Tables/DT_PrimaryAttributes.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Tables/DT_PrimaryAttributes.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Core/Tables/DT_TaggedMessages.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Core/Tables/DT_TaggedMessages.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Levels/StartupMap.umap
(Stored with Git LFS)
BIN
Project/Content/Levels/StartupMap.umap
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/MaterialLibrary/M_Crystal.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/MaterialLibrary/M_Crystal.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Pickups/HealthCrystal/Materials/MI_HealthCrystal.uasset
(Stored with Git LFS)
BIN
Project/Content/Pickups/HealthCrystal/Materials/MI_HealthCrystal.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/Pickups/HealthCrystal/Materials/M_HealthCrystal.uasset
(Stored with Git LFS)
BIN
Project/Content/Pickups/HealthCrystal/Materials/M_HealthCrystal.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/Pickups/MI_CrystalMana.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Pickups/MI_CrystalMana.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/Pickups/Potions/Liquid/MI_Liquid_DullRed.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/Pickups/Potions/Liquid/MI_Liquid_DullRed.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/UI/BP_HostWidgetController.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/UI/BP_HostWidgetController.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/UI/DT_StyleText_EffectMessage.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/UI/DT_StyleText_EffectMessage.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/UI/Globes/MI_BlackBG.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/UI/Globes/MI_BlackBG.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/UI/RTD_Default.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/UI/RTD_Default.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/UI/UI_EffectMessage.uasset
(Stored with Git LFS)
Normal file
BIN
Project/Content/UI/UI_EffectMessage.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Project/Content/UI/UI_GlobeHealth.uasset
(Stored with Git LFS)
BIN
Project/Content/UI/UI_GlobeHealth.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/UI/UI_GlobeMana.uasset
(Stored with Git LFS)
BIN
Project/Content/UI/UI_GlobeMana.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/UI/UI_GlobeTemplate.uasset
(Stored with Git LFS)
BIN
Project/Content/UI/UI_GlobeTemplate.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Project/Content/UI/UI_Host.uasset
(Stored with Git LFS)
BIN
Project/Content/UI/UI_Host.uasset
(Stored with Git LFS)
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>
|
||||||
|
38
Project/Source/Gasa/AbilitySystem/EffectProperties.cpp
Normal file
38
Project/Source/Gasa/AbilitySystem/EffectProperties.cpp
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
34
Project/Source/Gasa/AbilitySystem/EffectProperties.h
Normal file
34
Project/Source/Gasa/AbilitySystem/EffectProperties.h
Normal file
@ -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() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
53
Project/Source/Gasa/AbilitySystem/GasaAttributeSet_Inlines.h
Normal file
53
Project/Source/Gasa/AbilitySystem/GasaAttributeSet_Inlines.h
Normal file
@ -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);
|
|
||||||
|
InstantEffectUsage = EInstantEffectUsagePolicy::DoNotApply;
|
||||||
|
DurationEffectUsage = DefaultEffectUsagePolicy;
|
||||||
|
InfiniteEffectUsage = DefaultEffectUsagePolicy;
|
||||||
|
|
||||||
|
bDestroyOnEffectRemoval = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaEffectActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent
|
void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap)
|
||||||
, AActor* OtherActor
|
|
||||||
, UPrimitiveComponent* OtherComp
|
|
||||||
, int32 OtherBodyIndex
|
|
||||||
, bool bFromSweep
|
|
||||||
, FHitResult const& SweepResult)
|
|
||||||
{
|
{
|
||||||
// Demo of "restricted way"
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
||||||
if ( ! OtherActor->Implements<UAbilitySystemInterface>())
|
FGameplayEffectContextHandle
|
||||||
return;
|
Context = AS->MakeEffectContext();
|
||||||
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(OtherActor);
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, Level, Context );
|
||||||
if (ASI == nullptr)
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
return;
|
if (bRemoveOnEndOverlap)
|
||||||
|
ActiveEffectsToRemove.Add(ActiveEffect, AS);
|
||||||
// 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 );
|
|
||||||
Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaEffectActor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent
|
void AGasaEffectActor::OnOverlap(AActor* Actor)
|
||||||
, AActor* OtherActor
|
|
||||||
, UPrimitiveComponent* OtherComp
|
|
||||||
, int32 OtherBodyIndex)
|
|
||||||
{
|
{
|
||||||
}
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
||||||
|
FGameplayEffectContextHandle
|
||||||
|
Context = AS->MakeEffectContext();
|
||||||
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
void AGasaEffectActor::BeginPlay()
|
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap)
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
|
||||||
|
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
}
|
}
|
||||||
|
if (DurationEffectClass)
|
||||||
void AGasaEffectActor::PostInitializeComponents()
|
|
||||||
{
|
{
|
||||||
Super::PostInitializeComponents();
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap))
|
||||||
|
{
|
||||||
Sphere->OnComponentBeginOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapBegin);
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
|
||||||
Sphere->OnComponentEndOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapEnd);
|
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::OnEndOverlap(AActor* Actor)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FActiveGameplayEffectHandle> EffectsRemoved;
|
||||||
|
for (ActiveEffectEntry ActiveEffect : ActiveEffectsToRemove)
|
||||||
|
{
|
||||||
|
if (ActiveEffect.Value != AS)
|
||||||
|
continue;
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveEffect.Key, 1);
|
||||||
|
EffectsRemoved.Add(ActiveEffect.Key);
|
||||||
|
}
|
||||||
|
RemoveKeys(ActiveEffectsToRemove, EffectsRemoved);
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
, int32 OtherBodyIndex);
|
|
||||||
|
|
||||||
#pragma region Actor
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
void BeginPlay() override;
|
EInstantEffectUsagePolicy InstantEffectUsage;
|
||||||
|
|
||||||
void PostInitializeComponents() override;
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
#pragma endregion Actor
|
TSubclassOf<UGameplayEffect> DurationEffectClass;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy"))
|
||||||
|
int32 DurationEffectUsage;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
|
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);
|
||||||
};
|
};
|
||||||
|
63
Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.cpp
Normal file
63
Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.cpp
Normal file
@ -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);
|
||||||
|
}
|
42
Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.h
Normal file
42
Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.h
Normal file
@ -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
Project/Source/Gasa/Actors/GasaActor.cpp
Normal file
0
Project/Source/Gasa/Actors/GasaActor.cpp
Normal file
33
Project/Source/Gasa/Actors/GasaActor.h
Normal file
33
Project/Source/Gasa/Actors/GasaActor.h
Normal file
@ -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,21 +1,97 @@
|
|||||||
#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"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnLogoutSig, AGasaPlayerController*, PC);
|
||||||
|
|
||||||
UCLASS( Blueprintable )
|
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 )
|
||||||
|
@ -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,11 +14,87 @@ 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()
|
||||||
{
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
NetLog("BeginPlay");
|
||||||
|
|
||||||
|
// Notified as initialized here as any possible components should also be initialized by this point.
|
||||||
|
UGasaGameInstance*
|
||||||
|
GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
GI->Event_OnGameFrameworkInitialized.AddDynamic(this, & ThisClass::OnGameFrameworkInitialized);
|
||||||
|
GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::GameState);
|
||||||
|
|
||||||
#if ENABLE_COG
|
#if ENABLE_COG
|
||||||
CogWindowManager = NewObject<UCogWindowManager>(this);
|
CogWindowManager = NewObject<UCogWindowManager>(this);
|
||||||
CogWindowManagerRef = CogWindowManager;
|
CogWindowManagerRef = CogWindowManager;
|
||||||
@ -23,12 +104,44 @@ void AGasaGameState::BeginPlay()
|
|||||||
#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
|
||||||
|
if (CogWindowManager)
|
||||||
CogWindowManager->Tick(DeltaSeconds);
|
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,8 +1,9 @@
|
|||||||
#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"
|
||||||
|
|
||||||
@ -18,22 +19,98 @@ public:
|
|||||||
|
|
||||||
#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 GameState
|
#pragma region GameFramework
|
||||||
void BeginPlay() override;
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FOnPawnReadySig Event_OnPlayerPawnReady;
|
||||||
|
|
||||||
void Tick(float DeltaSeconds) override;
|
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
|
||||||
|
void HandleBeginPlay() override;
|
||||||
#pragma endregion GameState
|
#pragma endregion GameState
|
||||||
|
|
||||||
|
#pragma region GameStateBase
|
||||||
|
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 )
|
||||||
|
@ -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,26 +222,107 @@ 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);
|
||||||
|
|
||||||
Cam->AttachToActor(InPawn, FAttachmentTransformRules::KeepRelativeTransform);
|
|
||||||
|
|
||||||
AGasaPlayerState* PS = GetPlayerState();
|
AGasaPlayerState* PS = GetPlayerState();
|
||||||
AGasaCharacter* character = Cast<AGasaCharacter>(InPawn);
|
AGasaHUD* HUD = GetHUD<AGasaHUD>();
|
||||||
// Net Owner setup ability system
|
FWidgetControllerData Data = { this, PS, PS->AbilitySystem, PS->Attributes };
|
||||||
if (0)
|
HUD->InitHostWidget(& Data);
|
||||||
{
|
|
||||||
character->AbilitySystem = PS->AbilitySystem;
|
|
||||||
character->Attributes = PS->Attributes;
|
|
||||||
character->AbilitySystem->InitAbilityActorInfo(PS, character);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AGasaPlayerController::ClientUpdateLevelStreamingStatus_Implementation(FName PackageName, bool bNewShouldBeLoaded, bool bNewShouldBeVisible,
|
||||||
|
bool bNewShouldBlockOnLoad, int32 LODIndex, FNetLevelVisibilityTransactionId TransactionId, bool bNewShouldBlockOnUnload)
|
||||||
|
{
|
||||||
|
Super::ClientUpdateLevelStreamingStatus_Implementation(PackageName, bNewShouldBeLoaded, bNewShouldBeVisible, bNewShouldBlockOnLoad, LODIndex,
|
||||||
|
TransactionId, bNewShouldBlockOnUnload);
|
||||||
|
|
||||||
|
NetLog("ClientUpdateLevelStreamingStatus");
|
||||||
|
NetLog(FString("PackageName : ") + PackageName.ToString());
|
||||||
|
NetLog(FString("NewShouldBeLoaded : ") + FString(bNewShouldBeLoaded ? "true" : "false"));
|
||||||
|
NetLog(FString("NewShouldBeVisible : ") + FString(bNewShouldBeVisible ? "true" : "false"));
|
||||||
|
NetLog(FString("bNewShouldBlockOnLoad : ") + FString(bNewShouldBlockOnLoad ? "true" : "false"));
|
||||||
|
NetLog(FString("bNewShouldBlockOnUnload: ") + FString(bNewShouldBlockOnUnload ? "true" : "false"));
|
||||||
|
NetLog(FString("LODIndex : ") + FString::FromInt( LODIndex ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(Ed): We need to setup Net Slime...
|
||||||
|
void AGasaPlayerController::OnPossess(APawn* PawnPossesed)
|
||||||
|
{
|
||||||
|
// Super::OnPossess(PawnPossesed);
|
||||||
|
{
|
||||||
|
if (PawnPossesed && (PlayerState == NULL || !PlayerState->IsOnlyASpectator()) )
|
||||||
|
{
|
||||||
|
// ====================================================================Originally: Super::OnPossess(PawnToPossess);
|
||||||
|
const bool bNewPawn = (GetPawn() != PawnPossesed);
|
||||||
|
if (GetPawn() && bNewPawn)
|
||||||
|
UnPossess();
|
||||||
|
|
||||||
|
if (PawnPossesed->Controller != NULL)
|
||||||
|
PawnPossesed->Controller->UnPossess();
|
||||||
|
|
||||||
|
PawnPossesed->PossessedBy(this);
|
||||||
|
|
||||||
|
// update rotation to match possessed pawn's rotation
|
||||||
|
SetControlRotation( PawnPossesed->GetActorRotation() );
|
||||||
|
SetPawn(PawnPossesed);
|
||||||
|
|
||||||
|
check(GetPawn() != NULL);
|
||||||
|
if (GetPawn() && GetPawn()->PrimaryActorTick.bStartWithTickEnabled)
|
||||||
|
GetPawn()->SetActorTickEnabled(true);
|
||||||
|
|
||||||
|
INetworkPredictionInterface* NetworkPredictionInterface = GetPawn()
|
||||||
|
? Cast<INetworkPredictionInterface>(GetPawn()->GetMovementComponent())
|
||||||
|
: nullptr;
|
||||||
|
if (NetworkPredictionInterface)
|
||||||
|
NetworkPredictionInterface->ResetPredictionData_Server();
|
||||||
|
|
||||||
|
AcknowledgedPawn = NULL;
|
||||||
|
|
||||||
|
// Local PCs will have the Restart() triggered right away in ClientRestart (via PawnClientRestart()), but the server should call Restart() locally for remote PCs.
|
||||||
|
// We're really just trying to avoid calling Restart() multiple times.
|
||||||
|
if (!IsLocalPlayerController())
|
||||||
|
GetPawn()->Restart();
|
||||||
|
|
||||||
|
ClientRestart(GetPawn());
|
||||||
|
|
||||||
|
|
||||||
|
// Moved to: void AGasaPlayerController::OnPawnReady
|
||||||
|
#if 0
|
||||||
|
ChangeState( NAME_Playing );
|
||||||
|
if (bAutoManageActiveCameraTarget)
|
||||||
|
{
|
||||||
|
AutoManageActiveCameraTarget(GetPawn());
|
||||||
|
ResetCameraMode();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//==========================================================End of=================== Originally: Super::OnPossess(PawnToPossess);
|
||||||
|
|
||||||
|
NetLog("OnPossess");
|
||||||
|
Server_SetupOnPawnReadyBinds(PawnPossesed);
|
||||||
|
Event_OnPawnPossessed.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGasaPlayerController::OnRep_Pawn()
|
||||||
|
{
|
||||||
|
Super::OnRep_Pawn();
|
||||||
|
|
||||||
|
NetLog("OnRep_Pawn");
|
||||||
|
Client_CheckIfOwnerReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaPlayerController::OnUnPossess()
|
void AGasaPlayerController::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,13 +383,25 @@ void AGasaPlayerController::SetupInputComponent()
|
|||||||
EIC->BindAction(IA_Move, ETriggerEvent::Triggered, this, &ThisClass::Move);
|
EIC->BindAction(IA_Move, ETriggerEvent::Triggered, this, &ThisClass::Move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AGasaPlayerController::SpawnDefaultHUD()
|
||||||
|
{
|
||||||
|
Super::SpawnDefaultHUD();
|
||||||
|
}
|
||||||
#pragma endregion PlayerController
|
#pragma endregion PlayerController
|
||||||
|
|
||||||
#pragma region Actor
|
#pragma region Actor
|
||||||
void AGasaPlayerController::BeginPlay()
|
void AGasaPlayerController::BeginPlay()
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
|
NetLog("BeginPlay");
|
||||||
|
|
||||||
|
UGasaGameInstance* GI = GetGameInstance<UGasaGameInstance>();
|
||||||
|
GI->Event_OnGameFrameworkInitialized.AddUniqueDynamic(this, & AGasaPlayerController::OnGameFrameworkInitialized);
|
||||||
|
GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::PlayerController);
|
||||||
|
|
||||||
|
if (IsLocalController())
|
||||||
|
{
|
||||||
check(IMC);
|
check(IMC);
|
||||||
|
|
||||||
UEnhancedInputLocalPlayerSubsystem*
|
UEnhancedInputLocalPlayerSubsystem*
|
||||||
@ -169,19 +417,16 @@ void AGasaPlayerController::BeginPlay()
|
|||||||
SetInputMode(MouseMode);
|
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;
|
||||||
@ -33,6 +43,55 @@ public:
|
|||||||
#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)
|
||||||
TObjectPtr<AGasaCharacter> HoverPrev;
|
TObjectPtr<AGasaCharacter> HoverPrev;
|
||||||
@ -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
|
||||||
|
8
Project/Source/Gasa/Game/GasaPlayerController_Inlines.h
Normal file
8
Project/Source/Gasa/Game/GasaPlayerController_Inlines.h
Normal file
@ -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;
|
||||||
@ -25,14 +28,69 @@ public:
|
|||||||
TObjectPtr<UAttributeSet> Attributes;
|
TObjectPtr<UAttributeSet> Attributes;
|
||||||
#pragma endregion Ability System
|
#pragma endregion Ability System
|
||||||
|
|
||||||
AGasaPlayerState();
|
#pragma region GameFramework
|
||||||
|
UFUNCTION()
|
||||||
|
void OnGameFrameworkInitialized();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta = (DisplayName = "On Game Framework Initialized"))
|
||||||
|
void BP_OnGameFrameworkInitialized();
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void OnNetOwnerReady(AGasaPlayerController* PC);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, meta = (DisplayName = "On Net Owner Ready"))
|
||||||
|
void BP_OnNetOwnerReady();
|
||||||
|
#pragma endregion GameFramework
|
||||||
|
|
||||||
|
#pragma region Networking
|
||||||
|
#if 0
|
||||||
|
UPROPERTY(ReplicatedUsing = Client_OnRep_GasaID)
|
||||||
|
int32 GasaID = INDEX_NONE;
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void Client_OnRep_GasaID;
|
||||||
|
#endif
|
||||||
|
#pragma endregion Networking
|
||||||
|
|
||||||
|
#pragma region NetSlime
|
||||||
|
// 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;
|
||||||
@ -11,6 +11,32 @@ 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[]
|
||||||
{
|
{
|
||||||
|
53
Project/Source/Gasa/GasaColdHeadersPCH.h
Normal file
53
Project/Source/Gasa/GasaColdHeadersPCH.h
Normal file
@ -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
Project/Source/Gasa/GasaContainers.cpp
Normal file
0
Project/Source/Gasa/GasaContainers.cpp
Normal file
22
Project/Source/Gasa/GasaContainers.h
Normal file
22
Project/Source/Gasa/GasaContainers.h
Normal file
@ -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();
|
||||||
|
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();
|
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();
|
||||||
};
|
};
|
||||||
|
25
Project/Source/Gasa/GasaEngineMinimal.h
Normal file
25
Project/Source/Gasa/GasaEngineMinimal.h
Normal file
@ -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
|
||||||
{
|
{
|
||||||
|
77
Project/Source/Gasa/GasaObject.cpp
Normal file
77
Project/Source/Gasa/GasaObject.cpp
Normal file
@ -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;
|
||||||
|
}
|
80
Project/Source/Gasa/GasaObject.h
Normal file
80
Project/Source/Gasa/GasaObject.h
Normal file
@ -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"
|
||||||
|
201
Project/Source/Gasa/Networking/GasaNetLibrary_Inlines.h
Normal file
201
Project/Source/Gasa/Networking/GasaNetLibrary_Inlines.h
Normal file
@ -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