Example #1
0
        public static void InsertToExecutingSequence(MyFormation formation, params Action[] action)
        {
            if (formation != null && formation.Alive && action.Length > 0)
            {
                var executingAction = formation.ExecutingSequence?.GetExecutingAction();

                if (executingAction != null &&
                    executingAction.ActionType == ActionType.Move &&
                    executingAction.Interruptable)
                {
                    action.First().StartCondition = () => true;
                    formation.ExecutingSequence.AddRange(action);

                    var continueAction = executingAction.Clone();
                    continueAction.StartCondition = () =>
                                                    action.Last().Status == ActionStatus.Finished ||
                                                    action.Last().Status == ActionStatus.Aborted;
                    formation.ExecutingSequence.Add(continueAction);
                    executingAction.Abort();
                }
                if (executingAction == null)
                {
                    var newSequence = new ActionSequence(action);
                    Global.ActionQueue.Add(newSequence);
                }
            }
        }
Example #2
0
        private static void CompactAndContinue(MyFormation form, Point delta)
        {
            const double densistyLimit = 0.01;
            var          move          = form.ShiftTo(delta);

            //     move.Interruptable = false;
            move.IsAnticollision = true;
            if (form.Density < densistyLimit && form.Alive && form.Count > 0)
            {
                var scale1 = form.ScalePoint(form.MassCenter, 0.1);
                //     scale1.Interruptable = false;
                scale1.IsAnticollision  = true;
                scale1.AbortAtWorldTick = Global.World.TickIndex +
                                          (int)(Math.Sqrt(form.Rect.SqrDiameter) / (4 * form.MaxSpeed));

                var rotate = form.RotateCenter(Math.PI / 2);
                //   rotate.Interruptable = false;
                rotate.StartCondition   = () => Global.World.TickIndex >= scale1.AbortAtWorldTick;
                rotate.AbortAtWorldTick = scale1.AbortAtWorldTick + 10;

                move.StartCondition = () => Global.World.TickIndex >= rotate.AbortAtWorldTick;
                InsertToExecutingSequence(form, scale1, rotate, move);
            }
            else
            {
                InsertToExecutingSequence(form, move);
            }
        }
