孟宇 3 maanden geleden
bovenliggende
commit
302d308409

+ 13 - 2
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbility.cpp

@@ -7,12 +7,23 @@ UEzAbility::UEzAbility(const FObjectInitializer& ObjectInitializer)
 {
 }
 
-bool UEzAbility::CanAbility()
+bool UEzAbility::CanActivateAbility(FEzAbilityContext& Context, FText& OutText) const
+{
+	return K2_CanActivateAbility(Context, OutText);
+}
+
+bool UEzAbility::ActivateAbility(FEzAbilityContext& Context, const FEzAbilityParameter& Parameter, FText& OutText) const
 {
 	return false;
 }
 
-bool UEzAbility::ShouldReplicate(const FEzAbilityInstance& Instance) const
+bool UEzAbility::K2_ActivateAbility_Implementation(FEzAbilityContext& Context) const
+{
+	return true;
+}
+
+bool UEzAbility::K2_CanActivateAbility_Implementation(FEzAbilityContext& Context, FText& OutText) const
 {
+	
 	return true;
 }

+ 40 - 56
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityComponent.cpp

@@ -3,11 +3,12 @@
 
 #include "EzAbilityComponent.h"
 
+#include "EzAbilitySettings.h"
 #include "Net/UnrealNetwork.h"
 
-
 // Sets default values for this component's properties
 UEzAbilityComponent::UEzAbilityComponent()
+	: bCachedIsNetSimulated(false)
 {
 	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
 	// off to improve performance if you don't need them.
@@ -22,8 +23,41 @@ void UEzAbilityComponent::BeginPlay()
 {
 	Super::BeginPlay();
 
-	// ...
+	CacheIsNetSimulated();
+
+	if(SettingInterface == nullptr)
+	{
+		SettingInterface = TScriptInterface<IEzAbilitySettingInterface>(UEzAbilitySettings::GetSettings());
+	}
+}
+
+void UEzAbilityComponent::OnRegister()
+{
+	Super::OnRegister();
+
+	CacheIsNetSimulated();
+}
+
+void UEzAbilityComponent::InitializeComponent()
+{
+	Super::InitializeComponent();
 	
+	AbilityContext.InitContext(this);
+}
+
+void UEzAbilityComponent::PreNetReceive()
+{
+	Super::PreNetReceive();
+
+	if(!bCachedIsNetSimulated)
+	{
+		CacheIsNetSimulated();
+	}
+}
+
+bool UEzAbilityComponent::IsLocallyControlled() const
+{
+	return AbilityContext.IsLocallyControlled();
 }
 
 void UEzAbilityComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
@@ -34,7 +68,8 @@ void UEzAbilityComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>&
 	Params.bIsPushBased = true;
 
 	Params.Condition = COND_ReplayOrOwner;
-	DOREPLIFETIME_WITH_PARAMS_FAST(UEzAbilityComponent, AbilityInstances, Params);
+	DOREPLIFETIME_WITH_PARAMS_FAST(UEzAbilityComponent, AbilityInstance,			Params);
+	DOREPLIFETIME_WITH_PARAMS_FAST(UEzAbilityComponent, PassiveAbilityInstances,	Params);
 }
 
 
@@ -55,62 +90,11 @@ void UEzAbilityComponent::TickComponent(
 	// }
 }
 
-bool UEzAbilityComponent::ActivateAbility(UEzAbility* Ability, AActor* Instigator)
-{
-	if (GetOwnerRole() == ROLE_SimulatedProxy)
-    {
-    	return false;
-    }
-
-	return true;
-}
-
-bool UEzAbilityComponent::CancelAbility()
+void UEzAbilityComponent::CacheIsNetSimulated()
 {
-	return true;
+	bCachedIsNetSimulated = IsNetSimulating();
 }
 
-void UEzAbilityComponent::OnRep_AbilityInstances()
-{
-}
 
-void UEzAbilityComponent::ClientCancelAbility_Implementation()
-{
-}
 
