コード例 #1
0
 public ProceduralConstruction(ILogging logBase, ProceduralConstructionSeed seed)
 {
     Logger           = logBase.Root().CreateProxy(GetType().Name);
     m_roomTree       = new MyDynamicAABBTree(Vector3.Zero);
     m_rooms          = new Dictionary <int, ProceduralRoom>();
     m_mountPoints    = new Dictionary <Vector3I, ProceduralMountPoint>();
     m_roomsSafeOrder = new List <ProceduralRoom>();
     Seed             = seed;
     BlockSetInfo     = new BlockSetInfo();
 }
コード例 #2
0
        private string ProcessSpawn(CommandFeedback feedback, Dictionary <string, object> kwargs)
        {
            var generatorModule = Manager.GetDependencyProvider <StationGeneratorManager>();

            if (generatorModule == null)
            {
                return("No station generator module means no stations");
            }
            var factionModule = Manager.GetDependencyProvider <ProceduralFactions>();

            if (factionModule == null)
            {
                return("No faction module means no stations");
            }

            var debugMode  = (bool)kwargs["debug"];
            var roomCount  = (int?)kwargs["rooms"];
            var seedVal    = (long)kwargs["seed"];
            var population = (int?)kwargs["population"];
            var position   = MyAPIGateway.Session.Camera.Position + MyAPIGateway.Session.Camera.WorldMatrix.Forward * 100;
            var seed       = new ProceduralConstructionSeed(factionModule.SeedAt(position), new Vector4D(position, 0.5), null, seedVal, population);

            MyAPIGateway.Parallel.Start(() =>
            {
                ProceduralConstruction construction = null;
                ConstructionCopy grids;
                if (!generatorModule.GenerateFromSeedAndRemap(seed, ref construction, out grids, roomCount))
                {
                    this.Error("Failed to generate");
                    feedback.Invoke("Failed to generate");
                    return;
                }
                if (grids == null)
                {
                    this.Error("Failed to generate: Output grids are null");
                    feedback.Invoke("Failed to generate: Output grids are null");
                    return;
                }
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                {
                    var result             = grids.SpawnAsync();
                    result.ForceDebugDraw |= debugMode;
                });
            });
            return(null);
        }
コード例 #3
0
        private string ProcessStationLocations(CommandFeedback feedback)
        {
            if (!MyAPIGateway.Session.HasCreativeRights)
            {
                return("You must have creative rights to use the station location command");
            }
            var stationModule = Manager.GetDependencyProvider <ProceduralStationModule>();

            if (stationModule == null)
            {
                return("No station module means no stations");
            }
            var factionModule = Manager.GetDependencyProvider <ProceduralFactions>();

            if (factionModule == null)
            {
                return("No faction module means no stations");
            }
            var stationNoise = stationModule.StationNoise;
            var sphere       = new BoundingSphereD(MyAPIGateway.Session.Camera.Position, MyAPIGateway.Session.SessionSettings.ViewDistance * 10);
            var id           = MyAPIGateway.Session.Player.IdentityId;
            var aabb         = new BoundingBoxD(sphere.Center - sphere.Radius, sphere.Center + sphere.Radius);

            foreach (var s in stationNoise.TryGetSpawnIn(aabb, sphere.Intersects))
            {
                var position = new Vector3D(s.Item2.X, s.Item2.Y, s.Item2.Z);
                var cseed    = new ProceduralConstructionSeed(factionModule.SeedAt(s.Item2.XYZ()), s.Item2, null, s.Item1.GetHashCode());
                var name     = "[" + cseed.Faction.Tag + "] " + cseed.Name;
                foreach (var gps2 in MyAPIGateway.Session.GPS.GetGpsList(id))
                {
                    if (gps2.Name.Equals(name))
                    {
                        MyAPIGateway.Session.GPS.RemoveGps(id, gps2);
                    }
                }
                var gps = MyAPIGateway.Session.GPS.Create(name, "", position, true, true);
                gps.DiscardAt = MyAPIGateway.Session.ElapsedPlayTime + new TimeSpan(0, 5, 0);
                MyAPIGateway.Session.GPS.AddGps(id, gps);
            }
            return(null);
        }
コード例 #4
0
 public bool GenerateFromSeedAndRemap(ProceduralConstructionSeed seed, ref ProceduralConstruction construction, out ConstructionCopy grids, int?roomCount = null)
 {
     grids = null;
     try
     {
         if (!GenerateFromSeed(seed, ref construction, roomCount))
         {
             Log(MyLogSeverity.Debug, "Failed to generate from seed");
             return(false);
         }
         var watch = new Stopwatch();
         watch.Restart();
         grids = GridCreator.RemapAndBuild(construction);
         Log(MyLogSeverity.Debug, "Added {0} rooms in {1}", construction.Rooms.Count(), watch.Elapsed);
         return(true);
     }
     catch (Exception e)
     {
         Log(MyLogSeverity.Error, "Failed to generate station.\n{0}", e.ToString());
         return(false);
     }
 }