Example #3
0
 private static bool AttackOrRunAway(MyFormation formation, EnemyFormation enemy)
 {
     foreach (var enemyFormation in Global.EnemyFormations)
     {
         if (enemyFormation.Rect.IsInside(enemy.Center))
         {
             var dangerForEnemy = formation.DangerFor(enemy);
             var dangerForMe    = enemy.DangerFor(formation);
             if (dangerForMe < dangerForEnemy * 1.5)
             {
                 MakeAttackOrder(formation, enemy, true);
                 return(true);
             }
             if (MoveToAlly(formation, Global.MyArrvs))
             {
                 return(true);
             }
             if (MoveToAlly(formation, Global.MyIfvs))
             {
                 return(true);
             }
             if (MoveToAlly(formation, Global.MyTanks))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Example #4
0
        public static FormationResult CreateMyFormation(VehicleType type)
        {
            var formation = new MyFormation
            {
                GroupIndex = 1 + (int)type,
                Alive      = false,
                Type       = type
            };

            var left   = Global.MyVehicles.Values.Where(v => v.Type == type).Min(v => v.X);
            var top    = Global.MyVehicles.Values.Where(v => v.Type == type).Min(v => v.Y);
            var right  = Global.MyVehicles.Values.Where(v => v.Type == type).Max(v => v.X);
            var bottom = Global.MyVehicles.Values.Where(v => v.Type == type).Max(v => v.Y);

            var list = SelectAndAssignVehicles(formation, () => left, () => top, () => right, () => bottom,
                                               formation.GroupIndex);

            Global.MyFormations.Add(formation.GroupIndex, formation);

            return(new FormationResult
            {
                Formation = formation,
                GroupIndex = formation.GroupIndex,
                ActionList = list
            });
        }
Example #5
0
 private static bool MoveToAlly(MyFormation formation, MyFormation allyFormation)
 {
     if (allyFormation.Alive && allyFormation.Vehicles.Count > 10)
     {
         var actionMove = formation.MoveCenterTo(allyFormation.Center);
         AbortAndAddToExecutingSequence(formation, actionMove);
         return(true);
     }
     return(false);
 }
Example #6
0
 public Action(MyFormation formation, int minimumDuration = DefaultMinimalDuration)
 {
     Formation       = formation;
     MinimumDuration = minimumDuration;
     if (Formation != null)
     {
         FinishCondition = () => !Formation.Busy;
         StartCondition  = () => !Formation.Busy && Formation.Vehicles.Count > 0;
     }
 }
Example #7
0
        public static Action ScaleLeftTop(this MyFormation formation, double factor)
        {
            var action = new Action(formation)
            {
                ActionType = ActionType.Scale,
                Factor     = factor,
                GetX       = () => formation.Rect.Left,
                GetY       = () => formation.Rect.Top
            };

            return(action);
        }
Example #8
0
        public static Action ScalePoint(this MyFormation formation, Point point, double factor)
        {
            var action = new Action(formation)
            {
                ActionType = ActionType.Scale,
                Factor     = factor,
                GetX       = () => point.X,
                GetY       = () => point.Y
            };

            return(action);
        }
Example #9
0
        public static Action ScaleCenter(this MyFormation formation, double factor)
        {
            var action = new Action(formation)
            {
                ActionType = ActionType.Scale,
                Factor     = factor,
                GetX       = () => formation.MassCenter.X,
                GetY       = () => formation.MassCenter.Y
            };

            return(action);
        }
Example #10
0
        public static Action MoveCenterTo(this MyFormation formation, double x, double y, double maxSpeed = 10)
        {
            var action = new Action(formation)
            {
                ActionType = ActionType.Move,
                GetX       = () => x - formation.MassCenter.X,
                GetY       = () => y - formation.MassCenter.Y,
                MaxSpeed   = maxSpeed
            };

            return(action);
        }
Example #11
0
        public static Action RotateCenter(this MyFormation formation, double angle)
        {
            var action = new Action(formation)
            {
                ActionType = ActionType.Rotate,
                Angle      = angle,
                GetX       = () => formation.MassCenter.X,
                GetY       = () => formation.MassCenter.Y
            };

            return(action);
        }
Example #12
0
        public static Action ShiftTo(this MyFormation formation, double x, double y, double maxSpeed = 10)
        {
            var action = new Action(formation)
            {
                ActionType = ActionType.Move,
                GetX       = () => x,
                GetY       = () => y,
                MaxSpeed   = maxSpeed
            };

            return(action);
        }
Example #13
0
        public static Action MoveLeftTopTo(this MyFormation formation, double x, double y, double maxSpeed = 10)
        {
            var action = new Action(formation)
            {
                GetX       = () => x - formation.Rect.Left,
                GetY       = () => y - formation.Rect.Top,
                ActionType = ActionType.Move,
                MaxSpeed   = maxSpeed
            };

            return(action);
        }
Example #14
0
        public static void SplitFormation(MyFormation formation, int runFromCenter = 0)
        {
            var child = FormationFactory.CreateMyFormation(
                () => formation.Rect.Left,
                () => formation.Rect.Top,
                () => formation.MassCenter.X,
                () => formation.MassCenter.Y);

            formation.Children.Add(child.Formation);
            var sequence = new ActionSequence(child.ActionList.ToArray());

            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(-runFromCenter, -runFromCenter));
            }

            child = FormationFactory.CreateMyFormation(
                () => formation.MassCenter.X,
                () => formation.Rect.Top,
                () => formation.Rect.Right,
                () => formation.MassCenter.Y);
            sequence.AddRange(child.ActionList);
            formation.Children.Add(child.Formation);
            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(runFromCenter, -runFromCenter));
            }

            child = FormationFactory.CreateMyFormation(
                () => formation.Rect.Left,
                () => formation.MassCenter.Y,
                () => formation.MassCenter.X,
                () => formation.Rect.Bottom);
            sequence.AddRange(child.ActionList);
            formation.Children.Add(child.Formation);
            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(-runFromCenter, runFromCenter));
            }
            child = FormationFactory.CreateMyFormation(
                () => formation.MassCenter.X,
                () => formation.MassCenter.Y,
                () => formation.Rect.Right,
                () => formation.Rect.Bottom);
            sequence.AddRange(child.ActionList);
            formation.Children.Add(child.Formation);
            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(runFromCenter, runFromCenter));
            }
            Global.ActionQueue.Add(sequence);
        }