-void UEzAbilityComponent::ServerCancelAbility_Implementation()
-{
-}
-
-bool UEzAbilityComponent::ServerCancelAbility_Validate()
-{
-	return true;
-}
-
-void UEzAbilityComponent::ClientEndAbility_Implementation()
-{
-}
-
-void UEzAbilityComponent::ServerEndAbility_Implementation()
-{
-}
-
-bool UEzAbilityComponent::ServerEndAbility_Validate()
-{
-	return true;
-}
-
-void UEzAbilityComponent::ServerActivateAbility_Implementation()
-{
-}
-
-bool UEzAbilityComponent::ServerActivateAbility_Validate()
-{
-	return true;
-}
-
-
-void UEzAbilityComponent::ClientActivateAbility_Implementation()
-{
-}
 

+ 114 - 0
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityComponent_Ability.cpp

@@ -0,0 +1,114 @@
+#include "EzAbility.h"
+#include "EzAbilityComponent.h"
+
+bool UEzAbilityComponent::InternalActivateAbility(const UEzAbility* Ability, const FEzAbilityParameter& Parameter)
+{
+	if(Ability == nullptr)
+	{
+		return false;
+	}
+
+	FText OutText;
+	if(!Ability->CanActivateAbility(AbilityContext, OutText))
+	{
+		return false;
+	}
+
+	if(Ability->ActivateAbility(AbilityContext, Parameter, OutText))
+	{
+		return true;
+	}
+	
+	return false;
+}
+
+void UEzAbilityComponent::NotifyAbilityFailed(const UEzAbility* Ability, const FText& Text)
+{
+}
+
+bool UEzAbilityComponent::ActivateAbility(const UEzAbility* Ability, const FEzAbilityParameter& Parameter)
+{
+	if(Ability == nullptr)
+	{
+		return false;
+	}
+	
+	if(IsLocallyControlled())
+	{
+		if(SettingInterface->GetLocallyCanAbility())
+		{
+			FText OutText;
+			if(!Ability->CanActivateAbility(AbilityContext, OutText))
+			{
+				NotifyAbilityFailed(Ability, OutText);
+				return false;		
+			}
+		}
+		
+		ServerActivateAbility(Ability, Parameter);
+
+		return true;
+	}	
+
+	return InternalActivateAbility(Ability, Parameter);
+}
+
+bool UEzAbilityComponent::ActivateAbility_NoParameter(const UEzAbility* Ability)
+{
+	FEzAbilityParameter Parameter;
+	return ActivateAbility(Ability, Parameter);
+}
+
+bool UEzAbilityComponent::CancelAbility()
+{
+	return true;
+}
+
+void UEzAbilityComponent::OnRep_AbilityInstance()
+{
+}
+
+void UEzAbilityComponent::OnRep_PassiveAbilityInstances()
+{
+}
+
+void UEzAbilityComponent::ClientCancelAbility_Implementation()
+{
+}
+
+void UEzAbilityComponent::ServerCancelAbility_Implementation()
+{
+}
+
+bool UEzAbilityComponent::ServerCancelAbility_Validate()
+{
+	return true;
+}
+
+void UEzAbilityComponent::ClientEndAbility_Implementation()
+{
+}
+
+void UEzAbilityComponent::ServerEndAbility_Implementation()
+{
+}
+
+bool UEzAbilityComponent::ServerEndAbility_Validate()
+{
+	return true;
+}
+
+void UEzAbilityComponent::ServerActivateAbility_Implementation(const UEzAbility* Ability, const FEzAbilityParameter& Parameter)
+{
+	InternalActivateAbility(Ability, Parameter);
+}
+
+bool UEzAbilityComponent::ServerActivateAbility_Validate(const UEzAbility* Ability, const FEzAbilityParameter& Parameter)
+{
+	return true;
+}
+
+
+void UEzAbilityComponent::ClientActivateAbility_Implementation()
+{
+}

+ 58 - 0
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityContext.cpp

@@ -3,8 +3,66 @@
 
 #include "EzAbilityContext.h"
 
