mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- Bug-fixing for last commit - Moved CMapGenOptions to CMapGenerator
This commit is contained in:
		| @@ -1856,6 +1856,7 @@ void RandomMapTab::updateMapInfo() | ||||
| 		player.team = TeamID(i); | ||||
| 		player.hasMainTown = true; | ||||
| 		player.generateHeroAtMainTown = true; | ||||
| 		player.isFactionRandom = true; | ||||
| 		mapInfo.mapHeader->players.push_back(player); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| #include "GUIClasses.h" | ||||
| #include "FunctionList.h" | ||||
| #include "../lib/mapping/CMapInfo.h" | ||||
| #include "../lib/rmg/CMapGenOptions.h" | ||||
| #include "../lib/rmg/CMapGenerator.h" | ||||
|  | ||||
| /* | ||||
|  * CPreGame.h, part of VCMI engine | ||||
|   | ||||
| @@ -25,7 +25,6 @@ | ||||
| #include "JsonNode.h" | ||||
| #include "filesystem/CResourceLoader.h" | ||||
| #include "GameConstants.h" | ||||
| #include "rmg/CMapGenOptions.h" | ||||
| #include "rmg/CMapGenerator.h" | ||||
|  | ||||
| DLL_LINKAGE boost::rand48 ran; | ||||
|   | ||||
| @@ -21,7 +21,6 @@ set(lib_SRCS | ||||
| 		mapping/CMapInfo.cpp | ||||
| 		mapping/CMapService.cpp | ||||
| 		mapping/MapFormatH3M.cpp | ||||
| 		rmg/CMapGenOptions.cpp | ||||
| 		rmg/CMapGenerator.cpp | ||||
| 		BattleAction.cpp | ||||
| 		BattleHex.cpp | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include "CCreatureSet.h" //for CStackInstance | ||||
| #include "CObjectHandler.h" //for CArmedInstance | ||||
| #include "mapping/CCampaignHandler.h" //for CCampaignState | ||||
| #include "rmg/CMapGenerator.h" // for CMapGenOptions | ||||
|  | ||||
| const ui32 version = 739; | ||||
|  | ||||
|   | ||||
| @@ -12,8 +12,7 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "rmg/CMapGenOptions.h" | ||||
|  | ||||
| class CMapGenOptions; | ||||
| class CCampaignState; | ||||
|  | ||||
| /// Struct which describes the name, the color, the starting bonus of a player | ||||
|   | ||||
| @@ -159,8 +159,6 @@ | ||||
| 		<Unit filename="mapping/MapFormatH3M.h" /> | ||||
| 		<Unit filename="NetPacks.h" /> | ||||
| 		<Unit filename="NetPacksLib.cpp" /> | ||||
| 		<Unit filename="rmg/CMapGenOptions.cpp" /> | ||||
| 		<Unit filename="rmg/CMapGenOptions.h" /> | ||||
| 		<Unit filename="rmg/CMapGenerator.cpp" /> | ||||
| 		<Unit filename="rmg/CMapGenerator.h" /> | ||||
| 		<Unit filename="logging/CLogger.cpp" /> | ||||
|   | ||||
| @@ -201,7 +201,6 @@ | ||||
|     <ClCompile Include="mapping\CMapEditManager.cpp" /> | ||||
|     <ClCompile Include="mapping\MapFormatH3M.cpp" /> | ||||
|     <ClCompile Include="RegisterTypes.cpp" /> | ||||
|     <ClCompile Include="rmg\CMapGenOptions.cpp" /> | ||||
|     <ClCompile Include="rmg\CMapGenerator.cpp" /> | ||||
|     <ClCompile Include="logging\CLogger.cpp" /> | ||||
|     <ClCompile Include="logging\CBasicLogConfigurator.cpp" /> | ||||
| @@ -270,7 +269,6 @@ | ||||
|     <ClInclude Include="mapping\CMapService.h" /> | ||||
|     <ClInclude Include="mapping\CMapEditManager.h" /> | ||||
|     <ClInclude Include="mapping\MapFormatH3M.h" /> | ||||
|     <ClInclude Include="rmg\CMapGenOptions.h" /> | ||||
|     <ClInclude Include="rmg\CMapGenerator.h" /> | ||||
|     <ClInclude Include="logging\CLogger.h" /> | ||||
|     <ClInclude Include="logging\CBasicLogConfigurator.h" /> | ||||
|   | ||||
| @@ -1,354 +0,0 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CMapGenOptions.h" | ||||
|  | ||||
| #include "../GameConstants.h" | ||||
| #include "../CRandomGenerator.h" | ||||
| #include "../VCMI_Lib.h" | ||||
| #include "../CTownHandler.h" | ||||
|  | ||||
| CMapGenOptions::CMapGenOptions() : width(72), height(72), hasTwoLevels(true), | ||||
| 	playersCnt(RANDOM_SIZE), teamsCnt(RANDOM_SIZE), compOnlyPlayersCnt(0), compOnlyTeamsCnt(RANDOM_SIZE), | ||||
| 	waterContent(EWaterContent::RANDOM), monsterStrength(EMonsterStrength::RANDOM) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| si32 CMapGenOptions::getWidth() const | ||||
| { | ||||
| 	return width; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setWidth(si32 value) | ||||
| { | ||||
| 	if(value > 0) | ||||
| 	{ | ||||
| 		width = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("A map width lower than 1 is not allowed."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si32 CMapGenOptions::getHeight() const | ||||
| { | ||||
| 	return height; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setHeight(si32 value) | ||||
| { | ||||
| 	if(value > 0) | ||||
| 	{ | ||||
| 		height = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("A map height lower than 1 is not allowed."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool CMapGenOptions::getHasTwoLevels() const | ||||
| { | ||||
| 	return hasTwoLevels; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setHasTwoLevels(bool value) | ||||
| { | ||||
| 	hasTwoLevels = value; | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getPlayersCnt() const | ||||
| { | ||||
| 	return playersCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setPlayersCnt(si8 value) | ||||
| { | ||||
| 	if((value >= 1 && value <= PlayerColor::PLAYER_LIMIT_I) || value == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		playersCnt = value; | ||||
| 		resetPlayersMap(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("Players count of RMG options should be between 1 and " + | ||||
| 								 boost::lexical_cast<std::string>(PlayerColor::PLAYER_LIMIT) + " or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getTeamsCnt() const | ||||
| { | ||||
| 	return teamsCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setTeamsCnt(si8 value) | ||||
| { | ||||
| 	if(playersCnt == RANDOM_SIZE || (value >= 0 && value < playersCnt) || value == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		teamsCnt = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("Teams count of RMG options should be between 0 and <" + | ||||
| 								 boost::lexical_cast<std::string>(playersCnt) + "(players count) - 1> or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getCompOnlyPlayersCnt() const | ||||
| { | ||||
| 	return compOnlyPlayersCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setCompOnlyPlayersCnt(si8 value) | ||||
| { | ||||
| 	if(value == RANDOM_SIZE || (value >= 0 && value <= PlayerColor::PLAYER_LIMIT_I - playersCnt)) | ||||
| 	{ | ||||
| 		compOnlyPlayersCnt = value; | ||||
| 		resetPlayersMap(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error(std::string("Computer only players count of RMG options should be ") + | ||||
| 								 "between 0 and <PlayerColor::PLAYER_LIMIT - " + boost::lexical_cast<std::string>(playersCnt) + | ||||
| 								 "(playersCount)> or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getCompOnlyTeamsCnt() const | ||||
| { | ||||
| 	return compOnlyTeamsCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setCompOnlyTeamsCnt(si8 value) | ||||
| { | ||||
| 	if(value == RANDOM_SIZE || compOnlyPlayersCnt == RANDOM_SIZE || (value >= 0 && value <= std::max(compOnlyPlayersCnt - 1, 0))) | ||||
| 	{ | ||||
| 		compOnlyTeamsCnt = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error(std::string("Computer only teams count of RMG options should be ") + | ||||
| 								 "between 0 and <" + boost::lexical_cast<std::string>(compOnlyPlayersCnt) + | ||||
| 								 "(compOnlyPlayersCnt) - 1> or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| EWaterContent::EWaterContent CMapGenOptions::getWaterContent() const | ||||
| { | ||||
| 	return waterContent; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setWaterContent(EWaterContent::EWaterContent value) | ||||
| { | ||||
| 	waterContent = value; | ||||
| } | ||||
|  | ||||
| EMonsterStrength::EMonsterStrength CMapGenOptions::getMonsterStrength() const | ||||
| { | ||||
| 	return monsterStrength; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setMonsterStrength(EMonsterStrength::EMonsterStrength value) | ||||
| { | ||||
| 	monsterStrength = value; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::resetPlayersMap() | ||||
| { | ||||
| 	players.clear(); | ||||
| 	int realPlayersCnt = playersCnt == RANDOM_SIZE ? PlayerColor::PLAYER_LIMIT_I : playersCnt; | ||||
| 	int realCompOnlyPlayersCnt = compOnlyPlayersCnt == RANDOM_SIZE ? (PlayerColor::PLAYER_LIMIT_I - realPlayersCnt) : compOnlyPlayersCnt; | ||||
| 	for(int color = 0; color < (realPlayersCnt + realCompOnlyPlayersCnt); ++color) | ||||
| 	{ | ||||
| 		CPlayerSettings player; | ||||
| 		player.setColor(PlayerColor(color)); | ||||
| 		player.setPlayerType((color >= playersCnt) ? EPlayerType::COMP_ONLY : EPlayerType::AI); | ||||
| 		players[PlayerColor(color)] = player; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| const std::map<PlayerColor, CMapGenOptions::CPlayerSettings> & CMapGenOptions::getPlayersSettings() const | ||||
| { | ||||
| 	return players; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setStartingTownForPlayer(PlayerColor color, si32 town) | ||||
| { | ||||
| 	auto it = players.find(color); | ||||
| 	if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set starting town for the player with the color '%i'.") % color)); | ||||
| 	it->second.setStartingTown(town); | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType) | ||||
| { | ||||
| 	auto it = players.find(color); | ||||
| 	if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set player type for the player with the color '%i'.") % color)); | ||||
| 	if(playerType == EPlayerType::COMP_ONLY) throw std::runtime_error("Cannot set player type computer only to a standard player."); | ||||
| 	it->second.setPlayerType(playerType); | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::finalize() | ||||
| { | ||||
| 	CRandomGenerator gen; | ||||
| 	finalize(gen); | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::finalize(CRandomGenerator & gen) | ||||
| { | ||||
| 	if(playersCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		// 1 human is required at least | ||||
| 		auto humanPlayers = countHumanPlayers(); | ||||
| 		if(humanPlayers == 0) humanPlayers = 1; | ||||
| 		playersCnt = gen.getInteger(humanPlayers, PlayerColor::PLAYER_LIMIT_I); | ||||
|  | ||||
| 		// Remove AI players only from the end of the players map if necessary | ||||
| 		for(auto itrev = players.end(); itrev != players.begin();) | ||||
| 		{ | ||||
| 			auto it = itrev; | ||||
| 			--it; | ||||
| 			if(players.size() == playersCnt) break; | ||||
| 			if(it->second.getPlayerType() == EPlayerType::AI) | ||||
| 			{ | ||||
| 				players.erase(it); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				--itrev; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if(teamsCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		teamsCnt = gen.getInteger(0, playersCnt - 1); | ||||
| 	} | ||||
| 	if(compOnlyPlayersCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		compOnlyPlayersCnt = gen.getInteger(0, 8 - playersCnt); | ||||
| 		auto totalPlayersCnt = playersCnt + compOnlyPlayersCnt; | ||||
|  | ||||
| 		// Remove comp only players only from the end of the players map if necessary | ||||
| 		for(auto itrev = players.end(); itrev != players.begin();) | ||||
| 		{ | ||||
| 			auto it = itrev; | ||||
| 			--it; | ||||
| 			if(players.size() <= totalPlayersCnt) break; | ||||
| 			if(it->second.getPlayerType() == EPlayerType::COMP_ONLY) | ||||
| 			{ | ||||
| 				players.erase(it); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				--itrev; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Add some comp only players if necessary | ||||
| 		auto compOnlyPlayersToAdd = totalPlayersCnt - players.size(); | ||||
| 		for(int i = 0; i < compOnlyPlayersToAdd; ++i) | ||||
| 		{ | ||||
| 			CPlayerSettings pSettings; | ||||
| 			pSettings.setPlayerType(EPlayerType::COMP_ONLY); | ||||
| 			pSettings.setColor(getNextPlayerColor()); | ||||
| 			players[pSettings.getColor()] = pSettings; | ||||
| 		} | ||||
| 	} | ||||
| 	if(compOnlyTeamsCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		compOnlyTeamsCnt = gen.getInteger(0, std::max(compOnlyPlayersCnt - 1, 0)); | ||||
| 	} | ||||
|  | ||||
| 	// There should be at least 2 players (1-player-maps aren't allowed) | ||||
| 	if(playersCnt + compOnlyPlayersCnt < 2) | ||||
| 	{ | ||||
| 		CPlayerSettings pSettings; | ||||
| 		pSettings.setPlayerType(EPlayerType::AI); | ||||
| 		pSettings.setColor(getNextPlayerColor()); | ||||
| 		players[pSettings.getColor()] = pSettings; | ||||
| 		playersCnt = 2; | ||||
| 	} | ||||
|  | ||||
| 	// 1 team isn't allowed | ||||
| 	if(teamsCnt == 1 && compOnlyPlayersCnt == 0) | ||||
| 	{ | ||||
| 		teamsCnt = 0; | ||||
| 	} | ||||
|  | ||||
| 	if(waterContent == EWaterContent::RANDOM) | ||||
| 	{ | ||||
| 		waterContent = static_cast<EWaterContent::EWaterContent>(gen.getInteger(0, 2)); | ||||
| 	} | ||||
| 	if(monsterStrength == EMonsterStrength::RANDOM) | ||||
| 	{ | ||||
| 		monsterStrength = static_cast<EMonsterStrength::EMonsterStrength>(gen.getInteger(0, 2)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int CMapGenOptions::countHumanPlayers() const | ||||
| { | ||||
| 	return static_cast<int>(boost::count_if(players, [](const std::pair<PlayerColor, CPlayerSettings> & pair) | ||||
| 	{ | ||||
| 		return pair.second.getPlayerType() == EPlayerType::HUMAN; | ||||
| 	})); | ||||
| } | ||||
|  | ||||
| PlayerColor CMapGenOptions::getNextPlayerColor() const | ||||
| { | ||||
| 	for(PlayerColor i = PlayerColor(0); i < PlayerColor::PLAYER_LIMIT; i.advance(1)) | ||||
| 	{ | ||||
| 		if(!players.count(i)) | ||||
| 		{ | ||||
| 			return i; | ||||
| 		} | ||||
| 	} | ||||
| 	throw std::runtime_error("Shouldn't happen. No free player color exists."); | ||||
| } | ||||
|  | ||||
| CMapGenOptions::CPlayerSettings::CPlayerSettings() : color(0), startingTown(RANDOM_TOWN), playerType(EPlayerType::AI) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| PlayerColor CMapGenOptions::CPlayerSettings::getColor() const | ||||
| { | ||||
| 	return color; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::CPlayerSettings::setColor(PlayerColor value) | ||||
| { | ||||
| 	if(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT) | ||||
| 	{ | ||||
| 		color = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("The color of the player is not in a valid range."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si32 CMapGenOptions::CPlayerSettings::getStartingTown() const | ||||
| { | ||||
| 	return startingTown; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::CPlayerSettings::setStartingTown(si32 value) | ||||
| { | ||||
| 	if(value >= -1 && value < static_cast<int>(VLC->townh->towns.size())) | ||||
| 	{ | ||||
| 		startingTown = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("The starting town of the player is not in a valid range."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| EPlayerType::EPlayerType CMapGenOptions::CPlayerSettings::getPlayerType() const | ||||
| { | ||||
| 	return playerType; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::CPlayerSettings::setPlayerType(EPlayerType::EPlayerType value) | ||||
| { | ||||
| 	playerType = value; | ||||
| } | ||||
| @@ -1,163 +0,0 @@ | ||||
|  | ||||
| /* | ||||
|  * CMapGenOptions.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../GameConstants.h" | ||||
|  | ||||
| class CRandomGenerator; | ||||
|  | ||||
| namespace EWaterContent | ||||
| { | ||||
| enum EWaterContent | ||||
| { | ||||
| 	RANDOM = -1, | ||||
| 	NONE, | ||||
| 	NORMAL, | ||||
| 	ISLANDS | ||||
| }; | ||||
| } | ||||
|  | ||||
| namespace EMonsterStrength | ||||
| { | ||||
| enum EMonsterStrength | ||||
| { | ||||
| 	RANDOM = -1, | ||||
| 	WEAK, | ||||
| 	NORMAL, | ||||
| 	STRONG | ||||
| }; | ||||
| } | ||||
|  | ||||
| namespace EPlayerType | ||||
| { | ||||
| enum EPlayerType | ||||
| { | ||||
| 	HUMAN, | ||||
| 	AI, | ||||
| 	COMP_ONLY | ||||
| }; | ||||
| } | ||||
|  | ||||
| /// The map gen options class holds values about general map generation settings | ||||
| /// e.g. the size of the map, the count of players,... | ||||
| class DLL_LINKAGE CMapGenOptions | ||||
| { | ||||
| public: | ||||
| 	/// The player settings class maps the player color, starting town and human player flag. | ||||
| 	class CPlayerSettings | ||||
| 	{ | ||||
| 	public: | ||||
| 		CPlayerSettings(); | ||||
|  | ||||
| 		/// The color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1. | ||||
| 		/// The default value is 0. | ||||
| 		PlayerColor getColor() const; | ||||
| 		void setColor(PlayerColor value); | ||||
|  | ||||
| 		/// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN. | ||||
| 		/// The default value is RANDOM_TOWN. | ||||
| 		si32 getStartingTown() const; | ||||
| 		void setStartingTown(si32 value); | ||||
|  | ||||
| 		/// The default value is EPlayerType::AI. | ||||
| 		EPlayerType::EPlayerType getPlayerType() const; | ||||
| 		void setPlayerType(EPlayerType::EPlayerType value); | ||||
|  | ||||
| 		/// Constant for a random town selection. | ||||
| 		static const si32 RANDOM_TOWN = -1; | ||||
|  | ||||
| 	private: | ||||
| 		PlayerColor color; | ||||
| 		si32 startingTown; | ||||
| 		EPlayerType::EPlayerType playerType; | ||||
|  | ||||
| 	public: | ||||
| 		template <typename Handler> | ||||
| 		void serialize(Handler & h, const int version) | ||||
| 		{ | ||||
| 			h & color & startingTown & playerType; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	CMapGenOptions(); | ||||
|  | ||||
| 	si32 getWidth() const; | ||||
| 	void setWidth(si32 value); | ||||
|  | ||||
| 	si32 getHeight() const; | ||||
| 	void setHeight(si32 value); | ||||
|  | ||||
| 	bool getHasTwoLevels() const; | ||||
| 	void setHasTwoLevels(bool value); | ||||
|  | ||||
| 	/// The count of the players ranging from 1 to PlayerColor::PLAYER_LIMIT or RANDOM_SIZE for random. If you call | ||||
| 	/// this method, all player settings are reset to default settings. | ||||
| 	si8 getPlayersCnt() const; | ||||
| 	void setPlayersCnt(si8 value); | ||||
|  | ||||
| 	/// The count of the teams ranging from 0 to <players count - 1> or RANDOM_SIZE for random. | ||||
| 	si8 getTeamsCnt() const; | ||||
| 	void setTeamsCnt(si8 value); | ||||
|  | ||||
| 	/// The count of the computer only players ranging from 0 to <PlayerColor::PLAYER_LIMIT - players count> or RANDOM_SIZE for random. | ||||
| 	/// If you call this method, all player settings are reset to default settings. | ||||
| 	si8 getCompOnlyPlayersCnt() const; | ||||
| 	void setCompOnlyPlayersCnt(si8 value); | ||||
|  | ||||
| 	/// The count of the computer only teams ranging from 0 to <comp only players - 1> or RANDOM_SIZE for random. | ||||
| 	si8 getCompOnlyTeamsCnt() const; | ||||
| 	void setCompOnlyTeamsCnt(si8 value); | ||||
|  | ||||
| 	EWaterContent::EWaterContent getWaterContent() const; | ||||
| 	void setWaterContent(EWaterContent::EWaterContent value); | ||||
|  | ||||
| 	EMonsterStrength::EMonsterStrength getMonsterStrength() const; | ||||
| 	void setMonsterStrength(EMonsterStrength::EMonsterStrength value); | ||||
|  | ||||
| 	/// The first player colors belong to standard players and the last player colors belong to comp only players. | ||||
| 	/// All standard players are by default of type EPlayerType::AI. | ||||
| 	const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const; | ||||
| 	void setStartingTownForPlayer(PlayerColor color, si32 town); | ||||
| 	/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The | ||||
| 	/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN. Calling this method | ||||
| 	/// has no effect for the map itself, but it adds some informational text for the map description. | ||||
| 	void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType); | ||||
|  | ||||
| 	/// Finalizes the options. All random sizes for various properties will be overwritten by numbers from | ||||
| 	/// a random number generator by keeping the options in a valid state. | ||||
| 	void finalize(); | ||||
| 	void finalize(CRandomGenerator & gen); | ||||
|  | ||||
| 	static const si8 RANDOM_SIZE = -1; | ||||
|  | ||||
| private: | ||||
| 	void resetPlayersMap(); | ||||
| 	int countHumanPlayers() const; | ||||
| 	PlayerColor getNextPlayerColor() const; | ||||
|  | ||||
| 	si32 width, height; | ||||
| 	bool hasTwoLevels; | ||||
| 	si8 playersCnt, teamsCnt, compOnlyPlayersCnt, compOnlyTeamsCnt; | ||||
| 	EWaterContent::EWaterContent waterContent; | ||||
| 	EMonsterStrength::EMonsterStrength monsterStrength; | ||||
| 	std::map<PlayerColor, CPlayerSettings> players; | ||||
|  | ||||
| public: | ||||
| 	template <typename Handler> | ||||
| 	void serialize(Handler & h, const int version) | ||||
| 	{ | ||||
| 		//FIXME: Enum is not a fixed with data type. Add enum class to both enums | ||||
| 		// later. For now it is ok. | ||||
| 		h & width & height & hasTwoLevels & playersCnt & teamsCnt & compOnlyPlayersCnt; | ||||
| 		h & compOnlyTeamsCnt & waterContent & monsterStrength & players; | ||||
| 	} | ||||
| }; | ||||
| @@ -7,10 +7,356 @@ | ||||
| #include "../mapping/CMapEditManager.h" | ||||
| #include "../CObjectHandler.h" | ||||
| #include "../CDefObjInfoHandler.h" | ||||
| #include "../GameConstants.h" | ||||
| #include "../CTownHandler.h" | ||||
| #include "../StringConstants.h" | ||||
|  | ||||
| CMapGenOptions::CMapGenOptions() : width(72), height(72), hasTwoLevels(true), | ||||
| 	playersCnt(RANDOM_SIZE), teamsCnt(RANDOM_SIZE), compOnlyPlayersCnt(0), compOnlyTeamsCnt(RANDOM_SIZE), | ||||
| 	waterContent(EWaterContent::RANDOM), monsterStrength(EMonsterStrength::RANDOM) | ||||
| { | ||||
| 	resetPlayersMap(); | ||||
| } | ||||
|  | ||||
| si32 CMapGenOptions::getWidth() const | ||||
| { | ||||
| 	return width; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setWidth(si32 value) | ||||
| { | ||||
| 	if(value > 0) | ||||
| 	{ | ||||
| 		width = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("A map width lower than 1 is not allowed."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si32 CMapGenOptions::getHeight() const | ||||
| { | ||||
| 	return height; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setHeight(si32 value) | ||||
| { | ||||
| 	if(value > 0) | ||||
| 	{ | ||||
| 		height = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("A map height lower than 1 is not allowed."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool CMapGenOptions::getHasTwoLevels() const | ||||
| { | ||||
| 	return hasTwoLevels; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setHasTwoLevels(bool value) | ||||
| { | ||||
| 	hasTwoLevels = value; | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getPlayersCnt() const | ||||
| { | ||||
| 	return playersCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setPlayersCnt(si8 value) | ||||
| { | ||||
| 	if((value >= 1 && value <= PlayerColor::PLAYER_LIMIT_I) || value == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		playersCnt = value; | ||||
| 		resetPlayersMap(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("Players count of RMG options should be between 1 and " + | ||||
| 								 std::to_string(PlayerColor::PLAYER_LIMIT_I) + " or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getTeamsCnt() const | ||||
| { | ||||
| 	return teamsCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setTeamsCnt(si8 value) | ||||
| { | ||||
| 	if(playersCnt == RANDOM_SIZE || (value >= 0 && value < playersCnt) || value == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		teamsCnt = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("Teams count of RMG options should be between 0 and <" + | ||||
| 								 std::to_string(playersCnt) + "(players count) - 1> or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getCompOnlyPlayersCnt() const | ||||
| { | ||||
| 	return compOnlyPlayersCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setCompOnlyPlayersCnt(si8 value) | ||||
| { | ||||
| 	if(value == RANDOM_SIZE || (value >= 0 && value <= PlayerColor::PLAYER_LIMIT_I - playersCnt)) | ||||
| 	{ | ||||
| 		compOnlyPlayersCnt = value; | ||||
| 		resetPlayersMap(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error(std::string("Computer only players count of RMG options should be ") + | ||||
| 								 "between 0 and <PlayerColor::PLAYER_LIMIT - " + std::to_string(playersCnt) + | ||||
| 								 "(playersCount)> or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si8 CMapGenOptions::getCompOnlyTeamsCnt() const | ||||
| { | ||||
| 	return compOnlyTeamsCnt; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setCompOnlyTeamsCnt(si8 value) | ||||
| { | ||||
| 	if(value == RANDOM_SIZE || compOnlyPlayersCnt == RANDOM_SIZE || (value >= 0 && value <= std::max(compOnlyPlayersCnt - 1, 0))) | ||||
| 	{ | ||||
| 		compOnlyTeamsCnt = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error(std::string("Computer only teams count of RMG options should be ") + | ||||
| 								 "between 0 and <" + std::to_string(compOnlyPlayersCnt) + | ||||
| 								 "(compOnlyPlayersCnt) - 1> or CMapGenOptions::RANDOM_SIZE for random."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| EWaterContent::EWaterContent CMapGenOptions::getWaterContent() const | ||||
| { | ||||
| 	return waterContent; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setWaterContent(EWaterContent::EWaterContent value) | ||||
| { | ||||
| 	waterContent = value; | ||||
| } | ||||
|  | ||||
| EMonsterStrength::EMonsterStrength CMapGenOptions::getMonsterStrength() const | ||||
| { | ||||
| 	return monsterStrength; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setMonsterStrength(EMonsterStrength::EMonsterStrength value) | ||||
| { | ||||
| 	monsterStrength = value; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::resetPlayersMap() | ||||
| { | ||||
| 	players.clear(); | ||||
| 	int realPlayersCnt = playersCnt == RANDOM_SIZE ? PlayerColor::PLAYER_LIMIT_I : playersCnt; | ||||
| 	int realCompOnlyPlayersCnt = compOnlyPlayersCnt == RANDOM_SIZE ? (PlayerColor::PLAYER_LIMIT_I - realPlayersCnt) : compOnlyPlayersCnt; | ||||
| 	for(int color = 0; color < (realPlayersCnt + realCompOnlyPlayersCnt); ++color) | ||||
| 	{ | ||||
| 		CPlayerSettings player; | ||||
| 		player.setColor(PlayerColor(color)); | ||||
| 		player.setPlayerType((color >= realPlayersCnt) ? EPlayerType::COMP_ONLY : EPlayerType::AI); | ||||
| 		players[PlayerColor(color)] = player; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| const std::map<PlayerColor, CMapGenOptions::CPlayerSettings> & CMapGenOptions::getPlayersSettings() const | ||||
| { | ||||
| 	return players; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setStartingTownForPlayer(PlayerColor color, si32 town) | ||||
| { | ||||
| 	auto it = players.find(color); | ||||
| 	if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set starting town for the player with the color '%s'.") % std::to_string(color.getNum()))); | ||||
| 	it->second.setStartingTown(town); | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType) | ||||
| { | ||||
| 	auto it = players.find(color); | ||||
| 	if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set player type for the player with the color '%s'.") % std::to_string(color.getNum()))); | ||||
| 	if(playerType == EPlayerType::COMP_ONLY) throw std::runtime_error("Cannot set player type computer only to a standard player."); | ||||
| 	it->second.setPlayerType(playerType); | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::finalize() | ||||
| { | ||||
| 	CRandomGenerator gen; | ||||
| 	finalize(gen); | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::finalize(CRandomGenerator & gen) | ||||
| { | ||||
| 	if(playersCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		// 1 human is required at least | ||||
| 		auto humanPlayers = countHumanPlayers(); | ||||
| 		if(humanPlayers == 0) humanPlayers = 1; | ||||
| 		playersCnt = gen.getInteger(humanPlayers, PlayerColor::PLAYER_LIMIT_I); | ||||
|  | ||||
| 		// Remove AI players only from the end of the players map if necessary | ||||
| 		for(auto itrev = players.end(); itrev != players.begin();) | ||||
| 		{ | ||||
| 			auto it = itrev; | ||||
| 			--it; | ||||
| 			if(players.size() == playersCnt) break; | ||||
| 			if(it->second.getPlayerType() == EPlayerType::AI) | ||||
| 			{ | ||||
| 				players.erase(it); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				--itrev; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if(teamsCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		teamsCnt = gen.getInteger(0, playersCnt - 1); | ||||
| 	} | ||||
| 	if(compOnlyPlayersCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		compOnlyPlayersCnt = gen.getInteger(0, 8 - playersCnt); | ||||
| 		auto totalPlayersCnt = playersCnt + compOnlyPlayersCnt; | ||||
|  | ||||
| 		// Remove comp only players only from the end of the players map if necessary | ||||
| 		for(auto itrev = players.end(); itrev != players.begin();) | ||||
| 		{ | ||||
| 			auto it = itrev; | ||||
| 			--it; | ||||
| 			if(players.size() <= totalPlayersCnt) break; | ||||
| 			if(it->second.getPlayerType() == EPlayerType::COMP_ONLY) | ||||
| 			{ | ||||
| 				players.erase(it); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				--itrev; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Add some comp only players if necessary | ||||
| 		auto compOnlyPlayersToAdd = totalPlayersCnt - players.size(); | ||||
| 		for(int i = 0; i < compOnlyPlayersToAdd; ++i) | ||||
| 		{ | ||||
| 			CPlayerSettings pSettings; | ||||
| 			pSettings.setPlayerType(EPlayerType::COMP_ONLY); | ||||
| 			pSettings.setColor(getNextPlayerColor()); | ||||
| 			players[pSettings.getColor()] = pSettings; | ||||
| 		} | ||||
| 	} | ||||
| 	if(compOnlyTeamsCnt == RANDOM_SIZE) | ||||
| 	{ | ||||
| 		compOnlyTeamsCnt = gen.getInteger(0, std::max(compOnlyPlayersCnt - 1, 0)); | ||||
| 	} | ||||
|  | ||||
| 	// There should be at least 2 players (1-player-maps aren't allowed) | ||||
| 	if(playersCnt + compOnlyPlayersCnt < 2) | ||||
| 	{ | ||||
| 		CPlayerSettings pSettings; | ||||
| 		pSettings.setPlayerType(EPlayerType::AI); | ||||
| 		pSettings.setColor(getNextPlayerColor()); | ||||
| 		players[pSettings.getColor()] = pSettings; | ||||
| 		playersCnt = 2; | ||||
| 	} | ||||
|  | ||||
| 	// 1 team isn't allowed | ||||
| 	if(teamsCnt == 1 && compOnlyPlayersCnt == 0) | ||||
| 	{ | ||||
| 		teamsCnt = 0; | ||||
| 	} | ||||
|  | ||||
| 	if(waterContent == EWaterContent::RANDOM) | ||||
| 	{ | ||||
| 		waterContent = static_cast<EWaterContent::EWaterContent>(gen.getInteger(0, 2)); | ||||
| 	} | ||||
| 	if(monsterStrength == EMonsterStrength::RANDOM) | ||||
| 	{ | ||||
| 		monsterStrength = static_cast<EMonsterStrength::EMonsterStrength>(gen.getInteger(0, 2)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int CMapGenOptions::countHumanPlayers() const | ||||
| { | ||||
| 	return static_cast<int>(boost::count_if(players, [](const std::pair<PlayerColor, CPlayerSettings> & pair) | ||||
| 	{ | ||||
| 		return pair.second.getPlayerType() == EPlayerType::HUMAN; | ||||
| 	})); | ||||
| } | ||||
|  | ||||
| PlayerColor CMapGenOptions::getNextPlayerColor() const | ||||
| { | ||||
| 	for(PlayerColor i = PlayerColor(0); i < PlayerColor::PLAYER_LIMIT; i.advance(1)) | ||||
| 	{ | ||||
| 		if(!players.count(i)) | ||||
| 		{ | ||||
| 			return i; | ||||
| 		} | ||||
| 	} | ||||
| 	throw std::runtime_error("Shouldn't happen. No free player color exists."); | ||||
| } | ||||
|  | ||||
| CMapGenOptions::CPlayerSettings::CPlayerSettings() : color(0), startingTown(RANDOM_TOWN), playerType(EPlayerType::AI) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| PlayerColor CMapGenOptions::CPlayerSettings::getColor() const | ||||
| { | ||||
| 	return color; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::CPlayerSettings::setColor(PlayerColor value) | ||||
| { | ||||
| 	if(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT) | ||||
| 	{ | ||||
| 		color = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("The color of the player is not in a valid range."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| si32 CMapGenOptions::CPlayerSettings::getStartingTown() const | ||||
| { | ||||
| 	return startingTown; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::CPlayerSettings::setStartingTown(si32 value) | ||||
| { | ||||
| 	if(value >= -1 && value < static_cast<int>(VLC->townh->towns.size())) | ||||
| 	{ | ||||
| 		startingTown = value; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("The starting town of the player is not in a valid range."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| EPlayerType::EPlayerType CMapGenOptions::CPlayerSettings::getPlayerType() const | ||||
| { | ||||
| 	return playerType; | ||||
| } | ||||
|  | ||||
| void CMapGenOptions::CPlayerSettings::setPlayerType(EPlayerType::EPlayerType value) | ||||
| { | ||||
| 	playerType = value; | ||||
| } | ||||
|  | ||||
| CMapGenerator::CMapGenerator(const CMapGenOptions & mapGenOptions, int randomSeed) : | ||||
| 	mapGenOptions(mapGenOptions), randomSeed(randomSeed) | ||||
| { | ||||
|   | ||||
| @@ -12,13 +12,159 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "../GameConstants.h" | ||||
| #include "CMapGenOptions.h" | ||||
| #include "../CRandomGenerator.h" | ||||
|  | ||||
| class CMap; | ||||
| class CTerrainViewPatternConfig; | ||||
| class CMapEditManager; | ||||
|  | ||||
| namespace EWaterContent | ||||
| { | ||||
| enum EWaterContent | ||||
| { | ||||
| 	RANDOM = -1, | ||||
| 	NONE, | ||||
| 	NORMAL, | ||||
| 	ISLANDS | ||||
| }; | ||||
| } | ||||
|  | ||||
| namespace EMonsterStrength | ||||
| { | ||||
| enum EMonsterStrength | ||||
| { | ||||
| 	RANDOM = -1, | ||||
| 	WEAK, | ||||
| 	NORMAL, | ||||
| 	STRONG | ||||
| }; | ||||
| } | ||||
|  | ||||
| namespace EPlayerType | ||||
| { | ||||
| enum EPlayerType | ||||
| { | ||||
| 	HUMAN, | ||||
| 	AI, | ||||
| 	COMP_ONLY | ||||
| }; | ||||
| } | ||||
|  | ||||
| /// The map gen options class holds values about general map generation settings | ||||
| /// e.g. the size of the map, the count of players,... | ||||
| class DLL_LINKAGE CMapGenOptions | ||||
| { | ||||
| public: | ||||
| 	/// The player settings class maps the player color, starting town and human player flag. | ||||
| 	class CPlayerSettings | ||||
| 	{ | ||||
| 	public: | ||||
| 		CPlayerSettings(); | ||||
|  | ||||
| 		/// The color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1. | ||||
| 		/// The default value is 0. | ||||
| 		PlayerColor getColor() const; | ||||
| 		void setColor(PlayerColor value); | ||||
|  | ||||
| 		/// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN. | ||||
| 		/// The default value is RANDOM_TOWN. | ||||
| 		si32 getStartingTown() const; | ||||
| 		void setStartingTown(si32 value); | ||||
|  | ||||
| 		/// The default value is EPlayerType::AI. | ||||
| 		EPlayerType::EPlayerType getPlayerType() const; | ||||
| 		void setPlayerType(EPlayerType::EPlayerType value); | ||||
|  | ||||
| 		/// Constant for a random town selection. | ||||
| 		static const si32 RANDOM_TOWN = -1; | ||||
|  | ||||
| 	private: | ||||
| 		PlayerColor color; | ||||
| 		si32 startingTown; | ||||
| 		EPlayerType::EPlayerType playerType; | ||||
|  | ||||
| 	public: | ||||
| 		template <typename Handler> | ||||
| 		void serialize(Handler & h, const int version) | ||||
| 		{ | ||||
| 			h & color & startingTown & playerType; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	CMapGenOptions(); | ||||
|  | ||||
| 	si32 getWidth() const; | ||||
| 	void setWidth(si32 value); | ||||
|  | ||||
| 	si32 getHeight() const; | ||||
| 	void setHeight(si32 value); | ||||
|  | ||||
| 	bool getHasTwoLevels() const; | ||||
| 	void setHasTwoLevels(bool value); | ||||
|  | ||||
| 	/// The count of the players ranging from 1 to PlayerColor::PLAYER_LIMIT or RANDOM_SIZE for random. If you call | ||||
| 	/// this method, all player settings are reset to default settings. | ||||
| 	si8 getPlayersCnt() const; | ||||
| 	void setPlayersCnt(si8 value); | ||||
|  | ||||
| 	/// The count of the teams ranging from 0 to <players count - 1> or RANDOM_SIZE for random. | ||||
| 	si8 getTeamsCnt() const; | ||||
| 	void setTeamsCnt(si8 value); | ||||
|  | ||||
| 	/// The count of the computer only players ranging from 0 to <PlayerColor::PLAYER_LIMIT - players count> or RANDOM_SIZE for random. | ||||
| 	/// If you call this method, all player settings are reset to default settings. | ||||
| 	si8 getCompOnlyPlayersCnt() const; | ||||
| 	void setCompOnlyPlayersCnt(si8 value); | ||||
|  | ||||
| 	/// The count of the computer only teams ranging from 0 to <comp only players - 1> or RANDOM_SIZE for random. | ||||
| 	si8 getCompOnlyTeamsCnt() const; | ||||
| 	void setCompOnlyTeamsCnt(si8 value); | ||||
|  | ||||
| 	EWaterContent::EWaterContent getWaterContent() const; | ||||
| 	void setWaterContent(EWaterContent::EWaterContent value); | ||||
|  | ||||
| 	EMonsterStrength::EMonsterStrength getMonsterStrength() const; | ||||
| 	void setMonsterStrength(EMonsterStrength::EMonsterStrength value); | ||||
|  | ||||
| 	/// The first player colors belong to standard players and the last player colors belong to comp only players. | ||||
| 	/// All standard players are by default of type EPlayerType::AI. | ||||
| 	const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const; | ||||
| 	void setStartingTownForPlayer(PlayerColor color, si32 town); | ||||
| 	/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The | ||||
| 	/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN. Calling this method | ||||
| 	/// has no effect for the map itself, but it adds some informational text for the map description. | ||||
| 	void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType); | ||||
|  | ||||
| 	/// Finalizes the options. All random sizes for various properties will be overwritten by numbers from | ||||
| 	/// a random number generator by keeping the options in a valid state. | ||||
| 	void finalize(); | ||||
| 	void finalize(CRandomGenerator & gen); | ||||
|  | ||||
| 	static const si8 RANDOM_SIZE = -1; | ||||
|  | ||||
| private: | ||||
| 	void resetPlayersMap(); | ||||
| 	int countHumanPlayers() const; | ||||
| 	PlayerColor getNextPlayerColor() const; | ||||
|  | ||||
| 	si32 width, height; | ||||
| 	bool hasTwoLevels; | ||||
| 	si8 playersCnt, teamsCnt, compOnlyPlayersCnt, compOnlyTeamsCnt; | ||||
| 	EWaterContent::EWaterContent waterContent; | ||||
| 	EMonsterStrength::EMonsterStrength monsterStrength; | ||||
| 	std::map<PlayerColor, CPlayerSettings> players; | ||||
|  | ||||
| public: | ||||
| 	template <typename Handler> | ||||
| 	void serialize(Handler & h, const int version) | ||||
| 	{ | ||||
| 		//FIXME: Enum is not a fixed with data type. Add enum class to both enums | ||||
| 		// later. For now it is ok. | ||||
| 		h & width & height & hasTwoLevels & playersCnt & teamsCnt & compOnlyPlayersCnt; | ||||
| 		h & compOnlyTeamsCnt & waterContent & monsterStrength & players; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| /// The map generator creates a map randomly. | ||||
| class DLL_LINKAGE CMapGenerator | ||||
| { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user