public override double ShouldAccept()
        {
            var avoidExposedAirDefense = 0;

            if (avoidExposedAirDefense == 1)
            {
                if (AllInOnePushHelper.IsAirDefenseExposed())
                {
                    return(0);
                }
            }
            if (Opponent.MeetsRequirements(BaseRequirements.All))
            {
                return(1);
            }
            return(0);
        }
        public static IEnumerable <int> GroundAttack(int customOrder)
        {
            DeploymentMethods.clanCastle  = AllInOnePushDeploy.deployElements.ExtractOne(u => u.ElementType == DeployElementType.ClanTroops);
            DeploymentMethods.eq          = AllInOnePushDeploy.deployElements.Extract(u => u.Id == DeployId.Earthquake);
            DeploymentMethods.rageSpell   = AllInOnePushDeploy.deployElements.Extract(u => u.Id == DeployId.Rage);
            DeploymentMethods.healSpell   = AllInOnePushDeploy.deployElements.Extract(u => u.Id == DeployId.Heal);
            DeploymentMethods.freezeSpell = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.Freeze);
            DeploymentMethods.jumpSpell   = AllInOnePushDeploy.deployElements.Extract(u => u.Id == DeployId.Jump);
            DeploymentMethods.hasteSpell  = AllInOnePushDeploy.deployElements.Extract(u => u.Id == DeployId.Haste);
            DeploymentMethods.poison      = AllInOnePushDeploy.deployElements.Extract(u => u.Id == DeployId.Poison);
            //tanks
            DeploymentMethods.giant = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.Giant);
            DeploymentMethods.golem = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.Golem);
            //main troops
            DeploymentMethods.wallbreaker = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.WallBreaker);
            DeploymentMethods.bowler      = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.Bowler);
            DeploymentMethods.witch       = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.Witch);
            DeploymentMethods.healer      = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.Healer);
            DeploymentMethods.wizard      = AllInOnePushDeploy.deployElements.ExtractOne(DeployId.Wizard);

            DeploymentMethods.spells = AllInOnePushDeploy.deployElements.Extract(DeployElementType.Spell);

            DeploymentMethods.heroes = AllInOnePushDeploy.deployElements.Extract(x => x.IsHero);
            DeploymentMethods.warden = DeploymentMethods.heroes.ExtractOne(u => u.ElementType == DeployElementType.HeroWarden);
            DeploymentMethods.queen  = DeploymentMethods.heroes.ExtractOne(DeployId.Queen);

            // Drop earthquake
            foreach (var t in DeploymentMethods.DropEQ())
            {
                yield return(t);
            }

            if (customOrder == 1)
            {
                foreach (var t in DeploymentMethods.DeployInCustomOrder(AllInOnePushDeploy.CustomOrderList))
                {
                    yield return(t);
                }
            }
            else
            {
                // Check if queen walk is active
                var QW = AllInOnePushDeploy.QWSettings == 1 && DeploymentMethods.queen?.Count > 0 && DeploymentMethods.healer?.Count >= AllInOnePushDeploy.HealerOnQWSettings ? true : false;
                if (QW)
                {
                    foreach (var s in DeploymentMethods.DeployFunnlling())
                    {
                        yield return(s);
                    }
                    foreach (var s in DeploymentMethods.DeployGolems())
                    {
                        yield return(s);
                    }
                }
                else
                {
                    foreach (var s in DeploymentMethods.DeployGolems())
                    {
                        yield return(s);
                    }
                    foreach (var s in DeploymentMethods.DeployFunnlling())
                    {
                        yield return(s);
                    }
                }
                foreach (var s in DeploymentMethods.DeployGiants())
                {
                    yield return(s);
                }
                foreach (var s in DeploymentMethods.DeployHeroes())
                {
                    yield return(s);
                }
                foreach (var s in DeploymentMethods.DeployWB())
                {
                    yield return(s);
                }
                foreach (var s in DeploymentMethods.DeployNormalTroops())
                {
                    yield return(s);
                }
            }

            // Screen Shots for spells if debug mode is on
            if (AllInOnePushDeploy.Debug)
            {
                AllInOnePushHelper.DebugEQpells();
                AllInOnePushHelper.DebugSpells();
            }

            // Deploy spells
            foreach (var s in DeploymentMethods.DeployJump())
            {
                yield return(s);
            }

            foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.rageSpell, AllInOnePushDeploy.FirstRagePoint))
            {
                yield return(s);
            }

            yield return(2000);

            if (DeploymentMethods.hasteSpell.Sum(u => u.Count) > 0)
            {
                foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.hasteSpell, AllInOnePushDeploy.FirstHealPoint))
                {
                    yield return(s);
                }
            }
            else
            {
                foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.healSpell, AllInOnePushDeploy.FirstHealPoint))
                {
                    yield return(s);
                }
            }

            if (DeploymentMethods.poison?.Count > 0)
            {
                foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.poison, AllInOnePushDeploy.FirstHealPoint))
                {
                    yield return(s);
                }
            }

            // Use freeze if inferno is found
            if (DeploymentMethods.freezeSpell?.Count > 0)
            {
                var infernos = InfernoTower.Find();
                // find and watch inferno towers
                if (infernos != null)
                {
                    foreach (var inferno in infernos)
                    {
                        inferno.FirstActivated += DropFreeze;
                        inferno.StartWatching();
                    }
                }
            }

            yield return(4000);

            // activate Grand Warden apility
            if (DeploymentMethods.isWarden)
            {
                DeploymentMethods.warden.Select();
                DeploymentMethods.warden.Select();
            }

            foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.rageSpell, AllInOnePushDeploy.SecondRagePoint))
            {
                yield return(s);
            }

            foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.healSpell, AllInOnePushDeploy.SecondRagePoint))
            {
                yield return(s);
            }

            yield return(1000);

            foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.rageSpell, AllInOnePushDeploy.FirstHastePoint))
            {
                yield return(s);
            }

            foreach (var s in DeploymentMethods.DeploySpell(DeploymentMethods.hasteSpell, AllInOnePushDeploy.FirstHastePoint))
            {
                yield return(s);
            }



            // Start watching heroes
            if (DeploymentMethods.watchHeroes == true)
            {
                Deploy.WatchHeroes(DeploymentMethods.heroes);
            }

            if (DeploymentMethods.watchQueen == true)
            {
                Deploy.WatchHeroes(new List <DeployElement> {
                    DeploymentMethods.queen
                });
            }
        }
