mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-23 00:28:08 +02:00
Fix parsing of hota 1.7.3 maps/campaigns
This commit is contained in:
@ -552,12 +552,24 @@ void CampaignHandler::readHeaderFromMemory( CampaignHeader & ret, CBinaryReader
|
|||||||
|
|
||||||
if (ret.version == CampaignVersion::HotA)
|
if (ret.version == CampaignVersion::HotA)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] int32_t unknownA = reader.readInt32();
|
int32_t formatVersion = reader.readInt32();
|
||||||
[[maybe_unused]] int32_t unknownB = reader.readInt32();
|
|
||||||
[[maybe_unused]] int32_t unknownC = reader.readInt8();
|
if (formatVersion == 2)
|
||||||
|
{
|
||||||
|
int hotaVersionMajor = reader.readUInt32();
|
||||||
|
int hotaVersionMinor = reader.readUInt32();
|
||||||
|
int hotaVersionPatch = reader.readUInt32();
|
||||||
|
logGlobal->trace("Loading HotA campaign, version %d.%d.%d", hotaVersionMajor, hotaVersionMinor, hotaVersionPatch);
|
||||||
|
|
||||||
|
bool forceMatchingVersion = reader.readBool();
|
||||||
|
if (forceMatchingVersion)
|
||||||
|
logGlobal->warn("Map '%s': This map is forced to use specific hota version!", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] int32_t unknownB = reader.readInt8();
|
||||||
|
[[maybe_unused]] int32_t unknownC = reader.readInt32();
|
||||||
ret.numberOfScenarios = reader.readInt32();
|
ret.numberOfScenarios = reader.readInt32();
|
||||||
|
|
||||||
assert(unknownA == 1);
|
|
||||||
assert(unknownB == 1);
|
assert(unknownB == 1);
|
||||||
assert(unknownC == 0);
|
assert(unknownC == 0);
|
||||||
assert(ret.numberOfScenarios <= 8);
|
assert(ret.numberOfScenarios <= 8);
|
||||||
|
@ -131,7 +131,7 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesHOTA(uint32_t hotaVersion)
|
|||||||
{
|
{
|
||||||
// even if changes are minimal, we might not be able to parse map header in map selection screen
|
// even if changes are minimal, we might not be able to parse map header in map selection screen
|
||||||
// throw exception - to be caught by map selection screen & excluded as invalid
|
// throw exception - to be caught by map selection screen & excluded as invalid
|
||||||
if(hotaVersion > 7)
|
if(hotaVersion > 8)
|
||||||
throw std::runtime_error("Invalid map format!");
|
throw std::runtime_error("Invalid map format!");
|
||||||
|
|
||||||
MapFormatFeaturesH3M result = getFeaturesSOD();
|
MapFormatFeaturesH3M result = getFeaturesSOD();
|
||||||
@ -142,6 +142,7 @@ MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesHOTA(uint32_t hotaVersion)
|
|||||||
result.levelHOTA5 = hotaVersion > 4;
|
result.levelHOTA5 = hotaVersion > 4;
|
||||||
result.levelHOTA6 = hotaVersion > 5;
|
result.levelHOTA6 = hotaVersion > 5;
|
||||||
result.levelHOTA7 = hotaVersion > 6;
|
result.levelHOTA7 = hotaVersion > 6;
|
||||||
|
result.levelHOTA8 = hotaVersion > 7;
|
||||||
|
|
||||||
result.artifactsBytes = 21;
|
result.artifactsBytes = 21;
|
||||||
result.heroesBytes = 23;
|
result.heroesBytes = 23;
|
||||||
|
@ -75,6 +75,7 @@ public:
|
|||||||
bool levelHOTA5 = false; // 1.7.0
|
bool levelHOTA5 = false; // 1.7.0
|
||||||
bool levelHOTA6 = false; // 1.7.1
|
bool levelHOTA6 = false; // 1.7.1
|
||||||
bool levelHOTA7 = false; // 1.7.2
|
bool levelHOTA7 = false; // 1.7.2
|
||||||
|
bool levelHOTA8 = false; // 1.7.3
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -168,6 +168,14 @@ void CMapLoaderH3M::readHeader()
|
|||||||
features = MapFormatFeaturesH3M::find(mapHeader->version, hotaVersion);
|
features = MapFormatFeaturesH3M::find(mapHeader->version, hotaVersion);
|
||||||
reader->setFormatLevel(features);
|
reader->setFormatLevel(features);
|
||||||
|
|
||||||
|
if(features.levelHOTA8)
|
||||||
|
{
|
||||||
|
int hotaVersionMajor = reader->readUInt32();
|
||||||
|
int hotaVersionMinor = reader->readUInt32();
|
||||||
|
int hotaVersionPatch = reader->readUInt32();
|
||||||
|
logGlobal->trace("Loading HotA map, version %d.%d.%d", hotaVersionMajor, hotaVersionMinor, hotaVersionPatch);
|
||||||
|
}
|
||||||
|
|
||||||
if(features.levelHOTA1)
|
if(features.levelHOTA1)
|
||||||
{
|
{
|
||||||
bool isMirrorMap = reader->readBool();
|
bool isMirrorMap = reader->readBool();
|
||||||
@ -211,6 +219,13 @@ void CMapLoaderH3M::readHeader()
|
|||||||
if (!canHireDefeatedHeroes)
|
if (!canHireDefeatedHeroes)
|
||||||
logGlobal->warn("Map '%s': Option to block hiring of defeated heroes is not implemented!", mapName);
|
logGlobal->warn("Map '%s': Option to block hiring of defeated heroes is not implemented!", mapName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(features.levelHOTA8)
|
||||||
|
{
|
||||||
|
bool forceMatchingVersion = reader->readBool();
|
||||||
|
if (forceMatchingVersion)
|
||||||
|
logGlobal->warn("Map '%s': This map is forced to use specific hota version!", mapName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2401,7 +2416,8 @@ EQuestMission CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & positi
|
|||||||
case EQuestMission::KILL_HERO:
|
case EQuestMission::KILL_HERO:
|
||||||
case EQuestMission::KILL_CREATURE:
|
case EQuestMission::KILL_CREATURE:
|
||||||
{
|
{
|
||||||
assert(questsToResolve.count(guard) == 0);
|
// NOTE: assert might fail on multi-quest seers
|
||||||
|
//assert(questsToResolve.count(guard) == 0);
|
||||||
questsToResolve[guard] = reader->readUInt32();
|
questsToResolve[guard] = reader->readUInt32();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user