예제 #1
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);
 }
예제 #2
0
        public static EnemyFormation CreateEnemyFormation(IEnumerable <VehicleWrapper> vehicles)
        {
            var formation = new EnemyFormation();

            foreach (var v in vehicles)
            {
                formation.Vehicles.Add(v.Id, v);
            }

            formation.Update();
            Global.EnemyFormations.Add(formation);
            return(formation);
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
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);
        }