Browse Source

- Fixed some bugs when starting a RMG map - Checks if there is a template for the chosen options(rejects if not) - Added a few templates for development(2 to 4 players, medium maps are supported) - Refactoring

beegee1 12 years ago
parent
commit
5328beb8e7
10 changed files with 893 additions and 665 deletions
  1. 71 50
      client/CPreGame.cpp
  2. 11 118
      client/CPreGame.h
  3. 135 34
      config/rmg.json
  4. 1 12
      lib/CGameState.cpp
  5. 4 0
      lib/Connection.h
  6. 3 4
      lib/StartInfo.h
  7. 6 3
      lib/mapping/CMapEditManager.cpp
  8. 452 267
      lib/rmg/CMapGenerator.cpp
  9. 209 176
      lib/rmg/CMapGenerator.h
  10. 1 1
      server/CVCMIServer.cpp

+ 71 - 50
client/CPreGame.cpp

@@ -621,7 +621,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
 		opt = new OptionsTab(); //scenario options tab
 		opt->recActions = DISPOSE;
 
-		randMapTab = new RandomMapTab();
+		randMapTab = new CRandomMapTab();
 		randMapTab->getMapInfoChanged() += bind(&CSelectionScreen::changeSelection, this, _1);
 		randMapTab->recActions = DISPOSE;
 	}
@@ -650,7 +650,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
 			randomBtn->callback = [&]()
 			{
 				toggleTab(randMapTab);
-				changeSelection(&randMapTab->getMapInfo());
+				changeSelection(randMapTab->getMapInfo());
 			};
 
 			start  = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startScenario, this), 411, 535, "SCNRBEG.DEF", SDLK_b);
