Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        public Point2D GetCliffProxyLocation()
        {
            var numberOfCloseLocations = NumberOfCloseBaseLocations();
            var closeAirLocations      = BaseData.EnemyBaseLocations.Take(5).OrderBy(b => Vector2.DistanceSquared(new Vector2(TargetingData.EnemyMainBasePoint.X, TargetingData.EnemyMainBasePoint.Y), new Vector2(b.Location.X, b.Location.Y))).Take(numberOfCloseLocations);

            var baseLocation = closeAirLocations.OrderBy(b => PathFinder.GetGroundPath(TargetingData.EnemyMainBasePoint.X, TargetingData.EnemyMainBasePoint.Y, b.Location.X, b.Location.Y, 0).Count()).Last().Location;

            var angle    = Math.Atan2(TargetingData.EnemyMainBasePoint.Y - baseLocation.Y, baseLocation.X - TargetingData.EnemyMainBasePoint.X);
            var x        = 0 * Math.Cos(angle);
            var y        = 0 * Math.Sin(angle);
            var location = new Point2D {
                X = baseLocation.X + (float)x, Y = baseLocation.Y - (float)y
            };

            if (MapDataService.PathWalkable(location))
            {
                return(location);
            }
            return(baseLocation);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        bool StartWarping(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (!MapDataService.PathWalkable(commander.UnitCalculation.Unit.Pos))
            {
                return(false);
            }
            if (ActiveUnitData.Commanders.Values.Where(v => v.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPGATE && !v.UnitCalculation.Unit.IsActive && v.WarpInAlmostOffCooldown(frame, SharkyOptions.FramesPerSecond, SharkyUnitData)).Count() == 0)
            {
                return(false);
            }
            if (commander.UnitCalculation.Unit.Shield > 25 && !commander.UnitCalculation.NearbyAllies.Any(v => (v.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON || v.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISMPHASING) && DistanceSquared(commander.UnitCalculation, v) < 400)) // not near any pylons or other warping prisms
            {
                if (commander.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISM)
                {
                    action = commander.Order(frame, Abilities.MORPH_WARPPRISMPHASINGMODE, allowSpam: true);
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 5
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;

            UpdateLoadTimes(commander);

            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);
                    }
                }
            }

            // follow behind at the range of pickup
            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);
                    }
                }
            }

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

            var moveTo = GetPickupSpot(new Point2D {
                X = unitToSupport.Unit.Pos.X, Y = unitToSupport.Unit.Pos.Y
            }, defensivePoint);

            if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.UNLOADALLAT_WARPPRISM || o.AbilityId == (uint)Abilities.UNLOADUNIT_WARPPRISM) || !MapDataService.PathWalkable(moveTo)) // TODO: does this groundpathable thing work right?
            {
                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) && InRange(unitToSupport.Position, commander.UnitCalculation.Position, PickupRange))
            {
                //look at all units within pickup range, ordered by proximity to their closeest enemy
                // get average hp + shields of back
                // if unit is in front half weapon is off cooldown and (has below that hp + shields or could die in one hit) pick it up
                var friendliesInRange = commander.UnitCalculation.NearbyAllies.Where(u => !commander.UnitCalculation.Unit.Passengers.Any(p => p.Tag == u.Unit.Tag) && InRange(u.Position, commander.UnitCalculation.Position, PickupRange)).OrderBy(u => ClosestEnemyDistance(u));
                var frontHalf         = friendliesInRange.Take(friendliesInRange.Count() / 2);
                var backHalf          = friendliesInRange.Skip(friendliesInRange.Count() / 2);
                var backAverageHealth = backHalf.Sum(u => u.Unit.Health + u.Unit.Shield) / backHalf.Count();
                foreach (var friendly in frontHalf)
                {
                    if (commander.UnitCalculation.Unit.CargoSpaceMax - commander.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)friendly.Unit.UnitType))
                    {
                        if (ShouldLoadUnit(friendly, backAverageHealth, frame))
                        {
                            action = commander.Order(frame, Abilities.LOAD, null, friendly.Unit.Tag);
                            return(true);
                        }
                    }
                }

                if (friendliesInRange.Count() < 4)
                {
                    foreach (var friendly in friendliesInRange)
                    {
                        if (commander.UnitCalculation.Unit.CargoSpaceMax - commander.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)friendly.Unit.UnitType))
                        {
                            if (ShouldLoadUnit(friendly, friendly.Unit.Health + (friendly.Unit.ShieldMax / 2), frame))
                            {
                                if (friendly.Unit.WeaponCooldown > 0 && friendly.Unit.Shield < friendly.Unit.ShieldMax / 2)
                                {
                                    action = commander.Order(frame, Abilities.LOAD, null, friendly.Unit.Tag);
                                    return(true);
                                }
                            }
                        }
                    }
                }

                foreach (var friendly in friendliesInRange.Where(f => f.EnemiesInRangeOf.Count() > 0 && f.Range > 2).OrderBy(f => f.Unit.Shield).ThenBy(f => f.Unit.Health))
                {
                    if (commander.UnitCalculation.Unit.CargoSpaceMax - commander.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)friendly.Unit.UnitType))
                    {
                        if (friendly.Unit.WeaponCooldown > 0)
                        {
                            action = commander.Order(frame, Abilities.LOAD, null, friendly.Unit.Tag);
                            return(true);
                        }
                    }
                }

                StartWarping(commander, frame, out action);
                return(true);
            }
            else
            {
                // move to pickup the friendly closest to the enemy
                if (StopWarping(commander, frame, out action))
                {
                    return(true);
                }

                action = commander.Order(frame, Abilities.MOVE, moveTo);
                return(true);
            }
        }