Point2D GetBestTimeWarpLocation(IOrderedEnumerable <KeyValuePair <Point, float> > locations)
        {
            foreach (var location in locations)
            {
                if (location.Value < 150)
                {
                    return(null);
                }

                var placement = new Point2D {
                    X = location.Key.X, Y = location.Key.Y
                };
                bool good = true;
                if (!MapDataService.SelfVisible(placement))
                {
                    continue;
                }

                if (good)
                {
                    return(placement);
                }
            }
            return(null);
        }
Beispiel #2
0
 private void CheckComplete()
 {
     if (MapDataService.SelfVisible(TargetLocation) && !ActiveUnitData.EnemyUnits.Any(e => Vector2.DistanceSquared(new Vector2(TargetLocation.X, TargetLocation.Y), e.Value.Position) < 100))
     {
         Disable();
         ChatService.SendChatType("WarpPrismElevatorTask-TaskCompleted");
     }
 }
Beispiel #3
0
        public Point2D UpdateAttackPoint(Point2D armyPoint, Point2D attackPoint)
        {
            var enemyBuildings            = ActiveUnitData.EnemyUnits.Where(e => e.Value.UnitTypeData.Attributes.Contains(SC2APIProtocol.Attribute.Structure) && e.Value.Unit.UnitType != (uint)UnitTypes.ZERG_CREEPTUMOR && e.Value.Unit.UnitType != (uint)UnitTypes.ZERG_CREEPTUMORBURROWED && e.Value.Unit.UnitType != (uint)UnitTypes.ZERG_CREEPTUMORQUEEN);
            var currentEnemyBuildingCount = enemyBuildings.Count();

            if (MapDataService.SelfVisible(attackPoint) || EnemyBuildingCount != currentEnemyBuildingCount)
            {
                TargetingData.HiddenEnemyBase = false;
                EnemyBuildingCount            = currentEnemyBuildingCount;

                var enemyBuilding = ActiveUnitData.EnemyUnits.Where(e => e.Value.Unit.UnitType != (uint)UnitTypes.ZERG_CREEPTUMORBURROWED && e.Value.Unit.UnitType != (uint)UnitTypes.ZERG_CREEPTUMOR && e.Value.UnitTypeData.Attributes.Contains(SC2APIProtocol.Attribute.Structure)).OrderBy(e => Vector2.DistanceSquared(e.Value.Position, new Vector2(armyPoint.X, armyPoint.Y))).FirstOrDefault().Value;
                if (enemyBuilding != null)
                {
                    return(new Point2D {
                        X = enemyBuilding.Unit.Pos.X, Y = enemyBuilding.Unit.Pos.Y
                    });
                }
                else
                {
                    attackPoint = TargetingData.EnemyMainBasePoint;
                }
            }

            if (currentEnemyBuildingCount == 0 && MapDataService.SelfVisible(attackPoint) && MapDataService.Visibility(TargetingData.EnemyMainBasePoint) > 0)
            {
                // can't find enemy base, choose a random base location
                TargetingData.HiddenEnemyBase = true;
                var bases = BaseData.BaseLocations.Where(b => !MapDataService.SelfVisible(b.Location));
                if (bases.Count() == 0)
                {
                    // find a random spot on the map and check there
                    return(new Point2D {
                        X = new Random().Next(0, MapDataService.MapData.MapWidth), Y = new Random().Next(0, MapDataService.MapData.MapHeight)
                    });
                }
                else
                {
                    return(bases.ToList()[new Random().Next(0, bases.Count())].Location);
                }
            }

            return(attackPoint);
        }
