public ProceduralGridComponent(ProceduralConstruction cc, IEnumerable <IMyCubeGrid> gridsInGroup)
 {
     Logger       = cc.Logger.Root().CreateProxy(GetType().Name);
     Construction = cc;
     m_grids      = new List <IMyCubeGrid>(gridsInGroup);
     UpdateReadyState();
 }
Пример #2
0
        public ConstructionCopy(ProceduralRoom room, RoomRemapper remapper = null)
        {
            Logger = room.Owner.Logger.Root().CreateProxy(GetType().Name);
            var i = room.Part.PrimaryGrid;
            var o = new MyObjectBuilder_CubeGrid
            {
                GridSizeEnum           = i.GridSizeEnum,
                IsStatic               = true,
                DampenersEnabled       = true,
                Handbrake              = true,
                DisplayName            = room.Owner.Seed.Name,
                DestructibleBlocks     = true,
                IsRespawnGrid          = false,
                Editable               = true,
                PersistentFlags        = MyPersistentEntityFlags2.Enabled | MyPersistentEntityFlags2.InScene | MyPersistentEntityFlags2.CastShadows,
                PositionAndOrientation = new MyPositionAndOrientation(GridCreator.WorldTransformFor(room.Owner))
            };

            BoundingBox = BoundingBoxD.CreateInvalid();

            Construction = room.Owner;
            PrimaryGrid  = o;
            AuxGrids     = new List <MyObjectBuilder_CubeGrid>();
            m_remapper   = remapper ?? new RoomRemapper(Logger.Root());

            var iwatch = new Stopwatch();

            m_remapper.Remap(room, this);
            Logger.Debug("Added room {3} of {0} blocks with {1} aux grids in {2}", room.Part.PrimaryGrid.CubeBlocks.Count, room.Part.Prefab.CubeGrids.Length - 1, iwatch.Elapsed, room.Part.Name);
        }
Пример #3
0
        public static MatrixD WorldTransformFor(ProceduralConstruction construction)
        {
            var room          = construction.Rooms.First();
            var spawnLocation = construction.Seed.WorldMatrix;

            spawnLocation.Translation -= Vector3D.TransformNormal(room.BoundingBox.Center, ref spawnLocation) * MyDefinitionManager.Static.GetCubeSize(room.Part.PrimaryCubeSize);
            spawnLocation.Translation -= room.Part.Prefab.BoundingSphere.Center;
            return(spawnLocation);
        }
Пример #4
0
 public StationGenerator(StationGeneratorManager manager, ProceduralConstruction construction)
 {
     m_manager      = manager;
     m_construction = construction;
     foreach (var room in construction.Rooms)
     {
         foreach (var mount in room.MountPoints)
         {
             if (mount.AttachedTo == null)
             {
                 m_openMountPoints.Enqueue(mount);
             }
         }
     }
 }
Пример #5
0
 public void StoreBuildingBlueprint(ProceduralConstruction construction)
 {
     using (m_lock.AcquireExclusiveUsing())
         if (m_root != null && construction?.Seed != null)
         {
             this.Info("Storing building blueprint for {0}", construction.Seed.Name);
             m_root.Factions[construction.Seed.Faction.Seed] = construction.Seed.Faction.GetObjectBuilder();
             m_root.Buildings[construction.Seed.Seed]        =
                 new Ob_BuildingDatabase_Root.Ob_BuildingDatabase_BuildingNode()
             {
                 Blueprint = construction?.GetObjectBuilder(),
                 Seed      = construction.Seed.GetObjectBuilder()
             };
         }
 }
        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);
        }
Пример #7
0
        public static ConstructionCopy RemapAndBuild(ProceduralConstruction construction, RoomRemapper remapper = null)
        {
            ConstructionCopy grids = null;

            foreach (var room in construction.Rooms)
            {
                if (grids == null)
                {
                    grids = new ConstructionCopy(room, remapper);
                }
                else
                {
                    grids.AppendRoom(room);
                }
            }
            return(grids);
        }
 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);
     }
 }
            private bool Stage_Generate()
            {
                Module.Debug("Generation stage for {0}/{1}", m_cell, Seed.Seed);
                m_construction = null;

                var success = Module.Generator.GenerateFromSeed(Seed, ref m_construction);

                if (success)
                {
                    Module.Debug("Generation stage success for {0}/{1}", m_cell, Seed.Seed);
                    if (!IsMarkedForRemoval)
                    {
                        return(true);
                    }
                }
                else
                {
                    Module.Error("Generation stage failed for {0}/{1}", m_cell, Seed.Seed);
                }
                m_grids     = null;
                m_component = null;
                return(false);
            }
        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);
        }
            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!");
                };
            }
            internal bool TickRemoval(ref int hiddenEntities, ref int removedEntities, ref int removedOB, ref int removedRecipe)
            {
                if (!TimeRemoved.HasValue)
                {
                    return(false);
                }
                using (m_creationQueueSemaphore.AcquireSharedUsing())
                    if (m_creationQueued)
                    {
                        return(false);
                    }
                var dt = DateTime.UtcNow - TimeRemoved;

                if (dt > Module.ConfigReference.StationEntityPersistence && m_component != null)
                {
                    removedEntities++;
                    var grids = new List <IMyCubeGrid>(m_component.GridsInGroup);
                    foreach (var grid in grids)
                    {
                        grid.Close();
                    }
                    m_component = null;
                }
                if (dt > Module.ConfigReference.StationObjectBuilderPersistence && m_grids != null)
                {
                    removedOB++;
                    m_grids = null;
                }
                // ReSharper disable once InvertIf
                if (dt > Module.ConfigReference.StationRecipePersistence && m_construction != null)
                {
                    removedRecipe++;
                    m_construction = null;
                }
                return(dt > Module.ConfigReference.StationRecipePersistence);
            }
        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);
            }
        }