1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

HotA maps up to objects block can be parsed

This commit is contained in:
Ivan Savenko 2023-04-03 20:51:02 +03:00
parent 838d45b32c
commit c0e9eb6eb1
6 changed files with 70 additions and 18 deletions

View File

@ -15,7 +15,7 @@
VCMI_LIB_NAMESPACE_BEGIN
MapFormatFeaturesH3M MapFormatFeaturesH3M::find(EMapFormat format)
MapFormatFeaturesH3M MapFormatFeaturesH3M::find(EMapFormat format, uint8_t hotaVersion)
{
switch(format)
{
@ -30,7 +30,7 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::find(EMapFormat format)
//case EMapFormat::HOTA1: //TODO: find such maps? Not present in current HotA release (1.6)
//case EMapFormat::HOTA2:
case EMapFormat::HOTA3:
return getFeaturesHOTA();
return getFeaturesHOTA(hotaVersion);
default:
throw std::runtime_error("Invalid map format!");
}
@ -113,11 +113,16 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesWOG()
return result;
}
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesHOTA()
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesHOTA(uint8_t hotaVersion)
{
MapFormatFeaturesH3M result = getFeaturesSOD();
result.levelHOTA = true;
result.levelHOTA3 = hotaVersion == 3;
result.artifactsBytes = 21;
result.terrainsCount = 12; // +Highlands +Wasteland
result.skillsCount = 29; // + Interference
result.factionsCount = 10; // + Cove
result.creaturesCount = 162; // + Cove + neutrals
result.artifactsCount = 161; // + HotA artifacts

View File

@ -17,12 +17,12 @@ enum class EMapFormat : uint8_t;
struct MapFormatFeaturesH3M
{
public:
static MapFormatFeaturesH3M find(EMapFormat format);
static MapFormatFeaturesH3M find(EMapFormat format, uint8_t hotaVersion);
static MapFormatFeaturesH3M getFeaturesROE();
static MapFormatFeaturesH3M getFeaturesAB();
static MapFormatFeaturesH3M getFeaturesSOD();
static MapFormatFeaturesH3M getFeaturesWOG();
static MapFormatFeaturesH3M getFeaturesHOTA();
static MapFormatFeaturesH3M getFeaturesHOTA(uint8_t hotaVersion);
MapFormatFeaturesH3M() = default;
@ -64,6 +64,7 @@ public:
bool levelSOD = false;
bool levelWOG = false;
bool levelHOTA = false;
bool levelHOTA3 = false;
};
VCMI_LIB_NAMESPACE_END

View File

@ -116,6 +116,8 @@ void CMapLoaderH3M::init()
readDisposedHeroes();
times.emplace_back("disposed heroes", sw.getDiff());
readMapOptions();
readAllowedArtifacts();
times.emplace_back("allowed artifacts", sw.getDiff());
@ -151,12 +153,11 @@ void CMapLoaderH3M::readHeader()
// Map version
mapHeader->version = static_cast<EMapFormat>(reader->readUInt32());
features = MapFormatFeaturesH3M::find(mapHeader->version);
reader->setFormatLevel(mapHeader->version);
if(mapHeader->version == EMapFormat::HOTA1 || mapHeader->version == EMapFormat::HOTA2 || mapHeader->version == EMapFormat::HOTA3)
{
uint8_t hotaVersion = reader->readUInt8();
features = MapFormatFeaturesH3M::find(mapHeader->version, hotaVersion);
reader->setFormatLevel(mapHeader->version, hotaVersion);
reader->skipZero(5);
if (hotaVersion == 3)
@ -166,6 +167,11 @@ void CMapLoaderH3M::readHeader()
reader->skipZero(3);
}
}
else
{
features = MapFormatFeaturesH3M::find(mapHeader->version, 0);
reader->setFormatLevel(mapHeader->version, 0);
}
// Read map name, description, dimensions,...
mapHeader->areAnyPlayers = reader->readBool();
@ -613,9 +619,7 @@ void CMapLoaderH3M::readAllowedHeroes()
uint32_t heroesCount = features.heroesCount;
if (features.levelHOTA)
{
heroesCount = reader->readUInt32();
}
assert(heroesCount <= features.heroesCount);
@ -644,16 +648,46 @@ void CMapLoaderH3M::readDisposedHeroes()
map->disposedHeroes[g].players = reader->readUInt8();
}
}
}
void CMapLoaderH3M::readMapOptions()
{
//omitting NULLS
reader->skipZero(31);
if (features.levelHOTA)
{
std::vector<uint8_t> unknown(13);
for (size_t i = 0; i < 13; ++i)
unknown[i] = reader->readUInt8();
assert(unknown[0] == 0); // allowSpecialWeeks?
assert(unknown[1] == 0);
assert(unknown[2] == 0);
assert(unknown[3] == 16);
assert(unknown[4] == 0);
assert(unknown[5] == 0);
assert(unknown[6] == 0);
assert(unknown[7] == 0);
assert(unknown[8] == 0);
assert(unknown[9] == 163);
assert(unknown[10] == 0);
assert(unknown[11] == 0);
assert(unknown[12] == 0);
}
if (features.levelHOTA3)
{
uint32_t roundLimit = reader->readUInt32();
logGlobal->error("%s -> roundLimit of %d is not implemented!", mapName, roundLimit);
}
}
void CMapLoaderH3M::readAllowedArtifacts()
{
map->allowedArtifact = VLC->arth->getDefaultAllowed();
// Reading allowed artifacts: 17 or 18 bytes
// Reading allowed artifacts
if(features.levelAB)
reader->readBitmask(map->allowedArtifact, features.artifactsBytes, features.artifactsCount, true);
@ -707,9 +741,9 @@ void CMapLoaderH3M::readAllowedSpellsAbilities()
void CMapLoaderH3M::readRumors()
{
int rumNr = reader->readUInt32();
uint32_t rumorsCount = reader->readUInt32();
for(int it = 0; it < rumNr; it++)
for(int it = 0; it < rumorsCount; it++)
{
Rumor ourRumor;
ourRumor.name = readBasicString();
@ -723,7 +757,14 @@ void CMapLoaderH3M::readPredefinedHeroes()
if (!features.levelSOD)
return;
for(int z = 0; z < features.heroesCount; z++)
uint32_t heroesCount = features.heroesCount;
if (features.levelHOTA)
heroesCount = reader->readUInt32();
assert(heroesCount <= features.heroesCount);
for(int z = 0; z < heroesCount; z++)
{
bool custom = reader->readBool();
if(!custom)
@ -1333,7 +1374,7 @@ void CMapLoaderH3M::readObjects()
}
else
{
logGlobal->warn("Unrecognized object: %d:%d at %s on map %s", objTempl->id.toEnum(), objTempl->subid, objPos.toString(), map->name);
logGlobal->warn("Unrecognized object: %d:%d ('%s') at %s on map '%s'", objTempl->id.toEnum(), objTempl->subid, objTempl->animationFile, objPos.toString(), map->name);
nobj = new CGObjectInstance();
}
break;

View File

@ -87,6 +87,11 @@ private:
*/
void readTeamInfo();
/**
* Reads the list of map flags.
*/
void readMapOptions();
/**
* Reads the list of allowed heroes.
*/

View File

@ -21,9 +21,9 @@ MapReaderH3M::MapReaderH3M(CInputStream * stream)
{
}
void MapReaderH3M::setFormatLevel(EMapFormat newFormat)
void MapReaderH3M::setFormatLevel(EMapFormat newFormat, uint8_t hotaVersion)
{
features = MapFormatFeaturesH3M::find(newFormat);
features = MapFormatFeaturesH3M::find(newFormat, hotaVersion);
}
ArtifactID MapReaderH3M::readArtifact()

View File

@ -27,7 +27,7 @@ class MapReaderH3M
public:
explicit MapReaderH3M(CInputStream * stream);
void setFormatLevel(EMapFormat format);
void setFormatLevel(EMapFormat format, uint8_t hotaVersion);
ArtifactID readArtifact();
CreatureID readCreature();