第一次提交
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
#include "GIS_EquipmentStructLibrary.h"
|
||||
|
||||
#include "GIS_EquipmentInstance.h"
|
||||
#include "GIS_EquipmentSystemComponent.h"
|
||||
#include "GIS_ItemFragment_Equippable.h"
|
||||
#include "GIS_ItemInstance.h"
|
||||
#include "GIS_LogChannels.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GIS_EquipmentStructLibrary)
|
||||
|
||||
FString FGIS_EquipmentEntry::GetDebugString() const
|
||||
{
|
||||
return FString::Printf(TEXT("%s"), *GetNameSafe(Instance));
|
||||
}
|
||||
|
||||
bool FGIS_EquipmentEntry::CheckClientDataReady() const
|
||||
{
|
||||
bool bDataReady = Instance != nullptr && ItemInstance != nullptr && EquippedSlot.IsValid();
|
||||
if (!bDataReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
UGIS_EquipmentInstance* EquipmentInstance = Cast<UGIS_EquipmentInstance>(Instance);
|
||||
if (!EquipmentInstance)
|
||||
return true;
|
||||
|
||||
const UGIS_ItemFragment_Equippable* Equippable = ItemInstance->FindFragmentByClass<UGIS_ItemFragment_Equippable>();
|
||||
|
||||
if (!Equippable || Equippable->bActorBased || Equippable->ActorsToSpawn.IsEmpty())
|
||||
return true;
|
||||
|
||||
TArray<AActor*> EquipmentActors = EquipmentInstance->GetEquipmentActors();
|
||||
// actor num doesn't match.
|
||||
if (EquipmentActors.Num() != Equippable->ActorsToSpawn.Num())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bValid = true;
|
||||
for (int32 i = 0; i < EquipmentActors.Num(); i++)
|
||||
{
|
||||
if (!::IsValid(EquipmentActors[i]))
|
||||
{
|
||||
bValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bValid;
|
||||
}
|
||||
|
||||
bool FGIS_EquipmentEntry::IsValidEntry() const
|
||||
{
|
||||
return Instance != nullptr && ItemInstance != nullptr && EquippedSlot.IsValid();
|
||||
}
|
||||
|
||||
void FGIS_EquipmentContainer::PreReplicatedRemove(const TArrayView<int32> RemovedIndices, int32 FinalSize)
|
||||
{
|
||||
for (int32 Index : RemovedIndices)
|
||||
{
|
||||
FGIS_EquipmentEntry& Entry = Entries[Index];
|
||||
|
||||
// already in the list.
|
||||
if (OwningComponent->SlotToInstanceMap.Contains(Entry.EquippedSlot))
|
||||
{
|
||||
OwningComponent->OnEquipmentEntryRemoved(Entry, Index);
|
||||
}
|
||||
else if (OwningComponent->PendingEquipmentEntries.Contains(Index))
|
||||
{
|
||||
GIS_OWNED_CLOG(OwningComponent, Warning, "Discard pending equipment(%s).", *OwningComponent->PendingEquipmentEntries[Index].GetDebugString())
|
||||
OwningComponent->PendingEquipmentEntries.Remove(Index);
|
||||
}
|
||||
Entry.bPrevActive = Entry.bActive;
|
||||
Entry.PrevEquippedGroup = Entry.EquippedGroup;
|
||||
}
|
||||
}
|
||||
|
||||
void FGIS_EquipmentContainer::PostReplicatedAdd(const TArrayView<int32> AddedIndices, int32 FinalSize)
|
||||
{
|
||||
for (int32 Index : AddedIndices)
|
||||
{
|
||||
FGIS_EquipmentEntry& Entry = Entries[Index];
|
||||
if (OwningComponent)
|
||||
{
|
||||
if (OwningComponent->GetOwner() && OwningComponent->IsEquipmentSystemInitialized() && Entry.CheckClientDataReady())
|
||||
{
|
||||
OwningComponent->OnEquipmentEntryAdded(Entry, Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
OwningComponent->PendingEquipmentEntries.Add(Index, Entry);
|
||||
}
|
||||
}
|
||||
Entry.bPrevActive = Entry.bActive;
|
||||
}
|
||||
}
|
||||
|
||||
void FGIS_EquipmentContainer::PostReplicatedChange(const TArrayView<int32> ChangedIndices, int32 FinalSize)
|
||||
{
|
||||
for (int32 Index : ChangedIndices)
|
||||
{
|
||||
FGIS_EquipmentEntry& Entry = Entries[Index];
|
||||
if (OwningComponent->SlotToInstanceMap.Contains(Entry.EquippedSlot)) // Already Added.
|
||||
{
|
||||
OwningComponent->OnEquipmentEntryChanged(Entry, Index);
|
||||
}
|
||||
else if (OwningComponent->PendingEquipmentEntries.Contains(Index)) // In pending list.
|
||||
{
|
||||
OwningComponent->PendingEquipmentEntries.Emplace(Index, Entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
OwningComponent->PendingEquipmentEntries.Add(Index, Entry); // Add to pending list.
|
||||
}
|
||||
Entry.bPrevActive = Entry.bActive;
|
||||
Entry.PrevEquippedGroup = Entry.EquippedGroup;
|
||||
}
|
||||
}
|
||||
|
||||
int32 FGIS_EquipmentContainer::IndexOfBySlot(const FGameplayTag& Slot) const
|
||||
{
|
||||
if (!Slot.IsValid())
|
||||
{
|
||||
return INDEX_NONE;
|
||||
}
|
||||
return Entries.IndexOfByPredicate([Slot](const FGIS_EquipmentEntry& Entry)
|
||||
{
|
||||
return Entry.EquippedSlot == Slot;
|
||||
});
|
||||
}
|
||||
|
||||
int32 FGIS_EquipmentContainer::IndexOfByGroup(const FGameplayTag& Group) const
|
||||
{
|
||||
if (!Group.IsValid())
|
||||
{
|
||||
return INDEX_NONE;
|
||||
}
|
||||
return Entries.IndexOfByPredicate([Group](const FGIS_EquipmentEntry& Entry)
|
||||
{
|
||||
return Entry.EquippedGroup.IsValid() && Entry.EquippedGroup == Group;
|
||||
});
|
||||
}
|
||||
|
||||
int32 FGIS_EquipmentContainer::IndexOfByInstance(const UObject* Instance) const
|
||||
{
|
||||
if (!IsValid(Instance))
|
||||
{
|
||||
return INDEX_NONE;
|
||||
}
|
||||
return Entries.IndexOfByPredicate([Instance](const FGIS_EquipmentEntry& Entry)
|
||||
{
|
||||
return Entry.Instance && Entry.Instance == Instance;
|
||||
});
|
||||
}
|
||||
|
||||
int32 FGIS_EquipmentContainer::IndexOfByItem(const UGIS_ItemInstance* Item) const
|
||||
{
|
||||
if (!IsValid(Item))
|
||||
{
|
||||
return INDEX_NONE;
|
||||
}
|
||||
return Entries.IndexOfByPredicate([Item](const FGIS_EquipmentEntry& Entry)
|
||||
{
|
||||
return Entry.ItemInstance && Entry.ItemInstance == Item;
|
||||
});
|
||||
}
|
||||
|
||||
int32 FGIS_EquipmentContainer::IndexOfByItemId(const FGuid& ItemId) const
|
||||
{
|
||||
if (!ItemId.IsValid())
|
||||
{
|
||||
return INDEX_NONE;
|
||||
}
|
||||
return Entries.IndexOfByPredicate([ItemId](const FGIS_EquipmentEntry& Entry)
|
||||
{
|
||||
return Entry.ItemInstance && Entry.ItemInstance->GetItemId() == ItemId;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user