Browse Source

Cleaned up handling of hota map format versioning

Ivan Savenko 2 years ago
parent
commit
d6a3c0e666
4 changed files with 23 additions and 26 deletions
  1. 1 3
      lib/mapping/CMap.h
  2. 1 3
      lib/mapping/CMapService.cpp
  3. 6 5
      lib/mapping/MapFeaturesH3M.cpp
  4. 15 15
      lib/mapping/MapFormatH3M.cpp

+ 1 - 3
lib/mapping/CMap.h

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

+ 1 - 3
lib/mapping/CMapService.cpp

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

+ 6 - 5
lib/mapping/MapFeaturesH3M.cpp

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

+ 15 - 15
lib/mapping/MapFormatH3M.cpp

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