コード例 #5
0
        private string ProcessDebugPart(CommandFeedback feedback, string partName)
        {
            var part = m_partManager.FirstOrDefault(test => test.Prefab.Id.SubtypeName.ToLower().Contains(partName.ToLower()));

            if (part == null)
            {
                return("Unable to find part with name \"" + partName + "\"");
            }
            var position = MyAPIGateway.Session.Camera.Position + MyAPIGateway.Session.Camera.WorldMatrix.Forward * 100;
            var seed     = new ProceduralConstructionSeed(new ProceduralFactionSeed("dummy", 0), new Vector4D(position, 0.5), null, 0);

            MyAPIGateway.Parallel.Start(() =>
            {
                var construction = new ProceduralConstruction(RootLogger, seed);
                var room         = new ProceduralRoom();
                room.Init(new MatrixI(Base6Directions.Direction.Forward, Base6Directions.Direction.Up), part);
                construction.AddRoom(room);
                var remapper = new RoomRemapper(RootLogger)
                {
                    DebugRoomColors = true
                };
                var grids = GridCreator.RemapAndBuild(construction, remapper);
                if (grids == null)
                {
                    return;
                }
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                {
                    var component = grids.SpawnAsync();
                    if (component != null)
                    {
                        component.ForceDebugDraw = true;
                    }
                });
            });
            return(null);
        }
コード例 #6
0
            public LoadingConstruction(ProceduralStationModule module, Vector4I cell, ProceduralConstructionSeed seed) : base(module)
            {
                m_cell        = cell;
                m_boundingBox = module.StationNoise.GetNodeAABB(cell);
                RaiseMoved();
                Seed = seed;

                m_creationQueued         = false;
                m_creationQueueSemaphore = new FastResourceLock();

                m_construction  = null;
                m_grids         = null;
                m_component     = null;
                base.OnRemoved += (x) =>
                {
                    var station = x as LoadingConstruction;
                    if (station == null)
                    {
                        return;
                    }
                    station.TimeRemoved = DateTime.UtcNow;
                    Module.Debug("Marking station entity for removal!");
                };
            }
コード例 #7
0
        public override IEnumerable <ProceduralObject> Generate(BoundingSphereD include, BoundingSphereD?exclude)
        {
            var aabb = new BoundingBoxD(include.Center - include.Radius, include.Center + include.Radius);

            foreach (var cell in StationNoise.TryGetSpawnIn(aabb, (x) => include.Intersects(x) && (!exclude.HasValue || exclude.Value.Contains(x) != ContainmentType.Contains)))
            {
                LoadingConstruction instance;
                if (!m_instances.TryGetValue(cell.Item1, out instance))
                {
                    var numSeed = cell.Item1.GetHashCode();
                    Ob_ProceduralConstructionSeed dbSeed;
                    Ob_ProceduralConstruction     dbBlueprint;
                    Ob_ProceduralFaction          dbFaction;

                    ProceduralConstructionSeed seed;
                    if (m_database.TryGetBuildingBlueprint(numSeed, out dbSeed, out dbBlueprint) && dbSeed != null &&
                        m_database.TryGetFaction(dbSeed.FactionSeed, out dbFaction) && dbFaction != null)
                    {
                        seed = new ProceduralConstructionSeed(new ProceduralFactionSeed(dbFaction), cell.Item2.XYZ(), dbSeed);
                    }
                    else
                    {
                        seed = new ProceduralConstructionSeed(Factions.SeedAt(cell.Item2.XYZ()), cell.Item2, null,
                                                              numSeed);
                    }
                    instance = m_instances[cell.Item1] = new LoadingConstruction(this, cell.Item1,
                                                                                 seed);
                }
                else if (!instance.IsMarkedForRemoval)
                {
                    continue; // Already loaded + not marked for removal -- already in the tree.
                }
                instance.EnsureGenerationStarted();
                yield return(instance);
            }
        }