Beispiel #4
0
        protected override UnitCalculation GetBestTarget(UnitCommander commander, Point2D target, int frame)
        {
            var existingAttackOrder = commander.UnitCalculation.Unit.Orders.Where(o => o.AbilityId == (uint)Abilities.ATTACK || o.AbilityId == (uint)Abilities.ATTACK_ATTACK).FirstOrDefault();

            var range = commander.UnitCalculation.Range;

            var attacks = new List <UnitCalculation>(commander.UnitCalculation.EnemiesInRange.Where(u => u.Unit.DisplayType == DisplayType.Visible)); // units that are in range right now

            UnitCalculation bestAttack = null;

            if (attacks.Count > 0)
            {
                var oneShotKills = attacks.Where(a => a.Unit.Health + a.Unit.Shield < GetDamage(commander.UnitCalculation.Weapons, a.Unit, a.UnitTypeData) && !a.Unit.BuffIds.Contains((uint)Buffs.IMMORTALOVERLOAD));
                if (oneShotKills.Count() > 0)
                {
                    if (existingAttackOrder != null)
                    {
                        var existing = oneShotKills.FirstOrDefault(o => o.Unit.Tag == existingAttackOrder.TargetUnitTag);
                        if (existing != null)
                        {
                            return(existing); // just keep attacking the same unit
                        }
                    }

                    var oneShotKill = GetBestTargetFromList(commander, oneShotKills, existingAttackOrder);
                    if (oneShotKill != null)
                    {
                        return(oneShotKill);
                    }
                    else
                    {
                        commander.BestTarget = oneShotKills.OrderBy(o => o.Dps).FirstOrDefault();
                        return(commander.BestTarget);
                    }
                }

                bestAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                if (bestAttack != null && (bestAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure) || (bestAttack.UnitClassifications.Contains(UnitClassification.Worker) && bestAttack.EnemiesInRange.Any(e => e.Unit.Tag == commander.UnitCalculation.Unit.Tag))))
                {
                    commander.BestTarget = bestAttack;
                    return(bestAttack);
                }
            }

            attacks = new List <UnitCalculation>(); // nearby units not in range right now
            foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
            {
                if (enemyAttack.Unit.DisplayType == DisplayType.Visible && DamageService.CanDamage(commander.UnitCalculation, enemyAttack) && !InRange(enemyAttack.Position, commander.UnitCalculation.Position, range + enemyAttack.Unit.Radius + commander.UnitCalculation.Unit.Radius))
                {
                    attacks.Add(enemyAttack);
                }
            }

            var safeAttacks = attacks.Where(a => a.Damage < commander.UnitCalculation.Unit.Health);

            if (safeAttacks.Count() > 0)
            {
                var bestOutOfRangeAttack = GetBestTargetFromList(commander, safeAttacks, existingAttackOrder);
                if (bestOutOfRangeAttack != null && (bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure)))
                {
                    commander.BestTarget = bestOutOfRangeAttack;
                    return(bestOutOfRangeAttack);
                }
                if (bestAttack == null)
                {
                    bestAttack = bestOutOfRangeAttack;
                }
            }

            if (commander.UnitCalculation.Unit.Health < 6)
            {
                return(null);
            }

            if (attacks.Count > 0)
            {
                var bestOutOfRangeAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                if (bestOutOfRangeAttack != null && (bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure)))
                {
                    commander.BestTarget = bestOutOfRangeAttack;
                    return(bestOutOfRangeAttack);
                }
                if (bestAttack == null)
                {
                    bestAttack = bestOutOfRangeAttack;
                }
            }

            if (!MapDataService.SelfVisible(target)) // if enemy main is unexplored, march to enemy main
            {
                var fakeMainBase = new Unit(commander.UnitCalculation.Unit);
                fakeMainBase.Pos = new Point {
                    X = target.X, Y = target.Y, Z = 1
                };
                fakeMainBase.Alliance = Alliance.Enemy;
                return(new UnitCalculation(fakeMainBase, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame));
            }
            var unitsNearEnemyMain = ActiveUnitData.EnemyUnits.Values.Where(e => e.Unit.UnitType != (uint)UnitTypes.ZERG_LARVA && InRange(new Vector2(target.X, target.Y), e.Position, 20));

            if (unitsNearEnemyMain.Count() > 0 && InRange(new Vector2(target.X, target.Y), commander.UnitCalculation.Position, 100))
            {
                attacks = new List <UnitCalculation>(); // enemies in the main enemy base
                foreach (var enemyAttack in unitsNearEnemyMain)
                {
                    if (enemyAttack.Unit.DisplayType == DisplayType.Visible && DamageService.CanDamage(commander.UnitCalculation, enemyAttack))
                    {
                        attacks.Add(enemyAttack);
                    }
                }
                if (attacks.Count > 0)
                {
                    var bestMainAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                    if (bestMainAttack != null && (bestMainAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestMainAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure)))
                    {
                        commander.BestTarget = bestMainAttack;
                        return(bestMainAttack);
                    }
                    if (bestAttack == null)
                    {
                        bestAttack = bestMainAttack;
                    }
                }
            }

            commander.BestTarget = bestAttack;
            return(bestAttack);
        }
