diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 47c9194ff..af3bd4b41 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -2005,6 +2005,10 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt setOwnerAndValidate(position, object, reader->readPlayer()); + std::optional faction; + if (objectTemplate->id == Obj::TOWN) + faction = FactionID(objectTemplate->subid); + bool hasName = reader->readBool(); if(hasName) object->setNameTranslated(readLocalizedString(TextIdentifier("town", position.x, position.y, position.z, "name"))); @@ -2019,8 +2023,8 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt bool hasCustomBuildings = reader->readBool(); if(hasCustomBuildings) { - reader->readBitmaskBuildings(object->builtBuildings, FactionID(objectTemplate->subid)); - reader->readBitmaskBuildings(object->forbiddenBuildings, FactionID(objectTemplate->subid)); + reader->readBitmaskBuildings(object->builtBuildings, faction); + reader->readBitmaskBuildings(object->forbiddenBuildings, faction); } // Standard buildings else @@ -2086,7 +2090,7 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt reader->skipZero(17); // New buildings - reader->readBitmaskBuildings(event.buildings, FactionID(objectTemplate->subid)); + reader->readBitmaskBuildings(event.buildings, faction); event.creatures.resize(7); for(int i = 0; i < 7; ++i) diff --git a/lib/mapping/MapIdentifiersH3M.cpp b/lib/mapping/MapIdentifiersH3M.cpp index 400217555..23e6a5285 100644 --- a/lib/mapping/MapIdentifiersH3M.cpp +++ b/lib/mapping/MapIdentifiersH3M.cpp @@ -43,11 +43,11 @@ void MapIdentifiersH3M::loadMapping(const JsonNode & mapping) } } -BuildingID MapIdentifiersH3M::remapBuilding(FactionID owner, BuildingID input) const +BuildingID MapIdentifiersH3M::remapBuilding(std::optional owner, BuildingID input) const { - if (mappingFactionBuilding.count(owner)) + if (owner.has_value() && mappingFactionBuilding.count(*owner)) { - auto submap = mappingFactionBuilding.at(owner); + auto submap = mappingFactionBuilding.at(*owner); if (submap.count(input)) return submap.at(input); @@ -55,16 +55,7 @@ BuildingID MapIdentifiersH3M::remapBuilding(FactionID owner, BuildingID input) c 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; + return BuildingID::NONE; } VCMI_LIB_NAMESPACE_END diff --git a/lib/mapping/MapIdentifiersH3M.h b/lib/mapping/MapIdentifiersH3M.h index 770dc5430..01e48b387 100644 --- a/lib/mapping/MapIdentifiersH3M.h +++ b/lib/mapping/MapIdentifiersH3M.h @@ -30,8 +30,7 @@ class MapIdentifiersH3M public: void loadMapping(const JsonNode & mapping); - BuildingID remapBuilding(FactionID owner, BuildingID input) const; - BuildingID remapBuilding(BuildingID input) const; + BuildingID remapBuilding(std::optional owner, BuildingID input) const; //FactionID remapFaction(FactionID input) const; //CreatureID remapCreature(CreatureID input) const; //HeroTypeID remapHeroType(HeroTypeID input) const; diff --git a/lib/mapping/MapReaderH3M.cpp b/lib/mapping/MapReaderH3M.cpp index 6e17fa608..e8d068575 100644 --- a/lib/mapping/MapReaderH3M.cpp +++ b/lib/mapping/MapReaderH3M.cpp @@ -165,13 +165,18 @@ PlayerColor MapReaderH3M::readPlayer32() return result; } -void MapReaderH3M::readBitmaskBuildings(std::set & dest, FactionID faction) +void MapReaderH3M::readBitmaskBuildings(std::set & dest, std::optional faction) { std::set h3m; readBitmask(h3m, features.buildingsBytes, features.buildingsCount, false); for (auto const & h3mEntry : h3m) - dest.insert(remapper.remapBuilding(faction, h3mEntry)); + { + BuildingID mapped = remapper.remapBuilding(faction, h3mEntry); + + if (mapped != BuildingID::NONE) // artifact merchant may be set in random town, but not present in actual town + dest.insert(mapped); + } } void MapReaderH3M::readBitmask(std::vector & dest, const int bytesToRead, const int objectsToRead, bool invert) diff --git a/lib/mapping/MapReaderH3M.h b/lib/mapping/MapReaderH3M.h index 936d34034..c82c2caea 100644 --- a/lib/mapping/MapReaderH3M.h +++ b/lib/mapping/MapReaderH3M.h @@ -56,7 +56,7 @@ public: dest.insert(static_cast(i)); } - void readBitmaskBuildings(std::set & dest, FactionID faction); + void readBitmaskBuildings(std::set & dest, std::optional faction); /** Reads bitmask to boolean vector * @param dest destination vector, shall be filed with "true" values