public bool Place(Agent agent) { if (ForceFieldPlacementAssignments.ContainsKey(agent.Unit.Tag)) { foreach (Unit unit in Bot.Main.Observation.Observation.RawData.Units) { if (unit.UnitType != 135) { continue; } if (SC2Util.DistanceSq(unit.Pos, ForceFieldPlacementAssignments[agent.Unit.Tag]) < 2) { ForceFieldPlacementAssignments.Remove(agent.Unit.Tag); return(false); } } agent.Order(1526, ForceFieldPlacementAssignments[agent.Unit.Tag]); return(true); } return(false); }
public Unit GetTarget(Agent agent) { uint unitType = agent.Unit.UnitType; float maxRangeSq = 9; if (TypePriorities.ContainsKey(unitType) && TypePriorities[unitType].MaxRange > 0) { maxRangeSq = TypePriorities[unitType].MaxRange * TypePriorities[unitType].MaxRange; } if (DefaultPriorities.MaxRange > 0) { maxRangeSq = DefaultPriorities.MaxRange * DefaultPriorities.MaxRange; } Unit target = null; int priority = -2; float health = 0; foreach (Unit enemy in Bot.Main.Enemies()) { if (SC2Util.DistanceSq(enemy.Pos, agent.Unit.Pos) > maxRangeSq) { continue; } float enemyHealth = enemy.Health + enemy.Shield - GetDamageDealt(enemy.Tag); if (enemyHealth < 0) { continue; } int newPriority = 0; if (TypePriorities.ContainsKey(unitType) && TypePriorities[unitType][enemy.UnitType] != int.MinValue) { newPriority = TypePriorities[unitType][enemy.UnitType]; } else if (DefaultPriorities[enemy.UnitType] != int.MinValue) { newPriority = DefaultPriorities[enemy.UnitType]; } if (newPriority < priority) { continue; } if (newPriority == priority && enemyHealth >= health) { continue; } target = enemy; priority = newPriority; health = enemyHealth; } if (priority >= 0) { AddDamageDealt(target.Tag, agent.GetDamage(target)); return(target); } else { return(null); } }
public void DetermineForceFieldPlacement(List <Agent> units) { if (Bot.Main.Frame - ForceFieldPlacementFrame < 250) { return; } List <Unit> sentries = new List <Unit>(); foreach (Agent agent in units) { if (agent.Unit.UnitType == UnitTypes.SENTRY) { sentries.Add(agent.Unit); } } List <List <Unit> > sentryGroups = GroupUnits(sentries); List <Unit> mainSentryGroup = new List <Unit>(); foreach (List <Unit> sentryGroup in sentryGroups) { if (sentryGroup.Count > mainSentryGroup.Count) { mainSentryGroup = sentryGroup; } } Bot.Main.DrawText("MainSentryGroup size: " + mainSentryGroup.Count); if (mainSentryGroup.Count < 8) { return; } List <Unit> closeEnemies = new List <Unit>(); HashSet <ulong> enemyTags = new HashSet <ulong>(); foreach (Unit enemy in Bot.Main.Enemies()) { if (!ConsiderEnemy(enemy)) { continue; } foreach (Unit sentry in mainSentryGroup) { if (SC2Util.DistanceSq(sentry.Pos, enemy.Pos) <= 10 * 10) { closeEnemies.Add(enemy); enemyTags.Add(enemy.Tag); break; } } } for (int i = 0; i < closeEnemies.Count; i++) { Unit closeEnemy = closeEnemies[i]; foreach (Unit enemy in Bot.Main.Enemies()) { if (!ConsiderEnemy(enemy)) { continue; } if (enemyTags.Contains(enemy.Tag)) { continue; } if (SC2Util.DistanceSq(closeEnemy.Pos, enemy.Pos) <= 4 * 4) { closeEnemies.Add(enemy); enemyTags.Add(enemy.Tag); } } } List <List <Unit> > enemyGroups = GroupUnits(closeEnemies); List <Unit> mainEnemyGroup = new List <Unit>(); foreach (List <Unit> enemyGroup in enemyGroups) { if (enemyGroup.Count > mainEnemyGroup.Count) { mainEnemyGroup = enemyGroup; } } Bot.Main.DrawText("mainEnemyGroup size: " + mainEnemyGroup.Count); if (mainEnemyGroup.Count < 6) { return; } int zerglingCount = 0; int zealotCount = 0; foreach (Unit enemy in mainEnemyGroup) { if (enemy.UnitType == UnitTypes.ZEALOT) { zealotCount++; } if (enemy.UnitType == UnitTypes.ZERGLING) { zerglingCount++; } } bool closeForceFields = zealotCount >= 4 || zerglingCount >= 6; Point2D sentryCenter = CenterOfMass(mainSentryGroup); Point2D enemyCenter = CenterOfMass(mainEnemyGroup); Point2D towardEnemy = new Point2D() { X = enemyCenter.X - sentryCenter.X, Y = enemyCenter.Y - sentryCenter.Y }; float length = (float)Math.Sqrt(towardEnemy.X * towardEnemy.X + towardEnemy.Y * towardEnemy.Y); towardEnemy.X /= length; towardEnemy.Y /= length; Point2D rightAngle = new Point2D() { X = towardEnemy.Y, Y = -towardEnemy.X }; Dictionary <ulong, Point2D> newForceFieldLocations = new Dictionary <ulong, Point2D>(); for (int i = 0; i < NumberOfForceFields; i++) { Point2D forceFieldLocation; if (closeForceFields && (i == 0 || i == NumberOfForceFields - 1)) { float iMiddle = i == 0 ? 0.5f : (i - 0.5f); float x = sentryCenter.X + 1f * towardEnemy.X + (-1.5f * (NumberOfForceFields - 1) + 3 * iMiddle) * rightAngle.X; float y = sentryCenter.Y + 1f * towardEnemy.Y + (-1.5f * (NumberOfForceFields - 1) + 3 * iMiddle) * rightAngle.Y; forceFieldLocation = new Point2D() { X = x, Y = y }; } else if (closeForceFields) { float x = sentryCenter.X + 4 * towardEnemy.X + (-1.5f * (NumberOfForceFields - 1) + 3 * i) * rightAngle.X; float y = sentryCenter.Y + 4 * towardEnemy.Y + (-1.5f * (NumberOfForceFields - 1) + 3 * i) * rightAngle.Y; forceFieldLocation = new Point2D() { X = x, Y = y }; } else { forceFieldLocation = new Point2D() { X = enemyCenter.X + (-1.5f * (NumberOfForceFields - 1) + 3 * i) * rightAngle.X, Y = enemyCenter.Y + (-1.5f * (NumberOfForceFields - 1) + 3 * i) * rightAngle.Y } }; float dist = 14 * 14; Agent pickedSentry = null; foreach (Agent agent in units) { if (newForceFieldLocations.ContainsKey(agent.Unit.Tag)) { continue; } if (agent.Unit.UnitType != UnitTypes.SENTRY) { continue; } if (agent.Unit.Energy < 50) { continue; } if (Bot.Main.Frame - agent.LastOrderFrame < 3 && agent.LastAbility != Abilities.MOVE && agent.LastAbility != Abilities.ATTACK) { continue; } float newDist = agent.DistanceSq(forceFieldLocation); if (newDist >= dist) { continue; } dist = newDist; pickedSentry = agent; } if (pickedSentry == null) { Bot.Main.DrawText("Failed to find Sentry for forceField placement."); return; } newForceFieldLocations.Add(pickedSentry.Unit.Tag, forceFieldLocation); } ForceFieldPlacementFrame = Bot.Main.Frame; ForceFieldPlacementAssignments = newForceFieldLocations; }