Beispiel #5
0
        public override IEnumerable <Action> OnFrame(ResponseObservation observation)
        {
            //var total = new Stopwatch();
            //total.Start();

            //var stopwatch = new Stopwatch();
            //stopwatch.Start();

            var frame = (int)observation.Observation.GameLoop;

            if (observation.Observation.RawData.Event != null && observation.Observation.RawData.Event.DeadUnits != null)
            {
                ActiveUnitData.DeadUnits = observation.Observation.RawData.Event.DeadUnits.ToList();
            }
            else
            {
                ActiveUnitData.DeadUnits = new List <ulong>();
            }

            foreach (var unit in ActiveUnitData.SelfUnits.Where(u => u.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_DISRUPTORPHASED)) // remove things like purification novas that don't have dead unit events
            {
                if (!observation.Observation.RawData.Units.Any(u => u.Tag == unit.Key))
                {
                    ActiveUnitData.DeadUnits.Add(unit.Key);
                }
            }

            foreach (var tag in ActiveUnitData.DeadUnits)
            {
                if (ActiveUnitData.EnemyUnits.TryRemove(tag, out UnitCalculation removedEnemy))
                {
                    ActiveUnitData.EnemyDeaths++;
                }
                else if (ActiveUnitData.SelfUnits.TryRemove(tag, out UnitCalculation removedAlly))
                {
                    ActiveUnitData.SelfDeaths++;
                }
                else if (ActiveUnitData.NeutralUnits.TryRemove(tag, out UnitCalculation removedNeutral))
                {
                    ActiveUnitData.NeutralDeaths++;
                }

                ActiveUnitData.Commanders.TryRemove(tag, out UnitCommander removedCommander);
            }

            foreach (var unit in ActiveUnitData.EnemyUnits.Where(u => UndeadTypes.Contains((UnitTypes)u.Value.Unit.UnitType)))
            {
                ActiveUnitData.EnemyUnits.TryRemove(unit.Key, out UnitCalculation removed);
            }
            foreach (var unit in ActiveUnitData.SelfUnits.Where(u => UndeadTypes.Contains((UnitTypes)u.Value.Unit.UnitType)))
            {
                ActiveUnitData.SelfUnits.TryRemove(unit.Key, out UnitCalculation removed);
            }
            foreach (var unit in ActiveUnitData.Commanders.Where(u => UndeadTypes.Contains((UnitTypes)u.Value.UnitCalculation.Unit.UnitType)))
            {
                ActiveUnitData.Commanders.TryRemove(unit.Key, out UnitCommander removed);
            }

            foreach (var unit in ActiveUnitData.EnemyUnits.Where(u => u.Value.UnitTypeData.Attributes.Contains(SC2APIProtocol.Attribute.Structure))) // structures get replaced by snapshots if we can't see them, so just remove them and let them get readded
            {
                ActiveUnitData.EnemyUnits.TryRemove(unit.Key, out UnitCalculation removed);
            }

            //Debug.WriteLine($"removal {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            var repairers = observation.Observation.RawData.Units.Where(u => u.UnitType == (uint)UnitTypes.TERRAN_SCV || u.UnitType == (uint)UnitTypes.TERRAN_MULE);

            //Parallel.ForEach(observation.Observation.RawData.Units, (unit) =>
            //{
            //    if (unit.Alliance == Alliance.Enemy)
            //    {
            //        var repairingUnitCount = repairers.Where(u => u.Alliance == Alliance.Enemy && Vector2.DistanceSquared(new Vector2(u.Pos.X, u.Pos.Y), new Vector2(unit.Pos.X, unit.Pos.Y)) < (1.0 + u.Radius + unit.Radius) * (0.1 + u.Radius + unit.Radius)).Count();
            //        var attack = new UnitCalculation(unit, repairingUnitCount, SharkyUnitData, SharkyOptions, UnitDataService, frame);
            //        if (ActiveUnitData.EnemyUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
            //        {
            //            attack.SetPreviousUnit(existing, existing.FrameLastSeen);
            //        }
            //        ActiveUnitData.EnemyUnits[unit.Tag] = attack;
            //    }
            //    else if (unit.Alliance == Alliance.Self)
            //    {
            //        var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
            //        if (ActiveUnitData.SelfUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
            //        {
            //            attack.SetPreviousUnit(existing, existing.FrameLastSeen);
            //        }
            //        ActiveUnitData.SelfUnits[unit.Tag] = attack;
            //    }
            //    else if (unit.Alliance == Alliance.Neutral)
            //    {
            //        var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
            //        if (ActiveUnitData.NeutralUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
            //        {
            //            attack.SetPreviousUnit(existing, existing.FrameLastSeen);
            //        }
            //        ActiveUnitData.NeutralUnits[unit.Tag] = attack;
            //    }
            //});

            foreach (var unit in observation.Observation.RawData.Units)
            {
                if (unit.Alliance == Alliance.Enemy)
                {
                    var repairingUnitCount = repairers.Where(u => u.Alliance == Alliance.Enemy && Vector2.DistanceSquared(new Vector2(u.Pos.X, u.Pos.Y), new Vector2(unit.Pos.X, unit.Pos.Y)) < (1.0 + u.Radius + unit.Radius) * (0.1 + u.Radius + unit.Radius)).Count();
                    var attack             = new UnitCalculation(unit, repairingUnitCount, SharkyUnitData, SharkyOptions, UnitDataService, frame);
                    if (ActiveUnitData.EnemyUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
                    {
                        attack.SetPreviousUnit(existing, existing.FrameLastSeen);
                    }
                    ActiveUnitData.EnemyUnits[unit.Tag] = attack;
                }
                else if (unit.Alliance == Alliance.Self)
                {
                    var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
                    if (ActiveUnitData.SelfUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
                    {
                        attack.SetPreviousUnit(existing, existing.FrameLastSeen);
                    }
                    ActiveUnitData.SelfUnits[unit.Tag] = attack;
                }
                else if (unit.Alliance == Alliance.Neutral)
                {
                    var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
                    if (ActiveUnitData.NeutralUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
                    {
                        attack.SetPreviousUnit(existing, existing.FrameLastSeen);
                    }
                    ActiveUnitData.NeutralUnits[unit.Tag] = attack;
                }
            }

            //Debug.WriteLine($"parallel {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            foreach (var enemy in ActiveUnitData.EnemyUnits.Select(e => e.Value).ToList()) // if we can see this area of the map and the unit isn't there anymore remove it (we just remove it because visible units will get re-added below)
            {
                if (enemy.FrameLastSeen != frame && MapDataService.SelfVisible(enemy.Unit.Pos))
                {
                    ActiveUnitData.EnemyUnits.TryRemove(enemy.Unit.Tag, out UnitCalculation removed);
                }
            }

            //Debug.WriteLine($"remove vision {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            foreach (var allyAttack in ActiveUnitData.SelfUnits)
            {
                foreach (var enemyAttack in ActiveUnitData.EnemyUnits)
                {
                    if (DamageService.CanDamage(allyAttack.Value, enemyAttack.Value) && Vector2.DistanceSquared(allyAttack.Value.Position, enemyAttack.Value.Position) <= (allyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius) * (allyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius))
                    {
                        allyAttack.Value.EnemiesInRange.Add(enemyAttack.Value);
                        enemyAttack.Value.EnemiesInRangeOf.Add(allyAttack.Value);
                    }
                    if (DamageService.CanDamage(enemyAttack.Value, allyAttack.Value) && Vector2.DistanceSquared(allyAttack.Value.Position, enemyAttack.Value.Position) <= (enemyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius) * (enemyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius))
                    {
                        enemyAttack.Value.EnemiesInRange.Add(allyAttack.Value);
                        allyAttack.Value.EnemiesInRangeOf.Add(enemyAttack.Value);
                    }

                    if (Vector2.DistanceSquared(allyAttack.Value.Position, enemyAttack.Value.Position) <= NearbyDistance * NearbyDistance)
                    {
                        enemyAttack.Value.NearbyEnemies.Add(allyAttack.Value);
                        allyAttack.Value.NearbyEnemies.Add(enemyAttack.Value);
                    }
                }

                allyAttack.Value.NearbyAllies = ActiveUnitData.SelfUnits.Where(a => a.Key != allyAttack.Key && Vector2.DistanceSquared(allyAttack.Value.Position, a.Value.Position) <= NearbyDistance * NearbyDistance).Select(a => a.Value).ToList();

                var commander = new UnitCommander(allyAttack.Value);
                ActiveUnitData.Commanders.AddOrUpdate(allyAttack.Value.Unit.Tag, commander, (tag, existingCommander) =>
                {
                    commander = existingCommander;
                    commander.UnitCalculation = allyAttack.Value;
                    return(commander);
                });
            }

            //Debug.WriteLine($"allyattack {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            foreach (var enemyAttack in ActiveUnitData.EnemyUnits)
            {
                enemyAttack.Value.NearbyAllies = ActiveUnitData.EnemyUnits.Where(a => a.Key != enemyAttack.Key && Vector2.DistanceSquared(enemyAttack.Value.Position, a.Value.Position) <= NearbyDistance * NearbyDistance).Select(a => a.Value).ToList();
            }

            //Debug.WriteLine($"enemyunits {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            if (TargetPriorityCalculationFrame + 10 < frame)
            {
                foreach (var selfUnit in ActiveUnitData.SelfUnits)
                {
                    if (selfUnit.Value.TargetPriorityCalculation == null || selfUnit.Value.TargetPriorityCalculation.FrameCalculated + 10 < frame)
                    {
                        var priorityCalculation = TargetPriorityService.CalculateTargetPriority(selfUnit.Value, frame);
                        selfUnit.Value.TargetPriorityCalculation = priorityCalculation;
                        foreach (var nearbyUnit in selfUnit.Value.NearbyAllies.Where(a => a.NearbyEnemies.Count() == selfUnit.Value.NearbyAllies.Count()))
                        {
                            nearbyUnit.TargetPriorityCalculation = priorityCalculation;
                        }
                    }

                    selfUnit.Value.Attackers = GetTargettedAttacks(selfUnit.Value).ToList();
                }
                TargetPriorityCalculationFrame = frame;
            }
            //foreach (var selfUnit in ActiveUnitData.SelfUnits)
            //{
            //    if (selfUnit.Value.TargetPriorityCalculation == null || selfUnit.Value.TargetPriorityCalculation.FrameCalculated + 10 < frame)
            //    {
            //        var priorityCalculation = TargetPriorityService.CalculateTargetPriority(selfUnit.Value, frame);
            //        selfUnit.Value.TargetPriorityCalculation = priorityCalculation;
            //        foreach (var nearbyUnit in selfUnit.Value.NearbyAllies)
            //        {
            //            nearbyUnit.TargetPriorityCalculation = priorityCalculation;
            //        }
            //    }

            //    selfUnit.Value.Attackers = GetTargettedAttacks(selfUnit.Value).ToList();
            //}

            //Debug.WriteLine($"selfunits {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            if (SharkyOptions.Debug)
            {
                foreach (var selfUnit in ActiveUnitData.SelfUnits)
                {
                    DebugService.DrawLine(selfUnit.Value.Unit.Pos, new Point {
                        X = selfUnit.Value.End.X, Y = selfUnit.Value.End.Y, Z = selfUnit.Value.Unit.Pos.Z + 1f
                    }, new SC2APIProtocol.Color {
                        R = 0, B = 0, G = 255
                    });
                }
                foreach (var enemyUnit in ActiveUnitData.EnemyUnits)
                {
                    DebugService.DrawLine(enemyUnit.Value.Unit.Pos, new Point {
                        X = enemyUnit.Value.End.X, Y = enemyUnit.Value.End.Y, Z = enemyUnit.Value.Unit.Pos.Z + 1f
                    }, new SC2APIProtocol.Color {
                        R = 255, B = 0, G = 0
                    });
                }
            }

            //stopwatch.Stop();
            //Debug.WriteLine($"debug {stopwatch.ElapsedMilliseconds}");
            //total.Stop();
            //Debug.WriteLine($"total {total.ElapsedMilliseconds}");

            //if (total.ElapsedMilliseconds > 15)
            //{
            //    var uhoh = true;
            //}

            //Debug.WriteLine($"");

            return(null);
        }
        public override IEnumerable <SC2APIProtocol.Action> PerformActions(int frame)
        {
            var commands = new List <SC2APIProtocol.Action>();

            AssignHarassers();

            foreach (var harassInfo in HarassInfos)
            {
                foreach (var commander in harassInfo.Harassers)
                {
                    if (MapDataService.EnemyAirDpsInRange(commander.UnitCalculation.Unit.Pos) < 10 && ((commander.UnitCalculation.Unit.Shield >= (commander.UnitCalculation.Unit.ShieldMax / 2.0f) && commander.UnitCalculation.Unit.Energy > 50) || (commander.UnitCalculation.Unit.BuffIds.Contains((uint)Buffs.ORACLEWEAPON) && commander.UnitCalculation.Unit.Shield > 5)))
                    {
                        if (Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(harassInfo.BaseLocation.MineralLineLocation.X, harassInfo.BaseLocation.MineralLineLocation.Y)) < 100)
                        {
                            var action = OracleMicroController.HarassWorkers(commander, harassInfo.BaseLocation.MineralLineLocation, TargetingData.ForwardDefensePoint, frame);
                            if (action != null)
                            {
                                commands.AddRange(action);
                            }

                            if (commander.UnitCalculation.NearbyEnemies.Count(e => e.UnitClassifications.Contains(UnitClassification.Worker) && (Vector2.DistanceSquared(commander.UnitCalculation.Position, e.Position) <= 100)) < 1 && MapDataService.SelfVisible(harassInfo.BaseLocation.MineralLineLocation))
                            {
                                harassInfo.LastClearedFrame = frame;
                                harassInfo.Harassers.Remove(commander);
                                return(commands);
                            }
                            else if (commander.UnitCalculation.NearbyEnemies.Any(e => e.DamageAir && Vector2.DistanceSquared(new Vector2(harassInfo.BaseLocation.MineralLineLocation.X, harassInfo.BaseLocation.MineralLineLocation.Y), e.Position) < 100))
                            {
                                if (commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.FullRetreat || commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.Retreat || commander.UnitCalculation.Unit.Shield <= 5)
                                {
                                    harassInfo.LastDefendedFrame = frame;
                                    harassInfo.Harassers.Remove(commander);
                                    return(commands);
                                }
                            }
                        }
                        else if (!commander.UnitCalculation.NearbyEnemies.Any(e => e.DamageAir) && commander.UnitCalculation.NearbyEnemies.Count(e => e.UnitClassifications.Contains(UnitClassification.Worker)) > 2)  // if near woerkers and nothing can attack it just kill workers
                        {
                            var action = OracleMicroController.HarassWorkers(commander, harassInfo.BaseLocation.MineralLineLocation, TargetingData.ForwardDefensePoint, frame);
                            if (action != null)
                            {
                                commands.AddRange(action);
                            }
                        }
                        else
                        {
                            var action = OracleMicroController.NavigateToPoint(commander, harassInfo.BaseLocation.MineralLineLocation, TargetingData.ForwardDefensePoint, null, frame);
                            if (action != null)
                            {
                                commands.AddRange(action);
                            }

                            if (commander.UnitCalculation.Unit.Shield <= 10)
                            {
                                harassInfo.LastPathFailedFrame = frame;
                                harassInfo.Harassers.Remove(commander);
                                return(commands);
                            }
                        }
                    }
                    else
                    {
                        var action = OracleMicroController.NavigateToPoint(commander, TargetingData.ForwardDefensePoint, TargetingData.MainDefensePoint, null, frame);
                        if (action != null)
                        {
                            commands.AddRange(action);
                        }
                    }
                }
            }

            return(commands);
        }
Beispiel #7
0
 bool CanHarass(UnitCommander commander, Point2D target)
 {
     if (commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.FullRetreat || commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.Retreat)
     {
         return(false);
     }
     if (commander.UnitCalculation.NearbyEnemies.Count(e => e.UnitClassifications.Contains(UnitClassification.Worker) && (Vector2.DistanceSquared(commander.UnitCalculation.Position, e.Position) <= 100)) < 1 && MapDataService.SelfVisible(new Point2D {
         X = target.X, Y = target.Y,
     }))
     {
         return(false);
     }
     if (commander.UnitCalculation.Unit.Shield <= 5 || (commander.UnitCalculation.Unit.Shield < commander.UnitCalculation.Unit.ShieldMax && commander.UnitCalculation.NearbyEnemies.Where(e => !e.Attributes.Contains(Attribute.Structure) && e.DamageAir).Sum(e => e.Damage) * 3 > commander.UnitCalculation.Unit.Shield))
     {
         return(false);
     }
     return(true);
 }
        public override IEnumerable <SC2APIProtocol.Action> PerformActions(int frame)
        {
            var commands = new List <SC2APIProtocol.Action>();

            var positions = ActiveUnitData.Commanders.Values.Where(u => u.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON).Select(p => p.UnitCalculation.Position);

            if (ScoutPoints == null)
            {
                EnemyMainArea = AreaService.GetTargetArea(TargetingData.EnemyMainBasePoint);
                ScoutPoints   = new List <Point2D>();
                ScoutPoints.AddRange(EnemyMainArea);
                ScoutPoints.Add(BaseData.EnemyBaseLocations.Skip(1).First().Location);
            }

            var mainVector = new Vector2(TargetingData.EnemyMainBasePoint.X, TargetingData.EnemyMainBasePoint.Y);
            var points     = ScoutPoints.OrderBy(p => MapDataService.LastFrameVisibility(p)).ThenByDescending(p => Vector2.DistanceSquared(mainVector, new Vector2(p.X, p.Y)));

            foreach (var point in points)
            {
                //DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 });
            }

            foreach (var commander in UnitCommanders)
            {
                if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.BUILD_ASSIMILATOR) || commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.BUILD_PYLON))
                {
                    return(commands);
                }

                if (MacroData.Minerals >= 75 && commander.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_PROBE)
                {
                    if (!BaseData.EnemyBases.Any(enemyBase => enemyBase.VespeneGeysers.Any(g => g.Alliance == Alliance.Enemy)))
                    {
                        foreach (var enemyBase in BaseData.EnemyBases)
                        {
                            foreach (var gas in enemyBase.VespeneGeysers.Where(g => g.Alliance == Alliance.Neutral))
                            {
                                if (Vector2.DistanceSquared(new Vector2(gas.Pos.X, gas.Pos.Y), commander.UnitCalculation.Position) < 400)
                                {
                                    var gasSteal = commander.Order(frame, Abilities.BUILD_ASSIMILATOR, null, gas.Tag);
                                    if (gasSteal != null)
                                    {
                                        commands.AddRange(gasSteal);
                                        return(commands);
                                    }
                                }
                            }
                        }
                    }
                }

                if (MacroData.Minerals >= 100 && commander.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_PROBE)
                {
                    var enemyBase = BaseData.EnemyBaseLocations.FirstOrDefault();
                    if (BlockWall && enemyBase != null && MapData.BlockWallData != null)
                    {
                        var wallData = MapData.BlockWallData.FirstOrDefault(b => b.BasePosition.X == enemyBase.Location.X && b.BasePosition.Y == enemyBase.Location.Y);
                        if (wallData != null)
                        {
                            var vector = new Vector2(enemyBase.Location.X, enemyBase.Location.Y);
                            if (Vector2.DistanceSquared(vector, commander.UnitCalculation.Position) < 225)
                            {
                                if (!ActiveUnitData.SelfUnits.Any(a => a.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON && wallData.Pylons.Any(p => Vector2.DistanceSquared(new Vector2(p.X, p.Y), a.Value.Position) < 4)))
                                {
                                    foreach (var point in wallData.Pylons)
                                    {
                                        if (!BuildingService.Blocked(point.X, point.Y, 1, -.5f))
                                        {
                                            var wallBlock = commander.Order(frame, Abilities.BUILD_PYLON, point);
                                            if (wallBlock != null)
                                            {
                                                commands.AddRange(wallBlock);
                                                return(commands);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    var expansion = BaseData.EnemyBaseLocations.Skip(1).FirstOrDefault();
                    if (BlockExpansion && expansion != null)
                    {
                        var expansionVector = new Vector2(expansion.Location.X, expansion.Location.Y);
                        if (Vector2.DistanceSquared(expansionVector, commander.UnitCalculation.Position) < 225)
                        {
                            if (!commander.UnitCalculation.NearbyAllies.Any(a => Vector2.DistanceSquared(expansionVector, a.Position) < 9))
                            {
                                var expansionBlock = commander.Order(frame, Abilities.BUILD_PYLON, expansion.Location);
                                if (expansionBlock != null)
                                {
                                    commands.AddRange(expansionBlock);
                                    return(commands);
                                }
                            }
                        }
                    }

                    if (HidePylonInBase)
                    {
                        var hideLocation = EnemyMainArea.Where(p => MapDataService.SelfVisible(p) && !MapDataService.InEnemyVision(p)).OrderBy(p => Vector2.DistanceSquared(new Vector2(p.X, p.Y), mainVector)).FirstOrDefault();
                        if (hideLocation != null)
                        {
                            var hidenPylonOrder = commander.Order(frame, Abilities.BUILD_PYLON, hideLocation);
                            if (hidenPylonOrder != null)
                            {
                                commands.AddRange(hidenPylonOrder);
                                return(commands);
                            }
                        }
                    }
                }

                var action = commander.Order(frame, Abilities.MOVE, points.FirstOrDefault());
                if (action != null)
                {
                    commands.AddRange(action);
                }
            }

            return(commands);
        }