예제 #1
0
        bool Revelation(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.UnitCalculation.Unit.Energy < 25 || !commander.AbilityOffCooldown(Abilities.EFFECT_ORACLEREVELATION, frame, SharkyOptions.FramesPerSecond, SharkyUnitData) || commander.UnitCalculation.Unit.BuffIds.Contains((uint)Buffs.ORACLEWEAPON))
            {
                return(false);
            }

            var cloackedPosition = CloakedInvader(commander);

            if (cloackedPosition != null)
            {
                action = commander.Order(frame, Abilities.EFFECT_ORACLEREVELATION, cloackedPosition);
                return(true);
            }

            if (commander.UnitCalculation.NearbyEnemies.Any(e => e.Unit.BuffIds.Contains((uint)Buffs.ORACLEREVELATION)))
            {
                return(false); // TODO: unless a unit is invisible
            }

            var revelationLocation = GetBestRevelationLocation(commander);

            if (revelationLocation != null)
            {
                action = commander.Order(frame, Abilities.EFFECT_ORACLEREVELATION, revelationLocation);
                return(true);
            }

            return(false);
        }
예제 #2
0
        List <SC2APIProtocol.Action> Attack(UnitCommander commander, int frame)
        {
            var existingAttackOrder = commander.UnitCalculation.Unit.Orders.Where(o => o.AbilityId == (uint)Abilities.ATTACK || o.AbilityId == (uint)Abilities.ATTACK_ATTACK).FirstOrDefault();

            var oneShotKills = commander.UnitCalculation.EnemiesInRange.Where(a => a.Unit.Health + a.Unit.Shield < 20);

            if (oneShotKills.Count() > 0)
            {
                if (existingAttackOrder != null)
                {
                    var existing = oneShotKills.FirstOrDefault(o => o.Unit.Tag == existingAttackOrder.TargetUnitTag);
                    if (existing != null)
                    {
                        return(new List <SC2APIProtocol.Action>());
                    }
                }

                commander.BestTarget = oneShotKills.OrderBy(o => o.Dps).FirstOrDefault();

                return(commander.Order(frame, Abilities.ATTACK, null, commander.BestTarget.Unit.Tag));
            }


            var bestDpsReduction = commander.UnitCalculation.NearbyEnemies.OrderByDescending(enemy => enemy.Dps / enemy.SimulatedHitpoints).ThenBy(u => Vector2.DistanceSquared(u.Position, commander.UnitCalculation.Position)).FirstOrDefault();

            if (bestDpsReduction != null)
            {
                return(commander.Order(frame, Abilities.ATTACK, null, bestDpsReduction.Unit.Tag));
            }

            return(null);
        }
예제 #3
0
        bool Feedback(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;
            if (commander.UnitCalculation.Unit.Energy < 50)
            {
                return(false);
            }

            var vector         = commander.UnitCalculation.Position;
            var enemiesInRange = commander.UnitCalculation.NearbyEnemies.Where(e => e.Unit.Energy > 1 && e.Unit.DisplayType == DisplayType.Visible && Vector2.DistanceSquared(e.Position, vector) < FeedbackRangeSquared).OrderByDescending(e => e.Unit.Energy);

            var oneShotKill = enemiesInRange.Where(e => e.Unit.Energy * .5 > e.Unit.Health + e.Unit.Shield).FirstOrDefault();

            if (oneShotKill != null)
            {
                action = commander.Order(frame, Abilities.EFFECT_FEEDBACK, null, oneShotKill.Unit.Tag);
                return(true);
            }
            var target = enemiesInRange.FirstOrDefault();

            if (target != null && target.Unit.Energy > 50)
            {
                action = commander.Order(frame, Abilities.EFFECT_FEEDBACK, null, target.Unit.Tag);
                return(true);
            }

            return(false);
        }
