Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions Source/Editor/Private/Asset/AssetTypeAction_FactionCollection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2015-2020 Piperift. All Rights Reserved.

#include "Asset/AssetTypeAction_FactionCollection.h"

#include "AssetToolsModule.h"
#include "ContentBrowserModule.h"
#include "FactionCollection.h"
#include "FactionsModule.h"


#define LOCTEXT_NAMESPACE "AssetTypeActions"


//////////////////////////////////////////////////////////////////////////
// FAssetTypeAction_FactionCollection

FText FAssetTypeAction_FactionCollection::GetName() const
{
return LOCTEXT("FAssetTypeAction_FactionCollectionName", "Faction Collection");
}

FColor FAssetTypeAction_FactionCollection::GetTypeColor() const
{
return FColor(170, 66, 244);
}

UClass* FAssetTypeAction_FactionCollection::GetSupportedClass() const
{
return UFactionCollection::StaticClass();
}

uint32 FAssetTypeAction_FactionCollection::GetCategories()
{
return EAssetTypeCategories::Misc;
}

//////////////////////////////////////////////////////////////////////////

#undef LOCTEXT_NAMESPACE
33 changes: 33 additions & 0 deletions Source/Editor/Private/Asset/FactionCollectionFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2015-2020 Piperift. All Rights Reserved.

#include "Asset/FactionCollectionFactory.h"

#include <ClassViewerModule.h>
#include <ClassViewerFilter.h>
#include "Kismet2/SClassPickerDialog.h"
#include "FactionCollection.h"


#define LOCTEXT_NAMESPACE "FactionCollection"

UFactionCollectionFactory::UFactionCollectionFactory()
: Super()
{
SupportedClass = UFactionCollection::StaticClass();

bCreateNew = true;
bEditAfterNew = true;
}

UObject* UFactionCollectionFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{
if(Class != nullptr)
{
// if we have no asset class, use the passed-in class instead
check(Class == UFactionCollection::StaticClass() || Class->IsChildOf(UFactionCollection::StaticClass()));
return NewObject<UFactionCollection>(InParent, Class, Name, Flags);
}
return nullptr;
}

#undef LOCTEXT_NAMESPACE
4 changes: 2 additions & 2 deletions Source/Editor/Private/FactionsEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include <Kismet2/KismetEditorUtilities.h>

//#include "Asset/AssetTypeAction_FactionCollection.h"
#include "Asset/AssetTypeAction_FactionCollection.h"


DEFINE_LOG_CATEGORY(LogFactionsEditor)
Expand All @@ -28,7 +28,7 @@ void FFactionsEditorModule::StartupModule()
PrepareAutoGeneratedDefaultEvents();

IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
//RegisterAssetTypeAction(AssetTools, MakeShared<FAssetTypeAction_FactionCollection>());
RegisterAssetTypeAction(AssetTools, MakeShared<FAssetTypeAction_FactionCollection>());
}

void FFactionsEditorModule::ShutdownModule()
Expand Down
17 changes: 17 additions & 0 deletions Source/Editor/Public/Asset/AssetTypeAction_FactionCollection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2015-2020 Piperift. All Rights Reserved.

#pragma once

#include "AssetTypeActions_Base.h"

class FACTIONSEDITOR_API FAssetTypeAction_FactionCollection : public FAssetTypeActions_Base
{
public:
// IAssetTypeActions interface
virtual FText GetName() const override;
virtual FColor GetTypeColor() const override;
virtual UClass* GetSupportedClass() const override;
virtual bool HasActions(const TArray<UObject*>& InObjects) const override { return false; }
virtual uint32 GetCategories() override;
// End of IAssetTypeActions interface
};
20 changes: 20 additions & 0 deletions Source/Editor/Public/Asset/FactionCollectionFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2015-2020 Piperift. All Rights Reserved.

#pragma once

#include "Factories/Factory.h"
#include "FactionCollection.h"
#include "FactionCollectionFactory.generated.h"


UCLASS()
class UFactionCollectionFactory : public UFactory
{
GENERATED_BODY()

UFactionCollectionFactory();

// UFactory interface
virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
// End of UFactory interface
};
138 changes: 101 additions & 37 deletions Source/Factions/Private/FactionsSubsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,33 @@ void UFactionsSubsystem::PostInitProperties()

