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(); }
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); }
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); }
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 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!"); }; }
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); } }
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); } }