Example #15
0
        private static List <Action> SelectAndAssignVehicles(MyFormation formation,
                                                             Func <double> left, Func <double> top, Func <double> right, Func <double> bottom, int groupIndex)
        {
            var selectAction = new Action
            {
                ActionType = ActionType.ClearAndSelect,
                GetLeft    = left,
                GetTop     = top,
                GetRight   = right,
                GetBottom  = bottom,
            };

            selectAction.Callback = () =>
            {
                var rect = new Rect(left(), top(), right(), bottom());

                foreach (var keyVal in Global.MyVehicles)
                {
                    if (keyVal.Value.IsInside(rect))
                    {
                        formation.Vehicles.Add(keyVal.Key, keyVal.Value);
                    }
                }

                formation.Update();

                selectAction.Status = ActionStatus.Finished;
            };

            var assignAction = new Action
            {
                ActionType = ActionType.Assign,
                Group      = groupIndex,
                //     IsUrgent = true
            };

            assignAction.Callback = () =>
            {
                formation.Alive     = true;
                assignAction.Status = ActionStatus.Finished;
            };

            return(new List <Action> {
                selectAction, assignAction
            });
        }
Example #16
0
        public static bool OccupyFacilities(MyFormation formation)
        {
            if (formation.Alive && !formation.Busy && formation.AeralPercent < 0.1)
            {
                var freeFacility = Global.World.Facilities
                                   .OrderBy(f => f.Center.SqrDistance(formation.Center))
                                   .FirstOrDefault(f => !f.IsMine && !f.SelectedAsTargetForGroup.HasValue);

                if (freeFacility != null)
                {
                    freeFacility.SelectedAsTargetForGroup = formation.GroupIndex;

                    var actionMove = formation.MoveCenterTo(freeFacility.Center);
                    var sequence   = new ActionSequence(actionMove);
                    Global.ActionQueue.Add(sequence);
                    return(true);
                }
            }
            return(false);
        }
Example #17
0
        public static void AbortAndAddToExecutingSequence(MyFormation formation, params Action[] action)
        {
            if (formation != null && formation.Alive && action.Length > 0)
            {
                var executingAction = formation.ExecutingSequence?.GetExecutingAction();

                if (executingAction != null &&
                    executingAction.ActionType == ActionType.Move &&
                    executingAction.Interruptable)
                {
                    action.First().StartCondition = () => true;
                    formation.ExecutingSequence.AddRange(action);
                    executingAction.Abort();
                }
                if (executingAction == null)
                {
                    var newSequence = new ActionSequence(action);
                    Global.ActionQueue.Add(newSequence);
                }
            }
        }
Example #18
0
        public static FormationResult CreateMyFormation(Func <double> left, Func <double> top,
                                                        Func <double> right, Func <double> bottom)
        {
            var formation = new MyFormation
            {
                GroupIndex = GetMyFreeFormationIndex(),
                Alive      = false
            };


            var list = SelectAndAssignVehicles(formation, left, top, right, bottom, formation.GroupIndex);

            Global.MyFormations.Add(formation.GroupIndex, formation);

            return(new FormationResult
            {
                Formation = formation,
                GroupIndex = formation.GroupIndex,
                ActionList = list
            });
        }
