public static void Construct(uint unitType) { Vector3 startingSpot; var resourceCenters = GetUnits(Units.ResourceCenters); if (resourceCenters.Count > 0) { startingSpot = resourceCenters[0].position; } else { Logger.Error("Unable to construct: {0}. No resource center was found.", GetUnitName(unitType)); return; } const int radius = 12; //trying to find a valid construction spot var mineralFields = GetUnits(Units.MineralFields, onlyVisible: true, alliance: Alliance.Neutral); Vector3 constructionSpot; while (true) { constructionSpot = new Vector3(startingSpot.X + random.Next(-radius, radius + 1), startingSpot.Y + random.Next(-radius, radius + 1), 0); //avoid building in the mineral line if (IsInRange(constructionSpot, mineralFields, 5)) { continue; } //check if the building fits if (!CanPlace(unitType, constructionSpot)) { continue; } //ok, we found a spot break; } var worker = GetAvailableWorker(constructionSpot); if (worker == null) { Logger.Error("Unable to find worker to construct: {0}", GetUnitName(unitType)); return; } var abilityID = Abilities.GetID(unitType); var constructAction = CreateRawUnitCommand(abilityID); constructAction.ActionRaw.UnitCommand.UnitTags.Add(worker.tag); constructAction.ActionRaw.UnitCommand.TargetWorldSpacePos = new Point2D(); constructAction.ActionRaw.UnitCommand.TargetWorldSpacePos.X = constructionSpot.X; constructAction.ActionRaw.UnitCommand.TargetWorldSpacePos.Y = constructionSpot.Y; AddAction(constructAction); Logger.Info("Constructing: {0} @ {1} / {2}", GetUnitName(unitType), constructionSpot.X, constructionSpot.Y); }
public static void DistributeWorkers() { var workers = GetUnits(Units.Workers); List <Unit> idleWorkers = new List <Unit>(); foreach (var worker in workers) { if (worker.order.AbilityId != 0) { continue; } idleWorkers.Add(worker); } if (idleWorkers.Count > 0) { var resourceCenters = GetUnits(Units.ResourceCenters, onlyCompleted: true); var mineralFields = GetUnits(Units.MineralFields, onlyVisible: true, alliance: Alliance.Neutral); foreach (var rc in resourceCenters) { //get one of the closer mineral fields var mf = GetFirstInRange(rc.position, mineralFields, 7); if (mf == null) { continue; } //only one at a time Logger.Info("Distributing idle worker: {0}", idleWorkers[0].tag); idleWorkers[0].Smart(mf); return; } //nothing to be done return; } else { //let's see if we can distribute between bases var resourceCenters = GetUnits(Units.ResourceCenters, onlyCompleted: true); Unit transferFrom = null; Unit transferTo = null; foreach (var rc in resourceCenters) { if (rc.assignedWorkers <= rc.idealWorkers) { transferTo = rc; } else { transferFrom = rc; } } if ((transferFrom != null) && (transferTo != null)) { var mineralFields = GetUnits(Units.MineralFields, onlyVisible: true, alliance: Alliance.Neutral); var sqrDistance = 7 * 7; foreach (var worker in workers) { if (worker.order.AbilityId != Abilities.GATHER_MINERALS) { continue; } if (Vector3.DistanceSquared(worker.position, transferFrom.position) > sqrDistance) { continue; } var mf = GetFirstInRange(transferTo.position, mineralFields, 7); if (mf == null) { continue; } //only one at a time Logger.Info("Distributing idle worker: {0}", worker.tag); worker.Smart(mf); return; } } } }