bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile) { MTRand rnd; m_World = a_World; m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt()); AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable"); if (NoCaseCompare(GeneratorName, "Noise3D") == 0) { m_Generator = new cNoise3DGenerator(*this); } else { if (NoCaseCompare(GeneratorName, "composable") != 0) { LOGWARN("[Generator]::Generator value \"%s\" not recognized, using \"Composable\".", GeneratorName.c_str()); } m_Generator = new cComposableGenerator(*this); } if (m_Generator == NULL) { LOGERROR("Generator could not start, aborting the server"); return false; } m_Generator->Initialize(a_World, a_IniFile); return super::Start(); }
void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) { // The first schema added is considered the default m_Schemas.push_back(new cWSSAnvil (m_World,a_StorageCompressionFactor)); m_Schemas.push_back(new cWSSCompact (m_World,a_StorageCompressionFactor)); m_Schemas.push_back(new cWSSForgetful(m_World)); // Add new schemas here if (NoCaseCompare(m_StorageSchemaName, "default") == 0) { m_SaveSchema = m_Schemas.front(); return; } for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) { if (NoCaseCompare((*itr)->GetName(), m_StorageSchemaName) == 0) { m_SaveSchema = *itr; return; } } // for itr - m_Schemas[] // Unknown schema selected, let the admin know: LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str() ); for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) { LOGWARNING("\t\"%s\"", (*itr)->GetName().c_str()); } m_SaveSchema = m_Schemas.front(); }
void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { int Seed = m_ChunkGenerator.GetSeed(); eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow,Lilypads,BottomLava,DeadBushes,PreSimulator"); AStringVector Str = StringSplitAndTrim(Finishers, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { // Finishers, alpha-sorted: if (NoCaseCompare(*itr, "BottomLava") == 0) { int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); } else if (NoCaseCompare(*itr, "DeadBushes") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND)); } else if (NoCaseCompare(*itr, "Ice") == 0) { m_FinishGens.push_back(new cFinishGenIce); } else if (NoCaseCompare(*itr, "LavaSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); } else if (NoCaseCompare(*itr, "Lilypads") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_LILY_PAD, biSwampland, 4, E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER)); } else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { m_FinishGens.push_back(new cFinishGenPreSimulator); } else if (NoCaseCompare(*itr, "Snow") == 0) { m_FinishGens.push_back(new cFinishGenSnow); } else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) { m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)); } } // for itr - Str[] }
cObjective::eType cObjective::StringToType(const AString & a_Name) { static struct { eType m_Type; const char * m_String; } TypeMap [] = { {otDummy, "dummy" }, {otDeathCount, "deathCount" }, {otPlayerKillCount, "playerKillCount" }, {otTotalKillCount, "totalKillCount" }, {otHealth, "health" }, {otAchievement, "achievement" }, {otStat, "stat" }, {otStatItemCraft, "stat.craftItem" }, {otStatItemUse, "stat.useItem" }, {otStatItemBreak, "stat.breakItem" }, {otStatBlockMine, "stat.mineBlock" }, {otStatEntityKill, "stat.killEntity" }, {otStatEntityKilledBy, "stat.entityKilledBy"} }; for (size_t i = 0; i < ARRAYCOUNT(TypeMap); i++) { if (NoCaseCompare(TypeMap[i].m_String, a_Name) == 0) { return TypeMap[i].m_Type; } } // for i - TypeMap[] return otDummy; }
EMCSBiome StringToBiome(const AString & a_BiomeString) { // If it is a number, return it: int res = atoi(a_BiomeString.c_str()); if ((res != 0) || (a_BiomeString.compare("0") == 0)) { if ((res >= biFirstBiome) && (res < biNumBiomes)) { return (EMCSBiome)res; } else if ((res >= biFirstVariantBiome) && (res < biNumVariantBiomes)) { return (EMCSBiome)res; } // It was an invalid number return biInvalidBiome; } for (size_t i = 0; i < ARRAYCOUNT(g_BiomeMap); i++) { if (NoCaseCompare(g_BiomeMap[i].m_String, a_BiomeString) == 0) { return g_BiomeMap[i].m_Biome; } } // for i - BiomeMap[] return biInvalidBiome; }
cPiece::cVerticalStrategyPtr CreateVerticalStrategyFromString(const AString & a_StrategyDesc, bool a_LogWarnings) { // Break apart the strategy class, the first parameter before the first pipe char: auto idxPipe = a_StrategyDesc.find('|'); if (idxPipe == AString::npos) { idxPipe = a_StrategyDesc.length(); } AString StrategyClass = a_StrategyDesc.substr(0, idxPipe); // Create a strategy class based on the class string: cPiece::cVerticalStrategyPtr Strategy; if (NoCaseCompare(StrategyClass, "Fixed") == 0) { Strategy = std::make_shared<cVerticalStrategyFixed>(); } else if (NoCaseCompare(StrategyClass, "Range") == 0) { Strategy = std::make_shared<cVerticalStrategyRange>(); } else if (NoCaseCompare(StrategyClass, "TerrainTop") == 0) { Strategy = std::make_shared<cVerticalStrategyTerrainTop>(); } else if (NoCaseCompare(StrategyClass, "TerrainOrOceanTop") == 0) { Strategy = std::make_shared<cVerticalStrategyTerrainOrOceanTop>(); } else { return nullptr; } // Initialize the strategy's parameters: AString Params; if (idxPipe < a_StrategyDesc.length()) { Params = a_StrategyDesc.substr(idxPipe + 1); } if (!Strategy->InitializeFromString(Params, a_LogWarnings)) { return nullptr; } return Strategy; }
bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a_ChunkSink, cIniFile & a_IniFile) { m_PluginInterface = &a_PluginInterface; m_ChunkSink = &a_ChunkSink; // Get the seed; create a new one and log it if not found in the INI file: if (a_IniFile.HasValue("Seed", "Seed")) { m_Seed = a_IniFile.GetValueI("Seed", "Seed"); } else { MTRand rnd; m_Seed = rnd.randInt(); LOGINFO("Chosen a new random seed for world: %d", m_Seed); a_IniFile.SetValueI("Seed", "Seed", m_Seed); } // Get the generator engine based on the INI file settings: AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable"); if (NoCaseCompare(GeneratorName, "Noise3D") == 0) { m_Generator = new cNoise3DGenerator(*this); } else { if (NoCaseCompare(GeneratorName, "composable") != 0) { LOGWARN("[Generator]::Generator value \"%s\" not recognized, using \"Composable\".", GeneratorName.c_str()); } m_Generator = new cComposableGenerator(*this); } if (m_Generator == nullptr) { LOGERROR("Generator could not start, aborting the server"); return false; } m_Generator->Initialize(a_IniFile); return super::Start(); }
EMCSBiome StringToBiome(const AString & a_BiomeString) { // If it is a number, return it: int res = atoi(a_BiomeString.c_str()); if ((res != 0) || (a_BiomeString.compare("0") == 0)) { // It was a valid number return (EMCSBiome)res; } // Convert using the built-in map: static struct { EMCSBiome m_Biome; const char * m_String; } BiomeMap[] = { {biOcean, "Ocean"} , {biPlains, "Plains"}, {biDesert, "Desert"}, {biExtremeHills, "ExtremeHills"}, {biForest, "Forest"}, {biTaiga, "Taiga"}, {biSwampland, "Swampland"}, {biRiver, "River"}, {biNether, "Hell"}, {biNether, "Nether"}, {biEnd, "Sky"}, {biEnd, "End"}, {biFrozenOcean, "FrozenOcean"}, {biFrozenRiver, "FrozenRiver"}, {biIcePlains, "IcePlains"}, {biIcePlains, "Tundra"}, {biIceMountains, "IceMountains"}, {biMushroomIsland, "MushroomIsland"}, {biMushroomShore, "MushroomShore"}, {biBeach, "Beach"}, {biDesertHills, "DesertHills"}, {biForestHills, "ForestHills"}, {biTaigaHills, "TaigaHills"}, {biExtremeHillsEdge, "ExtremeHillsEdge"}, {biJungle, "Jungle"}, {biJungleHills, "JungleHills"}, } ; for (int i = 0; i < ARRAYCOUNT(BiomeMap); i++) { if (NoCaseCompare(BiomeMap[i].m_String, a_BiomeString) == 0) { return BiomeMap[i].m_Biome; } } // for i - BiomeMap[] return (EMCSBiome)-1; }
int cEnchantments::StringToEnchantmentID(const AString & a_EnchantmentName) { static const struct { int m_Value; const char * m_Name; } EnchantmentNames[] = { { enchProtection, "Protection"}, { enchFireProtection, "FireProtection"}, { enchFeatherFalling, "FeatherFalling"}, { enchBlastProtection, "BlastProtection"}, { enchProjectileProtection, "ProjectileProtection"}, { enchRespiration, "Respiration"}, { enchAquaAffinity, "AquaAffinity"}, { enchThorns, "Thorns"}, { enchDepthStrider, "DepthStrider"}, { enchSharpness, "Sharpness"}, { enchSmite, "Smite"}, { enchBaneOfArthropods, "BaneOfArthropods"}, { enchKnockback, "Knockback"}, { enchFireAspect, "FireAspect"}, { enchLooting, "Looting"}, { enchEfficiency, "Efficiency"}, { enchSilkTouch, "SilkTouch"}, { enchUnbreaking, "Unbreaking"}, { enchFortune, "Fortune"}, { enchPower, "Power"}, { enchPunch, "Punch"}, { enchFlame, "Flame"}, { enchInfinity, "Infinity"}, { enchLuckOfTheSea, "LuckOfTheSea"}, { enchLure, "Lure"}, } ; // First try to parse as a number: int id = atoi(a_EnchantmentName.c_str()); if ((id != 0) || (a_EnchantmentName == "0")) { return id; } // It wasn't a number, do a lookup: for (size_t i = 0; i < ARRAYCOUNT(EnchantmentNames); i++) { if (NoCaseCompare(EnchantmentNames[i].m_Name, a_EnchantmentName) == 0) { return EnchantmentNames[i].m_Value; } } // for i - EnchantmentNames[] return -1; }
void cHTTPRequest::OnHeaderLine(const AString & a_Key, const AString & a_Value) { if ( (NoCaseCompare(a_Key, "Authorization") == 0) && (strncmp(a_Value.c_str(), "Basic ", 6) == 0) ) { AString UserPass = Base64Decode(a_Value.substr(6)); size_t idxCol = UserPass.find(':'); if (idxCol != AString::npos) { m_AuthUsername = UserPass.substr(0, idxCol); m_AuthPassword = UserPass.substr(idxCol + 1); m_HasAuth = true; } } if ((a_Key == "Connection") && (NoCaseCompare(a_Value, "keep-alive") == 0)) { m_AllowKeepAlive = true; } AddHeader(a_Key, a_Value); }
cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault) { AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); if (BiomeGenName.empty()) { LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\"."); BiomeGenName = "MultiStepMap"; } cBiomeGen * res = NULL; a_CacheOffByDefault = false; if (NoCaseCompare(BiomeGenName, "constant") == 0) { res = new cBioGenConstant; a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :) } else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0) { res = new cBioGenCheckerboard; a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data } else if (NoCaseCompare(BiomeGenName, "voronoi") == 0) { res = new cBioGenVoronoi(a_Seed); } else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0) { res = new cBioGenDistortedVoronoi(a_Seed); } else if (NoCaseCompare(BiomeGenName, "twolevel") == 0) { res = new cBioGenTwoLevel(a_Seed); } else { if (NoCaseCompare(BiomeGenName, "multistepmap") != 0) { LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str()); } res = new cBioGenMultiStepMap(a_Seed); /* // Performance-testing: LOGINFO("Measuring performance of cBioGenMultiStepMap..."); clock_t BeginTick = clock(); for (int x = 0; x < 5000; x++) { cChunkDef::BiomeMap Biomes; res->GenBiomes(x * 5, x * 5, Biomes); } clock_t Duration = clock() - BeginTick; LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC); //*/ } res->InitializeBiomeGen(a_IniFile); return res; }
int StringToMobType(const AString & a_MobString) { static struct { int m_MobType; const char * m_String; } MobMap [] = { {cMonster::mtCreeper, "Creeper"}, {cMonster::mtSkeleton, "Skeleton"}, {cMonster::mtSpider, "Spider"}, {cMonster::mtGiant, "Giant"}, {cMonster::mtZombie, "Zombie"}, {cMonster::mtSlime, "Slime"}, {cMonster::mtGhast, "Ghast"}, {cMonster::mtZombiePigman, "ZombiePigman"}, {cMonster::mtEnderman, "Enderman"}, {cMonster::mtCaveSpider, "CaveSpider"}, {cMonster::mtSilverfish, "SilverFish"}, {cMonster::mtBlaze, "Blaze"}, {cMonster::mtMagmaCube, "MagmaCube"}, {cMonster::mtEnderDragon, "EnderDragon"}, {cMonster::mtWither, "Wither"}, {cMonster::mtBat, "Bat"}, {cMonster::mtWitch, "Witch"}, {cMonster::mtPig, "Pig"}, {cMonster::mtSheep, "Sheep"}, {cMonster::mtCow, "Cow"}, {cMonster::mtChicken, "Chicken"}, {cMonster::mtSquid, "Squid"}, {cMonster::mtWolf, "Wolf"}, {cMonster::mtMooshroom, "Mooshroom"}, {cMonster::mtSnowGolem, "SnowGolem"}, {cMonster::mtOcelot, "Ocelot"}, {cMonster::mtIronGolem, "IronGolem"}, {cMonster::mtVillager, "Villager"}, }; for (size_t i = 0; i < ARRAYCOUNT(MobMap); i++) { if (NoCaseCompare(MobMap[i].m_String, a_MobString) == 0) { return MobMap[i].m_MobType; } } // for i - MobMap[] return -1; }
void cPluginManager::TabCompleteCommand(const AString & a_Text, AStringVector & a_Results, cPlayer * a_Player) { for (CommandMap::iterator itr = m_Commands.begin(), end = m_Commands.end(); itr != end; ++itr) { if (NoCaseCompare(itr->first.substr(0, a_Text.length()), a_Text) != 0) { // Command name doesn't match continue; } if ((a_Player != NULL) && !a_Player->HasPermission(itr->second.m_Permission)) { // Player doesn't have permission for the command continue; } a_Results.push_back(itr->first); } }
void cHTTPFormParser::OnPartHeader(const AString & a_Key, const AString & a_Value) { if (NoCaseCompare(a_Key, "Content-Disposition") == 0) { size_t len = a_Value.size(); size_t ParamsStart = AString::npos; for (size_t i = 0; i < len; ++i) { if (a_Value[i] > ' ') { if (strncmp(a_Value.c_str() + i, "form-data", 9) != 0) { // Content disposition is not "form-data", mark the whole form invalid m_IsValid = false; return; } ParamsStart = a_Value.find(';', i + 9); break; } } if (ParamsStart == AString::npos) { // There is data missing in the Content-Disposition field, mark the whole form invalid: m_IsValid = false; return; } // Parse the field name and optional filename from this header: cNameValueParser Parser(a_Value.data() + ParamsStart, a_Value.size() - ParamsStart); Parser.Finish(); m_CurrentPartName = Parser["name"]; if (!Parser.IsValid() || m_CurrentPartName.empty()) { // The required parameter "name" is missing, mark the whole form invalid: m_IsValid = false; return; } m_CurrentPartFileName = Parser["filename"]; } }
int cEnchantments::StringToEnchantmentID(const AString & a_EnchantmentName) { struct { int m_Value; const char * m_Name; } EnchantmentNames[] = { { enchProtection, "Protection"}, { enchFireProtection, "FireProtection"}, { enchFeatherFalling, "FeatherFalling"}, { enchBlastProtection, "BlastProtection"}, { enchProjectileProtection, "ProjectileProtection"}, { enchRespiration, "Respiration"}, { enchAquaAffinity, "AquaAffinity"}, { enchThorns, "Thorns"}, { enchSharpness, "Sharpness"}, { enchSmite, "Smite"}, { enchBaneOfArthropods, "BaneOfArthropods"}, { enchKnockback, "Knockback"}, { enchFireAspect, "FireAspect"}, { enchLooting, "Looting"}, { enchEfficiency, "Efficiency"}, { enchSilkTouch, "SilkTouch"}, { enchUnbreaking, "Unbreaking"}, { enchFortune, "Fortune"}, { enchPower, "Power"}, { enchPunch, "Punch"}, { enchFlame, "Flame"}, { enchInfinity, "Infinity"}, } ; for (int i = 0; i < ARRAYCOUNT(EnchantmentNames); i++) { if (NoCaseCompare(EnchantmentNames[i].m_Name, a_EnchantmentName) == 0) { return EnchantmentNames[i].m_Value; } } // for i - EnchantmentNames[] return -1; }
cVillageGen::cVillageGen( int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen, int a_SeaLevel, const AStringVector & a_PrefabsToLoad ) : super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100), m_Noise(a_Seed + 1000), m_MaxDepth(a_MaxDepth), m_MaxSize(a_MaxSize), m_MinDensity(a_MinDensity), m_MaxDensity(a_MaxDensity), m_BiomeGen(a_BiomeGen), m_HeightGen(a_HeightGen) { for (const auto & toLoad: a_PrefabsToLoad) { auto prefabs = std::make_shared<cVillagePiecePool>(); auto fileName = Printf("Prefabs%sVillages%s%s.cubeset", cFile::GetPathSeparator().c_str(), cFile::GetPathSeparator().c_str(), toLoad.c_str()); if (prefabs->LoadFromFile(fileName, true)) { if (NoCaseCompare(prefabs->GetIntendedUse(), "village") != 0) { LOGWARNING("Village generator: File %s is intended for use in \"%s\", rather than villages. Loading the file, but the generator may behave unexpectedly.", fileName.c_str(), prefabs->GetIntendedUse().c_str() ); } prefabs->AssignGens(a_Seed, m_BiomeGen, m_HeightGen, a_SeaLevel); m_Pools.push_back(std::move(prefabs)); } } }
/** Test that FromString -> ToShortString preserves the original value for short UUIDs. */ static void UUIDFromStringToShortString() { const char TestStrings[][33]{ "0123456789abcdef0123456789ABCDEF", "d188b2648cc311e7bb31be2e44b06b34", "e760d270d8b34288b895d9f78a31e083", "7052f2f2594246abb8e3fed602158870", "7f14d4b60cd84ba7885c8301b67ce891", "57be7039250548b590af272291fabcfa" }; for (auto TestString : TestStrings) { cUUID UUID; assert_test(UUID.FromString(TestString)); auto ResultString = UUID.ToShortString(); // Result should be equivalent to original assert_test(NoCaseCompare(ResultString, TestString) == 0); // And should be all lower case assert_test(ResultString == StrToLower(ResultString)); } }
/** Test that FromString -> ToLongString preserves the original value for long UUIDs. */ static void UUIDFromStringToLongString() { const char TestStrings[][37]{ "01234567-89ab-cdef-0123-456789ABCDEF", "d188b264-8cc3-11e7-bb31-be2e44b06b34", "e760d270-d8b3-4288-b895-d9f78a31e083", "7052f2f2-5942-46ab-b8e3-fed602158870", "7f14d4b6-0cd8-4ba7-885c-8301b67ce891", "57be7039-2505-48b5-90af-272291fabcfa" }; for (auto TestString : TestStrings) { cUUID UUID; assert_test(UUID.FromString(TestString)); auto ResultString = UUID.ToLongString(); // Result should be equivalent to original assert_test(NoCaseCompare(ResultString, TestString) == 0); // And should be all lower case assert_test(ResultString == StrToLower(ResultString)); } }
void cPluginManager::TabCompleteCommand(const AString & a_Text, AStringVector & a_Results, cPlayer * a_Player) { for (CommandMap::iterator itr = m_Commands.begin(), end = m_Commands.end(); itr != end; ++itr) { if (NoCaseCompare(itr->first.substr(0, a_Text.length()), a_Text) != 0) { // Command name doesn't match continue; } if ((a_Player != nullptr) && !a_Player->HasPermission(itr->second.m_Permission)) { // Player doesn't have permission for the command continue; } /* Client expects to only get back the last part of a space separated command. Find the position of the beginning of the last part: Position of last space + 1 for space separated commands string::npos + 1 = 0 for commands that are not separated Then skip all commands that have too many subcommands. When the client asks for suggestions for "/time s" the server must skip all commands that consist of more than 2 words just as "/time set day". Or in other words, the position of the last space (separator) in the strings must be equal or string::npos for both. */ size_t LastSpaceInText = a_Text.find_last_of(' ') + 1; size_t LastSpaceInSuggestion = itr->first.find_last_of(' ') + 1; if (LastSpaceInText != LastSpaceInSuggestion) { // Suggestion has more subcommands than a_Text continue; } a_Results.push_back(itr->first.substr(LastSpaceInSuggestion)); } }
eDimension StringToDimension(const AString & a_DimensionString) { // First try decoding as a number int res; if (StringToInteger(a_DimensionString, res)) { // It was a valid number return static_cast<eDimension>(res); } // Decode using a built-in map: static struct { eDimension m_Dimension; const char * m_String; } DimensionMap [] = { { dimOverworld, "Overworld"}, { dimOverworld, "Normal"}, { dimOverworld, "World"}, { dimNether, "Nether"}, { dimNether, "Hell"}, // Alternate name for Nether { dimEnd, "End"}, { dimEnd, "Sky"}, // Old name for End } ; for (size_t i = 0; i < ARRAYCOUNT(DimensionMap); i++) { if (NoCaseCompare(DimensionMap[i].m_String, a_DimensionString) == 0) { return DimensionMap[i].m_Dimension; } } // for i - DimensionMap[] // Not found LOGWARNING("Unknown dimension: \"%s\". Setting to Overworld", a_DimensionString.c_str()); return dimOverworld; }
eDimension StringToDimension(const AString & a_DimensionString) { // First try decoding as a number int res = atoi(a_DimensionString.c_str()); if ((res != 0) || (a_DimensionString == "0")) { // It was a valid number return (eDimension)res; } // Decode using a built-in map: static struct { eDimension m_Dimension; const char * m_String; } DimensionMap [] = { { dimOverworld, "Overworld"}, { dimOverworld, "Normal"}, { dimOverworld, "World"}, { dimNether, "Nether"}, { dimNether, "Hell"}, // Alternate name for End { dimEnd, "End"}, { dimEnd, "Sky"}, // Old name for End } ; for (int i = 0; i < ARRAYCOUNT(DimensionMap); i++) { if (NoCaseCompare(DimensionMap[i].m_String, a_DimensionString) == 0) { return DimensionMap[i].m_Dimension; } } // for i - DimensionMap[] // Not found return (eDimension)-1000; }
void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile) { AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees"); int Seed = m_ChunkGenerator.GetSeed(); AStringVector Str = StringSplitAndTrim(Structures, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) { float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); m_StructureGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); } else if (NoCaseCompare(*itr, "DirectOverhangs") == 0) { m_StructureGens.push_back(new cStructGenDirectOverhangs(Seed)); } else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0) { m_StructureGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); } else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); m_StructureGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); } else if (NoCaseCompare(*itr, "MarbleCaves") == 0) { m_StructureGens.push_back(new cStructGenMarbleCaves(Seed)); } else if (NoCaseCompare(*itr, "MineShafts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512); int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160); int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); m_StructureGens.push_back(new cStructGenMineShafts( Seed, GridSize, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } else if (NoCaseCompare(*itr, "OreNests") == 0) { m_StructureGens.push_back(new cStructGenOreNests(Seed)); } else if (NoCaseCompare(*itr, "Ravines") == 0) { m_StructureGens.push_back(new cStructGenRavines(Seed, 128)); } else if (NoCaseCompare(*itr, "Trees") == 0) { m_StructureGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); m_StructureGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); } else if (NoCaseCompare(*itr, "WormNestCaves") == 0) { m_StructureGens.push_back(new cStructGenWormNestCaves(Seed)); } else { LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str()); } } // for itr - Str[] }
/// Translates a damage type string to damage type. Takes either a number or a damage type alias (built-in). Returns -1 on failure eDamageType StringToDamageType(const AString & a_DamageTypeString) { // First try decoding as a number: int res = atoi(a_DamageTypeString.c_str()); if ((res != 0) || (a_DamageTypeString == "0")) { // It was a valid number return (eDamageType)res; } // Decode using a built-in map: static struct { eDamageType m_DamageType; const char * m_String; } DamageTypeMap [] = { // Cannonical names: { dtAttack, "dtAttack"}, { dtLightning, "dtLightning"}, { dtFalling, "dtFalling"}, { dtDrowning, "dtDrowning"}, { dtSuffocating, "dtSuffocation"}, { dtStarving, "dtStarving"}, { dtCactusContact, "dtCactusContact"}, { dtLavaContact, "dtLavaContact"}, { dtPoisoning, "dtPoisoning"}, { dtOnFire, "dtOnFire"}, { dtFireContact, "dtFireContact"}, { dtInVoid, "dtInVoid"}, { dtPotionOfHarming, "dtPotionOfHarming"}, { dtAdmin, "dtAdmin"}, // Common synonyms: { dtPawnAttack, "dtAttack"}, { dtEntityAttack, "dtAttack"}, { dtMob, "dtAttack"}, { dtMobAttack, "dtAttack"}, { dtFall, "dtFalling"}, { dtDrown, "dtDrowning"}, { dtSuffocation, "dtSuffocating"}, { dtStarvation, "dtStarving"}, { dtHunger, "dtStarving"}, { dtCactus, "dtCactusContact"}, { dtCactuses, "dtCactusContact"}, { dtCacti, "dtCactusContact"}, { dtLava, "dtLavaContact"}, { dtPoison, "dtPoisoning"}, { dtBurning, "dtOnFire"}, { dtInFire, "dtFireContact"}, { dtPlugin, "dtAdmin"}, } ; for (int i = 0; i < ARRAYCOUNT(DamageTypeMap); i++) { if (NoCaseCompare(DamageTypeMap[i].m_String, a_DamageTypeString) == 0) { return DamageTypeMap[i].m_DamageType; } } // for i - DamageTypeMap[] // Not found: return (eDamageType)-1; }
void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { int Seed = m_ChunkGenerator.GetSeed(); eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); // Older configuration used "Structures" in addition to "Finishers"; we don't distinguish between the two anymore (#398) // Therefore, we load Structures from the ini file for compatibility, but move its contents over to Finishers: AString Structures = a_IniFile.GetValue("Generator", "Structures", ""); AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); if (!Structures.empty()) { LOGINFO("[Generator].Structures is deprecated, moving the contents to [Generator].Finishers."); // Structures used to generate before Finishers, so place them first: Structures.append(", "); Finishers = Structures + Finishers; a_IniFile.SetValue("Generator", "Finishers", Finishers); } a_IniFile.DeleteValue("Generator", "Structures"); // Create all requested finishers: AStringVector Str = StringSplitAndTrim(Finishers, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { // Finishers, alpha-sorted: if (NoCaseCompare(*itr, "BottomLava") == 0) { int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); } else if (NoCaseCompare(*itr, "DeadBushes") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND)); } else if (NoCaseCompare(*itr, "DirectOverhangs") == 0) { m_FinishGens.push_back(new cStructGenDirectOverhangs(Seed)); } else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0) { m_FinishGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); } else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) { float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); } else if (NoCaseCompare(*itr, "Ice") == 0) { m_FinishGens.push_back(new cFinishGenIce); } else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); m_FinishGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); } else if (NoCaseCompare(*itr, "LavaSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); } else if (NoCaseCompare(*itr, "MarbleCaves") == 0) { m_FinishGens.push_back(new cStructGenMarbleCaves(Seed)); } else if (NoCaseCompare(*itr, "MineShafts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512); int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160); int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); m_FinishGens.push_back(new cStructGenMineShafts( Seed, GridSize, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } else if (NoCaseCompare(*itr, "Lilypads") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_LILY_PAD, biSwampland, 4, E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER)); } else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); } else if (NoCaseCompare(*itr, "NetherForts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth)); } else if (NoCaseCompare(*itr, "OreNests") == 0) { m_FinishGens.push_back(new cStructGenOreNests(Seed)); } else if (NoCaseCompare(*itr, "POCPieces") == 0) { m_FinishGens.push_back(new cPOCPieceGenerator(Seed)); } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { m_FinishGens.push_back(new cFinishGenPreSimulator); } else if (NoCaseCompare(*itr, "RainbowRoads") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512); int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30); int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260); m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxDepth, MaxSize)); } else if (NoCaseCompare(*itr, "Ravines") == 0) { m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); } else if (NoCaseCompare(*itr, "Snow") == 0) { m_FinishGens.push_back(new cFinishGenSnow); } else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) { m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); } else if (NoCaseCompare(*itr, "Trees") == 0) { m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); } else if (NoCaseCompare(*itr, "UnderwaterBases") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024); int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen)); } else if (NoCaseCompare(*itr, "Villages") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384); int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 2); int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50); int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80); m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen)); } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); m_FinishGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)); } else if (NoCaseCompare(*itr, "WormNestCaves") == 0) { m_FinishGens.push_back(new cStructGenWormNestCaves(Seed)); } else { LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", itr->c_str()); } } // for itr - Str[] }
/// Translates a damage type string to damage type. Takes either a number or a damage type alias (built-in). Returns -1 on failure eDamageType StringToDamageType(const AString & a_DamageTypeString) { // First try decoding as a number: int res; if (!StringToInteger(a_DamageTypeString, res)) { // It was a valid number return static_cast<eDamageType>(res); } // Decode using a built-in map: static struct { eDamageType m_DamageType; const char * m_String; } DamageTypeMap [] = { // Cannonical names: { dtAttack, "dtAttack"}, { dtRangedAttack, "dtRangedAttack"}, { dtLightning, "dtLightning"}, { dtFalling, "dtFalling"}, { dtDrowning, "dtDrowning"}, { dtSuffocating, "dtSuffocation"}, { dtStarving, "dtStarving"}, { dtCactusContact, "dtCactusContact"}, { dtLavaContact, "dtLavaContact"}, { dtPoisoning, "dtPoisoning"}, { dtWithering, "dtWithering"}, { dtOnFire, "dtOnFire"}, { dtFireContact, "dtFireContact"}, { dtInVoid, "dtInVoid"}, { dtPotionOfHarming, "dtPotionOfHarming"}, { dtAdmin, "dtAdmin"}, { dtExplosion, "dtExplosion"}, // Common synonyms: { dtAttack, "dtPawnAttack"}, { dtAttack, "dtEntityAttack"}, { dtAttack, "dtMob"}, { dtAttack, "dtMobAttack"}, { dtRangedAttack, "dtArrowAttack"}, { dtRangedAttack, "dtArrow"}, { dtRangedAttack, "dtProjectile"}, { dtFalling, "dtFall"}, { dtDrowning, "dtDrown"}, { dtSuffocating, "dtSuffocation"}, { dtStarving, "dtStarvation"}, { dtStarving, "dtHunger"}, { dtCactusContact, "dtCactus"}, { dtCactusContact, "dtCactuses"}, { dtCactusContact, "dtCacti"}, { dtLavaContact, "dtLava"}, { dtPoisoning, "dtPoison"}, { dtWithering, "dtWither"}, { dtOnFire, "dtBurning"}, { dtFireContact, "dtInFire"}, { dtAdmin, "dtPlugin"}, } ; for (size_t i = 0; i < ARRAYCOUNT(DamageTypeMap); i++) { if (NoCaseCompare(DamageTypeMap[i].m_String, a_DamageTypeString) == 0) { return DamageTypeMap[i].m_DamageType; } } // for i - DamageTypeMap[] // Not found: return static_cast<eDamageType>(-1); }
bool operator ()(const AString & a_Item1, const AString & a_Item2) const { return (NoCaseCompare(a_Item1, a_Item2) > 0); }
cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault) { AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", ""); if (HeightGenName.empty()) { LOGWARN("[Generator] HeightGen value not set in world.ini, using \"Biomal\"."); HeightGenName = "Biomal"; } a_CacheOffByDefault = false; cTerrainHeightGen * res = nullptr; if (NoCaseCompare(HeightGenName, "flat") == 0) { res = new cHeiGenFlat; a_CacheOffByDefault = true; // We're generating faster than a cache would retrieve data } else if (NoCaseCompare(HeightGenName, "classic") == 0) { res = new cHeiGenClassic(a_Seed); } else if (NoCaseCompare(HeightGenName, "DistortedHeightmap") == 0) { res = new cDistortedHeightmap(a_Seed, a_BiomeGen); } else if (NoCaseCompare(HeightGenName, "End") == 0) { res = new cEndGen(a_Seed); } else if (NoCaseCompare(HeightGenName, "MinMax") == 0) { res = new cHeiGenMinMax(a_Seed, a_BiomeGen); } else if (NoCaseCompare(HeightGenName, "Mountains") == 0) { res = new cHeiGenMountains(a_Seed); } else if (NoCaseCompare(HeightGenName, "BiomalNoise3D") == 0) { res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen); } else if (NoCaseCompare(HeightGenName, "Noise3D") == 0) { res = new cNoise3DComposable(a_Seed); } else if (NoCaseCompare(HeightGenName, "biomal") == 0) { res = new cHeiGenBiomal(a_Seed, a_BiomeGen); /* // Performance-testing: LOGINFO("Measuring performance of cHeiGenBiomal..."); clock_t BeginTick = clock(); for (int x = 0; x < 500; x++) { cChunkDef::HeightMap Heights; res->GenHeightMap(x * 5, x * 5, Heights); } clock_t Duration = clock() - BeginTick; LOGINFO("HeightGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC); //*/ } else { // No match found, force-set the default and retry LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str()); a_IniFile.DeleteValue("Generator", "HeightGen"); a_IniFile.SetValue("Generator", "HeightGen", "Biomal"); return CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); } // Read the settings: res->InitializeHeightGen(a_IniFile); return cTerrainHeightGenPtr(res); }
cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, int a_Seed) { AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); if (CompoGenName.empty()) { LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\"."); CompoGenName = "Biomal"; } // Compositor list is alpha-sorted cTerrainCompositionGenPtr res; if (NoCaseCompare(CompoGenName, "Biomal") == 0) { res = CreateCompoGenBiomal(a_Seed); } else if (NoCaseCompare(CompoGenName, "BiomalNoise3D") == 0) { // The composition that used to be provided with BiomalNoise3D is now provided by the Biomal compositor: res = CreateCompoGenBiomal(a_Seed); } else if (NoCaseCompare(CompoGenName, "Classic") == 0) { res = std::make_shared<cCompoGenClassic>(); } else if (NoCaseCompare(CompoGenName, "DebugBiomes") == 0) { res = std::make_shared<cCompoGenDebugBiomes>(); } else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0) { // The composition that used to be provided with DistortedHeightmap is now provided by the Biomal compositor: res = CreateCompoGenBiomal(a_Seed); } else if (NoCaseCompare(CompoGenName, "End") == 0) { res = std::make_shared<cEndGen>(a_Seed); } else if (NoCaseCompare(CompoGenName, "Nether") == 0) { res = std::make_shared<cCompoGenNether>(a_Seed); } else if (NoCaseCompare(CompoGenName, "Noise3D") == 0) { // The composition that used to be provided with Noise3D is now provided by the Biomal compositor: res = CreateCompoGenBiomal(a_Seed); } else if (NoCaseCompare(CompoGenName, "SameBlock") == 0) { res = std::make_shared<cCompoGenSameBlock>(); } else { LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str()); a_IniFile.SetValue("Generator", "CompositionGen", "Biomal"); return CreateCompositionGen(a_IniFile, a_BiomeGen, a_ShapeGen, a_Seed); } ASSERT(res != nullptr); // Read the settings from the ini file: res->InitializeCompoGen(a_IniFile); return cTerrainCompositionGenPtr(res); }
void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { int Seed = m_ChunkGenerator.GetSeed(); eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); auto seaLevel = a_IniFile.GetValueI("Generator", "SeaLevel"); AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", ""); // Create all requested finishers: AStringVector Str = StringSplitAndTrim(Finishers, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { auto split = StringSplitAndTrim(*itr, ":"); if (split.empty()) { continue; } const auto & finisher = split[0]; // Finishers, alpha-sorted: if (NoCaseCompare(finisher, "Animals") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPassiveMobs(Seed, a_IniFile, Dimension))); } else if (NoCaseCompare(finisher, "BottomLava") == 0) { int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenBottomLava(BottomLavaLevel))); } else if (NoCaseCompare(finisher, "DeadBushes") == 0) { // A list with all the allowed biomes. cFinishGenSingleTopBlock::BiomeList AllowedBiomes; AllowedBiomes.push_back(biDesert); AllowedBiomes.push_back(biDesertHills); AllowedBiomes.push_back(biDesertM); AllowedBiomes.push_back(biMesa); AllowedBiomes.push_back(biMesaBryce); AllowedBiomes.push_back(biMesaPlateau); AllowedBiomes.push_back(biMesaPlateauF); AllowedBiomes.push_back(biMesaPlateauFM); AllowedBiomes.push_back(biMesaPlateauM); // A list with all the allowed blocks that can be below the dead bush. cFinishGenSingleTopBlock::BlockList AllowedBlocks; AllowedBlocks.push_back(E_BLOCK_SAND); AllowedBlocks.push_back(E_BLOCK_HARDENED_CLAY); AllowedBlocks.push_back(E_BLOCK_STAINED_CLAY); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, AllowedBiomes, 2, AllowedBlocks))); } else if (NoCaseCompare(finisher, "DirectOverhangs") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cStructGenDirectOverhangs(Seed))); } else if (NoCaseCompare(finisher, "DirtPockets") == 0) { auto gen = std::make_shared<cFinishGenOrePockets>(Seed + 1, cFinishGenOrePockets::DefaultNaturalPatches()); if (gen->Initialize(a_IniFile, "DirtPockets")) { m_FinishGens.push_back(gen); } } else if (NoCaseCompare(finisher, "DistortedMembraneOverhangs") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cStructGenDistortedMembraneOverhangs(Seed))); } else if (NoCaseCompare(finisher, "DualRidgeCaves") == 0) { float Threshold = static_cast<float>(a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenDualRidgeCaves(Seed, Threshold))); } else if (NoCaseCompare(finisher, "DungeonRooms") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsGridSize", 48); int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1"); m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_ShapeGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib))); } else if (NoCaseCompare(finisher, "GlowStone") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenGlowStone(Seed))); } else if (NoCaseCompare(finisher, "Ice") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenIce)); } else if (NoCaseCompare(finisher, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_ShapeGen, Probability))); } else if (NoCaseCompare(finisher, "LavaSprings") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension))); } else if (NoCaseCompare(finisher, "Lilypads") == 0) { // A list with all the allowed biomes. cFinishGenSingleTopBlock::BiomeList AllowedBiomes; AllowedBiomes.push_back(biSwampland); AllowedBiomes.push_back(biSwamplandM); // A list with all the allowed blocks that can be below the lilypad. cFinishGenSingleTopBlock::BlockList AllowedBlocks; AllowedBlocks.push_back(E_BLOCK_WATER); AllowedBlocks.push_back(E_BLOCK_STATIONARY_WATER); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks))); } else if (NoCaseCompare(finisher, "MarbleCaves") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cStructGenMarbleCaves(Seed))); } else if (NoCaseCompare(finisher, "MineShafts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512); int MaxOffset = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxOffset", 256); int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160); int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); m_FinishGens.push_back(cFinishGenPtr(new cStructGenMineShafts( Seed, GridSize, MaxOffset, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase ))); } else if (NoCaseCompare(finisher, "NaturalPatches") == 0) { m_FinishGens.push_back(std::make_shared<cFinishGenOreNests>(Seed + 1, cFinishGenOreNests::DefaultNaturalPatches())); } else if (NoCaseCompare(finisher, "NetherClumpFoliage") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenNetherClumpFoliage(Seed))); } else if (NoCaseCompare(*itr, "NetherForts") == 0) { LOGINFO("The NetherForts finisher is obsolete, you should use \"PieceStructures: NetherFort\" instead."); auto gen = std::make_shared<cPieceStructuresGen>(Seed); if (gen->Initialize("NetherFort", seaLevel, m_BiomeGen, m_CompositedHeightCache)) { m_FinishGens.push_back(gen); } } else if (NoCaseCompare(finisher, "NetherOreNests") == 0) { m_FinishGens.push_back(std::make_shared<cFinishGenOreNests>(Seed + 2, cFinishGenOreNests::DefaultNetherOres())); } else if (NoCaseCompare(finisher, "OreNests") == 0) { m_FinishGens.push_back(std::make_shared<cFinishGenOreNests>(Seed + 3, cFinishGenOreNests::DefaultOverworldOres())); } else if (NoCaseCompare(finisher, "OrePockets") == 0) { auto gen = std::make_shared<cFinishGenOrePockets>(Seed + 2, cFinishGenOrePockets::DefaultOverworldOres()); if (gen->Initialize(a_IniFile, "OrePockets")) { m_FinishGens.push_back(gen); } } else if (NoCaseCompare(finisher, "PieceStructures") == 0) { if (split.size() < 2) { LOGWARNING("The PieceStructures generator needs the structures to use. Example: \"PieceStructures: NetherFort\"."); continue; } auto gen = std::make_shared<cPieceStructuresGen>(Seed); if (gen->Initialize(split[1], seaLevel, m_BiomeGen, m_CompositedHeightCache)) { m_FinishGens.push_back(gen); } } else if (NoCaseCompare(finisher, "PreSimulator") == 0) { // Load the settings bool PreSimulateFallingBlocks = a_IniFile.GetValueSetB("Generator", "PreSimulatorFallingBlocks", true); bool PreSimulateWater = a_IniFile.GetValueSetB("Generator", "PreSimulatorWater", true); bool PreSimulateLava = a_IniFile.GetValueSetB("Generator", "PreSimulatorLava", true); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava))); } else if (NoCaseCompare(finisher, "RainbowRoads") == 0) { LOGINFO("The RainbowRoads finisher is obsolete, you should use \"PieceStructures: RainbowRoads\" instead."); auto gen = std::make_shared<cPieceStructuresGen>(Seed); if (gen->Initialize("RainbowRoads", seaLevel, m_BiomeGen, m_CompositedHeightCache)) { m_FinishGens.push_back(gen); } } else if (NoCaseCompare(finisher, "Ravines") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cStructGenRavines(Seed, 128))); } else if (NoCaseCompare(finisher, "RoughRavines") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "RoughRavinesGridSize", 256); int MaxOffset = a_IniFile.GetValueSetI("Generator", "RoughRavinesMaxOffset", 128); int MaxSize = a_IniFile.GetValueSetI("Generator", "RoughRavinesMaxSize", 128); int MinSize = a_IniFile.GetValueSetI("Generator", "RoughRavinesMinSize", 64); double MaxCenterWidth = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCenterWidth", 8); double MinCenterWidth = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCenterWidth", 2); double MaxRoughness = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxRoughness", 0.2); double MinRoughness = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinRoughness", 0.05); double MaxFloorHeightEdge = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxFloorHeightEdge", 8); double MinFloorHeightEdge = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinFloorHeightEdge", 30); double MaxFloorHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxFloorHeightCenter", 20); double MinFloorHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinFloorHeightCenter", 6); double MaxCeilingHeightEdge = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCeilingHeightEdge", 56); double MinCeilingHeightEdge = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightEdge", 38); double MaxCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCeilingHeightCenter", 58); double MinCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightCenter", 36); m_FinishGens.push_back(cFinishGenPtr(new cRoughRavines( Seed, MaxSize, MinSize, static_cast<float>(MaxCenterWidth), static_cast<float>(MinCenterWidth), static_cast<float>(MaxRoughness), static_cast<float>(MinRoughness), static_cast<float>(MaxFloorHeightEdge), static_cast<float>(MinFloorHeightEdge), static_cast<float>(MaxFloorHeightCenter), static_cast<float>(MinFloorHeightCenter), static_cast<float>(MaxCeilingHeightEdge), static_cast<float>(MinCeilingHeightEdge), static_cast<float>(MaxCeilingHeightCenter), static_cast<float>(MinCeilingHeightCenter), GridSize, MaxOffset ))); } else if (NoCaseCompare(finisher, "SoulsandRims") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSoulsandRims(Seed))); } else if (NoCaseCompare(finisher, "Snow") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSnow)); } else if (NoCaseCompare(finisher, "SprinkleFoliage") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSprinkleFoliage(Seed))); } else if (NoCaseCompare(finisher, "TallGrass") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenTallGrass(Seed))); } else if (NoCaseCompare(finisher, "Trees") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_ShapeGen, m_CompositionGen))); } else if (NoCaseCompare(finisher, "UnderwaterBases") == 0) { LOGINFO("The UnderwaterBases finisher is obsolete, you should use \"PieceStructures: UnderwaterBases\" instead."); auto gen = std::make_shared<cPieceStructuresGen>(Seed); if (gen->Initialize("UnderwaterBases", seaLevel, m_BiomeGen, m_CompositedHeightCache)) { m_FinishGens.push_back(gen); } } else if (NoCaseCompare(finisher, "Villages") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384); int MaxOffset = a_IniFile.GetValueSetI("Generator", "VillageMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 2); int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50); int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80); AString PrefabList = a_IniFile.GetValueSet("Generator", "VillagePrefabs", "PlainsVillage, SandVillage"); auto Prefabs = StringSplitAndTrim(PrefabList, ","); m_FinishGens.push_back(std::make_shared<cVillageGen>(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_CompositedHeightCache, seaLevel, Prefabs)); } else if (NoCaseCompare(finisher, "Vines") == 0) { int Level = a_IniFile.GetValueSetI("Generator", "VinesLevel", 40); m_FinishGens.push_back(std::make_shared<cFinishGenVines>(Seed, Level)); } else if (NoCaseCompare(finisher, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_ShapeGen, Probability))); } else if (NoCaseCompare(finisher, "WaterSprings") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension))); } else if (NoCaseCompare(finisher, "WormNestCaves") == 0) { int Size = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64); int Grid = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96); int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32); m_FinishGens.push_back(cFinishGenPtr(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset))); } else { LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", finisher.c_str()); } } // for itr - Str[] }
cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed) { AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); if (CompoGenName.empty()) { LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\"."); CompoGenName = "Biomal"; a_IniFile.SetValue("Generator", "CompositionGen", CompoGenName); } cTerrainCompositionGen * res = NULL; if (NoCaseCompare(CompoGenName, "sameblock") == 0) { res = new cCompoGenSameBlock; } else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) { res = new cCompoGenDebugBiomes; } else if (NoCaseCompare(CompoGenName, "classic") == 0) { res = new cCompoGenClassic; } else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0) { res = new cDistortedHeightmap(a_Seed, a_BiomeGen); } else if (NoCaseCompare(CompoGenName, "end") == 0) { res = new cEndGen(a_Seed); } else if (NoCaseCompare(CompoGenName, "nether") == 0) { res = new cCompoGenNether(a_Seed); } else if (NoCaseCompare(CompoGenName, "Noise3D") == 0) { res = new cNoise3DComposable(a_Seed); } else if (NoCaseCompare(CompoGenName, "biomal") == 0) { res = new cCompoGenBiomal(a_Seed); /* // Performance-testing: LOGINFO("Measuring performance of cCompoGenBiomal..."); clock_t BeginTick = clock(); for (int x = 0; x < 500; x++) { cChunkDesc Desc(200 + x * 8, 200 + x * 8); a_BiomeGen->GenBiomes(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetBiomeMap()); a_HeightGen->GenHeightMap(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetHeightMap()); res->ComposeTerrain(Desc); } clock_t Duration = clock() - BeginTick; LOGINFO("CompositionGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC); //*/ } else { LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str()); a_IniFile.DeleteValue("Generator", "CompositionGen"); a_IniFile.SetValue("Generator", "CompositionGen", "Biomal"); return CreateCompositionGen(a_IniFile, a_BiomeGen, a_HeightGen, a_Seed); } ASSERT(res != NULL); // Read the settings from the ini file: res->InitializeCompoGen(a_IniFile); return res; }