1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-28 23:06:24 +02:00

Cleaned up handling of hota map format versioning

This commit is contained in:
Ivan Savenko 2023-04-10 14:01:09 +03:00
parent 5b658462a1
commit d6a3c0e666
4 changed files with 23 additions and 26 deletions

View File

@ -257,9 +257,7 @@ enum class EMapFormat: uint8_t
ROE = 0x0e, // 14
AB = 0x15, // 21
SOD = 0x1c, // 28
HOTA1 = 0x1e, // 30
HOTA2 = 0x1f, // 31
HOTA3 = 0x20, // 32
HOTA = 0x20, // 32
WOG = 0x33, // 51
VCMI = 0xF0
};

View File

@ -124,9 +124,7 @@ std::unique_ptr<IMapLoader> CMapService::getMapLoader(std::unique_ptr<CInputStre
case static_cast<int>(EMapFormat::AB) :
case static_cast<int>(EMapFormat::ROE) :
case static_cast<int>(EMapFormat::SOD) :
case static_cast<int>(EMapFormat::HOTA1) :
case static_cast<int>(EMapFormat::HOTA2) :
case static_cast<int>(EMapFormat::HOTA3) :
case static_cast<int>(EMapFormat::HOTA) :
return std::unique_ptr<IMapLoader>(new CMapLoaderH3M(mapName, modName, encoding, stream.get()));
default :
throw std::runtime_error("Unknown map format");

View File

@ -27,9 +27,7 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::find(EMapFormat format, uint32_t hota
return getFeaturesSOD();
case EMapFormat::WOG:
return getFeaturesWOG();
//case EMapFormat::HOTA1: //TODO: find such maps? Not present in current HotA release (1.6)
//case EMapFormat::HOTA2:
case EMapFormat::HOTA3:
case EMapFormat::HOTA:
return getFeaturesHOTA(hotaVersion);
default:
throw std::runtime_error("Invalid map format!");
@ -115,7 +113,10 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesWOG()
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesHOTA(uint32_t hotaVersion)
{
assert(hotaVersion < 4);
// even if changes are minimal, we might not be able to parse map header in map selection screen
// throw exception - to be cached by map selection screen & excluded as invalid
if(hotaVersion > 3)
throw std::runtime_error("Invalid map format!");
MapFormatFeaturesH3M result = getFeaturesSOD();
result.levelHOTA0 = true;
@ -131,7 +132,7 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesHOTA(uint32_t hotaVersion)
result.factionsCount = 10; // + Cove
result.creaturesCount = 171; // + Cove + neutrals
if(hotaVersion == 0 || hotaVersion == 1 || hotaVersion == 2)
if(hotaVersion < 3)
{
result.artifactsCount = 163; // + HotA artifacts
result.heroesCount = 178; // + Cove

View File

@ -119,7 +119,7 @@ void CMapLoaderH3M::readHeader()
// Map version
mapHeader->version = static_cast<EMapFormat>(reader->readUInt32());
if(mapHeader->version == EMapFormat::HOTA1 || mapHeader->version == EMapFormat::HOTA2 || mapHeader->version == EMapFormat::HOTA3)
if(mapHeader->version == EMapFormat::HOTA)
{
uint32_t hotaVersion = reader->readUInt32();
features = MapFormatFeaturesH3M::find(mapHeader->version, hotaVersion);
@ -1623,13 +1623,13 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
bool hasGarison = reader->readBool();
if(hasGarison)
readCreatureSet(object, 7);
object->formation = static_cast<EArmyFormation>(reader->readUInt8());
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
loadArtifactsOfHero(object);
object->patrol.patrolRadius = reader->readUInt8();
readCreatureSet(object, 7);
object->formation = static_cast<EArmyFormation>(reader->readUInt8());
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
loadArtifactsOfHero(object);
object->patrol.patrolRadius = reader->readUInt8();
object->patrol.patrolling = (object->patrol.patrolRadius != 0xff);
if(features.levelAB)
@ -1952,13 +1952,13 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt
bool hasGarrison = reader->readBool();
if(hasGarrison)
readCreatureSet(object, 7);
object->formation = static_cast<EArmyFormation>(reader->readUInt8());
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
bool hasCustomBuildings = reader->readBool();
if(hasCustomBuildings)
readCreatureSet(object, 7);
object->formation = static_cast<EArmyFormation>(reader->readUInt8());
assert(object->formation == EArmyFormation::LOOSE || object->formation == EArmyFormation::TIGHT);
bool hasCustomBuildings = reader->readBool();
if(hasCustomBuildings)
{
reader->readBitmask(object->builtBuildings, features.buildingsBytes, features.buildingsCount, false);
reader->readBitmask(object->forbiddenBuildings, features.buildingsBytes, features.buildingsCount, false);