コード例 #8
0
        public bool GenerateFromSeed(ProceduralConstructionSeed seed, ref ProceduralConstruction construction, int?roomCount = null)
        {
            Ob_ProceduralConstructionSeed dbSeed;
            Ob_ProceduralConstruction     dbBlueprint;
            Ob_ProceduralFaction          dbFaction;

            if (m_database.TryGetBuildingBlueprint(seed.Seed, out dbSeed, out dbBlueprint) &&
                dbSeed != null &&
                m_database.TryGetFaction(dbSeed.FactionSeed, out dbFaction) && dbFaction != null)
            {
                seed = new ProceduralConstructionSeed(new ProceduralFactionSeed(dbFaction), seed.Location, dbSeed);
                if (construction == null)
                {
                    construction = new ProceduralConstruction(RootLogger, seed);
                }
                if (dbBlueprint != null)
                {
                    this.Debug("Cache hit for {0}", seed.Seed);
                    if (construction.Init(PartManager, dbBlueprint))
                    {
                        return(true);
                    }
                    this.Debug("Cache invalidated for {0}.  Could not find: {1}", seed.Seed, string.Join(", ", dbBlueprint.Rooms.Where(x => PartManager.LoadNullable(x.PrefabID) == null)));
                    construction.Clear();
                }
            }
            try
            {
                var watch = new Stopwatch();
                watch.Reset();
                watch.Start();
                if (Settings.DebugGenerationResults)
                {
                    Log(MyLogSeverity.Debug, "Seeded construction\n{0}", seed.ToString());
                }
                if (construction == null)
                {
                    construction = new ProceduralConstruction(RootLogger, seed);
                }
                // Seed the generator
                if (!construction.Rooms.Any())
                {
                    var parts = PartManager.ToList();
                    var part  = parts[(int)Math.Floor(parts.Count * seed.DeterministicNoise(1234567))];
                    var room  = new ProceduralRoom();
                    room.Init(new MatrixI(Base6Directions.Direction.Forward, Base6Directions.Direction.Up), part);
                    construction.AddRoom(room);
                    if (Settings.DebugGenerationStages || Settings.DebugGenerationResults)
                    {
                        this.Debug("Added {0} (number {1}) at {2}.", room.Part.Name, construction.Rooms.Count(), room.BoundingBox.Center);
                    }
                }
                var scorePrev           = construction.ComputeErrorAgainstSeed();
                var scoreStableTries    = 0;
                var fastGrowth          = (roomCount / 3) ?? (1 + (int)Math.Sqrt(seed.Population / 10f));
                var absoluteRoomsRemain = fastGrowth * 3;
                var gen = new StationGenerator(this, construction);
                while (absoluteRoomsRemain-- > 0)
                {
                    var currentRoomCount = construction.Rooms.Count();
                    if (roomCount.HasValue && currentRoomCount >= roomCount.Value)
                    {
                        break;
                    }
                    if (!roomCount.HasValue && scoreStableTries > 3)
                    {
                        break;
                    }
                    if (BlockLimit > 0 && construction.BlockSetInfo.BlockCountByType.Sum(x => x.Value) >= BlockLimit)
                    {
                        Log(MyLogSeverity.Warning, "Quit because we exceeded the block limit");
                        break;
                    }
                    if (!gen.StepGeneration(fastGrowth > 0 ? 2 : 0))
                    {
                        break;
                    }
                    fastGrowth--;
                    var scoreNow = construction.ComputeErrorAgainstSeed();
                    if (scoreNow >= scorePrev)
                    {
                        scoreStableTries++;
                    }
                    else
                    {
                        scoreStableTries = 0;
                    }
                    scorePrev = scoreNow;
                }
                // Give it plenty of tries to close itself
                if (true)
                {
                    var remainingMounts = construction.Rooms.SelectMany(x => x.MountPoints).Count(y => y.AttachedTo == null);
                    var triesToClose    = remainingMounts * 2 + 2;
                    if (Settings.DebugGenerationResults)
                    {
                        Log(MyLogSeverity.Debug, "There are {0} remaining mounts.  Giving it {1} tries to close itself.", remainingMounts, triesToClose);
                    }
                    var outOfOptions = false;
                    for (var i = 0; i < triesToClose; i++)
                    {
                        if (!gen.StepGeneration(-10))
                        {
                            outOfOptions = true;
                            break;
                        }
                    }
                    remainingMounts = construction.Rooms.SelectMany(x => x.MountPoints).Count(y => y.AttachedTo == null);
                    if (remainingMounts > 0)
                    {
                        if (Settings.DebugGenerationResults)
                        {
                            Log(MyLogSeverity.Debug, "Now there are {0} remaining mounts.  Trying without hints. Reason: {1}", remainingMounts, outOfOptions ? "Out of options" : "Out of tries");
                        }
                        triesToClose = remainingMounts * 2 + 2;
                        for (var i = 0; i < triesToClose; i++)
                        {
                            if (!gen.StepGeneration(-10, false))
                            {
                                outOfOptions = true;
                                break;
                            }
                        }
                    }
                    remainingMounts = construction.Rooms.SelectMany(x => x.MountPoints).Count(y => y.AttachedTo == null);
                    if (Settings.DebugGenerationResults)
                    {
                        if (remainingMounts > 0)
                        {
                            Log(MyLogSeverity.Debug, "Now there are {0} remaining mounts.  Reason: {1}", remainingMounts, outOfOptions ? "Out of options" : "Out of tries");
                        }
                        else
                        {
                            Log(MyLogSeverity.Debug, "Sucessfully closed all mount points");
                        }
                    }
                }
                if (Settings.DebugGenerationResultsError)
                {
                    using (this.IndentUsing())
                        construction.ComputeErrorAgainstSeed(this.Debug);
                }

                var location = MatrixD.CreateFromQuaternion(seed.Orientation);
                location.Translation = seed.Location;

                var msg = $"Added {construction.Rooms.Count()} rooms; generated in {watch.Elapsed}";
                Log(MyLogSeverity.Debug, msg);
                m_database.StoreBuildingBlueprint(construction);
                return(true);
            }
            catch (ArgumentException e)
            {
                Log(MyLogSeverity.Error, "Failed to generate station.\n{0}", e.ToString());
                return(false);
            }
        }