Skip to content

Commit 0876275

Browse files
committed
1.7 Update
- Added EQS faction test - New function for getting all actors from a faction - New handlers - Exposed display names
1 parent e308713 commit 0876275

File tree

7 files changed

+253
-10
lines changed

7 files changed

+253
-10
lines changed

FactionsExtension.uplugin

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"FileVersion": 3,
3-
"Version": 14,
4-
"VersionName": "1.6a",
3+
"Version": 15,
4+
"VersionName": "1.7",
55
"FriendlyName": "Factions Extension",
66
"Description": "Add factions and relations in your game using C++ or Blueprints",
77
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/29a33bd0c38e4b8f9626f495bb47dca8",

Source/Factions/Private/EnvironmentQuery/EnvQueryTest_Faction.cpp

+117-7
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,136 @@
33
#include "EnvQueryTest_Faction.h"
44
#include "EnvironmentQuery/Items/EnvQueryItemType_ActorBase.h"
55

6+
#include "FactionsLibrary.h"
7+
68
#define LOCTEXT_NAMESPACE "UEnvQueryTest_Faction"
79

810

9-
UEnvQueryTest_Faction::UEnvQueryTest_Faction(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
11+
UEnvQueryTest_Faction::UEnvQueryTest_Faction()
12+
: Super()
13+
, bCompareTowardsContextActor(false)
1014
{
11-
TestPurpose = EEnvTestPurpose::Filter;
12-
13-
Cost = EEnvTestCost::Low;
14-
SetWorkOnFloatValues(false);
15-
ValidItemType = UEnvQueryItemType_ActorBase::StaticClass();
15+
TestPurpose = EEnvTestPurpose::Filter;
1616

17+
Cost = EEnvTestCost::Low;
18+
SetWorkOnFloatValues(false);
19+
ValidItemType = UEnvQueryItemType_ActorBase::StaticClass();
1720
}
1821

1922
void UEnvQueryTest_Faction::RunTest(FEnvQueryInstance& QueryInstance) const
2023
{
24+
UObject* Owner = QueryInstance.Owner.Get();
25+
if (!Owner)
26+
return;
27+
28+
BoolValue.BindData(Owner, QueryInstance.QueryID);
29+
const bool bNegate = BoolValue.GetValue();
30+
31+
FFaction TargetFaction{ Faction };
32+
if (bCompareTowardsContextActor)
33+
{
34+
// don't support context Location here, it doesn't make any sense
35+
TArray<AActor*> ContextItems;
36+
if (!QueryInstance.PrepareContext(Context, ContextItems))
37+
return;
38+
39+
if (ContextItems.Num() <= 0)
40+
TargetFaction = FFaction::NoFaction;
41+
else
42+
TargetFaction = UFactionsLibrary::GetFaction(ContextItems[0]);
43+
}
44+
45+
switch (Mode)
46+
{
47+
case EFactionTestMode::IsTheSame:
48+
for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
49+
{
50+
AActor* PointActor = GetItemActor(QueryInstance, It.GetIndex());
51+
52+
const bool bIsTheSame = UFactionsLibrary::GetFaction(PointActor) == TargetFaction;
53+
It.SetScore(TestPurpose, FilterType, bIsTheSame, bNegate);
54+
}
55+
break;
56+
57+
case EFactionTestMode::IsFriendly:
58+
for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
59+
{
60+
AActor* PointActor = GetItemActor(QueryInstance, It.GetIndex());
61+
62+
const bool bIsFriendly = UFactionsLibrary::GetFaction(PointActor).IsFriendlyTowards(TargetFaction);
63+
It.SetScore(TestPurpose, FilterType, bIsFriendly, bNegate);
64+
}
65+
break;
66+
67+
case EFactionTestMode::IsNeutral:
68+
for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
69+
{
70+
AActor* PointActor = GetItemActor(QueryInstance, It.GetIndex());
71+
72+
const bool bIsNeutral = UFactionsLibrary::GetFaction(PointActor).IsNeutralTowards(TargetFaction);
73+
It.SetScore(TestPurpose, FilterType, bIsNeutral, bNegate);
74+
}
75+
break;
76+
77+
case EFactionTestMode::IsHostile:
78+
for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
79+
{
80+
AActor* PointActor = GetItemActor(QueryInstance, It.GetIndex());
81+
82+
const bool bIsHostile = UFactionsLibrary::GetFaction(PointActor).IsHostileTowards(TargetFaction);
83+
It.SetScore(TestPurpose, FilterType, bIsHostile, bNegate);
84+
}
85+
break;
86+
}
87+
}
88+
89+
FText UEnvQueryTest_Faction::GetDescriptionTitle() const
90+
{
91+
const bool bNegate = BoolValue.GetValue();
92+
FString ModeDesc;
93+
94+
if (Mode == EFactionTestMode::IsTheSame)
95+
{
96+
ModeDesc = bNegate? TEXT("Doesn't equal ") : TEXT("Equals ");
97+
}
98+
else
99+
{
100+
ModeDesc = TEXT("");
101+
if (bNegate)
102+
ModeDesc += TEXT("Not ");
103+
104+
switch (Mode)
105+
{
106+
case EFactionTestMode::IsFriendly:
107+
ModeDesc += TEXT("Friendly towards ");
108+
break;
109+
case EFactionTestMode::IsNeutral:
110+
ModeDesc += TEXT("Neutral towards ");
111+
break;
112+
case EFactionTestMode::IsHostile:
113+
ModeDesc += TEXT("Hostile towards ");
114+
break;
115+
default:
116+
break;
117+
}
118+
}
119+
120+
if (bCompareTowardsContextActor)
121+
{
122+
ModeDesc += *UEnvQueryTypes::DescribeContext(Context).ToString();
123+
ModeDesc += TEXT("'s faction");
124+
}
125+
else
126+
{
127+
ModeDesc += Faction.GetDisplayName();
128+
}
129+
130+
return FText::FromString(*ModeDesc);
21131
}
22132

23133
FText UEnvQueryTest_Faction::GetDescriptionDetails() const
24134
{
25-
return Super::GetDescriptionDetails();
135+
return FText::Format(LOCTEXT("DescriptionFormat", "{0} test: {1}"), Super::GetDescriptionTitle(), DescribeFloatTestParams());
26136
}
27137

28138
#undef LOCTEXT_NAMESPACE

Source/Factions/Private/Factions/Faction.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ const ETeamAttitude::Type FFaction::GetAttitudeTowards(const FFaction& Other) co
9494
return FoundRelationPtr->Attitude;
9595
}
9696

