예제 #1
0
void cMojangAPI::Start(cIniFile & a_SettingsIni)
{
	m_NameToUUIDServer     = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer",     DEFAULT_NAME_TO_UUID_SERVER);
	m_NameToUUIDAddress    = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress",    DEFAULT_NAME_TO_UUID_ADDRESS);
	m_UUIDToProfileServer  = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileServer",  DEFAULT_UUID_TO_PROFILE_SERVER);
	m_UUIDToProfileAddress = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS);
	LoadCachesFromDisk();
}
예제 #2
0
bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile)
{
	MTRand rnd;
	m_World = a_World;
	m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt());
	AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable");

	if (NoCaseCompare(GeneratorName, "Noise3D") == 0)
	{
		m_Generator = new cNoise3DGenerator(*this);
	}
	else
	{
		if (NoCaseCompare(GeneratorName, "composable") != 0)
		{
			LOGWARN("[Generator]::Generator value \"%s\" not recognized, using \"Composable\".", GeneratorName.c_str());
		}
		m_Generator = new cComposableGenerator(*this);
	}

	if (m_Generator == NULL)
	{
		LOGERROR("Generator could not start, aborting the server");
		return false;
	}

	m_Generator->Initialize(a_World, a_IniFile);

	return super::Start();
}
예제 #3
0
void cBioGenDistortedVoronoi::InitializeBiomeGen(cIniFile & a_IniFile)
{
	super::InitializeBiomeGen(a_IniFile);
	m_CellSize = a_IniFile.GetValueSetI("Generator", "DistortedVoronoiCellSize", 96);
	m_Voronoi.SetCellSize(m_CellSize);
	InitializeBiomes(a_IniFile.GetValueSet("Generator", "DistortedVoronoiBiomes", ""));
}
예제 #4
0
void cBioGenCheckerboard::InitializeBiomeGen(cIniFile & a_IniFile)
{
	super::InitializeBiomeGen(a_IniFile);
	AString Biomes = a_IniFile.GetValueSet ("Generator", "CheckerBoardBiomes",    "");
	m_BiomeSize    = a_IniFile.GetValueSetI("Generator", "CheckerboardBiomeSize", 64);
	m_BiomeSize = (m_BiomeSize < 8) ? 8 : m_BiomeSize;
	InitializeBiomes(Biomes);
}
예제 #5
0
파일: BlockID.cpp 프로젝트: 36451/MCServer
cItem GetIniItemSet(cIniFile & a_IniFile, const char * a_Section, const char * a_Key, const char * a_Default)
{
	AString ItemStr = a_IniFile.GetValueSet(a_Section, a_Key, a_Default);
	cItem res;
	if (!StringToItem(ItemStr, res))
	{
		res.Empty();
	}
	return res;
}
예제 #6
0
void cBioGenConstant::InitializeBiomeGen(cIniFile & a_IniFile)
{
	AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "Plains");
	m_Biome = StringToBiome(Biome);
	if (m_Biome == biInvalidBiome)
	{
		LOGWARN("[Generator]::ConstantBiome value \"%s\" not recognized, using \"Plains\".", Biome.c_str());
		m_Biome = biPlains;
	}
}
예제 #7
0
void cBioGenVoronoi::InitializeBiomeGen(cIniFile & a_IniFile)
{
	super::InitializeBiomeGen(a_IniFile);
	int CellSize     = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 128);
	int JitterSize   = a_IniFile.GetValueSetI("Generator", "VoronoiJitterSize", CellSize);
	int OddRowOffset = a_IniFile.GetValueSetI("Generator", "VoronoiOddRowOffset", 0);
	m_Voronoi.SetCellSize(CellSize);
	m_Voronoi.SetJitterSize(JitterSize);
	m_Voronoi.SetOddRowOffset(OddRowOffset);
	InitializeBiomes(a_IniFile.GetValueSet ("Generator", "VoronoiBiomes",   ""));
}
예제 #8
0
BLOCKTYPE cChunkGenerator::GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default)
{
	AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default);
	int Block = BlockStringToType(BlockType);
	if (Block < 0)
	{
		LOGWARN("[%s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(), a_Default.c_str());
		return static_cast<BLOCKTYPE>(BlockStringToType(a_Default));
	}
	return static_cast<BLOCKTYPE>(Block);
}
예제 #9
0
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[]
}
예제 #10
0
cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, eDimension a_Dimension) :
	m_Noise(a_Seed + a_Fluid * 100),  // Need to take fluid into account, otherwise water and lava springs generate next to each other
	m_HeightDistribution(255),
	m_Fluid(a_Fluid)
{
	bool IsWater = (a_Fluid == E_BLOCK_WATER);
	AString SectionName = IsWater ? "WaterSprings" : "LavaSprings";
	AString DefaultHeightDistribution;
	int DefaultChance = 0;
	switch (a_Dimension)
	{
		case dimNether:
		{
			DefaultHeightDistribution = IsWater ? DEF_NETHER_WATER_SPRINGS : DEF_NETHER_LAVA_SPRINGS;
			DefaultChance = IsWater ? 0 : 15;
			break;
		}
		case dimOverworld:
		{
			DefaultHeightDistribution = IsWater ? DEF_OVERWORLD_WATER_SPRINGS : DEF_OVERWORLD_LAVA_SPRINGS;
			DefaultChance = IsWater ? 24 : 9;
			break;
		}
		case dimEnd:
		{
			DefaultHeightDistribution = IsWater ? DEF_END_WATER_SPRINGS : DEF_END_LAVA_SPRINGS;
			DefaultChance = 0;
			break;
		}
		default:
		{
			ASSERT(!"Unhandled world dimension");
			break;
		}
	}  // switch (dimension)
	AString HeightDistribution = a_IniFile.GetValueSet(SectionName, "HeightDistribution", DefaultHeightDistribution);
	if (!m_HeightDistribution.SetDefString(HeightDistribution) || (m_HeightDistribution.GetSum() <= 0))
	{
		LOGWARNING("[%sSprings]: HeightDistribution is invalid, using the default of \"%s\".",
			(a_Fluid == E_BLOCK_WATER) ? "Water" : "Lava",
			DefaultHeightDistribution.c_str()
		);
		m_HeightDistribution.SetDefString(DefaultHeightDistribution);
	}
	m_Chance = a_IniFile.GetValueSetI(SectionName, "Chance", DefaultChance);
}
예제 #11
0
bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a_ChunkSink, cIniFile & a_IniFile)
{
	m_PluginInterface = &a_PluginInterface;
	m_ChunkSink = &a_ChunkSink;

	// Get the seed; create a new one and log it if not found in the INI file:
	if (a_IniFile.HasValue("Seed", "Seed"))
	{
		m_Seed = a_IniFile.GetValueI("Seed", "Seed");
	}
	else
	{
		MTRand rnd;
		m_Seed = rnd.randInt();
		LOGINFO("Chosen a new random seed for world: %d", m_Seed);
		a_IniFile.SetValueI("Seed", "Seed", m_Seed);
	}
	
	// Get the generator engine based on the INI file settings:
	AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable");
	if (NoCaseCompare(GeneratorName, "Noise3D") == 0)
	{
		m_Generator = new cNoise3DGenerator(*this);
	}
	else
	{
		if (NoCaseCompare(GeneratorName, "composable") != 0)
		{
			LOGWARN("[Generator]::Generator value \"%s\" not recognized, using \"Composable\".", GeneratorName.c_str());
		}
		m_Generator = new cComposableGenerator(*this);
	}

	if (m_Generator == nullptr)
	{
		LOGERROR("Generator could not start, aborting the server");
		return false;
	}

	m_Generator->Initialize(a_IniFile);

	return super::Start();
}
예제 #12
0
void cRoot::LoadWorlds(cIniFile & IniFile)
{
	// First get the default world
	AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world");
	m_pDefaultWorld = new cWorld(DefaultWorldName.c_str());
	m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld;

	// Then load the other worlds
	int KeyNum = IniFile.FindKey("Worlds");
	int NumWorlds = IniFile.GetNumValues(KeyNum);
	if (NumWorlds <= 0)
	{
		return;
	}
	
	bool FoundAdditionalWorlds = false;
	for (int i = 0; i < NumWorlds; i++)
	{
		AString ValueName = IniFile.GetValueName(KeyNum, i);
		if (ValueName.compare("World") != 0)
		{
			continue;
		}
		AString WorldName = IniFile.GetValue(KeyNum, i);
		if (WorldName.empty())
		{
			continue;
		}
		FoundAdditionalWorlds = true;
		cWorld* NewWorld = new cWorld( WorldName.c_str());
		m_WorldsByName[ WorldName ] = NewWorld;
	}  // for i - Worlds

	if (!FoundAdditionalWorlds)
	{
		if (IniFile.GetKeyComment("Worlds", 0) != " World=secondworld")
		{
			IniFile.DeleteKeyComment("Worlds", 0);
			IniFile.AddKeyComment("Worlds", " World=secondworld");
		}
	}
}
예제 #13
0
void cBioGenVoronoi::InitializeBiomeGen(cIniFile & a_IniFile)
{
	super::InitializeBiomeGen(a_IniFile);
	m_Voronoi.SetCellSize(a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64));
	InitializeBiomes     (a_IniFile.GetValueSet ("Generator", "VoronoiBiomes",   ""));
}
예제 #14
0
void cAuthenticator::ReadINI(cIniFile & IniFile)
{
	m_Server = IniFile.GetValueSet("Authentication", "Server", DEFAULT_AUTH_SERVER);
	m_Address = IniFile.GetValueSet("Authentication", "Address", DEFAULT_AUTH_ADDRESS);
	m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true);
}
예제 #15
0
파일: Server.cpp 프로젝트: DjKiDD/MCServer
bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth)
{
	m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!");
	m_MaxPlayers  = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100);
	m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false);
	m_bAllowMultiLogin = a_SettingsIni.GetValueSetB("Server", "AllowMultiLogin", false);
	m_PlayerCount = 0;
	m_PlayerCountDiff = 0;

	m_FaviconData = Base64Encode(cFile::ReadWholeFile(FILE_IO_PREFIX + AString("favicon.png")));  // Will return empty string if file nonexistant; client doesn't mind

	if (m_bIsConnected)
	{
		LOGERROR("ERROR: Trying to initialize server while server is already running!");
		return false;
	}

	LOGINFO("Compatible clients: %s", MCS_CLIENT_VERSIONS);
	LOGINFO("Compatible protocol versions %s", MCS_PROTOCOL_VERSIONS);

	m_Ports = ReadUpgradeIniPorts(a_SettingsIni, "Server", "Ports", "Port", "PortsIPv6", "25565");

	m_RCONServer.Initialize(a_SettingsIni);

	m_bIsConnected = true;

	m_ServerID = "-";
	m_ShouldAuthenticate = a_ShouldAuth;
	if (m_ShouldAuthenticate)
	{
		MTRand mtrand1;
		unsigned int r1 = (mtrand1.randInt() % 1147483647) + 1000000000;
		unsigned int r2 = (mtrand1.randInt() % 1147483647) + 1000000000;
		std::ostringstream sid;
		sid << std::hex << r1;
		sid << std::hex << r2;
		m_ServerID = sid.str();
		m_ServerID.resize(16, '0');
	}

	// Check if both BungeeCord and online mode are on, if so, warn the admin:
	m_ShouldAllowBungeeCord = a_SettingsIni.GetValueSetB("Authentication", "AllowBungeeCord", false);
	if (m_ShouldAllowBungeeCord && m_ShouldAuthenticate)
	{
		LOGWARNING("WARNING: BungeeCord is allowed and server set to online mode. This is unsafe and will not work properly. Disable either authentication or BungeeCord in settings.ini.");
	}

	m_ShouldLoadOfflinePlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false);
	m_ShouldLoadNamedPlayerData   = a_SettingsIni.GetValueSetB("PlayerData", "LoadNamedPlayerData", true);

	m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE);
	if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE)
	{
		m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE;
		LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance);
	}
	if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE)
	{
		m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE;
		LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance);
	}

	PrepareKeys();

	return true;
}
예제 #16
0
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[]
}
예제 #17
0
cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault)
{
	AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", "");
	if (HeightGenName.empty())
	{
		LOGWARN("[Generator] HeightGen value not set in world.ini, using \"Biomal\".");
		HeightGenName = "Biomal";
	}
	
	a_CacheOffByDefault = false;
	cTerrainHeightGen * res = nullptr;
	if (NoCaseCompare(HeightGenName, "flat") == 0)
	{
		res = new cHeiGenFlat;
		a_CacheOffByDefault = true;  // We're generating faster than a cache would retrieve data
	}
	else if (NoCaseCompare(HeightGenName, "classic") == 0)
	{
		res = new cHeiGenClassic(a_Seed);
	}
	else if (NoCaseCompare(HeightGenName, "DistortedHeightmap") == 0)
	{
		res = new cDistortedHeightmap(a_Seed, a_BiomeGen);
	}
	else if (NoCaseCompare(HeightGenName, "End") == 0)
	{
		res = new cEndGen(a_Seed);
	}
	else if (NoCaseCompare(HeightGenName, "MinMax") == 0)
	{
		res = new cHeiGenMinMax(a_Seed, a_BiomeGen);
	}
	else if (NoCaseCompare(HeightGenName, "Mountains") == 0)
	{
		res = new cHeiGenMountains(a_Seed);
	}
	else if (NoCaseCompare(HeightGenName, "BiomalNoise3D") == 0)
	{
		res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen);
	}
	else if (NoCaseCompare(HeightGenName, "Noise3D") == 0)
	{
		res = new cNoise3DComposable(a_Seed);
	}
	else if (NoCaseCompare(HeightGenName, "biomal") == 0)
	{
		res = new cHeiGenBiomal(a_Seed, a_BiomeGen);

		/*
		// Performance-testing:
		LOGINFO("Measuring performance of cHeiGenBiomal...");
		clock_t BeginTick = clock();
		for (int x = 0; x < 500; x++)
		{
			cChunkDef::HeightMap Heights;
			res->GenHeightMap(x * 5, x * 5, Heights);
		}
		clock_t Duration = clock() - BeginTick;
		LOGINFO("HeightGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
		//*/
	}
	else
	{
		// No match found, force-set the default and retry
		LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str());
		a_IniFile.DeleteValue("Generator", "HeightGen");
		a_IniFile.SetValue("Generator", "HeightGen", "Biomal");
		return CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault);
	}
	
	// Read the settings:
	res->InitializeHeightGen(a_IniFile);
	
	return cTerrainHeightGenPtr(res);
}
예제 #18
0
cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, int a_Seed)
{
	AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", "");
	if (CompoGenName.empty())
	{
		LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\".");
		CompoGenName = "Biomal";
	}

	// Compositor list is alpha-sorted
	cTerrainCompositionGenPtr res;
	if (NoCaseCompare(CompoGenName, "Biomal") == 0)
	{
		res = CreateCompoGenBiomal(a_Seed);
	}
	else if (NoCaseCompare(CompoGenName, "BiomalNoise3D") == 0)
	{
		// The composition that used to be provided with BiomalNoise3D is now provided by the Biomal compositor:
		res = CreateCompoGenBiomal(a_Seed);
	}
	else if (NoCaseCompare(CompoGenName, "Classic") == 0)
	{
		res = std::make_shared<cCompoGenClassic>();
	}
	else if (NoCaseCompare(CompoGenName, "DebugBiomes") == 0)
	{
		res = std::make_shared<cCompoGenDebugBiomes>();
	}
	else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0)
	{
		// The composition that used to be provided with DistortedHeightmap is now provided by the Biomal compositor:
		res = CreateCompoGenBiomal(a_Seed);
	}
	else if (NoCaseCompare(CompoGenName, "End") == 0)
	{
		res = std::make_shared<cEndGen>(a_Seed);
	}
	else if (NoCaseCompare(CompoGenName, "Nether") == 0)
	{
		res = std::make_shared<cCompoGenNether>(a_Seed);
	}
	else if (NoCaseCompare(CompoGenName, "Noise3D") == 0)
	{
		// The composition that used to be provided with Noise3D is now provided by the Biomal compositor:
		res = CreateCompoGenBiomal(a_Seed);
	}
	else if (NoCaseCompare(CompoGenName, "SameBlock") == 0)
	{
		res = std::make_shared<cCompoGenSameBlock>();
	}
	else
	{
		LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str());
		a_IniFile.SetValue("Generator", "CompositionGen", "Biomal");
		return CreateCompositionGen(a_IniFile, a_BiomeGen, a_ShapeGen, a_Seed);
	}
	ASSERT(res != nullptr);

	// Read the settings from the ini file:
	res->InitializeCompoGen(a_IniFile);

	return cTerrainCompositionGenPtr(res);
}
예제 #19
0
cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault)
{
	AString shapeGenName = a_IniFile.GetValueSet("Generator", "ShapeGen", "");
	if (shapeGenName.empty())
	{
		LOGWARN("[Generator] ShapeGen value not set in world.ini, using \"BiomalNoise3D\".");
		shapeGenName = "BiomalNoise3D";
	}

	// If the shapegen is HeightMap, redirect to older HeightMap-based generators:
	if (NoCaseCompare(shapeGenName, "HeightMap") == 0)
	{
		cTerrainHeightGenPtr heightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault);
		if (heightGen != nullptr)
		{
			return std::make_shared<cTerrainHeightToShapeGen>(heightGen);
		}

		// The height gen was not recognized; several heightgens were promoted to shape gens, so let's try them instead:
		shapeGenName = a_IniFile.GetValue("Generator", "HeightGen", "");
		if (shapeGenName.empty())
		{
			LOGWARNING("[Generator] ShapeGen set to HeightMap, but HeightGen not set. Reverting to \"BiomalNoise3D\".");
			shapeGenName = "BiomalNoise3D";
			a_IniFile.SetValue("Generator", "ShapeGen", shapeGenName);
		}
	}

	// Choose the shape generator based on the name:
	a_CacheOffByDefault = false;
	cTerrainShapeGenPtr res;
	if (NoCaseCompare(shapeGenName, "DistortedHeightmap") == 0)
	{
		res = std::make_shared<cDistortedHeightmap>(a_Seed, a_BiomeGen);
	}
	else if (NoCaseCompare(shapeGenName, "End") == 0)
	{
		res = std::make_shared<cEndGen>(a_Seed);
	}
	else if (NoCaseCompare(shapeGenName, "BiomalNoise3D") == 0)
	{
		res = std::make_shared<cBiomalNoise3DComposable>(a_Seed, a_BiomeGen);
	}
	else if (NoCaseCompare(shapeGenName, "Noise3D") == 0)
	{
		res = std::make_shared<cNoise3DComposable>(a_Seed);
	}
	else if (NoCaseCompare(shapeGenName, "TwoHeights") == 0)
	{
		res = CreateShapeGenTwoHeights(a_Seed, a_BiomeGen);
	}
	else
	{
		// No match found, force-set the default and retry
		LOGWARN("Unknown ShapeGen \"%s\", using \"BiomalNoise3D\" instead.", shapeGenName.c_str());
		a_IniFile.SetValue("Generator", "ShapeGen", "BiomalNoise3D");
		return CreateShapeGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault);
	}

	// Read the settings:
	res->InitializeShapeGen(a_IniFile);

	return res;
}
예제 #20
0
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[]
}
예제 #21
0
bool cServer::InitServer(cIniFile & a_SettingsIni)
{
	m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!").c_str();
	m_MaxPlayers  = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100);
	m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false);
	m_PlayerCount = 0;
	m_PlayerCountDiff = 0;

	if (m_bIsConnected)
	{
		LOGERROR("ERROR: Trying to initialize server while server is already running!");
		return false;
	}

	LOGINFO("Compatible clients: %s", MCS_CLIENT_VERSIONS);
	LOGINFO("Compatible protocol versions %s", MCS_PROTOCOL_VERSIONS);

	if (cSocket::WSAStartup() != 0) // Only does anything on Windows, but whatever
	{
		LOGERROR("WSAStartup() != 0");
		return false;
	}

	bool HasAnyPorts = false;
	AString Ports = a_SettingsIni.GetValueSet("Server", "Port", "25565");
	m_ListenThreadIPv4.SetReuseAddr(true);
	if (m_ListenThreadIPv4.Initialize(Ports))
	{
		HasAnyPorts = true;
	}

	Ports = a_SettingsIni.GetValueSet("Server", "PortsIPv6", "25565");
	m_ListenThreadIPv6.SetReuseAddr(true);
	if (m_ListenThreadIPv6.Initialize(Ports))
	{
		HasAnyPorts = true;
	}
	
	if (!HasAnyPorts)
	{
		LOGERROR("Couldn't open any ports. Aborting the server");
		return false;
	}

	m_RCONServer.Initialize(a_SettingsIni);

	m_bIsConnected = true;

	m_ServerID = "-";
	if (a_SettingsIni.GetValueSetB("Authentication", "Authenticate", true))
	{
		MTRand mtrand1;
		unsigned int r1 = (mtrand1.randInt() % 1147483647) + 1000000000;
		unsigned int r2 = (mtrand1.randInt() % 1147483647) + 1000000000;
		std::ostringstream sid;
		sid << std::hex << r1;
		sid << std::hex << r2;
		m_ServerID = sid.str();
		m_ServerID.resize(16, '0');
	}
	
	m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE);
	if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE)
	{
		m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE;
		LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance);
	}
	if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE)
	{
		m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE;
		LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance);
	}
	
	m_NotifyWriteThread.Start(this);
	
	PrepareKeys();
	
	return true;
}
예제 #22
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[]
}
예제 #23
0
void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile)
{
	AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", "");
	if (HeightGenName.empty())
	{
		LOGWARN("[Generator] HeightGen value not set in world.ini, using \"Biomal\".");
		HeightGenName = "Biomal";
	}
	
	int Seed = m_ChunkGenerator.GetSeed();
	bool CacheOffByDefault = false;
	if (NoCaseCompare(HeightGenName, "flat") == 0)
	{
		int Height = a_IniFile.GetValueSetI("Generator", "FlatHeight", 5);
		m_HeightGen = new cHeiGenFlat(Height);
		CacheOffByDefault = true;  // We're generating faster than a cache would retrieve data
	}
	else if (NoCaseCompare(HeightGenName, "classic") == 0)
	{
		// These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values):
		float HeightFreq1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq1", 0.1);
		float HeightFreq2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq2", 1.0);
		float HeightFreq3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq3", 2.0);
		float HeightAmp1  = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp1",  1.0);
		float HeightAmp2  = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp2",  0.5);
		float HeightAmp3  = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp3",  0.5);
		m_HeightGen = new cHeiGenClassic(Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3);
	}
	else if (NoCaseCompare(HeightGenName, "DistortedHeightmap") == 0)
	{
		m_HeightGen = new cDistortedHeightmap(Seed, *m_BiomeGen);
		((cDistortedHeightmap *)m_HeightGen)->Initialize(a_IniFile);
	}
	else if (NoCaseCompare(HeightGenName, "End") == 0)
	{
		m_HeightGen = new cEndGen(Seed);
		((cEndGen *)m_HeightGen)->Initialize(a_IniFile);
	}
	else if (NoCaseCompare(HeightGenName, "Noise3D") == 0)
	{
		m_HeightGen = new cNoise3DComposable(Seed);
		((cNoise3DComposable *)m_HeightGen)->Initialize(a_IniFile);
	}
	else  // "biomal" or <not found>
	{
		if (NoCaseCompare(HeightGenName, "biomal") != 0)
		{
			LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str());
		}
		m_HeightGen = new cHeiGenBiomal(Seed, *m_BiomeGen);

		/*
		// Performance-testing:
		LOGINFO("Measuring performance of cHeiGenBiomal...");
		clock_t BeginTick = clock();
		for (int x = 0; x < 500; x++)
		{
			cChunkDef::HeightMap Heights;
			m_HeightGen->GenHeightMap(x * 5, x * 5, Heights);
		}
		clock_t Duration = clock() - BeginTick;
		LOGINFO("HeightGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
		//*/
	}
	
	// Add a cache, if requested:
	int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64);
	if (CacheSize > 0)
	{
		if (CacheSize < 4)
		{
			LOGWARNING("Heightgen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", 
				CacheSize, 4
			);
			CacheSize = 4;
		}
		LOGINFO("Using a cache for Heightgen of size %d.", CacheSize);
		m_UnderlyingHeightGen = m_HeightGen;
		m_HeightGen = new cHeiGenCache(m_UnderlyingHeightGen, CacheSize);
	}
}
예제 #24
0
void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile)
{
	AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
	if (BiomeGenName.empty())
	{
		LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
		BiomeGenName = "MultiStepMap";
	}
	
	int Seed = m_ChunkGenerator.GetSeed();
	bool CacheOffByDefault = false;
	if (NoCaseCompare(BiomeGenName, "constant") == 0)
	{
		m_BiomeGen = new cBioGenConstant;
		CacheOffByDefault = true;  // we're generating faster than a cache would retrieve data :)
	}
	else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
	{
		m_BiomeGen = new cBioGenCheckerboard;
		CacheOffByDefault = true;  // we're (probably) generating faster than a cache would retrieve data
	}
	else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
	{
		m_BiomeGen = new cBioGenVoronoi(Seed);
	}
	else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0)
	{
		m_BiomeGen = new cBioGenDistortedVoronoi(Seed);
	}
	else
	{
		if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
		{
			LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
		}
		m_BiomeGen = new cBioGenMultiStepMap(Seed);

		/*
		// Performance-testing:
		LOGINFO("Measuring performance of cBioGenMultiStepMap...");
		clock_t BeginTick = clock();
		for (int x = 0; x < 5000; x++)
		{
			cChunkDef::BiomeMap Biomes;
			m_BiomeGen->GenBiomes(x * 5, x * 5, Biomes);
		}
		clock_t Duration = clock() - BeginTick;
		LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
		//*/
	}
	
	// Add a cache, if requested:
	int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64);
	if (CacheSize > 0)
	{
		if (CacheSize < 4)
		{
			LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", 
				CacheSize, 4
			);
			CacheSize = 4;
		}
		LOGD("Using a cache for biomegen of size %d.", CacheSize);
		m_UnderlyingBiomeGen = m_BiomeGen;
		m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize);
	}
	m_BiomeGen->Initialize(a_IniFile);
}
예제 #25
0
void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile)
{
	AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", "");
	if (CompoGenName.empty())
	{
		LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\".");
		CompoGenName = "Biomal";
	}
	if (NoCaseCompare(CompoGenName, "sameblock") == 0)
	{
		int Block = m_ChunkGenerator.GetIniBlock(a_IniFile, "Generator", "SameBlockType", "stone");
		bool Bedrocked = (a_IniFile.GetValueSetI("Generator", "SameBlockBedrocked", 1) != 0);
		m_CompositionGen = new cCompoGenSameBlock((BLOCKTYPE)Block, Bedrocked);
	}
	else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0)
	{
		m_CompositionGen = new cCompoGenDebugBiomes;
	}
	else if (NoCaseCompare(CompoGenName, "classic") == 0)
	{
		int SeaLevel    = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", 60);
		int BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", 2);
		int BeachDepth  = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", 4);
		BLOCKTYPE BlockTop         = m_ChunkGenerator.GetIniBlock(a_IniFile, "Generator", "ClassicBlockTop",         "grass");
		BLOCKTYPE BlockMiddle      = m_ChunkGenerator.GetIniBlock(a_IniFile, "Generator", "ClassicBlockMiddle",      "dirt");
		BLOCKTYPE BlockBottom      = m_ChunkGenerator.GetIniBlock(a_IniFile, "Generator", "ClassicBlockBottom",      "stone");
		BLOCKTYPE BlockBeach       = m_ChunkGenerator.GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeach",       "sand");
		BLOCKTYPE BlockBeachBottom = m_ChunkGenerator.GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeachBottom", "sandstone");
		BLOCKTYPE BlockSea         = m_ChunkGenerator.GetIniBlock(a_IniFile, "Generator", "ClassicBlockSea",         "stationarywater");
		m_CompositionGen = new cCompoGenClassic(
			SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach,
			BlockBeachBottom, BlockSea
		);
	}
	else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0)
	{
		m_CompositionGen = new cDistortedHeightmap(m_ChunkGenerator.GetSeed(), *m_BiomeGen);
		((cDistortedHeightmap *)m_CompositionGen)->Initialize(a_IniFile);
	}
	else if (NoCaseCompare(CompoGenName, "end") == 0)
	{
		m_CompositionGen = new cEndGen(m_ChunkGenerator.GetSeed());
		((cEndGen *)m_CompositionGen)->Initialize(a_IniFile);
	}
	else if (NoCaseCompare(CompoGenName, "nether") == 0)
	{
		m_CompositionGen = new cCompoGenNether(m_ChunkGenerator.GetSeed());
	}
	else if (NoCaseCompare(CompoGenName, "Noise3D") == 0)
	{
		m_CompositionGen = new cNoise3DComposable(m_ChunkGenerator.GetSeed());
		((cNoise3DComposable *)m_CompositionGen)->Initialize(a_IniFile);
	}
	else
	{
		if (NoCaseCompare(CompoGenName, "biomal") != 0)
		{
			LOGWARN("Unknown CompositionGen \"%s\", using \"biomal\" instead.", CompoGenName.c_str());
		}
		int SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", 62);
		int Seed = m_ChunkGenerator.GetSeed();
		m_CompositionGen = new cCompoGenBiomal(Seed, SeaLevel);

		/*
		// Performance-testing:
		LOGINFO("Measuring performance of cCompoGenBiomal...");
		clock_t BeginTick = clock();
		for (int x = 0; x < 500; x++)
		{
			cChunkDesc Desc(200 + x * 8, 200 + x * 8);
			m_BiomeGen->GenBiomes(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetBiomeMap());
			m_HeightGen->GenHeightMap(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetHeightMap());
			m_CompositionGen->ComposeTerrain(Desc);
		}
		clock_t Duration = clock() - BeginTick;
		LOGINFO("CompositionGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
		//*/
	}
	
	int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64);
	if (CompoGenCacheSize > 1)
	{
		m_UnderlyingCompositionGen = m_CompositionGen;
		m_CompositionGen = new cCompoGenCache(m_UnderlyingCompositionGen, 32);
	}
}
예제 #26
0
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[]
}