void AEQSTestingPawn::MakeOneStep()
{
	UEnvQueryManager* EQS = UEnvQueryManager::GetCurrent(GetWorld());
	if (EQS == NULL)
	{
		return;
	}

	if (QueryInstance.IsValid() == false && QueryTemplate != NULL)
	{
		FEnvQueryRequest QueryRequest(QueryTemplate, this);
		QueryRequest.SetNamedParams(QueryParams);
		QueryInstance = EQS->PrepareQueryInstance(QueryRequest, QueryingMode);
		if (QueryInstance.IsValid())
		{
			EQS->RegisterExternalQuery(QueryInstance);
		}
	}

	// possible still not valid 
	if (QueryInstance.IsValid() == true && QueryInstance->IsFinished() == false)
	{
		QueryInstance->ExecuteOneStep(double(TimeLimitPerStep));
		StepResults.Add(*(QueryInstance.Get()));

		if (QueryInstance->IsFinished())
		{
			StepToDebugDraw = StepResults.Num() - 1;
			UpdateDrawing();
		}
	}
}
EBTNodeResult::Type UBTTask_RunEQSQuery::ExecuteTask(class UBehaviorTreeComponent* OwnerComp, uint8* NodeMemory) const
{
	AActor* QueryOwner = OwnerComp->GetOwner();
	if (AController* ControllerOwner = Cast<AController>(QueryOwner))
	{
		QueryOwner = ControllerOwner->GetPawn();
	}

	FEnvQueryRequest QueryRequest(QueryTemplate, QueryOwner);
	QueryRequest.SetNamedParams(QueryParams);

	FBTEnvQueryTaskMemory* MyMemory = (FBTEnvQueryTaskMemory*)NodeMemory;
	MyMemory->RequestID = QueryRequest.Execute(EEnvQueryRunMode::SingleResult, this, &UBTTask_RunEQSQuery::OnQueryFinished);

	const bool bValid = (MyMemory->RequestID >= 0);
	if (bValid)
	{
		WaitForMessage(OwnerComp, UBrainComponent::AIMessage_QueryFinished, MyMemory->RequestID);
		return EBTNodeResult::InProgress;
	}

	return EBTNodeResult::Failed;
}
//----------------------------------------------------------------------//
// BP functions
//----------------------------------------------------------------------//
UEnvQueryInstanceBlueprintWrapper* UEnvQueryManager::RunEQSQuery(UObject* WorldContext, UEnvQuery* QueryTemplate, UObject* Querier, TEnumAsByte<EEnvQueryRunMode::Type> RunMode, TSubclassOf<UEnvQueryInstanceBlueprintWrapper> WrapperClass)
{ 
	if (QueryTemplate == nullptr)
	{
		return nullptr;
	}

	UEnvQueryManager* EQSManager = GetCurrent(WorldContext);
	UEnvQueryInstanceBlueprintWrapper* QueryInstanceWrapper = nullptr;

	if (EQSManager)
	{
		QueryInstanceWrapper = NewObject<UEnvQueryInstanceBlueprintWrapper>((UClass*)(WrapperClass)  ? (UClass*)WrapperClass : UEnvQueryInstanceBlueprintWrapper::StaticClass());
		check(QueryInstanceWrapper);
		FEnvQueryRequest QueryRequest(QueryTemplate, Querier);
		// @todo named params still missing support
		//QueryRequest.SetNamedParams(QueryParams);

		QueryInstanceWrapper->SetRunMode(RunMode);
		QueryInstanceWrapper->SetQueryID(QueryRequest.Execute(RunMode, QueryInstanceWrapper, &UEnvQueryInstanceBlueprintWrapper::OnQueryFinished));
	}
	
	return QueryInstanceWrapper;
}
int32 FEQSParametrizedQueryExecutionRequest::Execute(AActor& QueryOwner, const UBlackboardComponent* BlackboardComponent, FQueryFinishedSignature& QueryFinishedDelegate)
{
	if (bUseBBKeyForQueryTemplate)
	{
		check(BlackboardComponent);

		// set QueryTemplate to contents of BB key
		UObject* QueryTemplateObject = BlackboardComponent->GetValue<UBlackboardKeyType_Object>(EQSQueryBlackboardKey.GetSelectedKeyID());
		QueryTemplate = Cast<UEnvQuery>(QueryTemplateObject);

		UE_CVLOG(QueryTemplate == nullptr, &QueryOwner, LogBehaviorTree, Warning, TEXT("Trying to run EQS query configured to use BB key, but indicated key (%s) doesn't contain EQS template pointer")
			, *EQSQueryBlackboardKey.SelectedKeyName.ToString());
	}

	if (QueryTemplate != nullptr)
	{
		FEnvQueryRequest QueryRequest(QueryTemplate, &QueryOwner);
		if (QueryConfig.Num() > 0)
		{
			// resolve 
			for (FAIDynamicParam& RuntimeParam : QueryConfig)
			{
				// check if given param requires runtime resolve, like reading from BB
				if (RuntimeParam.BBKey.IsSet())
				{
					check(BlackboardComponent && "If BBKey.IsSet and there's no BB component then we\'re in the error land!");

					// grab info from BB
					switch (RuntimeParam.ParamType)
					{
					case EAIParamType::Float:
					{
						const float Value = BlackboardComponent->GetValue<UBlackboardKeyType_Float>(RuntimeParam.BBKey.GetSelectedKeyID());
						QueryRequest.SetFloatParam(RuntimeParam.ParamName, Value);
					}
					break;
					case EAIParamType::Int:
					{
						const int32 Value = BlackboardComponent->GetValue<UBlackboardKeyType_Int>(RuntimeParam.BBKey.GetSelectedKeyID());
						QueryRequest.SetIntParam(RuntimeParam.ParamName, Value);
					}
					break;
					case EAIParamType::Bool:
					{
						const bool Value = BlackboardComponent->GetValue<UBlackboardKeyType_Bool>(RuntimeParam.BBKey.GetSelectedKeyID());
						QueryRequest.SetBoolParam(RuntimeParam.ParamName, Value);
					}
					break;
					default:
						checkNoEntry();
						break;
					}
				}
				else
				{
					switch (RuntimeParam.ParamType)
					{
					case EAIParamType::Float:
					{
						QueryRequest.SetFloatParam(RuntimeParam.ParamName, RuntimeParam.Value);
					}
					break;
					case EAIParamType::Int:
					{
						QueryRequest.SetIntParam(RuntimeParam.ParamName, RuntimeParam.Value);
					}
					break;
					case EAIParamType::Bool:
					{
						bool Result = RuntimeParam.Value > 0;
						QueryRequest.SetBoolParam(RuntimeParam.ParamName, Result);
					}
					break;
					default:
						checkNoEntry();
						break;
					}
				}
			}
		}

		return QueryRequest.Execute(RunMode, QueryFinishedDelegate);
	}

	return INDEX_NONE;
}