97+
FString FFaction::GetDisplayName() const
98+
{
99+
FFactionInfo Info;
100+
if (GetFactionInfo(Info))
101+
{
102+
return Info.DisplayName.IsEmpty() ? ToString() : Info.DisplayName.ToString();
103+
}
104+
return ToString();
105+
}
106+
97107
const FGenericTeamId FFaction::GetTeam() const
98108
{
99109
if (IsNone()) {

Source/Factions/Private/FactionsLibrary.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright 2015-2018 Piperift. All Rights Reserved.
22

33
#include "FactionsLibrary.h"
4+
#include <EngineUtils.h>
5+
#include <Engine/Engine.h>
6+
47
#include "FactionsModule.h"
58

69

@@ -51,3 +54,55 @@ bool UFactionsLibrary::UnregistryRelation(const FFactionRelation& Relation)
5154

5255
return Settings->Internal_UnregistryRelation(Relation);
5356
}
57+
58+
bool UFactionsLibrary::GetAllActorsWithFaction(const UObject* ContextObject, const FFaction Faction, EFactionTestMode Comparison, TSubclassOf<AActor> ActorClass, TArray<AActor*>& OutActors)
59+
{
60+
QUICK_SCOPE_CYCLE_COUNTER(UGameplayStatics_GetAllActorsOfClass);
61+
OutActors.Reset();
62+
63+
if (Faction.IsNone() || !ActorClass)
64+
return false;
65+
66+
UWorld* World = GEngine->GetWorldFromContextObject(ContextObject, EGetWorldErrorMode::ReturnNull);
67+
if (World)
68+
{
69+
switch (Comparison) {
70+
case EFactionTestMode::IsTheSame:
71+
for (TActorIterator<AActor> It(World, ActorClass); It; ++It)
72+
{
73+
AActor* Actor = *It;
74+
if (!Actor->IsPendingKill() && UFactionsLibrary::GetFaction(Actor) == Faction)
75+
OutActors.Add(Actor);
76+
}
77+
break;
78+
case EFactionTestMode::IsFriendly:
79+
for (TActorIterator<AActor> It(World, ActorClass); It; ++It)
80+
{
81+
AActor* Actor = *It;
82+
if (!Actor->IsPendingKill() && UFactionsLibrary::GetFaction(Actor).IsFriendlyTowards(Faction))
83+
OutActors.Add(Actor);
84+
}
85+
break;
86+
case EFactionTestMode::IsNeutral:
87+
for (TActorIterator<AActor> It(World, ActorClass); It; ++It)
88+
{
89+
AActor* Actor = *It;
90+
if (!Actor->IsPendingKill() && UFactionsLibrary::GetFaction(Actor).IsNeutralTowards(Faction))
91+
OutActors.Add(Actor);
92+
}
93+
break;
94+
case EFactionTestMode::IsHostile:
95+
for (TActorIterator<AActor> It(World, ActorClass); It; ++It)
96+
{
97+
AActor* Actor = *It;
98+
if (!Actor->IsPendingKill() && UFactionsLibrary::GetFaction(Actor).IsHostileTowards(Faction))
99+
OutActors.Add(Actor);
100+
}
101+
break;
102+
}
103+
104+
return OutActors.Num() > 0;
105+
}
106+
107+
return false;
108+
}

Source/Factions/Public/EnvironmentQuery/EnvQueryTest_Faction.h

+25-1
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,41 @@
44

55
#include "CoreMinimal.h"
66
#include "EnvironmentQuery/EnvQueryTest.h"
7+
8+
#include "Faction.h"
9+
#include "FactionsLibrary.h"
710
#include "EnvQueryTest_Faction.generated.h"
811

12+
913
/**
1014
*
1115
*/
1216
UCLASS(meta = (DisplayName = "Faction"))
1317
class FACTIONS_API UEnvQueryTest_Faction : public UEnvQueryTest
1418
{
15-
GENERATED_UCLASS_BODY()
19+
GENERATED_BODY()
20+
21+
public:
22+
23+
UPROPERTY(EditAnywhere, Category = Faction)
24+
EFactionTestMode Mode;
25+
26+
UPROPERTY(EditAnywhere, Category = Faction)
27+
bool bCompareTowardsContextActor;
28+
29+
UPROPERTY(EditAnywhere, Category = Faction, meta = (EditCondition = "!bCompareTowardsContextActor"))
30+
FFaction Faction;
31+
32+
UPROPERTY(EditAnywhere, Category = Faction, meta = (EditCondition = "bCompareTowardsContextActor"))
33+
TSubclassOf<UEnvQueryContext> Context;
34+
35+
36+
UEnvQueryTest_Faction();
1637

1738
protected:
39+
1840
virtual void RunTest(FEnvQueryInstance& QueryInstance) const override;
41+
42+
virtual FText GetDescriptionTitle() const override;
1943
virtual FText GetDescriptionDetails() const override;
2044
};

Source/Factions/Public/Factions/Faction.h

+12
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ struct FACTIONS_API FFaction
6262
/**
6363
* Attitude evaluation
6464
*/
65+
FORCEINLINE bool IsFriendlyTowards(const FFaction& Other) const {
66+
return GetAttitudeTowards(Other) == ETeamAttitude::Friendly;
67+
}
68+
FORCEINLINE bool IsNeutralTowards(const FFaction& Other) const {
69+
return GetAttitudeTowards(Other) == ETeamAttitude::Neutral;
70+
}
6571
FORCEINLINE bool IsHostileTowards(const FFaction& Other) const {
6672
return GetAttitudeTowards(Other) == ETeamAttitude::Hostile;
6773
}
@@ -89,5 +95,11 @@ struct FACTIONS_API FFaction
8995
return Name;
9096
}
9197

