mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
multilevel support
This commit is contained in:
@@ -239,8 +239,7 @@ void CMap::showObject(CGObjectInstance * obj)
|
||||
|
||||
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++)
|
||||
{
|
||||
|
||||
@@ -370,7 +370,7 @@ inline bool CMap::isInTheMap(const int3 & pos) const
|
||||
return
|
||||
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.z) <= (twoLevel ? 1 : 0);
|
||||
static_cast<uint32_t>(pos.z) <= mapLevels - 1;
|
||||
}
|
||||
|
||||
inline TerrainTile & CMap::getTile(const int3 & tile)
|
||||
|
||||
@@ -122,7 +122,7 @@ CMapHeader::CMapHeader()
|
||||
: version(EMapFormat::VCMI)
|
||||
, height(72)
|
||||
, width(72)
|
||||
, twoLevel(true)
|
||||
, mapLevels(2)
|
||||
, difficulty(EMapDifficulty::NORMAL)
|
||||
, levelLimit(0)
|
||||
, victoryIconIndex(0)
|
||||
@@ -139,7 +139,7 @@ CMapHeader::~CMapHeader() = default;
|
||||
|
||||
ui8 CMapHeader::levels() const
|
||||
{
|
||||
return (twoLevel ? 2 : 1);
|
||||
return mapLevels;
|
||||
}
|
||||
|
||||
void CMapHeader::registerMapStrings()
|
||||
|
||||
@@ -246,7 +246,7 @@ public:
|
||||
|
||||
si32 height; /// 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 description;
|
||||
EMapDifficulty difficulty;
|
||||
@@ -295,7 +295,23 @@ public:
|
||||
h & creationDateTime;
|
||||
h & width;
|
||||
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 & levelLimit;
|
||||
|
||||
@@ -563,14 +563,11 @@ CDrawTerrainOperation::ValidationResult::ValidationResult(bool result, std::stri
|
||||
|
||||
CClearTerrainOperation::CClearTerrainOperation(CMap* map, vstd::RNG* gen) : CComposedOperation(map)
|
||||
{
|
||||
CTerrainSelection terrainSel(map);
|
||||
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)
|
||||
for (int i = 0; i < map->mapLevels; i++)
|
||||
{
|
||||
terrainSel.clearSelection();
|
||||
terrainSel.selectRange(MapRect(int3(0, 0, 1), map->width, map->height));
|
||||
addOperation(std::make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainId::ROCK, 0, gen));
|
||||
CTerrainSelection terrainSel(map);
|
||||
terrainSel.selectRange(MapRect(int3(0, 0, i), map->width, map->height));
|
||||
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,...
|
||||
mapHeader->areAnyPlayers = reader->readBool();
|
||||
mapHeader->height = mapHeader->width = reader->readInt32();
|
||||
mapHeader->twoLevel = reader->readBool();
|
||||
mapHeader->mapLevels = reader->readBool() ? 2 : 1;
|
||||
mapHeader->name.appendTextID(readLocalizedString("header.name"));
|
||||
mapHeader->description.appendTextID(readLocalizedString("header.description"));
|
||||
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::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():
|
||||
fileVersionMajor(0), fileVersionMinor(0),
|
||||
@@ -844,7 +853,6 @@ void CMapLoaderJson::readHeader(const bool complete)
|
||||
//loading mods
|
||||
mapHeader->mods = ModVerificationInfo::jsonDeserializeList(header["mods"]);
|
||||
|
||||
//todo: multilevel map load support
|
||||
{
|
||||
auto levels = handler.enterStruct("mapLevels");
|
||||
{
|
||||
@@ -852,10 +860,7 @@ void CMapLoaderJson::readHeader(const bool complete)
|
||||
handler.serializeInt("height", mapHeader->height);
|
||||
handler.serializeInt("width", mapHeader->width);
|
||||
}
|
||||
{
|
||||
auto underground = handler.enterStruct("underground");
|
||||
mapHeader->twoLevel = !underground->getCurrent().isNull();
|
||||
}
|
||||
mapHeader->mapLevels = levels->getCurrent().Struct().size();
|
||||
}
|
||||
|
||||
serializeHeader(handler);
|
||||
@@ -993,14 +998,10 @@ void CMapLoaderJson::readTerrainLevel(const JsonNode & src, const int index)
|
||||
|
||||
void CMapLoaderJson::readTerrain()
|
||||
{
|
||||
for(int i = 0; i < map->mapLevels; i++)
|
||||
{
|
||||
const JsonNode surface = getFromArchive(TERRAIN_FILE_NAMES[0]);
|
||||
readTerrainLevel(surface, 0);
|
||||
}
|
||||
if(map->twoLevel)
|
||||
{
|
||||
const JsonNode underground = getFromArchive(TERRAIN_FILE_NAMES[1]);
|
||||
readTerrainLevel(underground, 1);
|
||||
const JsonNode node = getFromArchive(getTerrainFilename(i));
|
||||
readTerrainLevel(node, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1198,17 +1199,22 @@ void CMapSaverJson::writeHeader()
|
||||
//write mods
|
||||
header["mods"] = ModVerificationInfo::jsonSerializeList(mapHeader->mods);
|
||||
|
||||
//todo: multilevel map save support
|
||||
JsonNode & levels = header["mapLevels"];
|
||||
levels["surface"]["height"].Float() = mapHeader->height;
|
||||
levels["surface"]["width"].Float() = mapHeader->width;
|
||||
levels["surface"]["index"].Float() = 0;
|
||||
auto getName = [](int level){
|
||||
if(level == 0)
|
||||
return std::string("surface");
|
||||
else if(level == 1)
|
||||
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;
|
||||
levels["underground"]["width"].Float() = mapHeader->width;
|
||||
levels["underground"]["index"].Float() = 1;
|
||||
auto name = getName(i);
|
||||
levels[name]["height"].Float() = mapHeader->height;
|
||||
levels[name]["width"].Float() = mapHeader->width;
|
||||
levels[name]["index"].Float() = i;
|
||||
}
|
||||
|
||||
serializeHeader(handler);
|
||||
@@ -1266,15 +1272,11 @@ JsonNode CMapSaverJson::writeTerrainLevel(const int index)
|
||||
void CMapSaverJson::writeTerrain()
|
||||
{
|
||||
logGlobal->trace("Saving terrain");
|
||||
//todo: multilevel map save support
|
||||
|
||||
JsonNode surface = writeTerrainLevel(0);
|
||||
addToArchive(surface, TERRAIN_FILE_NAMES[0]);
|
||||
|
||||
if(map->twoLevel)
|
||||
for(int i = 0; i < map->mapLevels; i++)
|
||||
{
|
||||
JsonNode underground = writeTerrainLevel(1);
|
||||
addToArchive(underground, TERRAIN_FILE_NAMES[1]);
|
||||
JsonNode node = writeTerrainLevel(i);
|
||||
addToArchive(node, getTerrainFilename(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user