+#include "EzAbilityComponent.h"
 #include "EzAbilityTypes.h"
 
+void FEzAbilityContext::InitContext(UEzAbilityComponent* Component)
+{
+	AbilityComponent = Component;
+	OwnerActor		 = Component->GetOwner();
+
+	AActor* TestActor = OwnerActor.Get();
+
+	while (TestActor != nullptr)
+	{
+		if (APlayerController * CastPC = Cast<APlayerController>(TestActor))
+		{
+			PlayerController = CastPC;
+			break;
+		}
+
+		if (APawn * Pawn = Cast<APawn>(TestActor))
+		{
+			PlayerController = Cast<APlayerController>(Pawn->GetController());
+			break;
+		}
+		
+		TestActor = TestActor->GetOwner();
+	}
+}
+
+bool FEzAbilityContext::IsLocallyControlled() const
+{
+	if (const APlayerController* PC = PlayerController.Get())
+	{
+		return PC->IsLocalController();
+	}
+	else if (const APawn* OwnerPawn = Cast<APawn>(OwnerActor))
+	{
+		if (OwnerPawn->IsLocallyControlled())
+		{
+			return true;
+		}
+		else if (OwnerPawn->GetController())
+		{
+			return false;
+		}
+	}
+	
+	return IsNetAuthority();
+}
+
+bool FEzAbilityContext::IsNetAuthority() const
+{
+	if (const AActor* OwnerActorPtr = OwnerActor.Get(true))
+	{
+		return (OwnerActorPtr->GetLocalRole() == ROLE_Authority);
+	}
+	
+	return false;
+}
+
+
 // EAbilityRunStatus FEzAbilityContext::Start()
 // {
 // 	return EAbilityRunStatus::Failed;

+ 2 - 2
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilitySettings.cpp

@@ -10,9 +10,9 @@ UEzAbilitySettings::UEzAbilitySettings(const FObjectInitializer& ObjectInitializ
 	SectionName = TEXT("EzAbility");
 }
 
-bool UEzAbilitySettings::GetVerbose() const
+UEzAbilitySettings* UEzAbilitySettings::GetSettings()
 {
-	return bVerbose;
+	return GetMutableDefault<UEzAbilitySettings>();
 }
 
 

+ 6 - 0
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbility_Replicate.cpp

@@ -0,0 +1,6 @@
+#include "EzAbility.h"
+
+bool UEzAbility::ShouldReplicate(const FEzAbilityInstance& Instance) const
+{
+	return true;
+}

+ 13 - 2
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbility.h

@@ -7,7 +7,9 @@
 #include "EzAbilityTypes.h"
 #include "EzAbility.generated.h"
 
+struct FEzAbilityContext;
 struct FEzAbilityInstance;
+struct FEzAbilityParameter;
 
 UCLASS(Blueprintable, hidecategories=(Internal, Thumbnail), meta = (ShowWorldContextPin, DisplayThumbnail = "true"))
 class UEzAbility : public UDataAsset
@@ -15,9 +17,18 @@ class UEzAbility : public UDataAsset
 	GENERATED_BODY()
 public:
 	UEzAbility(const FObjectInitializer& ObjectInitializer);
-
-	virtual bool CanAbility();
+	
+	virtual bool CanActivateAbility(FEzAbilityContext& Context, FText& OutText) const;
+	virtual bool ActivateAbility(FEzAbilityContext& Context, const FEzAbilityParameter& Parameter, FText& OutText) const;
 	virtual bool ShouldReplicate(const FEzAbilityInstance& Instance) const;
+
+protected:
+	UFUNCTION(BlueprintNativeEvent)
+	bool K2_ActivateAbility(FEzAbilityContext& Context) const;
+	
+	UFUNCTION(BlueprintNativeEvent)
+	bool K2_CanActivateAbility(FEzAbilityContext& Context, FText& OutText) const;
+	
 protected:
 
 	//Slices

+ 66 - 14
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityComponent.h

@@ -5,9 +5,37 @@
 #include "CoreMinimal.h"
 #include "EzAbilityContext.h"
 #include "EzAbilityInstance.h"
