1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

All h3m bitsets are now loaded inside mapReader

This commit is contained in:
Ivan Savenko 2023-05-23 22:41:21 +03:00
parent 5fe5d0c045
commit 8d0dcd6ad7
6 changed files with 119 additions and 69 deletions

View File

@ -1403,7 +1403,7 @@ void CGWitchHut::initObj(CRandomGenerator & rand)
for(int i = 0; i < defaultAllowed.size(); i++)
if (defaultAllowed[i] && cb->isAllowed(2, i))
allowedAbilities.insert(i);
allowedAbilities.insert(SecondarySkill(i));
}
ability = *RandomGeneratorUtil::nextItem(allowedAbilities, rand);
}
@ -1479,7 +1479,7 @@ void CGWitchHut::serializeJsonOptions(JsonSerializeFormat & handler)
allowedAbilities.clear();
for(si32 i = 0; i < skillCount; ++i)
if(temp[i])
allowedAbilities.insert(i);
allowedAbilities.insert(SecondarySkill(i));
}
}

View File

@ -131,8 +131,8 @@ protected:
class DLL_LINKAGE CGWitchHut : public CTeamVisited
{
public:
std::set<si32> allowedAbilities;
ui32 ability;
std::set<SecondarySkill> allowedAbilities;
SecondarySkill ability;
std::string getHoverText(PlayerColor player) const override;
std::string getHoverText(const CGHeroInstance * hero) const override;

View File

@ -214,7 +214,7 @@ void CMapLoaderH3M::readPlayerInfo()
std::set<FactionID> allowedFactions;
reader->readBitmask(allowedFactions, features.factionsBytes, features.factionsCount, false);
reader->readBitmaskFactions(allowedFactions, false);
const bool isFactionRandom = playerInfo.isFactionRandom = reader->readBool();
const bool allFactionsAllowed = isFactionRandom && allowedFactions.size() == features.factionsCount;
@ -612,18 +612,10 @@ void CMapLoaderH3M::readAllowedHeroes()
{
mapHeader->allowedHeroes = VLC->heroh->getDefaultAllowed();
uint32_t heroesCount = features.heroesCount;
uint32_t heroesBytes = features.heroesBytes;
if(features.levelHOTA0)
{
heroesCount = reader->readUInt32();
heroesBytes = (heroesCount + 7) / 8;
}
assert(heroesCount <= features.heroesCount);
reader->readBitmask(mapHeader->allowedHeroes, heroesBytes, heroesCount, false);
reader->readBitmaskHeroesSized(mapHeader->allowedHeroes, false);
else
reader->readBitmaskHeroes(mapHeader->allowedHeroes, false);
//TODO: unknown value. Check meaning? Only present in campaign maps.
if(features.levelAB)
@ -687,18 +679,13 @@ void CMapLoaderH3M::readAllowedArtifacts()
{
map->allowedArtifact = VLC->arth->getDefaultAllowed();
uint32_t artifactsCount = features.artifactsCount;
uint32_t artifactsBytes = features.artifactsBytes;
if(features.levelHOTA0)
{
artifactsCount = reader->readUInt32();
artifactsBytes = (artifactsCount + 7) / 8;
}
assert(artifactsCount <= features.artifactsCount);
if(features.levelAB)
reader->readBitmask(map->allowedArtifact, artifactsBytes, artifactsCount, true);
{
if(features.levelHOTA0)
reader->readBitmaskArtifactsSized(map->allowedArtifact, true);
else
reader->readBitmaskArtifacts(map->allowedArtifact, true);
}
// ban combo artifacts
if(!features.levelSOD)
@ -737,8 +724,8 @@ void CMapLoaderH3M::readAllowedSpellsAbilities()
if(features.levelSOD)
{
reader->readBitmask(map->allowedSpell, features.spellsBytes, features.spellsCount, true);
reader->readBitmask(map->allowedAbilities, features.skillsBytes, features.skillsCount, true);
reader->readBitmaskSpells(map->allowedSpell, true);
reader->readBitmaskSkills(map->allowedAbilities, true);
}
}
@ -812,7 +799,7 @@ void CMapLoaderH3M::readPredefinedHeroes()
bool hasCustomSpells = reader->readBool();
if(hasCustomSpells)
readSpells(hero->spells);
reader->readBitmaskSpells(hero->spells, false);
bool hasCustomPrimSkills = reader->readBool();
if(hasCustomPrimSkills)
@ -1069,7 +1056,7 @@ CGObjectInstance * CMapLoaderH3M::readWitchHut()
// AB and later maps have allowed abilities defined in H3M
if(features.levelAB)
{
reader->readBitmask(object->allowedAbilities, features.skillsBytes, features.skillsCount, false);
reader->readBitmaskSkills(object->allowedAbilities, false);
if(object->allowedAbilities.size() != 1)
{
@ -1077,7 +1064,7 @@ CGObjectInstance * CMapLoaderH3M::readWitchHut()
for(int skillID = 0; skillID < VLC->skillh->size(); ++skillID)
if(defaultAllowed[skillID])
object->allowedAbilities.insert(skillID);
object->allowedAbilities.insert(SecondarySkill(skillID));
}
}
return object;
@ -1156,7 +1143,7 @@ CGObjectInstance * CMapLoaderH3M::readMine(const int3 & mapPosition, std::shared
else
{
object->setOwner(PlayerColor::NEUTRAL);
reader->readBitmask(object->abandonedMineResources, features.resourcesBytes, features.resourcesCount, false);
reader->readBitmaskResources(object->abandonedMineResources, false);
}
return object;
}
@ -1718,7 +1705,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
object->spells.insert(SpellID::PRESET); //placeholder "preset spells"
readSpells(object->spells);
reader->readBitmaskSpells(object->spells, false);
}
}
else if(features.levelAB)
@ -1963,10 +1950,7 @@ void CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & position)
{
guard->quest->missionType = CQuest::MISSION_HOTA_HERO_CLASS;
std::set<HeroClassID> heroClasses;
uint32_t classesCount = reader->readUInt32();
uint32_t classesBytes = (classesCount + 7) / 8;
reader->readBitmask(heroClasses, classesBytes, classesCount, false);
reader->readBitmaskHeroClassesSized(heroClasses, false);
logGlobal->warn("Map '%s': Quest at %s 'Belong to one of %d classes' is not implemented!", mapName, position.toString(), heroClasses.size());
break;
@ -2041,14 +2025,14 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt
{
std::set<SpellID> spellsMask;
reader->readBitmask(spellsMask, features.spellsBytes, features.spellsCount, false);
reader->readBitmaskSpells(spellsMask, false);
std::copy(spellsMask.begin(), spellsMask.end(), std::back_inserter(object->obligatorySpells));
}
{
std::set<SpellID> spellsMask;
reader->readBitmask(spellsMask, features.spellsBytes, features.spellsCount, true);
reader->readBitmaskSpells(spellsMask, true);
std::copy(spellsMask.begin(), spellsMask.end(), std::back_inserter(object->possibleSpells));
auto defaultAllowed = VLC->spellh->getDefaultAllowed();
@ -2179,11 +2163,6 @@ void CMapLoaderH3M::readMessageAndGuards(std::string & message, CCreatureSet * g
}
}
void CMapLoaderH3M::readSpells(std::set<SpellID> & dest)
{
reader->readBitmask(dest, features.spellsBytes, features.spellsCount, false);
}
std::string CMapLoaderH3M::readBasicString()
{
return TextOperations::toUnicode(reader->readBaseString(), fileEncoding);

View File

@ -226,7 +226,6 @@ private:
std::string readLocalizedString(const TextIdentifier & identifier);
void setOwnerAndValidate(const int3 & mapPosition, CGObjectInstance * object, const PlayerColor & owner);
void readSpells(std::set<SpellID> & dest);
void afterRead();

View File

@ -179,6 +179,72 @@ void MapReaderH3M::readBitmaskBuildings(std::set<BuildingID> & dest, std::option
}
}
void MapReaderH3M::readBitmaskFactions(std::set<FactionID> & dest, bool invert)
{
readBitmask(dest, features.factionsBytes, features.factionsCount, invert);
}
void MapReaderH3M::readBitmaskResources(std::set<GameResID> & dest, bool invert)
{
readBitmask(dest, features.resourcesBytes, features.resourcesCount, invert);
}
void MapReaderH3M::readBitmaskHeroClassesSized(std::set<HeroClassID> & dest, bool invert)
{
uint32_t classesCount = reader->readUInt32();
uint32_t classesBytes = (classesCount + 7) / 8;
readBitmask(dest, classesBytes, classesCount, invert);
}
void MapReaderH3M::readBitmaskHeroes(std::vector<bool> & dest, bool invert)
{
readBitmask(dest, features.heroesBytes, features.heroesCount, invert);
}
void MapReaderH3M::readBitmaskHeroesSized(std::vector<bool> & dest, bool invert)
{
uint32_t heroesCount = readUInt32();
uint32_t heroesBytes = (heroesCount + 7) / 8;
assert(heroesCount <= features.heroesCount);
readBitmask(dest, heroesBytes, heroesCount, invert);
}
void MapReaderH3M::readBitmaskArtifacts(std::vector<bool> &dest, bool invert)
{
readBitmask(dest, features.artifactsBytes, features.artifactsCount, invert);
}
void MapReaderH3M::readBitmaskArtifactsSized(std::vector<bool> &dest, bool invert)
{
uint32_t artifactsCount = reader->readUInt32();
uint32_t artifactsBytes = (artifactsCount + 7) / 8;
assert(artifactsCount <= features.artifactsCount);
readBitmask(dest, artifactsBytes, artifactsCount, invert);
}
void MapReaderH3M::readBitmaskSpells(std::vector<bool> & dest, bool invert)
{
readBitmask(dest, features.spellsBytes, features.spellsCount, invert);
}
void MapReaderH3M::readBitmaskSpells(std::set<SpellID> & dest, bool invert)
{
readBitmask(dest, features.spellsBytes, features.spellsCount, invert);
}
void MapReaderH3M::readBitmaskSkills(std::vector<bool> & dest, bool invert)
{
readBitmask(dest, features.skillsBytes, features.skillsCount, invert);
}
void MapReaderH3M::readBitmaskSkills(std::set<SecondarySkill> & dest, bool invert)
{
readBitmask(dest, features.skillsBytes, features.skillsCount, invert);
}
void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int bytesToRead, const int objectsToRead, bool invert)
{
for(int byte = 0; byte < bytesToRead; ++byte)
@ -197,6 +263,19 @@ void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int bytesToRead,
}
}
template<class Identifier>
void MapReaderH3M::readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert)
{
std::vector<bool> bitmap;
bitmap.resize(objectsToRead, false);
readBitmask(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

@ -44,31 +44,19 @@ public:
PlayerColor readPlayer();
PlayerColor readPlayer32();
template<class Identifier>
void readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert)
{
std::vector<bool> bitmap;
bitmap.resize(objectsToRead, false);
readBitmask(bitmap, bytesToRead, objectsToRead, invert);
for(int i = 0; i < bitmap.size(); i++)
if(bitmap[i])
dest.insert(static_cast<Identifier>(i));
}
void readBitmaskBuildings(std::set<BuildingID> & dest, std::optional<FactionID> faction);
void readBitmaskFactions(std::set<FactionID> & dest, bool invert);
void readBitmaskResources(std::set<GameResID> & dest, bool invert);
void readBitmaskHeroClassesSized(std::set<HeroClassID> & dest, bool invert);
void readBitmaskHeroes(std::vector<bool> & dest, bool invert);
void readBitmaskHeroesSized(std::vector<bool> & dest, bool invert);
void readBitmaskArtifacts(std::vector<bool> & dest, bool invert);
void readBitmaskArtifactsSized(std::vector<bool> & dest, bool invert);
void readBitmaskSpells(std::vector<bool> & dest, bool invert);
void readBitmaskSpells(std::set<SpellID> & dest, bool invert);
void readBitmaskSkills(std::vector<bool> & dest, bool invert);
void readBitmaskSkills(std::set<SecondarySkill> & dest, bool invert);
/** Reads bitmask to boolean vector
* @param dest destination vector, shall be filed with "true" values
* @param byteCount size in bytes of bimask
* @param limit max count of vector elements to alter
* @param negate if true then set bit in mask means clear flag in vertor
*/
void readBitmask(std::vector<bool> & dest, int bytesToRead, int objectsToRead, bool invert);
/**
* Helper to read map position
*/
int3 readInt3();
void skipUnused(size_t amount);
@ -90,6 +78,11 @@ public:
CBinaryReader & getInternalReader();
private:
template<class Identifier>
void readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert);
void readBitmask(std::vector<bool> & dest, int bytesToRead, int objectsToRead, bool invert);
MapFormatFeaturesH3M features;
MapIdentifiersH3M remapper;