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 = new OptionsTab(); //scenario options tab
opt->recActions = DISPOSE; opt->recActions = DISPOSE;
randMapTab = new RandomMapTab(); randMapTab = new CRandomMapTab();
randMapTab->getMapInfoChanged() += bind(&CSelectionScreen::changeSelection, this, _1); randMapTab->getMapInfoChanged() += bind(&CSelectionScreen::changeSelection, this, _1);
randMapTab->recActions = DISPOSE; randMapTab->recActions = DISPOSE;
} }
@ -650,7 +650,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
randomBtn->callback = [&]() randomBtn->callback = [&]()
{ {
toggleTab(randMapTab); 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); 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) void CSelectionScreen::changeSelection(const CMapInfo * to)
{ {
if(current == to) return;
if(multiPlayer == CMenuScreen::MULTI_NETWORK_GUEST) if(multiPlayer == CMenuScreen::MULTI_NETWORK_GUEST)
{ {
vstd::clear_pointer(current); vstd::clear_pointer(current);
@ -814,17 +815,14 @@ void CSelectionScreen::changeSelection(const CMapInfo * to)
if(screenType != CMenuScreen::campaignList) if(screenType != CMenuScreen::campaignList)
{ {
updateStartInfo(to ? to->fileURI : "", sInfo, to ? to->mapHeader.get() : NULL); updateStartInfo(to ? to->fileURI : "", sInfo, to ? to->mapHeader.get() : NULL);
if(screenType == CMenuScreen::newGame) if(screenType == CMenuScreen::newGame)
{ {
if(to && to->isRandomMap) if(to && to->isRandomMap)
{ {
sInfo.createRandomMap = true;
sInfo.mapGenOptions = std::shared_ptr<CMapGenOptions>(new CMapGenOptions(randMapTab->getMapGenOptions())); sInfo.mapGenOptions = std::shared_ptr<CMapGenOptions>(new CMapGenOptions(randMapTab->getMapGenOptions()));
} }
else else
{ {
sInfo.createRandomMap = false;
sInfo.mapGenOptions.reset(); sInfo.mapGenOptions.reset();
} }
} }
@ -884,6 +882,26 @@ void CSelectionScreen::startScenario()
if(!current) if(!current)
return; 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(); saveGameName.clear();
if(screenType == CMenuScreen::loadGame) if(screenType == CMenuScreen::loadGame)
{ {
@ -1599,7 +1617,7 @@ const CMapInfo * SelectionTab::getSelectedMapInfo() const
return curItems.empty() ? nullptr : curItems[selectionPos]; return curItems.empty() ? nullptr : curItems[selectionPos];
} }
RandomMapTab::RandomMapTab() CRandomMapTab::CRandomMapTab()
{ {
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
bg = new CPicture("RANMAPBK", 0, 6); bg = new CPicture("RANMAPBK", 0, 6);
@ -1623,7 +1641,7 @@ RandomMapTab::RandomMapTab()
// Two levels // Two levels
twoLevelsBtn = new CHighlightableButton(0, 0, std::map<int,std::string>(), twoLevelsBtn = new CHighlightableButton(0, 0, std::map<int,std::string>(),
CGI->generaltexth->zelp[202].second, false, "RANUNDR", nullptr, 346, 81); 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->callback = [&]() { mapGenOptions.setHasTwoLevels(true); updateMapInfo(); };
twoLevelsBtn->callback2 = [&]() { mapGenOptions.setHasTwoLevels(false); updateMapInfo(); }; twoLevelsBtn->callback2 = [&]() { mapGenOptions.setHasTwoLevels(false); updateMapInfo(); };
@ -1643,7 +1661,7 @@ RandomMapTab::RandomMapTab()
addButtonsWithRandToGroup(playersCntGroup, numberDefs, 1, 8, NUMBERS_WIDTH, 204, 212); addButtonsWithRandToGroup(playersCntGroup, numberDefs, 1, 8, NUMBERS_WIDTH, 204, 212);
playersCntGroup->onChange = [&](int btnId) playersCntGroup->onChange = [&](int btnId)
{ {
mapGenOptions.setPlayersCnt(btnId); mapGenOptions.setPlayerCount(btnId);
deactivateButtonsFrom(teamsCntGroup, btnId); deactivateButtonsFrom(teamsCntGroup, btnId);
deactivateButtonsFrom(compOnlyPlayersCntGroup, 8 - btnId + 1); deactivateButtonsFrom(compOnlyPlayersCntGroup, 8 - btnId + 1);
validatePlayersCnt(btnId); validatePlayersCnt(btnId);
@ -1657,7 +1675,7 @@ RandomMapTab::RandomMapTab()
addButtonsWithRandToGroup(teamsCntGroup, numberDefs, 0, 7, NUMBERS_WIDTH, 214, 222); addButtonsWithRandToGroup(teamsCntGroup, numberDefs, 0, 7, NUMBERS_WIDTH, 214, 222);
teamsCntGroup->onChange = [&](int btnId) teamsCntGroup->onChange = [&](int btnId)
{ {
mapGenOptions.setTeamsCnt(btnId); mapGenOptions.setTeamCount(btnId);
updateMapInfo(); updateMapInfo();
}; };
@ -1669,7 +1687,7 @@ RandomMapTab::RandomMapTab()
compOnlyPlayersCntGroup->select(0, true); compOnlyPlayersCntGroup->select(0, true);
compOnlyPlayersCntGroup->onChange = [&](int btnId) compOnlyPlayersCntGroup->onChange = [&](int btnId)
{ {
mapGenOptions.setCompOnlyPlayersCnt(btnId); mapGenOptions.setCompOnlyPlayerCount(btnId);
deactivateButtonsFrom(compOnlyTeamsCntGroup, btnId); deactivateButtonsFrom(compOnlyTeamsCntGroup, btnId);
validateCompOnlyPlayersCnt(btnId); validateCompOnlyPlayersCnt(btnId);
updateMapInfo(); updateMapInfo();
@ -1683,7 +1701,7 @@ RandomMapTab::RandomMapTab()
deactivateButtonsFrom(compOnlyTeamsCntGroup, 0); deactivateButtonsFrom(compOnlyTeamsCntGroup, 0);
compOnlyTeamsCntGroup->onChange = [&](int btnId) compOnlyTeamsCntGroup->onChange = [&](int btnId)
{ {
mapGenOptions.setCompOnlyTeamsCnt(btnId); mapGenOptions.setCompOnlyTeamCount(btnId);
updateMapInfo(); updateMapInfo();
}; };
@ -1714,17 +1732,10 @@ RandomMapTab::RandomMapTab()
showRandMaps = new CAdventureMapButton("", CGI->generaltexth->zelp[252].second, 0, 54, 535, "RANSHOW"); showRandMaps = new CAdventureMapButton("", CGI->generaltexth->zelp[252].second, 0, 54, 535, "RANSHOW");
// Initialize map info object // 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(); 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); addButtonsToGroup(group, defs, nStart, nEnd, btnWidth, helpStartIndex);
@ -1735,7 +1746,7 @@ void RandomMapTab::addButtonsWithRandToGroup(CHighlightableButtonsGroup * group,
group->select(CMapGenOptions::RANDOM_SIZE, true); 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? // Buttons are relative to button group, TODO better solution?
SObjectConstruction obj__i(group); 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) 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) if(playersCnt == CMapGenOptions::RANDOM_SIZE)
{ {
return; return;
} }
if(mapGenOptions.getTeamsCnt() >= playersCnt) if(mapGenOptions.getTeamCount() >= playersCnt)
{ {
mapGenOptions.setTeamsCnt(playersCnt - 1); mapGenOptions.setTeamCount(playersCnt - 1);
teamsCntGroup->select(mapGenOptions.getTeamsCnt(), true); teamsCntGroup->select(mapGenOptions.getTeamCount(), true);
} }
if(mapGenOptions.getCompOnlyPlayersCnt() > 8 - playersCnt) if(mapGenOptions.getCompOnlyPlayerCount() > 8 - playersCnt)
{ {
mapGenOptions.setCompOnlyPlayersCnt(8 - playersCnt); mapGenOptions.setCompOnlyPlayerCount(8 - playersCnt);
compOnlyPlayersCntGroup->select(mapGenOptions.getCompOnlyPlayersCnt(), true); 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) if(compOnlyPlayersCnt == CMapGenOptions::RANDOM_SIZE)
{ {
return; return;
} }
if(mapGenOptions.getCompOnlyTeamsCnt() >= compOnlyPlayersCnt) if(mapGenOptions.getCompOnlyTeamCount() >= compOnlyPlayersCnt)
{ {
mapGenOptions.setCompOnlyTeamsCnt(compOnlyPlayersCnt - 1); mapGenOptions.setCompOnlyTeamCount(compOnlyPlayersCnt - 1);
compOnlyTeamsCntGroup->select(mapGenOptions.getCompOnlyTeamsCnt(), true); compOnlyTeamsCntGroup->select(mapGenOptions.getCompOnlyTeamCount(), true);
} }
} }
void RandomMapTab::showAll(SDL_Surface * to) void CRandomMapTab::showAll(SDL_Surface * to)
{ {
CIntObject::showAll(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); printAtLoc(CGI->generaltexth->allTexts[758], 68, 465, FONT_SMALL, Colors::WHITE, to);
} }
void RandomMapTab::updateMapInfo() void CRandomMapTab::updateMapInfo()
{ {
mapInfo.mapHeader->height = mapGenOptions.getHeight(); // Generate header info
mapInfo.mapHeader->width = mapGenOptions.getWidth(); mapInfo = make_unique<CMapInfo>();
mapInfo.mapHeader->twoLevel = mapGenOptions.getHasTwoLevels(); 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 // Generate player information
mapInfo.mapHeader->players.clear(); mapInfo->mapHeader->players.clear();
int playersToGen = (mapGenOptions.getPlayersCnt() == CMapGenOptions::RANDOM_SIZE int playersToGen = (mapGenOptions.getPlayerCount() == CMapGenOptions::RANDOM_SIZE
|| mapGenOptions.getCompOnlyPlayersCnt() == CMapGenOptions::RANDOM_SIZE) || mapGenOptions.getCompOnlyPlayerCount() == CMapGenOptions::RANDOM_SIZE)
? 8 : mapGenOptions.getPlayersCnt() + mapGenOptions.getCompOnlyPlayersCnt(); ? 8 : mapGenOptions.getPlayerCount() + mapGenOptions.getCompOnlyPlayerCount();
mapInfo.mapHeader->howManyTeams = playersToGen; mapInfo->mapHeader->howManyTeams = playersToGen;
for(int i = 0; i < playersToGen; ++i) for(int i = 0; i < playersToGen; ++i)
{ {
PlayerInfo player; PlayerInfo player;
player.isFactionRandom = true;
player.canComputerPlay = 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; player.canHumanPlay = false;
} }
@ -1860,23 +1881,23 @@ void RandomMapTab::updateMapInfo()
player.team = TeamID(i); player.team = TeamID(i);
player.hasMainTown = true; player.hasMainTown = true;
player.generateHeroAtMainTown = 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; 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; return mapGenOptions;
} }

View File

@ -29,7 +29,7 @@ class CCampaignState;
class CConnection; class CConnection;
class JsonNode; class JsonNode;
class CMapGenOptions; class CMapGenOptions;
class RandomMapTab; class CRandomMapTab;
struct CPackForSelectionScreen; struct CPackForSelectionScreen;
struct PlayerInfo; struct PlayerInfo;
@ -282,139 +282,32 @@ public:
bool canUseThisHero(PlayerColor player, int ID ); bool canUseThisHero(PlayerColor player, int ID );
}; };
/** /// The random map tab shows options for generating a random map.
* The random map tab shows options for generating a random map. class CRandomMapTab : public CIntObject
*/
class RandomMapTab : public CIntObject
{ {
public: public:
/** CRandomMapTab();
* 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); void showAll(SDL_Surface * to);
/**
* Updates the map info object and fires the associated callback method.
*/
void updateMapInfo(); 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(); CFunctionList<void (const CMapInfo *)> & getMapInfoChanged();
const CMapInfo * getMapInfo() const;
/**
* 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 CMapGenOptions & getMapGenOptions() const; const CMapGenOptions & getMapGenOptions() const;
private: 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; 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; 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); 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); 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); void validateCompOnlyPlayersCnt(int compOnlyPlayersCnt);
/** the background image of the rmg options tab */
CPicture * bg; CPicture * bg;
CHighlightableButton * twoLevelsBtn;
/** the map size buttons group */ CHighlightableButtonsGroup * mapSizeBtnGroup, * playersCntGroup, * teamsCntGroup, * compOnlyPlayersCntGroup,
CHighlightableButtonsGroup * mapSizeBtnGroup; * compOnlyTeamsCntGroup, * waterContentGroup, * monsterStrengthGroup;
/** 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 */
CAdventureMapButton * showRandMaps; CAdventureMapButton * showRandMaps;
/** the map options selected by the user */
CMapGenOptions mapGenOptions; CMapGenOptions mapGenOptions;
unique_ptr<CMapInfo> mapInfo;
/** map info object describing a randomly created map */
CMapInfo mapInfo;
/** callback method which gets called when the random options have been changed */
CFunctionList<void(const CMapInfo *)> mapInfoChanged; CFunctionList<void(const CMapInfo *)> mapInfoChanged;
}; };
@ -452,7 +345,7 @@ public:
CPicture *bg; //general bg image CPicture *bg; //general bg image
InfoCard *card; InfoCard *card;
OptionsTab *opt; OptionsTab *opt;
RandomMapTab * randMapTab; CRandomMapTab * randMapTab;
CAdventureMapButton *start, *back; CAdventureMapButton *start, *back;
SelectionTab *sel; SelectionTab *sel;

View File

@ -1,66 +1,167 @@
// Defines random map templates. // Defines random map templates.
{ {
"Small Ring" : "Analogy" :
{ {
"minSize" : "s", "maxSize" : "s+u", "minSize" : "m", "maxSize" : "m",
"minHumanCnt" : 1, "maxHumanCnt" : 8, "minTotalCnt" : 2, "maxTotalCnt" : 8, "players" : "4",
"zones" : "zones" :
{ {
"1" : "1" :
{ {
"type" : "humanStart", "baseSize" : 11, "owner" : 1, "type" : "playerStart", "size" : 1, "owner" : 1,
"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true "playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
}, },
"2" : "2" :
{ {
"type" : "humanStart", "baseSize" : 11, "owner" : 2, "type" : "playerStart", "size" : 1, "owner" : 2,
"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true "playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
}, },
"3" : "3" :
{ {
"type" : "humanStart", "baseSize" : 11, "owner" : 3, "type" : "playerStart", "size" : 1, "owner" : 3,
"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true "playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
}, },
"4" : "4" :
{ {
"type" : "humanStart", "baseSize" : 11, "owner" : 4, "type" : "playerStart", "size" : 1, "owner" : 4,
"playerTowns" : { "minCastles" : 1 }, "allowedTownTypes" : [ "all" ], "matchTerrainToTown" : true "playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true
}, },
"5" : "5" :
{ {
"type" : "humanStart", "baseSize" : 11, "owner" : 5, "type" : "treasure", "size" : 2, "terrainTypes" : [ "sand" ], "neutralTowns" : { "castles" : 1 }
"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
} }
}, },
"connections" : "connections" :
[ [
{ "a" : "1", "b" : "2", "guardStrength" : 4500 }, { "a" : "1", "b" : "5", "guard" : 1000 },
{ "a" : "2", "b" : "3", "guardStrength" : 4500 }, { "a" : "2", "b" : "5", "guard" : 1000 },
{ "a" : "3", "b" : "4", "guardStrength" : 4500 }, { "a" : "3", "b" : "5", "guard" : 1000 },
{ "a" : "4", "b" : "5", "guardStrength" : 4500 }, { "a" : "4", "b" : "5", "guard" : 1000 }
{ "a" : "5", "b" : "6", "guardStrength" : 4500 }, ]
{ "a" : "6", "b" : "7", "guardStrength" : 4500 }, },
{ "a" : "7", "b" : "8", "guardStrength" : 4500 }, "Upgrade" :
{ "a" : "8", "b" : "1", "guardStrength" : 4500 }, {
{ "a" : "4", "b" : "1", "guardStrength" : 4500 }, "minSize" : "m", "maxSize" : "m",
{ "a" : "5", "b" : "1", "guardStrength" : 4500 }, "players" : "2",
{ "a" : "6", "b" : "1", "guardStrength" : 4500 }, "zones" :
{ "a" : "7", "b" : "1", "guardStrength" : 4500 } {
"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: case StartInfo::NEW_GAME:
{ {
if(scenarioOps->createRandomMap) if(scenarioOps->createRandomMap())
{ {
logGlobal->infoStream() << "Create random map."; logGlobal->infoStream() << "Create random map.";
CStopWatch sw; 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 // Gen map
CMapGenerator mapGen(*(scenarioOps->mapGenOptions), scenarioOps->seedToBeUsed); CMapGenerator mapGen(*(scenarioOps->mapGenOptions), scenarioOps->seedToBeUsed);
map = mapGen.generate().release(); map = mapGen.generate().release();

View File

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

View File

@ -81,8 +81,8 @@ struct StartInfo
ui32 mapfileChecksum; //0 if not relevant ui32 mapfileChecksum; //0 if not relevant
ui8 turnTime; //in minutes, 0=unlimited ui8 turnTime; //in minutes, 0=unlimited
std::string mapname; // empty for random map, otherwise name of the map or savegame std::string mapname; // empty for random map, otherwise name of the map or savegame
bool createRandomMap; // true if a random map should be created bool createRandomMap() const { return mapGenOptions.get() != nullptr; }
shared_ptr<CMapGenOptions> mapGenOptions; // needs to be not nullptr if createRandomMap=true shared_ptr<CMapGenOptions> mapGenOptions;
shared_ptr<CCampaignState> campState; shared_ptr<CCampaignState> campState;
@ -113,13 +113,12 @@ struct StartInfo
h & mapfileChecksum; h & mapfileChecksum;
h & turnTime; h & turnTime;
h & mapname; h & mapname;
h & createRandomMap;
h & mapGenOptions; h & mapGenOptions;
h & campState; h & campState;
} }
StartInfo() : mode(INVALID), difficulty(0), seedToBeUsed(0), seedPostInit(0), 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); CTerrainSelection terrainSel(map);
terrainSel.selectRange(MapRect(int3(0, 0, 0), map->width, map->height)); terrainSel.selectRange(MapRect(int3(0, 0, 0), map->width, map->height));
addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::WATER, gen)); addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::WATER, gen));
terrainSel.clearSelection(); if(map->twoLevel)
terrainSel.selectRange(MapRect(int3(0, 0, 1), map->width, map->height)); {
addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::ROCK, gen)); 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 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 CMapEditManager;
class JsonNode; 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 namespace EWaterContent
{ {
enum 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 /// 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. /// this method, all player settings are reset to default settings.
si8 getPlayersCnt() const; si8 getPlayerCount() const;
void setPlayersCnt(si8 value); void setPlayerCount(si8 value);
/// The count of the teams ranging from 0 to <players count - 1> or RANDOM_SIZE for random. /// The count of the teams ranging from 0 to <players count - 1> or RANDOM_SIZE for random.
si8 getTeamsCnt() const; si8 getTeamCount() const;
void setTeamsCnt(si8 value); 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. /// 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. /// If you call this method, all player settings are reset to default settings.
si8 getCompOnlyPlayersCnt() const; si8 getCompOnlyPlayerCount() const;
void setCompOnlyPlayersCnt(si8 value); void setCompOnlyPlayerCount(si8 value);
/// The count of the computer only teams ranging from 0 to <comp only players - 1> or RANDOM_SIZE for random. /// The count of the computer only teams ranging from 0 to <comp only players - 1> or RANDOM_SIZE for random.
si8 getCompOnlyTeamsCnt() const; si8 getCompOnlyTeamCount() const;
void setCompOnlyTeamsCnt(si8 value); void setCompOnlyTeamCount(si8 value);
EWaterContent::EWaterContent getWaterContent() const; EWaterContent::EWaterContent getWaterContent() const;
void setWaterContent(EWaterContent::EWaterContent value); void setWaterContent(EWaterContent::EWaterContent value);
@ -132,37 +292,50 @@ public:
const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const; const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
void setStartingTownForPlayer(PlayerColor color, si32 town); 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 /// 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 /// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN.
/// has no effect for the map itself, but it adds some informational text for the map description.
void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType); 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 /// 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();
void finalize(CRandomGenerator & gen); 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; static const si8 RANDOM_SIZE = -1;
private: private:
void resetPlayersMap(); void resetPlayersMap();
int countHumanPlayers() const; int countHumanPlayers() const;
PlayerColor getNextPlayerColor() const; PlayerColor getNextPlayerColor() const;
void updateCompOnlyPlayers();
void updatePlayers();
const CRmgTemplate * getPossibleTemplate(CRandomGenerator & gen) const;
si32 width, height; si32 width, height;
bool hasTwoLevels; bool hasTwoLevels;
si8 playersCnt, teamsCnt, compOnlyPlayersCnt, compOnlyTeamsCnt; si8 playerCount, teamCount, compOnlyPlayerCount, compOnlyTeamCount;
EWaterContent::EWaterContent waterContent; EWaterContent::EWaterContent waterContent;
EMonsterStrength::EMonsterStrength monsterStrength; EMonsterStrength::EMonsterStrength monsterStrength;
std::map<PlayerColor, CPlayerSettings> players; std::map<PlayerColor, CPlayerSettings> players;
const CRmgTemplate * mapTemplate;
public: public:
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
//FIXME: Enum is not a fixed with data type. Add enum class to both enums h & width & height & hasTwoLevels & playerCount & teamCount & compOnlyPlayerCount;
// later. For now it is ok. h & compOnlyTeamCount & waterContent & monsterStrength & players;
h & width & height & hasTwoLevels & playersCnt & teamsCnt & compOnlyPlayersCnt; //TODO add name of template to class, enables selection of a template by a user
h & compOnlyTeamsCnt & waterContent & monsterStrength & players;
} }
}; };
@ -194,185 +367,45 @@ private:
/* Implementation/Detail classes, Private API */ /* Implementation/Detail classes, Private API */
/* ---------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------- */
namespace ETemplateZoneType /// The CRmgTemplateLoader is a abstract base class for loading templates.
{ class DLL_LINKAGE CRmgTemplateLoader
enum ETemplateZoneType
{
HUMAN_START,
COMPUTER_START,
TREASURE,
JUNCTION
};
}
/// The CTemplateZoneTowns holds info about towns in a template zone.
class DLL_LINKAGE CTemplateZoneTowns
{ {
public: public:
CTemplateZoneTowns(); virtual ~CRmgTemplateLoader() { };
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 void loadTemplates() = 0; virtual void loadTemplates() = 0;
const std::map<std::string, CRandomMapTemplate> & getTemplates() const; const std::map<std::string, CRmgTemplate> & getTemplates() const;
protected: protected:
std::map<std::string, CRandomMapTemplate> templates; std::map<std::string, CRmgTemplate> templates;
}; };
/// The CJsonRmTemplateLoader loads templates from a JSON file. /// The CJsonRmgTemplateLoader loads templates from a JSON file.
class DLL_LINKAGE CJsonRmTemplateLoader : public CRmTemplateLoader class DLL_LINKAGE CJsonRmgTemplateLoader : public CRmgTemplateLoader
{ {
public: public:
void loadTemplates() override; void loadTemplates() override;
private: private:
CRandomMapTemplateSize parseMapTemplateSize(const std::string & text) const; CRmgTemplate::CSize parseMapTemplateSize(const std::string & text) const;
CTemplateZoneTowns parseTemplateZoneTowns(const JsonNode & node) const; CRmgTemplateZone::CTownInfo parseTemplateZoneTowns(const JsonNode & node) const;
ETemplateZoneType::ETemplateZoneType getZoneType(const std::string & type) const; ETemplateZoneType::ETemplateZoneType parseZoneType(const std::string & type) const;
std::set<TFaction> getFactions(const std::vector<JsonNode> factionStrings) const; std::set<TFaction> parseTownTypes(const JsonVector & townTypesVector, const std::set<TFaction> & defaultTownTypes) const;
std::set<ETerrainType> parseTerrainTypes(const std::vector<JsonNode> terTypeStrings) 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. /// The CRmgTemplateStorage is a singleton object where templates are stored and which can be accessed from anywhere.
class DLL_LINKAGE CRandomMapTemplateStorage class DLL_LINKAGE CRmgTemplateStorage
{ {
public: public:
static CRandomMapTemplateStorage & get(); static CRmgTemplateStorage & get();
const std::map<std::string, CRandomMapTemplate> & getTemplates() const; const std::map<std::string, CRmgTemplate> & getTemplates() const;
private: private:
CRandomMapTemplateStorage(); CRmgTemplateStorage();
~CRandomMapTemplateStorage(); ~CRmgTemplateStorage();
static boost::mutex smx; 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; StartInfo si;
c >> si; //get start options c >> si; //get start options
if(!si.createRandomMap) if(!si.createRandomMap())
{ {
bool mapFound = CResourceHandler::get()->existsResource(ResourceID(si.mapname, EResType::MAP)); bool mapFound = CResourceHandler::get()->existsResource(ResourceID(si.mapname, EResType::MAP));