Files
UnrealEngineUWP/Engine/Plugins/Runtime/GameplayInteractions/Source/GameplayInteractionsModule/Private/StateTree/GameplayInteractionConditions.cpp
mikko mononen 8dc086e33a Gameplay Interactions:
- Moved all State Tree things into StateTree folder
- Added StateTree conditions that check Smart Object slot tags and state
- Added StateTree task to modify SmartObject slot tags
- Added StateTree task to monitor SmartObject slot tags
- Added StateTree task to listen SmartObject events
- Added StateTree task to sync execution based on SmartObject slot tags

#rb Maxime.Mercier Luciano.Ferraro
#preflight 636124a8ef6d25c67458635c

[CL 22888785 by mikko mononen in ue5-main branch]
2022-11-01 15:14:34 -04:00

119 lines
4.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "StateTree/GameplayInteractionConditions.h"
#include "GameplayTagContainer.h"
#include "StateTreeExecutionContext.h"
#include "SmartObjectSubsystem.h"
#include "StateTreeLinker.h"
#include "VisualLogger/VisualLogger.h"
#define ST_INTERACTION_LOG(Verbosity, Format, ...) UE_VLOG_UELOG(Context.GetOwner(), LogStateTree, Verbosity, TEXT("[%s] ") Format, *StaticStruct()->GetName(), ##__VA_ARGS__)
#define ST_INTERACTION_CLOG(Condition, Verbosity, Format, ...) UE_CVLOG_UELOG((Condition), Context.GetOwner(), LogStateTree, Verbosity, TEXT("[%s] ") Format, *StaticStruct()->GetName(), ##__VA_ARGS__)
namespace UE::GameplayInteraction
{
const FGameplayTagContainer* GetSlotTags(const USmartObjectSubsystem& SmartObjectSubsystem, const FSmartObjectSlotHandle Slot, const EGameplayInteractionMatchSlotTagSource Source)
{
const FSmartObjectSlotView SlotView = SmartObjectSubsystem.GetSlotView(Slot);
if (!SlotView.IsValid())
{
return nullptr;
}
if (Source == EGameplayInteractionMatchSlotTagSource::RuntimeTags)
{
return &SlotView.GetTags();
}
else if (Source == EGameplayInteractionMatchSlotTagSource::ActivityTags)
{
const FSmartObjectSlotDefinition& SlotDefinition = SlotView.GetDefinition();
return &SlotDefinition.ActivityTags;
}
return nullptr;
}
};
//----------------------------------------------------------------------//
// FGameplayInteractionSlotTagsMatchCondition
//----------------------------------------------------------------------//
bool FGameplayInteractionSlotTagsMatchCondition::Link(FStateTreeLinker& Linker)
{
Linker.LinkExternalData(SmartObjectSubsystemHandle);
return true;
}
bool FGameplayInteractionSlotTagsMatchCondition::TestCondition(FStateTreeExecutionContext& Context) const
{
const USmartObjectSubsystem& SmartObjectSubsystem = Context.GetExternalData(SmartObjectSubsystemHandle);
const FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
const FGameplayTagContainer* Container = UE::GameplayInteraction::GetSlotTags(SmartObjectSubsystem, InstanceData.Slot, Source);
if (Container == nullptr)
{
return false;
}
bool bResult = false;
switch (MatchType)
{
case EGameplayContainerMatchType::Any:
bResult = bExactMatch ? Container->HasAnyExact(InstanceData.TagsToMatch) : Container->HasAny(InstanceData.TagsToMatch);
break;
case EGameplayContainerMatchType::All:
bResult = bExactMatch ? Container->HasAllExact(InstanceData.TagsToMatch) : Container->HasAll(InstanceData.TagsToMatch);
break;
default:
ensureMsgf(false, TEXT("Unhandled match type %s."), *UEnum::GetValueAsString(MatchType));
}
return bResult ^ bInvert;
}
//----------------------------------------------------------------------//
// FGameplayInteractionQuerySlotTagCondition
//----------------------------------------------------------------------//
bool FGameplayInteractionQuerySlotTagCondition::Link(FStateTreeLinker& Linker)
{
Linker.LinkExternalData(SmartObjectSubsystemHandle);
return true;
}
bool FGameplayInteractionQuerySlotTagCondition::TestCondition(FStateTreeExecutionContext& Context) const
{
const USmartObjectSubsystem& SmartObjectSubsystem = Context.GetExternalData(SmartObjectSubsystemHandle);
const FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
const FGameplayTagContainer* Container = UE::GameplayInteraction::GetSlotTags(SmartObjectSubsystem, InstanceData.Slot, Source);
if (Container == nullptr)
{
return false;
}
return TagQuery.Matches(*Container) ^ bInvert;
}
//----------------------------------------------------------------------//
// FGameplayInteractionIsSlotHandleValidCondition
//----------------------------------------------------------------------//
bool FGameplayInteractionIsSlotHandleValidCondition::Link(FStateTreeLinker& Linker)
{
Linker.LinkExternalData(SmartObjectSubsystemHandle);
return true;
}
bool FGameplayInteractionIsSlotHandleValidCondition::TestCondition(FStateTreeExecutionContext& Context) const
{
const USmartObjectSubsystem& SmartObjectSubsystem = Context.GetExternalData(SmartObjectSubsystemHandle);
const FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
return (InstanceData.Slot.IsValid() && SmartObjectSubsystem.IsSmartObjectSlotValid(InstanceData.Slot)) ^ bInvert;
}