예제 #4
0
        List <SC2APIProtocol.Action> ChronoBoost(UnitCommander nexus, int frame)
        {
            if (nexus.UnitCalculation.Unit.Energy >= 50)
            {
                foreach (var upgrade in ChronoData.ChronodUpgrades)
                {
                    var upgradeData = SharkyUnitData.UpgradeData[upgrade];
                    var building    = ActiveUnitData.SelfUnits.Where(u => !u.Value.Unit.BuffIds.Contains((uint)Buffs.CHRONOBOOST) && upgradeData.ProducingUnits.Contains((UnitTypes)u.Value.Unit.UnitType) && u.Value.Unit.Orders.Any(o => o.AbilityId == (uint)upgradeData.Ability)).FirstOrDefault().Value;
                    if (building != null)
                    {
                        return(nexus.Order(frame, Abilities.CHRONOBOOST, null, building.Unit.Tag));
                    }
                }

                foreach (var unit in ChronoData.ChronodUnits)
                {
                    var trainingData = SharkyUnitData.TrainingData[unit];
                    var building     = ActiveUnitData.SelfUnits.Where(u => !u.Value.Unit.BuffIds.Contains((uint)Buffs.CHRONOBOOST) && trainingData.ProducingUnits.Contains((UnitTypes)u.Value.Unit.UnitType) && u.Value.Unit.Orders.Any(o => o.AbilityId == (uint)trainingData.Ability)).FirstOrDefault().Value;
                    if (building != null)
                    {
                        return(nexus.Order(frame, Abilities.CHRONOBOOST, null, building.Unit.Tag));
                    }
                }
            }

            return(null);
        }
        public override List <SC2APIProtocol.Action> Attack(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, int frame)
        {
            var enemyWorkers = commander.UnitCalculation.NearbyEnemies.Where(u => u.UnitClassifications.Contains(UnitClassification.Worker));

            if (enemyWorkers.Count() > 0)
            {
                // if any are building something
                var buildings = commander.UnitCalculation.NearbyEnemies.Where(u => u.Attributes.Contains(Attribute.Structure) && u.Unit.BuildProgress < 1);
                var builders  = enemyWorkers.Where(w => buildings.Any(b => Vector2.DistanceSquared(w.Position, b.Position) <= b.Unit.Radius + w.Unit.Radius)).OrderBy(w => w.Unit.Health);

                if (builders.Count() > 0) // TODO: if barracks almost finished build a pylon where the addon would go LUL
                {
                    return(commander.Order(frame, Abilities.ATTACK, null, builders.First().Unit.Tag));
                }

                var enemyWorker = enemyWorkers.OrderBy(e => e.Unit.Health).First();
                return(commander.Order(frame, Abilities.ATTACK, null, enemyWorker.Unit.Tag));
            }
            var enemyBuildings = commander.UnitCalculation.NearbyEnemies.Where(u => u.Attributes.Contains(Attribute.Structure)).OrderBy(b => b.Unit.Health);

            if (enemyBuildings.Count() > 0)
            {
                var pylon = enemyBuildings.Where(b => b.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON).FirstOrDefault();
                if (pylon != null)
                {
                    return(commander.Order(frame, Abilities.ATTACK, null, pylon.Unit.Tag));
                }
                return(commander.Order(frame, Abilities.ATTACK, null, enemyBuildings.First().Unit.Tag));
            }

            return(commander.Order(frame, Abilities.ATTACK, target));
        }
