示例#1
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);
 }
示例#2
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);
        }
示例#3
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);
        }
示例#4
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);
        }
示例#5
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);
        }
示例#6
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);
        }
示例#7
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);
        }