public BuildOptions() { StrictWorkerCount = false; StrictSupplyCount = false; StrictGasCount = false; StrictWorkersPerGas = false; StrictWorkersPerGasCount = 3; ProtossBuildOptions = new ProtossBuildOptions { PylonsAtDefensivePoint = 0, ShieldsAtDefensivePoint = 0 }; WallOffType = WallOffType.None; }
public List <Action> BuildBuilding(MacroData macroData, UnitTypes unitType, BuildingTypeData unitData, Point2D generalLocation = null, bool ignoreMineralProximity = false, float maxDistance = 50, List <UnitCommander> workerPool = null, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.None) { if (unitData.Minerals <= macroData.Minerals && unitData.Gas <= macroData.VespeneGas) { bool anyBase = false; var location = generalLocation; if (location == null) { anyBase = true; location = GetReferenceLocation(TargetingData.SelfMainBasePoint); } var placementLocation = BuildingPlacement.FindPlacement(location, unitType, unitData.Size, ignoreMineralProximity, maxDistance, requireSameHeight, wallOffType); if (placementLocation == null) { placementLocation = BuildingPlacement.FindPlacement(location, unitType, unitData.Size, true, maxDistance, requireSameHeight, wallOffType); } if (placementLocation == null && anyBase) { foreach (var selfBase in BaseData.SelfBases) { placementLocation = BuildingPlacement.FindPlacement(selfBase.Location, unitType, unitData.Size, true, maxDistance, requireSameHeight, wallOffType); if (placementLocation != null) { break; } } } if (placementLocation != null) { var worker = GetWorker(placementLocation, workerPool); if (worker != null) { if (workerPool == null) { worker.UnitRole = UnitRole.Build; } return(worker.Order(macroData.Frame, unitData.Ability, placementLocation)); } } } return(null); }
public Point2D FindPlacement(Point2D target, UnitTypes unitType, int size, bool ignoreResourceProximity = false, float maxDistance = 50, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.None) { if (unitType == UnitTypes.PROTOSS_NEXUS || unitType == UnitTypes.TERRAN_COMMANDCENTER || unitType == UnitTypes.ZERG_HATCHERY) { return(GetResourceCenterLocation()); } if (SharkyUnitData.TerranTypes.Contains(unitType)) { return(TerranBuildingPlacement.FindPlacement(target, unitType, size, ignoreResourceProximity, maxDistance, requireSameHeight, wallOffType)); } else if (SharkyUnitData.ProtossTypes.Contains(unitType)) { return(ProtossBuildingPlacement.FindPlacement(target, unitType, size, ignoreResourceProximity, maxDistance, requireSameHeight, wallOffType)); } else { return(ZergBuildingPlacement.FindPlacement(target, unitType, size, ignoreResourceProximity, maxDistance, requireSameHeight, wallOffType)); } }
public Point2D FindPlacement(Point2D target, UnitTypes unitType, int size, bool ignoreResourceProximity = false, float maxDistance = 50, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.Full) { var mineralProximity = 2; if (ignoreResourceProximity) { mineralProximity = 0; } ; if (wallOffType == WallOffType.Partial && MapData.PartialWallData == null) { return(null); } var baseLocation = GetBaseLocation(); if (baseLocation == null) { return(null); } WallData wallData = null; if (wallOffType == WallOffType.Partial) { wallData = MapData.PartialWallData.FirstOrDefault(b => b.BasePosition.X == baseLocation.X && b.BasePosition.Y == baseLocation.Y); if (wallData == null) { return(null); } } if (unitType == UnitTypes.PROTOSS_PYLON) { var placement = FindPylonPlacement(wallData, maxDistance, mineralProximity, wallOffType); if (placement == null) { return(null); } if (Vector2.DistanceSquared(new Vector2(placement.X, placement.Y), new Vector2(target.X, target.Y)) > maxDistance * maxDistance) { return(null); } return(placement); } else { var placement = FindProductionPlacement(wallData, size, maxDistance, mineralProximity, wallOffType); if (placement == null) { return(null); } if (Vector2.DistanceSquared(new Vector2(placement.X, placement.Y), new Vector2(target.X, target.Y)) > maxDistance * maxDistance) { return(null); } return(placement); } }
public Point2D FindProductionPlacement(WallData wallData, float size, float maxDistance, float minimumMineralProximinity = 2, WallOffType wallOffType = WallOffType.Full) { if (wallOffType == WallOffType.Partial) { return(FindPartialWallProductionPlacement(wallData, size, 4)); } return(FindFullWallProductionPlacement(wallData, size, 4)); }
public Point2D FindPylonPlacement(List <Point2D> wallPoints, float maxDistance, float minimumMineralProximinity = 0, WallOffType wallOffType = WallOffType.Full) { if (ActiveUnitData.Commanders.Values.Count(c => c.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON && Vector2.DistanceSquared(c.UnitCalculation.Position, new Vector2(wallPoints.FirstOrDefault().X, wallPoints.FirstOrDefault().Y)) < 100) > 0) { return(null); // if there is already a pylon by the wall don't build more there } if (wallOffType == WallOffType.Partial) { return(FindPartialWallPylonPlacement(wallPoints, 4)); } return(FindFullWallPylonPlacement(wallPoints, 4)); }
public Point2D FindPlacement(Point2D target, UnitTypes unitType, int size, bool ignoreResourceProximity = false, float maxDistance = 50, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.Full) { var mineralProximity = 2; if (ignoreResourceProximity) { mineralProximity = 0; } ; if (TargetingData.ForwardDefenseWallOffPoints == null) { return(null); } var wallPoint = TargetingData.ForwardDefenseWallOffPoints.FirstOrDefault(); if (wallPoint == null) { return(null); } if (Vector2.DistanceSquared(new Vector2(wallPoint.X, wallPoint.Y), new Vector2(target.X, target.Y)) > maxDistance * maxDistance) { return(null); } if (unitType == UnitTypes.PROTOSS_PYLON) { return(FindPylonPlacement(TargetingData.ForwardDefenseWallOffPoints, maxDistance, mineralProximity, wallOffType)); } else { if (unitType == UnitTypes.PROTOSS_GATEWAY || unitType == UnitTypes.PROTOSS_CYBERNETICSCORE || unitType == UnitTypes.PROTOSS_SHIELDBATTERY || unitType == UnitTypes.PROTOSS_PHOTONCANNON) { return(FindProductionPlacement(TargetingData.ForwardDefenseWallOffPoints, size, maxDistance, mineralProximity, wallOffType)); } return(null); } }
public Point2D FindPylonPlacement(Point2D reference, float maxDistance, float minimumMineralProximinity = 2, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.None) { var x = reference.X; var y = reference.Y; var radius = 1f; // start at 12 o'clock then rotate around 12 times, increase radius by 1 until it's more than maxDistance while (radius < maxDistance / 2.0) { var fullCircle = Math.PI * 2; var sliceSize = fullCircle / (8.0 + radius); var angle = 0.0; while (angle + (sliceSize / 2) < fullCircle) { var point = new Point2D { X = x + (float)(radius * Math.Cos(angle)), Y = y + (float)(radius * Math.Sin(angle)) }; //DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }); //if (!BuildingService.AreaBuildable(point.X, point.Y, 1.25f)) //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }, 1, new Color { R = 255, G = 0, B = 0 }); //} //else if (BuildingService.Blocked(point.X, point.Y, 1.25f, .1f)) //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }, 1, new Color { R = 255, G = 255, B = 0 }); //} //else if (BuildingService.HasCreep(point.X, point.Y, 1.5f)) //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }, 1, new Color { R = 255, G = 255, B = 255 }); //} //else //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }, 1, new Color { R = 0, G = 255, B = 0 }); //} if (BuildingService.AreaBuildable(point.X, point.Y, 1.25f) && (minimumMineralProximinity == 0 || !BuildingService.BlocksResourceCenter(point.X, point.Y, 1.25f)) && !BuildingService.Blocked(point.X, point.Y, 1.25f, .1f) && !BuildingService.HasCreep(point.X, point.Y, 1.5f) && (!requireSameHeight || MapDataService.MapHeight(point) == MapDataService.MapHeight(reference))) { var mineralFields = ActiveUnitData.NeutralUnits.Where(u => SharkyUnitData.MineralFieldTypes.Contains((UnitTypes)u.Value.Unit.UnitType) || SharkyUnitData.GasGeyserTypes.Contains((UnitTypes)u.Value.Unit.UnitType)); var squared = (1 + minimumMineralProximinity + .5) * (1 + minimumMineralProximinity + .5); var nexusDistanceSquared = 16f; if (minimumMineralProximinity == 0) { nexusDistanceSquared = 0; } var nexusClashes = ActiveUnitData.SelfUnits.Where(u => (u.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_NEXUS || u.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON) && Vector2.DistanceSquared(u.Value.Position, new Vector2(point.X, point.Y)) < squared + nexusDistanceSquared); if (nexusClashes.Count() == 0) { var clashes = mineralFields.Where(u => Vector2.DistanceSquared(u.Value.Position, new Vector2(point.X, point.Y)) < squared); if (clashes.Count() == 0) { if (Vector2.DistanceSquared(new Vector2(reference.X, reference.Y), new Vector2(point.X, point.Y)) <= maxDistance * maxDistance) { DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }); return(point); } } } } angle += sliceSize; } radius += 1; } return(null); }
public Point2D FindPlacement(Point2D target, UnitTypes unitType, int size, bool ignoreResourceProximity = false, float maxDistance = 50, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.None) { var mineralProximity = 2; if (ignoreResourceProximity) { mineralProximity = 0; } ; if (wallOffType == WallOffType.Full) { if (!BuildingService.FullyWalled()) { var point = WallOffPlacement.FindPlacement(target, unitType, size, ignoreResourceProximity, maxDistance, requireSameHeight, wallOffType); if (point != null) { return(point); } } } else if (wallOffType == WallOffType.Partial) { if (!BuildingService.PartiallyWalled()) { var point = WallOffPlacement.FindPlacement(target, unitType, size, ignoreResourceProximity, maxDistance, requireSameHeight, wallOffType); if (point != null) { return(point); } } } if (unitType == UnitTypes.PROTOSS_PYLON) { return(FindPylonPlacement(target, maxDistance, mineralProximity, requireSameHeight, wallOffType)); } else { return(FindProductionPlacement(target, size, maxDistance, mineralProximity, wallOffType)); } }
public Point2D FindProductionPlacement(Point2D target, float size, float maxDistance, float minimumMineralProximinity = 2, WallOffType wallOffType = WallOffType.None) { var targetVector = new Vector2(target.X, target.Y); var powerSources = ActiveUnitData.Commanders.Values.Where(c => c.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON && c.UnitCalculation.Unit.BuildProgress == 1).OrderBy(c => Vector2.DistanceSquared(c.UnitCalculation.Position, targetVector)); foreach (var powerSource in powerSources) { if (Vector2.DistanceSquared(new Vector2(target.X, target.Y), powerSource.UnitCalculation.Position) > (maxDistance + 8) * (maxDistance + 8)) { break; } var x = powerSource.UnitCalculation.Unit.Pos.X; var y = powerSource.UnitCalculation.Unit.Pos.Y; var radius = size / 2f; var powerRadius = 7 - (size / 2f); // start at 12 o'clock then rotate around 12 times, increase radius by 1 until it's more than powerRadius while (radius <= powerRadius) { var fullCircle = Math.PI * 2; var sliceSize = fullCircle / 24.0; var angle = 0.0; while (angle + (sliceSize / 2) < fullCircle) { var point = new Point2D { X = x + (float)(radius * Math.Cos(angle)), Y = y + (float)(radius * Math.Sin(angle)) }; //DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }); //if (!BuildingService.AreaBuildable(point.X, point.Y, 1.25f)) //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 10 }, 1, new Color { R = 255, G = 0, B = 0 }); //} //else if (BuildingService.Blocked(point.X, point.Y, 1.25f)) //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 10 }, 1, new Color { R = 255, G = 255, B = 0 }); //} //else if (BuildingService.HasCreep(point.X, point.Y, 1.5f)) //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 10 }, 1, new Color { R = 255, G = 255, B = 255 }); //} //else //{ // DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 10 }, 1, new Color { R = 0, G = 255, B = 0 }); //} var vector = new Vector2(point.X, point.Y); var tooClose = false; if (MapDataService.MapData.BlockWallData != null && MapDataService.MapData.BlockWallData.Any(d => d.Pylons.Any(p => Vector2.DistanceSquared(new Vector2(p.X, p.Y), vector) < 25))) { tooClose = true; } if (!tooClose && BuildingService.SameHeight(point.X, point.Y, size + 1 / 2.0f) && (minimumMineralProximinity == 0 || !BuildingService.BlocksResourceCenter(point.X, point.Y, size + 1 / 2.0f)) && BuildingService.AreaBuildable(point.X, point.Y, (size + 1) / 2.0f) && !BuildingService.Blocked(point.X, point.Y, (size + 1) / 2.0f) && !BuildingService.HasCreep(point.X, point.Y, size / 2.0f)) // size +1 because want 1 space to move around to prevent walling self in { var mineralFields = ActiveUnitData.NeutralUnits.Where(u => SharkyUnitData.MineralFieldTypes.Contains((UnitTypes)u.Value.Unit.UnitType)); var squared = (1 + minimumMineralProximinity + (size / 2f)) * (1 + minimumMineralProximinity + (size / 2f)); var clashes = mineralFields.Where(u => Vector2.DistanceSquared(u.Value.Position, new Vector2(point.X, point.Y)) < squared); if (clashes.Count() == 0) { if (Vector2.DistanceSquared(new Vector2(target.X, target.Y), new Vector2(point.X, point.Y)) <= maxDistance * maxDistance) { DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }); return(point); } } } angle += sliceSize; } radius += 1; } } return(FindProductionPlacementTryHarder(target, size, maxDistance, minimumMineralProximinity)); }
public Point2D FindPlacement(Point2D target, UnitTypes unitType, int size, bool ignoreMineralProximity = true, float maxDistance = 50, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.None) { var powerSources = ActiveUnitData.Commanders.Values.Where(c => c.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON || c.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISMPHASING && c.UnitCalculation.Unit.BuildProgress == 1).OrderBy(c => Vector2.DistanceSquared(c.UnitCalculation.Position, new Vector2(target.X, target.Y))); foreach (var powerSource in powerSources) { var x = powerSource.UnitCalculation.Unit.Pos.X; var y = powerSource.UnitCalculation.Unit.Pos.Y; var sourceRadius = 7f; if (powerSource.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISMPHASING) { sourceRadius = 5f; } var radius = 1 + (size / 2f); var powerRadius = sourceRadius - (size / 2f); // start at 12 o'clock then rotate around 12 times, increase radius by 1 until it's more than powerRadius while (radius < powerRadius) { var fullCircle = Math.PI * 2; var sliceSize = fullCircle / 12.0; var angle = 0.0; while (angle + (sliceSize / 2) < fullCircle) { var point = new Point2D { X = x + (float)(radius * Math.Cos(angle)), Y = y + (float)(radius * Math.Sin(angle)) }; if (AreaPlaceable(point.X, point.Y, size / 2.0f) && !Blocked(point.X, point.Y, size / 2.0f)) { DebugService.DrawSphere(new Point { X = point.X, Y = point.Y, Z = 12 }); return(point); } angle += sliceSize; } radius += 1; } } return(null); }
public Point2D FindPlacement(Point2D target, UnitTypes unitType, int size, bool ignoreResourceProximity = false, float maxDistance = 50, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.None) { var mineralProximity = 2; if (ignoreResourceProximity) { mineralProximity = 0; } ; return(FindTechPlacement(target, size, maxDistance, mineralProximity)); }
public Point2D FindPlacement(Point2D target, UnitTypes unitType, int size, bool ignoreResourceProximity = false, float maxDistance = 50, bool requireSameHeight = false, WallOffType wallOffType = WallOffType.None) { var mineralProximity = 2; if (ignoreResourceProximity) { mineralProximity = 0; } ; if (unitType == UnitTypes.TERRAN_BARRACKS || unitType == UnitTypes.TERRAN_FACTORY || unitType == UnitTypes.TERRAN_STARPORT) { return(FindProductionPlacement(target, size, maxDistance, mineralProximity)); } return(FindTechPlacement(target, size, maxDistance, mineralProximity)); }