示例#1
0
        public override List <EncounterAction> _DecideNextAction(EncounterState state, Entity parent)
        {
            var unit          = state.GetUnit(parent.GetComponent <UnitComponent>().UnitId);
            var unitComponent = parent.GetComponent <UnitComponent>();

            if (unit.StandingOrder == UnitOrder.REFORM)
            {
                if (state.CurrentTurn < EncounterStateBuilder.ADVANCE_AT_TURN)
                {
                    if (state.EncounterRand.Next(750) == 0)
                    {
                        parent.GetComponent <PositionComponent>().PlaySpeechBubble(Quips[state.EncounterRand.Next(Quips.Length)]);
                    }
                }
                return(AIUtils.ActionsForUnitReform(state, parent, unitComponent.FormationNumber, unit));
            }
            else if (unit.StandingOrder == UnitOrder.ADVANCE)
            {
                return(AIUtils.ActionsForUnitAdvanceInLine(state, parent, unit));
            }
            else if (unit.StandingOrder == UnitOrder.ROUT)
            {
                return(AIUtils.ActionsForUnitRetreat(state, parent, unit));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
示例#2
0
        private static bool ResolveMove(MoveAction action, EncounterState state)
        {
            Entity actor             = state.GetEntityById(action.ActorId);
            var    positionComponent = state.GetEntityById(action.ActorId).GetComponent <PositionComponent>();
            var    oldPosition       = positionComponent.EncounterPosition;

            if (positionComponent.EncounterPosition == action.TargetPosition)
            {
                GD.PrintErr(string.Format("Entity {0}:{1} tried to move to its current position {2}", actor.EntityName, actor.EntityId, action.TargetPosition));
                return(false);
            }
            else
            {
                state.TeleportEntity(actor, action.TargetPosition, ignoreCollision: false);
                var unitComponent = actor.GetComponent <UnitComponent>();
                if (unitComponent != null)
                {
                    state.GetUnit(unitComponent.UnitId).NotifyEntityMoved(oldPosition, action.TargetPosition);
                }
                // If you go into the retreat zone you insta-die
                if (IsInRetreatZone(state, action.TargetPosition))
                {
                    if (actor.GetComponent <PlayerComponent>() != null)
                    {
                        state.NotifyPlayerRetreat();
                        return(false);
                    }
                    else
                    {
                        ResolveAction(new DestroyAction(action.ActorId), state);
                    }
                }
                return(true);
            }
        }
示例#3
0
        public List <EncounterAction> DecideNextAction(EncounterState state, Entity parent)
        {
            if (this._DeploymentOrders.ContainsKey(this._CurrentTurn))
            {
                var deploymentOrders = this._DeploymentOrders[this._CurrentTurn];
                foreach (var order in deploymentOrders)
                {
                    order.ExecuteOrder(state);
                }
                if (this.LastDeploymentTurn == this._CurrentTurn)
                {
                    this.DeploymentComplete = true;
                }
            }
            else if (this.DeploymentComplete)
            {
                foreach (var kvp in this._TriggerOrders)
                {
                    var unit = state.GetUnit(kvp.Key);
                    if (unit.StandingOrder == UnitOrder.ROUT)
                    {
                        continue;
                    }
                    var removeThese = new List <TriggeredOrder>();
                    var addThese    = new List <TriggeredOrder>();

                    foreach (var triggeredOrder in kvp.Value)
                    {
                        if (triggeredOrder.Trigger.IsTriggered(state))
                        {
                            var newOrders = triggeredOrder.Order.ExecuteOrder(state);
                            if (newOrders != null)
                            {
                                addThese.AddRange(newOrders);
                            }
                            if (!triggeredOrder.Trigger.Repeating)
                            {
                                removeThese.Add(triggeredOrder);
                            }
                        }
                    }

                    foreach (var removeThis in removeThese)
                    {
                        kvp.Value.Remove(removeThis);
                    }
                    foreach (var addThis in addThese)
                    {
                        this.RegisterTriggeredOrder(addThis);
                    }
                }
            }

            this._CurrentTurn += 1;
            return(new List <EncounterAction>()
            {
                new WaitAction(parent.EntityId)
            });
        }
示例#4
0
        public List <string> AllowedActions(EncounterState state, Entity parent, UnitOrder standingOrder)
        {
            var parentPos       = parent.GetComponent <PositionComponent>().EncounterPosition;
            var unit            = state.GetUnit(parent.GetComponent <UnitComponent>().UnitId);
            var actions         = new List <string>();
            var parentIsLagging = AIUtils.IsPositionTooFarBehind(parentPos, unit);

            // TODO: this is a silly place to run this check
            if (parentIsLagging)
            {
                parent.GetComponent <AIRotationComponent>().NotifyRotationCompleted();
            }

            if (standingOrder == UnitOrder.ADVANCE && !parent.GetComponent <AIRotationComponent>().IsRotating)
            {
                // Directly ahead pos available if not too far ahead OR if too far behind
                var validAheadPositions = new List <EncounterPosition>()
                {
                    AIUtils.RotateAndProject(parentPos, 0, -1, unit.UnitFacing),
                    AIUtils.RotateAndProject(parentPos, 1, -1, unit.UnitFacing),
                    AIUtils.RotateAndProject(parentPos, -1, -1, unit.UnitFacing),
                };
                foreach (var possible in validAheadPositions)
                {
                    if (positionNotTooFarAheadAndMovable(state, parentPos, unit, possible) || parentIsLagging)
                    {
                        actions.Add(ToCardinalDirection(parentPos, possible));
                    }
                }

                // Flank positions available if not too far ahead AND not too far behind
                var validFlankPositions = new List <EncounterPosition>()
                {
                    AIUtils.RotateAndProject(parentPos, 1, 0, unit.UnitFacing),
                    AIUtils.RotateAndProject(parentPos, -1, 0, unit.UnitFacing),
                };
                foreach (var possible in validFlankPositions)
                {
                    if (positionNotTooFarAheadAndMovable(state, parentPos, unit, possible) && !parentIsLagging)
                    {
                        actions.Add(ToCardinalDirection(parentPos, possible));
                    }
                }

                if (parent.GetComponent <AIRotationComponent>().BackSecure(state, parent, unit))
                {
                    actions.Add(InputHandler.ActionMapping.ROTATE);
                }
            }

            if (!parentIsLagging)
            {
                actions.Add(InputHandler.ActionMapping.WAIT);
            }
            actions.Add(InputHandler.ActionMapping.LEAVE_FORMATION);

            return(actions);
        }
示例#5
0
        public override List <EncounterAction> _DecideNextAction(EncounterState state, Entity parent)
        {
            var unit          = state.GetUnit(parent.GetComponent <UnitComponent>().UnitId);
            var unitComponent = parent.GetComponent <UnitComponent>();

            if (unit.StandingOrder == UnitOrder.REFORM)
            {
                return(AIUtils.ActionsForUnitReform(state, parent, unitComponent.FormationNumber, unit));
            }
            else if (unit.StandingOrder == UnitOrder.ADVANCE)
            {
                return(AIUtils.ActionsForUnitAdvanceInLine(state, parent, unit));
            }
            else if (unit.StandingOrder == UnitOrder.ROUT)
            {
                return(AIUtils.ActionsForUnitRetreat(state, parent, unit));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
示例#6
0
 private static bool ResolveOnDeathEffect(DestroyAction action, string effectType, EncounterState state)
 {
     if (effectType == OnDeathEffectType.PLAYER_VICTORY)
     {
         state.NotifyPlayerVictory();
         return(true);
     }
     else if (effectType == OnDeathEffectType.PLAYER_DEFEAT)
     {
         state.NotifyPlayerDefeat();
         return(true);
     }
     else if (effectType == OnDeathEffectType.REMOVE_FROM_UNIT)
     {
         var unit = state.GetUnit(state.GetEntityById(action.ActorId).GetComponent <UnitComponent>().UnitId);
         unit.NotifyEntityDestroyed(state.GetEntityById(action.ActorId));
         return(false);
     }
     else
     {
         throw new NotImplementedException(String.Format("Don't know how to resolve on death effect type {0}", effectType));
     }
 }
示例#7
0
        public static List <TriggeredOrder> ExecutePREPARE_SWEEP_NEXT_LANE(EncounterState state, Unit unit)
        {
            // Find your current lane
            Lane   closestLane     = null;
            double closestDistance = 9999.0;

            foreach (var lane in state.DeploymentInfo.Lanes)
            {
                var d = lane.LaneCenter.DistanceTo(unit.AveragePosition);
                if (d < closestDistance)
                {
                    closestDistance = d;
                    closestLane     = lane;
                }
            }

            // Find a target lane
            int targetLane = -1;

            for (int i = closestLane.LaneIdx - 1; i >= 0; i--)
            {
                GD.Print("PREPPING CHECKING: ", i);
                var clear = state.DeploymentInfo.Lanes[i].UnitsForFaction(unit.UnitFaction.Opposite())
                            .Select((unitAtLanePosition) => state.GetUnit(unitAtLanePosition.UnitId).StandingOrder)
                            .All((order) => order == UnitOrder.ROUT);
                if (!clear)
                {
                    targetLane = i;
                    break;
                }
            }
            for (int i = closestLane.LaneIdx + 1; i < state.DeploymentInfo.Lanes.Count; i++)
            {
                GD.Print("PREPPING CHECKING: ", i);
                var clear = state.DeploymentInfo.Lanes[i].UnitsForFaction(unit.UnitFaction.Opposite())
                            .Select((unitAtLanePosition) => state.GetUnit(unitAtLanePosition.UnitId).StandingOrder)
                            .All((order) => order == UnitOrder.ROUT);
                if (!clear)
                {
                    targetLane = i;
                    break;
                }
            }
            GD.Print("CHOSEN LANE: ", targetLane);
            if (targetLane == -1)
            {
                return(null);
            }

            // Given a target lane, get the closest unit, and advance to its center
            var closestUnroutedEnemy = state.DeploymentInfo.Lanes[targetLane]
                                       .UnitsForFaction(unit.UnitFaction.Opposite())
                                       .Last((u) => state.GetUnit((u.UnitId)).StandingOrder != UnitOrder.ROUT);
            var enemyUnit     = state.GetUnit(closestUnroutedEnemy.UnitId);
            var enemyPos      = enemyUnit.AveragePosition;
            var vectorToEnemy = AIUtils.VectorFromCenterRotated(unit.AveragePosition, enemyPos.X, enemyPos.Y, unit.UnitFacing);
            var stepsBehind   = vectorToEnemy.Item2;

            GD.Print("UNIT IS BEHIND THE ENEMY UNIT BY: ", stepsBehind, " unit pos: ", unit.AveragePosition, " enemy pos: ", enemyPos, "facing: ", unit.UnitFacing);

            // Order unit to march steps + 5
            // unit.StandingOrder = UnitOrder.ADVANCE;

            // Order unit to reform perpendicular to the enemy line
            // var triggerStepsPlusFive = new OrderTrigger(OrderTriggerType.ACTIVATE_ON_OR_AFTER_TURN, false, activateOnTurn: state.CurrentTurn + stepsBehind + 5);
            var oldFacing = unit.UnitFacing;
            var newFacing = vectorToEnemy.Item1 < 0 ? unit.UnitFacing.LeftOf() : unit.UnitFacing.RightOf();

            unit.RallyPoint    = AIUtils.RotateAndProject(unit.AveragePosition, 0, -1 * stepsBehind - 25, unit.UnitFacing);;
            unit.UnitFacing    = newFacing;
            unit.StandingOrder = UnitOrder.REFORM;

            var behindEnemyUnit = AIUtils.RotateAndProject(enemyUnit.AveragePosition, 0, 15, enemyUnit.UnitFacing);

            // Order unit to advance after wheeling
            var triggerStepsPlus40 = new OrderTrigger(OrderTriggerType.ACTIVATE_ON_OR_AFTER_TURN, false, activateOnTurn: state.CurrentTurn + Math.Max(0, stepsBehind) + 15);
            var sweepOrder         = new TriggeredOrder(triggerStepsPlus40, new Order(unit.UnitId, OrderType.ROTATE_AND_REFORM_AT, newPosition: behindEnemyUnit, newFacing: oldFacing.Opposite()));

            // Order unit to finally advance
            var triggerStepsPlus60 = new OrderTrigger(OrderTriggerType.ACTIVATE_ON_OR_AFTER_TURN, false, activateOnTurn: state.CurrentTurn + Math.Max(0, stepsBehind) + 50);
            var advance            = new TriggeredOrder(triggerStepsPlus60, new Order(unit.UnitId, OrderType.ADVANCE));

            return(new List <TriggeredOrder>()
            {
                sweepOrder, advance
            });
        }
示例#8
0
        public bool IsTriggered(EncounterState state)
        {
            if (this.TriggerType == OrderTriggerType.UNIT_HAS_STANDING_ORDER)
            {
                foreach (var watchedUnitId in this.WatchedUnitIds)
                {
                    if (this.AwaitedStandingOrders.Contains(state.GetUnit(watchedUnitId).StandingOrder))
                    {
                        return(true);
                    }
                }
                return(false);
            }
            else if (this.TriggerType == OrderTriggerType.UNIT_BELOW_STRENGTH_PERCENT)
            {
                foreach (var watchedUnitId in this.WatchedUnitIds)
                {
                    var unit = state.GetUnit(watchedUnitId);
                    if ((float)unit.NumInFormation / (float)unit.OriginalUnitStrength < this.BelowStrengthPercent)
                    {
                        return(true);
                    }
                }
                return(false);
            }
            else if (this.TriggerType == OrderTriggerType.ALL_UNITS_OF_FACTION_ROUTED)
            {
                foreach (var unit in state.GetUnitsOfFaction(this.TriggerFaction))
                {
                    if (unit.StandingOrder != UnitOrder.ROUT)
                    {
                        return(false);
                    }
                }
                return(true);
            }
            else if (this.TriggerType == OrderTriggerType.LANE_CLEAR_OF_UNITS_FROM_FACTION)
            {
                if (this.TriggerFaction == FactionName.NEUTRAL || this.WatchedUnitIds.Count != 1)
                {
                    throw new ArgumentException("didn't set faction or proper watched unit ID, Fs in chat");
                }

                Lane   closestLane     = null;
                double closestDistance = 9999.0;
                Unit   unit            = state.GetUnit(this.WatchedUnitIds[0]);
                foreach (var lane in state.DeploymentInfo.Lanes)
                {
                    var d = lane.LaneCenter.DistanceTo(unit.AveragePosition);
                    if (d < closestDistance)
                    {
                        closestDistance = d;
                        closestLane     = lane;
                    }
                }

                /* if (closestLane == null) {
                 * GD.PrintErr("ClosestLane null somehow!? wtf.");
                 * GD.PrintErr(unit.AveragePosition);
                 * GD.PrintErr(unit.UnitFaction, " lol ", unit.NumInFormation);
                 * return false;
                 * } */
                return(closestLane.UnitsForFaction(this.TriggerFaction)
                       .Select((unitAtLanePosition) => state.GetUnit(unitAtLanePosition.UnitId).StandingOrder)
                       .All((order) => order == UnitOrder.ROUT));
            }
            else if (this.TriggerType == OrderTriggerType.ACTIVATE_ON_OR_AFTER_TURN)
            {
                if (this.ActivateOnTurn == -1)
                {
                    throw new ArgumentException("didn't set timer");
                }
                if (state.CurrentTurn >= this.ActivateOnTurn)
                {
                    GD.Print(String.Format("Activating trigger on turn {0}, timed for turn {1}!", state.CurrentTurn, this.ActivateOnTurn));
                }
                return(state.CurrentTurn >= this.ActivateOnTurn);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
示例#9
0
        public List <TriggeredOrder> ExecuteOrder(EncounterState state)
        {
            var unit = state.GetUnit(this.UnitId);

            if (this.OrderType == OrderType.ADVANCE)
            {
                unit.StandingOrder = UnitOrder.ADVANCE;
                return(null);
            }
            else if (this.OrderType == OrderType.OPEN_MANIPULE)
            {
                var firstUnit = state.GetEntityById(unit.EntityIdInForPositionZero);

                unit.UnitFormation = FormationType.MANIPULE_OPENED;
                unit.StandingOrder = UnitOrder.REFORM;
                // TODO: dumb hack to make blocks line up
                var firstUnitPos = firstUnit.GetComponent <PositionComponent>().EncounterPosition;
                if (unit.UnitFacing == FormationFacing.SOUTH)
                {
                    unit.RallyPoint = new EncounterPosition(firstUnitPos.X + 1, firstUnitPos.Y);
                }
                else if (unit.UnitFacing == FormationFacing.WEST)
                {
                    unit.RallyPoint = new EncounterPosition(firstUnitPos.X, firstUnitPos.Y + 1);
                }
                else
                {
                    unit.RallyPoint = firstUnitPos;
                }
                return(null);
            }
            else if (this.OrderType == OrderType.ROUT)
            {
                unit.StandingOrder = UnitOrder.ROUT;
                return(null);
            }
            else if (this.OrderType == OrderType.DECLARE_VICTORY)
            {
                state.NotifyArmyVictory();
                return(null);
            }
            else if (this.OrderType == OrderType.DECLARE_DEFEAT)
            {
                state.NotifyArmyDefeat();
                return(null);
            }
            else if (this.OrderType == OrderType.PRINT)
            {
                GD.Print("!!!!!!! PRINT ORDER EXECUTED !!!!!!!!!");
                return(null);
            }
            else if (this.OrderType == OrderType.PREPARE_SWEEP_NEXT_LANE)
            {
                return(OrderFns.ExecutePREPARE_SWEEP_NEXT_LANE(state, unit));
            }
            else if (this.OrderType == OrderType.ROTATE_AND_REFORM_AT)
            {
                if (this.NewPosition == null)
                {
                    unit.RallyPoint = unit.AveragePosition;
                }
                else
                {
                    unit.RallyPoint = this.NewPosition.Value;
                }
                unit.UnitFacing    = this.NewFacing;
                unit.StandingOrder = UnitOrder.REFORM;
                return(null);
            }
            else
            {
                throw new NotImplementedException("lol: " + this.OrderType);
            }
        }
示例#10
0
        public void RefreshStats(EncounterState state)
        {
            var player = state.Player;

            // Left column
            var playerDefenderComponent = player.GetComponent <DefenderComponent>();
            var newHPText = string.Format("Hit Points: {0}/{1}", playerDefenderComponent.CurrentHp, playerDefenderComponent.MaxHp);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/HPLabel").Text = newHPText;

            var newFootingText = string.Format("Footing: {0}/{1}", playerDefenderComponent.CurrentFooting,
                                               playerDefenderComponent.MaxFooting, playerDefenderComponent.FootingPenalty);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/FootingLabel").Text = newFootingText;

            var penalty = string.Format("Low Ftng Malus: {0}", -playerDefenderComponent.FootingPenalty);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/FootingPenaltyLabel").Text = penalty;

            var playerAttackerComponent = player.GetComponent <AttackerComponent>();
            var newMAtkText             = string.Format("Attack: {0}", playerAttackerComponent.MeleeAttack - playerDefenderComponent.FootingPenalty);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/MeleeAttackLabel").Text = newMAtkText;

            var newAttackPowerText = string.Format("Attack Power: {0}", playerAttackerComponent.Power);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/AttackPowerLabel").Text = newAttackPowerText;

            var newMDefText = string.Format("Defense: {0}", playerDefenderComponent.MeleeDefense - playerDefenderComponent.FootingPenalty);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/MeleeDefenseLabel").Text = newMDefText;

            var newRDefText = string.Format("Armor: {0}", playerDefenderComponent.BaseDR);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/RangedDefenseLabel").Text = newRDefText;

            var speedComponent = player.GetComponent <SpeedComponent>();
            var newSpeedText   = string.Format("Speed: {0}", speedComponent.Speed);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/StatsBlock/SpeedLabel").Text = newSpeedText;

            // Right column
            var playerPos = player.GetComponent <PositionComponent>().EncounterPosition;

            var newTurnReadoutText = string.Format("Turn: {0:0.00}", state.CurrentTick / 100);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/PositionBlock/TurnReadoutLabel").Text = newTurnReadoutText;

            var playerComponent = player.GetComponent <PlayerComponent>();
            var newPretigeText  = string.Format("Prestige: {0}", playerComponent.Prestige);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/PositionBlock/PrestigeLabel").Text = newPretigeText;

            var xpComponent  = player.GetComponent <XPTrackerComponent>();
            var newLevelText = string.Format("Level: {0}", xpComponent.Level);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/PositionBlock/LevelLabel").Text = newLevelText;
            var newXPText = string.Format("Experience: {0}/{1}", xpComponent.XP, xpComponent.NextLevelAtXP);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/PositionBlock/ExperienceLabel").Text = newXPText;

            var armyStatusText = string.Format("Army: {0}", state.RunStatus);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/PositionBlock/ArmyStatusLabel").Text = armyStatusText;

            var unit          = state.GetUnit(player.GetComponent <UnitComponent>().UnitId);
            var unitOrderText = string.Format("Unit Order: {0}", unit.StandingOrder.ToString());

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/PositionBlock/UnitOrderLabel").Text = unitOrderText;

            var unitSizeText = string.Format("Unit Size: {0}/{1}", unit.NumInFormation, unit.OriginalUnitStrength);

            GetNode <Label>("SidebarVBox/StatsAndPositionHBox/PositionBlock/UnitNumLabel").Text = unitSizeText;
        }
示例#11
0
 public void LeaveFormation(EncounterState state, Entity parent)
 {
     this.IsInFormation = false;
     state.GetUnit(parent.GetComponent <UnitComponent>().UnitId).NotifyEntityRouted(parent);
     this.AddPrestige(-10, state, "Your allies will remember how you broke from formation! [b]You lose 10 prestige.[/b]", PrestigeSource.BREAKING_FORMATION);
 }
示例#12
0
        public List <EncounterAction> DecideNextActionForInput(EncounterState state, Entity parent, string actionMapping)
        {
            var unit          = state.GetUnit(parent.GetComponent <UnitComponent>().UnitId);
            var unitComponent = parent.GetComponent <UnitComponent>();

            if (actionMapping == InputHandler.ActionMapping.LEAVE_FORMATION)
            {
                parent.GetComponent <PlayerComponent>().LeaveFormation(state, parent);
                return(null);
            }

            if (unit.StandingOrder == UnitOrder.REFORM)
            {
                if (actionMapping == AUTOPILOT)
                {
                    return(AIUtils.ActionsForUnitReform(state, parent, unitComponent.FormationNumber, unit));
                }
                else
                {
                    return(null);
                }
            }
            else if (unit.StandingOrder == UnitOrder.ADVANCE)
            {
                if (this.AllowedActions(state, parent, unit.StandingOrder).Contains(actionMapping))
                {
                    if (actionMapping == InputHandler.ActionMapping.ROTATE)
                    {
                        parent.GetComponent <AIRotationComponent>().PlayerSetRotation(true);
                        parent.GetComponent <PlayerComponent>().AddPrestige(-2, state,
                                                                            "You cry out [b]'Rotation!'[/b]' and pull back through your lines. [b]You lose 2 prestige.[/b]", PrestigeSource.ROTATING);
                        return(null);
                    }
                    else if (actionMapping == InputHandler.ActionMapping.WAIT)
                    {
                        return(new List <EncounterAction>()
                        {
                            new WaitAction(parent.EntityId)
                        });
                    }
                    else
                    {
                        return(HandleMoveCommand(state, actionMapping));
                    }
                }
                else if (actionMapping == AUTOPILOT)
                {
                    var playerComponent = state.Player.GetComponent <PlayerComponent>();

                    var actions = AIUtils.ActionsForUnitAdvanceInLine(state, parent, unit);

                    // Termination for startoflevel
                    if (playerComponent.StartOfLevel)
                    {
                        var anyHostilesAdjacent = AIUtils.AdjacentHostiles(state, FactionName.PLAYER, parent.GetComponent <PositionComponent>().EncounterPosition).Count > 0;
                        if (anyHostilesAdjacent)
                        {
                            state.Player.GetComponent <PlayerComponent>().StartOfLevel = false;
                            return(null);
                        }
                        foreach (var action in actions)
                        {
                            if (action.ActionType == ActionType.MOVE)
                            {
                                if (AIUtils.AdjacentHostiles(state, FactionName.PLAYER, ((MoveAction)action).TargetPosition).Count > 0)
                                {
                                    state.Player.GetComponent <PlayerComponent>().StartOfLevel = false;
                                    return(null);
                                }
                            }
                        }
                    }

                    return(actions);
                }
                else
                {
                    return(null);
                }
            }
            else if (unit.StandingOrder == UnitOrder.ROUT)
            {
                return(null);
            }
            else
            {
                throw new NotImplementedException();
            }
        }