Przeglądaj źródła

Fix loading of buildings of random town

Ivan Savenko 2 lat temu
rodzic
commit
5fe5d0c045

+ 7 - 3
lib/mapping/MapFormatH3M.cpp

@@ -2005,6 +2005,10 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt
 
 	setOwnerAndValidate(position, object, reader->readPlayer());
 
+	std::optional<FactionID> 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)

+ 4 - 13
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<FactionID> 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

+ 1 - 2
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<FactionID> owner, BuildingID input) const;
 	//FactionID remapFaction(FactionID input) const;
 	//CreatureID remapCreature(CreatureID input) const;
 	//HeroTypeID remapHeroType(HeroTypeID input) const;

+ 7 - 2
lib/mapping/MapReaderH3M.cpp

@@ -165,13 +165,18 @@ PlayerColor MapReaderH3M::readPlayer32()
 	return result;
 }
 
-void MapReaderH3M::readBitmaskBuildings(std::set<BuildingID> & dest, FactionID faction)
+void MapReaderH3M::readBitmaskBuildings(std::set<BuildingID> & dest, std::optional<FactionID> faction)
 {
 	std::set<BuildingID> 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<bool> & dest, const int bytesToRead, const int objectsToRead, bool invert)

+ 1 - 1
lib/mapping/MapReaderH3M.h

@@ -56,7 +56,7 @@ public:
 				dest.insert(static_cast<Identifier>(i));
 	}
 
-	void readBitmaskBuildings(std::set<BuildingID> & dest, FactionID faction);
+	void readBitmaskBuildings(std::set<BuildingID> & dest, std::optional<FactionID> faction);
 
 	/** Reads bitmask to boolean vector
 	* @param dest destination vector, shall be filed with "true" values