Example #19
0
        public static bool OccupyFacilities(MyFormation formation, bool breakCurrentAction)
        {
            if (formation.Alive &&
                (!formation.Busy || breakCurrentAction) &&
                formation.AeralPercent < 0.1)
            {
                var targetFacility = formation.FacilityAsTarget == null
                    ? null
                    : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value);

                Facility freeFacility = null;
                if (targetFacility != null && !targetFacility.IsMine)
                {
                    freeFacility = targetFacility;
                }
                else
                {
                    var planningToOccupy = Global.MyFormations.Values
                                           .Where(f => f.FacilityAsTarget.HasValue)
                                           .Select(f => f.FacilityAsTarget.Value).ToList();

                    freeFacility = Global.NotMyFacilities
                                   .Where(f => !f.IsMine && !planningToOccupy.Contains(f.Id))
                                   .OrderBy(f => f.Center.SqrDistance(formation.Center)).FirstOrDefault();
                }
                if (freeFacility != null)
                {
                    formation.FacilityAsTarget = freeFacility.Id;

                    var actionMove = formation.MoveCenterTo(freeFacility.Center);
                    var sequence   = new ActionSequence(actionMove);
                    Global.ActionQueue.Add(sequence);
                    return(true);
                }
            }
            return(false);
        }
Example #20
0
 public static Action ShiftTo(this MyFormation formation, Point point, double maxSpeed = 10)
 {
     return(ShiftTo(formation, point.X, point.Y, maxSpeed));
 }
Example #21
0
        private static bool AirAttack(MyFormation formation)
        {
            if (formation != Global.MyHelicopters && formation != Global.MyFighters)
            {
                return(false);
            }
            if (Global.MyArrvs.Alive && Global.MyArrvs.Vehicles.Count > 10)
            {
                var durabilityPercent = formation.Durability / (formation.MaxDurability + 1);
                if (durabilityPercent < 0.7 || (durabilityPercent < 0.9 && formation.Center.Distance(Global.MyArrvs.Center) < 100))
                {
                    if (MoveToAlly(formation, Global.MyArrvs))
                    {
                        return(true);
                    }
                }
            }
            var enemyFightersCount = Global.EnemyFighters.Count();

            if (formation == Global.MyHelicopters)
            {
                if (enemyFightersCount > 30)
                {
                    var enemyFighters = FormationFactory.CreateEnemyFormation(Global.EnemyFighters);

                    var isMyArrvsCanProtect  = Global.MyArrvs.Alive && Global.MyArrvs.Vehicles.Count > 30;
                    var distanceToProtection = isMyArrvsCanProtect
                        ? Global.MyArrvs.Rect.Center.Distance(formation.Center)
                        : 0;

                    if ((enemyFighters.Rect.RightBottom - enemyFighters.Rect.LeftTop).Length() < 300 &&
                        enemyFighters.Rect.Center.Distance(formation.Center) < distanceToProtection)
                    {
                        MyFormation foundAllyGround = null;
                        if (Global.MyIfvs.Alive && Global.MyIfvs.Vehicles.Count > 30)
                        {
                            foundAllyGround = Global.MyIfvs;
                        }
                        else if (isMyArrvsCanProtect)
                        {
                            foundAllyGround = Global.MyArrvs;
                        }
                        if (foundAllyGround != null)
                        {
                            var actionMove = formation.MoveCenterTo(foundAllyGround.Center);
                            AbortAndAddToExecutingSequence(formation, actionMove);
                            return(true);
                        }
                    }
                }
                if (Global.EnemyVehicles.Count == 0)
                {
                    var actionMove = formation.MoveCenterTo(Global.World.Width / 3 - 100, Global.World.Height / 3);
                    AbortAndAddToExecutingSequence(formation, actionMove);
                    return(true);
                }
            }
            if (formation == Global.MyFighters)
            {
                if (enemyFightersCount > 10)
                {
                    var rect = new Rect(Global.EnemyFighters.Min(f => f.X),
                                        Global.EnemyFighters.Min(f => f.Y),
                                        Global.EnemyFighters.Max(f => f.X),
                                        Global.EnemyFighters.Max(f => f.Y));
                    var allEnemiesNearFighters = Global.EnemyVehicles.Values.Where(v => v.IsInside(rect));
                    var enemy = FormationFactory.CreateEnemyFormation(allEnemiesNearFighters);


                    var enemyLength = (enemy.Rect.RightBottom - enemy.Rect.LeftTop).Length();
                    if (enemyLength < 200)
                    {
                        if (AttackOrRunAway(formation, enemy))
                        {
                            return(true);
                        }
                    }
                }
                if (Global.EnemyHelicopters.Count() > 10)
                {
                    var rect = new Rect(Global.EnemyHelicopters.Min(f => f.X),
                                        Global.EnemyHelicopters.Min(f => f.Y),
                                        Global.EnemyHelicopters.Max(f => f.X),
                                        Global.EnemyHelicopters.Max(f => f.Y));
                    var allEnemiesNearHeli = Global.EnemyVehicles.Values.Where(v => v.IsInside(rect));
                    var enemy = FormationFactory.CreateEnemyFormation(allEnemiesNearHeli);

                    var enemyLength = (enemy.Rect.RightBottom - enemy.Rect.LeftTop).Length();
                    if (enemyLength < 300)
                    {
                        if (AttackOrRunAway(formation, enemy))
                        {
                            return(true);
                        }
                    }
                }
                if (Global.EnemyVehicles.Count == 0)
                {
                    var actionMove = formation.MoveCenterTo(Global.World.Width / 2 + 100, Global.World.Height / 2);
                    AbortAndAddToExecutingSequence(formation, actionMove);
                    return(true);
                }
            }
            return(false);
        }