예제 #6
0
        bool UnloadUnits(UnitCommander commander, Point2D defensivePoint, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            // TODO: if already unloading all return false and it will unload as it moves?

            if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.UNLOADALLAT_WARPPRISM || o.AbilityId == (uint)Abilities.UNLOADUNIT_WARPPRISM))
            {
                // if a unit has been in there for more than a second, warp prism must be on unloadable ground, move to a new area then try again
                if (commander.LoadTimes.Any(l => l.Value > 100))
                {
                    action = commander.Order(frame, Abilities.MOVE, defensivePoint);
                }

                return(true);
            }

            if (!MapDataService.PathWalkable(commander.UnitCalculation.Unit.Pos))
            {
                return(false);
            }

            foreach (var passenger in commander.UnitCalculation.Unit.Passengers)
            {
                if (!commander.LoadTimes.ContainsKey(passenger.Tag))
                {
                    commander.LoadTimes[passenger.Tag] = frame;
                }

                // use LoadTimes to calculate weapon cooldown
                if (commander.UnitCalculation.Unit.Shield + commander.UnitCalculation.Unit.Health < 50 || passenger.Shield > 25) // unload any units that regained shields, or if warp prism dying
                {
                    action = commander.UnloadSpecificUnit(frame, Abilities.UNLOADUNIT_WARPPRISM, passenger.Tag);
                    return(true);
                }
                else
                {
                    if (!ActiveUnitData.SelfUnits.ContainsKey(passenger.Tag))
                    {
                        action = commander.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, null, commander.UnitCalculation.Unit.Tag);
                        return(true);
                    }
                    else
                    {
                        var weapon = ActiveUnitData.SelfUnits[passenger.Tag].Weapon;
                        if (weapon == null || (frame - commander.LoadTimes[passenger.Tag]) / SharkyOptions.FramesPerSecond > weapon.Speed) // unload any units ready to fire
                        {
                            action = commander.UnloadSpecificUnit(frame, Abilities.UNLOADUNIT_WARPPRISM, passenger.Tag);
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
예제 #7
0
        bool NavigateToSupportUnit(UnitCommander commander, Point2D target, int frame, out List <SC2APIProtocol.Action> action)
        {
            if (MapDataService.PathWalkable(commander.UnitCalculation.Unit.Pos))                                                                                // if it is in unplaceable terrain, can't unload
            {
                if (commander.UnitCalculation.Unit.Shield + commander.UnitCalculation.Unit.Health < 50 || commander.UnitCalculation.EnemiesInRangeOf.Count > 0) // if warp prism dying or enemies nearby unload
                {
                    action = commander.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, null, commander.UnitCalculation.Unit.Tag);
                    return(true);
                }

                foreach (var passenger in commander.UnitCalculation.Unit.Passengers)
                {
                    var passengerUnit = ActiveUnitData.Commanders[passenger.Tag].UnitCalculation.Unit;
                    var unit          = ActiveUnitData.Commanders[passenger.Tag].UnitCalculation;

                    foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
                    {
                        if (DamageService.CanDamage(unit, enemyAttack) && InRange(commander.UnitCalculation.Position, enemyAttack.Position, unit.Range + passengerUnit.Radius + enemyAttack.Unit.Radius) && MapDataService.MapHeight(commander.UnitCalculation.Unit.Pos) == MapDataService.MapHeight(enemyAttack.Unit.Pos))
                        {
                            if (!enemyAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) && !InRange(commander.UnitCalculation.Position, enemyAttack.Position, 2 + passengerUnit.Radius + enemyAttack.Unit.Radius))
                            {
                                continue;
                            }
                            // if an enemy is in range drop the unit
                            //action = commander.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, null, commander.UnitCalculation.Unit.Tag); // TODO: dropping a specific unit not working, can only drop all, change it if they ever fix the api
                            action = commander.UnloadSpecificUnit(frame, Abilities.UNLOADUNIT_WARPPRISM, passenger.Tag);
                            return(true);
                        }
                    }
                }

                if (InRange(new Vector2(target.X, target.Y), commander.UnitCalculation.Position, 3)) // if made it to the target just drop
                {
                    action = commander.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, null, commander.UnitCalculation.Unit.Tag);
                    return(true);
                }
            }

            if (commander.UnitCalculation.Unit.CargoSpaceMax > commander.UnitCalculation.Unit.CargoSpaceTaken && commander.UnitCalculation.Unit.Shield + commander.UnitCalculation.Unit.Health > 50) // find more units to load
            {
                var friendly = commander.UnitCalculation.NearbyAllies.Where(u => !u.Unit.IsFlying && u.Unit.BuildProgress == 1 && u.UnitClassifications.Contains(UnitClassification.ArmyUnit) && !commander.UnitCalculation.Unit.Passengers.Any(p => p.Tag == u.Unit.Tag) && commander.UnitCalculation.Unit.CargoSpaceMax - commander.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)u.Unit.UnitType) && u.EnemiesInRange.Count == 0 && u.EnemiesInRangeOf.Count == 0).OrderBy(u => Vector2.DistanceSquared(commander.UnitCalculation.Position, u.Position)).FirstOrDefault();

                if (friendly != null)
                {
                    action = commander.Order(frame, Abilities.LOAD, null, friendly.Unit.Tag);
                    return(true);
                }
            }

            action = commander.Order(frame, Abilities.MOVE, target);
            return(true);
        }
