1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- 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

This commit is contained in:
beegee1 2013-05-21 19:08:06 +00:00
parent c920f29c45
commit 5328beb8e7
10 changed files with 976 additions and 720 deletions

View File

@ -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;
}

View File

@ -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();
CRandomMapTab();
/**
* Shows the interface and the visual representation of this tab.
*
* @param to where the graphics should be inserted
*/
void showAll(SDL_Surface * to);
/**
* Updates the map info object and fires the associated callback method.
*/
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;

View File

@ -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
},
"6" :
{
"type" : "humanStart", "baseSize" : 11, "owner" : 6,
"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
},
"7" :
{
"type" : "humanStart", "baseSize" : 11, "owner" : 7,
"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
},
"8" :
{
"type" : "humanStart", "baseSize" : 11, "owner" : 8,
"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true
"type" : "treasure", "size" : 2, "terrainTypes" : [ "sand" ], "neutralTowns" : { "castles" : 1 }
}
},
"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" : "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 }
},
"3" :
{
"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : "1"
},
"4" :
{
"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : "2"
},
"5" :
{
"type" : "treasure", "size" : 3, "neutralTowns" : { "castles" : 1 }, "terrainTypes" : [ "sand" ]
}
},
"connections" :
[
{ "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 }
]
}
}

View File

@ -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();

View File

@ -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++)
{

View File

@ -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)
{
}

View File

@ -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 Load Diff

View File

@ -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
/// The CRmgTemplateLoader is a abstract base class for loading templates.
class DLL_LINKAGE CRmgTemplateLoader
{
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
{
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
};

View File

@ -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));