if (!IsDefaultSubobject() && !hasSetTeamIdAttitudeSolver)
{
FGenericTeamId::SetAttitudeSolver([this](FGenericTeamId A, FGenericTeamId B)
{
FGenericTeamId::SetAttitudeSolver([this](FGenericTeamId A, FGenericTeamId B) {
return GetAttitude(FromTeamId(A), FromTeamId(B));
});
hasSetTeamIdAttitudeSolver = true;
}
}

const FFactionDescriptor* UFactionsSubsystem::GetDescriptor(FFaction Faction) const
const FFactionDescriptor* UFactionsSubsystem::FindDescriptor(
FFaction Faction, UFactionCollection** OutCollection) const
{
return GetFactions().GetDescriptor(Faction);
const FFactionDescriptor* Descriptor = GetFactions().GetDescriptor(Faction);
UFactionCollection* Collection = nullptr;

for (auto It = Collections.begin(); !Descriptor && It != Collections.end(); ++It)
{
Collection = *It;
if (Collection)
{
Descriptor = Collection->Factions.GetDescriptor(Faction);
}
}

if (Descriptor && OutCollection)
{
*OutCollection = Collection;
}
return nullptr;
}

TEnumAsByte<ETeamAttitude::Type> UFactionsSubsystem::GetAttitude(
Expand All @@ -51,16 +67,22 @@ TEnumAsByte<ETeamAttitude::Type> UFactionsSubsystem::GetAttitude(
}
else if (!Source.IsNone())
{
UE_LOG(LogFactions, Warning, TEXT("Tried to get an attitude using an invalid faction ('%s'). All factions must be registered in the Factions Subsystem."), *Source.GetId().ToString());
UE_LOG(LogFactions, Warning,
TEXT("Tried to get an attitude using an invalid faction ('%s'). All factions must be registered "
"in the Factions Subsystem."),
*Source.GetId().ToString());
}
return ETeamAttitude::Neutral;
}

int32 UFactionsSubsystem::GetFactionIndex(FFaction Faction) const
{
return Algo::BinarySearchBy(BakedBehaviors, Faction.GetId(), [](const auto& Behavior) {
return Behavior.Id;
}, FBehaviorSort{});
return Algo::BinarySearchBy(
BakedBehaviors, Faction.GetId(),
[](const auto& Behavior) {
return Behavior.Id;
},
FBehaviorSort{});
}

FFaction UFactionsSubsystem::FromTeamId(FGenericTeamId TeamId) const
Expand All @@ -76,8 +98,9 @@ FFaction UFactionsSubsystem::FromTeamId(FGenericTeamId TeamId) const
FGenericTeamId UFactionsSubsystem::ToTeamId(FFaction Faction) const
{
const int32 Index = GetFactionIndex(Faction);
if (Index != INDEX_NONE &&
ensureMsgf(Index < FGenericTeamId::NoTeam.GetId(), TEXT("Faction Index exceeded maximum GenericTeamIds. GenericTeamId only supports up to 255 teams")))
if (Index != INDEX_NONE && ensureMsgf(Index < FGenericTeamId::NoTeam.GetId(),
TEXT("Faction Index exceeded maximum GenericTeamIds. GenericTeamId only "
"supports up to 255 teams")))
{
return FGenericTeamId{uint8(Index)};
}
Expand All @@ -86,11 +109,10 @@ FGenericTeamId UFactionsSubsystem::ToTeamId(FFaction Faction) const

FString UFactionsSubsystem::GetDisplayName(const FFaction Faction) const
{
const auto* Descriptor = GetDescriptor(Faction);
if (Descriptor)
if (const auto* Descriptor = FindDescriptor(Faction))
{
const bool bUseId = Descriptor->bIdAsDisplayName ||
(bUseIdsIfDisplayNamesAreEmpty && Descriptor->DisplayName.IsEmpty());
(bUseIdsIfDisplayNamesAreEmpty && Descriptor->DisplayName.IsEmpty());
if (!bUseId)
{
return Descriptor->DisplayName.ToString();
Expand Down Expand Up @@ -147,6 +169,45 @@ bool UFactionsSubsystem::RemoveRelation(const FFactionRelation& Relation)
return false;
}

bool UFactionsSubsystem::AddCollection(UFactionCollection* Collection)
{
if (Collections.Contains(Collection))
{
UE_LOG(LogFactions, Warning, TEXT("Collection ('%s') has already been added before."),
*Collection->GetName());
return false;
}

Collections.Add(Collection);

bool bFactionExisted = false;
for (const auto& Descriptor : Collection->Factions.List)
{
AddBakedFaction(Descriptor.Key, Descriptor.Value, &bFactionExisted);
if (bFactionExisted)
{
UE_LOG(LogFactions, Warning, TEXT("Added a duplicated faction from a collection. Relation: (%s)"),
*Descriptor.Key.ToString());
}
}

bool bRepeated = false;
Relations.List.Reserve(Relations.List.Num() + Collection->Relations.List.Num());
for (const auto& Relation : Collection->Relations.List)
{
Relations.List.Add(Relation, &bRepeated);
if (bRepeated)
{
UE_LOG(LogFactions, Warning,
TEXT("Added a duplicated relation from a collection. Relation: (%s)"),
*Relation.ToString(Collection));
}
}
Relations.List.Append(Collection->Relations.List);

return true;
}

int32 UFactionsSubsystem::ClearFactions()
{
const int32 Count = Factions.Num();
Expand Down Expand Up @@ -217,7 +278,7 @@ bool UFactionsSubsystem::GetActorsByFaction(const FFaction Faction, TArray<AActo

bool UFactionsSubsystem::SetDescriptor(const FFaction Faction, const FFactionDescriptor& Descriptor)
{
if (auto* Found = GetFactions().GetDescriptor(Faction))
if (auto* Found = Factions.GetDescriptor(Faction))
{
*Found = Descriptor;

Expand All @@ -235,18 +296,17 @@ bool UFactionsSubsystem::SetDescriptor(const FFaction Faction, const FFactionDes

void UFactionsSubsystem::GetAllFactions(TArray<FFaction>& OutFactions) const
{
const auto& AllFactions = GetFactions().List;

OutFactions.Reserve(OutFactions.Num() + AllFactions.Num());
for (const auto& Entry : AllFactions)
OutFactions.Reserve(OutFactions.Num() + BakedBehaviors.Num());
for (const auto& Behavior : BakedBehaviors)
{
OutFactions.Add({Entry.Key});
OutFactions.Add({Behavior.Id});
}
}

bool UFactionsSubsystem::BPGetDescriptor(const FFaction Faction, FFactionDescriptor& Descriptor) const
bool UFactionsSubsystem::BPFindDescriptor(
const FFaction Faction, FFactionDescriptor& Descriptor, UFactionCollection*& Collection) const
{
if (auto* Found = GetFactions().GetDescriptor(Faction))
if (auto* Found = FindDescriptor(Faction, &Collection))
{
Descriptor = *Found;
return true;
Expand Down Expand Up @@ -293,37 +353,36 @@ void UFactionsSubsystem::BakeFactions()
for (const auto& It : Factions.List)
{
const auto& Descriptor = It.Value;
BakedBehaviors.Add({
It.Key,
Descriptor.SelfAttitude,
Descriptor.ExternalAttitude
});
BakedBehaviors.Add({It.Key, Descriptor.SelfAttitude, Descriptor.ExternalAttitude});
}
BakedBehaviors.Sort([](const auto& A, const auto& B){
BakedBehaviors.Sort([](const auto& A, const auto& B) {
return A.Id.FastLess(B.Id);
});
}

void UFactionsSubsystem::AddBakedFaction(FName Id, const FFactionDescriptor& Descriptor)
void UFactionsSubsystem::AddBakedFaction(
FName Id, const FFactionDescriptor& Descriptor, bool* bWasAlreadyAdded)
{
// Insert sorted
const int32 Index = Algo::LowerBoundBy(BakedBehaviors, Id, [](const auto& Behavior) {
return Behavior.Id;
}, FBehaviorSort{});
const int32 Index = Algo::LowerBoundBy(
BakedBehaviors, Id,
[](const auto& Behavior) {
return Behavior.Id;
},
FBehaviorSort{});
check(Index >= 0 && Index <= BakedBehaviors.Num());

const FBakedFactionBehavior Behavior {
Id,
Descriptor.SelfAttitude,
Descriptor.ExternalAttitude
};
const FBakedFactionBehavior Behavior{Id, Descriptor.SelfAttitude, Descriptor.ExternalAttitude};
bool bReplaced = false;
if (BakedBehaviors.IsValidIndex(Index))
{
// Since we returned lower bound we already know Id <= Index key. So if Id is not < Index key, they must be equal
// Since we returned lower bound we already know Id <= Index key. So if Id is not < Index key, they
// must be equal
if (!FBehaviorSort{}(Id, BakedBehaviors[Index].Id))
{
// Found, replace
BakedBehaviors[Index] = Behavior;
bReplaced = true;
}
else
{
Expand All @@ -334,6 +393,11 @@ void UFactionsSubsystem::AddBakedFaction(FName Id, const FFactionDescriptor& Des
{
BakedBehaviors.Add(Behavior);
}

if (bWasAlreadyAdded)
{
*bWasAlreadyAdded = bReplaced;
}
}

void UFactionsSubsystem::RemoveBakedFaction(FFaction Faction)
Expand Down
Loading