Example #3
0
        /// <summary>
        /// Set deploy points for troops and spells
        /// </summary>
        public static void SetDeployPoints()
        {
            var GreenPoints = AllInOnePushHelper.GenerateGreenPoints();
            var redPoints   = GameGrid.RedPoints
                              .Where(
                point =>
                !(point.X > 18 && point.Y > 18 || point.X > 18 && point.Y < -18 || point.X < -18 && point.Y > 18 ||
                  point.X < -18 && point.Y < -18))
                              .OrderBy(point => Math.Atan2(point.X, point.Y)).ToArray();

            AllPoints = GreenPoints.Concat(redPoints).ToArray();

            // Top right side
            var topRight = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.DeployExtents.MaxX, (float)GameGrid.MaxY - 2))).First();
            var rightTop = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.DeployExtents.MaxX, (float)GameGrid.MinY + 2))).First();

            // Bottom right side
            var rightBottom = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.MaxX - 5, (float)GameGrid.DeployExtents.MinY - 2))).First();
            var bottomRight = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.MinX + 10, (float)GameGrid.DeployExtents.MinY - 2))).First();

            // Bottom left side
            // Move 8 tiles from bottom corner due to unitsbar.
            var bottomLeft = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.DeployExtents.MinX, (float)GameGrid.MinY + 8))).First();
            var leftBottom = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.DeployExtents.MinX, (float)GameGrid.MaxY - 2))).First();

            // Top Left side
            var leftTop = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.MinX + 2, (float)GameGrid.DeployExtents.MaxY))).First();
            var topLeft = AllPoints.OrderBy(p => p.DistanceSq(new PointFT((float)GameGrid.MaxX - 2, (float)GameGrid.DeployExtents.MaxY))).First();

            var isJumpSpell = Deploy.GetTroops().ExtractOne(DeployId.Jump)?.Count > 0 ? true : false;


            if (AllInOnePushDeploy.Origin.X > AllInOnePushDeploy.Core.X)
            {
                Log.Info($"[{AllInOnePushDeploy.AttackName}] Attacking from the top right");

                AllInOnePushDeploy.AttackLine = new Tuple <PointFT, PointFT>(topRight, rightTop);

                var distance = Math.Abs(AllInOnePushDeploy.Origin.X) - Math.Abs(AllInOnePushDeploy.Target.X);
                var target   = distance >= AllInOnePushDeploy.MinDistace ? AllInOnePushDeploy.Target : AllInOnePushDeploy.Core;

                var firstWall = GetFirstWallForJump(AllInOnePushDeploy.Origin.Y, "Y");
                AllInOnePushDeploy.FirstJumpPoint = new PointFT(firstWall.X - 2.75f, AllInOnePushDeploy.Core.Y);

                var maxX  = isJumpSpell ? AllInOnePushDeploy.FirstJumpPoint.X - 5f : firstWall.X - 1.5f;
                var start = target.X + 4f;

                var earthQuakePoints = new List <PointFT> {
                    new PointFT(AllInOnePushDeploy.Target.X + 6f, AllInOnePushDeploy.Core.Y)
                };
                var jumpPoints = new List <PointFT> {
                    new PointFT(AllInOnePushDeploy.Target.X + 5.5f, AllInOnePushDeploy.Core.Y)
                };

                if (GetWallsInsideSpell(earthQuakePoints[0], 4f) < 8)
                {
                    while (maxX > start)
                    {
                        earthQuakePoints.Add(new PointFT(start, AllInOnePushDeploy.Core.Y));
                        jumpPoints.Add(new PointFT(start - 0.5f, AllInOnePushDeploy.Core.Y));
                        start += 0.25f;
                    }
                }

                AllInOnePushDeploy.EqPoint = earthQuakePoints.OrderByDescending(e => GetWallsInsideSpell(e)).FirstOrDefault();

                // Prevent overlaping EQ with jump
                if (isJumpSpell && AllInOnePushDeploy.FirstJumpPoint.X - AllInOnePushDeploy.EqPoint.X < 7f)
                {
                    AllInOnePushDeploy.EqPoint = new PointFT(AllInOnePushDeploy.FirstJumpPoint.X - 7f, AllInOnePushDeploy.FirstJumpPoint.Y);
                }
                AllInOnePushDeploy.SecondJumpPoint = new PointFT(AllInOnePushDeploy.EqPoint.X - 0.5f, AllInOnePushDeploy.EqPoint.Y);

                var shiftSpells = AllInOnePushDeploy.ShiftSpells;
                AllInOnePushDeploy.FirstRagePoint  = new PointFT(AllInOnePushDeploy.Origin.X - 11f - shiftSpells, AllInOnePushDeploy.Core.Y);
                AllInOnePushDeploy.FirstHealPoint  = new PointFT(AllInOnePushDeploy.Origin.X - 17f - shiftSpells, AllInOnePushDeploy.Core.Y);
                AllInOnePushDeploy.SecondRagePoint = new PointFT(AllInOnePushDeploy.Origin.X - 22f - shiftSpells, AllInOnePushDeploy.Core.Y);
                AllInOnePushDeploy.FirstHastePoint = new PointFT(AllInOnePushDeploy.Origin.X - 26f - shiftSpells, AllInOnePushDeploy.Core.Y);

                //try to find better funneling points
                var frac = 0.75f;

                AllInOnePushDeploy.FirstFunnellingPoint = new PointFT(AllInOnePushDeploy.Origin.X + frac *
                                                                      (AllInOnePushDeploy.AttackLine.Item1.X - AllInOnePushDeploy.Origin.X),
                                                                      AllInOnePushDeploy.Origin.Y + frac *
                                                                      (AllInOnePushDeploy.AttackLine.Item1.Y - AllInOnePushDeploy.Origin.Y));

                AllInOnePushDeploy.SecondFunnellingPoint = new PointFT(AllInOnePushDeploy.Origin.X + frac *
                                                                       (AllInOnePushDeploy.AttackLine.Item2.X - AllInOnePushDeploy.Origin.X),
                                                                       AllInOnePushDeploy.Origin.Y + frac *
                                                                       (AllInOnePushDeploy.AttackLine.Item2.Y - AllInOnePushDeploy.Origin.Y));

                AllInOnePushDeploy.FirstHasteLine = new Tuple <PointFT, PointFT>
                                                    (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X - 11f - shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X - 11f - shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                    );
                AllInOnePushDeploy.FirstRageLine = new Tuple <PointFT, PointFT>
                                                   (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X - 19f - shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X - 19f - shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                   );

                AllInOnePushDeploy.SecondHasteLine = new Tuple <PointFT, PointFT>
                                                     (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X - 24f - shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X - 24f - shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                     );
                AllInOnePushDeploy.SecondRageLine = new Tuple <PointFT, PointFT>
                                                    (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X - 24f - shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X - 24f - shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                    );

                AllInOnePushDeploy.QWHealer    = new PointFT(GameGrid.DeployExtents.MaxX, AllInOnePushDeploy.FirstFunnellingPoint.Y);
                AllInOnePushDeploy.QWRagePoint = new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X - 3, AllInOnePushDeploy.FirstFunnellingPoint.Y - 1);
                AllInOnePushDeploy.SecondFunnellingRagePoint = new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X - 3, AllInOnePushDeploy.SecondFunnellingPoint.Y + 1);
            }

            else if (AllInOnePushDeploy.Origin.X < AllInOnePushDeploy.Core.X)
            {
                Log.Info($"[{AllInOnePushDeploy.AttackName}] Attacking from the bottom left");

                AllInOnePushDeploy.AttackLine = new Tuple <PointFT, PointFT>(leftBottom, bottomLeft);

                var distance = Math.Abs(AllInOnePushDeploy.Origin.X) - Math.Abs(AllInOnePushDeploy.Target.X);
                var target   = distance >= AllInOnePushDeploy.MinDistace ? AllInOnePushDeploy.Target : AllInOnePushDeploy.Core;

                var firstWall = GetFirstWallForJump(AllInOnePushDeploy.Origin.Y, "Y");
                AllInOnePushDeploy.FirstJumpPoint = new PointFT(firstWall.X + 2.75f, AllInOnePushDeploy.Core.Y);

                var maxX  = isJumpSpell ? AllInOnePushDeploy.FirstJumpPoint.X + 5f : firstWall.X + 1.5f;
                var start = target.X - 4f;

                var earthQuakePoints = new List <PointFT> {
                    new PointFT(AllInOnePushDeploy.Target.X - 6f, AllInOnePushDeploy.Core.Y)
                };
                var jumpPoints = new List <PointFT> {
                    new PointFT(AllInOnePushDeploy.Target.X - 5.5f, AllInOnePushDeploy.Core.Y)
                };

                if (GetWallsInsideSpell(earthQuakePoints[0], 4f) < 8)
                {
                    while (maxX < start)
                    {
                        earthQuakePoints.Add(new PointFT(start, AllInOnePushDeploy.Core.Y));
                        jumpPoints.Add(new PointFT(start + 0.5f, AllInOnePushDeploy.Core.Y));
                        start -= 0.25f;
                    }
                }

                AllInOnePushDeploy.EqPoint = earthQuakePoints.OrderByDescending(e => GetWallsInsideSpell(e)).FirstOrDefault();

                // Prevent overlaping EQ with jump
                if (isJumpSpell && Math.Abs(AllInOnePushDeploy.FirstJumpPoint.X - AllInOnePushDeploy.EqPoint.X) < 7f)
                {
                    AllInOnePushDeploy.EqPoint = new PointFT(AllInOnePushDeploy.FirstJumpPoint.X + 7f, AllInOnePushDeploy.FirstJumpPoint.Y);
                }

                AllInOnePushDeploy.SecondJumpPoint = new PointFT(AllInOnePushDeploy.EqPoint.X + 0.5f, AllInOnePushDeploy.EqPoint.Y);

                var shiftSpells = AllInOnePushDeploy.ShiftSpells;
                AllInOnePushDeploy.FirstRagePoint  = new PointFT(AllInOnePushDeploy.Origin.X + 11f + shiftSpells, AllInOnePushDeploy.Core.Y);
                AllInOnePushDeploy.FirstHealPoint  = new PointFT(AllInOnePushDeploy.Origin.X + 17f + shiftSpells, AllInOnePushDeploy.Core.Y);
                AllInOnePushDeploy.SecondRagePoint = new PointFT(AllInOnePushDeploy.Origin.X + 22f + shiftSpells, AllInOnePushDeploy.Core.Y);
                AllInOnePushDeploy.FirstHastePoint = new PointFT(AllInOnePushDeploy.Origin.X + 26f + shiftSpells, AllInOnePushDeploy.Core.Y);

                //try to find better funneling points
                var frac = 0.75f;

                AllInOnePushDeploy.FirstFunnellingPoint = new PointFT(AllInOnePushDeploy.Origin.X + frac *
                                                                      (AllInOnePushDeploy.AttackLine.Item1.X - AllInOnePushDeploy.Origin.X),
                                                                      AllInOnePushDeploy.Origin.Y + frac *
                                                                      (AllInOnePushDeploy.AttackLine.Item1.Y - AllInOnePushDeploy.Origin.Y));

                AllInOnePushDeploy.SecondFunnellingPoint = bottomLeft;

                AllInOnePushDeploy.FirstHasteLine = new Tuple <PointFT, PointFT>
                                                    (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X + 11f + shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X + 11f + shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                    );

                AllInOnePushDeploy.FirstRageLine = new Tuple <PointFT, PointFT>
                                                   (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X + 19f + shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X + 19f + shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                   );

                AllInOnePushDeploy.SecondHasteLine = new Tuple <PointFT, PointFT>
                                                     (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X + 24f + shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X + 24f + shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                     );

                AllInOnePushDeploy.SecondRageLine = new Tuple <PointFT, PointFT>
                                                    (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X + 24f + shiftSpells, AllInOnePushDeploy.FirstFunnellingPoint.Y),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X + 24f + shiftSpells, AllInOnePushDeploy.SecondFunnellingPoint.Y)
                                                    );

                AllInOnePushDeploy.QWHealer    = new PointFT(GameGrid.DeployExtents.MinX, AllInOnePushDeploy.FirstFunnellingPoint.Y);
                AllInOnePushDeploy.QWRagePoint = new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X + 3, AllInOnePushDeploy.FirstFunnellingPoint.Y - 1);
                AllInOnePushDeploy.SecondFunnellingRagePoint = new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X + 3, AllInOnePushDeploy.SecondFunnellingPoint.Y + 1);
            }

            else if (AllInOnePushDeploy.Origin.Y > AllInOnePushDeploy.Core.Y)
            {
                Log.Info($"[{AllInOnePushDeploy.AttackName}] Attacking from the top left");

                AllInOnePushDeploy.AttackLine = new Tuple <PointFT, PointFT>(leftTop, topLeft);

                var distance = Math.Abs(AllInOnePushDeploy.Origin.Y) - Math.Abs(AllInOnePushDeploy.Target.Y);
                var target   = distance >= AllInOnePushDeploy.MinDistace ? AllInOnePushDeploy.Target : AllInOnePushDeploy.Core;

                var firstWall = GetFirstWallForJump(AllInOnePushDeploy.Origin.X, "X");
                AllInOnePushDeploy.FirstJumpPoint = new PointFT(AllInOnePushDeploy.Core.X, firstWall.Y - 2.75f);

                var maxX  = isJumpSpell ? AllInOnePushDeploy.FirstJumpPoint.Y - 5f : firstWall.Y - 1.5f;
                var start = target.Y + 4f;

                var earthQuakePoints = new List <PointFT> {
                    new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Target.Y + 6f)
                };
                var jumpPoints = new List <PointFT> {
                    new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Target.Y + 5.5f)
                };

                if (GetWallsInsideSpell(earthQuakePoints[0], 4f) < 8)
                {
                    while (maxX > start)
                    {
                        earthQuakePoints.Add(new PointFT(AllInOnePushDeploy.Core.X, start));
                        jumpPoints.Add(new PointFT(AllInOnePushDeploy.Core.X, start - 0.5f));
                        start += 0.25f;
                    }
                }

                AllInOnePushDeploy.EqPoint = earthQuakePoints.OrderByDescending(e => GetWallsInsideSpell(e)).FirstOrDefault();

                // Prevent overlaping EQ with jump
                if (isJumpSpell && AllInOnePushDeploy.FirstJumpPoint.Y - AllInOnePushDeploy.EqPoint.Y < 7f)
                {
                    AllInOnePushDeploy.EqPoint = new PointFT(AllInOnePushDeploy.FirstJumpPoint.X, AllInOnePushDeploy.FirstJumpPoint.Y - 7f);
                }
                AllInOnePushDeploy.SecondJumpPoint = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.EqPoint.Y - 0.5f);

                var shiftSpells = AllInOnePushDeploy.ShiftSpells;
                AllInOnePushDeploy.FirstRagePoint  = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y - 11f - shiftSpells);
                AllInOnePushDeploy.FirstHealPoint  = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y - 17f - shiftSpells);
                AllInOnePushDeploy.SecondRagePoint = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y - 22f - shiftSpells);
                AllInOnePushDeploy.FirstHastePoint = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y - 26f - shiftSpells);

                //try to find better funneling points
                var frac = 0.75f;

                AllInOnePushDeploy.FirstFunnellingPoint = new PointFT(AllInOnePushDeploy.Origin.X + frac *
                                                                      (AllInOnePushDeploy.AttackLine.Item1.X - AllInOnePushDeploy.Origin.X),
                                                                      AllInOnePushDeploy.Origin.Y + frac *
                                                                      (AllInOnePushDeploy.AttackLine.Item1.Y - AllInOnePushDeploy.Origin.Y));

                AllInOnePushDeploy.SecondFunnellingPoint = new PointFT(AllInOnePushDeploy.Origin.X + frac *
                                                                       (AllInOnePushDeploy.AttackLine.Item2.X - AllInOnePushDeploy.Origin.X),
                                                                       AllInOnePushDeploy.Origin.Y + frac *
                                                                       (AllInOnePushDeploy.AttackLine.Item2.Y - AllInOnePushDeploy.Origin.Y));

                AllInOnePushDeploy.FirstHasteLine = new Tuple <PointFT, PointFT>
                                                    (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y - 11f - shiftSpells),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y - 11f - shiftSpells)
                                                    );

                AllInOnePushDeploy.FirstRageLine = new Tuple <PointFT, PointFT>
                                                   (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y - 19f - shiftSpells),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y - 19f - shiftSpells)
                                                   );

                AllInOnePushDeploy.SecondHasteLine = new Tuple <PointFT, PointFT>
                                                     (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y - 24f - shiftSpells),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y - 24f - shiftSpells)
                                                     );

                AllInOnePushDeploy.SecondRageLine = new Tuple <PointFT, PointFT>
                                                    (
                    new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y - 24f - shiftSpells),
                    new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y - 24f - shiftSpells)
                                                    );

                AllInOnePushDeploy.QWHealer    = new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, GameGrid.DeployExtents.MaxY);
                AllInOnePushDeploy.QWRagePoint = new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X + 1, AllInOnePushDeploy.FirstFunnellingPoint.Y - 3);
                AllInOnePushDeploy.SecondFunnellingRagePoint = new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X - 1, AllInOnePushDeploy.SecondFunnellingPoint.Y - 3);
            }

            else // (orgin.Y < core.Y)
            {
                Log.Info($"[{AllInOnePushDeploy.AttackName}] Attacking from the bottom right");

                // Avoid bottom right side until fix zoom out on attack progress issue
                var avoidBottomRight = AllInOnePushDeploy.AvoidBottomRight;
                if (avoidBottomRight == 1)
                {
                    var originPoints = new[]
                    {
                        new PointFT(GameGrid.DeployExtents.MaxX, AllInOnePushDeploy.Core.Y),
                        new PointFT(GameGrid.DeployExtents.MinX, AllInOnePushDeploy.Core.Y),
                        new PointFT(AllInOnePushDeploy.Core.X, GameGrid.DeployExtents.MaxY),
                        new PointFT(AllInOnePushDeploy.Core.X, GameGrid.DeployExtents.MinY)
                    };
                    AllInOnePushDeploy.Origin = originPoints.OrderBy(point => point.DistanceSq(AllInOnePushDeploy.Target)).ElementAt(1);
                    Log.Warning($"Avoid bottom right side set to true, We will attack from next closest side to the target");

                    SetDeployPoints();
                }
                else
                {
                    AllInOnePushDeploy.AttackLine = new Tuple <PointFT, PointFT>(rightBottom, bottomRight);

                    var distance = Math.Abs(AllInOnePushDeploy.Origin.Y) - Math.Abs(AllInOnePushDeploy.Target.Y);
                    var target   = distance >= AllInOnePushDeploy.MinDistace ? AllInOnePushDeploy.Target : AllInOnePushDeploy.Core;

                    var firstWall = GetFirstWallForJump(AllInOnePushDeploy.Origin.X, "X");
                    AllInOnePushDeploy.FirstJumpPoint = new PointFT(AllInOnePushDeploy.Core.X, firstWall.Y + 2.75f);

                    var maxX  = isJumpSpell ? AllInOnePushDeploy.FirstJumpPoint.Y + 5f : firstWall.Y + 1.5f;
                    var start = target.Y - 4f;

                    var earthQuakePoints = new List <PointFT> {
                        new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Target.Y - 6f)
                    };
                    var jumpPoints = new List <PointFT> {
                        new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Target.Y - 5.5f)
                    };

                    if (GetWallsInsideSpell(earthQuakePoints[0], 4f) < 8)
                    {
                        while (maxX < start)
                        {
                            earthQuakePoints.Add(new PointFT(AllInOnePushDeploy.Core.X, start));
                            jumpPoints.Add(new PointFT(AllInOnePushDeploy.Core.X, start + 0.5f));
                            start -= 0.25f;
                        }
                    }

                    AllInOnePushDeploy.EqPoint = earthQuakePoints.OrderByDescending(e => GetWallsInsideSpell(e)).FirstOrDefault();

                    // Prevent overlaping EQ with jump
                    if (isJumpSpell && Math.Abs(AllInOnePushDeploy.FirstJumpPoint.Y - AllInOnePushDeploy.EqPoint.Y) < 7f)
                    {
                        AllInOnePushDeploy.EqPoint = new PointFT(AllInOnePushDeploy.FirstJumpPoint.X, AllInOnePushDeploy.FirstJumpPoint.Y + 7f);
                    }
                    AllInOnePushDeploy.SecondJumpPoint = new PointFT(AllInOnePushDeploy.EqPoint.X, AllInOnePushDeploy.EqPoint.Y + 0.5f);

                    var shiftSpells = AllInOnePushDeploy.ShiftSpells;
                    AllInOnePushDeploy.FirstRagePoint  = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y + 11f + shiftSpells);
                    AllInOnePushDeploy.FirstHealPoint  = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y + 17f + shiftSpells);
                    AllInOnePushDeploy.SecondRagePoint = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y + 22f + shiftSpells);
                    AllInOnePushDeploy.FirstHastePoint = new PointFT(AllInOnePushDeploy.Core.X, AllInOnePushDeploy.Origin.Y + 26f + shiftSpells);

                    // Set Funneling point
                    AllInOnePushDeploy.FirstFunnellingPoint  = rightBottom;
                    AllInOnePushDeploy.SecondFunnellingPoint = bottomRight;

                    AllInOnePushDeploy.FirstHasteLine = new Tuple <PointFT, PointFT>
                                                        (
                        new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y + 11f + shiftSpells),
                        new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y + 11f + shiftSpells)
                                                        );

                    AllInOnePushDeploy.FirstRageLine = new Tuple <PointFT, PointFT>
                                                       (
                        new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y + 19f + shiftSpells),
                        new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y + 19f + shiftSpells)
                                                       );

                    AllInOnePushDeploy.SecondHasteLine = new Tuple <PointFT, PointFT>
                                                         (
                        new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y + 24f + shiftSpells),
                        new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y + 24f + shiftSpells)
                                                         );

                    AllInOnePushDeploy.SecondRageLine = new Tuple <PointFT, PointFT>
                                                        (
                        new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, AllInOnePushDeploy.FirstFunnellingPoint.Y + 24f + shiftSpells),
                        new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X, AllInOnePushDeploy.SecondFunnellingPoint.Y + 24f + shiftSpells)
                                                        );

                    AllInOnePushDeploy.QWHealer    = new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X, GameGrid.DeployExtents.MinY);
                    AllInOnePushDeploy.QWRagePoint = new PointFT(AllInOnePushDeploy.FirstFunnellingPoint.X - 1, AllInOnePushDeploy.FirstFunnellingPoint.Y + 3);
                    AllInOnePushDeploy.SecondFunnellingRagePoint = new PointFT(AllInOnePushDeploy.SecondFunnellingPoint.X + 1, AllInOnePushDeploy.SecondFunnellingPoint.Y + 3);
                }
            }
            AllInOnePushDeploy.SecondJumpPoint = AllInOnePushDeploy.EqPoint;

            AllInOnePushDeploy.FirstFunnellingPoint  = AllPoints.OrderBy(p => p.DistanceSq(AllInOnePushDeploy.FirstFunnellingPoint)).First();
            AllInOnePushDeploy.SecondFunnellingPoint = AllPoints.OrderBy(p => p.DistanceSq(AllInOnePushDeploy.SecondFunnellingPoint)).First();
            AllInOnePushDeploy.Origin = AllPoints.OrderBy(p => p.DistanceSq(AllInOnePushDeploy.Origin)).First();

            DebugBottomRightSidePoints();
        }
