Browse Source

Implemented identifiers remapping for game entities

Ivan Savenko 2 years ago
parent
commit
bf720200f9

+ 71 - 5
lib/mapping/MapIdentifiersH3M.cpp

@@ -18,16 +18,24 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-void MapIdentifiersH3M::loadMapping(const JsonNode & mapping)
+template<typename IdentifierID>
+std::map<IdentifierID, IdentifierID> MapIdentifiersH3M::loadMapping(const JsonNode & mapping, const std::string & identifierName)
 {
-	for (auto entry : mapping["buildingsCommon"].Struct())
+	std::map<IdentifierID, IdentifierID> result;
+
+	for (auto entry : mapping.Struct())
 	{
-		BuildingID sourceID (entry.second.Integer());
-		BuildingID targetID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "building.core:random", entry.first));
+		IdentifierID sourceID (entry.second.Integer());
+		IdentifierID targetID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), identifierName, entry.first));
 
-		mappingBuilding[sourceID] = targetID;
+		result[sourceID] = targetID;
 	}
 
+	return result;
+}
+
+void MapIdentifiersH3M::loadMapping(const JsonNode & mapping)
+{
 	for (auto entryFaction : mapping["buildings"].Struct())
 	{
 		FactionID factionID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "faction", entryFaction.first));
@@ -41,6 +49,15 @@ void MapIdentifiersH3M::loadMapping(const JsonNode & mapping)
 			mappingFactionBuilding[factionID][sourceID] = targetID;
 		}
 	}
+
+	mappingBuilding = loadMapping<BuildingID>(mapping["buildingsCommon"], "building.core:random");
+	mappingFaction = loadMapping<FactionID>(mapping["factions"], "faction");
+	mappingCreature = loadMapping<CreatureID>(mapping["creatures"], "creature");
+	mappingHeroType = loadMapping<HeroTypeID>(mapping["heroes"], "hero");
+	mappingHeroClass = loadMapping<HeroClassID>(mapping["heroClasses"], "heroClass");
+	mappingTerrain = loadMapping<TerrainId>(mapping["terrains"], "terrain");
+	mappingArtifact = loadMapping<ArtifactID>(mapping["artifacts"], "artifact");
+	mappingSecondarySkill = loadMapping<SecondarySkill>(mapping["skills"], "skill");
 }
 
 BuildingID MapIdentifiersH3M::remapBuilding(std::optional<FactionID> owner, BuildingID input) const
@@ -58,4 +75,53 @@ BuildingID MapIdentifiersH3M::remapBuilding(std::optional<FactionID> owner, Buil
 	return BuildingID::NONE;
 }
 
+FactionID MapIdentifiersH3M::remap(FactionID input) const
+{
+	if (mappingFaction.count(input))
+		return mappingFaction.at(input);
+	return input;
+}
+
+CreatureID MapIdentifiersH3M::remap(CreatureID input) const
+{
+	if (mappingCreature.count(input))
+		return mappingCreature.at(input);
+	return input;
+}
+
+HeroTypeID MapIdentifiersH3M::remap(HeroTypeID input) const
+{
+	if (mappingHeroType.count(input))
+		return mappingHeroType.at(input);
+	return input;
+}
+
+HeroClassID MapIdentifiersH3M::remap(HeroClassID input) const
+{
+	if (mappingHeroClass.count(input))
+		return mappingHeroClass.at(input);
+	return input;
+}
+
+TerrainId MapIdentifiersH3M::remap(TerrainId input) const
+{
+	if (mappingTerrain.count(input))
+		return mappingTerrain.at(input);
+	return input;
+}
+
+ArtifactID MapIdentifiersH3M::remap(ArtifactID input) const
+{
+	if (mappingArtifact.count(input))
+		return mappingArtifact.at(input);
+	return input;
+}
+
+SecondarySkill MapIdentifiersH3M::remap(SecondarySkill input) const
+{
+	if (mappingSecondarySkill.count(input))
+		return mappingSecondarySkill.at(input);
+	return input;
+}
+
 VCMI_LIB_NAMESPACE_END

+ 17 - 14
lib/mapping/MapIdentifiersH3M.h