예제 #8
0
        protected override bool OffensiveAbility(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.EFFECT_KD8CHARGE))
            {
                return(true);
            }

            if (commander.UnitCalculation.NearbyAllies.Any(a => a.Unit.UnitType == (uint)UnitTypes.TERRAN_KD8CHARGE))
            {
                return(false);
            }                                                                                                                            // don't spam them all at once

            if (bestTarget != null && bestTarget.Unit.Tag != commander.UnitCalculation.Unit.Tag && bestTarget.FrameLastSeen == frame && !bestTarget.Attributes.Contains(Attribute.Structure) && commander.AbilityOffCooldown(Abilities.EFFECT_KD8CHARGE, frame, SharkyOptions.FramesPerSecond, SharkyUnitData))
            {
                var distanceSqaured = Vector2.DistanceSquared(commander.UnitCalculation.Position, bestTarget.Position); // TODO: use unit velocity to predict where to place the charge and check if in range of that

                if (distanceSqaured <= 100)
                {
                    var enemyPosition = new Point2D {
                        X = bestTarget.Unit.Pos.X, Y = bestTarget.Unit.Pos.Y
                    };
                    if (bestTarget.Velocity > 0)
                    {
                        var futurePosition = bestTarget.Position + (bestTarget.AverageVector * (bestTarget.AverageVelocity * SharkyOptions.FramesPerSecond));
                        if (Vector2.DistanceSquared(commander.UnitCalculation.Position, futurePosition) < Kd8Charge * Kd8Charge)
                        {
                            var interceptionPoint = new Point2D {
                                X = futurePosition.X, Y = futurePosition.Y
                            };
                            action = commander.Order(frame, Abilities.EFFECT_KD8CHARGE, interceptionPoint);
                            return(true);
                        }
                    }
                    else if (distanceSqaured < Kd8Charge * Kd8Charge)
                    {
                        var point = new Point2D {
                            X = bestTarget.Position.X, Y = bestTarget.Position.Y
                        };
                        action = commander.Order(frame, Abilities.EFFECT_KD8CHARGE, point);
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #9
0
        protected override bool MaintainRange(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            var range          = 9f;
            var enemiesInRange = new List <UnitCalculation>();

            foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
            {
                if (DamageService.CanDamage(enemyAttack, commander.UnitCalculation) && InRange(commander.UnitCalculation.Position, enemyAttack.Position, range + commander.UnitCalculation.Unit.Radius + enemyAttack.Unit.Radius))
                {
                    enemiesInRange.Add(enemyAttack);
                }
            }

            var closestEnemy = enemiesInRange.OrderBy(u => Vector2.DistanceSquared(u.Position, commander.UnitCalculation.Position)).FirstOrDefault();

            if (closestEnemy == null)
            {
                return(false);
            }

            var avoidPoint = GetPositionFromRange(commander, closestEnemy.Unit.Pos, commander.UnitCalculation.Unit.Pos, range + commander.UnitCalculation.Unit.Radius + closestEnemy.Unit.Radius);

            action = commander.Order(frame, Abilities.MOVE, avoidPoint);
            return(true);
        }
예제 #10
0
        public override List <SC2APIProtocol.Action> HarassWorkers(UnitCommander commander, Point2D target, Point2D defensivePoint, int frame)
        {
            List <SC2APIProtocol.Action> action = null;

            var formation  = GetDesiredFormation(commander);
            var bestTarget = GetBestHarassTarget(commander, target);

            if (PulsarBeam(commander, frame, bestTarget, out action))
            {
                return(action);
            }

            if (WeaponReady(commander))
            {
                if (AttackBestTarget(commander, target, defensivePoint, null, bestTarget, frame, out action))
                {
                    return(action);
                }
            }

            return(NavigateToPoint(commander, target, defensivePoint, null, frame));

            if (Move(commander, target, defensivePoint, null, bestTarget, formation, frame, out action))
            {
                return(action);
            }

            return(commander.Order(frame, Abilities.MOVE, target));
        }
예제 #11
0
        protected override bool OffensiveAbility(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.AbilityOffCooldown(Abilities.EFFECT_VOIDRAYPRISMATICALIGNMENT, frame, SharkyOptions.FramesPerSecond, SharkyUnitData))
            {
                if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.ATTACK || o.AbilityId == (uint)Abilities.ATTACK_ATTACK))
                {
                    foreach (var tag in commander.UnitCalculation.Unit.Orders.Select(o => o.TargetUnitTag))
                    {
                        UnitCalculation unit;
                        if (ActiveUnitData.EnemyUnits.TryGetValue(tag, out unit))
                        {
                            if (unit.Attributes.Contains(Attribute.Armored))
                            {
                                if (commander.UnitCalculation.EnemiesInRange.Where(e => e.Attributes.Contains(Attribute.Armored)).Sum(e => e.Unit.Health) > 200)
                                {
                                    action = commander.Order(frame, Abilities.EFFECT_VOIDRAYPRISMATICALIGNMENT);
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #12
0
        protected override bool AttackBestTarget(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            if (AttackBestTargetInRange(commander, target, bestTarget, frame, out action))
            {
                return(true);
            }

            if (!commander.UnitCalculation.TargetPriorityCalculation.Overwhelm && MicroPriority != MicroPriority.AttackForward && commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.Retreat)
            {
                action = commander.Order(frame, Abilities.MOVE, defensivePoint); // no damaging targets in range, retreat towards the defense point
                return(true);
            }

            if (bestTarget != null && commander.UnitCalculation.NearbyEnemies.Any(e => e.Unit.Tag == bestTarget.Unit.Tag) && MicroPriority != MicroPriority.NavigateToLocation)
            {
                action = commander.Order(frame, Abilities.MOVE, GetPositionFromRange(commander, bestTarget.Unit.Pos, commander.UnitCalculation.Unit.Pos, commander.UnitCalculation.Range));
                return(true);
            }

            if (GroupUpEnabled && GroupUp(commander, target, groupCenter, true, frame, out action))
            {
                return(true);
            }

            if (bestTarget != null && MicroPriority != MicroPriority.NavigateToLocation)
            {
                action = commander.Order(frame, Abilities.MOVE, GetPositionFromRange(commander, bestTarget.Unit.Pos, commander.UnitCalculation.Unit.Pos, commander.UnitCalculation.Range));
                return(true);
            }

            var vectors = commander.UnitCalculation.NearbyAllies.Where(a => (!a.Unit.IsFlying && !commander.UnitCalculation.Unit.IsFlying) || (a.Unit.IsFlying && commander.UnitCalculation.Unit.IsFlying)).Select(u => u.Position);

            if (vectors.Count() > 0)
            {
                var center = new Point2D {
                    X = vectors.Average(v => v.X), Y = vectors.Average(v => v.Y)
                };
                if (Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(center.X, center.Y)) + commander.UnitCalculation.Unit.Radius > 1)
                {
                    action = commander.Order(frame, Abilities.MOVE, center);
                    return(true);
                }
            }

            action = commander.Order(frame, Abilities.ATTACK, target);
            return(true);
        }
예제 #13
0
        public bool SupportArmy(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, int frame, out List <SC2APIProtocol.Action> action, IEnumerable <UnitCalculation> supportableUnits = null)
        {
            action = null;

            if (commander.UnitCalculation.Unit.Shield < commander.UnitCalculation.Unit.ShieldMax / 2)
            {
                if (AvoidTargettedDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(true);
                }

                if (AvoidDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(true);
                }

                if (commander.UnitCalculation.Unit.Shield < 1)
                {
                    if (Retreat(commander, target, defensivePoint, frame, out action))
                    {
                        return(true);
                    }
                }
            }

            var unitToSupport = GetSupportTarget(commander, target, defensivePoint, supportableUnits);

            if (unitToSupport == null)
            {
                return(false);
            }

            if (!commander.UnitCalculation.NearbyAllies.Any(a => a.Unit.Tag == unitToSupport.Unit.Tag))
            {
                if (Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(target.X, target.Y)) > Vector2.DistanceSquared(unitToSupport.Position, new Vector2(target.X, target.Y)))
                {
                    if (NavigateToSupportUnit(commander, target, frame, out action))
                    {
                        return(true);
                    }
                }
            }

            var moveTo = new Point2D {
                X = unitToSupport.Unit.Pos.X, Y = unitToSupport.Unit.Pos.Y
            };

            if (!InRange(new Vector2(moveTo.X, moveTo.Y), commander.UnitCalculation.Position, 2))
            {
                action = commander.Order(frame, Abilities.MOVE, moveTo);
                return(true);
            }

            return(false);
        }
        private bool PurificationNova(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;
            var attacks = new List <UnitCalculation>();
            var center  = commander.UnitCalculation.Position;

            foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
            {
                if (!enemyAttack.Unit.IsFlying && InRange(enemyAttack.Position, commander.UnitCalculation.Position, ((PurificationNovaSpeed / SharkyOptions.FramesPerSecond) * commander.UnitCalculation.Unit.BuffDurationRemain) + 3f + enemyAttack.Unit.Radius + commander.UnitCalculation.Unit.Radius)) // TODO: do actual pathing to see if the shot can make it there, if a wall is in the way it can't
                {
                    attacks.Add(enemyAttack);
                }
            }

            if (attacks.Count > 0)
            {
                var oneShotKills = attacks.OrderBy(a => GetPurificationNovaDamage(a.Unit, SharkyUnitData.UnitData[(UnitTypes)a.Unit.UnitType])).ThenByDescending(u => u.Dps);
                if (oneShotKills.Count() > 0)
                {
                    var bestAttack = GetBestAttack(commander.UnitCalculation, oneShotKills, attacks);
                    if (commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.WinAir)
                    {
                        var airAttackers = oneShotKills.Where(u => u.DamageAir);
                        if (airAttackers.Count() > 0)
                        {
                            var air = GetBestAttack(commander.UnitCalculation, airAttackers, attacks);
                            if (air != null)
                            {
                                bestAttack = air;
                            }
                        }
                    }
                    else if (commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.WinGround)
                    {
                        var groundAttackers = oneShotKills.Where(u => u.DamageGround);
                        if (groundAttackers.Count() > 0)
                        {
                            var ground = GetBestAttack(commander.UnitCalculation, groundAttackers, attacks);
                            if (ground != null)
                            {
                                bestAttack = ground;
                            }
                        }
                    }

                    if (bestAttack != null)
                    {
                        action = commander.Order(frame, Abilities.MOVE, bestAttack);
                        return(true);
                    }
                }
            }

            return(AvoidFriendlyFire(commander, frame, out action));
        }
예제 #15
0
        protected override bool PreOffenseOrder(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.AbilityOffCooldown(Abilities.EFFECT_ADEPTPHASESHIFT, frame, SharkyOptions.FramesPerSecond, SharkyUnitData))
            {
                action = commander.Order(frame, Abilities.EFFECT_ADEPTPHASESHIFT, target);
                return(true);
            }

            return(false);
        }
예제 #16
0
 public override List <SC2APIProtocol.Action> Retreat(UnitCommander commander, Point2D defensivePoint, Point2D groupCenter, int frame)
 {
     if (commander.UnitCalculation.Unit.BuffIds.Contains((uint)Buffs.VOIDRAYSWARMDAMAGEBOOST))
     {
         var action = commander.Order(frame, Abilities.CANCEL);
         if (action != null)
         {
             return(action);
         }
     }
     return(base.Retreat(commander, defensivePoint, groupCenter, frame));
 }
예제 #17
0
        protected override bool AttackBestTargetInRange(UnitCommander commander, Point2D target, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;
            if (bestTarget != null)
            {
                if (commander.UnitCalculation.EnemiesInRange.Any(e => e.Unit.Tag == bestTarget.Unit.Tag) && bestTarget.Unit.DisplayType == DisplayType.Visible)
                {
                    action = commander.Order(frame, Abilities.ATTACK, null, bestTarget.Unit.Tag);
                    return(true);
                }

                var blinkReady = SharkyUnitData.ResearchedUpgrades.Contains((uint)Upgrades.BLINKTECH) && commander.AbilityOffCooldown(Abilities.EFFECT_BLINK_STALKER, frame, SharkyOptions.FramesPerSecond, SharkyUnitData);
                if (blinkReady)
                {
                    action = commander.Order(frame, Abilities.EFFECT_BLINK_STALKER, new Point2D {
                        X = bestTarget.Unit.Pos.X, Y = bestTarget.Unit.Pos.Y
                    });
                    return(true);
                }
            }

            return(false);
        }
예제 #18
0
        protected override bool AttackBestTargetInRange(UnitCommander commander, Point2D target, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;
            if (bestTarget != null && (bestTarget.UnitClassifications.Contains(UnitClassification.Worker) || !commander.UnitCalculation.NearbyEnemies.Any(e => e.UnitClassifications.Contains(UnitClassification.Worker))))
            {
                if (commander.UnitCalculation.EnemiesInRange.Any(e => e.Unit.Tag == bestTarget.Unit.Tag) && bestTarget.Unit.DisplayType == DisplayType.Visible)
                {
                    action = commander.Order(frame, Abilities.ATTACK, null, bestTarget.Unit.Tag);
                    return(true);
                }
            }

            return(false);
        }
        private bool AvoidFriendlyFire(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            var closest = commander.UnitCalculation.NearbyAllies.OrderBy(a => Vector2.DistanceSquared(a.Position, commander.UnitCalculation.Position)).FirstOrDefault();

            if (closest != null)
            {
                var avoidPoint = GetPositionFromRange(commander, closest.Unit.Pos, commander.UnitCalculation.Unit.Pos, 3f + commander.UnitCalculation.Unit.Radius + closest.Unit.Radius + .5f);
                action = commander.Order(frame, Abilities.MOVE, avoidPoint);
                return(true);
            }
            return(false);
        }
예제 #20
0
        List <SC2APIProtocol.Action> Scan(UnitCommander orbital, int frame)
        {
            if (orbital.UnitCalculation.Unit.Energy >= 50)
            {
                var undetectedEnemy = ActiveUnitData.EnemyUnits.Where(e => e.Value.Unit.DisplayType == DisplayType.Hidden).OrderByDescending(e => e.Value.EnemiesInRangeOf.Count()).FirstOrDefault();
                if (undetectedEnemy.Value != null && undetectedEnemy.Value.EnemiesInRangeOf.Count() > 0)
                {
                    return(orbital.Order(frame, Abilities.EFFECT_SCAN, new Point2D {
                        X = undetectedEnemy.Value.Position.X, Y = undetectedEnemy.Value.Position.Y
                    }));
                }
            }

            return(null);
        }
예제 #21
0
        bool StopWarping(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISMPHASING)
            {
                if (commander.UnitCalculation.NearbyAllies.Any(v => v.Unit.BuildProgress < 1 && Vector2.DistanceSquared(v.Position, commander.UnitCalculation.Position) < 49)) // and not warping any units in
                {
                    return(false);
                }
                action = commander.Order(frame, Abilities.MORPH_WARPPRISMTRANSPORTMODE);
                return(true);
            }
            return(false);
        }
예제 #22
0
        bool Hallucinate(UnitCommander commander, int frame, out List<SC2APIProtocol.Action> action)
        {
            action = null;
            if (commander.UnitCalculation.Unit.Energy < 75)
            {
                return false;
            }

            if (commander.UnitCalculation.NearbyEnemies.Count(e => e.UnitClassifications.Contains(UnitClassification.ArmyUnit)) > 3 && !commander.UnitCalculation.NearbyEnemies.Any(e => e.UnitClassifications.Contains(UnitClassification.Detector)))
            {
                action = commander.Order(frame, Abilities.HALLUCINATION_ARCHON);
                return true;
            }
            return false;
        }
예제 #23
0
        List <SC2APIProtocol.Action> Overcharge(UnitCommander nexus, int frame)
        {
            if (nexus.UnitCalculation.Unit.Energy >= 50)
            {
                foreach (var shieldBattery in nexus.UnitCalculation.NearbyAllies.Where(u => u.Unit.UnitType == (uint)UnitTypes.PROTOSS_SHIELDBATTERY && u.Unit.BuildProgress == 1 && Vector2.DistanceSquared(nexus.UnitCalculation.Position, u.Position) < OverchargeRangeSquared).OrderBy(u => u.Unit.Energy))
                {
                    if (shieldBattery.NearbyAllies.Any(a => a.EnemiesInRangeOf.Count() > 0 && a.Unit.Shield < 5 && Vector2.DistanceSquared(shieldBattery.Position, a.Position) < RestoreRangeSquared))
                    {
                        return(nexus.Order(frame, Abilities.BATTERYOVERCHARGE, null, shieldBattery.Unit.Tag));
                    }
                }
            }

            return(null);
        }
예제 #24
0
        bool GuardianShield(UnitCommander commander, int frame, out List<SC2APIProtocol.Action> action)
        {
            action = null;
            if (commander.UnitCalculation.Unit.BuffIds.Contains((uint)Buffs.GUARDIANSHIELD) || commander.UnitCalculation.Unit.Energy < 75)
            {
                return false;
            }

            if (commander.UnitCalculation.EnemiesInRangeOf.Count(e => e.Range > 1) > 3)
            {
                action = commander.Order(frame, Abilities.EFFECT_GUARDIANSHIELD);
                return true;
            }
            return false;
        }
예제 #25
0
        List <SC2APIProtocol.Action> Mule(UnitCommander orbital, int frame)
        {
            if (orbital.UnitCalculation.Unit.Energy >= 50 && !EnemyData.EnemyStrategies["InvisibleAttacks"].Detected || orbital.UnitCalculation.Unit.Energy > 95)
            {
                foreach (var baseLocation in BaseData.SelfBases.Where(b => b.ResourceCenter.BuildProgress == 1 && b.MineralFields.Count() > 0))
                {
                    var baseVector   = new Vector2(baseLocation.Location.X, baseLocation.Location.Y);
                    var mineralPatch = baseLocation.MineralFields.OrderByDescending(m => Vector2.DistanceSquared(new Vector2(m.Pos.X, m.Pos.Y), baseVector)).ThenByDescending(m => m.MineralContents).FirstOrDefault();
                    if (mineralPatch != null)
                    {
                        return(orbital.Order(frame, Abilities.EFFECT_CALLDOWNMULE, targetTag: mineralPatch.Tag));
                    }
                }
            }

            return(null);
        }
예제 #26
0
        bool DeactivatePulsarBeam(UnitCommander commander, int frame, UnitCalculation bestTarget, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (!commander.UnitCalculation.Unit.BuffIds.Contains((uint)Buffs.ORACLEWEAPON))
            {
                return(false);
            }

            if (bestTarget == null || !commander.UnitCalculation.NearbyEnemies.Any(e => e.Unit.Tag == bestTarget.Unit.Tag))
            {
                action = commander.Order(frame, Abilities.BEHAVIOR_PULSARBEAMOFF);
                return(true);
            }

            return(false);
        }
예제 #27
0
        private List <SC2APIProtocol.Action> OrderWarpPrism(UnitCommander warpPrism, IEnumerable <UnitCommander> droppedAttackers, IEnumerable <UnitCommander> unDroppedAttackers, int frame)
        {
            var readyForPickup = unDroppedAttackers.Where(c => !warpPrism.UnitCalculation.Unit.Passengers.Any(p => p.Tag == c.UnitCalculation.Unit.Tag) && Vector2.DistanceSquared(c.UnitCalculation.Position, new Vector2(LoadingLocation.X, LoadingLocation.Y)) < 10);

            foreach (var pickup in readyForPickup)
            {
                if (warpPrism.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISMPHASING)
                {
                    return(warpPrism.Order(frame, Abilities.MORPH_WARPPRISMTRANSPORTMODE));
                }

                if (warpPrism.UnitCalculation.Unit.CargoSpaceMax - warpPrism.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)pickup.UnitCalculation.Unit.UnitType) && !warpPrism.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.UNLOADALLAT_WARPPRISM))
                {
                    if (Vector2.DistanceSquared(warpPrism.UnitCalculation.Position, new Vector2(LoadingLocation.X, LoadingLocation.Y)) < PickupRangeSquared)
                    {
                        return(warpPrism.Order(frame, Abilities.LOAD, null, pickup.UnitCalculation.Unit.Tag));
                    }
                    else
                    {
                        return(warpPrism.Order(frame, Abilities.MOVE, LoadingLocation));
                    }
                }
            }

            if (warpPrism.UnitCalculation.Unit.Passengers.Count() > 0)
            {
                if (AreaService.InArea(warpPrism.UnitCalculation.Unit.Pos, DropArea))
                {
                    return(warpPrism.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, null, warpPrism.UnitCalculation.Unit.Tag));
                }
                else
                {
                    return(warpPrism.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, DropLocation));
                }
            }

            if (droppedAttackers.Count() > 0)
            {
                List <SC2APIProtocol.Action> action = null;
                WarpPrismMicroController.SupportArmy(warpPrism, TargetLocation, DropLocation, null, frame, out action, droppedAttackers.Select(c => c.UnitCalculation));
                return(action);
            }

            if (unDroppedAttackers.Count() > 0)
            {
                List <SC2APIProtocol.Action> action = null;
                WarpPrismMicroController.SupportArmy(warpPrism, TargetLocation, DefensiveLocation, null, frame, out action, unDroppedAttackers.Select(c => c.UnitCalculation));
                return(action);
            }

            return(warpPrism.Order(frame, Abilities.MOVE, DefensiveLocation));
        }
