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