Files
UnrealEngineUWP/Engine/Plugins/Runtime/SmartObjects/Source/SmartObjectsModule/Private/SmartObjectBlueprintFunctionLibrary.cpp
ben hoffman 8c35dff059 Add Find Smart Object functions that take in AActor's and avoid using the normal QueryBox.
This is more friendly to the UE Gameplay Framework and lets you pass in specific actor's that you case about. If you had to use a spatial query, then you may get results from objects that you don't explictly want if they are overlapping objects.

Add a function to check if the subsystem is running on the server or not to make doing some future replication checks easier

#jira UE-180500
#rb mikko.mononen

[CL 27597760 by ben hoffman in ue5-main branch]
2023-09-05 11:29:58 -04:00

290 lines
10 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SmartObjectBlueprintFunctionLibrary.h"
#include "Engine/Engine.h"
#include "SmartObjectSubsystem.h"
#include "BlackboardKeyType_SOClaimHandle.h"
#include "SmartObjectComponent.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "BehaviorTree/BTFunctionLibrary.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(SmartObjectBlueprintFunctionLibrary)
//----------------------------------------------------------------------//
// USmartObjectBlueprintFunctionLibrary
//----------------------------------------------------------------------//
FSmartObjectClaimHandle USmartObjectBlueprintFunctionLibrary::GetValueAsSOClaimHandle(UBlackboardComponent* BlackboardComponent, const FName& KeyName)
{
if (BlackboardComponent == nullptr)
{
return {};
}
return BlackboardComponent->GetValue<UBlackboardKeyType_SOClaimHandle>(KeyName);
}
void USmartObjectBlueprintFunctionLibrary::SetValueAsSOClaimHandle(UBlackboardComponent* BlackboardComponent, const FName& KeyName, const FSmartObjectClaimHandle Value)
{
if (BlackboardComponent == nullptr)
{
return;
}
const FBlackboard::FKey KeyID = BlackboardComponent->GetKeyID(KeyName);
BlackboardComponent->SetValue<UBlackboardKeyType_SOClaimHandle>(KeyID, Value);
}
FSmartObjectClaimHandle USmartObjectBlueprintFunctionLibrary::SmartObjectClaimHandle_Invalid()
{
return FSmartObjectClaimHandle::InvalidHandle;
}
bool USmartObjectBlueprintFunctionLibrary::AddOrRemoveSmartObject(AActor* SmartObjectActor, const bool bAdd)
{
return AddOrRemoveMultipleSmartObjects({SmartObjectActor}, bAdd);
}
bool USmartObjectBlueprintFunctionLibrary::AddSmartObject(AActor* SmartObjectActor)
{
return AddOrRemoveMultipleSmartObjects({SmartObjectActor}, /*bAdd*/true);
}
bool USmartObjectBlueprintFunctionLibrary::AddMultipleSmartObjects(const TArray<AActor*>& SmartObjectActors)
{
return AddOrRemoveMultipleSmartObjects(SmartObjectActors, /*bAdd*/true);
}
bool USmartObjectBlueprintFunctionLibrary::RemoveSmartObject(AActor* SmartObjectActor)
{
return AddOrRemoveMultipleSmartObjects({SmartObjectActor}, /*bAdd*/false);
}
bool USmartObjectBlueprintFunctionLibrary::RemoveMultipleSmartObjects(const TArray<AActor*>& SmartObjectActors)
{
return AddOrRemoveMultipleSmartObjects(SmartObjectActors, /*bAdd*/false);
}
bool USmartObjectBlueprintFunctionLibrary::AddOrRemoveMultipleSmartObjects(const TArray<AActor*>& SmartObjectActors, const bool bAdd)
{
bool bSuccess = true;
if (SmartObjectActors.IsEmpty())
{
return bSuccess;
}
USmartObjectSubsystem* Subsystem = nullptr;
for (const AActor* SmartObjectActor : SmartObjectActors)
{
if (SmartObjectActor == nullptr)
{
UE_LOG(LogSmartObject, Warning, TEXT("Null actor found and skipped"))
bSuccess = false;
continue;
}
if (Subsystem == nullptr)
{
Subsystem = USmartObjectSubsystem::GetCurrent(SmartObjectActor->GetWorld());
if (Subsystem == nullptr)
{
UE_LOG(LogSmartObject, Warning, TEXT("Unable to find SmartObjectSubsystem for the provided actors."))
return false;
}
}
bSuccess = bAdd ? Subsystem->RegisterSmartObjectActor(*SmartObjectActor) : Subsystem->RemoveSmartObjectActor(*SmartObjectActor) && bSuccess;
}
return bSuccess;
}
bool USmartObjectBlueprintFunctionLibrary::SetSmartObjectEnabled(AActor* SmartObjectActor, const bool bEnabled)
{
return SetMultipleSmartObjectsEnabled({SmartObjectActor}, bEnabled);
}
FSmartObjectClaimHandle USmartObjectBlueprintFunctionLibrary::MarkSmartObjectSlotAsClaimed(
UObject* WorldContextObject,
const FSmartObjectSlotHandle SlotHandle,
const AActor* UserActor)
{
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (USmartObjectSubsystem* Subsystem = USmartObjectSubsystem::GetCurrent(World))
{
return Subsystem->MarkSlotAsClaimed(SlotHandle, FConstStructView::Make(FSmartObjectActorUserData(UserActor)));
}
return FSmartObjectClaimHandle::InvalidHandle;
}
const USmartObjectBehaviorDefinition* USmartObjectBlueprintFunctionLibrary::MarkSmartObjectSlotAsOccupied(
UObject* WorldContextObject,
const FSmartObjectClaimHandle ClaimHandle,
const TSubclassOf<USmartObjectBehaviorDefinition> DefinitionClass)
{
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (USmartObjectSubsystem* Subsystem = USmartObjectSubsystem::GetCurrent(World))
{
Subsystem->MarkSlotAsOccupied(ClaimHandle, DefinitionClass);
}
return nullptr;
}
bool USmartObjectBlueprintFunctionLibrary::MarkSmartObjectSlotAsFree(
UObject* WorldContextObject,
const FSmartObjectClaimHandle ClaimHandle)
{
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (USmartObjectSubsystem* Subsystem = USmartObjectSubsystem::GetCurrent(World))
{
return Subsystem->MarkSlotAsFree(ClaimHandle);
}
return false;
}
bool USmartObjectBlueprintFunctionLibrary::FindSmartObjectsInComponent(const FSmartObjectRequestFilter& Filter, USmartObjectComponent* SmartObjectComponent, TArray<FSmartObjectRequestResult>& OutResults, const AActor* UserActor)
{
if (SmartObjectComponent)
{
if (const USmartObjectSubsystem* Subsystem = USmartObjectSubsystem::GetCurrent(SmartObjectComponent->GetWorld()))
{
return Subsystem->FindSmartObjectsInList(Filter, { SmartObjectComponent->GetOwner() }, OutResults, FConstStructView::Make(FSmartObjectActorUserData(UserActor)));
}
}
return false;
}
bool USmartObjectBlueprintFunctionLibrary::FindSmartObjectsInActor(const FSmartObjectRequestFilter& Filter, AActor* SearchActor, TArray<FSmartObjectRequestResult>& OutResults, const AActor* UserActor)
{
if (SearchActor)
{
if (const USmartObjectSubsystem* Subsystem = USmartObjectSubsystem::GetCurrent(SearchActor->GetWorld()))
{
return Subsystem->FindSmartObjectsInList(Filter, { SearchActor }, OutResults, FConstStructView::Make(FSmartObjectActorUserData(UserActor)));
}
}
return false;
}
bool USmartObjectBlueprintFunctionLibrary::FindSmartObjectsInList(UObject* WorldContextObject, const FSmartObjectRequestFilter& Filter, const TArray<AActor*>& ActorList, TArray<FSmartObjectRequestResult>& OutResults, const AActor* UserActor /*= nullptr*/)
{
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (const USmartObjectSubsystem* Subsystem = USmartObjectSubsystem::GetCurrent(World))
{
return Subsystem->FindSmartObjectsInList(Filter, ActorList, OutResults, FConstStructView::Make(FSmartObjectActorUserData(UserActor)));
}
return false;
}
FString USmartObjectBlueprintFunctionLibrary::Conv_SmartObjectClaimHandleToString(const FSmartObjectClaimHandle& Result)
{
return LexToString(Result);
}
FString USmartObjectBlueprintFunctionLibrary::Conv_SmartObjectRequestResultToString(const FSmartObjectRequestResult& Result)
{
return LexToString(Result);
}
FString USmartObjectBlueprintFunctionLibrary::Conv_SmartObjectDefinitionToString(const USmartObjectDefinition* Definition)
{
if (Definition)
{
return LexToString(*Definition);
}
UE_LOG(LogSmartObject, Error, TEXT("Attempted to convert null SmartObjectDefinition to string!"));
static const FString InvalidDefinitionString = TEXT("INVALID");
return InvalidDefinitionString;
}
FString USmartObjectBlueprintFunctionLibrary::Conv_SmartObjectHandleToString(const FSmartObjectHandle& Handle)
{
return LexToString(Handle);
}
bool USmartObjectBlueprintFunctionLibrary::NotEqual_SmartObjectHandleSmartObjectHandle(const FSmartObjectHandle& A, const FSmartObjectHandle& B)
{
return A != B;
}
bool USmartObjectBlueprintFunctionLibrary::Equal_SmartObjectHandleSmartObjectHandle(const FSmartObjectHandle& A, const FSmartObjectHandle& B)
{
return A == B;
}
bool USmartObjectBlueprintFunctionLibrary::IsValidSmartObjectHandle(const FSmartObjectHandle& Handle)
{
return Handle.IsValid();
}
FString USmartObjectBlueprintFunctionLibrary::Conv_SmartObjectSlotHandleToString(const FSmartObjectSlotHandle& Handle)
{
return LexToString(Handle);
}
bool USmartObjectBlueprintFunctionLibrary::Equal_SmartObjectSlotHandleSmartObjectSlotHandle(const FSmartObjectSlotHandle& A, const FSmartObjectSlotHandle& B)
{
return A == B;
}
bool USmartObjectBlueprintFunctionLibrary::NotEqual_SmartObjectSlotHandleSmartObjectSlotHandle(const FSmartObjectSlotHandle& A, const FSmartObjectSlotHandle& B)
{
return A != B;
}
bool USmartObjectBlueprintFunctionLibrary::IsValidSmartObjectSlotHandle(const FSmartObjectSlotHandle& Handle)
{
return Handle.IsValid();
}
bool USmartObjectBlueprintFunctionLibrary::SetMultipleSmartObjectsEnabled(const TArray<AActor*>& SmartObjectActors, const bool bEnabled)
{
bool bSuccess = true;
if (SmartObjectActors.IsEmpty())
{
return bSuccess;
}
USmartObjectSubsystem* Subsystem = nullptr;
for (const AActor* SmartObjectActor : SmartObjectActors)
{
if (SmartObjectActor == nullptr)
{
UE_LOG(LogSmartObject, Warning, TEXT("Null actor found and skipped"))
bSuccess = false;
continue;
}
if (Subsystem == nullptr)
{
Subsystem = USmartObjectSubsystem::GetCurrent(SmartObjectActor->GetWorld());
if (Subsystem == nullptr)
{
UE_LOG(LogSmartObject, Warning, TEXT("Unable to find SmartObjectSubsystem for the provided actors."))
return false;
}
}
bSuccess = Subsystem->SetSmartObjectActorEnabled(*SmartObjectActor, bEnabled) && bSuccess;
}
return bSuccess;
}
void USmartObjectBlueprintFunctionLibrary::SetBlackboardValueAsSOClaimHandle(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, const FSmartObjectClaimHandle& Value)
{
if (UBlackboardComponent* BlackboardComp = UBTFunctionLibrary::GetOwnersBlackboard(NodeOwner))
{
BlackboardComp->SetValue<UBlackboardKeyType_SOClaimHandle>(Key.SelectedKeyName, Value);
}
}
FSmartObjectClaimHandle USmartObjectBlueprintFunctionLibrary::GetBlackboardValueAsSOClaimHandle(UBTNode* NodeOwner, const FBlackboardKeySelector& Key)
{
UBlackboardComponent* BlackboardComp = UBTFunctionLibrary::GetOwnersBlackboard(NodeOwner);
return BlackboardComp ? BlackboardComp->GetValue<UBlackboardKeyType_SOClaimHandle>(Key.SelectedKeyName) : FSmartObjectClaimHandle::InvalidHandle;
}