1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Cleanup and formatting of H3M loader code

This commit is contained in:
Ivan Savenko
2023-04-03 15:02:15 +03:00
parent 3738171b21
commit f93335d678
5 changed files with 110 additions and 110 deletions

View File

@@ -1394,11 +1394,16 @@ void CGArtifact::serializeJsonOptions(JsonSerializeFormat& handler)
void CGWitchHut::initObj(CRandomGenerator & rand) void CGWitchHut::initObj(CRandomGenerator & rand)
{ {
if (allowedAbilities.empty()) //this can happen for RMG. regular maps load abilities from map file if (allowedAbilities.empty()) //this can happen for RMG and RoE maps.
{ {
// Necromancy can't be learned on random maps auto defaultAllowed = VLC->skillh->getDefaultAllowed();
for(int i = 0; i < VLC->skillh->size(); i++)
if(VLC->skillh->getByIndex(i)->getId() != SecondarySkill::NECROMANCY) // Necromancy and Leadership can't be learned by default
defaultAllowed[SecondarySkill::NECROMANCY] = false;
defaultAllowed[SecondarySkill::LEADERSHIP] = false;
for(int i = 0; i < defaultAllowed.size(); i++)
if (defaultAllowed[i])
allowedAbilities.insert(i); allowedAbilities.insert(i);
} }
ability = *RandomGeneratorUtil::nextItem(allowedAbilities, rand); ability = *RandomGeneratorUtil::nextItem(allowedAbilities, rand);

View File

@@ -10,19 +10,25 @@
#include "StdInc.h" #include "StdInc.h"
#include "MapFeaturesH3M.h" #include "MapFeaturesH3M.h"
#include "CMap.h" #include "CMap.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
MapFormatFeaturesH3M MapFormatFeaturesH3M::find(EMapFormat format) MapFormatFeaturesH3M MapFormatFeaturesH3M::find(EMapFormat format)
{ {
switch (format) switch(format)
{ {
case EMapFormat::ROE: return getFeaturesROE(); case EMapFormat::ROE:
case EMapFormat::AB: return getFeaturesAB(); return getFeaturesROE();
case EMapFormat::SOD: return getFeaturesSOD(); case EMapFormat::AB:
case EMapFormat::WOG: return getFeaturesWOG(); return getFeaturesAB();
case EMapFormat::HOTA: return getFeaturesHOTA(); case EMapFormat::SOD:
return getFeaturesSOD();
case EMapFormat::WOG:
return getFeaturesWOG();
case EMapFormat::HOTA:
return getFeaturesHOTA();
default: default:
throw std::runtime_error("Invalid map format!"); throw std::runtime_error("Invalid map format!");
} }

View File

@@ -29,7 +29,6 @@
#include "../TerrainHandler.h" #include "../TerrainHandler.h"
#include "../RoadHandler.h" #include "../RoadHandler.h"
#include "../RiverHandler.h" #include "../RiverHandler.h"
#include "../NetPacksBase.h"
#include <boost/crc.hpp> #include <boost/crc.hpp>
@@ -41,7 +40,7 @@ static std::string convertMapName(std::string input)
boost::algorithm::to_lower(input); boost::algorithm::to_lower(input);
boost::algorithm::trim(input); boost::algorithm::trim(input);
size_t slashPos = input.find_last_of("/"); size_t slashPos = input.find_last_of('/');
if (slashPos != std::string::npos) if (slashPos != std::string::npos)
return input.substr(slashPos + 1); return input.substr(slashPos + 1);
@@ -175,7 +174,7 @@ void CMapLoaderH3M::readHeader()
// Read map name, description, dimensions,... // Read map name, description, dimensions,...
mapHeader->areAnyPlayers = reader->readBool(); mapHeader->areAnyPlayers = reader->readBool();
mapHeader->height = mapHeader->width = reader->readUInt32(); mapHeader->height = mapHeader->width = reader->readInt32();
mapHeader->twoLevel = reader->readBool(); mapHeader->twoLevel = reader->readBool();
mapHeader->name = readLocalizedString("header.name"); mapHeader->name = readLocalizedString("header.name");
mapHeader->description = readLocalizedString("header.description"); mapHeader->description = readLocalizedString("header.description");
@@ -256,8 +255,7 @@ void CMapLoaderH3M::readPlayerInfo()
if(features.levelAB) if(features.levelAB)
{ {
reader->skipUnused(1); //TODO: check meaning? reader->skipUnused(1); //TODO: check meaning?
int heroCount = reader->readUInt8(); uint32_t heroCount = reader->readUInt32();
reader->skipZero(3);
for(int pp = 0; pp < heroCount; ++pp) for(int pp = 0; pp < heroCount; ++pp)
{ {
SHeroName vv; SHeroName vv;
@@ -355,7 +353,7 @@ void CMapLoaderH3M::readVictoryLossConditions()
{ {
EventCondition cond(EventCondition::HAVE_CREATURES); EventCondition cond(EventCondition::HAVE_CREATURES);
cond.objectType = reader->readCreature(); cond.objectType = reader->readCreature();
cond.value = reader->readUInt32(); cond.value = reader->readInt32();
specialVictory.effect.toOtherMessage = VLC->generaltexth->allTexts[277]; specialVictory.effect.toOtherMessage = VLC->generaltexth->allTexts[277];
specialVictory.onFulfill = VLC->generaltexth->allTexts[276]; specialVictory.onFulfill = VLC->generaltexth->allTexts[276];
@@ -366,7 +364,7 @@ void CMapLoaderH3M::readVictoryLossConditions()
{ {
EventCondition cond(EventCondition::HAVE_RESOURCES); EventCondition cond(EventCondition::HAVE_RESOURCES);
cond.objectType = reader->readUInt8(); cond.objectType = reader->readUInt8();
cond.value = reader->readUInt32(); cond.value = reader->readInt32();
specialVictory.effect.toOtherMessage = VLC->generaltexth->allTexts[279]; specialVictory.effect.toOtherMessage = VLC->generaltexth->allTexts[279];
specialVictory.onFulfill = VLC->generaltexth->allTexts[278]; specialVictory.onFulfill = VLC->generaltexth->allTexts[278];
@@ -591,14 +589,14 @@ void CMapLoaderH3M::readTeamInfo()
void CMapLoaderH3M::readAllowedHeroes() void CMapLoaderH3M::readAllowedHeroes()
{ {
mapHeader->allowedHeroes.resize(VLC->heroh->size(), true); mapHeader->allowedHeroes = VLC->heroh->getDefaultAllowed();
reader->readBitmask(mapHeader->allowedHeroes, features.heroesBytes, features.heroesCount, false); reader->readBitmask(mapHeader->allowedHeroes, features.heroesBytes, features.heroesCount, false);
//TODO: unknown value. Check meaning? Only present in campaign maps. //TODO: unknown value. Check meaning? Only present in campaign maps.
if(features.levelAB) if(features.levelAB)
{ {
int placeholdersQty = reader->readUInt32(); uint32_t placeholdersQty = reader->readUInt32();
reader->skipUnused(placeholdersQty * 1); reader->skipUnused(placeholdersQty * 1);
} }
} }
@@ -625,11 +623,11 @@ void CMapLoaderH3M::readDisposedHeroes()
void CMapLoaderH3M::readAllowedArtifacts() void CMapLoaderH3M::readAllowedArtifacts()
{ {
map->allowedArtifact.resize (VLC->arth->objects.size(),true); //handle new artifacts, make them allowed by default map->allowedArtifact = VLC->arth->getDefaultAllowed();
// Reading allowed artifacts: 17 or 18 bytes // Reading allowed artifacts: 17 or 18 bytes
if(features.levelAB) if(features.levelAB)
reader->readBitmask(map->allowedArtifact, features.artifactsBytes, features.artifactsCount); reader->readBitmask(map->allowedArtifact, features.artifactsBytes, features.artifactsCount, true);
// ban combo artifacts // ban combo artifacts
if (!features.levelSOD) if (!features.levelSOD)
@@ -664,21 +662,13 @@ void CMapLoaderH3M::readAllowedArtifacts()
void CMapLoaderH3M::readAllowedSpellsAbilities() void CMapLoaderH3M::readAllowedSpellsAbilities()
{ {
// Read allowed spells, including new ones map->allowedSpell = VLC->spellh->getDefaultAllowed();
map->allowedSpell.resize(VLC->spellh->objects.size(), true); map->allowedAbilities = VLC->skillh->getDefaultAllowed();
// Read allowed abilities
map->allowedAbilities.resize(VLC->skillh->objects.size(), true);
if(features.levelSOD) if(features.levelSOD)
{ {
// Reading allowed spells (9 bytes) reader->readBitmask(map->allowedSpell, features.spellsBytes, features.spellsCount, true);
const int spell_bytes = 9; reader->readBitmask(map->allowedAbilities, features.skillsBytes, features.skillsCount, true);
reader->readBitmask(map->allowedSpell, spell_bytes, GameConstants::SPELLS_QUANTITY);
// Allowed hero's abilities (4 bytes)
const int abil_bytes = 4;
reader->readBitmask(map->allowedAbilities, abil_bytes, GameConstants::SKILL_QUANTITY);
} }
//do not generate special abilities and spells //do not generate special abilities and spells
@@ -728,7 +718,7 @@ void CMapLoaderH3M::readPredefinedHeroes()
bool hasSecSkills = reader->readBool(); bool hasSecSkills = reader->readBool();
if(hasSecSkills) if(hasSecSkills)
{ {
int howMany = reader->readUInt32(); uint32_t howMany = reader->readUInt32();
hero->secSkills.resize(howMany); hero->secSkills.resize(howMany);
for(int yy = 0; yy < howMany; ++yy) for(int yy = 0; yy < howMany; ++yy)
{ {
@@ -864,7 +854,7 @@ void CMapLoaderH3M::readTerrain()
void CMapLoaderH3M::readDefInfo() void CMapLoaderH3M::readDefInfo()
{ {
int defAmount = reader->readUInt32(); uint32_t defAmount = reader->readUInt32();
templates.reserve(defAmount); templates.reserve(defAmount);
@@ -879,15 +869,15 @@ void CMapLoaderH3M::readDefInfo()
void CMapLoaderH3M::readObjects() void CMapLoaderH3M::readObjects()
{ {
int howManyObjs = reader->readUInt32(); uint32_t howManyObjs = reader->readUInt32();
for(int ww = 0; ww < howManyObjs; ++ww) for(uint32_t ww = 0; ww < howManyObjs; ++ww)
{ {
CGObjectInstance * nobj = nullptr; CGObjectInstance * nobj = nullptr;
int3 objPos = reader->readInt3(); int3 objPos = reader->readInt3();
int defnum = reader->readUInt32(); uint32_t defnum = reader->readUInt32();
ObjectInstanceID idToBeGiven = ObjectInstanceID(static_cast<si32>(map->objects.size())); ObjectInstanceID idToBeGiven = ObjectInstanceID(static_cast<si32>(map->objects.size()));
std::shared_ptr<const ObjectTemplate> objTempl = templates.at(defnum); std::shared_ptr<const ObjectTemplate> objTempl = templates.at(defnum);
@@ -903,7 +893,7 @@ void CMapLoaderH3M::readObjects()
readMessageAndGuards(evnt->message, evnt, objPos); readMessageAndGuards(evnt->message, evnt, objPos);
evnt->gainedExp = reader->readUInt32(); evnt->gainedExp = reader->readUInt32();
evnt->manaDiff = reader->readUInt32(); evnt->manaDiff = reader->readInt32();
evnt->moraleDiff = reader->readInt8(); evnt->moraleDiff = reader->readInt8();
evnt->luckDiff = reader->readInt8(); evnt->luckDiff = reader->readInt8();
@@ -976,7 +966,7 @@ void CMapLoaderH3M::readObjects()
//type will be set during initialization //type will be set during initialization
cre->putStack(SlotID(0), hlp); cre->putStack(SlotID(0), hlp);
cre->character = reader->readUInt8(); cre->character = reader->readInt8();
bool hasMessage = reader->readBool(); bool hasMessage = reader->readBool();
if(hasMessage) if(hasMessage)
@@ -1009,21 +999,20 @@ void CMapLoaderH3M::readObjects()
auto * wh = new CGWitchHut(); auto * wh = new CGWitchHut();
nobj = wh; nobj = wh;
// AB and later maps have allowed abilities defined in H3M
if(features.levelAB) if(features.levelAB)
{ {
reader->readBitmask(wh->allowedAbilities, features.skillsBytes, features.skillsCount); reader->readBitmask(wh->allowedAbilities, features.skillsBytes, features.skillsCount, false);
// enable new (modded) skills
if(wh->allowedAbilities.size() != 1) if(wh->allowedAbilities.size() != 1)
{ {
for(int skillID = features.skillsCount; skillID < VLC->skillh->size(); ++skillID) auto defaultAllowed = VLC->skillh->getDefaultAllowed();
wh->allowedAbilities.insert(skillID);
}
}
else
{
for(int skillID = 0; skillID < VLC->skillh->size(); ++skillID) for(int skillID = 0; skillID < VLC->skillh->size(); ++skillID)
if (defaultAllowed[skillID])
wh->allowedAbilities.insert(skillID); wh->allowedAbilities.insert(skillID);
} }
}
break; break;
} }
case Obj::SCHOLAR: case Obj::SCHOLAR:
@@ -1143,7 +1132,7 @@ void CMapLoaderH3M::readObjects()
readMessageAndGuards(box->message, box, objPos); readMessageAndGuards(box->message, box, objPos);
box->gainedExp = reader->readUInt32(); box->gainedExp = reader->readUInt32();
box->manaDiff = reader->readUInt32(); box->manaDiff = reader->readInt32();
box->moraleDiff = reader->readInt8(); box->moraleDiff = reader->readInt8();
box->luckDiff = reader->readInt8(); box->luckDiff = reader->readInt8();
@@ -1177,7 +1166,7 @@ void CMapLoaderH3M::readObjects()
case Obj::GRAIL: case Obj::GRAIL:
{ {
map->grailPos = objPos; map->grailPos = objPos;
map->grailRadius = reader->readUInt32(); map->grailRadius = reader->readInt32();
continue; continue;
} }
case Obj::RANDOM_DWELLING: //same as castle + level range case Obj::RANDOM_DWELLING: //same as castle + level range
@@ -1252,7 +1241,7 @@ void CMapLoaderH3M::readObjects()
case Obj::SHIPYARD: case Obj::SHIPYARD:
{ {
nobj = new CGShipyard(); nobj = new CGShipyard();
nobj->setOwner(PlayerColor(reader->readUInt32())); nobj->setOwner(reader->readPlayer32());
break; break;
} }
case Obj::HERO_PLACEHOLDER: //hero placeholder case Obj::HERO_PLACEHOLDER: //hero placeholder
@@ -1459,7 +1448,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const ObjectInstanceID & idToBeGiven,
nhi->secSkills.clear(); nhi->secSkills.clear();
} }
int howMany = reader->readUInt32(); uint32_t howMany = reader->readUInt32();
nhi->secSkills.resize(howMany); nhi->secSkills.resize(howMany);
for(int yy = 0; yy < howMany; ++yy) for(int yy = 0; yy < howMany; ++yy)
{ {
@@ -1602,10 +1591,8 @@ CGSeerHut * CMapLoaderH3M::readSeerHut(const int3 & position)
hut->rID = reader->readUInt8(); hut->rID = reader->readUInt8();
hut->rVal = reader->readUInt32(); hut->rVal = reader->readUInt32();
// Only the first 3 bytes are used. Skip the 4th.
assert(hut->rID < features.resourcesCount); assert(hut->rID < features.resourcesCount);
assert((hut->rVal & 0x00ffffff) == hut->rVal); assert((hut->rVal & 0x00ffffff) == hut->rVal);
hut->rVal = hut->rVal & 0x00ffffff;
break; break;
} }
case CGSeerHut::PRIMARY_SKILL: case CGSeerHut::PRIMARY_SKILL:
@@ -1781,20 +1768,22 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID, const int3 & position)
std::copy(spellsMask.begin(), spellsMask.end(), std::back_inserter(nt->obligatorySpells)); std::copy(spellsMask.begin(), spellsMask.end(), std::back_inserter(nt->obligatorySpells));
} }
if (features.levelROE)
{ {
std::set<SpellID> spellsMask; std::set<SpellID> spellsMask;
reader->readBitmask(spellsMask, features.spellsBytes, features.spellsCount, false ); reader->readBitmask(spellsMask, features.spellsBytes, features.spellsCount, true );
std::copy(spellsMask.begin(), spellsMask.end(), std::back_inserter(nt->possibleSpells)); std::copy(spellsMask.begin(), spellsMask.end(), std::back_inserter(nt->possibleSpells));
}
auto defaultAllowed = VLC->spellh->getDefaultAllowed();
//add all spells from mods //add all spells from mods
for (int i = SpellID::AFTER_LAST; i < VLC->spellh->objects.size(); ++i) for (int i = features.spellsCount; i < defaultAllowed.size(); ++i)
if (defaultAllowed[i])
nt->possibleSpells.emplace_back(i); nt->possibleSpells.emplace_back(i);
}
// Read castle events // Read castle events
int numberOfEvent = reader->readUInt32(); uint32_t numberOfEvent = reader->readUInt32();
for(int gh = 0; gh < numberOfEvent; ++gh) for(int gh = 0; gh < numberOfEvent; ++gh)
{ {
@@ -1903,7 +1892,7 @@ std::set<BuildingID> CMapLoaderH3M::convertBuildings(const std::set<BuildingID>
void CMapLoaderH3M::readEvents() void CMapLoaderH3M::readEvents()
{ {
int numberOfEvents = reader->readUInt32(); uint32_t numberOfEvents = reader->readUInt32();
for(int yyoo = 0; yyoo < numberOfEvents; ++yyoo) for(int yyoo = 0; yyoo < numberOfEvents; ++yyoo)
{ {
CMapEvent ne; CMapEvent ne;

View File

@@ -10,6 +10,7 @@
#include "StdInc.h" #include "StdInc.h"
#include "MapReaderH3M.h" #include "MapReaderH3M.h"
#include "CMap.h" #include "CMap.h"
#include "../filesystem/CBinaryReader.h" #include "../filesystem/CBinaryReader.h"
@@ -29,12 +30,12 @@ ArtifactID MapReaderH3M::readArtifact()
{ {
ArtifactID result; ArtifactID result;
if (features.levelAB) if(features.levelAB)
result = ArtifactID(reader->readUInt16()); result = ArtifactID(reader->readUInt16());
else else
result = ArtifactID(reader->readUInt8()); result = ArtifactID(reader->readUInt8());
if (result == features.artifactIdentifierInvalid) if(result == features.artifactIdentifierInvalid)
return ArtifactID::NONE; return ArtifactID::NONE;
assert(result < features.artifactsCount); assert(result < features.artifactsCount);
@@ -43,9 +44,9 @@ ArtifactID MapReaderH3M::readArtifact()
HeroTypeID MapReaderH3M::readHero() HeroTypeID MapReaderH3M::readHero()
{ {
HeroTypeID result (reader->readUInt8()); HeroTypeID result(reader->readUInt8());
if (result.getNum() == features.heroIdentifierInvalid) if(result.getNum() == features.heroIdentifierInvalid)
return HeroTypeID(-1); return HeroTypeID(-1);
assert(result.getNum() < features.heroesPortraitsCount); assert(result.getNum() < features.heroesPortraitsCount);
@@ -56,105 +57,103 @@ CreatureID MapReaderH3M::readCreature()
{ {
CreatureID result; CreatureID result;
if (features.levelAB) if(features.levelAB)
result = CreatureID(reader->readUInt16()); result = CreatureID(reader->readUInt16());
else else
result = CreatureID(reader->readUInt8()); result = CreatureID(reader->readUInt8());
if (result == features.creatureIdentifierInvalid) if(result == features.creatureIdentifierInvalid)
return CreatureID::NONE; return CreatureID::NONE;
if(result > features.creaturesCount) if(result > features.creaturesCount)
{ {
// this may be random creature in army/town, to be randomized later // this may be random creature in army/town, to be randomized later
CreatureID randomIndex (result.getNum() - features.creatureIdentifierInvalid - 1); CreatureID randomIndex(result.getNum() - features.creatureIdentifierInvalid - 1);
assert(randomIndex < CreatureID::NONE); assert(randomIndex < CreatureID::NONE);
assert(randomIndex > -16); assert(randomIndex > -16);
return randomIndex; return randomIndex;
} }
return result; return result;
} }
TerrainId MapReaderH3M::readTerrain() TerrainId MapReaderH3M::readTerrain()
{ {
TerrainId result(readUInt8()); TerrainId result(readUInt8());
assert (result.getNum() < features.terrainsCount); assert(result.getNum() < features.terrainsCount);
return result; return result;
} }
RoadId MapReaderH3M::readRoad() RoadId MapReaderH3M::readRoad()
{ {
RoadId result(readUInt8()); RoadId result(readInt8());
assert (result < Road::ORIGINAL_ROAD_COUNT); assert(result < Road::ORIGINAL_ROAD_COUNT);
return result; return result;
} }
RiverId MapReaderH3M::readRiver() RiverId MapReaderH3M::readRiver()
{ {
RiverId result(readUInt8()); RiverId result(readInt8());
assert (result < River::ORIGINAL_RIVER_COUNT); assert(result < River::ORIGINAL_RIVER_COUNT);
return result; return result;
} }
SecondarySkill MapReaderH3M::readSkill() SecondarySkill MapReaderH3M::readSkill()
{ {
SecondarySkill result(readUInt8()); SecondarySkill result(readUInt8());
assert (result < features.skillsCount); assert(result < features.skillsCount);
return result; return result;
} }
SpellID MapReaderH3M::readSpell() SpellID MapReaderH3M::readSpell()
{ {
SpellID result(readUInt8()); SpellID result(readUInt8());
if (result == features.spellIdentifierInvalid) if(result == features.spellIdentifierInvalid)
return SpellID::NONE; return SpellID::NONE;
if (result == features.spellIdentifierInvalid - 1) if(result == features.spellIdentifierInvalid - 1)
return SpellID::PRESET; return SpellID::PRESET;
assert (result < features.spellsCount); assert(result < features.spellsCount);
return result; return result;
} }
SpellID MapReaderH3M::readSpell32() SpellID MapReaderH3M::readSpell32()
{ {
SpellID result(readUInt32()); SpellID result(readInt32());
if (result == features.spellIdentifierInvalid) if(result == features.spellIdentifierInvalid)
return SpellID::NONE; return SpellID::NONE;
assert (result < features.spellsCount); assert(result < features.spellsCount);
return result; return result;
} }
PlayerColor MapReaderH3M::readPlayer() PlayerColor MapReaderH3M::readPlayer()
{ {
PlayerColor result(readUInt8()); PlayerColor result(readUInt8());
assert (result < PlayerColor::PLAYER_LIMIT || result == PlayerColor::NEUTRAL); assert(result < PlayerColor::PLAYER_LIMIT || result == PlayerColor::NEUTRAL);
return result; return result;
} }
PlayerColor MapReaderH3M::readPlayer32() PlayerColor MapReaderH3M::readPlayer32()
{ {
PlayerColor result(readUInt32()); PlayerColor result(readInt32());
assert (result < PlayerColor::PLAYER_LIMIT || result == PlayerColor::NEUTRAL); assert(result < PlayerColor::PLAYER_LIMIT || result == PlayerColor::NEUTRAL);
return result; return result;
} }
void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int byteCount, const int limit, bool negate) void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int bytesToRead, const int objectsToRead, bool invert)
{ {
for(int byte = 0; byte < byteCount; ++byte) for(int byte = 0; byte < bytesToRead; ++byte)
{ {
const ui8 mask = reader->readUInt8(); const ui8 mask = reader->readUInt8();
for(int bit = 0; bit < 8; ++bit) for(int bit = 0; bit < 8; ++bit)
{ {
if(byte * 8 + bit < limit) if(byte * 8 + bit < objectsToRead)
{ {
const size_t index = byte * 8 + bit;
const bool flag = mask & (1 << bit); const bool flag = mask & (1 << bit);
if((negate && flag) || (!negate && !flag)) // FIXME: check PR388 const bool result = (flag != invert);
dest[byte * 8 + bit] = false; dest[index] = result;
} }
} }
} }
@@ -179,7 +178,7 @@ void MapReaderH3M::skipZero(size_t amount)
#ifdef NDEBUG #ifdef NDEBUG
skipUnused(amount); skipUnused(amount);
#else #else
for (size_t i = 0; i < amount; ++i) for(size_t i = 0; i < amount; ++i)
{ {
uint8_t value = reader->readUInt8(); uint8_t value = reader->readUInt8();
assert(value == 0); assert(value == 0);
@@ -187,10 +186,10 @@ void MapReaderH3M::skipZero(size_t amount)
#endif #endif
} }
void MapReaderH3M::readResourses(TResources& resources) void MapReaderH3M::readResourses(TResources & resources)
{ {
for(int x = 0; x < features.resourcesCount; ++x) for(int x = 0; x < features.resourcesCount; ++x)
resources[x] = reader->readUInt32(); resources[x] = reader->readInt32();
} }
bool MapReaderH3M::readBool() bool MapReaderH3M::readBool()

View File

@@ -10,8 +10,8 @@
#pragma once #pragma once
#include "../ResourceSet.h"
#include "../GameConstants.h" #include "../GameConstants.h"
#include "../ResourceSet.h"
#include "MapFeaturesH3M.h" #include "MapFeaturesH3M.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@@ -41,15 +41,15 @@ public:
PlayerColor readPlayer(); PlayerColor readPlayer();
PlayerColor readPlayer32(); PlayerColor readPlayer32();
template <class Identifier> template<class Identifier>
void readBitmask(std::set<Identifier> &dest, const int byteCount, const int limit, bool negate = true) void readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert)
{ {
std::vector<bool> temp; std::vector<bool> bitmap;
temp.resize(limit,true); bitmap.resize(objectsToRead, false);
readBitmask(temp, byteCount, limit, negate); readBitmask(bitmap, bytesToRead, objectsToRead, invert);
for(int i = 0; i< std::min(temp.size(), static_cast<size_t>(limit)); i++) for(int i = 0; i < bitmap.size(); i++)
if(temp[i]) if(bitmap[i])
dest.insert(static_cast<Identifier>(i)); dest.insert(static_cast<Identifier>(i));
} }
@@ -59,7 +59,7 @@ public:
* @param limit max count of vector elements to alter * @param limit max count of vector elements to alter
* @param negate if true then set bit in mask means clear flag in vertor * @param negate if true then set bit in mask means clear flag in vertor
*/ */
void readBitmask(std::vector<bool> & dest, int byteCount, int limit, bool negate = true); void readBitmask(std::vector<bool> & dest, int bytesToRead, int objectsToRead, bool invert);
/** /**
* Helper to read map position * Helper to read map position
@@ -69,7 +69,7 @@ public:
void skipUnused(size_t amount); void skipUnused(size_t amount);
void skipZero(size_t amount); void skipZero(size_t amount);
void readResourses(TResources& resources); void readResourses(TResources & resources);
bool readBool(); bool readBool();
@@ -83,6 +83,7 @@ public:
std::string readBaseString(); std::string readBaseString();
CBinaryReader & getInternalReader(); CBinaryReader & getInternalReader();
private: private:
MapFormatFeaturesH3M features; MapFormatFeaturesH3M features;