private void HandleSprinkleOfElement(WorldGenSettings settings, Tag targetTag, Chunk world, SetValuesFunction SetValues, float temperatureMin, float temperatureRange, SeededRandom rnd) { FeatureSettings feature = settings.GetFeature(targetTag.Name); string element = feature.GetOneWeightedSimHash("SprinkleOfElementChoices", rnd).element; Element element2 = ElementLoader.FindElementByName(element); ProcGen.Room value = null; SettingsCache.rooms.TryGetValue(targetTag.Name, out value); SampleDescriber sampleDescriber = value; Sim.PhysicsData defaultValues = element2.defaultValues; Sim.DiseaseCell invalid = Sim.DiseaseCell.Invalid; for (int i = 0; i < terrainPositions.Count; i++) { if (!(terrainPositions[i].Value != targetTag)) { float radius = rnd.RandomRange(sampleDescriber.blobSize.min, sampleDescriber.blobSize.max); Vector2 center = Grid.CellToPos2D(terrainPositions[i].Key); List <Vector2I> filledCircle = ProcGen.Util.GetFilledCircle(center, radius); for (int j = 0; j < filledCircle.Count; j++) { Vector2I vector2I = filledCircle[j]; int x = vector2I.x; Vector2I vector2I2 = filledCircle[j]; int num = Grid.XYToCell(x, vector2I2.y); if (Grid.IsValidCell(num)) { defaultValues.mass = GetDensityMassForCell(world, num, element2.defaultValues.mass); defaultValues.temperature = temperatureMin + world.heatOffset[num] * temperatureRange; SetValues(num, element2, defaultValues, invalid); } } } } }
private void InitSettings() { if (worldGenSettings == null) { worldGenSettings = SaveGame.Instance.worldGen.Settings; } }
private void ApplyForeground(WorldGenSettings settings, Chunk world, SetValuesFunction SetValues, float temperatureMin, float temperatureRange, SeededRandom rnd) { LogInfo("Apply foregreound", (node.tags != null).ToString(), (float)((node.tags != null) ? node.tags.Count : 0)); if (node.tags != null) { FeatureSettings featureSettings = settings.TryGetFeature(node.type); LogInfo("\tFeature?", (featureSettings != null).ToString(), 0f); if (featureSettings == null && node.tags != null) { List <Tag> list = new List <Tag>(); foreach (Tag tag2 in node.tags) { if (settings.HasFeature(tag2.Name)) { list.Add(tag2); } } LogInfo("\tNo feature, checking possible feature tags, found", string.Empty, (float)list.Count); if (list.Count > 0) { Tag tag = list[rnd.RandomSource().Next(list.Count)]; featureSettings = settings.GetFeature(tag.Name); LogInfo("\tPicked feature", tag.Name, 0f); } } if (featureSettings != null) { LogInfo("APPLY FOREGROUND", node.type, 0f); float num = featureSettings.blobSize.GetRandomValueWithinRange(rnd); float num2 = poly.DistanceToClosestEdge(null); if (!node.tags.Contains(WorldGenTags.AllowExceedNodeBorders) && num2 < num) { if (debugMode) { Debug.LogWarning(node.type + " " + featureSettings.shape + " blob size too large to fit in node. Size reduced. " + num + "->" + (num2 - 6f).ToString()); } num = num2 - 6f; } if (!(num <= 0f)) { featureSpawnPoints = DigFeature(featureSettings.shape, num, featureSettings.borders, rnd, out List <Vector2I> featureCenterPoints, out List <List <Vector2I> > featureBorders); LogInfo("\t\t", "claimed points", (float)featureSpawnPoints.Count); availableTerrainPoints.ExceptWith(featureSpawnPoints); ApplyPlaceElementForRoom(featureSettings, "RoomCenterElements", featureCenterPoints, world, SetValues, temperatureMin, temperatureRange, rnd); if (featureBorders != null) { for (int i = 0; i < featureBorders.Count; i++) { ApplyPlaceElementForRoom(featureSettings, "RoomBorderChoices" + i, featureBorders[i], world, SetValues, temperatureMin, temperatureRange, rnd); } } if (featureSettings.tags.Contains(WorldGenTags.HighPriorityFeature.Name)) { AddHighPriorityCells(featureSpawnPoints); } } } } }
private static bool SaveSim(WorldGenSettings settings, Data data, Action <OfflineWorldGen.ErrorInfo> error_cb) { try { Manager.Clear(); SimSaveFileStructure simSaveFileStructure = new SimSaveFileStructure(); for (int i = 0; i < data.overworldCells.Count; i++) { simSaveFileStructure.worldDetail.overworldCells.Add(new WorldDetailSave.OverworldCell(SettingsCache.GetCachedSubWorld(data.overworldCells[i].node.type).zoneType, data.overworldCells[i])); } simSaveFileStructure.worldDetail.globalWorldSeed = data.globalWorldSeed; simSaveFileStructure.worldDetail.globalWorldLayoutSeed = data.globalWorldLayoutSeed; simSaveFileStructure.worldDetail.globalTerrainSeed = data.globalTerrainSeed; simSaveFileStructure.worldDetail.globalNoiseSeed = data.globalNoiseSeed; simSaveFileStructure.WidthInCells = Grid.WidthInCells; simSaveFileStructure.HeightInCells = Grid.HeightInCells; using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memoryStream)) { Sim.Save(writer); } simSaveFileStructure.Sim = memoryStream.ToArray(); } using (MemoryStream memoryStream2 = new MemoryStream()) { using (BinaryWriter writer2 = new BinaryWriter(memoryStream2)) { try { Serializer.Serialize(simSaveFileStructure, writer2); } catch (Exception ex) { DebugUtil.LogErrorArgs("Couldn't serialize", ex.Message, ex.StackTrace); } } using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(WorldGen.SIM_SAVE_FILENAME, FileMode.Create))) { Manager.SerializeDirectory(binaryWriter); binaryWriter.Write(memoryStream2.ToArray()); } } return(true); } catch (Exception ex2) { error_cb(new OfflineWorldGen.ErrorInfo { errorDesc = string.Format(UI.FRONTEND.SUPPORTWARNINGS.SAVE_DIRECTORY_READ_ONLY, WorldGen.SIM_SAVE_FILENAME), exception = ex2 }); DebugUtil.LogErrorArgs("Couldn't write", ex2.Message, ex2.StackTrace); return(false); } }
private void GenerateActionCells(WorldGenSettings settings, Tag tag, HashSet <Vector2I> possiblePoints, SeededRandom rnd) { ProcGen.Room value = null; SettingsCache.rooms.TryGetValue(tag.Name, out value); SampleDescriber sampleDescriber = value; if (sampleDescriber == null && settings.HasMob(tag.Name)) { sampleDescriber = settings.GetMob(tag.Name); } if (sampleDescriber != null) { HashSet <Vector2I> hashSet = new HashSet <Vector2I>(); float randomValueWithinRange = sampleDescriber.density.GetRandomValueWithinRange(rnd); List <Vector2> list; switch (sampleDescriber.selectMethod) { case SampleDescriber.PointSelectionMethod.RandomPoints: list = PointGenerator.GetRandomPoints(poly, randomValueWithinRange, 0f, null, sampleDescriber.sampleBehaviour, true, rnd, true, true); break; default: list = new List <Vector2>(); list.Add(node.position); break; } foreach (Vector2 item2 in list) { Vector2 current = item2; Vector2I item = new Vector2I((int)current.x, (int)current.y); if (possiblePoints.Contains(item)) { hashSet.Add(item); } } if (value != null && value.mobselection == ProcGen.Room.Selection.None) { if (terrainPositions == null) { terrainPositions = new List <KeyValuePair <int, Tag> >(); } foreach (Vector2I item3 in hashSet) { Vector2I current2 = item3; int num = Grid.XYToCell(current2.x, current2.y); if (Grid.IsValidCell(num)) { terrainPositions.Add(new KeyValuePair <int, Tag>(num, tag)); } } } } }
private void Awake() { BackToMainMenu(); foreach (WorldGenSettings genSetting in genSettings) { GameObject preset = Instantiate(genPreset, genPresetsHolder); preset.transform.GetChild(1).GetComponent <TextMeshProUGUI>().text = genSetting.name; Button button = preset.transform.GetChild(2).GetComponent <Button>(); // TODO: Change text to say that it is selected button.onClick.AddListener(delegate { _activeGenSettings = genSetting; }); } var worlds = new string[0]; try { worlds = Directory.GetDirectories($"{Application.persistentDataPath}/worlds"); } catch (DirectoryNotFoundException) { Directory.CreateDirectory($"{Application.persistentDataPath}/worlds"); } if (worlds.Length == 0) { noWorldsText.SetActive(true); } foreach (string world in worlds) { var directory = world.Split('\\'); string worldName = directory[directory.Length - 1]; GameObject worldGameObject = Instantiate(loadableWorldPrefab, worldsHolder); worldGameObject.transform.GetChild(1).GetComponent <TextMeshProUGUI>().text = worldName; Button button = worldGameObject.transform.GetChild(2).GetComponent <Button>(); button.onClick.AddListener(delegate { LoadWorld(worldName); }); // TODO: Create option to delete a world } }
private void PlaceMobsInRoom(WorldGenSettings settings, List <MobReference> mobTags, List <Vector2I> points, SeededRandom rnd) { if (points != null) { if (mobs == null) { mobs = new List <KeyValuePair <int, Tag> >(); } for (int i = 0; i < mobTags.Count; i++) { if (!settings.HasMob(mobTags[i].type)) { Debug.LogError("Missing sample description for tag [" + mobTags[i].type + "]"); } else { Mob mob = settings.GetMob(mobTags[i].type); int num = Mathf.RoundToInt(mobTags[i].count.GetRandomValueWithinRange(rnd)); for (int j = 0; j < num; j++) { int indexForLocation = GetIndexForLocation(points, mob.location, rnd); if (indexForLocation == -1) { break; } if (points.Count <= indexForLocation) { return; } Vector2I vector2I = points[indexForLocation]; int x = vector2I.x; Vector2I vector2I2 = points[indexForLocation]; int cellIdx = Grid.XYToCell(x, vector2I2.y); points.RemoveAt(indexForLocation); AddMob(cellIdx, mobTags[i].type); } } } } }
public unsafe static bool DoSettleSim(WorldGenSettings settings, Sim.Cell[] cells, float[] bgTemp, Sim.DiseaseCell[] dcs, WorldGen.OfflineCallbackFunction updateProgressFn, Data data, List <KeyValuePair <Vector2I, TemplateContainer> > templateSpawnTargets, Action <OfflineWorldGen.ErrorInfo> error_cb, Action <Sim.Cell[], float[], Sim.DiseaseCell[]> onSettleComplete) { Sim.SIM_Initialize(Sim.DLL_MessageHandler); SimMessages.CreateSimElementsTable(ElementLoader.elements); SimMessages.CreateWorldGenHACKDiseaseTable(WorldGen.diseaseIds); Sim.DiseaseCell[] dc = new Sim.DiseaseCell[dcs.Length]; SimMessages.SimDataInitializeFromCells(Grid.WidthInCells, Grid.HeightInCells, cells, bgTemp, dc); int num = 500; updateProgressFn(UI.WORLDGEN.SETTLESIM.key, 0f, WorldGenProgressStages.Stages.SettleSim); Vector2I min = new Vector2I(0, 0); Vector2I max = new Vector2I(Grid.WidthInCells, Grid.HeightInCells); byte[] bytes = null; using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memoryStream)) { try { Sim.Save(writer); } catch (Exception ex) { string message = ex.Message; string stackTrace = ex.StackTrace; WorldGenLogger.LogException(message, stackTrace); return(updateProgressFn(new StringKey("Exception in Sim Save"), -1f, WorldGenProgressStages.Stages.Failure)); } } bytes = memoryStream.ToArray(); } FastReader reader = new FastReader(bytes); if (Sim.Load(reader) != 0) { updateProgressFn(UI.WORLDGEN.FAILED.key, -1f, WorldGenProgressStages.Stages.Failure); return(true); } byte[] array = new byte[Grid.CellCount]; for (int i = 0; i < Grid.CellCount; i++) { array[i] = byte.MaxValue; } for (int j = 0; j < num; j++) { SimMessages.NewGameFrame(0.2f, min, max); IntPtr intPtr = Sim.HandleMessage(SimMessageHashes.PrepareGameData, array.Length, array); updateProgressFn(UI.WORLDGEN.SETTLESIM.key, (float)j / (float)num * 100f, WorldGenProgressStages.Stages.SettleSim); if (!(intPtr == IntPtr.Zero)) { Sim.GameDataUpdate *ptr = (Sim.GameDataUpdate *)(void *) intPtr; for (int k = 0; k < ptr->numSubstanceChangeInfo; k++) { Sim.SubstanceChangeInfo substanceChangeInfo = ptr->substanceChangeInfo[k]; int cellIdx = substanceChangeInfo.cellIdx; cells[cellIdx].elementIdx = ptr->elementIdx[cellIdx]; cells[cellIdx].insulation = ptr->insulation[cellIdx]; cells[cellIdx].properties = ptr->properties[cellIdx]; cells[cellIdx].temperature = ptr->temperature[cellIdx]; cells[cellIdx].mass = ptr->mass[cellIdx]; cells[cellIdx].strengthInfo = ptr->strengthInfo[cellIdx]; } foreach (KeyValuePair <Vector2I, TemplateContainer> templateSpawnTarget in templateSpawnTargets) { Cell templateCellData; for (int l = 0; l < templateSpawnTarget.Value.cells.Count; l++) { templateCellData = templateSpawnTarget.Value.cells[l]; Vector2I key = templateSpawnTarget.Key; int x = key.x; Vector2I key2 = templateSpawnTarget.Key; int num2 = Grid.OffsetCell(Grid.XYToCell(x, key2.y), templateCellData.location_x, templateCellData.location_y); if (Grid.IsValidCell(num2)) { cells[num2].elementIdx = (byte)ElementLoader.GetElementIndex(templateCellData.element); cells[num2].temperature = templateCellData.temperature; cells[num2].mass = templateCellData.mass; dcs[num2].diseaseIdx = (byte)WorldGen.diseaseIds.FindIndex((string name) => name == templateCellData.diseaseName); dcs[num2].elementCount = templateCellData.diseaseCount; } } } } } for (int m = 0; m < Grid.CellCount; m++) { int callbackIdx = (m != Grid.CellCount - 1) ? (-1) : 2147481337; SimMessages.ModifyCell(m, cells[m].elementIdx, cells[m].temperature, cells[m].mass, dcs[m].diseaseIdx, dcs[m].elementCount, SimMessages.ReplaceType.Replace, false, callbackIdx); } bool flag = false; while (!flag) { SimMessages.NewGameFrame(0.2f, min, max); IntPtr intPtr2 = Sim.HandleMessage(SimMessageHashes.PrepareGameData, array.Length, array); if (!(intPtr2 == IntPtr.Zero)) { Sim.GameDataUpdate *ptr2 = (Sim.GameDataUpdate *)(void *) intPtr2; for (int n = 0; n < ptr2->numCallbackInfo; n++) { Sim.CallbackInfo callbackInfo = ptr2->callbackInfo[n]; if (callbackInfo.callbackIdx == 2147481337) { flag = true; break; } } } } Sim.HandleMessage(SimMessageHashes.SettleWorldGen, 0, null); bool result = SaveSim(settings, data, error_cb); onSettleComplete(cells, bgTemp, dcs); Sim.Shutdown(); return(result); }
public static void Postfix(WorldGenSettings __instance, ref string worldName, ref List <string> traits) { // 256x512 default Debug.Log(" === CWS: Using custom world size ... Default: " + __instance.world.worldsize.x + "/" + __instance.world.worldsize.y + " === "); //if (!CustomGameSettings.Get().is_custom_game) //if (!CustomGameSettings.Instance.is_custom_game) Debug.Log(" === " + CustomGameSettings.Instance.customGameMode + " === "); if (CustomGameSettings.Instance.customGameMode != CustomGameSettings.CustomGameMode.Custom) { Debug.Log(" === CWS: Nah, no custom game ... === "); return; } //SettingConfig settingConfig = CustomGameSettings.Get().QualitySettings[CustomWorldSize.UseCustomWorldSize]; SettingConfig settingConfig = CustomGameSettings.Instance.QualitySettings[CustomWorldSize.UseCustomWorldSize]; SettingLevel currentQualitySetting = //CustomGameSettings.Get().GetCurrentQualitySetting(CustomWorldSize.UseCustomWorldSize); CustomGameSettings.Instance.GetCurrentQualitySetting(CustomWorldSize.UseCustomWorldSize); bool allowCustomSize = !settingConfig.IsDefaultLevel(currentQualitySetting.id); if (!allowCustomSize) { Debug.Log(" === CWS: No custom size applied ... === " + "Using " + __instance.world.worldsize.x + " / " + __instance.world.worldsize.y + " as new world size === "); return; } //SettingLevel currentQualitySettingX = CustomGameSettings.Get().GetCurrentQualitySetting(CustomWorldSize.WorldsizeX); //SettingLevel currentQualitySettingY = CustomGameSettings.Get().GetCurrentQualitySetting(CustomWorldSize.WorldsizeY); SettingLevel currentQualitySettingX = CustomGameSettings.Instance.GetCurrentQualitySetting(CustomWorldSize.WorldsizeX); SettingLevel currentQualitySettingY = CustomGameSettings.Instance.GetCurrentQualitySetting(CustomWorldSize.WorldsizeY); int width = __instance.world.worldsize.x; int height = __instance.world.worldsize.y; Int32.TryParse(currentQualitySettingX.id, out width); Int32.TryParse(currentQualitySettingY.id, out height); Vector2I worldsize = __instance.world.worldsize; worldsize.x = width; worldsize.y = height; if (worldsize.x > worldsize.y) { Debug.Log(" === CWS: Fixing width. Width must be equals or less than height. There is a bug in ONI code somewhere :( otherwise, game crashes === "); worldsize.x = worldsize.y; } AccessTools.Property(typeof(ProcGen.World), "worldsize").SetValue(__instance.world, worldsize, null); Debug.Log(" === CWS: Using " + __instance.world.worldsize.x + "/" + __instance.world.worldsize.y + " as new world size === "); // if (Config.Enabled && Config.CustomWorldSize) //{ // width = Config.width; // height = Config.height; //} }
public static Dictionary <int, string> PlaceBiomeAmbientMobs(WorldGenSettings settings, TerrainCell tc, SeededRandom rnd, Sim.Cell[] cells, float[] bgTemp, Sim.DiseaseCell[] dc, HashSet <int> avoidCells, bool isDebug) { Dictionary <int, string> spawnedMobs = new Dictionary <int, string>(); Node node = tc.node; HashSet <int> alreadyOccupiedCells = new HashSet <int>(); List <Tag> list = new List <Tag>(); if (node.biomeSpecificTags == null) { tc.LogInfo("PlaceBiomeAmbientMobs", "No tags", (float)node.node.Id); return(null); } foreach (Tag biomeSpecificTag in node.biomeSpecificTags) { if (settings.HasMob(biomeSpecificTag.Name) && settings.GetMob(biomeSpecificTag.Name) != null) { list.Add(biomeSpecificTag); } } if (list.Count <= 0) { tc.LogInfo("PlaceBiomeAmbientMobs", "No biome MOBS", (float)node.node.Id); return(null); } List <int> list2 = (!node.tags.Contains(WorldGenTags.PreventAmbientMobsInFeature)) ? tc.GetAvailableSpawnCellsAll() : tc.GetAvailableSpawnCellsBiome(); tc.LogInfo("PlaceBiomAmbientMobs", "possibleSpawnPoints", (float)list2.Count); for (int num = list2.Count - 1; num > 0; num--) { int num2 = list2[num]; if (ElementLoader.elements[cells[num2].elementIdx].id == SimHashes.Katairite || ElementLoader.elements[cells[num2].elementIdx].id == SimHashes.Unobtanium || avoidCells.Contains(num2)) { list2.RemoveAt(num); } } tc.LogInfo("mob spawns", "Id:" + node.node.Id + " possible cells", (float)list2.Count); if (list2.Count == 0) { if (isDebug) { Debug.LogWarning("No where to put mobs possibleSpawnPoints [" + tc.node.node.Id + "]"); } return(null); } list.ShuffleSeeded(rnd.RandomSource()); for (int i = 0; i < list.Count; i++) { Mob mob = settings.GetMob(list[i].Name); if (mob == null) { Debug.LogError("Missing sample description for tag [" + list[i].Name + "]"); } else { List <int> mobPossibleSpawnPoints = GetMobPossibleSpawnPoints(mob, list2, cells, alreadyOccupiedCells, rnd); if (mobPossibleSpawnPoints.Count == 0) { if (!isDebug) { continue; } } else { tc.LogInfo("\t\tpossible", list[i].ToString() + " mps: " + mobPossibleSpawnPoints.Count + " ps:", (float)list2.Count); float num3 = mob.density.GetRandomValueWithinRange(rnd) * MobSettings.AmbientMobDensity; if (num3 > 1f) { if (isDebug) { Debug.LogWarning("Got a mob density greater than 1.0 for " + list[i].Name + ". Probably using density as spacing!"); } num3 = 1f; } tc.LogInfo("\t\tdensity:", string.Empty, num3); int num4 = Mathf.RoundToInt((float)mobPossibleSpawnPoints.Count * num3); tc.LogInfo("\t\tcount", list[i].ToString(), (float)num4); Tag mobPrefab = (mob.prefabName != null) ? new Tag(mob.prefabName) : list[i]; SpawnCountMobs(mob, mobPrefab, num4, mobPossibleSpawnPoints, tc, ref spawnedMobs, ref alreadyOccupiedCells); } } } return(spawnedMobs); }
public static Dictionary <int, string> PlaceFeatureAmbientMobs(WorldGenSettings settings, TerrainCell tc, SeededRandom rnd, Sim.Cell[] cells, float[] bgTemp, Sim.DiseaseCell[] dc, HashSet <int> avoidCells, bool isDebug) { Dictionary <int, string> spawnedMobs = new Dictionary <int, string>(); Node node = tc.node; HashSet <int> alreadyOccupiedCells = new HashSet <int>(); FeatureSettings featureSettings = null; foreach (Tag featureSpecificTag in node.featureSpecificTags) { if (settings.HasFeature(featureSpecificTag.Name)) { featureSettings = settings.GetFeature(featureSpecificTag.Name); break; } } if (featureSettings == null) { return(spawnedMobs); } if (featureSettings.internalMobs == null || featureSettings.internalMobs.Count == 0) { return(spawnedMobs); } List <int> availableSpawnCellsFeature = tc.GetAvailableSpawnCellsFeature(); tc.LogInfo("PlaceFeatureAmbientMobs", "possibleSpawnPoints", (float)availableSpawnCellsFeature.Count); for (int num = availableSpawnCellsFeature.Count - 1; num > 0; num--) { int num2 = availableSpawnCellsFeature[num]; if (ElementLoader.elements[cells[num2].elementIdx].id == SimHashes.Katairite || ElementLoader.elements[cells[num2].elementIdx].id == SimHashes.Unobtanium || avoidCells.Contains(num2)) { availableSpawnCellsFeature.RemoveAt(num); } } tc.LogInfo("mob spawns", "Id:" + node.node.Id + " possible cells", (float)availableSpawnCellsFeature.Count); if (availableSpawnCellsFeature.Count == 0) { if (isDebug) { Debug.LogWarning("No where to put mobs possibleSpawnPoints [" + tc.node.node.Id + "]"); } return(null); } foreach (MobReference internalMob in featureSettings.internalMobs) { Mob mob = settings.GetMob(internalMob.type); if (mob == null) { Debug.LogError("Missing mob description for internal mob [" + internalMob.type + "]"); } else { List <int> mobPossibleSpawnPoints = GetMobPossibleSpawnPoints(mob, availableSpawnCellsFeature, cells, alreadyOccupiedCells, rnd); if (mobPossibleSpawnPoints.Count == 0) { if (!isDebug) { continue; } } else { tc.LogInfo("\t\tpossible", internalMob.type + " mps: " + mobPossibleSpawnPoints.Count + " ps:", (float)availableSpawnCellsFeature.Count); int num3 = Mathf.RoundToInt(internalMob.count.GetRandomValueWithinRange(rnd)); tc.LogInfo("\t\tcount", internalMob.type, (float)num3); Tag mobPrefab = (mob.prefabName != null) ? new Tag(mob.prefabName) : new Tag(internalMob.type); SpawnCountMobs(mob, mobPrefab, num3, mobPossibleSpawnPoints, tc, ref spawnedMobs, ref alreadyOccupiedCells); } } } return(spawnedMobs); }
public static void Postfix(string worldName, List <string> traits, WorldGenSettings __instance) { }