Example #4
0
        public override IEnumerable <int> AttackRoutine()
        {
            Log.Info($"[{AttackName}] V{Version} Deploy start");

            // Get user settings
            ClanCastleSettings = GetCurrentSetting("use Clan Castle troops as");
            QWSettings         = GetCurrentSetting("Use Queen Walk");
            HealerOnQWSettings = GetCurrentSetting("Number of healers to use on Queen");
            RageOnQWSettings   = GetCurrentSetting("Drop 1 rage in the first of the QW");
            ShiftSpells        = GetCurrentSetting("Shift Spells In(+) and Out(-)");
            int customOrder = GetCurrentSetting("use custom deploy order");

            Debug = GetCurrentSetting("Debug Mode") == 1 ? true : false;

            // Set core point
            AllInOnePushHelper.SetCore();

            // Set the target
            var targetFromUserSettings = GetCurrentSetting("Select Your Target");

            foreach (var t in AllInOnePushHelper.SeTarget(targetFromUserSettings))
            {
                yield return(t);
            }

            // Set Origin
            var originPoints = new[]
            {
                new PointFT(GameGrid.DeployExtents.MaxX, Core.Y),
                new PointFT(GameGrid.DeployExtents.MinX, Core.Y),
                new PointFT(Core.X, GameGrid.DeployExtents.MaxY),
                new PointFT(Core.X, GameGrid.DeployExtents.MinY)
            };

            Origin = originPoints.OrderBy(point => point.DistanceSq(Target)).First();


            // Set deploy elements
            deployElements = Deploy.GetTroops(useCache: false);
            Log.Info($"[{AttackName}] Deployable Troops: " + ToUnitString(deployElements));

            // Check attack type (air or ground attack)
            AllInOnePushHelper.IsAirAttack();

            // Set deployment points
            AllInOnePushHelper.SetDeployPoints();

            // Set custom order list
            if (customOrder == 1)
            {
                CustomOrderList = new List <int>
                {
                    GetCurrentSetting("#1"),
                    GetCurrentSetting("#2"),
                    GetCurrentSetting("#3"),
                    GetCurrentSetting("#4"),
                    GetCurrentSetting("#5"),
                    GetCurrentSetting("#6")
                };
            }

            // Deploy troops
            if (!IsAirAttack)
            {
                Log.Info($"[{AttackName}] Ground attack start");
                foreach (var t in TroopsDeployment.GroundAttack(customOrder))
                {
                    yield return(t);
                }
            }
            else
            {
                Log.Info($"[{AttackName}] Air attack start");
                foreach (var t in TroopsDeployment.AirAttack(customOrder))
                {
                    yield return(t);
                }
            }

            yield break;
        }