public ProceduralGridComponent(ProceduralConstruction cc, IEnumerable <IMyCubeGrid> gridsInGroup) { Logger = cc.Logger.Root().CreateProxy(GetType().Name); Construction = cc; m_grids = new List <IMyCubeGrid>(gridsInGroup); UpdateReadyState(); }
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); }
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); }
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); } } } }
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); }
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); } }