void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { ASSERT(a_CharMapDef != NULL); // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { a_CharMapOut[i].m_BlockType = 0; a_CharMapOut[i].m_BlockMeta = 16; // Mark unassigned entries with a meta that is impossible otherwise } // Process the lines in the definition: AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { AStringVector CharDef = StringSplitAndTrim(*itr, ":"); size_t NumElements = CharDef.size(); if ((NumElements < 2) || CharDef[0].empty() || CharDef[1].empty()) { LOGWARNING("Bad prefab CharMap definition line: \"%s\", skipping.", itr->c_str()); continue; } unsigned char Src = (unsigned char)CharDef[0][0]; ASSERT(a_CharMapOut[Src].m_BlockMeta == 16); // This letter has not been assigned yet? a_CharMapOut[Src].m_BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); NIBBLETYPE BlockMeta = 0; if ((NumElements >= 3) && !CharDef[2].empty()) { BlockMeta = (NIBBLETYPE)atoi(CharDef[2].c_str()); ASSERT((BlockMeta <= 15)); } a_CharMapOut[Src].m_BlockMeta = BlockMeta; } // for itr - Lines[] }
bool cProbabDistrib::SetDefString(const AString & a_DefString) { AStringVector Points = StringSplitAndTrim(a_DefString, ";"); if (Points.empty()) { return false; } cPoints Pts; for (AStringVector::const_iterator itr = Points.begin(), end = Points.end(); itr != end; ++itr) { AStringVector Split = StringSplitAndTrim(*itr, ","); if (Split.size() != 2) { // Bad format return false; } int Value = atoi(Split[0].c_str()); int Prob = atoi(Split[1].c_str()); if ( ((Value == 0) && (Split[0] != "0")) || ((Prob == 0) && (Split[1] != "0")) ) { // Number parse error return false; } Pts.push_back(cPoint(Value, Prob)); } // for itr - Points[] SetPoints(Pts); return true; }
void cPlayer::LoadPermissionsFromDisk() { m_Groups.clear(); m_Permissions.clear(); cIniFile IniFile; if (IniFile.ReadFile("users.ini")) { AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default"); AStringVector Split = StringSplitAndTrim(Groups, ","); for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr) { if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr)) { LOGWARNING("The group %s for player %s was not found!", itr->c_str(), GetName().c_str()); } AddToGroup(*itr); } AString Color = IniFile.GetValue(GetName(), "Color", "-"); if (!Color.empty()) { m_Color = Color[0]; } } else { cGroupManager::GenerateDefaultUsersIni(IniFile); IniFile.AddValue("Groups", GetName(), "Default"); AddToGroup("Default"); } IniFile.WriteFile("users.ini"); ResolvePermissions(); }
bool cGroupManager::CheckUsers() { cIniFile IniFile; if (!IniFile.ReadFile("users.ini")) { GenerateDefaultUsersIni(IniFile); return true; } int NumKeys = IniFile.GetNumKeys(); for (int i = 0; i < NumKeys; i++) { AString Player = IniFile.GetKeyName(i); AString Groups = IniFile.GetValue(Player, "Groups", ""); if (Groups.empty()) { continue; } AStringVector Split = StringSplitAndTrim(Groups, ","); for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr) { if (!ExistsGroup(*itr)) { LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), Player.c_str()); } } // for itr - Split[] } // for i - ini file keys // Always return true for now, just but we can handle writefile fails later. return true; }
/** Parses a string containing a range in which both values are optional ("<MinHeight>|<MaxHeight>") into Min, Range. Returns true if successful, false on failure. If a_LogWarnings is true, outputs failure reasons to console. The range is returned in a_Min and a_Range, they are left unchanged if the range value is not present in the string. */ static bool ParseRange(const AString & a_Params, int & a_Min, int & a_Range, bool a_LogWarnings) { auto params = StringSplitAndTrim(a_Params, "|"); if (params.size() == 0) { // No params, generate directly on top: return true; } if (!StringToInteger(params[0], a_Min)) { // Failed to parse the min rel height: CONDWARNING(a_LogWarnings, "Cannot parse minimum height from string \"%s\"!", params[0].c_str()); return false; } if (params.size() == 1) { // Only one param was given, there's no range return true; } int maxHeight = a_Min; if (!StringToInteger(params[1], maxHeight)) { CONDWARNING(a_LogWarnings, "Cannot parse maximum height from string \"%s\"!", params[1].c_str()); return false; } if (maxHeight < a_Min) { std::swap(maxHeight, a_Min); } a_Range = maxHeight - a_Min + 1; return true; }
void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) { // The member needn't be defined at all, if so, skip: if (a_DepthWeightDef == NULL) { return; } // Split into individual records: "Record | Record | Record" AStringVector Defs = StringSplitAndTrim(a_DepthWeightDef, "|"); // Add each record's contents: for (AStringVector::const_iterator itr = Defs.begin(), end = Defs.end(); itr != end; ++itr) { // Split into components: "Depth : Weight" AStringVector Components = StringSplitAndTrim(*itr, ":"); if (Components.size() != 2) { LOGWARNING("Bad prefab DepthWeight record: \"%s\", skipping.", itr->c_str()); continue; } // Parse depth: int Depth = atoi(Components[0].c_str()); if ((Depth == 0) && (Components[0] != "0")) { LOGWARNING("Bad prefab DepthWeight record, cannot parse depth \"%s\", skipping.", Components[0].c_str()); continue; } // Parse weight: int Weight = atoi(Components[1].c_str()); if ((Weight == 0) && (Components[1] != "0")) { LOGWARNING("Bad prefab DepthWeight record, cannot parse weight \"%s\", skipping.", Components[1].c_str()); continue; } // Save to map: ASSERT(m_DepthWeight.find(Depth) == m_DepthWeight.end()); // Not a duplicate m_DepthWeight[Depth] = Weight; } // for itr - Defs[] }
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[] }
void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { ASSERT(a_ConnectorsDef != nullptr); AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { if (itr->empty()) { continue; } // Split into components: "Type: X, Y, Z: Direction": AStringVector Defs = StringSplitAndTrim(*itr, ":"); if (Defs.size() != 3) { LOGWARNING("Bad prefab Connector definition line: \"%s\", skipping.", itr->c_str()); continue; } AStringVector Coords = StringSplitAndTrim(Defs[1], ","); if (Coords.size() != 3) { LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); continue; } // Check that the Direction is valid: cPiece::cConnector::eDirection Direction; if (!cPiece::cConnector::StringToDirection(Defs[2], Direction)) { LOGWARNING("Bad prefab Connector direction: \"%s\", skipping.", Defs[2].c_str()); continue; } // Add the connector: m_Connectors.push_back(cPiece::cConnector( atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos atoi(Defs[0].c_str()), // Connector type Direction )); } // for itr - Lines[] }
void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { ASSERT(a_ConnectorsDef != NULL); AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { if (itr->empty()) { continue; } // Split into components: "Type: X, Y, Z: Face": AStringVector Defs = StringSplitAndTrim(*itr, ":"); if (Defs.size() != 3) { LOGWARNING("Bad prefab Connector definition line: \"%s\", skipping.", itr->c_str()); continue; } AStringVector Coords = StringSplitAndTrim(Defs[1], ","); if (Coords.size() != 3) { LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); continue; } // Check that the BlockFace is within range: int BlockFace = atoi(Defs[2].c_str()); if ((BlockFace < 0) || (BlockFace >= 6)) { LOGWARNING("Bad prefab Connector Blockface: \"%s\", skipping.", Defs[2].c_str()); continue; } // Add the connector: m_Connectors.push_back(cPiece::cConnector( atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos atoi(Defs[0].c_str()), // Connector type (eBlockFace)BlockFace )); } // for itr - Lines[] }
void cPrefabPiecePool::ApplyBaseMetadataCubesetVer1( const AString & a_FileName, bool a_LogWarnings ) { // Set the metadata values to defaults: m_MinDensity = 100; m_MaxDensity = 100; m_VillageRoadBlockType = E_BLOCK_GRAVEL; m_VillageRoadBlockMeta = 0; m_VillageWaterRoadBlockType = E_BLOCK_PLANKS; m_VillageWaterRoadBlockMeta = 0; // Read the metadata values: m_IntendedUse = GetMetadata("IntendedUse"); GetStringMapInteger(m_Metadata, "MaxDensity", m_MaxDensity); GetStringMapInteger(m_Metadata, "MinDensity", m_MinDensity); GetStringMapInteger(m_Metadata, "VillageRoadBlockType", m_VillageRoadBlockType); GetStringMapInteger(m_Metadata, "VillageRoadBlockMeta", m_VillageRoadBlockMeta); GetStringMapInteger(m_Metadata, "VillageWaterRoadBlockType", m_VillageWaterRoadBlockType); GetStringMapInteger(m_Metadata, "VillageWaterRoadBlockMeta", m_VillageWaterRoadBlockMeta); // Read the allowed biomes: AString allowedBiomes = GetMetadata("AllowedBiomes"); if (allowedBiomes.empty()) { // All biomes are allowed: for (int b = biFirstBiome; b <= biMaxBiome; b++) { m_AllowedBiomes.insert(static_cast<EMCSBiome>(b)); } for (int b = biFirstVariantBiome; b <= biMaxVariantBiome; b++) { m_AllowedBiomes.insert(static_cast<EMCSBiome>(b)); } } else { auto biomes = StringSplitAndTrim(allowedBiomes, ","); for (const auto & biome: biomes) { EMCSBiome b = StringToBiome(biome); if (b == biInvalidBiome) { CONDWARNING(a_LogWarnings, "Invalid biome (\"%s\") specified in AllowedBiomes in cubeset file %s. Skipping the biome.", biome.c_str(), a_FileName.c_str() ); continue; } m_AllowedBiomes.insert(b); } } }
bool ResolveItem(const AString & a_ItemName, cItem & a_Item) { // Split into parts divided by either ':' or '^' AStringVector Split = StringSplitAndTrim(a_ItemName, ":^"); if (Split.empty()) { return false; } ItemMap::iterator itr = m_Map.find(Split[0]); if (itr != m_Map.end()) { // Resolved as a string, assign the type and the default damage / count a_Item.m_ItemType = itr->second.first; a_Item.m_ItemDamage = itr->second.second; if (a_Item.m_ItemDamage == -1) { a_Item.m_ItemDamage = 0; } } else { // Not a resolvable string, try pure numbers: "45:6", "45^6" etc. a_Item.m_ItemType = (short)atoi(Split[0].c_str()); if ((a_Item.m_ItemType == 0) && (Split[0] != "0")) { // Parsing the number failed return false; } } // Parse the damage, if present: if (Split.size() < 2) { // Not present, set the item as valid and return success: a_Item.m_ItemCount = 1; return true; } a_Item.m_ItemDamage = (short)atoi(Split[1].c_str()); if ((a_Item.m_ItemDamage == 0) && (Split[1] != "0")) { // Parsing the number failed return false; } a_Item.m_ItemCount = 1; return true; }
void cEnchantments::AddFromString(const AString & a_StringSpec) { // Add enchantments in the stringspec; if a specified enchantment already exists, overwrites it // Split the StringSpec into separate declarations, each in the form "id=lvl": AStringVector Decls = StringSplit(a_StringSpec, ";"); for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr) { // Split each declaration into the id and lvl part: if (itr->empty()) { // The decl is empty (may happen if there's an extra semicolon at the end), ignore silently continue; } AStringVector Split = StringSplitAndTrim(*itr, "="); if (Split.size() != 2) { // Malformed decl LOG("%s: Malformed enchantment decl: \"%s\", skipping.", __FUNCTION__, itr->c_str()); continue; } int id = atoi(Split[0].c_str()); if ((id == 0) && (Split[0] != "0")) { id = StringToEnchantmentID(Split[0]); } int lvl = atoi(Split[1].c_str()); if ( ((id <= 0) && (Split[0] != "0")) || ((lvl == 0) && (Split[1] != "0")) ) { // Numbers failed to parse LOG("%s: Failed to parse enchantment declaration for numbers: \"%s\" and \"%s\", skipping.", __FUNCTION__, Split[0].c_str(), Split[1].c_str() ); continue; } SetLevel(id, lvl); } // for itr - Decls[] }
virtual bool InitializeFromString(const AString & a_Params, bool a_LogWarnings) override { // Params: "<MinHeight>|<MaxHeight>", all compulsory auto params = StringSplitAndTrim(a_Params, "|"); if (params.size() != 2) { CONDWARNING(a_LogWarnings, "Cannot parse the range parameters from string \"%s\"!", a_Params.c_str()); return false; } int Max = 0; if (!StringToInteger(params[0], m_Min) || !StringToInteger(params[1], Max)) { CONDWARNING(a_LogWarnings, "Cannot parse the minimum or maximum height from string \"%s\"!", a_Params.c_str()); return false; } if (m_Min > Max) { std::swap(m_Min, Max); } m_Range = Max - m_Min + 1; return true; }
bool cPrefabPiecePool::ApplyPoolMetadataCubesetVer1( const AString & a_FileName, cLuaState & a_LuaState, bool a_LogWarnings ) { // Push the Cubeset.Metadata table on top of the Lua stack: lua_getglobal(a_LuaState, "_G"); auto md = a_LuaState.WalkToValue("Cubeset.Metadata"); if (!md.IsValid()) { CONDWARNING(a_LogWarnings, "Cannot load cubeset from file %s: Cubeset.Metadata table is missing", a_FileName.c_str()); return false; } // Set the metadata values to defaults: m_MinDensity = 100; m_MaxDensity = 100; m_VillageRoadBlockType = E_BLOCK_GRAVEL; m_VillageRoadBlockMeta = 0; m_VillageWaterRoadBlockType = E_BLOCK_PLANKS; m_VillageWaterRoadBlockMeta = 0; // Read the metadata values: a_LuaState.GetNamedValue("IntendedUse", m_IntendedUse); a_LuaState.GetNamedValue("MaxDensity", m_MaxDensity); a_LuaState.GetNamedValue("MinDensity", m_MinDensity); a_LuaState.GetNamedValue("VillageRoadBlockType", m_VillageRoadBlockType); a_LuaState.GetNamedValue("VillageRoadBlockMeta", m_VillageRoadBlockMeta); a_LuaState.GetNamedValue("VillageWaterRoadBlockType", m_VillageWaterRoadBlockType); a_LuaState.GetNamedValue("VillageWaterRoadBlockMeta", m_VillageWaterRoadBlockMeta); AString allowedBiomes; if (a_LuaState.GetNamedValue("AllowedBiomes", allowedBiomes)) { auto biomes = StringSplitAndTrim(allowedBiomes, ","); for (const auto & biome: biomes) { EMCSBiome b = StringToBiome(biome); if (b == biInvalidBiome) { CONDWARNING(a_LogWarnings, "Invalid biome (\"%s\") specified in AllowedBiomes in cubeset file %s. Skipping the biome.", biome.c_str(), a_FileName.c_str() ); continue; } m_AllowedBiomes.insert(b); } } else { // All biomes are allowed: for (int b = biFirstBiome; b <= biMaxBiome; b++) { m_AllowedBiomes.insert(static_cast<EMCSBiome>(b)); } for (int b = biFirstVariantBiome; b <= biMaxVariantBiome; b++) { m_AllowedBiomes.insert(static_cast<EMCSBiome>(b)); } } return true; }
bool cListenThread::CreateSockets(const AString & a_PortsString) { AStringVector Ports = StringSplitAndTrim(a_PortsString, ","); if (Ports.empty()) { return false; } AString FamilyStr = m_ServiceName; switch (m_Family) { case cSocket::IPv4: FamilyStr.append(" IPv4"); break; case cSocket::IPv6: FamilyStr.append(" IPv6"); break; default: { ASSERT(!"Unknown address family"); break; } } for (AStringVector::const_iterator itr = Ports.begin(), end = Ports.end(); itr != end; ++itr) { int Port = atoi(itr->c_str()); if ((Port <= 0) || (Port > 65535)) { LOGWARNING("%s: Invalid port specified: \"%s\".", FamilyStr.c_str(), itr->c_str()); continue; } m_Sockets.push_back(cSocket::CreateSocket(m_Family)); if (!m_Sockets.back().IsValid()) { LOGWARNING("%s: Cannot create listening socket for port %d: \"%s\"", FamilyStr.c_str(), Port, cSocket::GetLastErrorString().c_str()); m_Sockets.pop_back(); continue; } if (m_ShouldReuseAddr) { if (!m_Sockets.back().SetReuseAddress()) { LOG("%s: Port %d cannot reuse addr, syscall failed: \"%s\".", FamilyStr.c_str(), Port, cSocket::GetLastErrorString().c_str()); } } // Bind to port: bool res = false; switch (m_Family) { case cSocket::IPv4: res = m_Sockets.back().BindToAnyIPv4(Port); break; case cSocket::IPv6: res = m_Sockets.back().BindToAnyIPv6(Port); break; default: { ASSERT(!"Unknown address family"); res = false; } } if (!res) { LOGWARNING("%s: Cannot bind port %d: \"%s\".", FamilyStr.c_str(), Port, cSocket::GetLastErrorString().c_str()); m_Sockets.pop_back(); continue; } if (!m_Sockets.back().Listen()) { LOGWARNING("%s: Cannot listen on port %d: \"%s\".", FamilyStr.c_str(), Port, cSocket::GetLastErrorString().c_str()); m_Sockets.pop_back(); continue; } LOGINFO("%s: Port %d is open for connections", FamilyStr.c_str(), Port); } // for itr - Ports[] return !(m_Sockets.empty()); }
bool cGroupManager::LoadGroups() { cIniFile IniFile; if (!IniFile.ReadFile("groups.ini")) { LOGWARNING("Regenerating groups.ini, all groups will be reset"); IniFile.AddHeaderComment(" This is the MCServer permissions manager groups file"); IniFile.AddHeaderComment(" It stores all defined groups such as Administrators, Players, or Moderators"); IniFile.SetValue("Owner", "Permissions", "*", true); IniFile.SetValue("Owner", "Color", "2", true); IniFile.SetValue("Moderator", "Permissions", "core.time,core.item,core.tpa,core.tpaccept,core.ban,core.unban,core.save-all,core.toggledownfall"); IniFile.SetValue("Moderator", "Color", "2", true); IniFile.SetValue("Moderator", "Inherits", "Player", true); IniFile.SetValue("Player", "Permissions", "core.portal", true); IniFile.SetValue("Player", "Color", "f", true); IniFile.SetValue("Player", "Inherits", "Default", true); IniFile.SetValue("Default", "Permissions", "core.help,core.plugins,core.spawn,core.worlds,core.back,core.motd,core.build,core.locate,core.viewdistance", true); IniFile.SetValue("Default", "Color", "f", true); IniFile.WriteFile("groups.ini"); } int NumKeys = IniFile.GetNumKeys(); for (int i = 0; i < NumKeys; i++) { AString KeyName = IniFile.GetKeyName(i); cGroup * Group = GetGroup(KeyName.c_str()); Group->ClearPermission(); // Needed in case the groups are reloaded. LOGD("Loading group %s", KeyName.c_str()); Group->SetName(KeyName); AString Color = IniFile.GetValue(KeyName, "Color", "-"); if ((Color != "-") && (Color.length() >= 1)) { Group->SetColor(cChatColor::Color + Color[0]); } else { Group->SetColor(cChatColor::White); } AString Commands = IniFile.GetValue(KeyName, "Commands", ""); if (!Commands.empty()) { AStringVector Split = StringSplitAndTrim(Commands, ","); for (size_t i = 0; i < Split.size(); i++) { Group->AddCommand(Split[i]); } } AString Permissions = IniFile.GetValue(KeyName, "Permissions", ""); if (!Permissions.empty()) { AStringVector Split = StringSplitAndTrim(Permissions, ","); for (size_t i = 0; i < Split.size(); i++) { Group->AddPermission(Split[i]); } } AString Groups = IniFile.GetValue(KeyName, "Inherits", ""); if (!Groups.empty()) { AStringVector Split = StringSplitAndTrim(Groups, ","); for (size_t i = 0; i < Split.size(); i++) { Group->InheritFrom(GetGroup(Split[i].c_str())); } } } // Always return true, we can handle writefile fails later. return true; }
void cBiomeGenList::InitializeBiomes(const AString & a_Biomes) { AStringVector Split = StringSplitAndTrim(a_Biomes, ","); // Convert each string in the list into biome: for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr) { AStringVector Split2 = StringSplit(*itr, ":"); if (Split2.size() < 1) { continue; } int Count = 1; if (Split2.size() >= 2) { Count = atol(Split2[1].c_str()); if (Count <= 0) { LOGWARNING("Cannot decode biome count: \"%s\"; using 1.", Split2[1].c_str()); Count = 1; } } EMCSBiome Biome = StringToBiome(Split2[0]); if (Biome != biInvalidBiome) { for (int i = 0; i < Count; i++) { m_Biomes.push_back(Biome); } } else { LOGWARNING("Cannot decode biome name: \"%s\"; skipping", Split2[0].c_str()); } } // for itr - Split[] if (!m_Biomes.empty()) { m_BiomesCount = (int)m_Biomes.size(); return; } // There were no biomes, add default biomes: static EMCSBiome Biomes[] = { biOcean, biPlains, biDesert, biExtremeHills, biForest, biTaiga, biSwampland, biRiver, biFrozenOcean, biFrozenRiver, biIcePlains, biIceMountains, biMushroomIsland, biMushroomShore, biBeach, biDesertHills, biForestHills, biTaigaHills, biExtremeHillsEdge, biJungle, biJungleHills, } ; m_Biomes.reserve(ARRAYCOUNT(Biomes)); for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) { m_Biomes.push_back(Biomes[i]); } m_BiomesCount = (int)m_Biomes.size(); }
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[] }
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[] }
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[] }
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", ""); // 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) { // 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(new cFinishGenSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, AllowedBiomes, 2, AllowedBlocks)); } 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, "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(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib)); } 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 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(new cStructGenMineShafts( Seed, GridSize, MaxOffset, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } else if (NoCaseCompare(*itr, "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(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks)); } else if (NoCaseCompare(*itr, "NaturalPatches") == 0) { cStructGenOreNests::OreList Ores; // Dirt vein cStructGenOreNests::OreInfo DirtVein; DirtVein.BlockType = E_BLOCK_DIRT; DirtVein.MaxHeight = 127; DirtVein.NumNests = 20; DirtVein.NestSize = 32; Ores.push_back(DirtVein); // Gravel vein cStructGenOreNests::OreInfo GravelVein; GravelVein.BlockType = E_BLOCK_DIRT; GravelVein.MaxHeight = 127; GravelVein.NumNests = 20; GravelVein.NestSize = 32; Ores.push_back(GravelVein); m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); } 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 MaxOffset = a_IniFile.GetValueSetI("Generator", "NetherFortMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth)); } else if (NoCaseCompare(*itr, "NetherOreNests") == 0) { cStructGenOreNests::OreList Ores; // Quartz vein cStructGenOreNests::OreInfo QuartzVein; QuartzVein.BlockType = E_BLOCK_NETHER_QUARTZ_ORE; QuartzVein.MaxHeight = 255; QuartzVein.NumNests = 80; QuartzVein.NestSize = 8; Ores.push_back(QuartzVein); m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK)); } else if (NoCaseCompare(*itr, "OreNests") == 0) { cStructGenOreNests::OreList Ores; // Coal vein cStructGenOreNests::OreInfo CoalVein; CoalVein.BlockType = E_BLOCK_COAL_ORE; CoalVein.MaxHeight = 127; CoalVein.NumNests = 50; CoalVein.NestSize = 10; Ores.push_back(CoalVein); // Iron vein cStructGenOreNests::OreInfo IronVein; IronVein.BlockType = E_BLOCK_IRON_ORE; IronVein.MaxHeight = 64; IronVein.NumNests = 14; IronVein.NestSize = 6; Ores.push_back(IronVein); // Gold vein cStructGenOreNests::OreInfo GoldVein; GoldVein.BlockType = E_BLOCK_GOLD_ORE; GoldVein.MaxHeight = 32; GoldVein.NumNests = 2; GoldVein.NestSize = 6; Ores.push_back(GoldVein); // Redstone vein cStructGenOreNests::OreInfo RedstoneVein; RedstoneVein.BlockType = E_BLOCK_REDSTONE_ORE; RedstoneVein.MaxHeight = 16; RedstoneVein.NumNests = 4; RedstoneVein.NestSize = 6; Ores.push_back(RedstoneVein); // Lapis vein cStructGenOreNests::OreInfo LapisVein; LapisVein.BlockType = E_BLOCK_LAPIS_ORE; LapisVein.MaxHeight = 30; LapisVein.NumNests = 2; LapisVein.NestSize = 5; Ores.push_back(LapisVein); // Diamond vein cStructGenOreNests::OreInfo DiamondVein; DiamondVein.BlockType = E_BLOCK_DIAMOND_ORE; DiamondVein.MaxHeight = 15; DiamondVein.NumNests = 1; DiamondVein.NestSize = 4; Ores.push_back(DiamondVein); m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); } else if (NoCaseCompare(*itr, "POCPieces") == 0) { m_FinishGens.push_back(new cPOCPieceGenerator(Seed)); } else if (NoCaseCompare(*itr, "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(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava)); } else if (NoCaseCompare(*itr, "RainbowRoads") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512); int MaxOffset = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30); int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260); m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize)); } else if (NoCaseCompare(*itr, "Ravines") == 0) { m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); } else if (NoCaseCompare(*itr, "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(new cRoughRavines( Seed, MaxSize, MinSize, (float)MaxCenterWidth, (float)MinCenterWidth, (float)MaxRoughness, (float)MinRoughness, (float)MaxFloorHeightEdge, (float)MinFloorHeightEdge, (float)MaxFloorHeightCenter, (float)MinFloorHeightCenter, (float)MaxCeilingHeightEdge, (float)MinCeilingHeightEdge, (float)MaxCeilingHeightCenter, (float)MinCeilingHeightCenter, GridSize, MaxOffset )); } 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, "TallGrass") == 0) { m_FinishGens.push_back(new cFinishGenTallGrass(Seed)); } else if (NoCaseCompare(*itr, "TestRails") == 0) { m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50)); } 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 MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, *m_BiomeGen)); } else if (NoCaseCompare(*itr, "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); m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxOffset, 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) { 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(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset)); } else { LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", itr->c_str()); } } // for itr - Str[] }