Skip to content

Commit

Permalink
Implementation for the Sockets system.
Browse files Browse the repository at this point in the history
  • Loading branch information
mattyman174 committed Mar 24, 2024
1 parent dacc405 commit ae11aeb
Show file tree
Hide file tree
Showing 36 changed files with 916 additions and 19 deletions.
Binary file modified Content/Itemization/AffixTables/Affixes.uasset
Binary file not shown.
Binary file modified Content/Itemization/BP_ItemDrop.uasset
Binary file not shown.
Binary file modified Content/Itemization/DropTables/TreasureClass.uasset
Binary file not shown.
Binary file modified Content/Itemization/GameMode/BP_PlayerController.uasset
Binary file not shown.
Binary file modified Content/Itemization/Inventories/WBP_CursorInventory.uasset
Binary file not shown.
Binary file modified Content/Itemization/Inventories/WBP_InventorySlot.uasset
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified Content/Itemization/ItemTables/Ammo.uasset
Binary file not shown.
Binary file modified Content/Itemization/ItemTables/Armor.uasset
Binary file not shown.
Binary file modified Content/Itemization/ItemTables/Gold.uasset
Binary file not shown.
Binary file modified Content/Itemization/ItemTables/Misc.uasset
Binary file not shown.
Binary file modified Content/Itemization/ItemTables/Potions.uasset
Binary file not shown.
Binary file not shown.
Binary file modified Content/Itemization/ItemTables/Weapons.uasset
Binary file not shown.
Binary file modified Content/Itemization/WBP_ItemDropDetails.uasset
Binary file not shown.
Binary file modified Content/Itemization/WBP_ItemDropTag.uasset
Binary file not shown.
Binary file modified ItemSystem.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ void FAffixInstance::SetAffixDefinition(const FDataTableRowHandle& Handle)
/* Items
/************************************************************************/

FItemSocketInstance::FItemSocketInstance()
{
SocketId = FGuid::NewGuid();
bIsEmpty = false;
}

const FConstStructView FItemSocketInstance::GetSocketedItem() const
{
return FConstStructView(SocketedItemInstance);
}

FItemInstance::FItemInstance()
{
ItemId = FGuid::NewGuid();
Expand Down Expand Up @@ -110,6 +121,8 @@ bool FItemInstance::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOu
SafeNetSerializeTArray_WithNetSerialize<31>(Ar, ReplicatedAffixes, Map); // @NOTE: This means we have a practical maximum of 32 Affixes per ItemInstance. Should we expose this somehow?
if (Ar.IsLoading())
{
// We need to empty the actual array as we are effectively rebuilding it.
Affixes.Empty(ReplicatedAffixes.Num());
for (const FInstancedStruct& ReplicatedAffix : ReplicatedAffixes)
{
TInstancedStruct<FAffixInstance> Affix;
Expand All @@ -118,6 +131,31 @@ bool FItemInstance::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOu
}
}

// Ar << Sockets;
TArray<FInstancedStruct> ReplicatedSockets;
if (Ar.IsSaving())
{
for (const TInstancedStruct<FItemSocketInstance>& Socket : Sockets)
{
FInstancedStruct ReplicatedSocket;
ReplicatedSocket.InitializeAs(Socket.GetScriptStruct(), Socket.GetMemory());
ReplicatedSockets.Add(ReplicatedSocket);
}
}
SafeNetSerializeTArray_WithNetSerialize<31>(Ar, ReplicatedSockets, Map); // @NOTE: This means we have a practical maximum of 32 Sockets per ItemInstance. Should we expose this somehow?
if (Ar.IsLoading())
{
// We need to empty the actual array as we are effectively rebuilding it.
Sockets.Empty(ReplicatedSockets.Num());
for (const FInstancedStruct& ReplicatedSocket : ReplicatedSockets)
{
TInstancedStruct<FItemSocketInstance> Socket;
Socket.InitializeAsScriptStruct(ReplicatedSocket.GetScriptStruct(), ReplicatedSocket.GetMemory());

AddSocket(Socket);
}
}

bOutSuccess = true;
return true;
}
Expand All @@ -135,6 +173,40 @@ void FItemInstance::SetItemDefinition(const FDataTableRowHandle& Handle)
}
}

void FItemInstance::AddSocket(TInstancedStruct<FItemSocketInstance>& NewSocket)
{
// Let the Socket know what its definition is.
FSetSocketInstanceSocketDefinition(ItemDefinition.GetPtr(), NewSocket.GetMutablePtr());
Sockets.Add(NewSocket);
}