@@ -20,24 +20,27 @@ class MapIdentifiersH3M
 {
 	std::map<BuildingID, BuildingID> mappingBuilding;
 	std::map<FactionID, std::map<BuildingID, BuildingID>> mappingFactionBuilding;
-	//std::map<FactionID, FactionID> mappingFaction;
-	//std::map<CreatureID, CreatureID> mappingCreature;
-	//std::map<HeroTypeID, HeroTypeID> mappingHeroType;
-	//std::map<HeroClassID, HeroClassID> mappingHeroClass;
-	//std::map<TerrainId, TerrainId> mappingTerrain;
-	//std::map<ArtifactID, ArtifactID> mappingArtifact;
-	//std::map<SecondarySkill, SecondarySkill> mappingSecondarySkill;
+	std::map<FactionID, FactionID> mappingFaction;
+	std::map<CreatureID, CreatureID> mappingCreature;
+	std::map<HeroTypeID, HeroTypeID> mappingHeroType;
+	std::map<HeroClassID, HeroClassID> mappingHeroClass;
+	std::map<TerrainId, TerrainId> mappingTerrain;
+	std::map<ArtifactID, ArtifactID> mappingArtifact;
+	std::map<SecondarySkill, SecondarySkill> mappingSecondarySkill;
+
+	template<typename IdentifierID>
+	std::map<IdentifierID, IdentifierID> loadMapping(const JsonNode & mapping, const std::string & identifierName);
 public:
 	void loadMapping(const JsonNode & mapping);
 
 	BuildingID remapBuilding(std::optional<FactionID> owner, 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;
+	FactionID remap(FactionID input) const;
+	CreatureID remap(CreatureID input) const;
+	HeroTypeID remap(HeroTypeID input) const;
+	HeroClassID remap(HeroClassID input) const;
+	TerrainId remap(TerrainId input) const;
+	ArtifactID remap(ArtifactID input) const;
+	SecondarySkill remap(SecondarySkill input) const;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 46 - 16
lib/mapping/MapReaderH3M.cpp

@@ -16,6 +16,30 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+template<>
+BuildingID MapReaderH3M::remapIdentifier(const BuildingID & identifier)
+{
+	return identifier;
+}
+
+template<>
+GameResID MapReaderH3M::remapIdentifier(const GameResID & identifier)
+{
+	return identifier;
+}
+
+template<>
+SpellID MapReaderH3M::remapIdentifier(const SpellID & identifier)
+{
+	return identifier;
+}
+
+template<class Identifier>
+Identifier MapReaderH3M::remapIdentifier(const Identifier & identifier)
+{
+	return remapper.remap(identifier);
+}
+
 MapReaderH3M::MapReaderH3M(CInputStream * stream)
 	: reader(std::make_unique<CBinaryReader>(stream))
 {
@@ -44,7 +68,7 @@ ArtifactID MapReaderH3M::readArtifact()
 		return ArtifactID::NONE;
 
 	if (result < features.artifactsCount)
-		return result;
+		return remapIdentifier(result);
 
 	logGlobal->warn("Map contains invalid artifact %d. Will be removed!", result.getNum());
 	return ArtifactID::NONE;
@@ -58,7 +82,7 @@ ArtifactID MapReaderH3M::readArtifact32()
 		return ArtifactID::NONE;
 
 	if (result < features.artifactsCount)
-		return result;
+		return remapIdentifier(result);
 
 	logGlobal->warn("Map contains invalid artifact %d. Will be removed!", result.getNum());
 	return ArtifactID::NONE;
@@ -72,7 +96,7 @@ HeroTypeID MapReaderH3M::readHero()
 		return HeroTypeID(-1);
 
 	assert(result.getNum() < features.heroesPortraitsCount);
-	return result;
+	return remapIdentifier(result);;
 }
 
 CreatureID MapReaderH3M::readCreature()
@@ -88,7 +112,7 @@ CreatureID MapReaderH3M::readCreature()
 		return CreatureID::NONE;
 
 	if(result < features.creaturesCount)
-		return result;
+		return remapIdentifier(result);;
 
 	// this may be random creature in army/town, to be randomized later
 	CreatureID randomIndex(result.getNum() - features.creatureIdentifierInvalid - 1);
@@ -105,7 +129,7 @@ TerrainId MapReaderH3M::readTerrain()
 {
 	TerrainId result(readUInt8());
 	assert(result.getNum() < features.terrainsCount);
-	return result;
+	return remapIdentifier(result);;
 }
 
 RoadId MapReaderH3M::readRoad()
@@ -126,7 +150,7 @@ SecondarySkill MapReaderH3M::readSkill()
 {
 	SecondarySkill result(readUInt8());
 	assert(result < features.skillsCount);
-	return result;
+	return remapIdentifier(result);;
 }
 
 SpellID MapReaderH3M::readSpell()
@@ -138,7 +162,7 @@ SpellID MapReaderH3M::readSpell()
 		return SpellID::PRESET;
 
 	assert(result < features.spellsCount);
-	return result;
+	return remapIdentifier(result);;
 }
 
 SpellID MapReaderH3M::readSpell32()
@@ -199,7 +223,7 @@ void MapReaderH3M::readBitmaskHeroClassesSized(std::set<HeroClassID> & dest, boo
 
 void MapReaderH3M::readBitmaskHeroes(std::vector<bool> & dest, bool invert)
 {
-	readBitmask(dest, features.heroesBytes, features.heroesCount, invert);
+	readBitmask<HeroTypeID>(dest, features.heroesBytes, features.heroesCount, invert);
 }
 
 void MapReaderH3M::readBitmaskHeroesSized(std::vector<bool> & dest, bool invert)
@@ -208,12 +232,12 @@ void MapReaderH3M::readBitmaskHeroesSized(std::vector<bool> & dest, bool invert)
 	uint32_t heroesBytes = (heroesCount + 7) / 8;
 	assert(heroesCount <= features.heroesCount);
 
-	readBitmask(dest, heroesBytes, heroesCount, invert);
+	readBitmask<HeroTypeID>(dest, heroesBytes, heroesCount, invert);
 }
 
 void MapReaderH3M::readBitmaskArtifacts(std::vector<bool> &dest, bool invert)
 {
-	readBitmask(dest, features.artifactsBytes, features.artifactsCount, invert);
+	readBitmask<ArtifactID>(dest, features.artifactsBytes, features.artifactsCount, invert);
 }
 
 void MapReaderH3M::readBitmaskArtifactsSized(std::vector<bool> &dest, bool invert)
@@ -222,12 +246,12 @@ void MapReaderH3M::readBitmaskArtifactsSized(std::vector<bool> &dest, bool inver
 	uint32_t artifactsBytes = (artifactsCount + 7) / 8;
 	assert(artifactsCount <= features.artifactsCount);
 
-	readBitmask(dest, artifactsBytes, artifactsCount, invert);
+	readBitmask<ArtifactID>(dest, artifactsBytes, artifactsCount, invert);
 }
 
 void MapReaderH3M::readBitmaskSpells(std::vector<bool> & dest, bool invert)
 {
-	readBitmask(dest, features.spellsBytes, features.spellsCount, invert);
+	readBitmask<SpellID>(dest, features.spellsBytes, features.spellsCount, invert);
 }
 
 void MapReaderH3M::readBitmaskSpells(std::set<SpellID> & dest, bool invert)
@@ -237,7 +261,7 @@ void MapReaderH3M::readBitmaskSpells(std::set<SpellID> & dest, bool invert)
 
 void MapReaderH3M::readBitmaskSkills(std::vector<bool> & dest, bool invert)
 {
-	readBitmask(dest, features.skillsBytes, features.skillsCount, invert);
+	readBitmask<SecondarySkill>(dest, features.skillsBytes, features.skillsCount, invert);
 }
 
 void MapReaderH3M::readBitmaskSkills(std::set<SecondarySkill> & dest, bool invert)
@@ -245,6 +269,7 @@ void MapReaderH3M::readBitmaskSkills(std::set<SecondarySkill> & dest, bool inver
 	readBitmask(dest, features.skillsBytes, features.skillsCount, invert);
 }
 
+template<class Identifier>
 void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int bytesToRead, const int objectsToRead, bool invert)
 {
 	for(int byte = 0; byte < bytesToRead; ++byte)
@@ -257,7 +282,13 @@ void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int bytesToRead,
 				const size_t index = byte * 8 + bit;
 				const bool flag = mask & (1 << bit);
 				const bool result = (flag != invert);
-				dest[index] = result;
+
+				Identifier h3mID(index);
+				Identifier vcmiID = remapIdentifier(h3mID);
+
+				if (vcmiID.getNum() >= dest.size())
+					dest.resize(vcmiID.getNum() + 1);
+				dest[vcmiID.getNum()] = result;
 			}
 		}
 	}
@@ -268,14 +299,13 @@ void MapReaderH3M::readBitmask(std::set<Identifier> & dest, int bytesToRead, int
 {
 	std::vector<bool> bitmap;
 	bitmap.resize(objectsToRead, false);
-	readBitmask(bitmap, bytesToRead, objectsToRead, invert);
+	readBitmask<Identifier>(bitmap, bytesToRead, objectsToRead, invert);
 
 	for(int i = 0; i < bitmap.size(); i++)
 		if(bitmap[i])
 			dest.insert(static_cast<Identifier>(i));
 }
 
-
 int3 MapReaderH3M::readInt3()
 {
 	int3 p;

+ 4 - 0
lib/mapping/MapReaderH3M.h

@@ -78,9 +78,13 @@ public:
 	CBinaryReader & getInternalReader();
 
 private:
+	template<class Identifier>
+	Identifier remapIdentifier(const Identifier & identifier);
+
 	template<class Identifier>
 	void readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert);
 
+	template<class Identifier>
 	void readBitmask(std::vector<bool> & dest, int bytesToRead, int objectsToRead, bool invert);
 
 	MapFormatFeaturesH3M features;