Example #22
0
        public static FormationResult CreateMyFormation(MyFormation f1, MyFormation f2)
        {
            var center    = (f1.Rect.Center + f2.Rect.Center) / 2;
            var formation = new MyFormation
            {
                GroupIndex = GetMyFreeFormationIndex(),
                Alive      = false,
                Type       = f1.Type
            };

            Global.ActionQueue.AbortOldActionsFor(f1);
            Global.ActionQueue.AbortOldActionsFor(f2);


            var select1 = f1.GetSelectionAction();

            select1.Priority = ActionPriority.High;
            var select2 = f2.GetSelectionAction();

            select2.ActionType = ActionType.AddToSelection;
            select2.Priority   = ActionPriority.High;

            foreach (var vehicle in f1.Vehicles)
            {
                formation.Vehicles.Add(vehicle.Key, vehicle.Value);
            }
            foreach (var vehicle in f2.Vehicles)
            {
                formation.Vehicles.Add(vehicle.Key, vehicle.Value);
            }

            var assign = new Action
            {
                ActionType = ActionType.Assign,
                Group      = formation.GroupIndex,
                Priority   = ActionPriority.High
            };

            assign.Callback = () =>
            {
                formation.Update();
                formation.Alive = true;
                assign.Status   = ActionStatus.Finished;
            };

            Global.MyFormations.Remove(f1.GroupIndex);
            Global.MyFormations.Remove(f2.GroupIndex);
            Global.MyFormations.Add(formation.GroupIndex, formation);
            var scale1 = formation.ScalePoint(center, 0.1);

            scale1.Priority = ActionPriority.High;
            var scale2 = formation.ScalePoint(center, 1.1);

            scale2.Priority = ActionPriority.High;

            return(new FormationResult
            {
                Formation = formation,
                GroupIndex = formation.GroupIndex,
                ActionList = new List <Action> {
                    select1, select2, assign, scale1, scale2
                }
            });
        }
Example #23
0
 public bool HasActionsFor(MyFormation formation)
 {
     return(_internalQueue.Any(sequence => sequence.Any(a => a.Formation == formation)));
 }
Example #24
0
 public static Action MoveLeftTopTo(this MyFormation formation, Point point, double maxSpeed = 10)
 {
     return(MoveLeftTopTo(formation, point.X, point.Y));
 }