+#include "EzAbilitySettingInterface.h"
 #include "Components/ActorComponent.h"
 #include "EzAbilityComponent.generated.h"
 
+USTRUCT(BlueprintType)
+struct FEzAbilityParameter
+{
+	GENERATED_BODY()
+
+	FEzAbilityParameter() = default;
+	
+	FEzAbilityParameter& operator=(const FEzAbilityParameter& Parameter)
+	{
+		Instigator	= Parameter.Instigator;
+		Targets		= Parameter.Targets;
+		Locations	= Parameter.Locations;
+		
+		return *this;
+	}
+
+	UPROPERTY(EditAnywhere)
+	TObjectPtr<AActor>			Instigator = nullptr;
+
+	UPROPERTY(EditAnywhere)
+	TArray<TObjectPtr<AActor>>	Targets;
+
+	UPROPERTY(EditAnywhere)
+	TArray<FVector>				Locations;
+};
+
+
 UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
 class EZABILITY_API UEzAbilityComponent : public UActorComponent
 {
@@ -20,19 +48,25 @@ public:
 protected:
 	// Called when the game starts
 	virtual void BeginPlay() override;
-
+	virtual void OnRegister() override;
+	virtual void InitializeComponent() override;
+	virtual void PreNetReceive() override;
+	virtual bool IsLocallyControlled() const;
+	
 public:
 	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
 	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
 
-	
-	UFUNCTION(BlueprintCallable)
-	bool ActivateAbility(UEzAbility* Ability, AActor* Instigator = nullptr);
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////
+	///Ability
+	UFUNCTION(BlueprintCallable, Category="Ability")
+	bool ActivateAbility(const UEzAbility* Ability, const FEzAbilityParameter& Parameter);
 
-	UFUNCTION(BlueprintCallable)
+	UFUNCTION(BlueprintCallable, meta=(DisplayName="ActivateAbility"), Category="Ability")
+	bool ActivateAbility_NoParameter(const UEzAbility* Ability);
+	
+	UFUNCTION(BlueprintCallable, Category="Ability")
 	bool CancelAbility();
-
-
 	
 	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityRunStatusChanged, EAbilityRunStatus, RunStatus);
 	/** Called when the run status of the Ability has changed */
@@ -40,11 +74,19 @@ public:
 	FAbilityRunStatusChanged OnAbilityRunStatusChanged;
 
 protected:
-	UFUNCTION()
-	void OnRep_AbilityInstances();
+	void CacheIsNetSimulated();
+	bool InternalActivateAbility(const UEzAbility* Ability, const FEzAbilityParameter& Parameter);
 
+	void NotifyAbilityFailed(const UEzAbility* Ability, const FText& Text);
+	
+	UFUNCTION()
+	void OnRep_AbilityInstance();
+	
+	UFUNCTION()
+	void OnRep_PassiveAbilityInstances();
+	
 	UFUNCTION(Server, reliable, WithValidation)
-	void ServerActivateAbility();
+	void ServerActivateAbility(const UEzAbility* Ability, const FEzAbilityParameter& Parameter);
 	
 	UFUNCTION(Client, reliable)
 	void ClientActivateAbility();
@@ -60,11 +102,21 @@ protected:
 	
 	UFUNCTION(Client, reliable)
 	void ClientCancelAbility();
-	
+
+
 protected:
+	UPROPERTY(EditAnywhere, Category="Ability")
+	TScriptInterface<IEzAbilitySettingInterface>	SettingInterface;
+	
 	UPROPERTY(BlueprintReadOnly, Transient, Category="Ability")
-	FEzAbilityContext	AbilityContext;
+	FEzAbilityContext			AbilityContext;
+
+	UPROPERTY(BlueprintReadOnly, Transient, Category="Ability", ReplicatedUsing=OnRep_AbilityInstance)
+	FEzAbilityInstance			AbilityInstance;
+	
+	UPROPERTY(BlueprintReadOnly, Transient, Category="Ability", ReplicatedUsing=OnRep_PassiveAbilityInstances)
+	FEzAbilityInstanceContainer	PassiveAbilityInstances;
 
