Exemple #1
0
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[]
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #6
0
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[]
}
Exemple #8
0
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[]
}
Exemple #9
0
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);
		}
	}
}
Exemple #11
0
	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;
	}
Exemple #12
0
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;
}
Exemple #15
0
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;
}
Exemple #17
0
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[]
}
Exemple #20
0
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[]
}