Files
UnrealEngineUWP/Engine/Plugins/Runtime/GameplayInteractions/Source/GameplayInteractionsModule/Private/StateTree/GameplayInteractionFindSlotTask.cpp
mikko mononen 1c69b826cc StateTree: Added node validation during compilation
- Added a pass during compilation when node and instance data can be checked and adjusted by the node
- Changed blueprint based task to copy flags to the node in Compile()
- Changed relevant gameplay interaction tasks to check tags during Compile()

#rb Mieszko.Zielinski
#preflight 6377724cf514e1ded9a5ff44

[CL 23193668 by mikko mononen in ue5-main branch]
2022-11-18 08:38:31 -05:00

104 lines
3.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "GameplayInteractionFindSlotTask.h"
#include "StateTreeExecutionContext.h"
#include "SmartObjectSubsystem.h"
#include "VisualLogger/VisualLogger.h"
#include "Annotations/SmartObjectSlotLinkAnnotation.h"
#include "StateTreeLinker.h"
FGameplayInteractionFindSlotTask::FGameplayInteractionFindSlotTask()
{
// No tick needed.
bShouldCallTick = false;
// No need to update bound properties after enter state.
bShouldCopyBoundPropertiesOnTick = false;
bShouldCopyBoundPropertiesOnExitState = false;
}
bool FGameplayInteractionFindSlotTask::Link(FStateTreeLinker& Linker)
{
Linker.LinkExternalData(SmartObjectSubsystemHandle);
return true;
}
bool FGameplayInteractionFindSlotTask::UpdateResult(const FStateTreeExecutionContext& Context) const
{
const USmartObjectSubsystem& SmartObjectSubsystem = Context.GetExternalData(SmartObjectSubsystemHandle);
FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
if (!InstanceData.ReferenceSlot.IsValid())
{
UE_VLOG_UELOG(Context.GetOwner(), LogStateTree, Error, TEXT("[GameplayInteractionFindSlotTask] Expected valid ReferenceSlot handle."));
return false;
}
InstanceData.ResultSlot = FSmartObjectSlotHandle();
if (ReferenceType == EGameplayInteractionSlotReferenceType::ByLinkTag)
{
// Acquire the target slot based on a link
InstanceData.ResultSlot = FSmartObjectSlotHandle();
const FSmartObjectSlotView SlotView = SmartObjectSubsystem.GetSlotView(InstanceData.ReferenceSlot);
const FSmartObjectSlotDefinition& SlotDefinition = SlotView.GetDefinition();
for (const FInstancedStruct& Data : SlotDefinition.Data)
{
if (const FSmartObjectSlotLinkAnnotation* Link = Data.GetPtr<FSmartObjectSlotLinkAnnotation>())
{
if (Link->Tag.MatchesTag(FindByTag))
{
TArray<FSmartObjectSlotHandle> Slots;
SmartObjectSubsystem.GetAllSlots(SlotView.GetOwnerRuntimeObject(), Slots);
const int32 SlotIndex = Link->LinkedSlot.GetIndex();
if (Slots.IsValidIndex(SlotIndex))
{
InstanceData.ResultSlot = Slots[SlotIndex];
break;
}
}
}
}
}
else if (ReferenceType == EGameplayInteractionSlotReferenceType::ByActivityTag)
{
// Acquire the target slot based on activity tags
InstanceData.ResultSlot = FSmartObjectSlotHandle();
const FSmartObjectSlotView SlotView = SmartObjectSubsystem.GetSlotView(InstanceData.ReferenceSlot);
const USmartObjectDefinition& Definition = SlotView.GetSmartObjectDefinition();
int32 SlotIndex = 0;
for (const FSmartObjectSlotDefinition& SlotDefinition : Definition.GetSlots())
{
if (SlotDefinition.ActivityTags.HasTag(FindByTag))
{
TArray<FSmartObjectSlotHandle> Slots;
SmartObjectSubsystem.GetAllSlots(SlotView.GetOwnerRuntimeObject(), Slots);
if (Slots.IsValidIndex(SlotIndex))
{
InstanceData.ResultSlot = Slots[SlotIndex];
break;
}
}
SlotIndex++;
}
}
return InstanceData.ResultSlot.IsValid();
}
EStateTreeRunStatus FGameplayInteractionFindSlotTask::EnterState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const
{
if (!UpdateResult(Context))
{
return EStateTreeRunStatus::Failed;
}
return EStateTreeRunStatus::Running;
}