-	UPROPERTY(BlueprintReadOnly, Transient, Category="Ability", ReplicatedUsing=OnRep_AbilityInstances)
-	FEzAbilityInstanceContainer	AbilityInstances;
+	UPROPERTY()
+	bool bCachedIsNetSimulated;
 };

+ 12 - 4
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityContext.h

@@ -16,6 +16,11 @@ struct EZABILITY_API FEzAbilityContext
 {
 	GENERATED_BODY()
 public:
+	void InitContext(UEzAbilityComponent* Component);
+	bool IsLocallyControlled() const;
+	bool IsNetAuthority() const;
+	
+	
 	// EAbilityRunStatus Start();
 	// EAbilityRunStatus Tick(float DeltaTime);
 	// EAbilityRunStatus Stop();
@@ -23,14 +28,17 @@ public:
 	// EAbilityRunStatus GetAbilityRunStatus() const;
 protected:
 	UPROPERTY(Transient)
-	TObjectPtr<UEzAbilityComponent>	Component;
+	TWeakObjectPtr<UEzAbilityComponent>	AbilityComponent;
 
 	UPROPERTY(Transient)
-	TWeakObjectPtr<AActor>	Owner;
+	TWeakObjectPtr<AActor>				OwnerActor;
 
 	UPROPERTY(Transient)
-	TWeakObjectPtr<AActor>	Instigator;
+	TWeakObjectPtr<APlayerController>	PlayerController;
 
 	UPROPERTY(Transient)
-	TArray<TWeakObjectPtr<AActor>>	TargetActors;
+	TWeakObjectPtr<AActor>				Instigator;
+
+	UPROPERTY(Transient)
+	TArray<TWeakObjectPtr<AActor>>		TargetActors;
 };

+ 4 - 1
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityInstance.h

@@ -11,6 +11,7 @@ class UEzAbility;
 class UEzAbilityComponent;
 
 
+#if 1 
 USTRUCT(BlueprintType)
 struct EZABILITY_API FEzAbilityInstance : public FFastArraySerializerItem
 {
@@ -75,4 +76,6 @@ struct TStructOpsTypeTraits< FEzAbilityInstanceContainer > : public TStructOpsTy
 	{
 		WithNetDeltaSerializer = true,
 	};
-};
+};
+
+#endif

+ 1 - 1
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilitySettingInterface.h

@@ -23,5 +23,5 @@ class EZABILITY_API IEzAbilitySettingInterface
 	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
 public:
 	virtual bool	GetVerbose()				const = 0;
-
+	virtual bool	GetLocallyCanAbility()		const = 0;
 };

+ 7 - 3
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilitySettings.h

@@ -19,10 +19,14 @@ class EZABILITY_API UEzAbilitySettings : public UDeveloperSettings, public IEzAb
 public:
 	UEzAbilitySettings(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
 
-	virtual bool	GetVerbose()				const override;
-
+	static UEzAbilitySettings* GetSettings();
+	
+	virtual bool GetVerbose()			const override { return bVerbose; }
+	virtual bool GetLocallyCanAbility() const override { return bLocallyCanAbility; }
 protected:
 	UPROPERTY(Config, EditAnywhere, Category = Debug, meta = (DisplayName = "Log Verbose Output"))
 	bool bVerbose = false;
-	
+
+	UPROPERTY(Config, EditAnywhere, Category = Ability)
+	bool bLocallyCanAbility = true;
 };

+ 1 - 1
Ability/Source/Ability/AbilityCharacter.cpp

@@ -62,7 +62,7 @@ void AAbilityCharacter::OnAttackPress()
 
 void AAbilityCharacter::OnAttackRelease()
 {
-	AbilityComponent->ActivateAbility(nullptr);
+	AbilityComponent->ActivateAbility_NoParameter(nullptr);
 }
 
 void AAbilityCharacter::BeginPlay()