Beispiel #1
0
EBTNodeResult::Type UBoolChange::ExecuteTask(UBehaviorTreeComponent & OwnerComp, uint8 * NodeMemory)
{
	Super::ExecuteTask(OwnerComp, NodeMemory);

	if (!GetWorld())
	{
		return EBTNodeResult::Failed;
	}
	if (!CurrentBanditController)
	{
		Controller = OwnerComp.GetAIOwner();
		CurrentBanditController = Cast<ABanditController>(Controller);
	}
	if (CurrentBanditController)
	{
		OwnerComp.GetBlackboardComponent()->SetValueAsBool(TEXT("PlayerSpotted"), true);
		OwnerComp.GetBlackboardComponent()->SetValueAsBool(TEXT("PlayerNearby"), true);
		return EBTNodeResult::Succeeded;
	}
	return EBTNodeResult::Failed;
}
EBTNodeResult::Type UBTTask_PlayAbility::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	FBTPlayAbilityTaskMemory* TaskMemory = reinterpret_cast<FBTPlayAbilityTaskMemory*>(NodeMemory);
	AAIController* const OwnerController = OwnerComp.GetAIOwner();
	const UAblAbility* AbilityCDO = Cast<UAblAbility>(Ability.GetDefaultObject());
	if (AbilityCDO && OwnerController)
	{
		if (APawn* Owner = OwnerController->GetPawn())
		{
			if (UAblAbilityComponent* AbilityComponent = Owner->FindComponentByClass<UAblAbilityComponent>())
			{
				if (!TaskMemory->bAbilityPlayed)
				{
					UAblAbilityContext* Context = UAblAbilityContext::MakeContext(AbilityCDO, AbilityComponent, Owner, nullptr);
					EAblAbilityStartResult Result = AbilityComponent->ActivateAbility(Context);
					if (Result == EAblAbilityStartResult::Success || Result == EAblAbilityStartResult::AsyncProcessing)
					{
						TaskMemory->bAbilityPlayed = true;
						if (MarkAsInProgressDuringExecution)
						{
							TaskMemory->AbilityComponent = AbilityComponent;
							return EBTNodeResult::InProgress;
						}
						else
						{
							return EBTNodeResult::Succeeded;
						}
					}
					else
					{
						return EBTNodeResult::Failed;
					}
				}
			}
		}
	}

	return EBTNodeResult::Failed;
}
EBTNodeResult::Type UBTTask_FindPointNearWaypoint::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	AsbrAIController* aiController = Cast<AsbrAIController>(OwnerComp.GetAIOwner());
	if (aiController == NULL)
		return EBTNodeResult::Failed;

	ATargetPoint* waypoint = aiController->GetWaypoint();
	if (waypoint)
	{
		const float SearchRadius = 200.0f;
		const FVector SearchOrigin = waypoint->GetActorLocation();
		const FVector Loc = UNavigationSystem::GetRandomPointInNavigableRadius(aiController, SearchOrigin, SearchRadius);
		if (Loc != FVector::ZeroVector)
		{
			OwnerComp.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Vector>(BlackboardKey.GetSelectedKeyID(), Loc);
			aiController->SetWaypointVisited(waypoint);	// сообщаем что посетили waypoint (todo: надо учесть расстояние)
			return EBTNodeResult::Succeeded;
		}
	}

	return EBTNodeResult::Failed;
}
EBTNodeResult::Type UShootAtEnemyTask::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	AMinionAIController* MinionController = Cast<AMinionAIController>(OwnerComp.GetAIOwner());
	if (MinionController == NULL)
	{
		return EBTNodeResult::Failed;
	}

	AMinionCharacter* Minion = Cast<AMinionCharacter>(MinionController->GetPawn());
	ABorderItem* Enemy = MinionController->GetEnemy();
	if (CanAttack(Minion, Enemy))
	{
		AttackEnemy(Minion, Enemy);

		return EBTNodeResult::InProgress;
	}
	else if (!Enemy)
	{
		return EBTNodeResult::Succeeded;
	}

	return EBTNodeResult::Failed;
}
EBTNodeResult::Type UBTTask_MoveDirectlyToward::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	const UBlackboardComponent* MyBlackboard = OwnerComp.GetBlackboardComponent();
	FBTMoveDirectlyTowardMemory* MyMemory = reinterpret_cast<FBTMoveDirectlyTowardMemory*>(NodeMemory);
	AAIController* MyController = OwnerComp.GetAIOwner();
	EBTNodeResult::Type NodeResult = EBTNodeResult::Failed;

	if (MyController && MyBlackboard)
	{
		if (GET_AI_CONFIG_VAR(bEnableBTAITasks))
		{
			UAITask_MoveTo* AIMoveTask = NewBTAITask<UAITask_MoveTo>(OwnerComp);

			if (AIMoveTask != nullptr)
			{
				bool bSetUp = false;
				if (BlackboardKey.SelectedKeyType == UBlackboardKeyType_Object::StaticClass())
				{
					UObject* KeyValue = MyBlackboard->GetValue<UBlackboardKeyType_Object>(BlackboardKey.GetSelectedKeyID());
					AActor* TargetActor = Cast<AActor>(KeyValue);
					if (TargetActor)
					{
						AIMoveTask->SetUp(MyController, FVector::ZeroVector, TargetActor, AcceptableRadius, /*bUsePathfinding=*/false, FAISystem::BoolToAIOption(bStopOnOverlap));
						NodeResult = EBTNodeResult::InProgress;
					}
					else
					{
						UE_VLOG(MyController, LogBehaviorTree, Warning, TEXT("UBTTask_MoveDirectlyToward::ExecuteTask tried to go to actor while BB %s entry was empty"), *BlackboardKey.SelectedKeyName.ToString());
					}
				}
				else if (BlackboardKey.SelectedKeyType == UBlackboardKeyType_Vector::StaticClass())
				{
					const FVector TargetLocation = MyBlackboard->GetValue<UBlackboardKeyType_Vector>(BlackboardKey.GetSelectedKeyID());
					AIMoveTask->SetUp(MyController, TargetLocation, nullptr, AcceptableRadius, /*bUsePathfinding=*/false, FAISystem::BoolToAIOption(bStopOnOverlap));
					NodeResult = EBTNodeResult::InProgress;
				}

				if (NodeResult == EBTNodeResult::InProgress)
				{
					AIMoveTask->ReadyForActivation();
				}
			}
		}
		else
		{
			EPathFollowingRequestResult::Type RequestResult = EPathFollowingRequestResult::Failed;

			if (BlackboardKey.SelectedKeyType == UBlackboardKeyType_Object::StaticClass())
			{
				UObject* KeyValue = MyBlackboard->GetValue<UBlackboardKeyType_Object>(BlackboardKey.GetSelectedKeyID());
				AActor* TargetActor = Cast<AActor>(KeyValue);
				if (TargetActor)
				{
					RequestResult = bDisablePathUpdateOnGoalLocationChange ?
						MyController->MoveToLocation(TargetActor->GetActorLocation(), AcceptableRadius, bStopOnOverlap, /*bUsePathfinding=*/false, /*bProjectDestinationToNavigation=*/bProjectVectorGoalToNavigation, bAllowStrafe) :
						MyController->MoveToActor(TargetActor, AcceptableRadius, bStopOnOverlap, /*bUsePathfinding=*/false, bAllowStrafe);
				}
			}
			else if (BlackboardKey.SelectedKeyType == UBlackboardKeyType_Vector::StaticClass())
			{
				const FVector TargetLocation = MyBlackboard->GetValue<UBlackboardKeyType_Vector>(BlackboardKey.GetSelectedKeyID());
				RequestResult = MyController->MoveToLocation(TargetLocation, AcceptableRadius, bStopOnOverlap, /*bUsePathfinding=*/false, /*bProjectDestinationToNavigation=*/bProjectVectorGoalToNavigation, bAllowStrafe);
			}

			if (RequestResult == EPathFollowingRequestResult::RequestSuccessful)
			{
				const FAIRequestID RequestID = MyController->GetCurrentMoveRequestID();

				MyMemory->MoveRequestID = RequestID;
				WaitForMessage(OwnerComp, UBrainComponent::AIMessage_MoveFinished, RequestID);

				NodeResult = EBTNodeResult::InProgress;
			}
			else if (RequestResult == EPathFollowingRequestResult::AlreadyAtGoal)
			{
				NodeResult = EBTNodeResult::Succeeded;
			}
		}
	}

	return NodeResult;
}
EBTNodeResult::Type UBTTask_Escape::ExecuteTask(UBehaviorTreeComponent& OwnedTree, uint8* Node)
{
	AWolfAIController* Controller = Cast<AWolfAIController>(OwnedTree.GetAIOwner());
	if (!Controller)
	{
		GLog->Log("Controller fail");
		return EBTNodeResult::Failed;
	}


	FName SensedTargetKey = "SensedTarget";
	AMyCharacter_FirstTry* Caveman = Cast<AMyCharacter_FirstTry>(OwnedTree.GetBlackboardComponent()->GetValueAsObject(SensedTargetKey));
	if (Caveman)
	{
		TArray<FHitResult> HitResults;
		//Start and End Location of the capsule
		FVector StartLocation = Caveman->GetActorLocation();
		FVector EndLocation = StartLocation;
		EndLocation.Z += Caveman->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() / 2;

		//Collision Channel
		ECollisionChannel ECC = ECollisionChannel::ECC_WorldDynamic;

		//Collision Shape
		FCollisionShape CollisionShape;

		//Making Collision in sphere
		CollisionShape.ShapeType = ECollisionShape::Sphere;
		CollisionShape.SetSphere(350);

		//Sweeping for possible escape nodes
		if (Caveman->GetWorld()->SweepMultiByChannel(HitResults, StartLocation, EndLocation, FQuat::FQuat(), ECC, CollisionShape))
		{
			//DrawDebugSphere(Caveman->GetWorld(), ((EndLocation - StartLocation) / 2) + StartLocation, CollisionShape.GetSphereRadius(), 100, FColor::Green, true);
			TArray<AActor*> AllPathNodes;
			UGameplayStatics::GetAllActorsOfClass(Caveman->GetWorld(), APathNode::StaticClass(), AllPathNodes);

			APathNode* NextNode;
			NextNode = Cast<APathNode>(AllPathNodes[FMath::RandRange(0, AllPathNodes.Num() - 1)]);
			//Finding next possible node
			while (NextNode->bIsCurrentlyOccupied && AllPathNodes.Contains(NextNode))
			{
				NextNode = Cast<APathNode>(AllPathNodes[FMath::RandRange(0, AllPathNodes.Num() - 1)]);
				GLog->Log("Fear success");
			}

			//Occupy the node
			NextNode->bIsCurrentlyOccupied = true;
			
			//Set the new node in the blackboard
			OwnedTree.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Object>(BlackboardKey.GetSelectedKeyID(), NextNode);
			//OwnedTree.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Object>(Bl)
			
			GLog->Log("Success after while");
			return EBTNodeResult::Succeeded;

		}

	}

	GLog->Log("General Fail");
	return EBTNodeResult::Failed;
}
EBTNodeResult::Type UBTTask_FlyTo::SchedulePathfindingRequest(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	if(!NavigationManager)
		NavigationManager =  UDonNavigationHelper::DonNavigationManager(this);

	auto pawn        =  OwnerComp.GetAIOwner()->GetPawn();
	auto myMemory    =  (FBT_FlyToTarget*)NodeMemory;
	auto blackboard  =  pawn ? pawn->GetController()->FindComponentByClass<UBlackboardComponent>() : NULL;
	
	// Validate internal state:
	if (!pawn || !myMemory || !blackboard || !NavigationManager)
	{
		UE_LOG(LogTemp, Log, TEXT("[DoN Navigation] BTTask_FlyTo has invalid data for AI Pawn or NodeMemory or NavigationManager. Unable to proceed."));

		if(blackboard)
			HandleTaskFailure(blackboard);

		return EBTNodeResult::Failed;
	}
	
	// Validate blackboard key data:
	if(FlightLocationKey.SelectedKeyType != UBlackboardKeyType_Vector::StaticClass())
	{
		UE_LOG(LogTemp, Log, TEXT("[DoN Navigation] Invalid FlightLocationKey. Expected Vector type, found %s"), *(FlightLocationKey.SelectedKeyType ? FlightLocationKey.SelectedKeyType->GetName() : FString("?")));
		HandleTaskFailure(blackboard);

		return EBTNodeResult::Failed;
	}	

	// Prepare input:
	myMemory->Reset();	
	myMemory->Metadata.ActiveInstanceIdx = OwnerComp.GetActiveInstanceIdx();
	myMemory->Metadata.OwnerComp = &OwnerComp;
	myMemory->QueryParams = QueryParams;
	myMemory->QueryParams.CustomDelegatePayload = &myMemory->Metadata;
	myMemory->bIsANavigator = pawn->GetClass()->ImplementsInterface(UDonNavigator::StaticClass());

	FVector flightDestination = blackboard->GetValueAsVector(FlightLocationKey.SelectedKeyName);

	// Bind result notification delegate:
	FDoNNavigationResultHandler resultHandler;
	resultHandler.BindDynamic(this, &UBTTask_FlyTo::Pathfinding_OnFinish);

	// Bind dynamic collision updates delegate:		
	myMemory->DynamicCollisionListener.BindDynamic(this, &UBTTask_FlyTo::Pathfinding_OnDynamicCollisionAlert);

	// Schedule task:	
	bool bTaskScheduled = NavigationManager->SchedulePathfindingTask(pawn, flightDestination, myMemory->QueryParams, DebugParams, resultHandler, myMemory->DynamicCollisionListener);

	if (bTaskScheduled)
	{
		if(myMemory->QueryResults.QueryStatus != EDonNavigationQueryStatus::Success) // for simple paths the scheduler may have already solved the path synchronously
			myMemory->QueryResults.QueryStatus = EDonNavigationQueryStatus::InProgress;

		return EBTNodeResult::InProgress;
	}
	else
	{
		HandleTaskFailure(blackboard);

		return EBTNodeResult::Failed;
	}	
}