AMWWaypoint* AMWPatController::FindNearestWaypoint(bool bSetAsNext)
{
	const AMWPat* pat = Cast<AMWPat>(GetPawn());
	if (!pat)
	{
		return nullptr;
	}

	float minDist = MAX_FLT;
	AMWWaypoint* nearestWp = nullptr;

	// get all the waypoints in the level
	TArray<AActor*> foundActors;
	UGameplayStatics::GetAllActorsOfClass(this, AMWWaypoint::StaticClass(), foundActors);
	
	if (!foundActors.Num())
	{
		UE_LOG(LogTemp, Error, TEXT("No waypoints in the level"));
		return nullptr;
	}

	for (AActor* actor : foundActors)
	{
		const float dist = (pat->GetActorLocation() - actor->GetActorLocation()).SizeSquared();

		AMWWaypoint* waypoint = Cast<AMWWaypoint>(actor);
		const FString patTag = pat->WaypointTag;
		const FString wpTag = waypoint->Tag;
		
		// tags must match
		if (dist < minDist && patTag == wpTag)
		{
			minDist = dist;
			nearestWp = waypoint;
		}
	}

	if (!nearestWp)
	{
		UE_LOG(LogTemp, Error, TEXT("Pat %s couldn't find a waypoint with matching tag %s"), *pat->GetName(), *pat->WaypointTag);
		return nullptr;
	}

	// check whether we are already stand on that waypoint
	// normally waypoints stay far away from each other, so there is only one possible overlapping at a given time
	TArray<AActor*> overlaps;
	pat->GetOverlappingActors(overlaps, AMWWaypoint::StaticClass());
	if (overlaps.Num() && overlaps[0] == nearestWp)
	{
		check(nearestWp->Next)
		nearestWp = nearestWp->Next;
	}

	if (nearestWp && bSetAsNext)
	{
		SetNextWaypoint(nearestWp);
	}

	return nearestWp;
}
bool npc_escortAI::SetNextWaypoint(uint32 pointId, float x, float y, float z, float orientation)
{
    me->UpdatePosition(x, y, z, orientation);
    return SetNextWaypoint(pointId, false, true);
}