Example #1
0
        public static bool IsPositionTooFarBehind(EncounterPosition position, Unit unit)
        {
            var behindVec = AIUtils.VectorFromCenterRotated(unit.AveragePosition, position.X, position.Y, unit.UnitFacing);

            // This can't be too restrictive or it stops you from sitting at the back of the line when rotating.
            return(behindVec.Item2 > -Mathf.CeilToInt(unit.Depth / 2) + 5);
        }
Example #2
0
        public static bool IsNextRowTooFarAhead(EncounterPosition parentPos, Unit unit)
        {
            var directlyInFrontPosition = AIUtils.RotateAndProject(parentPos, 0, -1, unit.UnitFacing);
            var forwardVec = AIUtils.VectorFromCenterRotated(unit.AveragePosition, directlyInFrontPosition.X, directlyInFrontPosition.Y, unit.UnitFacing);

            return(forwardVec.Item2 < -Mathf.CeilToInt(unit.Depth / 2) - 1);
        }
Example #3
0
        public override bool IsOnFlank(int x, int y, Unit unit, Flank flank)
        {
            var northFacing = AIUtils.VectorFromCenterRotated(unit.RallyPoint, x, y, unit.UnitFacing);

            if (flank == Flank.LEFT)
            {
                return(northFacing.Item1 <= -10);
            }
            else if (flank == Flank.RIGHT)
            {
                return(northFacing.Item1 >= 9);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Example #4
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
            });
        }