Example #1
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 #2
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);
        }