예제 #28
0
        protected override bool AvoidDamage(UnitCommander commander, Point2D target, Point2D defensivePoint, int frame, out List <SC2APIProtocol.Action> action) // TODO: use unit speed to dynamically adjust AvoidDamageDistance
        {
            action = null;

            var blinkReady = SharkyUnitData.ResearchedUpgrades.Contains((uint)Upgrades.BLINKTECH) && commander.AbilityOffCooldown(Abilities.EFFECT_BLINK_STALKER, frame, SharkyOptions.FramesPerSecond, SharkyUnitData);

            if (blinkReady && commander.UnitCalculation.Unit.Shield < 10)
            {
                var attacks = new List <UnitCalculation>();

                foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
                {
                    if (DamageService.CanDamage(enemyAttack, commander.UnitCalculation) && InRange(commander.UnitCalculation.Position, enemyAttack.Position, UnitDataService.GetRange(enemyAttack.Unit) + commander.UnitCalculation.Unit.Radius + enemyAttack.Unit.Radius + AvoidDamageDistance))
                    {
                        attacks.Add(enemyAttack);
                    }
                }

                if (attacks.Count > 0)
                {
                    var attack = attacks.OrderBy(e => (e.Range * e.Range) - Vector2.DistanceSquared(commander.UnitCalculation.Position, e.Position)).FirstOrDefault();  // enemies that are closest to being outranged
                    var range  = UnitDataService.GetRange(attack.Unit);
                    if (attack.Range > range)
                    {
                        range = attack.Range;
                    }

                    var avoidPoint = GetGroundAvoidPoint(commander, commander.UnitCalculation.Unit.Pos, attack.Unit.Pos, target, defensivePoint, attack.Range + attack.Unit.Radius + commander.UnitCalculation.Unit.Radius + AvoidDamageDistance);
                    action = commander.Order(frame, Abilities.EFFECT_BLINK_STALKER, avoidPoint);
                    return(true);
                }

                if (MaintainRange(commander, frame, out action))
                {
                    return(true);
                }

                return(false);
            }

            return(base.AvoidDamage(commander, target, defensivePoint, frame, out action));
        }
