// 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& 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; }