public static int[, ,] SmudgeArray3D(this int[, ,] intArea, double dblChance) { int[, ,] intNew = new int[intArea.GetLength(0), intArea.GetLength(1), intArea.GetLength(2)]; for (int x = 0; x < intArea.GetLength(0); x++) { for (int y = 0; y < intArea.GetLength(1); y++) { for (int z = 0; z < intArea.GetLength(2); z++) { if (RNG.NextDouble() <= dblChance) { int intNewX, intNewY, intNewZ; do { intNewX = RNG.Next(-1, 2); intNewY = RNG.Next(-1, 2); intNewZ = RNG.Next(-1, 2); } while (!intArea.IsValidPositionInArray3D(x + intNewX, y + intNewY, z + intNewZ) || Math.Abs(intNewX) + Math.Abs(intNewY) + Math.Abs(intNewZ) > 1); intNew[x, y, z] = intArea[x + intNewX, y + intNewY, z + intNewZ]; } else { intNew[x, y, z] = intArea[x, y, z]; } } } } return(intNew); }
private static void SplitArea(BlockManager bm, int[,] intArea, int x1, int z1, int x2, int z2) { for (int x = x1; x <= x2; x++) { for (int y = z1; y <= z2; y++) { if (x == x1 || x == x2 || y == z1 || y == z2) { if (intArea[x, y] < 500) { intArea[x, y] = 1; } } } } bool booPossibleToSplit = true; bool booSplitByX = false; if (Math.Abs(x1 - x2) > 50 && Math.Abs(z1 - z2) > 50) { booSplitByX = RNG.NextDouble() > 0.5; } else if (Math.Abs(x1 - x2) > 50) { booSplitByX = true; } else if (Math.Abs(z1 - z2) <= 50) { booPossibleToSplit = false; } if (booPossibleToSplit) { if (booSplitByX) { int intSplitPoint = RNG.Next(x1 + 20, x2 - 20); SplitArea(bm, intArea, x1, z1, intSplitPoint, z2); SplitArea(bm, intArea, intSplitPoint, z1, x2, z2); _intStreet++; MakeStreetSign(bm, intSplitPoint - 1, z1 + 1, intSplitPoint - 1, z2 - 1); } else { int intSplitPoint = RNG.Next(z1 + 20, z2 - 20); SplitArea(bm, intArea, x1, z1, x2, intSplitPoint); SplitArea(bm, intArea, x1, intSplitPoint, x2, z2); _intStreet++; MakeStreetSign(bm, x1 + 1, intSplitPoint - 1, x2 - 1, intSplitPoint - 1); } } else { structDistrict stdCurrent = new structDistrict(); stdCurrent.x1 = x1; stdCurrent.x2 = x2; stdCurrent.z1 = z1; stdCurrent.z2 = z2; _lstDistricts.Add(stdCurrent); } }
// this is a simplified version of the MakeBuildings method from Buildings.cs private static void MakeBuildings(BlockManager bm, int[,] intArea, BetaWorld world) { int intBuildings = 0; for (int x = 0; x < intArea.GetLength(0); x++) { for (int z = 0; z < intArea.GetLength(1); z++) { // hack low: this 100 to 500 stuff is all a bit hackish really, need to find a proper solution if (intArea[x, z] >= 100 && intArea[x, z] <= 500) { SourceWorld.Building CurrentBuilding = SourceWorld.GetBuilding(intArea[x, z] - 100); if (CurrentBuilding.intSizeX >= 10 && RNG.NextDouble() > 0.8) { if (RNG.NextDouble() > 0.5) { MakePond(bm, 6 + x, CurrentBuilding.intSizeX, (6 - City.FarmLength) + z, CurrentBuilding.intSizeZ); } else { MakeHill(bm, 6 + x, CurrentBuilding.intSizeX, (6 - City.FarmLength) + z, CurrentBuilding.intSizeZ); } } else { SourceWorld.InsertBuilding(bm, intArea, 0, 6 + x, (6 - City.FarmLength) + z, CurrentBuilding, 0, -1); } intArea[x + CurrentBuilding.intSizeX - 2, z + CurrentBuilding.intSizeZ - 2] = 0; if (++intBuildings == NumberOfBuildingsBetweenSaves) { world.Save(); intBuildings = 0; } } } } }
private static int[, ,] AddResources(int[, ,] intEnlargedArea, int Y, frmMace frmLogForm, string strUndergroundOres) { int X, Z; int intResources = City.mapLength * Y * (City.farmLength + City.mapLength); switch (strUndergroundOres) { case "Sparse": intResources /= 400; break; case "Uncommon": intResources /= 300; break; case "Normal": intResources /= 200; break; case "Common": intResources /= 100; break; case "Dense": intResources /= 50; break; default: intResources /= 200; Debug.Fail("Invalid switch for underground ores."); break; } frmLogForm.UpdateLog("Adding resource patches: " + intResources, true, true); do { X = RNG.Next(1, intEnlargedArea.GetLength(0) - 1); Y = RNG.Next(1, intEnlargedArea.GetLength(1) - 1); Z = RNG.Next(1, intEnlargedArea.GetLength(2) - 1); if (intEnlargedArea[X, Y, Z] == BlockInfo.Stone.ID) { double dblDepth = (double)Y / intEnlargedArea.GetLength(1); // this increases ore frequency as we get lower if (dblDepth < RNG.NextDouble() * 1.5) { intEnlargedArea[X, Y, Z] = SelectRandomResource(dblDepth); intResources--; } } } while (intResources > 0); return(intEnlargedArea); }
private static int[, ,] MakeUndergroundTerrain(int SizeY, frmMace frmLogForm, string strUndergroundOres) { int[, ,] intArea = new int[(City.mapLength / 8) + 1, (SizeY / 8) + 1, ((City.farmLength + City.mapLength) / 8) + 1]; int[] intGroundBlockIDs = Utils.ArrayFromXMLElement(Path.Combine("Resources", "Themes", City.themeName + ".xml"), "options", "underground").StringArrayToIntArray(); for (int x = 0; x < intArea.GetLength(0); x++) { for (int y = 0; y < intArea.GetLength(1); y++) { for (int z = 0; z < intArea.GetLength(2); z++) { intArea[x, y, z] = intGroundBlockIDs[RNG.Next(intGroundBlockIDs.GetLength(0))]; } } } double dblSmudgeArrayChance = 0.6; intArea = intArea.EnlargeArray3D(4, 4, 4).SmudgeArray3D(dblSmudgeArrayChance); intArea = AddResources(intArea, SizeY, frmLogForm, strUndergroundOres); intArea = intArea.EnlargeArray3D(2, 2, 2).SmudgeArray3D(dblSmudgeArrayChance); for (int x = 0; x < intArea.GetLength(0); x++) { for (int y = 0; y < intArea.GetLength(1); y++) { for (int z = 0; z < intArea.GetLength(2); z++) { if (intArea[x, y, z] == BlockInfo.Sand.ID && RNG.NextDouble() < 0.2) { intArea[x, y, z] = BlockInfo.Sandstone.ID; } } } } return(intArea); }
static public void Generate(frmMace frmLogForm, string UserWorldName, string strWorldSeed, string strWorldType, bool booWorldMapFeatures, int TotalCities, string[] strCheckedThemes, int ChunksBetweenCities, string strSpawnPoint, bool booExportSchematics, string strSelectedNPCs, string strUndergroundOres) { frmLogForm.UpdateLog("Started at " + DateTime.Now.ToLocalTime(), false, true); worldCities = new WorldCity[TotalCities]; lstCityNames.Clear(); Chunks.biomes.Clear(); RNG.SetRandomSeed(); #region create minecraft world directory from a random unused world name string strFolder = String.Empty, strWorldName = String.Empty; UserWorldName = UserWorldName.ToSafeFilename(); if (UserWorldName.Trim().Length == 0) { UserWorldName = "random"; } if (UserWorldName.ToLower().Trim() != "random") { if (Directory.Exists(UserWorldName.ToMinecraftSaveDirectory())) { if (MessageBox.Show("A world called \"" + UserWorldName + "\" already exists. " + "Would you like to use a random name instead?", "World already exists", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) { frmLogForm.UpdateLog("Cancelled, because a world with this name already exists.", false, false); return; } } else { strWorldName = UserWorldName; strFolder = strWorldName.ToMinecraftSaveDirectory(); } } if (strWorldName.Length == 0) { strWorldName = Utils.GenerateWorldName(); strFolder = strWorldName.ToMinecraftSaveDirectory(); } Directory.CreateDirectory(strFolder); frmLogForm.btnSaveLogNormal.Tag = Path.Combine(strFolder, "LogNormal.txt"); frmLogForm.btnSaveLogVerbose.Tag = Path.Combine(strFolder, "LogVerbose.txt"); frmLogForm.UpdateLog("World name: " + strWorldName, false, true); #endregion #region get handles to world, chunk manager and block manager AnvilWorld worldDest = AnvilWorld.Create(@strFolder); worldDest.Level.LevelName = "Creating. Don't open until Mace is finished."; RegionChunkManager cmDest = worldDest.GetChunkManager(); BlockManager bmDest = worldDest.GetBlockManager(); bmDest.AutoLight = false; #endregion #region Determine themes // "how does this work, robson?" // well, I'm glad you asked! // we keep selecting a random unused checked theme, until they've all been used once. // after that, all other cities will have a random checked theme int maxFarmSize = 0; strCheckedThemes = RNG.ShuffleArray(strCheckedThemes); for (int CurrentCityID = 0; CurrentCityID < TotalCities; CurrentCityID++) { if (CurrentCityID <= strCheckedThemes.GetUpperBound(0)) { worldCities[CurrentCityID].ThemeName = strCheckedThemes[CurrentCityID]; } else { worldCities[CurrentCityID].ThemeName = RNG.RandomItem(strCheckedThemes); } City.themeName = worldCities[CurrentCityID].ThemeName; worldCities[CurrentCityID].ChunkLength = GetThemeRandomXMLElementNumber("options", "city_size"); int farmSize = GetThemeLastXMLElementNumber("options", "farm_size"); maxFarmSize = Math.Max(maxFarmSize, farmSize); } #endregion GenerateCityLocations(TotalCities, ChunksBetweenCities + maxFarmSize); int intRandomCity = RNG.Next(TotalCities); for (int CurrentCityID = 0; CurrentCityID < TotalCities; CurrentCityID++) { MakeCitySettings(frmLogForm, worldCities[CurrentCityID].ThemeName, CurrentCityID, strSelectedNPCs); if (!GenerateCity.Generate(frmLogForm, worldDest, cmDest, bmDest, worldCities[CurrentCityID].x, worldCities[CurrentCityID].z, booExportSchematics, strUndergroundOres)) { frmLogForm.UpdateLog("World generation failed/cancelled.", false, false); return; } #region set spawn point if (City.id == intRandomCity) { switch (strSpawnPoint) { case "Away from the cities": worldDest.Level.Spawn = new SpawnPoint(0, 65, 0); break; case "Inside a random city": worldDest.Level.Spawn = new SpawnPoint(((worldCities[intRandomCity].x + Chunks.CITY_RELOCATION_CHUNKS) * 16) + (City.mapLength / 2), 65, ((worldCities[intRandomCity].z + Chunks.CITY_RELOCATION_CHUNKS) * 16) + (City.mapLength / 2)); break; case "Outside a random city": worldDest.Level.Spawn = new SpawnPoint(((worldCities[intRandomCity].x + Chunks.CITY_RELOCATION_CHUNKS) * 16) + (City.mapLength / 2), 65, ((worldCities[intRandomCity].z + Chunks.CITY_RELOCATION_CHUNKS) * 16) + 2); break; default: Debug.Fail("invalid spawn point"); break; } frmLogForm.UpdateLog("Spawn point set to " + worldDest.Level.Spawn.X + "," + worldDest.Level.Spawn.Y + "," + worldDest.Level.Spawn.Z, false, true); } #endregion } #region weather frmLogForm.UpdateLog("Setting weather", false, true); worldDest.Level.Time = RNG.Next(24000); if (RNG.NextDouble() < 0.15) { frmLogForm.UpdateLog("Rain", false, true); worldDest.Level.IsRaining = true; // one-quarter to three-quarters of a day worldDest.Level.RainTime = RNG.Next(6000, 18000); if (RNG.NextDouble() < 0.25) { frmLogForm.UpdateLog("Thunder", false, true); worldDest.Level.IsThundering = true; worldDest.Level.ThunderTime = worldDest.Level.RainTime; } } #endregion #region world details worldDest.Level.LevelName = strWorldName; frmLogForm.UpdateLog("Setting world type: " + strWorldType, false, true); switch (strWorldType.ToLower()) { case "creative": worldDest.Level.GameType = GameType.CREATIVE; break; case "survival": worldDest.Level.GameType = GameType.SURVIVAL; break; case "hardcore": worldDest.Level.GameType = GameType.SURVIVAL; worldDest.Level.Hardcore = true; break; default: Debug.Fail("Invalidate world type selected."); break; } frmLogForm.UpdateLog("World map features: " + booWorldMapFeatures.ToString(), false, true); worldDest.Level.UseMapFeatures = booWorldMapFeatures; if (strWorldSeed != String.Empty) { long seed = 0; if (long.TryParse(strWorldSeed, out seed)) { worldDest.Level.RandomSeed = seed; frmLogForm.UpdateLog("Specified world seed: " + worldDest.Level.RandomSeed, false, true); } else { worldDest.Level.RandomSeed = strWorldSeed.ToJavaHashCode(); frmLogForm.UpdateLog("Specified world seed: " + strWorldSeed, false, true); frmLogForm.UpdateLog("Specified world seed converted to a number: " + worldDest.Level.RandomSeed, false, true); } } else { worldDest.Level.RandomSeed = RNG.Next(); frmLogForm.UpdateLog("Random world seed: " + worldDest.Level.RandomSeed, false, true); } worldDest.Level.LastPlayed = (DateTime.UtcNow.Ticks - DateTime.Parse("01/01/1970 00:00:00").Ticks) / 10000; frmLogForm.UpdateLog("World time: " + worldDest.Level.LastPlayed, false, true); #endregion cmDest.Save(); worldDest.Save(); Chunks.SetBiomeData(@strFolder); frmLogForm.UpdateLog("\nCreated the " + strWorldName + "!", false, false); frmLogForm.UpdateLog("It'll be at the top of your MineCraft world list.", false, false); frmLogForm.UpdateLog("Finished at " + DateTime.Now.ToLocalTime(), false, true); }
public static void MakeFlowers(AnvilWorld worldDest, BlockManager bm) { string[] strFlowers = Utils.ArrayFromXMLElement(Path.Combine("Resources", "Themes", City.themeName + ".xml"), "options", "flowers"); int FlowerCount = 0; for (int x = 0; x <= City.mapLength; x++) { for (int z = -City.farmLength; z <= City.mapLength; z++) { if (bm.GetID(x, 63, z) == City.groundBlockID && bm.GetID(x, 64, z) == BlockInfo.Air.ID) { int FreeNeighbours = 0; for (int xCheck = x - 1; xCheck <= x + 1; xCheck++) { for (int zCheck = z - 1; zCheck <= z + 1; zCheck++) { if (bm.GetID(xCheck, 63, zCheck) == City.groundBlockID && bm.GetID(xCheck, 64, zCheck) == BlockInfo.Air.ID) { FreeNeighbours++; } } } if (FreeNeighbours >= MinimumFreeNeighboursNeededForFlowers && RNG.NextDouble() * 100 <= City.flowerSpawnPercent) { AddFlowersToBlock(bm, x, z, FreeNeighbours, RNG.RandomItemFromArray(strFlowers)); if (++FlowerCount >= NumberOfFlowersBetweenSaves) { worldDest.Save(); FlowerCount = 0; } } } } } }
public static void MakeMoat(frmMace frmLogForm, BlockManager bm) { frmLogForm.UpdateLog("Moat type: " + City.MoatType, true, true); switch (City.MoatType) { case "Drop to Bedrock": for (int a = City.EdgeLength - 1; a <= City.EdgeLength + 5; a++) { BlockShapes.MakeHollowLayers(a, City.MapLength - a, 2, 63, a, City.MapLength - a, BlockInfo.Air.ID, 0, -1); } BlockShapes.MakeHollowLayers(City.EdgeLength - 2, City.MapLength - (City.EdgeLength - 2), 64, 64, City.EdgeLength - 2, City.MapLength - (City.EdgeLength - 2), BlockInfo.Fence.ID, 0, -1); break; case "Cactus": for (int a = City.EdgeLength - 1; a <= City.EdgeLength + 5; a++) { BlockShapes.MakeHollowLayers(a, City.MapLength - a, 63, 63, a, City.MapLength - a, BlockInfo.Sand.ID, 0, -1); } for (int a = City.EdgeLength + 1; a <= City.MapLength / 2; a += 2) { if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 64, City.EdgeLength + 1, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 65, City.EdgeLength + 1, BlockInfo.Cactus.ID, 2, 50, -1); } if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 64, City.EdgeLength + 3, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 65, City.EdgeLength + 3, BlockInfo.Cactus.ID, 2, 50, -1); } } for (int a = City.EdgeLength; a <= City.MapLength / 2; a += 2) { if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 64, City.EdgeLength, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 65, City.EdgeLength, BlockInfo.Cactus.ID, 2, 50, -1); } if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 64, City.EdgeLength + 2, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 65, City.EdgeLength + 2, BlockInfo.Cactus.ID, 2, 50, -1); } if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 64, City.EdgeLength + 4, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 65, City.EdgeLength + 4, BlockInfo.Cactus.ID, 2, 50, -1); } } if (City.HasGuardTowers) { for (int a = City.EdgeLength + 3; a <= City.EdgeLength + 13; a += 2) { BlockShapes.MakeBlock(a, 64, City.EdgeLength + 3, BlockInfo.Air.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 65, City.EdgeLength + 3, BlockInfo.Air.ID, 2, 100, -1); } } break; case "Cactus Low": for (int a = City.EdgeLength - 1; a <= City.EdgeLength + 5; a++) { BlockShapes.MakeHollowLayers(a, City.MapLength - a, 59, 63, a, City.MapLength - a, BlockInfo.Air.ID, 0, -1); BlockShapes.MakeHollowLayers(a, City.MapLength - a, 58, 58, a, City.MapLength - a, BlockInfo.Sand.ID, 0, -1); } for (int a = City.EdgeLength + 1; a <= City.MapLength / 2; a += 2) { if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 59, City.EdgeLength + 1, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 60, City.EdgeLength + 1, BlockInfo.Cactus.ID, 2, 50, -1); } if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 59, City.EdgeLength + 3, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 60, City.EdgeLength + 3, BlockInfo.Cactus.ID, 2, 50, -1); } } for (int a = City.EdgeLength; a <= City.MapLength / 2; a += 2) { if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 59, City.EdgeLength, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 60, City.EdgeLength, BlockInfo.Cactus.ID, 2, 50, -1); } if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 59, City.EdgeLength + 2, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 60, City.EdgeLength + 2, BlockInfo.Cactus.ID, 2, 50, -1); } if (RNG.NextDouble() > 0.5) { BlockShapes.MakeBlock(a, 59, City.EdgeLength + 4, BlockInfo.Cactus.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 60, City.EdgeLength + 4, BlockInfo.Cactus.ID, 2, 50, -1); } } if (City.HasGuardTowers) { for (int a = City.EdgeLength + 3; a <= City.EdgeLength + 13; a += 2) { BlockShapes.MakeBlock(a, 59, City.EdgeLength + 3, BlockInfo.Air.ID, 2, 100, -1); BlockShapes.MakeBlock(a, 60, City.EdgeLength + 3, BlockInfo.Air.ID, 2, 100, -1); } } break; case "Lava": for (int a = City.EdgeLength - 1; a <= City.EdgeLength + 5; a++) { BlockShapes.MakeHollowLayers(a, City.MapLength - a, 55, 56, a, City.MapLength - a, BlockInfo.Lava.ID, 0, -1); BlockShapes.MakeHollowLayers(a, City.MapLength - a, 57, 63, a, City.MapLength - a, BlockInfo.Air.ID, 0, -1); } break; case "Fire": for (int a = City.EdgeLength - 1; a <= City.EdgeLength + 5; a++) { BlockShapes.MakeHollowLayers(a, City.MapLength - a, 56, 56, a, City.MapLength - a, BlockInfo.Netherrack.ID, 0, -1); BlockShapes.MakeHollowLayers(a, City.MapLength - a, 57, 57, a, City.MapLength - a, BlockInfo.Fire.ID, 0, -1); BlockShapes.MakeHollowLayers(a, City.MapLength - a, 58, 63, a, City.MapLength - a, BlockInfo.Air.ID, 0, -1); } break; case "Water": for (int a = City.EdgeLength - 1; a <= City.EdgeLength + 5; a++) { BlockShapes.MakeHollowLayers(a, City.MapLength - a, 59, 63, a, City.MapLength - a, BlockInfo.Water.ID, 0, -1); } break; default: Debug.Fail("Invalid switch result"); break; } // drawbridge int intBridgeEnd = City.HasMoat ? -2 : 5; if (City.MoatType == "Lava" || City.MoatType == "Fire") { BlockShapes.MakeSolidBox((City.MapLength / 2) - 2, City.MapLength / 2, 63, 63, City.EdgeLength + intBridgeEnd, City.EdgeLength + 13, BlockInfo.StoneBrick.ID, 2); } else { BlockShapes.MakeSolidBox((City.MapLength / 2) - 2, City.MapLength / 2, 63, 63, City.EdgeLength + intBridgeEnd, City.EdgeLength + 13, BlockInfo.WoodPlank.ID, 2); } BlockShapes.MakeSolidBox((City.MapLength / 2) - 2, City.MapLength / 2, 64, 65, City.EdgeLength + intBridgeEnd, City.EdgeLength + 13, BlockInfo.Air.ID, 2); }
private static bool IsValidBuilding(SourceWorld.Building bldCheck, List <int> lstBuildings, int[,] intArea, int intStartX, int intStartZ, int intSizeX, int intSizeZ) { if (bldCheck.booUnique) { if (_lstAllBuildings.Contains(bldCheck.intID) || lstBuildings.Contains(bldCheck.intID)) { return(false); } else { foreach (int intID in lstBuildings) { if (SourceWorld.GetBuilding(intID).booUnique) { return(false); } } for (int x = intStartX - 8; x < intStartX + intSizeX + 8; x++) { for (int z = intStartZ - 8; z < intStartZ + intSizeZ + 8; z++) { if (x >= 0 && z >= 0 && x <= intArea.GetUpperBound(0) && z <= intArea.GetUpperBound(1)) { if (intArea[x, z] >= 100) { if (SourceWorld.GetBuilding(intArea[x, z] - 100).booUnique) { return(false); } } } } } return(true); } } else { switch (bldCheck.strFrequency) { case "very common": case "common": return(true); case "average": case "rare": case "very rare": // this exists to avoid infite loops if (RNG.NextDouble() > 0.975) { return(true); } if (lstBuildings.Contains(bldCheck.intID)) { return(false); } else { int intDistance = 0; switch (bldCheck.strFrequency) { case "average": intDistance = 12; break; case "rare": intDistance = 25; break; case "very rare": intDistance = 50; break; } for (int x = intStartX - intDistance; x < intStartX + intSizeX + intDistance; x++) { for (int z = intStartZ - intDistance; z < intStartZ + intSizeZ + intDistance; z++) { if (x >= 0 && z >= 0 && x <= intArea.GetUpperBound(0) && z <= intArea.GetUpperBound(1)) { if (intArea[x, z] - 100 == bldCheck.intID) { return(false); } } } } return(true); } // should never get here to either of these, but just in case case "exclude": Debug.WriteLine("Excluded buildings are not allowed here"); return(false); default: Debug.WriteLine("Unknown frequency type encountered"); return(false); } } }
private static int[,] FillArea(int[,] intArea, int intSizeX, int intSizeZ, int intStartX, int intStartZ, bool booUniqueBonus) { int[,] intDistrict = new int[intSizeX, intSizeZ]; int[,] intFinal = new int[intSizeX, intSizeZ]; int intWasted = intSizeX * intSizeZ, intAttempts = 15, intFail = 0; int intBonus = 0; List <int> lstBuildings = new List <int>(); List <int> lstAcceptedBuildings = new List <int>(); bool booAreaNeedsMineshaft = false; do { lstBuildings.Clear(); intBonus = 0; if (!_booIncludedMineshaft) { booAreaNeedsMineshaft = true; } do { SourceWorld.Building CurrentBuilding; if (booAreaNeedsMineshaft) { CurrentBuilding = SourceWorld.SelectRandomBuilding(SourceWorld.BuildingTypes.MineshaftEntrance, 0); // mineshaft is always the first building, so therefore it will always be possible to place it booAreaNeedsMineshaft = false; } else { do { CurrentBuilding = SourceWorld.SelectRandomBuilding(SourceWorld.BuildingTypes.City, 0); } while (!IsValidBuilding(CurrentBuilding, lstBuildings, intArea, intStartX, intStartZ, intSizeX, intSizeZ)); } bool booFound = false; if (RNG.NextDouble() > 0.5) { intDistrict = intDistrict.RotateArray(RNG.Next(4)); } int x, z = 0; for (x = 0; x < intDistrict.GetLength(0) - CurrentBuilding.intSizeX && !booFound; x++) { for (z = 0; z < intDistrict.GetLength(1) - CurrentBuilding.intSizeZ && !booFound; z++) { booFound = intDistrict.IsArraySectionAllZeros2D(x, z, x + CurrentBuilding.intSizeX, z + CurrentBuilding.intSizeZ); } } x--; z--; if (booFound) { for (int a = x + 1; a <= x + CurrentBuilding.intSizeX - 1; a++) { for (int b = z + 1; b <= z + CurrentBuilding.intSizeZ - 1; b++) { intDistrict[a, b] = 2; } } if (CurrentBuilding.booUnique && booUniqueBonus) { // we want to include the unique buildings, // so we give a slight preference to those intBonus += 15; } lstBuildings.Add(CurrentBuilding.intID); intDistrict[x + 1, z + 1] = 100 + CurrentBuilding.intID; intDistrict[x + CurrentBuilding.intSizeX - 1, z + CurrentBuilding.intSizeZ - 1] = 100 + CurrentBuilding.intID; intFail = 0; } else { intFail++; } } while (intFail < 10); int intCurWasted = Utils.ZerosInArray2D(intDistrict) - intBonus; if (intCurWasted < intWasted) { intFinal = new int[intDistrict.GetLength(0), intDistrict.GetLength(1)]; Array.Copy(intDistrict, intFinal, intDistrict.Length); intWasted = intCurWasted; intAttempts = 10; lstAcceptedBuildings.Clear(); lstAcceptedBuildings.AddRange(lstBuildings); } Array.Clear(intDistrict, 0, intDistrict.Length); intAttempts--; } while (intAttempts > 0); if (intSizeX == intFinal.GetLength(1)) { intFinal = intFinal.RotateArray(1); } _lstAllBuildings.AddRange(lstAcceptedBuildings); _booIncludedMineshaft = true; return(intFinal); }
// todo low: this is way too big private static void MakeLevel(BetaWorld world, BlockManager bm, int intDepth, int intMineshaftSize, Buildings.structPoint spMineshaftEntrance, frmMace frmLogForm) { frmLogForm.UpdateLog("Creating mineshaft level " + intDepth, true, true); string[] strResourceNames = Utils.ValueFromXMLElement(Path.Combine("Resources", "Mineshaft.xml"), "level" + intDepth, "names").Split(','); int[] intResourceChances = Utils.ValueFromXMLElement( Path.Combine("Resources", "Mineshaft.xml"), "level" + intDepth, "chances").Split(',').StringArrayToIntArray(); int intTorchChance = Convert.ToInt32(Utils.ValueFromXMLElement(Path.Combine("Resources", "Mineshaft.xml"), "level" + intDepth, "torch_chance")); MineshaftBlocks[,] mbAreaFull = new MineshaftBlocks[intMineshaftSize + (MULTIPLIER * 2), intMineshaftSize + (MULTIPLIER * 2)]; int intXPosOriginal = spMineshaftEntrance.x - _intBlockStartBuildings; int intZPosOriginal = spMineshaftEntrance.z - _intBlockStartBuildings; _intBlockStartBuildings -= 2; int[,] intAreaOverview = new int[(mbAreaFull.GetLength(0) / MULTIPLIER), (mbAreaFull.GetLength(1) / MULTIPLIER)]; int intXPos = intXPosOriginal / MULTIPLIER; int intZPos = intZPosOriginal / MULTIPLIER; intAreaOverview[intXPos, intZPos] = (int)MineshaftBlocks.Air; CreateRouteXPlus(intAreaOverview, intXPos + 1, intZPos, 0); CreateRouteZPlus(intAreaOverview, intXPos, intZPos + 1, 1); CreateRouteXMinus(intAreaOverview, intXPos - 1, intZPos, 2); CreateRouteZMinus(intAreaOverview, intXPos, intZPos - 1, 3); int intOffsetX = (intXPosOriginal - (intXPos * MULTIPLIER)) - 2; int intOffsetZ = (intZPosOriginal - (intZPos * MULTIPLIER)) - 2; List <structSection> lstSections = new List <structSection>(); intAreaOverview[intXPos, intZPos] = (int)MineshaftBlocks.Placeholder; intAreaOverview = AddMineshaftSections(intAreaOverview, intDepth); intAreaOverview[intXPos, intZPos] = (int)MineshaftBlocks.Air; for (int x = 0; x < intAreaOverview.GetLength(0); x++) { for (int z = 0; z < intAreaOverview.GetLength(1); z++) { if (intAreaOverview[x, z] >= 100) { structSection structCurrentSection = new structSection(); structCurrentSection.bldMineshaftSection = SourceWorld.GetBuilding(intAreaOverview[x, z] - 100); structCurrentSection.x = ((x * MULTIPLIER) + intOffsetX) - 1; structCurrentSection.z = ((z * MULTIPLIER) + intOffsetZ) - 1; for (int x2 = x; x2 <= x + (structCurrentSection.bldMineshaftSection.intSizeX - 1) / 7; x2++) { for (int z2 = z; z2 <= z + (structCurrentSection.bldMineshaftSection.intSizeZ - 1) / 7; z2++) { if (intAreaOverview[x2, z2] == structCurrentSection.bldMineshaftSection.intID + 100) { intAreaOverview[x2, z2] = (int)MineshaftBlocks.Structure; } } } lstSections.Add(structCurrentSection); } } } for (int x = 4; x < mbAreaFull.GetLength(0) - 4; x++) { for (int z = 4; z < mbAreaFull.GetLength(1) - 4; z++) { if (intAreaOverview.GetLength(0) > x / MULTIPLIER && intAreaOverview.GetLength(1) > z / MULTIPLIER) { switch (mbAreaFull[x + intOffsetX, z + intOffsetZ]) { case MineshaftBlocks.NaturalTerrain: case MineshaftBlocks.Air: case MineshaftBlocks.Placeholder: case MineshaftBlocks.EntranceSection: mbAreaFull[x + intOffsetX, z + intOffsetZ] = (MineshaftBlocks)intAreaOverview[x / MULTIPLIER, z / MULTIPLIER]; break; } } if ((x + 3) % 5 == 0 && (z + 3) % 5 == 0 && intAreaOverview[x / MULTIPLIER, z / MULTIPLIER] == (int)MineshaftBlocks.Air) { if (intAreaOverview[(x / MULTIPLIER) + 1, z / MULTIPLIER] >= 100) { for (int x2 = 0; x2 < 5; x2++) { mbAreaFull[x + intOffsetX + 3, z + intOffsetZ + x2 - 2] = MineshaftBlocks.Structure; } } if (intAreaOverview[(x / MULTIPLIER) + 1, z / MULTIPLIER] == (int)MineshaftBlocks.Air) { for (int x2 = 0; x2 < 5; x2++) { if (x2 == 1 || x2 == 3) { mbAreaFull[x + intOffsetX + 3, z + intOffsetZ + x2 - 2] = MineshaftBlocks.CeilingSupport; mbAreaFull[x + intOffsetX + 2, z + intOffsetZ + x2 - 2] = MineshaftBlocks.CeilingSupport; } else { mbAreaFull[x + intOffsetX + 3, z + intOffsetZ + x2 - 2] = MineshaftBlocks.Support; mbAreaFull[x + intOffsetX + 2, z + intOffsetZ + x2 - 2] = MineshaftBlocks.Support; } } for (int x2 = 0; x2 <= 5; x2++) { if (mbAreaFull[x + intOffsetX + x2, z + intOffsetZ] == MineshaftBlocks.Support) { mbAreaFull[x + intOffsetX + x2, z + intOffsetZ] = MineshaftBlocks.RailWithSupport; } else { mbAreaFull[x + intOffsetX + x2, z + intOffsetZ] = MineshaftBlocks.Rail; } } } if (intAreaOverview[x / MULTIPLIER, (z / MULTIPLIER) + 1] == (int)MineshaftBlocks.Air) { for (int z2 = 0; z2 < 5; z2++) { if (z2 == 1 || z2 == 3) { mbAreaFull[x + intOffsetX + z2 - 2, z + intOffsetZ + 3] = MineshaftBlocks.CeilingSupport; mbAreaFull[x + intOffsetX + z2 - 2, z + intOffsetZ + 2] = MineshaftBlocks.CeilingSupport; } else { mbAreaFull[x + intOffsetX + z2 - 2, z + intOffsetZ + 3] = MineshaftBlocks.Support; mbAreaFull[x + intOffsetX + z2 - 2, z + intOffsetZ + 2] = MineshaftBlocks.Support; } } for (int z2 = 0; z2 <= 5; z2++) { if (mbAreaFull[x + intOffsetX, z + intOffsetZ + z2] == MineshaftBlocks.Support) { mbAreaFull[x + intOffsetX, z + intOffsetZ + z2] = MineshaftBlocks.RailWithSupport; } else { mbAreaFull[x + intOffsetX, z + intOffsetZ + z2] = MineshaftBlocks.Rail; } } } if (intAreaOverview[x / MULTIPLIER, z / MULTIPLIER] == (int)MineshaftBlocks.Air) { MakeChestAndOrTorch(intAreaOverview, mbAreaFull, (x - 3) / MULTIPLIER, z / MULTIPLIER, x + intOffsetX - 2, z + intOffsetZ); MakeChestAndOrTorch(intAreaOverview, mbAreaFull, (x + 3) / MULTIPLIER, z / MULTIPLIER, x + intOffsetX + 2, z + intOffsetZ); MakeChestAndOrTorch(intAreaOverview, mbAreaFull, x / MULTIPLIER, (z - 3) / MULTIPLIER, x + intOffsetX, z + intOffsetZ - 2); MakeChestAndOrTorch(intAreaOverview, mbAreaFull, x / MULTIPLIER, (z + 3) / MULTIPLIER, x + intOffsetX, z + intOffsetZ + 2); } } } } mbAreaFull[intXPosOriginal, intZPosOriginal] = MineshaftBlocks.EntranceSection; int intSupportMaterial = RNG.RandomItem(BlockInfo.Wood.ID, BlockInfo.WoodPlank.ID, BlockInfo.Fence.ID); for (int x = 0; x < mbAreaFull.GetLength(0); x++) { for (int z = 0; z < mbAreaFull.GetLength(1); z++) { if (intDepth <= 4) { if (bm.GetID(x + _intBlockStartBuildings, 42 - (5 * intDepth), z + _intBlockStartBuildings) == BlockInfo.Gravel.ID) { bm.SetID(x + _intBlockStartBuildings, 42 - (5 * intDepth), z + _intBlockStartBuildings, BlockInfo.Stone.ID); } } if (intDepth <= 2) { if (bm.GetID(x + _intBlockStartBuildings, 42 - (5 * intDepth), z + _intBlockStartBuildings) == BlockInfo.Sand.ID || bm.GetID(x + _intBlockStartBuildings, 42 - (5 * intDepth), z + _intBlockStartBuildings) == BlockInfo.Sandstone.ID) { bm.SetID(x + _intBlockStartBuildings, 42 - (5 * intDepth), z + _intBlockStartBuildings, BlockInfo.Dirt.ID); } } switch (mbAreaFull[x, z]) { case MineshaftBlocks.NaturalTerrain: break; case MineshaftBlocks.Air: for (int y = 39 - (5 * intDepth); y <= 41 - (5 * intDepth); y++) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Air.ID); } break; case MineshaftBlocks.EntranceSection: case MineshaftBlocks.Rail: for (int y = 38 - (5 * intDepth); y <= 41 - (5 * intDepth); y++) { if (y == 38 - (5 * intDepth)) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Gravel.ID); } else if (y == 39 - (5 * intDepth)) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Rails.ID); } else { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Air.ID); } } break; case MineshaftBlocks.RailWithSupport: for (int y = 38 - (5 * intDepth); y <= 41 - (5 * intDepth); y++) { if (y == 38 - (5 * intDepth)) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Gravel.ID); } else if (y == 39 - (5 * intDepth)) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Rails.ID); } else if (y == 40 - (5 * intDepth)) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Air.ID); } else { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, intSupportMaterial); } } break; case MineshaftBlocks.Support: for (int y = 39 - (5 * intDepth); y <= 41 - (5 * intDepth); y++) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, intSupportMaterial); } break; case MineshaftBlocks.ChestAndOrTorch: for (int y = 39 - (5 * intDepth); y <= 41 - (5 * intDepth); y++) { if (y == 39 - (5 * intDepth) && RNG.NextDouble() > 0.9) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Chest.ID); MakeChestItems(bm, x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, intResourceChances, strResourceNames); } else if (y == 41 - (5 * intDepth) && RNG.NextDouble() < (double)intTorchChance / 100) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Torch.ID); if (mbAreaFull[x - 1, z] == 0) { bm.SetData(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, 1); } else if (mbAreaFull[x + 1, z] == 0) { bm.SetData(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, 2); } else if (mbAreaFull[x, z - 1] == 0) { bm.SetData(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, 3); } else { bm.SetData(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, 4); } } else { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Air.ID); } } break; case MineshaftBlocks.CeilingSupport: for (int y = 39 - (5 * intDepth); y <= 41 - (5 * intDepth); y++) { if (y == 41 - (5 * intDepth)) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, intSupportMaterial); } else { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Air.ID); } } break; case MineshaftBlocks.Unused9: for (int y = 39 - (5 * intDepth); y <= 41 - (5 * (intDepth - 1)); y++) { bm.SetID(x + _intBlockStartBuildings, y, z + _intBlockStartBuildings, BlockInfo.Air.ID); } break; case MineshaftBlocks.Structure: // this will be overwritten later break; default: Debug.Fail("Invalid switch result"); break; } } } foreach (structSection MineshaftSection in lstSections) { SourceWorld.InsertBuilding(bm, new int[0, 0], _intBlockStartBuildings, MineshaftSection.x, MineshaftSection.z, MineshaftSection.bldMineshaftSection, 38 - (5 * intDepth), -1); } world.Save(); _intBlockStartBuildings += 2; //#if DEBUG // File.WriteAllText("output_area_" + intDepth + ".txt", Utils.TwoDimensionalArrayToString(intAreaOverview)); // File.WriteAllText("output_map_" + intDepth + ".txt", Utils.TwoDimensionalArrayToString(intAreaFull)); //#endif }
// this is a simplified version of the FillArea method from Paths.cs private static int[,] FillArea(int intSizeX, int intSizeZ) { int[,] intDistrict = new int[intSizeX, intSizeZ]; int[,] intFinal = new int[intSizeX, intSizeZ]; int intWasted = intSizeX * intSizeZ, intAttempts = 15, intFail = 0; int intBonus = 0; List <int> lstBuildings = new List <int>(); do { lstBuildings.Clear(); intBonus = 0; do { SourceWorld.Building CurrentBuilding; do { CurrentBuilding = SourceWorld.SelectRandomBuilding(SourceWorld.BuildingTypes.Farming, 0); } while (!IsValidBuilding(CurrentBuilding, lstBuildings)); bool booFound = false; if (RNG.NextDouble() > 0.5) { intDistrict = intDistrict.RotateArray(RNG.Next(4)); } int x, z = 0; for (x = 0; x < intDistrict.GetLength(0) - CurrentBuilding.intSizeX && !booFound; x++) { for (z = 0; z < intDistrict.GetLength(1) - CurrentBuilding.intSizeZ && !booFound; z++) { booFound = intDistrict.IsArraySectionAllZeros2D(x, z, x + CurrentBuilding.intSizeX, z + CurrentBuilding.intSizeZ); } } x--; z--; if (booFound) { for (int a = x + 1; a <= x + CurrentBuilding.intSizeX - 1; a++) { for (int b = z + 1; b <= z + CurrentBuilding.intSizeZ - 1; b++) { intDistrict[a, b] = 2; } } if (CurrentBuilding.booUnique) { intBonus += 15; } lstBuildings.Add(CurrentBuilding.intID); intDistrict[x + 1, z + 1] = 100 + CurrentBuilding.intID; intDistrict[x + CurrentBuilding.intSizeX - 1, z + CurrentBuilding.intSizeZ - 1] = 100 + CurrentBuilding.intID; intFail = 0; } else { intFail++; } } while (intFail < 10); int intCurWasted = Utils.ZerosInArray2D(intDistrict) - intBonus; if (intCurWasted < intWasted) { intFinal = new int[intDistrict.GetLength(0), intDistrict.GetLength(1)]; Array.Copy(intDistrict, intFinal, intDistrict.Length); intWasted = intCurWasted; intAttempts = 10; } Array.Clear(intDistrict, 0, intDistrict.Length); intAttempts--; } while (intAttempts > 0); if (intSizeX == intFinal.GetLength(1)) { intFinal = intFinal.RotateArray(1); } return(intFinal); }
private static void MakePond(BlockManager bm, int x, int xlen, int z, int zlen) { int[,] intArea = new int[xlen, zlen]; int a, b; int c = 0, d = 0, clen = -1, dlen = -1; if (xlen >= 12 && zlen >= 12) { c = RNG.Next(1, intArea.GetUpperBound(0) - 7); d = RNG.Next(1, intArea.GetUpperBound(1) - 7); clen = RNG.Next(2, 4); dlen = RNG.Next(2, 4); } for (a = 1; a <= intArea.GetUpperBound(0) - 1; a++) { for (b = 1; b <= intArea.GetUpperBound(1) - 1; b++) { if (a < c || a > c + clen || b < d || b > d + dlen) { intArea[a, b] = 1; } } } intArea = CheckAgainstNeighbours(intArea, 0, 0, 7, 0, RNG.Next(3, 6), true); intArea = CheckAgainstNeighbours(intArea, 6, 0, 2, 2, 1, false); intArea = CheckAgainstNeighbours(intArea, 14, 0, 3, 3, 1, false); bool booLava = RNG.NextDouble() < 0.15; for (a = 1; a < intArea.GetUpperBound(0); a++) { for (b = 1; b < intArea.GetUpperBound(1); b++) { if (intArea[a, b] == 1) { if (!booLava && RNG.NextDouble() < 0.05) { bm.SetID(x + a, 64, z + b, BlockInfo.SugarCane.ID); } else { bm.SetID(x + a, 64, z + b, BlockInfo.TallGrass.ID); bm.SetData(x + a, 64, z + b, RNG.Next(1, 3)); } } else { for (int y = 2; y <= intArea[a, b]; y++) { if (booLava) { bm.SetID(x + a, 65 - y, z + b, BlockInfo.StationaryLava.ID); } else { bm.SetID(x + a, 65 - y, z + b, BlockInfo.StationaryWater.ID); if (y == 2 && RNG.NextDouble() < 0.1) { bm.SetID(x + a, 66 - y, z + b, BlockInfo.LillyPad.ID); } } } } } } }