diff --git a/cmake_modules/VCMI_lib.cmake b/cmake_modules/VCMI_lib.cmake index d847145cb..3fd3997d9 100644 --- a/cmake_modules/VCMI_lib.cmake +++ b/cmake_modules/VCMI_lib.cmake @@ -90,6 +90,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/mapping/CMapOperation.cpp ${MAIN_LIB_DIR}/mapping/CMapService.cpp ${MAIN_LIB_DIR}/mapping/MapEditUtils.cpp + ${MAIN_LIB_DIR}/mapping/MapIdentifiersH3M.cpp ${MAIN_LIB_DIR}/mapping/MapFeaturesH3M.cpp ${MAIN_LIB_DIR}/mapping/MapFormatH3M.cpp ${MAIN_LIB_DIR}/mapping/MapReaderH3M.cpp @@ -386,6 +387,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/mapping/CMapOperation.h ${MAIN_LIB_DIR}/mapping/CMapService.h ${MAIN_LIB_DIR}/mapping/MapEditUtils.h + ${MAIN_LIB_DIR}/mapping/MapIdentifiersH3M.h ${MAIN_LIB_DIR}/mapping/MapFeaturesH3M.h ${MAIN_LIB_DIR}/mapping/MapFormatH3M.h ${MAIN_LIB_DIR}/mapping/MapReaderH3M.h diff --git a/config/buildings5.json b/config/buildings5.json deleted file mode 100644 index ee508242f..000000000 --- a/config/buildings5.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - // Conversion table of buildings between vcmi and H3 - "table": [ - { "town": -1, "h3": 0, "vcmi": 11 }, - { "town": -1, "h3": 1, "vcmi": 12 }, - { "town": -1, "h3": 2, "vcmi": 13 }, - { "town": -1, "h3": 3, "vcmi": 7 }, - { "town": -1, "h3": 4, "vcmi": 8 }, - { "town": -1, "h3": 5, "vcmi": 9 }, - { "town": -1, "h3": 6, "vcmi": 5 }, - { "town": -1, "h3": 7, "vcmi": 16 }, - { "town": -1, "h3": 8, "vcmi": 14 }, - { "town": -1, "h3": 9, "vcmi": 15 }, - { "town": -1, "h3": 10, "vcmi": 17 }, - { "town": -1, "h3": 11, "vcmi": 0 }, - { "town": -1, "h3": 12, "vcmi": 1 }, - { "town": -1, "h3": 13, "vcmi": 2 }, - { "town": -1, "h3": 14, "vcmi": 3 }, - { "town": -1, "h3": 15, "vcmi": 4 }, - { "town": -1, "h3": 16, "vcmi": 6 }, - { "town": -1, "h3": 17, "vcmi": 26 }, - { "town": -1, "h3": 18, "vcmi": 17 }, - { "town": -1, "h3": 19, "vcmi": 22 }, - { "town": -1, "h3": 20, "vcmi": 22 }, - { "town": -1, "h3": 21, "vcmi": 23 }, - { "town": -1, "h3": 22, "vcmi": 30 }, - { "town": -1, "h3": 23, "vcmi": 37 }, - { "town": -1, "h3": 24, "vcmi": -1 }, - { "town": -1, "h3": 25, "vcmi": 31 }, - { "town": -1, "h3": 26, "vcmi": 38 }, - { "town": -1, "h3": 27, "vcmi": -2 }, - { "town": -1, "h3": 28, "vcmi": 32 }, - { "town": -1, "h3": 29, "vcmi": 39 }, - { "town": -1, "h3": 30, "vcmi": -3 }, - { "town": -1, "h3": 31, "vcmi": 33 }, - { "town": -1, "h3": 32, "vcmi": 40 }, - { "town": -1, "h3": 33, "vcmi": -4 }, - { "town": -1, "h3": 34, "vcmi": 34 }, - { "town": -1, "h3": 35, "vcmi": 41 }, - { "town": -1, "h3": 36, "vcmi": -5 }, - { "town": -1, "h3": 37, "vcmi": 35 }, - { "town": -1, "h3": 38, "vcmi": 42 }, - { "town": -1, "h3": 39, "vcmi": 36 }, - { "town": -1, "h3": 40, "vcmi": 43 }, - { "town": 0, "h3": 20, "vcmi": 21 }, - { "town": 1, "h3": 19, "vcmi": 21 }, - { "town": 2, "h3": 18, "vcmi": 22 }, - { "town": 2, "h3": 19, "vcmi": 23 }, - { "town": 2, "h3": 20, "vcmi": 21 }, - { "town": 3, "h3": 20, "vcmi": 23 }, - { "town": 3, "h3": 18, "vcmi": 21 }, - { "town": 4, "h3": 19, "vcmi": 21 }, - { "town": 5, "h3": 20, "vcmi": 23 }, - { "town": 5, "h3": 18, "vcmi": 21 }, - { "town": 6, "h3": 19, "vcmi": 21 }, - { "town": 7, "h3": 20, "vcmi": 17 }, - { "town": 7, "h3": 18, "vcmi": 22 }, - { "town": 7, "h3": 19, "vcmi": 21 }, - { "town": 8, "h3": 18, "vcmi": 21 } - ] -} diff --git a/config/gameConfig.json b/config/gameConfig.json index b24b1625a..0e98de99d 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -127,11 +127,108 @@ "mapFormat" : { "restorationOfErathia" : { "supported" : true, - "iconIndex" : 0 + "iconIndex" : 0, + + "buildingsCommon": { + "townHall" : 0, + "cityHall" : 1, + "capitol" : 2, + + "fort" : 3, + "citadel" : 4, + "castle" : 5, + + "tavern" : 6, + "blacksmith" : 7, + "marketplace" : 8, + "resourceSilo" : 9, + + "mageGuild1" : 11, + "mageGuild2" : 12, + "mageGuild3" : 13, + "mageGuild4" : 14, + "mageGuild5" : 15, + + "shipyard" : 16, + "grail" : 17, + + "dwellingLvl1" : 22, + "dwellingUpLvl1" : 23, + "horde1" : 24, + "dwellingLvl2" : 25, + "dwellingUpLvl2" : 26, + "horde2" : 27, + "dwellingLvl3" : 28, + "dwellingUpLvl3" : 29, + "horde3" : 30, + "dwellingLvl4" : 31, + "dwellingUpLvl4" : 32, + "horde4" : 33, + "dwellingLvl5" : 34, + "dwellingUpLvl5" : 35, + "horde5" : 36, + + "dwellingLvl6" : 37, + "dwellingUpLvl6" : 38, + "dwellingLvl7" : 39, + "dwellingUpLvl7" : 40 + }, + + "buildings" : { + "castle" : { + "special1" : 18, // lighthouse + "special2" : 20, // stables + "special3" : 19 // brotherhoodOfSword + }, + "rampart" : { + "special1" : 18, // mysticPond + "special2" : 19, // fountainOfFortune + "special3" : 20 // treasury + }, + "tower" : { + "special1" : 10, // artifactMerchants + "special2" : 20, // lookoutTower + "special3" : 18, // library + "special4" : 19 // wallOfKnowledge + }, + "inferno" : { + "special2" : 18, // brimstoneStormclouds + "special3" : 19, // castleGate + "special4" : 20 // orderOfFire + }, + "necropolis" : { + "special1" : 18, // coverOfDarkness + "special2" : 19, // necromancyAmplifier + "special3" : 20 // skeletonTransformer + }, + "dungeon" : { + "special1" : 10, // artifactMerchants + "special2" : 18, // manaVortex + "special3" : 19, // portalOfSummoning + "special4" : 20 // battleScholarAcademy + }, + "stronghold" : { + "special1" : 18, // escapeTunnel + "special2" : 19, // freelancersGuild + "special3" : 20, // ballistaYard + "special4" : 21 // hallOfValhalla + }, + "fortress" : { + "special1" : 20, // cageOfWarlords + "special2" : 19, // bloodObelisk + "special3" : 18 // glyphsOfFear + } + } }, "armageddonsBlade" : { "supported" : true, - "iconIndex" : 1 + "iconIndex" : 1, + "buildings" : { + "conflux" : { + "special1" : 10, // artifactMerchants + "special2" : 18 // magicUniversity + } + } }, "shadowOfDeath" : { "supported" : true, diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 5ece9a50c..d06934524 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1752,6 +1752,10 @@ void CGameState::initTowns() vti->setNameTranslated(vti->getTown()->getRandomNameTranslated(nameID)); } + static const BuildingID basicDwellings[] = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7 }; + static const BuildingID upgradedDwellings[] = { BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP }; + static const BuildingID hordes[] = { BuildingID::HORDE_PLACEHOLDER1, BuildingID::HORDE_PLACEHOLDER2, BuildingID::HORDE_PLACEHOLDER3, BuildingID::HORDE_PLACEHOLDER4, BuildingID::HORDE_PLACEHOLDER5, BuildingID::HORDE_PLACEHOLDER6, BuildingID::HORDE_PLACEHOLDER7 }; + //init buildings if(vstd::contains(vti->builtBuildings, BuildingID::DEFAULT)) //give standard set of buildings { @@ -1762,8 +1766,6 @@ void CGameState::initTowns() auto definesBuildingsChances = VLC->settings()->getVector(EGameSettings::TOWNS_STARTING_DWELLING_CHANCES); - BuildingID basicDwellings[] = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7 }; - for(int i = 0; i < definesBuildingsChances.size(); i++) { if((getRandomGenerator().nextInt(1,100) <= definesBuildingsChances[i])) @@ -1773,23 +1775,26 @@ void CGameState::initTowns() } } + // village hall must always exist + vti->builtBuildings.insert(BuildingID::VILLAGE_HALL); + //init hordes for (int i = 0; i < GameConstants::CREATURES_PER_TOWN; i++) { - if (vstd::contains(vti->builtBuildings, (BuildingID::HORDE_PLACEHOLDER1 - i))) //if we have horde for this level + if (vstd::contains(vti->builtBuildings, hordes[i])) //if we have horde for this level { - vti->builtBuildings.erase(BuildingID(BuildingID::HORDE_PLACEHOLDER1 - i));//remove old ID + vti->builtBuildings.erase(hordes[i]);//remove old ID if (vti->getTown()->hordeLvl.at(0) == i)//if town first horde is this one { vti->builtBuildings.insert(BuildingID::HORDE_1);//add it //if we have upgraded dwelling as well - if (vstd::contains(vti->builtBuildings, (BuildingID::DWELL_UP_FIRST + i))) + if (vstd::contains(vti->builtBuildings, upgradedDwellings[i])) vti->builtBuildings.insert(BuildingID::HORDE_1_UPGR);//add it as well } if (vti->getTown()->hordeLvl.at(1) == i)//if town second horde is this one { vti->builtBuildings.insert(BuildingID::HORDE_2); - if (vstd::contains(vti->builtBuildings, (BuildingID::DWELL_UP_FIRST + i))) + if (vstd::contains(vti->builtBuildings, upgradedDwellings[i])) vti->builtBuildings.insert(BuildingID::HORDE_2_UPGR); } } @@ -1815,9 +1820,9 @@ void CGameState::initTowns() for(CCastleEvent &ev : vti->events) { for (int i = 0; igetTown()->hordeLvl.at(0) == i) ev.buildings.insert(BuildingID::HORDE_1); if (vti->getTown()->hordeLvl.at(1) == i) diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 8c5d00977..af8dfe4f2 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -477,7 +477,6 @@ public: HORDE_PLACEHOLDER3 = -32, HORDE_PLACEHOLDER2 = -31, HORDE_PLACEHOLDER1 = -30, - HORDE_BUILDING_CONVERTER = -29, //-1 => -30 NONE = -1, FIRST_REGULAR_ID = 0, MAGES_GUILD_1 = 0, MAGES_GUILD_2, MAGES_GUILD_3, MAGES_GUILD_4, MAGES_GUILD_5, diff --git a/lib/StringConstants.h b/lib/StringConstants.h index 95794f31e..ff0facbd8 100644 --- a/lib/StringConstants.h +++ b/lib/StringConstants.h @@ -56,14 +56,14 @@ namespace EBuildingType { const std::string names [44] = { - "mageGuild1", "mageGuild2", "mageGuild3", "mageGuild4", "mageGuild5", - "tavern", "shipyard", "fort", "citadel", "castle", - "villageHall", "townHall", "cityHall", "capitol", "marketplace", - "resourceSilo", "blacksmith", "special1", "horde1", "horde1Upgr", - "ship", "special2", "special3", "special4", "horde2", - "horde2Upgr", "grail", "extraTownHall", "extraCityHall", "extraCapitol", - "dwellingLvl1", "dwellingLvl2", "dwellingLvl3", "dwellingLvl4", "dwellingLvl5", - "dwellingLvl6", "dwellingLvl7", "dwellingUpLvl1", "dwellingUpLvl2", "dwellingUpLvl3", + "mageGuild1", "mageGuild2", "mageGuild3", "mageGuild4", "mageGuild5", // 5 + "tavern", "shipyard", "fort", "citadel", "castle", // 10 + "villageHall", "townHall", "cityHall", "capitol", "marketplace", // 15 + "resourceSilo", "blacksmith", "special1", "horde1", "horde1Upgr", // 20 + "ship", "special2", "special3", "special4", "horde2", // 25 + "horde2Upgr", "grail", "extraTownHall", "extraCityHall", "extraCapitol", // 30 + "dwellingLvl1", "dwellingLvl2", "dwellingLvl3", "dwellingLvl4", "dwellingLvl5", // 35 + "dwellingLvl6", "dwellingLvl7", "dwellingUpLvl1", "dwellingUpLvl2", "dwellingUpLvl3", // 40 "dwellingUpLvl4", "dwellingUpLvl5", "dwellingUpLvl6", "dwellingUpLvl7" }; } diff --git a/lib/mapping/MapFeaturesH3M.cpp b/lib/mapping/MapFeaturesH3M.cpp index ea165f551..6aecfd6ee 100644 --- a/lib/mapping/MapFeaturesH3M.cpp +++ b/lib/mapping/MapFeaturesH3M.cpp @@ -57,7 +57,7 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesROE() result.skillsCount = 28; result.terrainsCount = 10; result.artifactSlotsCount = 18; - result.buildingsCount = 40; + result.buildingsCount = 41; result.heroIdentifierInvalid = 0xff; result.artifactIdentifierInvalid = 0xff; diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 9953f262d..47c9194ff 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -19,6 +19,7 @@ #include "../CHeroHandler.h" #include "../CSkillHandler.h" #include "../CStopWatch.h" +#include "../GameSettings.h" #include "../RiverHandler.h" #include "../RoadHandler.h" #include "../TerrainHandler.h" @@ -123,7 +124,7 @@ void CMapLoaderH3M::readHeader() { uint32_t hotaVersion = reader->readUInt32(); features = MapFormatFeaturesH3M::find(mapHeader->version, hotaVersion); - reader->setFormatLevel(mapHeader->version, hotaVersion); + reader->setFormatLevel(features); if(hotaVersion > 0) { @@ -145,9 +146,23 @@ void CMapLoaderH3M::readHeader() else { features = MapFormatFeaturesH3M::find(mapHeader->version, 0); - reader->setFormatLevel(mapHeader->version, 0); + reader->setFormatLevel(features); } + MapIdentifiersH3M identifierMapper; + + if (features.levelROE) + identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_RESTORATION_OF_ERATHIA)); + if (features.levelAB) + identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_ARMAGEDDONS_BLADE)); + if (features.levelSOD) + identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_SHADOW_OF_DEATH)); + if (features.levelWOG) + identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_IN_THE_WAKE_OF_GODS)); + if (features.levelHOTA0) + identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_HORN_OF_THE_ABYSS)); + reader->setIdentifierRemapper(identifierMapper); + // include basic mod if(mapHeader->version == EMapFormat::WOG) mapHeader->mods["wake-of-gods"]; @@ -2004,11 +2019,8 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt bool hasCustomBuildings = reader->readBool(); if(hasCustomBuildings) { - reader->readBitmask(object->builtBuildings, features.buildingsBytes, features.buildingsCount, false); - reader->readBitmask(object->forbiddenBuildings, features.buildingsBytes, features.buildingsCount, false); - - object->builtBuildings = convertBuildings(object->builtBuildings, objectTemplate->subid); - object->forbiddenBuildings = convertBuildings(object->forbiddenBuildings, objectTemplate->subid); + reader->readBitmaskBuildings(object->builtBuildings, FactionID(objectTemplate->subid)); + reader->readBitmaskBuildings(object->forbiddenBuildings, FactionID(objectTemplate->subid)); } // Standard buildings else @@ -2074,10 +2086,7 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt reader->skipZero(17); // New buildings - - reader->readBitmask(event.buildings, features.buildingsBytes, features.buildingsCount, false); - - event.buildings = convertBuildings(event.buildings, objectTemplate->subid, false); + reader->readBitmaskBuildings(event.buildings, FactionID(objectTemplate->subid)); event.creatures.resize(7); for(int i = 0; i < 7; ++i) @@ -2123,67 +2132,6 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt return object; } -std::set CMapLoaderH3M::convertBuildings(const std::set & h3m, int castleID, bool addAuxiliary) const -{ - std::map helperMap; - std::set ret; - - // Note: this file is parsed many times. - static const JsonNode config(ResourceID("config/buildings5.json")); - - for(const JsonNode & entry : config["table"].Vector()) - { - int town = static_cast(entry["town"].Float()); - - if(town == castleID || town == -1) - { - helperMap[static_cast(entry["h3"].Float())] = BuildingID(static_cast(entry["vcmi"].Float())); - } - } - - for(const auto & elem : h3m) - { - if(helperMap[elem] >= BuildingID::FIRST_REGULAR_ID) - { - ret.insert(helperMap[elem]); - } - // horde buildings use indexes from -1 to -5, where creature level is 1 to 5 - else if(helperMap[elem] >= (-GameConstants::CREATURES_PER_TOWN)) - { - int level = (helperMap[elem]); - - //(-30)..(-36) - horde buildings (for game loading only) - //They will be replaced in CGameState::initTowns() - ret.insert(BuildingID(level + BuildingID::HORDE_BUILDING_CONVERTER)); //-1 => -30 - } - else - { - logGlobal->warn("Conversion warning: unknown building %d in castle %d", elem.num, castleID); - } - } - - if(addAuxiliary) - { - //village hall is always present - ret.insert(BuildingID::VILLAGE_HALL); - - if(ret.find(BuildingID::CITY_HALL) != ret.end()) - { - ret.insert(BuildingID::EXTRA_CITY_HALL); - } - if(ret.find(BuildingID::TOWN_HALL) != ret.end()) - { - ret.insert(BuildingID::EXTRA_TOWN_HALL); - } - if(ret.find(BuildingID::CAPITOL) != ret.end()) - { - ret.insert(BuildingID::EXTRA_CAPITOL); - } - } - - return ret; -} - void CMapLoaderH3M::readEvents() { uint32_t eventsCount = reader->readUInt32(); diff --git a/lib/mapping/MapFormatH3M.h b/lib/mapping/MapFormatH3M.h index 27c63466a..4ea3f66f2 100644 --- a/lib/mapping/MapFormatH3M.h +++ b/lib/mapping/MapFormatH3M.h @@ -209,16 +209,6 @@ private: void readSeerHutQuest(CGSeerHut * hut, const int3 & position); - /** - * Converts buildings to the specified castle id. - * - * @param h3m the ids of the buildings - * @param castleID the castle id - * @param addAuxiliary true if the village hall should be added - * @return the converted buildings - */ - std::set convertBuildings(const std::set & h3m, int castleID, bool addAuxiliary = true) const; - /** * Reads events. */ diff --git a/lib/mapping/MapIdentifiersH3M.cpp b/lib/mapping/MapIdentifiersH3M.cpp new file mode 100644 index 000000000..400217555 --- /dev/null +++ b/lib/mapping/MapIdentifiersH3M.cpp @@ -0,0 +1,70 @@ +/* + * MapIdentifiersH3M.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +#include "StdInc.h" +#include "MapIdentifiersH3M.h" + +#include "../JsonNode.h" +#include "../VCMI_Lib.h" +#include "../CModHandler.h" +#include "../CTownHandler.h" + +VCMI_LIB_NAMESPACE_BEGIN + +void MapIdentifiersH3M::loadMapping(const JsonNode & mapping) +{ + for (auto entry : mapping["buildingsCommon"].Struct()) + { + BuildingID sourceID (entry.second.Integer()); + BuildingID targetID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "building.core:random", entry.first)); + + mappingBuilding[sourceID] = targetID; + } + + for (auto entryFaction : mapping["buildings"].Struct()) + { + FactionID factionID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "faction", entryFaction.first)); + auto buildingMap = entryFaction.second; + + for (auto entryBuilding : buildingMap.Struct()) + { + BuildingID sourceID (entryBuilding.second.Integer()); + BuildingID targetID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "building." + VLC->factions()->getById(factionID)->getJsonKey(), entryBuilding.first)); + + mappingFactionBuilding[factionID][sourceID] = targetID; + } + } +} + +BuildingID MapIdentifiersH3M::remapBuilding(FactionID owner, BuildingID input) const +{ + if (mappingFactionBuilding.count(owner)) + { + auto submap = mappingFactionBuilding.at(owner); + + if (submap.count(input)) + return submap.at(input); + } + + if (mappingBuilding.count(input)) + return mappingBuilding.at(input); + logGlobal->warn("Not mapped building ID %d found for faction %d!", input, owner); + return input; +} + +BuildingID MapIdentifiersH3M::remapBuilding(BuildingID input) const +{ + if (mappingBuilding.count(input)) + return mappingBuilding.at(input); + logGlobal->warn("Not mapped building ID %d found!"); + return input; +} + +VCMI_LIB_NAMESPACE_END diff --git a/lib/mapping/MapIdentifiersH3M.h b/lib/mapping/MapIdentifiersH3M.h new file mode 100644 index 000000000..770dc5430 --- /dev/null +++ b/lib/mapping/MapIdentifiersH3M.h @@ -0,0 +1,44 @@ +/* + * MapIdentifiersH3M.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +#pragma once + +#include "../GameConstants.h" + +VCMI_LIB_NAMESPACE_BEGIN + +class JsonNode; + +class MapIdentifiersH3M +{ + std::map mappingBuilding; + std::map> mappingFactionBuilding; + //std::map mappingFaction; + //std::map mappingCreature; + //std::map mappingHeroType; + //std::map mappingHeroClass; + //std::map mappingTerrain; + //std::map mappingArtifact; + //std::map mappingSecondarySkill; +public: + void loadMapping(const JsonNode & mapping); + + BuildingID remapBuilding(FactionID owner, BuildingID input) const; + BuildingID remapBuilding(BuildingID input) const; + //FactionID remapFaction(FactionID input) const; + //CreatureID remapCreature(CreatureID input) const; + //HeroTypeID remapHeroType(HeroTypeID input) const; + //HeroClassID remapHeroClass(HeroClassID input) const; + //TerrainId remapTerrain(TerrainId input) const; + //ArtifactID remapArtifact(ArtifactID input) const; + //SecondarySkill remapSecondarySkill(SecondarySkill input) const; +}; + +VCMI_LIB_NAMESPACE_END diff --git a/lib/mapping/MapReaderH3M.cpp b/lib/mapping/MapReaderH3M.cpp index 89bb22040..6e17fa608 100644 --- a/lib/mapping/MapReaderH3M.cpp +++ b/lib/mapping/MapReaderH3M.cpp @@ -21,9 +21,14 @@ MapReaderH3M::MapReaderH3M(CInputStream * stream) { } -void MapReaderH3M::setFormatLevel(EMapFormat newFormat, uint8_t hotaVersion) +void MapReaderH3M::setFormatLevel(const MapFormatFeaturesH3M & newFeatures) { - features = MapFormatFeaturesH3M::find(newFormat, hotaVersion); + features = newFeatures; +} + +void MapReaderH3M::setIdentifierRemapper(const MapIdentifiersH3M & newRemapper) +{ + remapper = newRemapper; } ArtifactID MapReaderH3M::readArtifact() @@ -160,6 +165,15 @@ PlayerColor MapReaderH3M::readPlayer32() return result; } +void MapReaderH3M::readBitmaskBuildings(std::set & dest, FactionID faction) +{ + std::set h3m; + readBitmask(h3m, features.buildingsBytes, features.buildingsCount, false); + + for (auto const & h3mEntry : h3m) + dest.insert(remapper.remapBuilding(faction, h3mEntry)); +} + void MapReaderH3M::readBitmask(std::vector & dest, const int bytesToRead, const int objectsToRead, bool invert) { for(int byte = 0; byte < bytesToRead; ++byte) diff --git a/lib/mapping/MapReaderH3M.h b/lib/mapping/MapReaderH3M.h index 4a7344c97..936d34034 100644 --- a/lib/mapping/MapReaderH3M.h +++ b/lib/mapping/MapReaderH3M.h @@ -13,6 +13,7 @@ #include "../GameConstants.h" #include "../ResourceSet.h" #include "MapFeaturesH3M.h" +#include "MapIdentifiersH3M.h" VCMI_LIB_NAMESPACE_BEGIN @@ -27,7 +28,8 @@ class MapReaderH3M public: explicit MapReaderH3M(CInputStream * stream); - void setFormatLevel(EMapFormat format, uint8_t hotaVersion); + void setFormatLevel(const MapFormatFeaturesH3M & features); + void setIdentifierRemapper(const MapIdentifiersH3M & remapper); ArtifactID readArtifact(); ArtifactID readArtifact32(); @@ -54,6 +56,8 @@ public: dest.insert(static_cast(i)); } + void readBitmaskBuildings(std::set & dest, FactionID faction); + /** Reads bitmask to boolean vector * @param dest destination vector, shall be filed with "true" values * @param byteCount size in bytes of bimask @@ -87,6 +91,7 @@ public: private: MapFormatFeaturesH3M features; + MapIdentifiersH3M remapper; std::unique_ptr reader; };