예제 #29
0
 protected override bool RechargeShieldsAtBattery(UnitCommander commander, Point2D target, Point2D defensivePoint, int frame, out List <SC2APIProtocol.Action> action)
 {
     action = null;
     if (commander.UnitCalculation.Unit.ShieldMax > 0 && commander.UnitCalculation.Unit.Shield < 25)
     {
         var shieldBatttery = ActiveUnitData.SelfUnits.Where(a => a.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_SHIELDBATTERY && a.Value.Unit.BuildProgress == 1 && a.Value.Unit.Energy > 5 && a.Value.Unit.Orders.Count() == 0).OrderBy(a => Vector2.DistanceSquared(commander.UnitCalculation.Position, a.Value.Position)).FirstOrDefault().Value;
         if (shieldBatttery != null)
         {
             var distanceSquared = Vector2.DistanceSquared(commander.UnitCalculation.Position, shieldBatttery.Position);
             if (distanceSquared > 35 && distanceSquared < 2500)
             {
                 action = commander.Order(frame, Abilities.MOVE, new Point2D {
                     X = shieldBatttery.Position.X, Y = shieldBatttery.Position.Y
                 });
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #30
0
        protected override bool AvoidTargettedDamage(UnitCommander commander, Point2D target, Point2D defensivePoint, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            var blinkReady = SharkyUnitData.ResearchedUpgrades.Contains((uint)Upgrades.BLINKTECH) && commander.AbilityOffCooldown(Abilities.EFFECT_BLINK_STALKER, frame, SharkyOptions.FramesPerSecond, SharkyUnitData);

            if (blinkReady)
            {
                var attack = commander.UnitCalculation.Attackers.OrderBy(e => (e.Range * e.Range) - Vector2.DistanceSquared(commander.UnitCalculation.Position, e.Position)).FirstOrDefault();
                if (attack != null)
                {
                    var avoidPoint = GetGroundAvoidPoint(commander, commander.UnitCalculation.Unit.Pos, attack.Unit.Pos, target, defensivePoint, attack.Range + attack.Unit.Radius + commander.UnitCalculation.Unit.Radius + AvoidDamageDistance);
                    action = commander.Order(frame, Abilities.EFFECT_BLINK_STALKER, avoidPoint);
                    return(true);
                }
                return(false);
            }

            return(base.AvoidTargettedDamage(commander, target, defensivePoint, frame, out action));
        }