144 lines
3.0 KiB
C++
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;
|
|
}
|