/// <summary> /// Creates the state to make the agent perform an action /// </summary> private void CreatePerformActionState() { PerformActionState = (a_fFinateStateMachine, a_goObject) => { if (!HasActionPlan()) { FinateStateMachine.PopStateStack(); FinateStateMachine.PushStateToStack(IdleState); DataProviderInterface.AllActionsFinished(); return; } CS_GOAPAction Action = CurrentlyActiveActions.Peek(); if (Action.IsActionFinished()) { CurrentlyActiveActions.Dequeue(); } if (HasActionPlan()) { Action = CurrentlyActiveActions.Peek(); bool bIsInRange = Action.NeedsToBeInRange() ? Action.IsAgentInRange() : true; if (bIsInRange) { bool bActionPerformSuccess = Action.PerformAction(a_goObject); if (!bActionPerformSuccess) { FinateStateMachine.PopStateStack(); FinateStateMachine.PushStateToStack(IdleState); CreateIdleState(); DataProviderInterface.AbortPlan(Action); } } else { FinateStateMachine.PushStateToStack(MovingState); } } else { FinateStateMachine.PopStateStack(); FinateStateMachine.PushStateToStack(IdleState); DataProviderInterface.AllActionsFinished(); } }; }
/// <summary> /// Creates the state to move the agent to its destination for the FSM /// </summary> private void CreateMovingState() { MovingState = (a_fFinateStateMachine, a_goObject) => { CS_GOAPAction Action = CurrentlyActiveActions.Peek(); if (Action.NeedsToBeInRange() && Action.m_goTarget == null) { FinateStateMachine.PopStateStack(); FinateStateMachine.PopStateStack(); FinateStateMachine.PushStateToStack(IdleState); return; } if (DataProviderInterface.MoveAgentToAction(Action)) { FinateStateMachine.PopStateStack(); } }; }
/// <summary> /// Creates the idle state for the FSM where the agent will do nothin at all https://i.imgur.com/3IcRtUP.png. /// </summary> private void CreateIdleState() { IdleState = (a_fFinateStateMachine, a_goObject) => { HashSet <KeyValuePair <string, object> > kvpWorldState = DataProviderInterface.GetWorldState(); HashSet <KeyValuePair <string, object> > kvpGoal = DataProviderInterface.CreateGoalState(); Queue <CS_GOAPAction> ActionPlan = ActionPlanner.CreateActionPlan(gameObject, AvailableActions, kvpWorldState, kvpGoal); if (ActionPlan != null) { CurrentlyActiveActions = ActionPlan; DataProviderInterface.PlanFound(kvpGoal, ActionPlan); FinateStateMachine.PopStateStack(); FinateStateMachine.PushStateToStack(PerformActionState); } else { DataProviderInterface.PlanFailed(kvpGoal); FinateStateMachine.PopStateStack(); FinateStateMachine.PushStateToStack(IdleState); } }; }