Example #25
0
        public static bool Attack(MyFormation formation)
        {
            if (AirAttack(formation))
            {
                return(true);
            }

            var targetFacility = formation.FacilityAsTarget == null
                ? null
                : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value);

            if (formation.FacilityAsTarget == null)
            {
                OccupyFacilities(formation, true);

                targetFacility = formation.FacilityAsTarget == null
                    ? null
                    : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value);
            }
            if (targetFacility != null)
            {
                if (targetFacility.IsMine)
                {
                    targetFacility             = null;
                    formation.FacilityAsTarget = null;
                }
            }

            double maxAttackDistance = (targetFacility == null)
                ? Global.World.Width / 2
                : Math.Min(100, formation.Center.Distance(targetFacility.Center) / 2);


            var myDurability    = Global.MyVehicles.Values.Sum(v => v.Durability);
            var enemyDurability = Global.EnemyVehicles.Values.Sum(v => v.Durability);

            var betterCoeff   = Math.Max(1, myDurability / (enemyDurability + 1.0));
            var oneShotDanger = new Dictionary <EnemyFormation, double>();

            foreach (var enemy in Global.EnemyFormations)
            {
                var dangerForEnemy = formation.DangerFor(enemy);
                var dangerForMe    = enemy.DangerFor(formation);
                if (enemy.Center.Distance(formation.Center) < maxAttackDistance)
                {
                    oneShotDanger.Add(enemy, (betterCoeff) * dangerForEnemy - dangerForMe);
                }
            }

            EnemyFormation target = null;

            if (oneShotDanger.Count > 0)
            {
                var targetPair = oneShotDanger
                                 .OrderByDescending(kv => kv.Value)
                                 .FirstOrDefault();

                if (targetPair.Value > 0)
                {
                    target = targetPair.Key;
                }
            }

            if (target != null)
            {
                MakeAttackOrder(formation, target, false);
                return(true);
            }

            var runAwayDanger = new Dictionary <EnemyFormation, double>();

            foreach (var enemy in Global.EnemyFormations)
            {
                var dangerForEnemy = formation.DangerFor(enemy);
                var dangerForMe    = enemy.DangerFor(formation);
                if (enemy.Center.Distance(formation.Center) < 150)
                {
                    runAwayDanger.Add(enemy, (dangerForEnemy - dangerForMe) / (formation.Count + 1.0));
                }
            }
            if (runAwayDanger.Count > 0)
            {
                var targetPair = runAwayDanger
                                 .OrderBy(kv => kv.Value)
                                 .FirstOrDefault();
                if (targetPair.Value < -10)
                {
                    var runAwayFromThis = targetPair.Key;
                    var direction       = (formation.MassCenter - runAwayFromThis.MassCenter).Normalized();
                    formation.FacilityAsTarget = null;


                    Global.ActionQueue.AbortOldActionsFor(formation);
                    var actionMove = formation.ShiftTo(direction * 100);
                    actionMove.Priority       = ActionPriority.High;
                    actionMove.StartCondition = () => true;
                    actionMove.Interruptable  = false;
                    var sequence = new ActionSequence(actionMove);
                    Global.ActionQueue.Add(sequence);
                }
            }


            if (targetFacility != null)
            {
                var actionMove = formation.MoveCenterTo(targetFacility.Center);
                var sequence   = new ActionSequence(actionMove);
                Global.ActionQueue.Add(sequence);
            }
            return(false);
        }