98+
FString ToString() const {
99+
return GetIdName().ToString();
100+
}
101+
102+
FString GetDisplayName() const;
103+
92104
const FGenericTeamId GetTeam() const;
93105
};

Source/Factions/Public/FactionsLibrary.h

+32
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@
1111

1212
#include "FactionsLibrary.generated.h"
1313

14+
15+
UENUM()
16+
enum class EFactionTestMode : uint8
17+
{
18+
IsTheSame,
19+
IsFriendly,
20+
IsNeutral,
21+
IsHostile
22+
};
23+
24+
1425
/**
1526
*
1627
*/
@@ -140,6 +151,17 @@ class FACTIONS_API UFactionsLibrary : public UBlueprintFunctionLibrary
140151
static FORCEINLINE bool IsNeutralFaction(const FFaction One, const FFaction Other) {
141152
return GetAttitudeToFaction(One, Other) == ETeamAttitude::Neutral;
142153
}
154+
/**
155+
* Find the information of a faction
156+
* @param Faction to search for
157+
* @param Info associated to the faction, if found
158+
* @return true if the faction was valid and information was found
159+
*/
160+
UFUNCTION(BlueprintPure, Category = Factions)
161+
static FORCEINLINE FString GetDisplayName(const FFaction Faction)
162+
{
163+
return Faction.GetDisplayName();
164+
}
143165

144166
/**
145167
* Registry a new faction.
@@ -180,4 +202,14 @@ class FACTIONS_API UFactionsLibrary : public UBlueprintFunctionLibrary
180202
*/
181203
UFUNCTION(BlueprintCallable, Category = Factions)
182204
static bool UnregistryRelation(const FFactionRelation& Relation);
205+
206+
/**
207+
* Get all actors in the world with a certain faction
208+
* @param Faction to check actors for
209+
* @param Comparison relation between the actor and the faction
210+
* @param ActorClass limits the actors to be found by that class
211+
* @return true if operation was successful and the array of actors
212+
*/
213+
UFUNCTION(BlueprintCallable, Category = Factions, meta = (WorldContext = "ContextObject", AdvancedDisplay="ActorClass", DeterminesOutputType = "ActorClass", DynamicOutputParam = "OutActors"))
214+
static bool GetAllActorsWithFaction(const UObject* ContextObject, const FFaction Faction, EFactionTestMode Comparison, TSubclassOf<AActor> ActorClass, TArray<AActor*>& OutActors);
183215
};

0 commit comments

Comments
 (0)