Files
PHY/Plugins/GCS/Source/GenericGameplayAbilities/Private/Globals/GGA_GameplayEffectContext.cpp
2026-03-03 01:23:02 +08:00

144 lines
3.0 KiB
C++

// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#include "Globals/GGA_GameplayEffectContext.h"
FGameplayEffectContext* FGGA_GameplayEffectContext::Duplicate() const
{
FGGA_GameplayEffectContext* NewContext = new FGGA_GameplayEffectContext();
*NewContext = *this;
if (GetHitResult())
{
// Does a deep copy of the hit result
NewContext->AddHitResult(*GetHitResult(), true);
}
return NewContext;
}
UScriptStruct* FGGA_GameplayEffectContext::GetScriptStruct() const
{
return StaticStruct();
}
//Reference this:https://www.thegames.dev/?p=62
bool FGGA_GameplayEffectContext::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
bool bCombinedSuccess = FGameplayEffectContext::NetSerialize(Ar, Map, bOutSuccess);
enum RepFlag
{
REP_ContextPayloads,
REP_MAX
};
uint16 RepBits = 0;
if (Ar.IsSaving())
{
if (Payloads.Num() > 0)
{
RepBits |= 1 << REP_ContextPayloads;
}
}
Ar.SerializeBits(&RepBits, REP_MAX);
if (RepBits & (1 << REP_ContextPayloads))
{
// or also check if Ar.IsSaving || Ar.IsLoading
bCombinedSuccess &= SafeNetSerializeTArray_WithNetSerialize<31>(Ar, Payloads, Map);
}
return bCombinedSuccess;
}
TArray<FInstancedStruct>& FGGA_GameplayEffectContext::GetPayloads()
{
return Payloads;
}
void FGGA_GameplayEffectContext::AddOrOverwriteData(const FInstancedStruct& DataInstance)
{
RemovePayloadByType(DataInstance.GetScriptStruct());
Payloads.Add(DataInstance);
}
const FInstancedStruct* FGGA_GameplayEffectContext::FindPayloadByType(const UScriptStruct* PayloadType) const
{
for (const FInstancedStruct& Payload : Payloads)
{
if (const UScriptStruct* CandidateStruct = Payload.GetScriptStruct())
{
if (CandidateStruct == PayloadType)
{
return &Payload;
}
}
}
return nullptr;
}
FInstancedStruct* FGGA_GameplayEffectContext::FindPayloadByType(const UScriptStruct* PayloadType)
{
for (FInstancedStruct& Payload : Payloads)
{
if (const UScriptStruct* CandidateStruct = Payload.GetScriptStruct())
{
if (CandidateStruct == PayloadType)
{
return &Payload;
}
}
}
return nullptr;
}
FInstancedStruct* FGGA_GameplayEffectContext::FindOrAddPayloadByType(const UScriptStruct* PayloadType)
{
if (FInstancedStruct* ExistingData = FindPayloadByType(PayloadType))
{
return ExistingData;
}
return AddPayloadByType(PayloadType);
}
FInstancedStruct* FGGA_GameplayEffectContext::AddPayloadByType(const UScriptStruct* PayloadType)
{
if (ensure(!FindPayloadByType(PayloadType)))
{
FInstancedStruct Data;
Data.InitializeAs(PayloadType);
AddOrOverwriteData(Data);
return FindPayloadByType(PayloadType);
}
return nullptr;
}
bool FGGA_GameplayEffectContext::RemovePayloadByType(const UScriptStruct* PayloadType)
{
int32 IndexToRemove = -1;
for (int32 i = 0; i < Payloads.Num() && IndexToRemove < 0; ++i)
{
if (const UScriptStruct* CandidateStruct = Payloads[i].GetScriptStruct())
{
if (CandidateStruct == PayloadType)
{
IndexToRemove = i;
break;
}
}
}
if (IndexToRemove >= 0)
{
Payloads.RemoveAt(IndexToRemove);
return true;
}
return false;
}