void FPawnActionStack::PopAction(UPawnAction& ActionToPop)
{
    // first check if it's there
    UPawnAction* CutPoint = TopAction;
    while (CutPoint != NULL && CutPoint != &ActionToPop)
    {
        CutPoint = CutPoint->ParentAction;
    }

    if (CutPoint == &ActionToPop)
    {
        UPawnAction* ActionBeingRemoved = TopAction;
        // note StopAction can be null
        UPawnAction* StopAction = ActionToPop.ParentAction;

        while (ActionBeingRemoved != StopAction)
        {
            UPawnAction* NextAction = ActionBeingRemoved->ParentAction;

            if (ActionBeingRemoved->IsBeingAborted() == false && ActionBeingRemoved->IsFinished() == false)
            {
                // forcing abort to make sure it happens instantly. We don't have time for delayed finish here.
                ActionBeingRemoved->Abort(EAIForceParam::Force);
            }
            ActionBeingRemoved->OnPopped();
            if (ActionBeingRemoved->ParentAction)
            {
                ActionBeingRemoved->ParentAction->OnChildFinished(*ActionBeingRemoved, ActionBeingRemoved->FinishResult);
            }
            ActionBeingRemoved = NextAction;
        }

        TopAction = StopAction;
    }
}
bool UPawnActionsComponent::HasActiveActionOfType(EAIRequestPriority::Type Priority, TSubclassOf<UPawnAction> PawnActionClass) const
{
    TArray<UPawnAction*> ActionsToTest;
    ActionsToTest.Add(GetActiveAction(Priority));

    while (ActionsToTest.Num() > 0)
    {
        UPawnAction* ActiveActionIter = ActionsToTest[0];

        if (ActiveActionIter)
        {
            if (ActiveActionIter->GetClass()->IsChildOf(*PawnActionClass))
            {
                return true;
            }
            else
            {
                UPawnAction_Sequence* PawnActionSequence = Cast<UPawnAction_Sequence>(ActiveActionIter);

                if (PawnActionSequence)
                {
                    for (int32 PawnActionSequenceCount = 0; PawnActionSequenceCount < PawnActionSequence->ActionSequence.Num(); ++PawnActionSequenceCount)
                    {
                        ActionsToTest.Add(PawnActionSequence->ActionSequence[PawnActionSequenceCount]);
                    }
                }
            }
        }

        ActionsToTest.RemoveAt(0);
    }

    // Didn't find one.
    return false;
}
bool UPawnActionsComponent::OnEvent(UPawnAction& Action, EPawnActionEventType::Type Event)
{
    bool bResult = false;
    const FPawnActionEvent ActionEvent(Action, Event, ActionEventIndex++);

    if (Event != EPawnActionEventType::Invalid && ActionEvents.Find(ActionEvent) == INDEX_NONE)
    {
        ActionEvents.Add(ActionEvent);

        // if it's a first even enable tick
        if (ActionEvents.Num() == 1)
        {
            SetComponentTickEnabled(true);
        }

        bResult = true;
    }
    else if (Event == EPawnActionEventType::Invalid)
    {
        // ignore
        UE_VLOG(ControlledPawn, LogPawnAction, Warning, TEXT("Ignoring Action Event: Action %s Event %s")
                , *Action.GetName(), *GetEventName(Event));
    }
    else
    {
        UE_VLOG(ControlledPawn, LogPawnAction, Warning, TEXT("Ignoring duplicate Action Event: Action %s Event %s")
                , *Action.GetName(), *GetEventName(Event));
    }

    return bResult;
}
uint32 UPawnActionsComponent::AbortActionsInstigatedBy(UObject* const Instigator, EAIRequestPriority::Type Priority)
{
    uint32 AbortedActionsCount = 0;

    if (Priority == EAIRequestPriority::MAX)
    {
        // call for every regular priority
        for (int32 PriorityIndex = 0; PriorityIndex < EAIRequestPriority::MAX; ++PriorityIndex)
        {
            AbortedActionsCount += AbortActionsInstigatedBy(Instigator, EAIRequestPriority::Type(PriorityIndex));
        }
    }
    else
    {
        UPawnAction* Action = ActionStacks[Priority].GetTop();
        while (Action)
        {
            if (Action->GetInstigator() == Instigator)
            {
                OnEvent(*Action, EPawnActionEventType::InstantAbort);
                ++AbortedActionsCount;
            }
            Action = Action->ParentAction;
        }
    }

    return AbortedActionsCount;
}
bool UPawnActionsComponent::PushAction(UPawnAction& NewAction, EAIRequestPriority::Type Priority, UObject* Instigator)
{
    if (NewAction.HasBeenStarted() == false || NewAction.IsFinished() == true)
    {
        NewAction.ExecutionPriority = Priority;
        NewAction.SetOwnerComponent(this);
        NewAction.SetInstigator(Instigator);
        return OnEvent(NewAction, EPawnActionEventType::Push);
    }

    return false;
}
void UPawnActionsComponent::OnUnregister()
{
    if ((ControlledPawn != nullptr) && !ControlledPawn->IsPendingKillPending())
    {
        // call for every regular priority
        for (int32 PriorityIndex = 0; PriorityIndex < EAIRequestPriority::MAX; ++PriorityIndex)
        {
            UPawnAction* Action = ActionStacks[PriorityIndex].GetTop();
            while (Action)
            {
                Action->Abort(EAIForceParam::Force);
                Action = Action->ParentAction;
            }
        }
    }

    Super::OnUnregister();
}
Esempio n. 7
0
void UPawnAction::OnChildFinished(UPawnAction& Action, EPawnActionResult::Type WithResult)
{
	UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Child \'%s\' finished with result %s")
		, *GetName(), *Action.GetName(), *GetActionResultName(WithResult));

	ensure(Action.ParentAction == this);
	ensure(ChildAction == &Action);
	Action.ParentAction = NULL;
	ChildAction = NULL;
}
Esempio n. 8
0
bool UPawnAction::PushChildAction(UPawnAction& Action)
{
	bool bResult = false;
	
	if (OwnerComponent != NULL)
	{
		UE_CVLOG( ChildAction != NULL
			, GetPawn(), LogPawnAction, Log, TEXT("%s> Pushing child action %s while already having ChildAction set to %s")
			, *GetName(), *Action.GetName(), *ChildAction->GetName());
		
		// copy runtime data
		// note that priority and instigator will get assigned as part of PushAction.

		bResult = OwnerComponent->PushAction(Action, GetPriority(), Instigator);

		// adding a check to make sure important data has been set 
		ensure(Action.GetPriority() == GetPriority() && Action.GetInstigator() == GetInstigator());
	}

	return bResult;
}
EPawnActionAbortState::Type UPawnActionsComponent::AbortAction(UPawnAction& ActionToAbort)
{
    const EPawnActionAbortState::Type AbortState = ActionToAbort.Abort(EAIForceParam::DoNotForce);
    if (AbortState == EPawnActionAbortState::NeverStarted)
    {
        // this is a special case. It's possible someone tried to abort an action that
        // has just requested to be pushes and the push event has not been processed yet.
        // in such a case we'll look through the awaiting action events and remove a push event
        // for given ActionToAbort
        RemoveEventsForAction(ActionToAbort);
    }
    return AbortState;
}
Esempio n. 10
0
void FPawnActionStack::PushAction(UPawnAction& NewTopAction)
{
    if (TopAction != NULL)
    {
        if (TopAction->IsPaused() == false && TopAction->HasBeenStarted() == true)
        {
            TopAction->Pause(&NewTopAction);
        }
        ensure(TopAction->ChildAction == NULL);
        TopAction->ChildAction = &NewTopAction;
        NewTopAction.ParentAction = TopAction;
    }

    TopAction = &NewTopAction;
    NewTopAction.OnPushed();
}
Esempio n. 11
0
FPawnActionEvent::FPawnActionEvent(UPawnAction& InAction, EPawnActionEventType::Type InEventType, uint32 InIndex)
    : Action(&InAction), EventType(InEventType), Index(InIndex)
{
    Priority = InAction.GetPriority();
}
Esempio n. 12
0
EPawnActionAbortState::Type UPawnActionsComponent::ForceAbortAction(UPawnAction& ActionToAbort)
{
    return ActionToAbort.Abort(EAIForceParam::Force);
}