Example #26
0
        public static bool Attack(MyFormation formation)
        {
            var enemyFightersCount = Global.EnemyFighters.Count();

            if (formation == Global.MyHelicopters && enemyFightersCount > 30)
            {
                var enemyFighters = FormationFactory.CreateEnemyFormation(Global.EnemyFighters);
                if ((enemyFighters.Rect.RightBottom - enemyFighters.Rect.LeftTop).Length() < 300)
                {
                    MyFormation foundAllyGround = null;
                    if (Global.MyIfvs.Alive && Global.MyIfvs.Vehicles.Count > 30)
                    {
                        foundAllyGround = Global.MyIfvs;
                    }
                    else if (Global.MyArrvs.Alive && Global.MyArrvs.Vehicles.Count > 30)
                    {
                        foundAllyGround = Global.MyArrvs;
                    }
                    if (foundAllyGround != null)
                    {
                        var actionMove = formation.MoveCenterTo(Global.MyIfvs.Center);
                        AbortAndAddToExecutingSequence(formation, actionMove);
                        return(true);
                    }
                }
            }
            if (formation == Global.MyFighters)
            {
                if (enemyFightersCount > 10)
                {
                    var enemy       = FormationFactory.CreateEnemyFormation(Global.EnemyFighters);
                    var enemyLength = (enemy.Rect.RightBottom - enemy.Rect.LeftTop).Length();
                    if (enemyLength < 200)
                    {
                        MakeAttackOrder(formation, enemy, true);
                        return(true);
                    }
                }
                if (Global.EnemyHelicopters.Count() > 10)
                {
                    var enemy       = FormationFactory.CreateEnemyFormation(Global.EnemyHelicopters);
                    var enemyLength = (enemy.Rect.RightBottom - enemy.Rect.LeftTop).Length();
                    if (enemyLength < 300)
                    {
                        MakeAttackOrder(formation, enemy, true);
                        return(true);
                    }
                }
//                if (Global.MyArrvs.Alive && Global.MyArrvs.Vehicles.Count > 30)
//                {
//                    var actionMove = formation.MoveCenterTo(Global.MyArrvs.Center);
//                    AbortAndAddToExecutingSequence(formation, actionMove);
//                    return true;
//                }
            }

            var oneShotDanger = new Dictionary <EnemyFormation, double>();

            foreach (var enemy in Global.EnemyFormations)
            {
                var dangerForEnemy = formation.DangerFor(enemy);
                var dangerForMe    = enemy.DangerFor(formation);
                oneShotDanger.Add(enemy, dangerForEnemy - dangerForMe);
            }

            // todo: давать правильную команду
            // выбирать также по расстоянию
            EnemyFormation target     = null;
            var            targetPair = oneShotDanger.OrderByDescending(kv => kv.Value).First();

            if (targetPair.Value > 0)
            {
                target = targetPair.Key;
            }

            if (target != null)
            {
                var targetFacility = Global.World.Facilities
                                     .Where(f => f.SelectedAsTargetForGroup == formation.GroupIndex).ToList();
                if (targetFacility.Any())
                {
                    foreach (var facility in targetFacility)
                    {
                        facility.SelectedAsTargetForGroup = null;
                    }
                    OccupyFacilities(formation);
                    return(true);
                }
                MakeAttackOrder(formation, target, false);
                return(true);
            }
            return(false);
        }
Example #27
0
        public static bool MakeAttackOrder(MyFormation me, EnemyFormation enemy, bool breakCurrentAction)
        {
            if (!(me.Alive && (!me.Busy || breakCurrentAction)))
            {
                return(false);
            }


            var pointToMove = enemy == null
                ? Point.EndOfWorld / 2
                : enemy.MassCenter;


            var myMassCenter = me.MassCenter;
            var distance     = pointToMove.Distance(myMassCenter);

            if (enemy != null)
            {
                var enemySpeedScalar = enemy.AvgSpeed.Length();
                var mySpeedScalar    = me.MaxSpeed;

                var myDirection    = (pointToMove - myMassCenter).Normalized();
                var enemyDirection = enemy.AvgSpeed.Normalized();

                var resultDirection =
                    (myDirection + enemySpeedScalar / mySpeedScalar * enemyDirection).Normalized();

                pointToMove = myMassCenter + distance * resultDirection;
            }

            if (distance > 100)
            {
                pointToMove = (me.Center + pointToMove) / 2;
            }

            if (me.ExecutingAction != null && me.ExecutingAction.ActionType == ActionType.Move)
            {
                var oldVector = new Point(me.ExecutingAction.GetX(), me.ExecutingAction.GetY());


                var newVector = pointToMove - me.Center;

                var scalar = oldVector.Normalized() * newVector.Normalized();
                if (scalar > 0.95) // около 18 градусов
                {
                    return(false);
                }
            }

            var actionMove = me.MoveCenterTo(pointToMove);

            if (me.Density < 0.01 && distance > 200)
            {
                var actionScale = me.ScaleCenter(0.1);
                AbortAndAddToExecutingSequence(me, actionScale, actionMove);
            }
            else
            {
                AbortAndAddToExecutingSequence(me, actionMove);
            }

            foreach (var facility in Global.World.Facilities)
            {
                if (facility.SelectedAsTargetForGroup == me.GroupIndex)
                {
                    facility.SelectedAsTargetForGroup = null;
                }
            }
            return(true);
        }