TOptional<const FConstStructView> FItemInstance::GetSocket(FGuid SocketId) const
{
TOptional<const FConstStructView> Result;
for (const TInstancedStruct<FItemSocketInstance>& Socket : Sockets)
{
if (Socket.Get().SocketId == SocketId)
{
Result.Emplace(FConstStructView(Socket.GetScriptStruct(), Socket.GetMemory()));
}
}

return Result;
}

bool FItemInstance::HasSocket(FGuid SocketId) const
{
for (const TInstancedStruct<FItemSocketInstance>& Socket : Sockets)
{
if (Socket.Get().SocketId == SocketId)
{
return true;
}
}

return false;
}

void FFastItemInstance::Initialize(FInstancedStruct& InItemInstance, FInstancedStruct& InUserContextData)
{
ItemInstance = InItemInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "GenericItemizationInstanceTypes.h"
#include "GenericItemizationPickFunctions.h"
#include "GameplayTagsManager.h"
#include "ItemManagement/ItemSocketSettings.h"

UItemInstancingFunction::UItemInstancingFunction()
{
Expand Down Expand Up @@ -203,6 +204,40 @@ bool UItemInstancingFunction::CalculateStackCount_Implementation(const FInstance
return true;
}

bool UItemInstancingFunction::DetermineActiveSockets_Implementation(const FInstancedStruct& ItemInstance, const FInstancedStruct& ItemInstancingContext, TArray<int32>& OutActiveSocketDefinitions) const
{
const FItemInstance* ItemInstancePtr = ItemInstance.GetPtr<FItemInstance>();
if (!ItemInstancePtr)
{
return false;
}

const TInstancedStruct<FItemDefinition>& ItemDefinitionInstance = ItemInstancePtr->GetItemDefinition();
if (!ItemDefinitionInstance.IsValid())
{
return false;
}

const FItemDefinition& ItemDefinition = ItemDefinitionInstance.Get();
if (ItemDefinition.bStacksOverSockets)
{
// If we are using Stacking functionality instead of Socketing functionality, then we can exit early with no default Active Sockets.
OutActiveSocketDefinitions.Empty();
return true;
}

const UItemSocketSettings* const ItemSocketSettingsCDO = ItemDefinition.SocketSettings.GetDefaultObject();
if (!ItemSocketSettingsCDO)
{
// This isn't necessarily a failure case.
OutActiveSocketDefinitions.Empty();
return true;
}

// By default we let the ItemSocketSettings decide what to do.
return ItemSocketSettingsCDO->DetermineActiveSockets(ItemInstance, ItemInstancingContext, OutActiveSocketDefinitions);
}

bool UItemInstancingContextFunction::BuildItemInstancingContext_Implementation(const UItemDropperComponent* ItemDropperComponent, const FInstancedStruct& UserContextData, FInstancedStruct& OutItemInstancingContext)
{
// Override to provide your own context.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "StructView.h"
#include "Engine/DataTable.h"
#include "Kismet/KismetSystemLibrary.h"
#include "ItemManagement/ItemSocketSettings.h"

TOptional<TInstancedStruct<FItemDropTableType>> UGenericItemizationStatics::PickDropTableCollectionEntry(const TInstancedStruct<FItemDropTableCollectionRow>& DropTableCollectionEntry, const FInstancedStruct& ItemInstancingContext, bool bIncludeNoPick)
{
Expand Down Expand Up @@ -393,6 +394,38 @@ bool UGenericItemizationStatics::GenerateItemInstanceFromItemDefinition(const FD
MutableItemInstance->StackCount = FMath::Max(1, DesiredStackCount);
}

// =====================================================================================
// 6. Assign all of the Sockets to the ItemInstance that it has access to.
// Also activate those that need to be from the InstancingFunction and by extension the SocketSettings.
{
TArray<int32> SocketsToActivate;
bool bDeterminedSocketsToActivate = InstancingFunctionCDO->DetermineActiveSockets(NewItemInstance, ItemInstancingContext, SocketsToActivate);
if (bDeterminedSocketsToActivate)
{
// Add all of the Sockets that the ItemSocketSettings is saying the ItemInstance needs to have.
const UItemSocketSettings* const ItemSocketSettingsCDO = ItemInstanceItemDefinition.Get().SocketSettings.GetDefaultObject();
if (ItemSocketSettingsCDO)
{
const int32 MaximumSocketCount = ItemInstanceItemDefinition.Get().MaximumSocketCount;
int32 SocketCount = MaximumSocketCount >= 0 ? MaximumSocketCount : INT_MAX;
for (const TInstancedStruct<FItemSocketDefinition>& SocketDefintion : ItemSocketSettingsCDO->GetSocketDefinitions(SocketsToActivate))
{
if(SocketCount > 0)
{
FItemSocketInstance NewSocket;
NewSocket.SocketDefinitionHandle = SocketDefintion.Get().SocketDefinitionHandle;
NewSocket.bIsEmpty = true; // Empty by default.

TInstancedStruct<FItemSocketInstance> SocketInstance = TInstancedStruct<FItemSocketInstance>::Make(NewSocket);
MutableItemInstance->AddSocket(SocketInstance);
}

SocketCount--;
}
}
}
}

OutItemInstance = NewItemInstance;
return true;
}
Expand All @@ -418,3 +451,45 @@ bool UGenericItemizationStatics::GenerateItemInstanceFromTemplate(const FInstanc

return true;
}

bool UGenericItemizationStatics::GetItemAffixes(const TInstancedStruct<FItemInstance>& Item, TArray<TInstancedStruct<FAffixInstance>>& OutAffixes, bool bIncludeSocketedItems /*= true*/)
{
const FItemInstance* ItemInstance = Item.GetPtr();
if (!ItemInstance)
{
return false;
}

OutAffixes.Empty(ItemInstance->Affixes.Num());
OutAffixes.Append(ItemInstance->Affixes);

if (bIncludeSocketedItems)
{
for (const TInstancedStruct<FItemSocketInstance>& Socket : ItemInstance->Sockets)
{
const FItemSocketInstance* SocketInstance = Socket.GetPtr();
if (SocketInstance && !SocketInstance->bIsEmpty)
{
const FItemInstance* SocketedItemInstance = SocketInstance->GetSocketedItem().GetPtr<const FItemInstance>();
if (SocketedItemInstance)
{
const TArray<TInstancedStruct<FAffixInstance>>& Affixes = SocketedItemInstance->Affixes;
for (const TInstancedStruct<FAffixInstance>& Affix : Affixes)
{
const FAffixInstance* AffixInstance = Affix.GetPtr();
if (AffixInstance)
{
const FAffixDefinition* AffixDefinition = AffixInstance->GetAffixDefinition().GetPtr();
if (AffixDefinition && AffixDefinition->bShouldAggregateInSockets)
{
OutAffixes.Add(Affix);
}
}
}
}
}
}
}

return OutAffixes.Num() > 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ namespace GenericItemizationGameplayTags
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(AffixType, "Itemization.AffixType", "The overarching type of a particular Affix that creates logical groups of Affixes that might do the same/similar thing.");
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(UserData, "Itemization.UserData", "Arbitrary Data that can contain whatever you like.");
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(Mutator, "Itemization.Mutator", "Arbitrary Data that can contain whatever you like that is appended to the ItemInstancingContext.");
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(SocketType, "Itemization.SocketType", "The overarching type of an ItemSocket.");

GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(ItemInstanceChange, "Itemization.ItemInstanceChange", "Describes a change to an ItemInstance.");
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(StackCountChange, "Itemization.ItemInstanceChange.StackCount", "The StackCount of an ItemInstance was changed.");
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(ItemInstanceChange_StackCount, "Itemization.ItemInstanceChange.StackCount", "The StackCount of an ItemInstance was changed.");
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(ItemInstanceChange_SocketChange_Socketed, "Itemization.ItemInstanceChange.SocketChange.Socketed", "An ItemInstance was Socketed into another ItemInstance.");
GENERICITEMIZATION_API UE_DEFINE_GAMEPLAY_TAG_COMMENT(ItemInstanceChange_SocketChange_Unsocketed, "Itemization.ItemInstanceChange.SocketChange.Unsocketed", "An ItemInstance was Unsocketed from another ItemInstance.");
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "GenericItemizationTypes.h"
#include "GenericItemizationPickFunctions.h"
#include "GenericItemizationInstancingFunctions.h"
#include "GenericItemizationTags.h"

FItemDropTableCollectionRow::FItemDropTableCollectionRow()
{
Expand All @@ -19,6 +20,7 @@ FItemDefinitionCollection::FItemDefinitionCollection()
FItemDefinition::FItemDefinition()
{
InstancingFunction = UItemInstancingFunction::StaticClass();
SocketableInto.AddTag(GenericItemizationGameplayTags::SocketType);
}

bool FItemDefinition::IsSameItemDefinition(const FItemDefinition& Other) const
Expand Down
Loading

0 comments on commit ae11aeb

Please sign in to comment.