mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
multilevel support
This commit is contained in:
@@ -154,7 +154,7 @@ void AdventureMapShortcuts::worldViewScale4x()
|
|||||||
void AdventureMapShortcuts::switchMapLevel()
|
void AdventureMapShortcuts::switchMapLevel()
|
||||||
{
|
{
|
||||||
int maxLevels = GAME->interface()->cb->getMapSize().z;
|
int maxLevels = GAME->interface()->cb->getMapSize().z;
|
||||||
if (maxLevels < 2)
|
if (maxLevels < 2) // TODO: multilevel support
|
||||||
return;
|
return;
|
||||||
|
|
||||||
owner.hotkeySwitchMapLevel();
|
owner.hotkeySwitchMapLevel();
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ void AdventureMapWidget::updateActiveStateChildden(CIntObject * widget)
|
|||||||
if (container->disableCondition == "heroSleeping")
|
if (container->disableCondition == "heroSleeping")
|
||||||
container->setEnabled(shortcuts->optionHeroSleeping());
|
container->setEnabled(shortcuts->optionHeroSleeping());
|
||||||
|
|
||||||
if (container->disableCondition == "mapLayerSurface")
|
if (container->disableCondition == "mapLayerSurface") // TODO: multilevel support
|
||||||
container->setEnabled(shortcuts->optionMapLevelSurface());
|
container->setEnabled(shortcuts->optionMapLevelSurface());
|
||||||
|
|
||||||
if (container->disableCondition == "mapLayerUnderground")
|
if (container->disableCondition == "mapLayerUnderground")
|
||||||
|
|||||||
@@ -54,15 +54,15 @@ RandomMapTab::RandomMapTab():
|
|||||||
mapGenOptions->setWidth(mapSizeVal[btnId]);
|
mapGenOptions->setWidth(mapSizeVal[btnId]);
|
||||||
mapGenOptions->setHeight(mapSizeVal[btnId]);
|
mapGenOptions->setHeight(mapSizeVal[btnId]);
|
||||||
if(mapGenOptions->getMapTemplate())
|
if(mapGenOptions->getMapTemplate())
|
||||||
if(!mapGenOptions->getMapTemplate()->matchesSize(int3{mapGenOptions->getWidth(), mapGenOptions->getHeight(), 1 + mapGenOptions->getHasTwoLevels()}))
|
if(!mapGenOptions->getMapTemplate()->matchesSize(int3{mapGenOptions->getWidth(), mapGenOptions->getHeight(), mapGenOptions->getLevels()}))
|
||||||
setTemplate(nullptr);
|
setTemplate(nullptr);
|
||||||
updateMapInfoByHost();
|
updateMapInfoByHost();
|
||||||
});
|
});
|
||||||
addCallback("toggleTwoLevels", [&](bool on)
|
addCallback("toggleTwoLevels", [&](bool on)
|
||||||
{
|
{
|
||||||
mapGenOptions->setHasTwoLevels(on);
|
mapGenOptions->setLevels(on ? 2 : 1); // TODO: multilevel support
|
||||||
if(mapGenOptions->getMapTemplate())
|
if(mapGenOptions->getMapTemplate())
|
||||||
if(!mapGenOptions->getMapTemplate()->matchesSize(int3{mapGenOptions->getWidth(), mapGenOptions->getHeight(), 1 + mapGenOptions->getHasTwoLevels()}))
|
if(!mapGenOptions->getMapTemplate()->matchesSize(int3{mapGenOptions->getWidth(), mapGenOptions->getHeight(), mapGenOptions->getLevels()}))
|
||||||
setTemplate(nullptr);
|
setTemplate(nullptr);
|
||||||
updateMapInfoByHost();
|
updateMapInfoByHost();
|
||||||
});
|
});
|
||||||
@@ -202,7 +202,7 @@ void RandomMapTab::updateMapInfoByHost()
|
|||||||
mapInfo->mapHeader->difficulty = EMapDifficulty::NORMAL;
|
mapInfo->mapHeader->difficulty = EMapDifficulty::NORMAL;
|
||||||
mapInfo->mapHeader->height = mapGenOptions->getHeight();
|
mapInfo->mapHeader->height = mapGenOptions->getHeight();
|
||||||
mapInfo->mapHeader->width = mapGenOptions->getWidth();
|
mapInfo->mapHeader->width = mapGenOptions->getWidth();
|
||||||
mapInfo->mapHeader->twoLevel = mapGenOptions->getHasTwoLevels();
|
mapInfo->mapHeader->mapLevels = mapGenOptions->getLevels();
|
||||||
|
|
||||||
// Generate player information
|
// Generate player information
|
||||||
int playersToGen = mapGenOptions->getMaxPlayersCount();
|
int playersToGen = mapGenOptions->getMaxPlayersCount();
|
||||||
@@ -321,7 +321,7 @@ void RandomMapTab::setMapGenOptions(std::shared_ptr<CMapGenOptions> opts)
|
|||||||
if(auto button = std::dynamic_pointer_cast<CToggleButton>(toggle.second))
|
if(auto button = std::dynamic_pointer_cast<CToggleButton>(toggle.second))
|
||||||
{
|
{
|
||||||
const auto & mapSizes = getPossibleMapSizes();
|
const auto & mapSizes = getPossibleMapSizes();
|
||||||
int3 size( mapSizes[toggle.first], mapSizes[toggle.first], 1 + mapGenOptions->getHasTwoLevels());
|
int3 size( mapSizes[toggle.first], mapSizes[toggle.first], mapGenOptions->getLevels());
|
||||||
|
|
||||||
bool sizeAllowed = !mapGenOptions->getMapTemplate() || mapGenOptions->getMapTemplate()->matchesSize(size);
|
bool sizeAllowed = !mapGenOptions->getMapTemplate() || mapGenOptions->getMapTemplate()->matchesSize(size);
|
||||||
button->block(!sizeAllowed);
|
button->block(!sizeAllowed);
|
||||||
@@ -335,7 +335,7 @@ void RandomMapTab::setMapGenOptions(std::shared_ptr<CMapGenOptions> opts)
|
|||||||
|
|
||||||
bool undergoundAllowed = !mapGenOptions->getMapTemplate() || mapGenOptions->getMapTemplate()->matchesSize(size);
|
bool undergoundAllowed = !mapGenOptions->getMapTemplate() || mapGenOptions->getMapTemplate()->matchesSize(size);
|
||||||
|
|
||||||
w->setSelected(opts->getHasTwoLevels());
|
w->setSelected(opts->getLevels() == 2); // TODO: multilevel support
|
||||||
w->block(!undergoundAllowed);
|
w->block(!undergoundAllowed);
|
||||||
}
|
}
|
||||||
if(auto w = widget<CToggleGroup>("groupMaxPlayers"))
|
if(auto w = widget<CToggleGroup>("groupMaxPlayers"))
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ std::vector<std::shared_ptr<CanvasImage>> CMapOverviewWidget::createMinimaps(std
|
|||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<CanvasImage>> ret;
|
std::vector<std::shared_ptr<CanvasImage>> ret;
|
||||||
|
|
||||||
for(int i = 0; i < (map->twoLevel ? 2 : 1); i++)
|
for(int i = 0; i < map->levels(); i++)
|
||||||
ret.push_back(createMinimapForLayer(map, i));
|
ret.push_back(createMinimapForLayer(map, i));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -129,6 +129,7 @@ std::vector<std::shared_ptr<CanvasImage>> CMapOverviewWidget::createMinimaps(std
|
|||||||
|
|
||||||
std::shared_ptr<CPicture> CMapOverviewWidget::buildDrawMinimap(const JsonNode & config) const
|
std::shared_ptr<CPicture> CMapOverviewWidget::buildDrawMinimap(const JsonNode & config) const
|
||||||
{
|
{
|
||||||
|
// TODO: multilevel support
|
||||||
logGlobal->debug("Building widget drawMinimap");
|
logGlobal->debug("Building widget drawMinimap");
|
||||||
|
|
||||||
auto rect = readRect(config["rect"]);
|
auto rect = readRect(config["rect"]);
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ MinimapWithIcons::MinimapWithIcons(const Point & position)
|
|||||||
Rect borderSurface(10, 40, 147, 147);
|
Rect borderSurface(10, 40, 147, 147);
|
||||||
Rect borderUnderground(166, 40, 147, 147);
|
Rect borderUnderground(166, 40, 147, 147);
|
||||||
|
|
||||||
bool singleLevelMap = GAME->interface()->cb->getMapSize().z == 1;
|
bool singleLevelMap = GAME->interface()->cb->getMapSize().z == 1; // TODO: multilevel support
|
||||||
|
|
||||||
if (singleLevelMap)
|
if (singleLevelMap)
|
||||||
{
|
{
|
||||||
@@ -375,7 +375,7 @@ void MinimapWithIcons::addIcon(const int3 & coordinates, const ImagePath & image
|
|||||||
|
|
||||||
Rect areaSurface(11, 41, 144, 144);
|
Rect areaSurface(11, 41, 144, 144);
|
||||||
Rect areaUnderground(167, 41, 144, 144);
|
Rect areaUnderground(167, 41, 144, 144);
|
||||||
bool singleLevelMap = GAME->interface()->cb->getMapSize().z == 1;
|
bool singleLevelMap = GAME->interface()->cb->getMapSize().z == 1; // TODO: multilevel support
|
||||||
if (singleLevelMap)
|
if (singleLevelMap)
|
||||||
areaSurface.x += 78;
|
areaSurface.x += 78;
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ bool MapInfoCallback::isAllowed(SecondarySkill id) const
|
|||||||
|
|
||||||
int3 MapInfoCallback::getMapSize() const
|
int3 MapInfoCallback::getMapSize() const
|
||||||
{
|
{
|
||||||
return int3(getMapConstPtr()->width, getMapConstPtr()->height, getMapConstPtr()->twoLevel ? 2 : 1);
|
return int3(getMapConstPtr()->width, getMapConstPtr()->height, getMapConstPtr()->levels());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
void MapInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ float Statistic::getMapExploredRatio(const CGameState * gs, PlayerColor player)
|
|||||||
float visible = 0.0;
|
float visible = 0.0;
|
||||||
float numTiles = 0.0;
|
float numTiles = 0.0;
|
||||||
|
|
||||||
for(int layer = 0; layer < (gs->getMap().twoLevel ? 2 : 1); layer++)
|
for(int layer = 0; layer < gs->getMap().levels(); layer++)
|
||||||
for(int y = 0; y < gs->getMap().height; ++y)
|
for(int y = 0; y < gs->getMap().height; ++y)
|
||||||
for(int x = 0; x < gs->getMap().width; ++x)
|
for(int x = 0; x < gs->getMap().width; ++x)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -239,8 +239,7 @@ void CMap::showObject(CGObjectInstance * obj)
|
|||||||
|
|
||||||
void CMap::calculateGuardingGreaturePositions()
|
void CMap::calculateGuardingGreaturePositions()
|
||||||
{
|
{
|
||||||
int levels = twoLevel ? 2 : 1;
|
for(int z = 0; z < levels(); z++)
|
||||||
for(int z = 0; z < levels; z++)
|
|
||||||
{
|
{
|
||||||
for(int x = 0; x < width; x++)
|
for(int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ inline bool CMap::isInTheMap(const int3 & pos) const
|
|||||||
return
|
return
|
||||||
static_cast<uint32_t>(pos.x) < static_cast<uint32_t>(width) &&
|
static_cast<uint32_t>(pos.x) < static_cast<uint32_t>(width) &&
|
||||||
static_cast<uint32_t>(pos.y) < static_cast<uint32_t>(height) &&
|
static_cast<uint32_t>(pos.y) < static_cast<uint32_t>(height) &&
|
||||||
static_cast<uint32_t>(pos.z) <= (twoLevel ? 1 : 0);
|
static_cast<uint32_t>(pos.z) <= mapLevels - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TerrainTile & CMap::getTile(const int3 & tile)
|
inline TerrainTile & CMap::getTile(const int3 & tile)
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ CMapHeader::CMapHeader()
|
|||||||
: version(EMapFormat::VCMI)
|
: version(EMapFormat::VCMI)
|
||||||
, height(72)
|
, height(72)
|
||||||
, width(72)
|
, width(72)
|
||||||
, twoLevel(true)
|
, mapLevels(2)
|
||||||
, difficulty(EMapDifficulty::NORMAL)
|
, difficulty(EMapDifficulty::NORMAL)
|
||||||
, levelLimit(0)
|
, levelLimit(0)
|
||||||
, victoryIconIndex(0)
|
, victoryIconIndex(0)
|
||||||
@@ -139,7 +139,7 @@ CMapHeader::~CMapHeader() = default;
|
|||||||
|
|
||||||
ui8 CMapHeader::levels() const
|
ui8 CMapHeader::levels() const
|
||||||
{
|
{
|
||||||
return (twoLevel ? 2 : 1);
|
return mapLevels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHeader::registerMapStrings()
|
void CMapHeader::registerMapStrings()
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ public:
|
|||||||
|
|
||||||
si32 height; /// The default value is 72.
|
si32 height; /// The default value is 72.
|
||||||
si32 width; /// The default value is 72.
|
si32 width; /// The default value is 72.
|
||||||
bool twoLevel; /// The default value is true.
|
si32 mapLevels; /// The default value is 2.
|
||||||
MetaString name;
|
MetaString name;
|
||||||
MetaString description;
|
MetaString description;
|
||||||
EMapDifficulty difficulty;
|
EMapDifficulty difficulty;
|
||||||
@@ -295,7 +295,23 @@ public:
|
|||||||
h & creationDateTime;
|
h & creationDateTime;
|
||||||
h & width;
|
h & width;
|
||||||
h & height;
|
h & height;
|
||||||
h & twoLevel;
|
if (h.version >= Handler::Version::MORE_MAP_LAYERS)
|
||||||
|
h & mapLevels;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (h.saving)
|
||||||
|
{
|
||||||
|
bool hasTwoLevels = mapLevels == 2;
|
||||||
|
h & hasTwoLevels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool hasTwoLevels;
|
||||||
|
h & hasTwoLevels;
|
||||||
|
mapLevels = hasTwoLevels ? 2 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
h & difficulty;
|
h & difficulty;
|
||||||
|
|
||||||
h & levelLimit;
|
h & levelLimit;
|
||||||
|
|||||||
@@ -563,14 +563,11 @@ CDrawTerrainOperation::ValidationResult::ValidationResult(bool result, std::stri
|
|||||||
|
|
||||||
CClearTerrainOperation::CClearTerrainOperation(CMap* map, vstd::RNG* gen) : CComposedOperation(map)
|
CClearTerrainOperation::CClearTerrainOperation(CMap* map, vstd::RNG* gen) : CComposedOperation(map)
|
||||||
{
|
{
|
||||||
CTerrainSelection terrainSel(map);
|
for (int i = 0; i < map->mapLevels; i++)
|
||||||
terrainSel.selectRange(MapRect(int3(0, 0, 0), map->width, map->height));
|
|
||||||
addOperation(std::make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainId::WATER, 0, gen));
|
|
||||||
if(map->twoLevel)
|
|
||||||
{
|
{
|
||||||
terrainSel.clearSelection();
|
CTerrainSelection terrainSel(map);
|
||||||
terrainSel.selectRange(MapRect(int3(0, 0, 1), map->width, map->height));
|
terrainSel.selectRange(MapRect(int3(0, 0, i), map->width, map->height));
|
||||||
addOperation(std::make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainId::ROCK, 0, gen));
|
addOperation(std::make_unique<CDrawTerrainOperation>(map, terrainSel, i == 1 ? ETerrainId::ROCK : ETerrainId::WATER, 0, gen));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ void CMapLoaderH3M::readHeader()
|
|||||||
// Read map name, description, dimensions,...
|
// Read map name, description, dimensions,...
|
||||||
mapHeader->areAnyPlayers = reader->readBool();
|
mapHeader->areAnyPlayers = reader->readBool();
|
||||||
mapHeader->height = mapHeader->width = reader->readInt32();
|
mapHeader->height = mapHeader->width = reader->readInt32();
|
||||||
mapHeader->twoLevel = reader->readBool();
|
mapHeader->mapLevels = reader->readBool() ? 2 : 1;
|
||||||
mapHeader->name.appendTextID(readLocalizedString("header.name"));
|
mapHeader->name.appendTextID(readLocalizedString("header.name"));
|
||||||
mapHeader->description.appendTextID(readLocalizedString("header.description"));
|
mapHeader->description.appendTextID(readLocalizedString("header.description"));
|
||||||
mapHeader->author.appendRawString("");
|
mapHeader->author.appendRawString("");
|
||||||
|
|||||||
@@ -240,7 +240,16 @@ const int CMapFormatJson::VERSION_MINOR = 0;
|
|||||||
|
|
||||||
const std::string CMapFormatJson::HEADER_FILE_NAME = "header.json";
|
const std::string CMapFormatJson::HEADER_FILE_NAME = "header.json";
|
||||||
const std::string CMapFormatJson::OBJECTS_FILE_NAME = "objects.json";
|
const std::string CMapFormatJson::OBJECTS_FILE_NAME = "objects.json";
|
||||||
const std::string CMapFormatJson::TERRAIN_FILE_NAMES[2] = {"surface_terrain.json", "underground_terrain.json"};
|
|
||||||
|
std::string getTerrainFilename(int i)
|
||||||
|
{
|
||||||
|
if(i == 0)
|
||||||
|
return "surface_terrain.json";
|
||||||
|
else if(i == 1)
|
||||||
|
return "underground_terrain.json";
|
||||||
|
else
|
||||||
|
return "level-" + std::to_string(i + 1) + "_terrain.json";
|
||||||
|
}
|
||||||
|
|
||||||
CMapFormatJson::CMapFormatJson():
|
CMapFormatJson::CMapFormatJson():
|
||||||
fileVersionMajor(0), fileVersionMinor(0),
|
fileVersionMajor(0), fileVersionMinor(0),
|
||||||
@@ -844,7 +853,6 @@ void CMapLoaderJson::readHeader(const bool complete)
|
|||||||
//loading mods
|
//loading mods
|
||||||
mapHeader->mods = ModVerificationInfo::jsonDeserializeList(header["mods"]);
|
mapHeader->mods = ModVerificationInfo::jsonDeserializeList(header["mods"]);
|
||||||
|
|
||||||
//todo: multilevel map load support
|
|
||||||
{
|
{
|
||||||
auto levels = handler.enterStruct("mapLevels");
|
auto levels = handler.enterStruct("mapLevels");
|
||||||
{
|
{
|
||||||
@@ -852,10 +860,7 @@ void CMapLoaderJson::readHeader(const bool complete)
|
|||||||
handler.serializeInt("height", mapHeader->height);
|
handler.serializeInt("height", mapHeader->height);
|
||||||
handler.serializeInt("width", mapHeader->width);
|
handler.serializeInt("width", mapHeader->width);
|
||||||
}
|
}
|
||||||
{
|
mapHeader->mapLevels = levels->getCurrent().Struct().size();
|
||||||
auto underground = handler.enterStruct("underground");
|
|
||||||
mapHeader->twoLevel = !underground->getCurrent().isNull();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
serializeHeader(handler);
|
serializeHeader(handler);
|
||||||
@@ -993,14 +998,10 @@ void CMapLoaderJson::readTerrainLevel(const JsonNode & src, const int index)
|
|||||||
|
|
||||||
void CMapLoaderJson::readTerrain()
|
void CMapLoaderJson::readTerrain()
|
||||||
{
|
{
|
||||||
|
for(int i = 0; i < map->mapLevels; i++)
|
||||||
{
|
{
|
||||||
const JsonNode surface = getFromArchive(TERRAIN_FILE_NAMES[0]);
|
const JsonNode node = getFromArchive(getTerrainFilename(i));
|
||||||
readTerrainLevel(surface, 0);
|
readTerrainLevel(node, i);
|
||||||
}
|
|
||||||
if(map->twoLevel)
|
|
||||||
{
|
|
||||||
const JsonNode underground = getFromArchive(TERRAIN_FILE_NAMES[1]);
|
|
||||||
readTerrainLevel(underground, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1198,17 +1199,22 @@ void CMapSaverJson::writeHeader()
|
|||||||
//write mods
|
//write mods
|
||||||
header["mods"] = ModVerificationInfo::jsonSerializeList(mapHeader->mods);
|
header["mods"] = ModVerificationInfo::jsonSerializeList(mapHeader->mods);
|
||||||
|
|
||||||
//todo: multilevel map save support
|
auto getName = [](int level){
|
||||||
JsonNode & levels = header["mapLevels"];
|
if(level == 0)
|
||||||
levels["surface"]["height"].Float() = mapHeader->height;
|
return std::string("surface");
|
||||||
levels["surface"]["width"].Float() = mapHeader->width;
|
else if(level == 1)
|
||||||
levels["surface"]["index"].Float() = 0;
|
return std::string("underground");
|
||||||
|
else
|
||||||
|
return "level-" + std::to_string(level + 1);
|
||||||
|
};
|
||||||
|
|
||||||
if(mapHeader->twoLevel)
|
JsonNode & levels = header["mapLevels"];
|
||||||
|
for(int i = 0; i < map->mapLevels; i++)
|
||||||
{
|
{
|
||||||
levels["underground"]["height"].Float() = mapHeader->height;
|
auto name = getName(i);
|
||||||
levels["underground"]["width"].Float() = mapHeader->width;
|
levels[name]["height"].Float() = mapHeader->height;
|
||||||
levels["underground"]["index"].Float() = 1;
|
levels[name]["width"].Float() = mapHeader->width;
|
||||||
|
levels[name]["index"].Float() = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
serializeHeader(handler);
|
serializeHeader(handler);
|
||||||
@@ -1266,15 +1272,11 @@ JsonNode CMapSaverJson::writeTerrainLevel(const int index)
|
|||||||
void CMapSaverJson::writeTerrain()
|
void CMapSaverJson::writeTerrain()
|
||||||
{
|
{
|
||||||
logGlobal->trace("Saving terrain");
|
logGlobal->trace("Saving terrain");
|
||||||
//todo: multilevel map save support
|
|
||||||
|
|
||||||
JsonNode surface = writeTerrainLevel(0);
|
for(int i = 0; i < map->mapLevels; i++)
|
||||||
addToArchive(surface, TERRAIN_FILE_NAMES[0]);
|
|
||||||
|
|
||||||
if(map->twoLevel)
|
|
||||||
{
|
{
|
||||||
JsonNode underground = writeTerrainLevel(1);
|
JsonNode node = writeTerrainLevel(i);
|
||||||
addToArchive(underground, TERRAIN_FILE_NAMES[1]);
|
addToArchive(node, getTerrainFilename(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
CMapGenOptions::CMapGenOptions()
|
CMapGenOptions::CMapGenOptions()
|
||||||
: width(CMapHeader::MAP_SIZE_MIDDLE), height(CMapHeader::MAP_SIZE_MIDDLE), hasTwoLevels(true),
|
: width(CMapHeader::MAP_SIZE_MIDDLE), height(CMapHeader::MAP_SIZE_MIDDLE), levels(2),
|
||||||
humanOrCpuPlayerCount(RANDOM_SIZE), teamCount(RANDOM_SIZE), compOnlyPlayerCount(RANDOM_SIZE), compOnlyTeamCount(RANDOM_SIZE),
|
humanOrCpuPlayerCount(RANDOM_SIZE), teamCount(RANDOM_SIZE), compOnlyPlayerCount(RANDOM_SIZE), compOnlyTeamCount(RANDOM_SIZE),
|
||||||
waterContent(EWaterContent::RANDOM), monsterStrength(EMonsterStrength::RANDOM), mapTemplate(nullptr),
|
waterContent(EWaterContent::RANDOM), monsterStrength(EMonsterStrength::RANDOM), mapTemplate(nullptr),
|
||||||
customizedPlayers(false)
|
customizedPlayers(false)
|
||||||
@@ -54,14 +54,14 @@ void CMapGenOptions::setHeight(si32 value)
|
|||||||
height = value;
|
height = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMapGenOptions::getHasTwoLevels() const
|
int CMapGenOptions::getLevels() const
|
||||||
{
|
{
|
||||||
return hasTwoLevels;
|
return levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenOptions::setHasTwoLevels(bool value)
|
void CMapGenOptions::setLevels(int value)
|
||||||
{
|
{
|
||||||
hasTwoLevels = value;
|
levels = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
si8 CMapGenOptions::getHumanOrCpuPlayerCount() const
|
si8 CMapGenOptions::getHumanOrCpuPlayerCount() const
|
||||||
@@ -425,12 +425,12 @@ void CMapGenOptions::setMapTemplate(const CRmgTemplate * value)
|
|||||||
//validate & adapt options according to template
|
//validate & adapt options according to template
|
||||||
if(mapTemplate)
|
if(mapTemplate)
|
||||||
{
|
{
|
||||||
if(!mapTemplate->matchesSize(int3(getWidth(), getHeight(), 1 + getHasTwoLevels())))
|
if(!mapTemplate->matchesSize(int3(getWidth(), getHeight(), getLevels())))
|
||||||
{
|
{
|
||||||
auto sizes = mapTemplate->getMapSizes();
|
auto sizes = mapTemplate->getMapSizes();
|
||||||
setWidth(sizes.first.x);
|
setWidth(sizes.first.x);
|
||||||
setHeight(sizes.first.y);
|
setHeight(sizes.first.y);
|
||||||
setHasTwoLevels(sizes.first.z - 1);
|
setLevels(sizes.first.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
si8 maxPlayerCount = getMaxPlayersCount(false);
|
si8 maxPlayerCount = getMaxPlayersCount(false);
|
||||||
@@ -488,7 +488,7 @@ void CMapGenOptions::setPlayerTeam(const PlayerColor & color, const TeamID & tea
|
|||||||
|
|
||||||
void CMapGenOptions::finalize(vstd::RNG & rand)
|
void CMapGenOptions::finalize(vstd::RNG & rand)
|
||||||
{
|
{
|
||||||
logGlobal->info("RMG map: %dx%d, %s underground", getWidth(), getHeight(), getHasTwoLevels() ? "WITH" : "NO");
|
logGlobal->info("RMG map: %dx%d, %s underground", getWidth(), getHeight(), getLevels() >= 2 ? "WITH" : "NO");
|
||||||
logGlobal->info("RMG settings: players %d, teams %d, computer players %d, computer teams %d, water %d, monsters %d",
|
logGlobal->info("RMG settings: players %d, teams %d, computer players %d, computer teams %d, water %d, monsters %d",
|
||||||
static_cast<int>(getHumanOrCpuPlayerCount()), static_cast<int>(getTeamCount()), static_cast<int>(getCompOnlyPlayerCount()),
|
static_cast<int>(getHumanOrCpuPlayerCount()), static_cast<int>(getTeamCount()), static_cast<int>(getCompOnlyPlayerCount()),
|
||||||
static_cast<int>(getCompOnlyTeamCount()), static_cast<int>(getWaterContent()), static_cast<int>(getMonsterStrength()));
|
static_cast<int>(getCompOnlyTeamCount()), static_cast<int>(getWaterContent()), static_cast<int>(getMonsterStrength()));
|
||||||
@@ -700,7 +700,7 @@ bool CMapGenOptions::arePlayersCustomized() const
|
|||||||
|
|
||||||
std::vector<const CRmgTemplate *> CMapGenOptions::getPossibleTemplates() const
|
std::vector<const CRmgTemplate *> CMapGenOptions::getPossibleTemplates() const
|
||||||
{
|
{
|
||||||
int3 tplSize(width, height, (hasTwoLevels ? 2 : 1));
|
int3 tplSize(width, height, levels);
|
||||||
auto humanPlayers = countHumanPlayers();
|
auto humanPlayers = countHumanPlayers();
|
||||||
|
|
||||||
auto templates = LIBRARY->tplh->getTemplates();
|
auto templates = LIBRARY->tplh->getTemplates();
|
||||||
@@ -825,7 +825,12 @@ void CMapGenOptions::serializeJson(JsonSerializeFormat & handler)
|
|||||||
{
|
{
|
||||||
handler.serializeInt("width", width);
|
handler.serializeInt("width", width);
|
||||||
handler.serializeInt("height", height);
|
handler.serializeInt("height", height);
|
||||||
handler.serializeBool("haswoLevels", hasTwoLevels);
|
bool hasTwoLevelsKey = !handler.getCurrent()["haswoLevels"].isNull();
|
||||||
|
bool hasTwoLevels = levels == 2;
|
||||||
|
if(handler.saving || !hasTwoLevelsKey)
|
||||||
|
handler.serializeInt("levels", levels);
|
||||||
|
else
|
||||||
|
handler.serializeBool("haswoLevels", hasTwoLevels);
|
||||||
handler.serializeInt("humanOrCpuPlayerCount", humanOrCpuPlayerCount);
|
handler.serializeInt("humanOrCpuPlayerCount", humanOrCpuPlayerCount);
|
||||||
handler.serializeInt("teamCount", teamCount);
|
handler.serializeInt("teamCount", teamCount);
|
||||||
handler.serializeInt("compOnlyPlayerCount", compOnlyPlayerCount);
|
handler.serializeInt("compOnlyPlayerCount", compOnlyPlayerCount);
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ public:
|
|||||||
si32 getHeight() const;
|
si32 getHeight() const;
|
||||||
void setHeight(si32 value);
|
void setHeight(si32 value);
|
||||||
|
|
||||||
bool getHasTwoLevels() const;
|
int getLevels() const;
|
||||||
void setHasTwoLevels(bool value);
|
void setLevels(int value);
|
||||||
|
|
||||||
/// The count of all (human or computer) players ranging from 1 to PlayerColor::PLAYER_LIMIT or RANDOM_SIZE for random. If you call
|
/// The count of all (human or computer) 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.
|
||||||
@@ -170,7 +170,7 @@ private:
|
|||||||
|
|
||||||
si32 width;
|
si32 width;
|
||||||
si32 height;
|
si32 height;
|
||||||
bool hasTwoLevels;
|
si32 levels;
|
||||||
si8 humanOrCpuPlayerCount;
|
si8 humanOrCpuPlayerCount;
|
||||||
si8 teamCount;
|
si8 teamCount;
|
||||||
si8 compOnlyPlayerCount;
|
si8 compOnlyPlayerCount;
|
||||||
@@ -190,7 +190,22 @@ public:
|
|||||||
{
|
{
|
||||||
h & width;
|
h & width;
|
||||||
h & height;
|
h & height;
|
||||||
h & hasTwoLevels;
|
if (h.version >= Handler::Version::MORE_MAP_LAYERS)
|
||||||
|
h & levels;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (h.saving)
|
||||||
|
{
|
||||||
|
bool hasTwoLevels = levels == 2;
|
||||||
|
h & hasTwoLevels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool hasTwoLevels;
|
||||||
|
h & hasTwoLevels;
|
||||||
|
levels = hasTwoLevels ? 2 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
h & humanOrCpuPlayerCount;
|
h & humanOrCpuPlayerCount;
|
||||||
h & teamCount;
|
h & teamCount;
|
||||||
h & compOnlyPlayerCount;
|
h & compOnlyPlayerCount;
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ void CMapGenerator::addHeaderInfo()
|
|||||||
m.version = EMapFormat::VCMI;
|
m.version = EMapFormat::VCMI;
|
||||||
m.width = mapGenOptions.getWidth();
|
m.width = mapGenOptions.getWidth();
|
||||||
m.height = mapGenOptions.getHeight();
|
m.height = mapGenOptions.getHeight();
|
||||||
m.twoLevel = mapGenOptions.getHasTwoLevels();
|
m.mapLevels = mapGenOptions.getLevels();
|
||||||
m.name.appendLocalString(EMetaText::GENERAL_TXT, 740);
|
m.name.appendLocalString(EMetaText::GENERAL_TXT, 740);
|
||||||
m.description = getMapDescription();
|
m.description = getMapDescription();
|
||||||
m.difficulty = EMapDifficulty::NORMAL;
|
m.difficulty = EMapDifficulty::NORMAL;
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ void CZonePlacer::placeZones(vstd::RNG * rand)
|
|||||||
{
|
{
|
||||||
return pr.second->getType() == ETemplateZoneType::WATER;
|
return pr.second->getType() == ETemplateZoneType::WATER;
|
||||||
});
|
});
|
||||||
bool underground = map.getMapGenOptions().getHasTwoLevels();
|
bool mapLevels = map.getMapGenOptions().getLevels();
|
||||||
|
|
||||||
findPathsBetweenZones();
|
findPathsBetweenZones();
|
||||||
placeOnGrid(rand);
|
placeOnGrid(rand);
|
||||||
@@ -347,7 +347,7 @@ void CZonePlacer::placeZones(vstd::RNG * rand)
|
|||||||
RandomGeneratorUtil::randomShuffle(zonesVector, *rand);
|
RandomGeneratorUtil::randomShuffle(zonesVector, *rand);
|
||||||
|
|
||||||
//0. set zone sizes and surface / underground level
|
//0. set zone sizes and surface / underground level
|
||||||
prepareZones(zones, zonesVector, underground, rand);
|
prepareZones(zones, zonesVector, mapLevels, rand);
|
||||||
|
|
||||||
std::map<std::shared_ptr<Zone>, float3> bestSolution;
|
std::map<std::shared_ptr<Zone>, float3> bestSolution;
|
||||||
|
|
||||||
@@ -441,21 +441,44 @@ void CZonePlacer::placeZones(vstd::RNG * rand)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, vstd::RNG * rand)
|
void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const int mapLevels, vstd::RNG * rand)
|
||||||
{
|
{
|
||||||
std::vector<float> totalSize = { 0, 0 }; //make sure that sum of zone sizes on surface and uderground match size of the map
|
std::map<int, float> totalSize; //make sure that sum of zone sizes on surface and uderground match size of the map
|
||||||
|
|
||||||
int zonesOnLevel[2] = { 0, 0 };
|
std::map<int, int> zonesOnLevel;
|
||||||
|
for (int i = 0; i < mapLevels; i++)
|
||||||
|
zonesOnLevel[i] = 0;
|
||||||
|
|
||||||
//even distribution for surface / underground zones. Surface zones always have priority.
|
//even distribution for surface / underground zones. Surface zones always have priority.
|
||||||
|
|
||||||
TZoneVector zonesToPlace;
|
TZoneVector zonesToPlace;
|
||||||
std::map<TRmgTemplateZoneId, int> levels;
|
std::map<TRmgTemplateZoneId, int> levels;
|
||||||
|
|
||||||
|
auto addZoneEqually = [&](auto & zone, bool ignoreUnderground = false) {
|
||||||
|
int chosenLevel = -1;
|
||||||
|
int minCount = std::numeric_limits<int>::max();
|
||||||
|
|
||||||
|
for (const auto& [level, count] : zonesOnLevel) {
|
||||||
|
if (ignoreUnderground && level == 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (count < minCount ||
|
||||||
|
(count == minCount && level == 0) ||
|
||||||
|
(count == minCount && chosenLevel != 0 && level < chosenLevel))
|
||||||
|
{
|
||||||
|
chosenLevel = level;
|
||||||
|
minCount = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
levels[zone.first] = chosenLevel;
|
||||||
|
zonesOnLevel[chosenLevel]++;
|
||||||
|
};
|
||||||
|
|
||||||
//first pass - determine fixed surface for zones
|
//first pass - determine fixed surface for zones
|
||||||
for(const auto & zone : zonesVector)
|
for(const auto & zone : zonesVector)
|
||||||
{
|
{
|
||||||
if (!underground) //this step is ignored
|
if (mapLevels == 1) //this step is ignored
|
||||||
zonesToPlace.push_back(zone);
|
zonesToPlace.push_back(zone);
|
||||||
else //place players depending on their factions
|
else //place players depending on their factions
|
||||||
{
|
{
|
||||||
@@ -495,8 +518,7 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//surface
|
//surface
|
||||||
zonesOnLevel[0]++;
|
addZoneEqually(zone, true);
|
||||||
levels[zone.first] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -509,17 +531,8 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
}
|
}
|
||||||
for(const auto & zone : zonesToPlace)
|
for(const auto & zone : zonesToPlace)
|
||||||
{
|
{
|
||||||
if (underground) //only then consider underground zones
|
if (mapLevels > 1) //only then consider underground zones
|
||||||
{
|
addZoneEqually(zone);
|
||||||
int level = 0;
|
|
||||||
if (zonesOnLevel[1] < zonesOnLevel[0]) //only if there are less underground zones
|
|
||||||
level = 1;
|
|
||||||
else
|
|
||||||
level = 0;
|
|
||||||
|
|
||||||
levels[zone.first] = level;
|
|
||||||
zonesOnLevel[level]++;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
levels[zone.first] = 0;
|
levels[zone.first] = 0;
|
||||||
}
|
}
|
||||||
@@ -541,8 +554,8 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
prescaler = sqrt((WH)/(sum(n^2)*pi))
|
prescaler = sqrt((WH)/(sum(n^2)*pi))
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::vector<float> prescaler = { 0, 0 };
|
std::map<int, float> prescaler;
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < mapLevels; i++)
|
||||||
prescaler[i] = std::sqrt((width * height) / (totalSize[i] * PI_CONSTANT));
|
prescaler[i] = std::sqrt((width * height) / (totalSize[i] * PI_CONSTANT));
|
||||||
mapSize = static_cast<float>(sqrt(width * height));
|
mapSize = static_cast<float>(sqrt(width * height));
|
||||||
for(const auto & zone : zones)
|
for(const auto & zone : zones)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
const TDistanceMap & getDistanceMap();
|
const TDistanceMap & getDistanceMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, vstd::RNG * rand);
|
void prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const int mapLevels, vstd::RNG * rand);
|
||||||
void attractConnectedZones(TZoneMap & zones, TForceVector & forces, TDistanceVector & distances) const;
|
void attractConnectedZones(TZoneMap & zones, TForceVector & forces, TDistanceVector & distances) const;
|
||||||
void separateOverlappingZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &overlaps);
|
void separateOverlappingZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &overlaps);
|
||||||
void moveOneZone(TZoneMap & zones, TForceVector & totalForces, TDistanceVector & distances, TDistanceVector & overlaps);
|
void moveOneZone(TZoneMap & zones, TForceVector & totalForces, TDistanceVector & distances, TDistanceVector & overlaps);
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ enum class ESerializationVersion : int32_t
|
|||||||
UNIVERSITY_CONFIG, // town university is configurable
|
UNIVERSITY_CONFIG, // town university is configurable
|
||||||
CAMPAIGN_BONUSES, // new format for scenario bonuses in campaigns
|
CAMPAIGN_BONUSES, // new format for scenario bonuses in campaigns
|
||||||
BONUS_HIDDEN, // hidden bonus
|
BONUS_HIDDEN, // hidden bonus
|
||||||
|
MORE_MAP_LAYERS, // more map layers
|
||||||
|
|
||||||
CURRENT = BONUS_HIDDEN,
|
CURRENT = MORE_MAP_LAYERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ESerializationVersion::MINIMAL <= ESerializationVersion::CURRENT, "Invalid serialization version definition!");
|
static_assert(ESerializationVersion::MINIMAL <= ESerializationVersion::CURRENT, "Invalid serialization version definition!");
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ void MainWindow::initializeMap(bool isNew)
|
|||||||
ui->actionMapSettings->setEnabled(true);
|
ui->actionMapSettings->setEnabled(true);
|
||||||
ui->actionPlayers_settings->setEnabled(true);
|
ui->actionPlayers_settings->setEnabled(true);
|
||||||
ui->actionTranslations->setEnabled(true);
|
ui->actionTranslations->setEnabled(true);
|
||||||
ui->actionLevel->setEnabled(controller.map()->twoLevel);
|
ui->actionLevel->setEnabled(controller.map()->mapLevels == 2); // TODO: multilevel support
|
||||||
|
|
||||||
//set minimal players count
|
//set minimal players count
|
||||||
if(isNew)
|
if(isNew)
|
||||||
@@ -968,7 +968,7 @@ void MainWindow::loadObjectsTree()
|
|||||||
|
|
||||||
void MainWindow::on_actionLevel_triggered()
|
void MainWindow::on_actionLevel_triggered()
|
||||||
{
|
{
|
||||||
if(controller.map() && controller.map()->twoLevel)
|
if(controller.map() && controller.map()->mapLevels == 2) // TODO: multilevel support
|
||||||
{
|
{
|
||||||
mapLevel = mapLevel ? 0 : 1;
|
mapLevel = mapLevel ? 0 : 1;
|
||||||
ui->mapView->setScene(controller.scene(mapLevel));
|
ui->mapView->setScene(controller.scene(mapLevel));
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ void MapController::sceneForceUpdate()
|
|||||||
{
|
{
|
||||||
_scenes[0]->updateViews();
|
_scenes[0]->updateViews();
|
||||||
_miniscenes[0]->updateViews();
|
_miniscenes[0]->updateViews();
|
||||||
if(_map->twoLevel)
|
if(_map->mapLevels == 2) // TODO: multilevel support
|
||||||
{
|
{
|
||||||
_scenes[1]->updateViews();
|
_scenes[1]->updateViews();
|
||||||
_miniscenes[1]->updateViews();
|
_miniscenes[1]->updateViews();
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ void MapHandler::initObjectRects()
|
|||||||
if(!map)
|
if(!map)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tileObjects.resize(map->width * map->height * (map->twoLevel ? 2 : 1));
|
tileObjects.resize(map->width * map->height * map->mapLevels);
|
||||||
|
|
||||||
//initializing objects / rects
|
//initializing objects / rects
|
||||||
for(const auto & elem : map->objects)
|
for(const auto & elem : map->objects)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ void PassabilityLayer::update()
|
|||||||
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
|
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
|
||||||
pixmap->fill(Qt::transparent);
|
pixmap->fill(Qt::transparent);
|
||||||
|
|
||||||
if(scene->level == 0 || map->twoLevel)
|
if(scene->level == 0 || map->mapLevels == 2) // TODO: multilevel support
|
||||||
{
|
{
|
||||||
QPainter painter(pixmap.get());
|
QPainter painter(pixmap.get());
|
||||||
for(int j = 0; j < map->height; ++j)
|
for(int j = 0; j < map->height; ++j)
|
||||||
@@ -121,7 +121,7 @@ void ObjectPickerLayer::highlight(std::function<bool(const CGObjectInstance *)>
|
|||||||
if(!map)
|
if(!map)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(scene->level == 0 || map->twoLevel)
|
if(scene->level == 0 || map->mapLevels == 2) // TODO: multilevel support
|
||||||
{
|
{
|
||||||
for(int j = 0; j < map->height; ++j)
|
for(int j = 0; j < map->height; ++j)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ WindowNewMap::WindowNewMap(QWidget *parent) :
|
|||||||
mapGenOptions.setWidth(width ? width : 1);
|
mapGenOptions.setWidth(width ? width : 1);
|
||||||
mapGenOptions.setHeight(height ? height : 1);
|
mapGenOptions.setHeight(height ? height : 1);
|
||||||
bool twoLevel = ui->twoLevelCheck->isChecked();
|
bool twoLevel = ui->twoLevelCheck->isChecked();
|
||||||
mapGenOptions.setHasTwoLevels(twoLevel);
|
mapGenOptions.setLevels(twoLevel ? 2 : 1); // TODO: multilevel support
|
||||||
|
|
||||||
updateTemplateList();
|
updateTemplateList();
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ bool WindowNewMap::loadUserSettings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->twoLevelCheck->setChecked(mapGenOptions.getHasTwoLevels());
|
ui->twoLevelCheck->setChecked(mapGenOptions.getLevels() == 2); // TODO: multilevel support
|
||||||
|
|
||||||
ui->humanCombo->setCurrentIndex(mapGenOptions.getHumanOrCpuPlayerCount());
|
ui->humanCombo->setCurrentIndex(mapGenOptions.getHumanOrCpuPlayerCount());
|
||||||
ui->cpuCombo->setCurrentIndex(mapGenOptions.getCompOnlyPlayerCount());
|
ui->cpuCombo->setCurrentIndex(mapGenOptions.getCompOnlyPlayerCount());
|
||||||
@@ -213,7 +213,7 @@ std::unique_ptr<CMap> generateEmptyMap(CMapGenOptions & options)
|
|||||||
map->creationDateTime = std::time(nullptr);
|
map->creationDateTime = std::time(nullptr);
|
||||||
map->width = options.getWidth();
|
map->width = options.getWidth();
|
||||||
map->height = options.getHeight();
|
map->height = options.getHeight();
|
||||||
map->twoLevel = options.getHasTwoLevels();
|
map->mapLevels = options.getLevels();
|
||||||
|
|
||||||
map->initTerrain();
|
map->initTerrain();
|
||||||
map->getEditManager()->clearTerrain(&CRandomGenerator::getDefault());
|
map->getEditManager()->clearTerrain(&CRandomGenerator::getDefault());
|
||||||
@@ -331,7 +331,7 @@ void WindowNewMap::on_sizeCombo_activated(int index)
|
|||||||
void WindowNewMap::on_twoLevelCheck_stateChanged(int arg1)
|
void WindowNewMap::on_twoLevelCheck_stateChanged(int arg1)
|
||||||
{
|
{
|
||||||
bool twoLevel = ui->twoLevelCheck->isChecked();
|
bool twoLevel = ui->twoLevelCheck->isChecked();
|
||||||
mapGenOptions.setHasTwoLevels(twoLevel);
|
mapGenOptions.setLevels(twoLevel ? 2 : 1); // TODO: multilevel support
|
||||||
updateTemplateList();
|
updateTemplateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ TEST(MapFormat, DISABLED_Random)
|
|||||||
|
|
||||||
opt.setHeight(CMapHeader::MAP_SIZE_MIDDLE);
|
opt.setHeight(CMapHeader::MAP_SIZE_MIDDLE);
|
||||||
opt.setWidth(CMapHeader::MAP_SIZE_MIDDLE);
|
opt.setWidth(CMapHeader::MAP_SIZE_MIDDLE);
|
||||||
opt.setHasTwoLevels(true);
|
opt.setLevels(2);
|
||||||
opt.setHumanOrCpuPlayerCount(4);
|
opt.setHumanOrCpuPlayerCount(4);
|
||||||
|
|
||||||
opt.setPlayerTypeForStandardPlayer(PlayerColor(0), EPlayerType::HUMAN);
|
opt.setPlayerTypeForStandardPlayer(PlayerColor(0), EPlayerType::HUMAN);
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ void MapComparer::compareHeader()
|
|||||||
//map size parameters are vital for further checks
|
//map size parameters are vital for further checks
|
||||||
VCMI_REQUIRE_FIELD_EQUAL_P(height);
|
VCMI_REQUIRE_FIELD_EQUAL_P(height);
|
||||||
VCMI_REQUIRE_FIELD_EQUAL_P(width);
|
VCMI_REQUIRE_FIELD_EQUAL_P(width);
|
||||||
VCMI_REQUIRE_FIELD_EQUAL_P(twoLevel);
|
VCMI_REQUIRE_FIELD_EQUAL_P(mapLevels);
|
||||||
|
|
||||||
VCMI_CHECK_FIELD_EQUAL_P(name);
|
VCMI_CHECK_FIELD_EQUAL_P(name);
|
||||||
VCMI_CHECK_FIELD_EQUAL_P(description);
|
VCMI_CHECK_FIELD_EQUAL_P(description);
|
||||||
|
|||||||
Reference in New Issue
Block a user