public Point2D FindTechPlacement(Point2D reference, float size, float maxDistance, float minimumMineralProximinity = 2)
        {
            var x      = reference.X;
            var y      = reference.Y;
            var radius = size / 2f;

            // 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 / (4.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))
                    };
                    if (BuildingService.HasCreep(point.X, point.Y, size / 2.0f) && BuildingService.AreaBuildable(point.X, point.Y, size / 2.0f) && !BuildingService.Blocked(point.X, point.Y, size / 2.0f))
                    {
                        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)
                        {
                            var productionStructures = ActiveUnitData.SelfUnits.Where(u => u.Value.Unit.UnitType == (uint)UnitTypes.TERRAN_BARRACKS || u.Value.Unit.UnitType == (uint)UnitTypes.TERRAN_FACTORY || u.Value.Unit.UnitType == (uint)UnitTypes.TERRAN_STARPORT);
                            if (!productionStructures.Any(u => Vector2.DistanceSquared(u.Value.Position, new Vector2(point.X, point.Y)) < 16))
                            {
                                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);
        }
 private bool Buildable(Point2D point, float radius)
 {
     if (BuildingService.AreaBuildable(point.X, point.Y, radius) && !BuildingService.Blocked(point.X, point.Y, radius, -.5f) && !BuildingService.HasCreep(point.X, point.Y, radius))
     {
         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 + .5) * (1 + .5);
         var 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)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Exemple #3
0
        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);
        }