private bool Unbuildable(BuildRequest request)
        {
            if (UnitTypes.ResourceCenters.Contains(request.Type))
            {
                if (request.Type != UnitTypes.HATCHERY)
                {
                    // Check for creep.
                    BoolGrid creep = new ImageBoolGrid(Tyr.Bot.Observation.Observation.RawData.MapState.Creep, 1);
                    for (float dx = -2.5f; dx <= 2.51f; dx++)
                    {
                        for (float dy = -2.5f; dy <= 2.51f; dy++)
                        {
                            if (creep[(int)(request.Pos.X + dx), (int)(request.Pos.Y + dy)])
                            {
                                return(true);
                            }
                        }
                    }
                }
                foreach (BuildingLocation loc in Tyr.Bot.EnemyManager.EnemyBuildings.Values)
                {
                    if (SC2Util.DistanceSq(request.Pos, loc.Pos) <= 6 * 6)
                    {
                        return(true);
                    }
                }
                foreach (Unit enemy in Tyr.Bot.Enemies())
                {
                    if (!enemy.IsFlying &&
                        SC2Util.DistanceSq(request.Pos, enemy.Pos) <= 6 * 6)
                    {
                        return(true);
                    }
                }
                return(false);
            }

            if (UnitTypes.GasGeysers.Contains(request.Type) ||
                UnitTypes.ResourceCenters.Contains(request.Type) ||
                UnitTypes.PYLON == request.Type)
            {
                return(false);
            }

            if (Tyr.Bot.MyRace == Race.Terran && request.Type != UnitTypes.COMMAND_CENTER)
            {
                return(false);
            }

            return(!Tyr.Bot.buildingPlacer.CheckPlacement(request.Pos, BuildingType.LookUp[request.Type].Size, request.Type, request, true));
        }
        public static bool RectBuildable(float x1, float y1, float x2, float y2)
        {
            BoolGrid creep = new ImageBoolGrid(Bot.Main.Observation.Observation.RawData.MapState.Creep, 1);

            for (float x = x1; x <= x2; x++)
            {
                for (float y = y1; y <= y2; y++)
                {
                    if (!SC2Util.GetTilePlacable((int)x, (int)y) || creep[(int)(x), (int)(y)])
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Beispiel #3
0
        public static bool CheckPlacement(Point2D location, Point2D size, uint type, BuildRequest skipRequest, bool buildingsOnly)
        {
            // Check if the building can be placed on this position of the map.
            for (float x = -size.X / 2f; x < size.X / 2f + 0.1f; x++)
            {
                for (float y = -size.Y / 2f; y < size.Y / 2f + 0.1f; y++)
                {
                    if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + x), (int)Math.Round(location.Y + y)))
                    {
                        return(false);
                    }
                }
            }

            if (CanHaveAddOn(type))
            {
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 2f), (int)Math.Round(location.Y - 1)))
                {
                    return(false);
                }
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 2f), (int)Math.Round(location.Y)))
                {
                    return(false);
                }
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 3f), (int)Math.Round(location.Y - 1)))
                {
                    return(false);
                }
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 3f), (int)Math.Round(location.Y)))
                {
                    return(false);
                }
            }

            foreach (Unit unit in Tyr.Bot.Observation.Observation.RawData.Units)
            {
                if (!unit.IsFlying && (unit.Owner != Tyr.Bot.PlayerId || unit.UnitType == UnitTypes.SIEGE_TANK_SIEGED || UnitTypes.BuildingTypes.Contains(unit.UnitType)) && !CheckDistance(location, type, SC2Util.To2D(unit.Pos), unit.UnitType, buildingsOnly))
                {
                    return(false);
                }
            }

            foreach (BuildRequest request in ConstructionTask.Task.UnassignedRequests)
            {
                if (request != skipRequest && !CheckDistance(location, type, request.Pos, request.Type, buildingsOnly))
                {
                    return(false);
                }
            }

            foreach (BuildRequest request in ConstructionTask.Task.BuildRequests)
            {
                if (request != skipRequest && !CheckDistance(location, type, request.Pos, request.Type, buildingsOnly))
                {
                    return(false);
                }
            }

            if (Tyr.Bot.MyRace == Race.Zerg && type != UnitTypes.HATCHERY && type != UnitTypes.EXTRACTOR)
            {
                BoolGrid creep = new ImageBoolGrid(Tyr.Bot.Observation.Observation.RawData.MapState.Creep, 1);
                for (float dx = -size.X / 2f; dx <= size.X / 2f + 0.01f; dx++)
                {
                    for (float dy = -size.Y / 2f; dy <= size.Y / 2f + 0.01f; dy++)
                    {
                        if (!creep[(int)(location.X + dx), (int)(location.Y + dy)])
                        {
                            return(false);
                        }
                    }
                }
            }
            if (Tyr.Bot.MyRace != Race.Zerg)
            {
                BoolGrid creep = new ImageBoolGrid(Tyr.Bot.Observation.Observation.RawData.MapState.Creep, 1);
                for (float dx = -size.X / 2f; dx <= size.X / 2f + 0.01f; dx++)
                {
                    for (float dy = -size.Y / 2f; dy <= size.Y / 2f + 0.01f; dy++)
                    {
                        if (creep[(int)(location.X + dx), (int)(location.Y + dy)])
                        {
                            return(false);
                        }
                    }
                }
            }

            if (type != UnitTypes.PYLON && Tyr.Bot.MyRace == Race.Protoss)
            {
                foreach (Unit unit in Tyr.Bot.Observation.Observation.RawData.Units)
                {
                    if (unit.UnitType != UnitTypes.PYLON || unit.BuildProgress < 1)
                    {
                        continue;
                    }

                    if (Tyr.Bot.MapAnalyzer.MapHeight((int)unit.Pos.X, (int)unit.Pos.Y) < Tyr.Bot.MapAnalyzer.MapHeight((int)location.X, (int)location.Y))
                    {
                        continue;
                    }

                    if (location.X - size.X / 2f >= unit.Pos.X - 6 && location.X + size.X / 2f <= unit.Pos.X + 6 &&
                        location.Y - size.Y / 2f >= unit.Pos.Y - 7 && location.Y + size.Y / 2f <= unit.Pos.Y + 7)
                    {
                        if (SC2Util.DistanceGrid(unit.Pos, location) <= 10 - size.X / 2f - size.Y / 2f)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }

            return(true);
        }
Beispiel #4
0
        public static bool ConstructResourceCenter(uint unitType)
        {
            // Check if there is already a Resource center constructing.
            foreach (Agent unit in Tyr.Bot.UnitManager.Agents.Values)
            {
                if (unit.IsWorker && unit.Unit.Orders != null && unit.Unit.Orders.Count > 0 && unit.Unit.Orders[0].AbilityId == BuildingType.LookUp[unitType].Ability)
                {
                    return(false);
                }
            }

            Base  picked  = null;
            float dist    = 1000000000;
            bool  natural = Tyr.Bot.UnitManager.Count(unitType) == 1;

            foreach (Base loc in Tyr.Bot.BaseManager.Bases)
            {
                if (loc.Owner != -1)
                {
                    continue;
                }
                bool blocked = false;
                foreach (Unit enemy in Tyr.Bot.Enemies())
                {
                    if (SC2Util.DistanceSq(enemy.Pos, loc.BaseLocation.Pos) <= 6 * 6)
                    {
                        blocked = true;
                        break;
                    }
                }
                if (blocked)
                {
                    continue;
                }

                if (unitType != UnitTypes.HATCHERY)
                {
                    // Check for creep.
                    BoolGrid creep = new ImageBoolGrid(Tyr.Bot.Observation.Observation.RawData.MapState.Creep, 1);
                    for (float dx = -2.5f; !blocked && dx <= 2.51f; dx++)
                    {
                        for (float dy = -2.5f; !blocked && dy <= 2.51f; dy++)
                        {
                            if (creep[(int)(loc.BaseLocation.Pos.X + dx), (int)(loc.BaseLocation.Pos.Y + dy)])
                            {
                                blocked = true;
                            }
                        }
                    }
                    if (blocked)
                    {
                        continue;
                    }
                }

                foreach (Agent agent in Tyr.Bot.UnitManager.Agents.Values)
                {
                    if (!agent.IsBuilding)
                    {
                        continue;
                    }
                    blocked = System.Math.Abs(agent.Unit.Pos.X - loc.BaseLocation.Pos.X) < 5 &&
                              System.Math.Abs(agent.Unit.Pos.Y - loc.BaseLocation.Pos.Y) < 5;
                    if (blocked)
                    {
                        break;
                    }
                }
                if (blocked)
                {
                    File.AppendAllLines(Directory.GetCurrentDirectory() + "/Data/Tyr/debug.txt", new string[] { "Base at " + loc.BaseLocation.Pos + " blocked by allied unit." });
                    continue;
                }

                // Ignore the pocket expand as a first base.
                if (natural && Tyr.Bot.MapAnalyzer.EnemyDistances[(int)loc.BaseLocation.Pos.X, (int)loc.BaseLocation.Pos.Y] > Tyr.Bot.MapAnalyzer.EnemyDistances[(int)Tyr.Bot.MapAnalyzer.StartLocation.X, (int)Tyr.Bot.MapAnalyzer.StartLocation.Y])
                {
                    continue;
                }
                int newdist = loc.DistanceToMain;
                if (newdist < dist)
                {
                    dist   = newdist;
                    picked = loc;
                }
            }
            if (picked == null)
            {
                ConstructionTask.Task.ExpandingBlockedUntilFrame = Tyr.Bot.Frame + 112;
                return(false);
            }

            ConstructionTask.Task.Build(unitType, picked, picked.BaseLocation.Pos, null, false);
            return(true);
        }
Beispiel #5
0
        public bool CheckPlacement(Point2D location, Point2D size, uint type, BuildRequest skipRequest, bool buildingsOnly)
        {
            // Check if the building can be placed on this position of the map.
            for (float x = -size.X / 2f; x < size.X / 2f + 0.1f; x++)
            {
                for (float y = -size.Y / 2f; y < size.Y / 2f + 0.1f; y++)
                {
                    if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + x), (int)Math.Round(location.Y + y)))
                    {
                        return(false);
                    }
                }
            }

            if (BuildInsideMainOnly)
            {
                for (float x = -size.X / 2f; x < size.X / 2f + 0.1f; x++)
                {
                    for (float y = -size.Y / 2f; y < size.Y / 2f + 0.1f; y++)
                    {
                        if (!Tyr.Bot.MapAnalyzer.StartArea[(int)Math.Round(location.X + x), (int)Math.Round(location.Y + y)])
                        {
                            return(false);
                        }
                    }
                }
            }

            if (!UnitTypes.ResourceCenters.Contains(type))
            {
                foreach (Base b in Tyr.Bot.BaseManager.Bases)
                {
                    if (Math.Abs(b.BaseLocation.Pos.X - location.X) < 5 &&
                        Math.Abs(b.BaseLocation.Pos.Y - location.Y) < 5)
                    {
                        return(false);
                    }
                }
            }

            foreach (Unit unit in bot.Observation.Observation.RawData.Units)
            {
                if (!CheckDistance(location, type, SC2Util.To2D(unit.Pos), unit.UnitType, buildingsOnly))
                {
                    return(false);
                }
            }

            foreach (BuildRequest request in ConstructionTask.Task.UnassignedRequests)
            {
                if (request != skipRequest && !CheckDistance(location, type, request.Pos, request.Type, buildingsOnly))
                {
                    return(false);
                }
            }

            foreach (BuildRequest request in ConstructionTask.Task.BuildRequests)
            {
                if (request != skipRequest && !CheckDistance(location, type, request.Pos, request.Type, buildingsOnly))
                {
                    return(false);
                }
            }

            if (Tyr.Bot.MyRace == Race.Zerg && type != UnitTypes.HATCHERY && type != UnitTypes.EXTRACTOR)
            {
                BoolGrid creep = new ImageBoolGrid(bot.Observation.Observation.RawData.MapState.Creep, 1);
                for (float dx = -size.X / 2f; dx <= size.X / 2f + 0.01f; dx++)
                {
                    for (float dy = -size.Y / 2f; dy <= size.Y / 2f + 0.01f; dy++)
                    {
                        if (!creep[(int)(location.X + dx), (int)(location.Y + dy)])
                        {
                            return(false);
                        }
                    }
                }
            }

            if (type != UnitTypes.PYLON && bot.MyRace == Race.Protoss)
            {
                foreach (Unit unit in bot.Observation.Observation.RawData.Units)
                {
                    if (unit.UnitType != UnitTypes.PYLON || unit.BuildProgress < 1)
                    {
                        continue;
                    }

                    if (Tyr.Bot.MapAnalyzer.MapHeight((int)unit.Pos.X, (int)unit.Pos.Y) < Tyr.Bot.MapAnalyzer.MapHeight((int)location.X, (int)location.Y))
                    {
                        continue;
                    }

                    if (location.X - size.X / 2f >= unit.Pos.X - 6 && location.X + size.X / 2f <= unit.Pos.X + 6 &&
                        location.Y - size.Y / 2f >= unit.Pos.Y - 7 && location.Y + size.Y / 2f <= unit.Pos.Y + 7)
                    {
                        if (SC2Util.DistanceGrid(unit.Pos, location) <= 10 - size.X / 2f - size.Y / 2f)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }

            return(true);
        }
Beispiel #6
0
        private bool Unbuildable(BuildRequest request)
        {
            if (UnitTypes.ResourceCenters.Contains(request.Type))
            {
                if (request.Type != UnitTypes.HATCHERY)
                {
                    // Check for creep.
                    BoolGrid creep = new ImageBoolGrid(Tyr.Bot.Observation.Observation.RawData.MapState.Creep, 1);
                    for (float dx = -2.5f; dx <= 2.51f; dx++)
                    {
                        for (float dy = -2.5f; dy <= 2.51f; dy++)
                        {
                            if (creep[(int)(request.Pos.X + dx), (int)(request.Pos.Y + dy)])
                            {
                                return(true);
                            }
                        }
                    }
                }
                foreach (BuildingLocation loc in Tyr.Bot.EnemyManager.EnemyBuildings.Values)
                {
                    if (SC2Util.DistanceSq(request.Pos, loc.Pos) <= 6 * 6)
                    {
                        return(true);
                    }
                }
                foreach (Unit enemy in Tyr.Bot.Enemies())
                {
                    if (!enemy.IsFlying &&
                        SC2Util.DistanceSq(request.Pos, enemy.Pos) <= 6 * 6)
                    {
                        return(true);
                    }
                }
                return(false);
            }

            if (UnitTypes.GasGeysers.Contains(request.Type) ||
                UnitTypes.ResourceCenters.Contains(request.Type) ||
                UnitTypes.PYLON == request.Type)
            {
                return(false);
            }

            if (Tyr.Bot.MyRace != Race.Zerg && request.Type != UnitTypes.COMMAND_CENTER && request.Type != UnitTypes.NEXUS)
            {
                Point2D  size  = BuildingType.LookUp[request.Type].Size;
                BoolGrid creep = new ImageBoolGrid(Tyr.Bot.Observation.Observation.RawData.MapState.Creep, 1);
                for (float dx = -size.X / 2f; dx <= size.X / 2f + 0.01f; dx++)
                {
                    for (float dy = -size.Y / 2f; dy <= size.Y / 2f + 0.01f; dy++)
                    {
                        if (creep[(int)(request.Pos.X + dx), (int)(request.Pos.Y + dy)])
                        {
                            return(true);
                        }
                    }
                }

                foreach (Agent agent in Tyr.Bot.UnitManager.Agents.Values)
                {
                    if (!agent.IsBuilding && agent.Unit.UnitType != UnitTypes.SIEGE_TANK_SIEGED)
                    {
                        continue;
                    }
                    if (agent.DistanceSq(request.Pos) <= (agent.Unit.UnitType == UnitTypes.SIEGE_TANK_SIEGED ? (2 * 2) : 2))
                    {
                        return(true);
                    }
                }

                foreach (BuildRequest existingRequest in UnassignedRequests)
                {
                    if (existingRequest == request)
                    {
                        continue;
                    }
                    if (SC2Util.DistanceSq(existingRequest.Pos, request.Pos) <= 2)
                    {
                        return(true);
                    }
                }

                foreach (BuildRequest existingRequest in BuildRequests)
                {
                    if (existingRequest == request)
                    {
                        continue;
                    }
                    if (SC2Util.DistanceSq(existingRequest.Pos, request.Pos) <= 2)
                    {
                        return(true);
                    }
                }
                return(false);
            }

            return(!Tyr.Bot.buildingPlacer.CheckPlacement(request.Pos, BuildingType.LookUp[request.Type].Size, request.Type, request, true));
        }
Beispiel #7
0
        public bool CheckPlacement(Point2D location, Point2D size, uint type, BuildRequest skipRequest, bool buildingsOnly)
        {
            // Check if the building can be placed on this position of the map.
            for (float x = -size.X / 2f; x < size.X / 2f + 0.1f; x++)
            {
                for (float y = -size.Y / 2f; y < size.Y / 2f + 0.1f; y++)
                {
                    if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + x), (int)Math.Round(location.Y + y)))
                    {
                        return(false);
                    }
                }
            }

            if (CanHaveAddOn(type))
            {
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 2f), (int)Math.Round(location.Y - 1)))
                {
                    return(false);
                }
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 2f), (int)Math.Round(location.Y)))
                {
                    return(false);
                }
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 3f), (int)Math.Round(location.Y - 1)))
                {
                    return(false);
                }
                if (!SC2Util.GetTilePlacable((int)Math.Round(location.X + 3f), (int)Math.Round(location.Y)))
                {
                    return(false);
                }
            }

            if (BuildInsideMainOnly)
            {
                for (float x = -size.X / 2f; x < size.X / 2f + 0.1f; x++)
                {
                    for (float y = -size.Y / 2f; y < size.Y / 2f + 0.1f; y++)
                    {
                        if (!Tyr.Bot.MapAnalyzer.StartArea[(int)Math.Round(location.X + x), (int)Math.Round(location.Y + y)])
                        {
                            return(false);
                        }
                    }
                }
            }

            if (!UnitTypes.ResourceCenters.Contains(type))
            {
                float baseDistance = (type == UnitTypes.MISSILE_TURRET || type == UnitTypes.SPORE_CRAWLER || type == UnitTypes.PYLON) ? 3f : 5f;
                foreach (Base b in Tyr.Bot.BaseManager.Bases)
                {
                    if (Math.Abs(b.BaseLocation.Pos.X - location.X) < baseDistance &&
                        Math.Abs(b.BaseLocation.Pos.Y - location.Y) < baseDistance)
                    {
                        return(false);
                    }

                    foreach (MineralField mineral in b.BaseLocation.MineralFields)
                    {
                        Point2D halfWay = SC2Util.Point((mineral.Pos.X + b.BaseLocation.Pos.X) / 2f, (mineral.Pos.Y + b.BaseLocation.Pos.Y) / 2f);
                        if (SC2Util.DistanceSq(halfWay, location) <= 4 * 4)
                        {
                            return(false);
                        }
                    }
                    foreach (Gas gas in b.BaseLocation.Gasses)
                    {
                        Point2D halfWay = SC2Util.Point((gas.Pos.X + b.BaseLocation.Pos.X) / 2f, (gas.Pos.Y + b.BaseLocation.Pos.Y) / 2f);
                        if (SC2Util.DistanceSq(halfWay, location) <= 4 * 4)
                        {
                            return(false);
                        }
                    }
                }
            }

            foreach (Unit unit in bot.Observation.Observation.RawData.Units)
            {
                if (!unit.IsFlying && !CheckDistance(location, type, SC2Util.To2D(unit.Pos), unit.UnitType, buildingsOnly))
                {
                    return(false);
                }
            }

            foreach (BuildRequest request in ConstructionTask.Task.UnassignedRequests)
            {
                if (request != skipRequest && !CheckDistance(location, type, request.Pos, request.Type, buildingsOnly))
                {
                    return(false);
                }
            }

            foreach (BuildRequest request in ConstructionTask.Task.BuildRequests)
            {
                if (request != skipRequest && !CheckDistance(location, type, request.Pos, request.Type, buildingsOnly))
                {
                    return(false);
                }
            }

            foreach (ReservedBuilding building in Tyr.Bot.buildingPlacer.ReservedLocation)
            {
                if (!CheckDistClose(location.X - 1.5f, location.Y - 1.5f, location.X + 1.5f, location.Y + 1.5f, building.Pos, building.Type))
                {
                    return(false);
                }
            }

            if (Tyr.Bot.MyRace == Race.Zerg && type != UnitTypes.HATCHERY && type != UnitTypes.EXTRACTOR)
            {
                BoolGrid creep = new ImageBoolGrid(bot.Observation.Observation.RawData.MapState.Creep, 1);
                for (float dx = -size.X / 2f; dx <= size.X / 2f + 0.01f; dx++)
                {
                    for (float dy = -size.Y / 2f; dy <= size.Y / 2f + 0.01f; dy++)
                    {
                        if (!creep[(int)(location.X + dx), (int)(location.Y + dy)])
                        {
                            return(false);
                        }
                    }
                }
            }
            if (Tyr.Bot.MyRace != Race.Zerg)
            {
                BoolGrid creep = new ImageBoolGrid(bot.Observation.Observation.RawData.MapState.Creep, 1);
                for (float dx = -size.X / 2f; dx <= size.X / 2f + 0.01f; dx++)
                {
                    for (float dy = -size.Y / 2f; dy <= size.Y / 2f + 0.01f; dy++)
                    {
                        if (creep[(int)(location.X + dx), (int)(location.Y + dy)])
                        {
                            return(false);
                        }
                    }
                }
            }

            if (type != UnitTypes.PYLON && bot.MyRace == Race.Protoss)
            {
                foreach (Unit unit in bot.Observation.Observation.RawData.Units)
                {
                    if (unit.UnitType != UnitTypes.PYLON || unit.BuildProgress < 1)
                    {
                        continue;
                    }

                    if (Tyr.Bot.MapAnalyzer.MapHeight((int)unit.Pos.X, (int)unit.Pos.Y) < Tyr.Bot.MapAnalyzer.MapHeight((int)location.X, (int)location.Y))
                    {
                        continue;
                    }

                    if (location.X - size.X / 2f >= unit.Pos.X - 6 && location.X + size.X / 2f <= unit.Pos.X + 6 &&
                        location.Y - size.Y / 2f >= unit.Pos.Y - 7 && location.Y + size.Y / 2f <= unit.Pos.Y + 7)
                    {
                        if (SC2Util.DistanceGrid(unit.Pos, location) <= 10 - size.X / 2f - size.Y / 2f)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }

            return(true);
        }
Beispiel #8
0
        public static bool ConstructResourceCenter(uint unitType)
        {
            // Check if there is already a Resource center constructing.
            foreach (Agent unit in Bot.Main.UnitManager.Agents.Values)
            {
                if (unit.IsWorker && unit.Unit.Orders != null && unit.Unit.Orders.Count > 0 && unit.Unit.Orders[0].AbilityId == BuildingType.LookUp[unitType].Ability)
                {
                    return(false);
                }
            }

            Base  picked  = null;
            float dist    = 1000000000;
            bool  natural = Bot.Main.UnitManager.Count(unitType) == 1;

            foreach (Base loc in Bot.Main.BaseManager.Bases)
            {
                if (loc.Owner != -1)
                {
                    continue;
                }
                bool blocked = false;
                foreach (Unit enemy in Bot.Main.Enemies())
                {
                    if (enemy.IsFlying)
                    {
                        continue;
                    }
                    if (UnitTypes.WorkerTypes.Contains(enemy.UnitType))
                    {
                        continue;
                    }
                    if (IgnoreExpansionBlockingUnitTypes.Contains(enemy.UnitType))
                    {
                        continue;
                    }
                    if (SC2Util.DistanceSq(enemy.Pos, loc.BaseLocation.Pos) <= 6 * 6)
                    {
                        blocked = true;
                        break;
                    }
                }
                if (blocked)
                {
                    continue;
                }

                if (unitType != UnitTypes.HATCHERY)
                {
                    // Check for creep.
                    BoolGrid creep = new ImageBoolGrid(Bot.Main.Observation.Observation.RawData.MapState.Creep, 1);
                    for (float dx = -2.5f; !blocked && dx <= 2.51f; dx++)
                    {
                        for (float dy = -2.5f; !blocked && dy <= 2.51f; dy++)
                        {
                            if (creep[(int)(loc.BaseLocation.Pos.X + dx), (int)(loc.BaseLocation.Pos.Y + dy)])
                            {
                                blocked = true;
                            }
                        }
                    }
                    if (blocked)
                    {
                        continue;
                    }
                }

                foreach (BuildingPlacement.ReservedBuilding reservedBuilding in Bot.Main.buildingPlacer.ReservedLocation)
                {
                    if (SC2Util.DistanceSq(reservedBuilding.Pos, loc.BaseLocation.Pos) <= 3 * 3)
                    {
                        blocked = true;
                        break;
                    }
                }
                if (blocked)
                {
                    continue;
                }

                foreach (Agent agent in Bot.Main.UnitManager.Agents.Values)
                {
                    if (!agent.IsBuilding)
                    {
                        continue;
                    }
                    blocked = !Bot.Main.buildingPlacer.CheckDistanceClose(loc.BaseLocation.Pos, unitType, SC2Util.To2D(agent.Unit.Pos), agent.Unit.UnitType);
                    //blocked = System.Math.Abs(agent.Unit.Pos.X - loc.BaseLocation.Pos.X) < 5
                    //    && System.Math.Abs(agent.Unit.Pos.Y - loc.BaseLocation.Pos.Y) < 5;
                    if (blocked)
                    {
                        break;
                    }
                }
                if (blocked)
                {
                    continue;
                }

                // Ignore the pocket expand as a first base.
                if (natural && Bot.Main.MapAnalyzer.EnemyDistances[(int)loc.BaseLocation.Pos.X, (int)loc.BaseLocation.Pos.Y] > Bot.Main.MapAnalyzer.EnemyDistances[(int)Bot.Main.MapAnalyzer.StartLocation.X, (int)Bot.Main.MapAnalyzer.StartLocation.Y])
                {
                    continue;
                }
                int newdist = loc.DistanceToMain - Bot.Main.MapAnalyzer.EnemyDistances[(int)loc.BaseLocation.Pos.X, (int)loc.BaseLocation.Pos.Y];
                if (newdist < dist)
                {
                    dist   = newdist;
                    picked = loc;
                }
            }
            if (picked == null)
            {
                ConstructionTask.Task.ExpandingBlockedUntilFrame = Bot.Main.Frame + 112;
                return(false);
            }

            ConstructionTask.Task.Build(unitType, picked, picked.BaseLocation.Pos, null, false);
            return(true);
        }