Exemplo n.º 1
0
void SmartAI::UpdatePath(const uint32 diff)
{
    if (!HasEscortState(SMART_ESCORT_ESCORTING))
        return;

    if (mEscortInvokerCheckTimer < diff)
    {
        if (!IsEscortInvokerInRange())
        {
            StopPath(0, mEscortQuestID, true);

            // allow to properly hook out of range despawn action, which in most cases should perform the same operation as dying
            GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, me);
            me->DespawnOrUnsummon(1);
            return;
        }
        mEscortInvokerCheckTimer = 1000;
    }
    else
        mEscortInvokerCheckTimer -= diff;

    // handle pause
    if (HasEscortState(SMART_ESCORT_PAUSED))
    {
        if (mWPPauseTimer <= diff)
        {
            if (!me->IsInCombat() && !HasEscortState(SMART_ESCORT_RETURNING) && (mWPReached || mForcedPaused))
            {
                ResumePath();
            }
        }
        else
            mWPPauseTimer -= diff;
    }
    else if (m_Ended) // end path
    {
        m_Ended = false;
        StopPath();
        return;
    }

    if (HasEscortState(SMART_ESCORT_RETURNING))
    {
        if (mOOCReached)//reached OOC WP
        {
            mOOCReached = false;
            RemoveEscortState(SMART_ESCORT_RETURNING);
            if (!HasEscortState(SMART_ESCORT_PAUSED))
                ResumePath();
        }
    }
}
bool UNavigationComponent::FindSimplePathToActor(const AActor* NewGoalActor, float RepathDistance)
{
	bool bPathGenerationSucceeded = false;

	if (bIsPaused && NewGoalActor != NULL && GoalActor == NewGoalActor
		&& Path.IsValid() && Path->IsValid() && Path->GetOwner() == NULL)
	{
		RepathDistanceSq = FMath::Square(RepathDistance);
		OriginalGoalActorLocation = GetCurrentMoveGoal(NewGoalActor, GetOwner());

		bPathGenerationSucceeded = ResumePath();
	}
	else 
	{
		if (NewGoalActor != NULL)
		{
			const FVector NewGoalActorLocation = GetCurrentMoveGoal(NewGoalActor, GetOwner());
			bPathGenerationSucceeded = GenerateSimplePath(NewGoalActorLocation);

			if (bPathGenerationSucceeded)
			{
				GoalActor = NewGoalActor;
				RepathDistanceSq = FMath::Square(RepathDistance);
				OriginalGoalActorLocation = NewGoalActorLocation;
				bUseSimplePath = true;

				// if doing sync pathfinding enabling component's ticking needs to be done now
				SetComponentTickEnabledAsync(true);
			}
		}

		if (!bPathGenerationSucceeded)
		{
			UE_VLOG(GetOwner(), LogNavigation, Warning, TEXT("Failed to generate simple path to %s"), *GetNameSafe(NewGoalActor));
		}
	}

	if (bPathGenerationSucceeded == false)
	{
		ResetTransientData();
	}

	return bPathGenerationSucceeded;
}
Exemplo n.º 3
0
void SmartAI::MovepointReached(uint32 id)
{
    // override the id, path can be resumed any time and counter will reset
    // mCurrentWPID holds proper id

    // xinef: both point movement and escort generator can enter this function
    if (id == SMART_ESCORT_LAST_OOC_POINT)
    {
        mOOCReached = true;
        return;
    }

    mWPReached = true;
    GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_REACHED, NULL, mCurrentWPID);

    if (mLastWP)
    {
        me->SetPosition(mLastWP->x, mLastWP->y, mLastWP->z, me->GetOrientation());
        me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
    }

    if (HasEscortState(SMART_ESCORT_PAUSED))
    {
        if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_ACTIVE) == ESCORT_MOTION_TYPE)
            me->GetMotionMaster()->MovementExpired();

        me->StopMovingOnCurrentPos();
        me->GetMotionMaster()->MoveIdle();
    }
    // Xinef: Can be unset in ProcessEvents
    else if (HasEscortState(SMART_ESCORT_ESCORTING) && me->GetMotionMaster()->GetCurrentMovementGeneratorType() == ESCORT_MOTION_TYPE)
    {
        mWPReached = false;
        if (mCurrentWPID == GetWPCount())
            EndPath();
        else if (GetNextWayPoint())
        {
            SetRun(mRun);
            // xinef: if we have reached waypoint, and there is no working spline movement it means our splitted array has ended, make new one
            if (me->movespline->Finalized())
                ResumePath();
        }
    }
}
bool UNavigationComponent::FindSimplePathToLocation(const FVector& DestLocation)
{
	bool bPathGenerationSucceeded = false;

	if (bIsPaused && Path.IsValid() && Path->IsValid() && Path->GetOwner() == NULL
		&& FVector::DistSquared(CurrentGoal, DestLocation) < SMALL_NUMBER)
	{
		bPathGenerationSucceeded = ResumePath();
	}

	if (bPathGenerationSucceeded == false)
	{
		ResetTransientData();

		bPathGenerationSucceeded = GenerateSimplePath(DestLocation);
	}

	return bPathGenerationSucceeded;
}
bool UNavigationComponent::FindPathToLocation(const FVector& DestLocation, TSharedPtr<const FNavigationQueryFilter> QueryFilter)
{
	bool bPathGenerationSucceeded = false;

	if (bIsPaused == true && Path.IsValid() && Path->IsValid() 
		&& FVector::DistSquared(CurrentGoal, DestLocation) < SMALL_NUMBER)
	{
		// path to destination already generated. Use it.

		if (bDoAsyncPathfinding == true)
		{
			FSimpleDelegateGraphTask::CreateAndDispatchWhenReady(
				FSimpleDelegateGraphTask::FDelegate::CreateUObject(this, &UNavigationComponent::DeferredResumePath)
				, TEXT("Deferred resume path")
				, NULL
				, ENamedThreads::GameThread
				);
			bPathGenerationSucceeded = true;
		}
		else
		{
			bPathGenerationSucceeded = ResumePath();
		}
	}
	
	if (bPathGenerationSucceeded == false)
	{
		ResetTransientData();

		if (bDoAsyncPathfinding == true)
		{
			bPathGenerationSucceeded = AsyncGeneratePathTo(DestLocation, QueryFilter);
		}
		else
		{
			bPathGenerationSucceeded = GeneratePathTo(DestLocation, QueryFilter);
		}
	}

	return bPathGenerationSucceeded;
}
Exemplo n.º 6
0
void SmartAI::UpdatePath(const uint32 diff)
{
    if (!HasEscortState(SMART_ESCORT_ESCORTING))
        return;
    if (mEscortInvokerCheckTimer < diff)
    {
        if (!IsEscortInvokerInRange())
        {
            StopPath(mDespawnTime, mEscortQuestID, true);
        }
        mEscortInvokerCheckTimer = 1000;
    } else mEscortInvokerCheckTimer -= diff;
    // handle pause
    if (HasEscortState(SMART_ESCORT_PAUSED))
    {
        if (mWPPauseTimer < diff)
        {
            if (!me->isInCombat() && !HasEscortState(SMART_ESCORT_RETURNING) && (mWPReached || mLastWPIDReached == SMART_ESCORT_LAST_OOC_POINT || mForcedPaused))
            {
                GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_RESUMED, NULL, mLastWP->id, GetScript()->GetPathId());
                RemoveEscortState(SMART_ESCORT_PAUSED);
                if (mForcedPaused)// if paused between 2 wps resend movement
                {
                    ResumePath();
                    mWPReached = false;
                    mForcedPaused = false;
                }
                if (mLastWPIDReached == SMART_ESCORT_LAST_OOC_POINT)
                    mWPReached = true;
            }
            mWPPauseTimer = 0;
        } else {
            mWPPauseTimer -= diff;

        }
    }
    if (HasEscortState(SMART_ESCORT_RETURNING))
    {
        if (mWPReached)//reached OOC WP
        {
            RemoveEscortState(SMART_ESCORT_RETURNING);
            if (!HasEscortState(SMART_ESCORT_PAUSED))
                ResumePath();
            mWPReached = false;
        }
    }
    if (me->isInCombat() || HasEscortState(SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING))
        return;
    // handle next wp
    if (mWPReached)//reached WP
    {
        mWPReached = false;
        if (mCurrentWPID == GetWPCount())
        {
            EndPath();
        } else {
            WayPoint* wp = GetNextWayPoint();
            if (wp)
            {
                SetRun(mRun);
                me->GetMotionMaster()->MovePoint(wp->id, wp->x, wp->y, wp->z);
            }
        }

    }
}
Exemplo n.º 7
0
void SmartAI::UpdatePath(const uint32 diff)
{
    if (!HasEscortState(SMART_ESCORT_ESCORTING))
        return;

    if (mEscortInvokerCheckTimer < diff)
    {
        // Xinef: Escort failed - no players in range
        // Xinef: Despawn immediately
        if (!IsEscortInvokerInRange())
        {
            StopPath(0, mEscortQuestID, true);

            // Xinef: allow to properly hook out of range despawn action, which in most cases should perform the same operation as dying
            GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, me);
            me->DespawnOrUnsummon(1);
            return;
        }
        mEscortInvokerCheckTimer = 1000;
    }
    else
        mEscortInvokerCheckTimer -= diff;

    // handle pause
    if (HasEscortState(SMART_ESCORT_PAUSED))
    {
        if (mWPPauseTimer < diff)
        {
            if (!me->IsInCombat() && !HasEscortState(SMART_ESCORT_RETURNING) && (mWPReached || mForcedPaused))
            {
                GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_RESUMED, NULL, mCurrentWPID, GetScript()->GetPathId());
                RemoveEscortState(SMART_ESCORT_PAUSED);
                if (mForcedPaused)// if paused between 2 wps resend movement
                {
                    mWPReached = false;
                    mForcedPaused = false;
                    ResumePath();
                }

                mWPPauseTimer = 0;
            }
        }
        else
            mWPPauseTimer -= diff;
    }

    if (HasEscortState(SMART_ESCORT_RETURNING))
    {
        if (mOOCReached)//reached OOC WP
        {
            mOOCReached = false;
            RemoveEscortState(SMART_ESCORT_RETURNING);
            if (!HasEscortState(SMART_ESCORT_PAUSED))
                ResumePath();
        }
    }

    if ((me->GetVictim() && me->IsInCombat()) || HasEscortState(SMART_ESCORT_PAUSED | SMART_ESCORT_RETURNING))
        return;

    // handle next wp
    if (!me->HasUnitState(UNIT_STATE_NOT_MOVE) && me->movespline->Finalized())//reached WP
    {
        if (!mWPReached)
        {
            ResumePath();
            return;
        }

        mWPReached = false;
        if (mCurrentWPID == GetWPCount())
            EndPath();
        else if (GetNextWayPoint())
        {
            SetRun(mRun);
            // xinef: if we have reached waypoint, and there is no working spline movement it means our splitted array has ended, make new one
            if (me->movespline->Finalized())
                ResumePath();
        }
    }
}
bool UNavigationComponent::FindPathToActor(const AActor* NewGoalActor, TSharedPtr<const FNavigationQueryFilter> QueryFilter, float RepathDistance)
{
	bool bPathGenerationSucceeded = false;

	if (bIsPaused && NewGoalActor != NULL && GoalActor == NewGoalActor 
		&& Path.IsValid() && Path->IsValid())
	{
		RepathDistanceSq = FMath::Square(RepathDistance);
		OriginalGoalActorLocation = GetCurrentMoveGoal(NewGoalActor, GetOwner());

		if (bDoAsyncPathfinding == true)
		{
			FSimpleDelegateGraphTask::CreateAndDispatchWhenReady(
				FSimpleDelegateGraphTask::FDelegate::CreateUObject(this, &UNavigationComponent::DeferredResumePath)
				, TEXT("Deferred resume path")
				, NULL
				, ENamedThreads::GameThread
				);
			bPathGenerationSucceeded = true;
		}
		else
		{
			bPathGenerationSucceeded = ResumePath();
		}
	}
	else
	{
		if (NewGoalActor != NULL)
		{
			const FVector NewGoalActorLocation = GetCurrentMoveGoal(NewGoalActor, GetOwner());
			if (bDoAsyncPathfinding == true)
			{
				bPathGenerationSucceeded = AsyncGeneratePathTo(NewGoalActorLocation, QueryFilter);
			}
			else
			{
				bPathGenerationSucceeded = GeneratePathTo(NewGoalActorLocation, QueryFilter);
			}

			if (bPathGenerationSucceeded)
			{
				// if there's a specific query filter store it
				StoredQueryFilter = QueryFilter;

				GoalActor = NewGoalActor;
				RepathDistanceSq = FMath::Square(RepathDistance);
				OriginalGoalActorLocation = NewGoalActorLocation;
				bUseSimplePath = false;

				if (bDoAsyncPathfinding == false)
				{
					// if doing sync pathfinding enabling component's ticking needs to be done now
					SetComponentTickEnabledAsync(true);
				}
			}
		}

		if (!bPathGenerationSucceeded)
		{
			UE_VLOG(GetOwner(), LogNavigation, Log, TEXT("%s failed to generate path to %s"), *GetNameSafe(GetOwner()), *GetNameSafe(NewGoalActor));
		}
	}

	if (bPathGenerationSucceeded == false)
	{
		ResetTransientData();
	}

	return bPathGenerationSucceeded;
}
void UNavigationComponent::DeferredResumePath()
{
	ResumePath();
}