1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Implemented identifiers remapping for game entities

This commit is contained in:
Ivan Savenko 2023-05-23 23:55:18 +03:00
parent c51e0ef052
commit bf720200f9
4 changed files with 139 additions and 36 deletions

View File

@ -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())
{
BuildingID sourceID (entry.second.Integer());
BuildingID targetID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "building.core:random", entry.first));
std::map<IdentifierID, IdentifierID> result;
mappingBuilding[sourceID] = targetID;
for (auto entry : mapping.Struct())
{
IdentifierID sourceID (entry.second.Integer());
IdentifierID targetID (*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), identifierName, entry.first));
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

View File

@ -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

View File

@ -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;

View File

@ -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;