@@ -801,6 +801,7 @@ void CSelectionScreen::toggleTab(CIntObject *tab)
 
 void CSelectionScreen::changeSelection(const CMapInfo * to)
 {
+	if(current == to) return;
 	if(multiPlayer == CMenuScreen::MULTI_NETWORK_GUEST)
 	{
 		vstd::clear_pointer(current);
@@ -814,17 +815,14 @@ void CSelectionScreen::changeSelection(const CMapInfo * to)
 	if(screenType != CMenuScreen::campaignList)
 	{
 		updateStartInfo(to ? to->fileURI : "", sInfo, to ? to->mapHeader.get() : NULL);
-
 		if(screenType == CMenuScreen::newGame)
 		{
 			if(to && to->isRandomMap)
 			{
-				sInfo.createRandomMap = true;
 				sInfo.mapGenOptions = std::shared_ptr<CMapGenOptions>(new CMapGenOptions(randMapTab->getMapGenOptions()));
 			}
 			else
 			{
-				sInfo.createRandomMap = false;
 				sInfo.mapGenOptions.reset();
 			}
 		}
@@ -884,6 +882,26 @@ void CSelectionScreen::startScenario()
 		if(!current)
 			return;
 
+		if(sInfo.mapGenOptions)
+		{
+			// Update player settings for RMG
+			BOOST_FOREACH(const auto & psetPair, sInfo.playerInfos)
+			{
+				const auto & pset = psetPair.second;
+				sInfo.mapGenOptions->setStartingTownForPlayer(pset.color, pset.castle);
+				if(pset.playerID != PlayerSettings::PLAYER_AI)
+				{
+					sInfo.mapGenOptions->setPlayerTypeForStandardPlayer(pset.color, EPlayerType::HUMAN);
+				}
+			}
+
+			if(!sInfo.mapGenOptions->checkOptions())
+			{
+				GH.pushInt(CInfoWindow::create(CGI->generaltexth->allTexts[751]));
+				return;
+			}
+		}
+
 		saveGameName.clear();
 		if(screenType == CMenuScreen::loadGame)
 		{
@@ -1599,7 +1617,7 @@ const CMapInfo * SelectionTab::getSelectedMapInfo() const
 	return curItems.empty() ? nullptr : curItems[selectionPos];
 }
 
-RandomMapTab::RandomMapTab()
+CRandomMapTab::CRandomMapTab()
 {
 	OBJ_CONSTRUCTION;
 	bg = new CPicture("RANMAPBK", 0, 6);
@@ -1623,7 +1641,7 @@ RandomMapTab::RandomMapTab()
 	// Two levels
 	twoLevelsBtn = new CHighlightableButton(0, 0, std::map<int,std::string>(),
 		CGI->generaltexth->zelp[202].second, false, "RANUNDR", nullptr, 346, 81);
-	twoLevelsBtn->select(true);
+	//twoLevelsBtn->select(true); for now, deactivated
 	twoLevelsBtn->callback = [&]() { mapGenOptions.setHasTwoLevels(true); updateMapInfo(); };
 	twoLevelsBtn->callback2 = [&]() { mapGenOptions.setHasTwoLevels(false); updateMapInfo(); };
 
@@ -1643,7 +1661,7 @@ RandomMapTab::RandomMapTab()
 	addButtonsWithRandToGroup(playersCntGroup, numberDefs, 1, 8, NUMBERS_WIDTH, 204, 212);
 	playersCntGroup->onChange = [&](int btnId)
 	{
-		mapGenOptions.setPlayersCnt(btnId);
+		mapGenOptions.setPlayerCount(btnId);
 		deactivateButtonsFrom(teamsCntGroup, btnId);
 		deactivateButtonsFrom(compOnlyPlayersCntGroup, 8 - btnId + 1);
 		validatePlayersCnt(btnId);
@@ -1657,7 +1675,7 @@ RandomMapTab::RandomMapTab()
 	addButtonsWithRandToGroup(teamsCntGroup, numberDefs, 0, 7, NUMBERS_WIDTH, 214, 222);
 	teamsCntGroup->onChange = [&](int btnId)
 	{
-		mapGenOptions.setTeamsCnt(btnId);
+		mapGenOptions.setTeamCount(btnId);
 		updateMapInfo();
 	};
 
@@ -1669,7 +1687,7 @@ RandomMapTab::RandomMapTab()
 	compOnlyPlayersCntGroup->select(0, true);
 	compOnlyPlayersCntGroup->onChange = [&](int btnId)
 	{
-		mapGenOptions.setCompOnlyPlayersCnt(btnId);
+		mapGenOptions.setCompOnlyPlayerCount(btnId);
 		deactivateButtonsFrom(compOnlyTeamsCntGroup, btnId);
 		validateCompOnlyPlayersCnt(btnId);
 		updateMapInfo();
@@ -1683,7 +1701,7 @@ RandomMapTab::RandomMapTab()
 	deactivateButtonsFrom(compOnlyTeamsCntGroup, 0);
 	compOnlyTeamsCntGroup->onChange = [&](int btnId)
 	{
-		mapGenOptions.setCompOnlyTeamsCnt(btnId);
+		mapGenOptions.setCompOnlyTeamCount(btnId);
 		updateMapInfo();
 	};
 
@@ -1714,17 +1732,10 @@ RandomMapTab::RandomMapTab()
 	showRandMaps = new CAdventureMapButton("", CGI->generaltexth->zelp[252].second, 0, 54, 535, "RANSHOW");
 
 	// Initialize map info object
-	mapInfo.isRandomMap = true;
-	shared_ptr<CMapHeader> mapHeader(new CMapHeader());
-	mapHeader->version = EMapFormat::SOD;
-	mapHeader->name = CGI->generaltexth->allTexts[740];
-	mapHeader->description = CGI->generaltexth->allTexts[741];
-	mapHeader->difficulty = 1; // Normal
-	mapInfo.mapHeader = mapHeader;
 	updateMapInfo();
 }
 
-void RandomMapTab::addButtonsWithRandToGroup(CHighlightableButtonsGroup * group, const std::vector<std::string> & defs, int nStart, int nEnd, int btnWidth, int helpStartIndex, int helpRandIndex) const
+void CRandomMapTab::addButtonsWithRandToGroup(CHighlightableButtonsGroup * group, const std::vector<std::string> & defs, int nStart, int nEnd, int btnWidth, int helpStartIndex, int helpRandIndex) const
 {
 	addButtonsToGroup(group, defs, nStart, nEnd, btnWidth, helpStartIndex);
 
@@ -1735,7 +1746,7 @@ void RandomMapTab::addButtonsWithRandToGroup(CHighlightableButtonsGroup * group,
 	group->select(CMapGenOptions::RANDOM_SIZE, true);
 }
 
-void RandomMapTab::addButtonsToGroup(CHighlightableButtonsGroup * group, const std::vector<std::string> & defs, int nStart, int nEnd, int btnWidth, int helpStartIndex) const
+void CRandomMapTab::addButtonsToGroup(CHighlightableButtonsGroup * group, const std::vector<std::string> & defs, int nStart, int nEnd, int btnWidth, int helpStartIndex) const
 {
 	// Buttons are relative to button group, TODO better solution?
 	SObjectConstruction obj__i(group);
@@ -1746,7 +1757,7 @@ void RandomMapTab::addButtonsToGroup(CHighlightableButtonsGroup * group, const s
 	}
 }
 
-void RandomMapTab::deactivateButtonsFrom(CHighlightableButtonsGroup * group, int startId)
+void CRandomMapTab::deactivateButtonsFrom(CHighlightableButtonsGroup * group, int startId)
 {
 	BOOST_FOREACH(CHighlightableButton * btn, group->buttons)
 	{
@@ -1767,42 +1778,42 @@ void RandomMapTab::deactivateButtonsFrom(CHighlightableButtonsGroup * group, int
 	}
 }
 
-void RandomMapTab::validatePlayersCnt(int playersCnt)
+void CRandomMapTab::validatePlayersCnt(int playersCnt)
 {
 	if(playersCnt == CMapGenOptions::RANDOM_SIZE)
 	{
 		return;
 	}
 
-	if(mapGenOptions.getTeamsCnt() >= playersCnt)
+	if(mapGenOptions.getTeamCount() >= playersCnt)
 	{
-		mapGenOptions.setTeamsCnt(playersCnt - 1);
-		teamsCntGroup->select(mapGenOptions.getTeamsCnt(), true);
+		mapGenOptions.setTeamCount(playersCnt - 1);
+		teamsCntGroup->select(mapGenOptions.getTeamCount(), true);
 	}
-	if(mapGenOptions.getCompOnlyPlayersCnt() > 8 - playersCnt)
+	if(mapGenOptions.getCompOnlyPlayerCount() > 8 - playersCnt)
 	{
-		mapGenOptions.setCompOnlyPlayersCnt(8 - playersCnt);
-		compOnlyPlayersCntGroup->select(mapGenOptions.getCompOnlyPlayersCnt(), true);
+		mapGenOptions.setCompOnlyPlayerCount(8 - playersCnt);
+		compOnlyPlayersCntGroup->select(mapGenOptions.getCompOnlyPlayerCount(), true);
 	}
 
-	validateCompOnlyPlayersCnt(mapGenOptions.getCompOnlyPlayersCnt());
+	validateCompOnlyPlayersCnt(mapGenOptions.getCompOnlyPlayerCount());
 }
 
-void RandomMapTab::validateCompOnlyPlayersCnt(int compOnlyPlayersCnt)
+void CRandomMapTab::validateCompOnlyPlayersCnt(int compOnlyPlayersCnt)
 {
 	if(compOnlyPlayersCnt == CMapGenOptions::RANDOM_SIZE)
 	{
 		return;
 	}
 
-	if(mapGenOptions.getCompOnlyTeamsCnt() >= compOnlyPlayersCnt)
+	if(mapGenOptions.getCompOnlyTeamCount() >= compOnlyPlayersCnt)
 	{
-		mapGenOptions.setCompOnlyTeamsCnt(compOnlyPlayersCnt - 1);
-		compOnlyTeamsCntGroup->select(mapGenOptions.getCompOnlyTeamsCnt(), true);
+		mapGenOptions.setCompOnlyTeamCount(compOnlyPlayersCnt - 1);
+		compOnlyTeamsCntGroup->select(mapGenOptions.getCompOnlyTeamCount(), true);
 	}
 }
 
-void RandomMapTab::showAll(SDL_Surface * to)
+void CRandomMapTab::showAll(SDL_Surface * to)
 {
 	CIntObject::showAll(to);
 
@@ -1832,24 +1843,34 @@ void RandomMapTab::showAll(SDL_Surface * to)
 	printAtLoc(CGI->generaltexth->allTexts[758], 68, 465, FONT_SMALL, Colors::WHITE, to);
 }
 
-void RandomMapTab::updateMapInfo()
+void CRandomMapTab::updateMapInfo()
 {
-	mapInfo.mapHeader->height = mapGenOptions.getHeight();
-	mapInfo.mapHeader->width = mapGenOptions.getWidth();
-	mapInfo.mapHeader->twoLevel = mapGenOptions.getHasTwoLevels();
+	// Generate header info
+	mapInfo = make_unique<CMapInfo>();
+	mapInfo->isRandomMap = true;
+	auto mapHeader = std::make_shared<CMapHeader>();
+	mapHeader->version = EMapFormat::SOD;
+	mapHeader->name = CGI->generaltexth->allTexts[740];
+	mapHeader->description = CGI->generaltexth->allTexts[741];
+	mapHeader->difficulty = 1; // Normal
+	mapInfo->mapHeader = mapHeader;
+	mapInfo->mapHeader->height = mapGenOptions.getHeight();
+	mapInfo->mapHeader->width = mapGenOptions.getWidth();
+	mapInfo->mapHeader->twoLevel = mapGenOptions.getHasTwoLevels();
 
 	// Generate player information
-	mapInfo.mapHeader->players.clear();
-	int playersToGen = (mapGenOptions.getPlayersCnt() == CMapGenOptions::RANDOM_SIZE
-		|| mapGenOptions.getCompOnlyPlayersCnt() == CMapGenOptions::RANDOM_SIZE)
-			? 8 : mapGenOptions.getPlayersCnt() + mapGenOptions.getCompOnlyPlayersCnt();
-	mapInfo.mapHeader->howManyTeams = playersToGen;
+	mapInfo->mapHeader->players.clear();
+	int playersToGen = (mapGenOptions.getPlayerCount() == CMapGenOptions::RANDOM_SIZE
+		|| mapGenOptions.getCompOnlyPlayerCount() == CMapGenOptions::RANDOM_SIZE)
+			? 8 : mapGenOptions.getPlayerCount() + mapGenOptions.getCompOnlyPlayerCount();
+	mapInfo->mapHeader->howManyTeams = playersToGen;
 
 	for(int i = 0; i < playersToGen; ++i)
 	{
 		PlayerInfo player;
+		player.isFactionRandom = true;
 		player.canComputerPlay = true;
-		if(i >= mapGenOptions.getPlayersCnt() && mapGenOptions.getPlayersCnt() != CMapGenOptions::RANDOM_SIZE)
+		if(i >= mapGenOptions.getPlayerCount() && mapGenOptions.getPlayerCount() != CMapGenOptions::RANDOM_SIZE)
 		{
 			player.canHumanPlay = false;
 		}
@@ -1860,23 +1881,23 @@ void RandomMapTab::updateMapInfo()
 		player.team = TeamID(i);
 		player.hasMainTown = true;
 		player.generateHeroAtMainTown = true;
-		mapInfo.mapHeader->players.push_back(player);
+		mapInfo->mapHeader->players.push_back(player);
 	}
 
-	mapInfoChanged(&mapInfo);
+	mapInfoChanged(mapInfo.get());
 }
 
-CFunctionList<void(const CMapInfo *)> & RandomMapTab::getMapInfoChanged()
+CFunctionList<void(const CMapInfo *)> & CRandomMapTab::getMapInfoChanged()
 {
 	return mapInfoChanged;
 }
 
-const CMapInfo & RandomMapTab::getMapInfo() const
+const CMapInfo * CRandomMapTab::getMapInfo() const
 {
-	return mapInfo;
+	return mapInfo.get();
 }
 
-const CMapGenOptions & RandomMapTab::getMapGenOptions() const
+const CMapGenOptions & CRandomMapTab::getMapGenOptions() const
 {
 	return mapGenOptions;
 }

+ 11 - 118
client/CPreGame.h

@@ -29,7 +29,7 @@ class CCampaignState;
 class CConnection;
 class JsonNode;
 class CMapGenOptions;
-class RandomMapTab;
+class CRandomMapTab;
 struct CPackForSelectionScreen;
 struct PlayerInfo;
 
@@ -282,139 +282,32 @@ public:
 	bool canUseThisHero(PlayerColor player, int ID );
 };
 
-/**
- * The random map tab shows options for generating a random map.
- */
-class RandomMapTab : public CIntObject
+/// The random map tab shows options for generating a random map.
+class CRandomMapTab : public CIntObject
 {
 public:
-    /**
-     * C-tor.
-     */
-    RandomMapTab();
-
-    /**
-     * Shows the interface and the visual representation of this tab.
-     *
-     * @param to where the graphics should be inserted
-     */
-    void showAll(SDL_Surface * to);
+	CRandomMapTab();
 
-	/**
-	 * Updates the map info object and fires the associated callback method.
-	 */
+    void showAll(SDL_Surface * to);
 	void updateMapInfo();
-
-	/**
-	 * Gets the map info changed callback method list object. This event
-	 * occurs when the updateMapInfo method has been called or the options
-	 * of this tab have been changed.
-	 *
-	 * @return the map info changed callback method list object
-	 */
 	CFunctionList<void (const CMapInfo *)> & getMapInfoChanged();
-
-	/**
-	 * Gets the created map info object.
-	 *
-	 * @return the created map info object
-	 */
-	const CMapInfo & getMapInfo() const;
-
-	/**
-	 * Gets the map generation options.
-	 *
-	 * @return the map generation options
-	 */
+	const CMapInfo * getMapInfo() const;
 	const CMapGenOptions & getMapGenOptions() const;
 
 private:
-    /**
-     * Adds buttons specified by the defs list to the given buttons group.
-     *
-     * @param group the button group where the buttons should be added to
-     * @param defs the names of the button defs
-     * @param startIndex start index of the defs vector
-     * @param endIndex end index of the defs vector
-     * @param btnWidth width of one button(fixed width)
-     * @param helpStartIndex the index of the first help msg entry
-     */
     void addButtonsToGroup(CHighlightableButtonsGroup * group, const std::vector<std::string> & defs, int startIndex, int endIndex, int btnWidth, int helpStartIndex) const;
-
-    /**
-     * Adds buttons specified by the defs list and the random button to the given buttons group. Auto-selects the
-     * random button.
-     *
-     * @param group the button group where the buttons should be added to
-     * @param defs the names of the button defs
-     * @param startIndex start index of the defs vector
-     * @param endIndex end index of the defs vector
-     * @param btnWidth width of one button(fixed width)
-     * @param helpStartIndex the index of the first help msg entry
-     * @param helpRandIndex the index of the random help msg entry
-     */
     void addButtonsWithRandToGroup(CHighlightableButtonsGroup * group, const std::vector<std::string> & defs, int startIndex, int endIndex, int btnWidth, int helpStartIndex, int helpRandIndex) const;
-
-    /**
-     * Deactives buttons of a highlightable button group beginning from startId. Buttons with a id
-     * lower than startId will be activated/reseted.
-     *
-     * @param group the associated highlightable button group
-     * @param startId the id of the first button to deactivate
-     */
     void deactivateButtonsFrom(CHighlightableButtonsGroup * group, int startId);
-
-    /**
-     * Validates players count and updates teams count, comp only players/teams count if necessary.
-     *
-     * @param playersCnt the players count to validate
-     */
     void validatePlayersCnt(int playersCnt);
-
-    /**
-     * Validates computer only players count and updates comp only teams count if necessary.
-     *
-     * @param compOnlyPlayersCnt the computer only players count to validate
-     */
     void validateCompOnlyPlayersCnt(int compOnlyPlayersCnt);
 
-    /** the background image of the rmg options tab */
     CPicture * bg;
-
-    /** the map size buttons group */
-    CHighlightableButtonsGroup * mapSizeBtnGroup;
-
-    /** the two levels highlightable button */
-    CHighlightableButton * twoLevelsBtn;
-
-    /** the players count group */
-    CHighlightableButtonsGroup * playersCntGroup;
-
-    /** the teams count group */
-    CHighlightableButtonsGroup * teamsCntGroup;
-
-    /** the computer only players count group */
-    CHighlightableButtonsGroup * compOnlyPlayersCntGroup;
-
-    /** the computer only teams count group */
-    CHighlightableButtonsGroup * compOnlyTeamsCntGroup;
-
-    /** the water content group */
-    CHighlightableButtonsGroup * waterContentGroup;
-
-    /** the monster strength group */
-    CHighlightableButtonsGroup * monsterStrengthGroup;
-
-	/** show previously created random maps button */
+	CHighlightableButton * twoLevelsBtn;
+	CHighlightableButtonsGroup * mapSizeBtnGroup, * playersCntGroup, * teamsCntGroup, * compOnlyPlayersCntGroup,
+		* compOnlyTeamsCntGroup, * waterContentGroup, * monsterStrengthGroup;
     CAdventureMapButton * showRandMaps;
-
-    /** the map options selected by the user */
 	CMapGenOptions mapGenOptions;
-
-	/** map info object describing a randomly created map */
-	CMapInfo mapInfo;
-
-	/** callback method which gets called when the random options have been changed */
+	unique_ptr<CMapInfo> mapInfo;
 	CFunctionList<void(const CMapInfo *)> mapInfoChanged;
 };
 
@@ -452,7 +345,7 @@ public:
 	CPicture *bg; //general bg image
 	InfoCard *card;
 	OptionsTab *opt;
-    RandomMapTab * randMapTab;
+	CRandomMapTab * randMapTab;
 	CAdventureMapButton *start, *back;
 
 	SelectionTab *sel;

+ 135 - 34
config/rmg.json

@@ -1,66 +1,167 @@
 // Defines random map templates.
 {
-	"Small Ring" : 
+	"Analogy" : 
 	{
-		"minSize" : "s", "maxSize" : "s+u",
-		"minHumanCnt" : 1, "maxHumanCnt" : 8, "minTotalCnt" : 2, "maxTotalCnt" : 8,
+		"minSize" : "m", "maxSize" : "m",
+		"players" : "4",
 		"zones" :
 		{
 			"1" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 1,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "playerStart", "size" : 1, "owner" : 1,
+				"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
 			},
 			"2" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 2,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "playerStart", "size" : 1, "owner" : 2,
+				"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
 			},
 			"3" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 3,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "playerStart", "size" : 1, "owner" : 3,
+				"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
 			},
 			"4" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 4,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "playerStart", "size" : 1, "owner" : 4,
+				"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
 			},
 			"5" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 5,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "treasure", "size" : 2, "terrainTypes" : [ "sand" ], "neutralTowns" : { "castles" : 1 }
+			}
+		},
+		"connections" :
+		[
+			{ "a" : "1", "b" : "5", "guard" : 1000 },
+			{ "a" : "2", "b" : "5", "guard" : 1000 },
+			{ "a" : "3", "b" : "5", "guard" : 1000 },
+			{ "a" : "4", "b" : "5", "guard" : 1000 }
+		]
+	},
+	"Upgrade" :
+	{
+		"minSize" : "m", "maxSize" : "m",
+		"players" : "2",
+		"zones" :
+		{
+			"1" :
+			{
+				"type" : "playerStart", "size" : 1, "owner" : 1,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"2" :
+			{
+				"type" : "playerStart", "size" : 1, "owner" : 2,
+				"playerTowns" : { "castles" : 1 }
 			},
-			"6" :
+			"3" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 6,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : "1"
 			},
-			"7" :
+			"4" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 7,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : "2"
 			},
-			"8" :
+			"5" :
 			{
-				"type" : "humanStart", "baseSize" : 11, "owner" : 8,
-				"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
+				"type" : "treasure", "size" : 3, "neutralTowns" : { "castles" : 1 }, "terrainTypes" : [ "sand" ]
 			}
 		},
 		"connections" :
 		[
-			{ "a" : "1", "b" : "2", "guardStrength" : 4500 },
-			{ "a" : "2", "b" : "3", "guardStrength" : 4500 },
-			{ "a" : "3", "b" : "4", "guardStrength" : 4500 },
-			{ "a" : "4", "b" : "5", "guardStrength" : 4500 },
-			{ "a" : "5", "b" : "6", "guardStrength" : 4500 },
-			{ "a" : "6", "b" : "7", "guardStrength" : 4500 },
-			{ "a" : "7", "b" : "8", "guardStrength" : 4500 },
-			{ "a" : "8", "b" : "1", "guardStrength" : 4500 },
-			{ "a" : "4", "b" : "1", "guardStrength" : 4500 },
-			{ "a" : "5", "b" : "1", "guardStrength" : 4500 },
-			{ "a" : "6", "b" : "1", "guardStrength" : 4500 },
-			{ "a" : "7", "b" : "1", "guardStrength" : 4500 }
+			{ "a" : "1", "b" : "3", "guard" : 1000 },
+			{ "a" : "1", "b" : "5", "guard" : 4000 },
+			{ "a" : "2", "b" : "4", "guard" : 1000 },
+			{ "a" : "2", "b" : "5", "guard" : 4000 },
+			{ "a" : "3", "b" : "5", "guard" : 2000 },
+			{ "a" : "4", "b" : "5", "guard" : 2000 }
+		]
+	},
+	"Golden Ring" :
+	{
+		"minSize" : "m", "maxSize" : "m",
+		"players" : "3",
+		"zones" :
+		{
+			"1" :
+			{
+				"type" : "playerStart", "size" : 3, "owner" : 1,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"2" :
+			{
+				"type" : "playerStart", "size" : 3, "owner" : 2,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"3" :
+			{
+				"type" : "playerStart", "size" : 3, "owner" : 3,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"4" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "1" },
+			"5" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "1" },
+			"6" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "2" },
+			"7" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "2" },
+			"8" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "3" },
+			"9" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "3" },
+			"10" : { "type" : "treasure", "size" : 1, "neutralTowns" : { "towns" : 1 } },
+			"11" : { "type" : "treasure", "size" : 1, "neutralTowns" : { "towns" : 1 } },
+			"12" : { "type" : "treasure", "size" : 1, "neutralTowns" : { "towns" : 1 } }
+		},
+		"connections" :
+		[
+			{ "a" : "1", "b" : "4", "guard" : 1000 },
+			{ "a" : "1", "b" : "5", "guard" : 1000 },
+			{ "a" : "2", "b" : "6", "guard" : 1000 },
+			{ "a" : "2", "b" : "7", "guard" : 1000 },
+			{ "a" : "3", "b" : "8", "guard" : 1000 },
+			{ "a" : "3", "b" : "9", "guard" : 1000 },
+			{ "a" : "4", "b" : "10", "guard" : 1000 },
+			{ "a" : "5", "b" : "12", "guard" : 1000 },
+			{ "a" : "6", "b" : "10", "guard" : 1000 },
+			{ "a" : "7", "b" : "11", "guard" : 1000 },
+			{ "a" : "8", "b" : "12", "guard" : 1000 },
+			{ "a" : "9", "b" : "11", "guard" : 1000 }
+		]
+	},
+	"Unfair Game" :
+	{
+		"minSize" : "m", "maxSize" : "m",
+		"players" : "2", "cpu" : "2",
+		"zones" :
+		{
+			"1" :
+			{
+				"type" : "playerStart", "size" : 2, "owner" : 1,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"2" :
+			{
+				"type" : "playerStart", "size" : 2, "owner" : 2,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"3" :
+			{
+				"type" : "cpuStart", "size" : 3, "owner" : 3,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"4" :
+			{
+				"type" : "cpuStart", "size" : 3, "owner" : 4,
+				"playerTowns" : { "castles" : 1 }
+			},
+			"5" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "3" },
+			"6" : { "type" : "treasure", "size" : 1, "terrainTypeLikeZone" : "4" }
+		},
+		"connections" :
+		[
+			{ "a" : "1", "b" : "3", "guard" : 2000 },
+			{ "a" : "1", "b" : "4", "guard" : 2000 },
+			{ "a" : "2", "b" : "3", "guard" : 2000 },
+			{ "a" : "2", "b" : "4", "guard" : 2000 },
+			{ "a" : "3", "b" : "5", "guard" : 1000 },
+			{ "a" : "4", "b" : "6", "guard" : 1000 }
 		]
 	}
 }

+ 1 - 12
lib/CGameState.cpp

@@ -862,22 +862,11 @@ void CGameState::init(StartInfo * si)
 	{
 	case StartInfo::NEW_GAME:
 		{
-			if(scenarioOps->createRandomMap)
+			if(scenarioOps->createRandomMap())
 			{
                 logGlobal->infoStream() << "Create random map.";
 				CStopWatch sw;
 
-				// Create player settings for RMG
-                BOOST_FOREACH(const auto & pair, scenarioOps->playerInfos)
-				{
-                    const auto & playerSettings = pair.second;
-                    scenarioOps->mapGenOptions->setStartingTownForPlayer(playerSettings.color, playerSettings.castle);
-                    if(playerSettings.playerID > 0)
-					{
-                        scenarioOps->mapGenOptions->setPlayerTypeForStandardPlayer(playerSettings.color, EPlayerType::HUMAN);
-					}
-				}
-
 				// Gen map
                 CMapGenerator mapGen(*(scenarioOps->mapGenOptions), scenarioOps->seedToBeUsed);
 				map = mapGen.generate().release();

+ 4 - 0
lib/Connection.h

@@ -1081,6 +1081,7 @@ public:
 	void loadSerializable(std::set<T> &data)
 	{
 		READ_CHECK_U32(length);
+        data.clear();
 		T ins;
 		for(ui32 i=0;i<length;i++)
 		{
@@ -1092,6 +1093,7 @@ public:
 	void loadSerializable(boost::unordered_set<T, U> &data)
 	{
 		READ_CHECK_U32(length);
+        data.clear();
 		T ins;
 		for(ui32 i=0;i<length;i++)
 		{
@@ -1103,6 +1105,7 @@ public:
 	void loadSerializable(std::list<T> &data)
 	{
 		READ_CHECK_U32(length);
+        data.clear();
 		T ins;
 		for(ui32 i=0;i<length;i++)
 		{
@@ -1120,6 +1123,7 @@ public:
 	void loadSerializable(std::map<T1,T2> &data)
 	{
 		READ_CHECK_U32(length);
+        data.clear();
 		T1 t;
 		for(ui32 i=0;i<length;i++)
 		{

+ 3 - 4
lib/StartInfo.h

@@ -81,8 +81,8 @@ struct StartInfo
 	ui32 mapfileChecksum; //0 if not relevant
 	ui8 turnTime; //in minutes, 0=unlimited
 	std::string mapname; // empty for random map, otherwise name of the map or savegame
-	bool createRandomMap; // true if a random map should be created
-	shared_ptr<CMapGenOptions> mapGenOptions; // needs to be not nullptr if createRandomMap=true
+	bool createRandomMap() const { return mapGenOptions.get() != nullptr; }
+	shared_ptr<CMapGenOptions> mapGenOptions;
 
 	shared_ptr<CCampaignState> campState;
 
@@ -113,13 +113,12 @@ struct StartInfo
 		h & mapfileChecksum;
 		h & turnTime;
 		h & mapname;
-		h & createRandomMap;
 		h & mapGenOptions;
 		h & campState;
 	}
 
 	StartInfo() : mode(INVALID), difficulty(0), seedToBeUsed(0), seedPostInit(0),
-		mapfileChecksum(0), turnTime(0), createRandomMap(false)
+		mapfileChecksum(0), turnTime(0)
 	{
 
 	}

+ 6 - 3
lib/mapping/CMapEditManager.cpp

@@ -897,9 +897,12 @@ CClearTerrainOperation::CClearTerrainOperation(CMap * map, CRandomGenerator * ge
 	CTerrainSelection terrainSel(map);
 	terrainSel.selectRange(MapRect(int3(0, 0, 0), map->width, map->height));
 	addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::WATER, gen));
-	terrainSel.clearSelection();
-	terrainSel.selectRange(MapRect(int3(0, 0, 1), map->width, map->height));
-	addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::ROCK, gen));
+	if(map->twoLevel)
+	{
+		terrainSel.clearSelection();
+		terrainSel.selectRange(MapRect(int3(0, 0, 1), map->width, map->height));
+		addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::ROCK, gen));
+	}
 }
 
 std::string CClearTerrainOperation::getLabel() const

File diff suppressed because it is too large
+ 452 - 267
lib/rmg/CMapGenerator.cpp


+ 209 - 176
lib/rmg/CMapGenerator.h

@@ -19,6 +19,166 @@ class CTerrainViewPatternConfig;
 class CMapEditManager;
 class JsonNode;
 
+typedef std::vector<JsonNode> JsonVector;
+
+namespace ETemplateZoneType
+{
+enum ETemplateZoneType
+{
+	PLAYER_START,
+	CPU_START,
+	TREASURE,
+	JUNCTION
+};
+}
+
+typedef int TRmgTemplateZoneId;
+
+/// The CRmgTemplateZone describes a zone in a template.
+class DLL_LINKAGE CRmgTemplateZone
+{
+public:
+	class DLL_LINKAGE CTownInfo
+	{
+	public:
+		CTownInfo();
+
+		int getTownCount() const; /// Default: 0
+		void setTownCount(int value);
+		int getCastleCount() const; /// Default: 0
+		void setCastleCount(int value);
+		int getTownDensity() const; /// Default: 0
+		void setTownDensity(int value);
+		int getCastleDensity() const; /// Default: 0
+		void setCastleDensity(int value);
+
+	private:
+		int townCount, castleCount, townDensity, castleDensity;
+	};
+
+	CRmgTemplateZone();
+
+	TRmgTemplateZoneId getId() const; /// Default: 0
+	void setId(TRmgTemplateZoneId value);
+	ETemplateZoneType::ETemplateZoneType getType() const; /// Default: ETemplateZoneType::PLAYER_START
+	void setType(ETemplateZoneType::ETemplateZoneType value);
+	int getSize() const; /// Default: 1
+	void setSize(int value);
+	boost::optional<int> getOwner() const;
+	void setOwner(boost::optional<int> value);
+	const CTownInfo & getPlayerTowns() const;
+	void setPlayerTowns(const CTownInfo & value);
+	const CTownInfo & getNeutralTowns() const;
+	void setNeutralTowns(const CTownInfo & value);
+	bool getTownsAreSameType() const; /// Default: false
+	void setTownsAreSameType(bool value);
+	const std::set<TFaction> & getTownTypes() const; /// Default: all
+	void setTownTypes(const std::set<TFaction> & value);
+	std::set<TFaction> getDefaultTownTypes() const;
+	bool getMatchTerrainToTown() const; /// Default: true
+	void setMatchTerrainToTown(bool value);
+	const std::set<ETerrainType> & getTerrainTypes() const; /// Default: all
+	void setTerrainTypes(const std::set<ETerrainType> & value);
+	std::set<ETerrainType> getDefaultTerrainTypes() const;
+	boost::optional<TRmgTemplateZoneId> getTerrainTypeLikeZone() const;
+	void setTerrainTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
+	boost::optional<TRmgTemplateZoneId> getTownTypeLikeZone() const;
+	void setTownTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
+
+private:
+	TRmgTemplateZoneId id;
+	ETemplateZoneType::ETemplateZoneType type;
+	int size;
+	boost::optional<int> owner;
+	CTownInfo playerTowns, neutralTowns;
+	bool townsAreSameType;
+	std::set<TFaction> townTypes;
+	bool matchTerrainToTown;
+	std::set<ETerrainType> terrainTypes;
+	boost::optional<TRmgTemplateZoneId> terrainTypeLikeZone, townTypeLikeZone;
+};
+
+/// The CRmgTemplateZoneConnection describes the connection between two zones.
+class DLL_LINKAGE CRmgTemplateZoneConnection
+{
+public:
+	CRmgTemplateZoneConnection();
+
+	TRmgTemplateZoneId getZoneA() const; /// Default: 0
+	void setZoneA(TRmgTemplateZoneId value);
+	TRmgTemplateZoneId getZoneB() const; /// Default: 0
+	void setZoneB(TRmgTemplateZoneId value);
+	int getGuardStrength() const; /// Default: 0
+	void setGuardStrength(int value);
+
+private:
+	TRmgTemplateZoneId zoneA, zoneB;
+	int guardStrength;
+};
+
+/// The CRmgTemplate describes a random map template.
+class DLL_LINKAGE CRmgTemplate
+{
+public:
+	class CSize
+	{
+	public:
+		CSize();
+		CSize(int width, int height, bool under);
+
+		int getWidth() const; /// Default: CMapHeader::MAP_SIZE_MIDDLE
+		void setWidth(int value);
+		int getHeight() const; /// Default: CMapHeader::MAP_SIZE_MIDDLE
+		void setHeight(int value);
+		bool getUnder() const; /// Default: true
+		void setUnder(bool value);
+		bool operator<=(const CSize & value) const;
+		bool operator>=(const CSize & value) const;
+
+	private:
+		int width, height;
+		bool under;
+	};
+
+	class CPlayerCountRange
+	{
+	public:
+		void addRange(int lower, int upper);
+		void addNumber(int value);
+		bool isInRange(int count) const;
+		std::set<int> getNumbers() const;
+
+	private:
+		std::list<std::pair<int, int> > range;
+	};
+
+	CRmgTemplate();
+
+	const std::string & getName() const;
+	void setName(const std::string & value);
+	const CSize & getMinSize() const;
+	void setMinSize(const CSize & value);
+	const CSize & getMaxSize() const;
+	void setMaxSize(const CSize & value);
+	const CPlayerCountRange & getPlayers() const;
+	void setPlayers(const CPlayerCountRange & value);
+	const CPlayerCountRange & getCpuPlayers() const;
+	void setCpuPlayers(const CPlayerCountRange & value);
+	const std::map<TRmgTemplateZoneId, CRmgTemplateZone> & getZones() const;
+	void setZones(const std::map<TRmgTemplateZoneId, CRmgTemplateZone> & value);
+	const std::list<CRmgTemplateZoneConnection> & getConnections() const;
+	void setConnections(const std::list<CRmgTemplateZoneConnection> & value);
+
+	void validate() const; /// Tests template on validity and throws exception on failure
+
+private:
+	std::string name;
+	CSize minSize, maxSize;
+	CPlayerCountRange players, cpuPlayers;
+	std::map<TRmgTemplateZoneId, CRmgTemplateZone> zones;
+	std::list<CRmgTemplateZoneConnection> connections;
+};
+
 namespace EWaterContent
 {
 enum EWaterContent
@@ -105,21 +265,21 @@ public:
 
 	/// 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);
+	si8 getPlayerCount() const;
+	void setPlayerCount(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);
+	si8 getTeamCount() const;
+	void setTeamCount(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);
+	si8 getCompOnlyPlayerCount() const;
+	void setCompOnlyPlayerCount(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);
+	si8 getCompOnlyTeamCount() const;
+	void setCompOnlyTeamCount(si8 value);
 
 	EWaterContent::EWaterContent getWaterContent() const;
 	void setWaterContent(EWaterContent::EWaterContent value);
@@ -132,37 +292,50 @@ public:
 	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.
+	/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN.
 	void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType);
 
+	/// The random map template to generate the map with or empty/not set if the template should be chosen randomly.
+	/// Default: Not set/random.
+	const CRmgTemplate * getMapTemplate() const;
+	void setMapTemplate(const CRmgTemplate * value);
+
+	const std::map<std::string, CRmgTemplate> & getAvailableTemplates() const;
+
 	/// 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.
+	/// a random number generator by keeping the options in a valid state. Check options should return true, otherwise
+	/// this function fails.
 	void finalize();
 	void finalize(CRandomGenerator & gen);
 
+	/// Returns false if there is no template available which fits to the currently selected options.
+	bool checkOptions() const;
+
 	static const si8 RANDOM_SIZE = -1;
 
 private:
 	void resetPlayersMap();
 	int countHumanPlayers() const;
 	PlayerColor getNextPlayerColor() const;
+	void updateCompOnlyPlayers();
+	void updatePlayers();
+	const CRmgTemplate * getPossibleTemplate(CRandomGenerator & gen) const;
 
 	si32 width, height;
 	bool hasTwoLevels;
-	si8 playersCnt, teamsCnt, compOnlyPlayersCnt, compOnlyTeamsCnt;
+	si8 playerCount, teamCount, compOnlyPlayerCount, compOnlyTeamCount;
 	EWaterContent::EWaterContent waterContent;
 	EMonsterStrength::EMonsterStrength monsterStrength;
 	std::map<PlayerColor, CPlayerSettings> players;
+	const CRmgTemplate * mapTemplate;
 
 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;
+		h & width & height & hasTwoLevels & playerCount & teamCount & compOnlyPlayerCount;
+		h & compOnlyTeamCount & waterContent & monsterStrength & players;
+        //TODO add name of template to class, enables selection of a template by a user
 	}
 };
 
@@ -194,185 +367,45 @@ private:
 /* Implementation/Detail classes, Private API */
 /* ---------------------------------------------------------------------------- */
 
-namespace ETemplateZoneType
-{
-enum ETemplateZoneType
-{
-	HUMAN_START,
-	COMPUTER_START,
-	TREASURE,
-	JUNCTION
-};
-}
-
-/// The CTemplateZoneTowns holds info about towns in a template zone.
-class DLL_LINKAGE CTemplateZoneTowns
-{
-public:
-	CTemplateZoneTowns();
-
-	int getMinTowns() const; /// Default: 0
-	void setMinTowns(int value);
-	int getMinCastles() const; /// Default: 0
-	void setMinCastles(int value);
-	int getTownDensity() const; /// Default: 0
-	void setTownDensity(int value);
-	int getCastleDensity() const; /// Default: 0
-	void setCastleDensity(int value);
-
-private:
-	int minTowns, minCastles, townDensity, castleDensity;
-};
-
-typedef int TTemplateZoneId;
-
-/// The CTemplateZone describes a zone in a template.
-class DLL_LINKAGE CTemplateZone
-{
-public:
-	CTemplateZone();
-
-	TTemplateZoneId getId() const; /// Default: 0 = not set;
-	void setId(TTemplateZoneId value);
-	ETemplateZoneType::ETemplateZoneType getType() const; /// Default: ETemplateZoneType::HUMAN_START
-	void setType(ETemplateZoneType::ETemplateZoneType value);
-	int getBaseSize() const; /// Default: 0 = not set;
-	void setBaseSize(int value);
-	int getOwner() const; /// Default: 0 = not set;
-	void setOwner(int value);
-	const CTemplateZoneTowns & getPlayerTowns() const;
-	void setPlayerTowns(const CTemplateZoneTowns & value);
-	const CTemplateZoneTowns & getNeutralTowns() const;
-	void setNeutralTowns(const CTemplateZoneTowns & value);
-	bool getNeutralTownsAreSameType() const; /// Default: false
-	void setNeutralTownsAreSameType(bool value);
-	const std::set<TFaction> & getAllowedTownTypes() const;
-	void setAllowedTownTypes(const std::set<TFaction> & value);
-	bool getMatchTerrainToTown() const; /// Default: false
-	void setMatchTerrainToTown(bool value);
-	const std::set<ETerrainType> & getTerrainTypes() const;
-	void setTerrainTypes(const std::set<ETerrainType> & value);
-
-private:
-	TTemplateZoneId id;
-	ETemplateZoneType::ETemplateZoneType type;
-	int baseSize;
-	int owner;
-	CTemplateZoneTowns playerTowns, neutralTowns;
-	bool neutralTownsAreSameType;
-	std::set<TFaction> allowedTownTypes;
-	bool matchTerrainToTown;
-	std::set<ETerrainType> terrainTypes;
-};
-
-/// The CTemplateZoneConnection describes the connection between two zones.
-class DLL_LINKAGE CTemplateZoneConnection
-{
-public:
-	CTemplateZoneConnection();
-
-	TTemplateZoneId getZoneA() const; /// Default: 0 = not set;
-	void setZoneA(TTemplateZoneId value);
-	TTemplateZoneId getZoneB() const; /// Default: 0 = not set;
-	void setZoneB(TTemplateZoneId value);
-	int getGuardStrength() const; /// Default: 0
-	void setGuardStrength(int value);
-
-private:
-	TTemplateZoneId zoneA, zoneB;
-	int guardStrength;
-};
-
-/// The CRandomMapTemplateSize describes the dimensions of the template.
-class CRandomMapTemplateSize
-{
-public:
-	CRandomMapTemplateSize();
-	CRandomMapTemplateSize(int width, int height, bool under);
-
-	int getWidth() const; /// Default: CMapHeader::MAP_SIZE_MIDDLE
-	void setWidth(int value);
-	int getHeight() const; /// Default: CMapHeader::MAP_SIZE_MIDDLE
-	void setHeight(int value);
-	bool getUnder() const; /// Default: true
-	void setUnder(bool value);
-
-private:
-	int width, height;
-	bool under;
-};
-
-/// The CRandomMapTemplate describes a random map template.
-class DLL_LINKAGE CRandomMapTemplate
-{
-public:
-	CRandomMapTemplate();
-
-	const std::string & getName() const;
-	void setName(const std::string & value);
-	const CRandomMapTemplateSize & getMinSize() const; /// Default: CMapHeader::MAP_SIZE_SMALL x CMapHeader::MAP_SIZE_SMALL x wo under
-	void setMinSize(const CRandomMapTemplateSize & value);
-	const CRandomMapTemplateSize & getMaxSize() const; /// Default: CMapHeader::MAP_SIZE_XLARGE x CMapHeader::MAP_SIZE_XLARGE x under
-	void setMaxSize(const CRandomMapTemplateSize & value);
-	int getMinHumanCnt() const; /// Default: 1
-	void setMinHumanCnt(int value);
-	int getMaxHumanCnt() const; /// Default: PlayerColor::PLAYER_LIMIT_I
-	void setMaxHumanCnt(int value);
-	int getMinTotalCnt() const; /// Default: 2
-	void setMinTotalCnt(int value);
-	int getMaxTotalCnt() const; /// Default: PlayerColor::PLAYER_LIMIT_I
-	void setMaxTotalCnt(int value);
-	const std::map<TTemplateZoneId, CTemplateZone> & getZones() const;
-	void setZones(const std::map<TTemplateZoneId, CTemplateZone> & value);
-	const std::list<CTemplateZoneConnection> & getConnections() const;
-	void setConnections(const std::list<CTemplateZoneConnection> & value);
-
-private:
-	std::string name;
-	CRandomMapTemplateSize minSize, maxSize;
-	int minHumanCnt, maxHumanCnt, minTotalCnt, maxTotalCnt;
-	std::map<TTemplateZoneId, CTemplateZone> zones;
-	std::list<CTemplateZoneConnection> connections;
-};
-
-/// The CRmTemplateLoader is a abstract base class for loading templates.
-class DLL_LINKAGE CRmTemplateLoader
+/// The CRmgTemplateLoader is a abstract base class for loading templates.
+class DLL_LINKAGE CRmgTemplateLoader
 {
 public:
-	virtual ~CRmTemplateLoader() { };
+	virtual ~CRmgTemplateLoader() { };
 	virtual void loadTemplates() = 0;
-	const std::map<std::string, CRandomMapTemplate> & getTemplates() const;
+	const std::map<std::string, CRmgTemplate> & getTemplates() const;
 
 protected:
-	std::map<std::string, CRandomMapTemplate> templates;
+	std::map<std::string, CRmgTemplate> templates;
 };
 
-/// The CJsonRmTemplateLoader loads templates from a JSON file.
-class DLL_LINKAGE CJsonRmTemplateLoader : public CRmTemplateLoader
+/// The CJsonRmgTemplateLoader loads templates from a JSON file.
+class DLL_LINKAGE CJsonRmgTemplateLoader : public CRmgTemplateLoader
 {
 public:
 	void loadTemplates() override;
 
 private:
-	CRandomMapTemplateSize parseMapTemplateSize(const std::string & text) const;
-	CTemplateZoneTowns parseTemplateZoneTowns(const JsonNode & node) const;
-	ETemplateZoneType::ETemplateZoneType getZoneType(const std::string & type) const;
-	std::set<TFaction> getFactions(const std::vector<JsonNode> factionStrings) const;
-	std::set<ETerrainType> parseTerrainTypes(const std::vector<JsonNode> terTypeStrings) const;
+	CRmgTemplate::CSize parseMapTemplateSize(const std::string & text) const;
+	CRmgTemplateZone::CTownInfo parseTemplateZoneTowns(const JsonNode & node) const;
+	ETemplateZoneType::ETemplateZoneType parseZoneType(const std::string & type) const;
+	std::set<TFaction> parseTownTypes(const JsonVector & townTypesVector, const std::set<TFaction> & defaultTownTypes) const;
+	std::set<ETerrainType> parseTerrainTypes(const JsonVector & terTypeStrings, const std::set<ETerrainType> & defaultTerrainTypes) const;
+	CRmgTemplate::CPlayerCountRange parsePlayers(const std::string & players) const;
 };
 
-/// The CRandomMapTemplateStorage is a singleton object where templates are stored and which can be accessed from anywhere.
-class DLL_LINKAGE CRandomMapTemplateStorage
+/// The CRmgTemplateStorage is a singleton object where templates are stored and which can be accessed from anywhere.
+class DLL_LINKAGE CRmgTemplateStorage
 {
 public:
-	static CRandomMapTemplateStorage & get();
+	static CRmgTemplateStorage & get();
 
-	const std::map<std::string, CRandomMapTemplate> & getTemplates() const;
+	const std::map<std::string, CRmgTemplate> & getTemplates() const;
 
 private:
-	CRandomMapTemplateStorage();
-	~CRandomMapTemplateStorage();
+	CRmgTemplateStorage();
+	~CRmgTemplateStorage();
 
 	static boost::mutex smx;
-	std::map<std::string, CRandomMapTemplate> templates; /// Key: Template name
+	std::map<std::string, CRmgTemplate> templates; /// Key: Template name
 };

+ 1 - 1
server/CVCMIServer.cpp

@@ -325,7 +325,7 @@ CGameHandler * CVCMIServer::initGhFromHostingConnection(CConnection &c)
 	StartInfo si;
 	c >> si; //get start options
 
-	if(!si.createRandomMap)
+	if(!si.createRandomMap())
 	{
 		bool mapFound = CResourceHandler::get()->existsResource(ResourceID(si.mapname, EResType::MAP));
 

Some files were not shown because too many files changed in this diff