2023-04-02 18:56:10 +02:00
|
|
|
/*
|
|
|
|
* MapFeaturesH3M.cpp, part of VCMI engine
|
|
|
|
*
|
|
|
|
* Authors: listed in file AUTHORS in main folder
|
|
|
|
*
|
|
|
|
* License: GNU General Public License v2.0 or later
|
|
|
|
* Full text of license available in license.txt file, in main folder
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "StdInc.h"
|
|
|
|
#include "MapFeaturesH3M.h"
|
2023-04-03 14:02:15 +02:00
|
|
|
|
2023-05-24 00:14:06 +02:00
|
|
|
#include "MapFormat.h"
|
2023-04-02 18:56:10 +02:00
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
2023-04-04 14:40:16 +02:00
|
|
|
MapFormatFeaturesH3M MapFormatFeaturesH3M::find(EMapFormat format, uint32_t hotaVersion)
|
2023-04-02 18:56:10 +02:00
|
|
|
{
|
2023-04-03 14:02:15 +02:00
|
|
|
switch(format)
|
2023-04-02 18:56:10 +02:00
|
|
|
{
|
2023-04-03 14:02:15 +02:00
|
|
|
case EMapFormat::ROE:
|
|
|
|
return getFeaturesROE();
|
|
|
|
case EMapFormat::AB:
|
|
|
|
return getFeaturesAB();
|
|
|
|
case EMapFormat::SOD:
|
|
|
|
return getFeaturesSOD();
|
|
|
|
case EMapFormat::WOG:
|
|
|
|
return getFeaturesWOG();
|
2023-04-10 13:01:09 +02:00
|
|
|
case EMapFormat::HOTA:
|
2023-04-03 19:51:02 +02:00
|
|
|
return getFeaturesHOTA(hotaVersion);
|
2023-04-02 18:56:10 +02:00
|
|
|
default:
|
|
|
|
throw std::runtime_error("Invalid map format!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesROE()
|
|
|
|
{
|
|
|
|
MapFormatFeaturesH3M result;
|
|
|
|
result.levelROE = true;
|
|
|
|
|
|
|
|
result.factionsBytes = 1;
|
|
|
|
result.heroesBytes = 16;
|
|
|
|
result.artifactsBytes = 16;
|
|
|
|
result.skillsBytes = 4;
|
|
|
|
result.resourcesBytes = 4;
|
|
|
|
result.spellsBytes = 9;
|
|
|
|
result.buildingsBytes = 6;
|
|
|
|
|
|
|
|
result.factionsCount = 8;
|
|
|
|
result.heroesCount = 128;
|
|
|
|
result.heroesPortraitsCount = 128;
|
|
|
|
result.artifactsCount = 127;
|
|
|
|
result.resourcesCount = 7;
|
|
|
|
result.creaturesCount = 118;
|
|
|
|
result.spellsCount = 70;
|
|
|
|
result.skillsCount = 28;
|
|
|
|
result.terrainsCount = 10;
|
|
|
|
result.artifactSlotsCount = 18;
|
2023-05-23 14:07:44 +02:00
|
|
|
result.buildingsCount = 41;
|
2023-04-02 18:56:10 +02:00
|
|
|
|
|
|
|
result.heroIdentifierInvalid = 0xff;
|
|
|
|
result.artifactIdentifierInvalid = 0xff;
|
|
|
|
result.creatureIdentifierInvalid = 0xff;
|
|
|
|
result.spellIdentifierInvalid = 0xff;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesAB()
|
|
|
|
{
|
|
|
|
MapFormatFeaturesH3M result = getFeaturesROE();
|
|
|
|
result.levelAB = true;
|
|
|
|
|
|
|
|
result.factionsBytes = 2; // + Conflux
|
|
|
|
result.factionsCount = 9;
|
|
|
|
|
2023-05-20 14:09:53 +02:00
|
|
|
result.creaturesCount = 145; // + Conflux and new neutrals
|
2023-04-02 18:56:10 +02:00
|
|
|
|
|
|
|
result.heroesCount = 156; // + Conflux and campaign heroes
|
|
|
|
result.heroesPortraitsCount = 163;
|
|
|
|
result.heroesBytes = 20;
|
|
|
|
|
|
|
|
result.artifactsCount = 129; // + Armaggedon Blade and Vial of Dragon Blood
|
|
|
|
result.artifactsBytes = 17;
|
|
|
|
|
|
|
|
result.artifactIdentifierInvalid = 0xffff; // Now uses 2 bytes / object
|
|
|
|
result.creatureIdentifierInvalid = 0xffff; // Now uses 2 bytes / object
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesSOD()
|
|
|
|
{
|
|
|
|
MapFormatFeaturesH3M result = getFeaturesAB();
|
|
|
|
result.levelSOD = true;
|
|
|
|
|
|
|
|
result.artifactsCount = 141; // + Combined artifacts
|
|
|
|
result.artifactsBytes = 18;
|
|
|
|
|
|
|
|
result.artifactSlotsCount = 19; // + MISC_5 slot
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesWOG()
|
|
|
|
{
|
|
|
|
MapFormatFeaturesH3M result = getFeaturesSOD();
|
|
|
|
result.levelWOG = true;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-04-04 14:40:16 +02:00
|
|
|
MapFormatFeaturesH3M MapFormatFeaturesH3M::getFeaturesHOTA(uint32_t hotaVersion)
|
2023-04-02 18:56:10 +02:00
|
|
|
{
|
2023-04-10 13:01:09 +02:00
|
|
|
// even if changes are minimal, we might not be able to parse map header in map selection screen
|
2023-05-20 17:28:35 +02:00
|
|
|
// throw exception - to be catched by map selection screen & excluded as invalid
|
2023-04-10 13:01:09 +02:00
|
|
|
if(hotaVersion > 3)
|
|
|
|
throw std::runtime_error("Invalid map format!");
|
2023-04-04 12:45:31 +02:00
|
|
|
|
2023-04-02 18:56:10 +02:00
|
|
|
MapFormatFeaturesH3M result = getFeaturesSOD();
|
2023-04-09 00:03:43 +02:00
|
|
|
result.levelHOTA0 = true;
|
|
|
|
result.levelHOTA1 = hotaVersion > 0;
|
2023-04-04 14:40:16 +02:00
|
|
|
//result.levelHOTA2 = hotaVersion > 1; // HOTA2 seems to be identical to HOTA1 so far
|
|
|
|
result.levelHOTA3 = hotaVersion > 2;
|
2023-04-02 18:56:10 +02:00
|
|
|
|
2023-04-03 19:51:02 +02:00
|
|
|
result.artifactsBytes = 21;
|
2023-04-04 12:45:31 +02:00
|
|
|
result.heroesBytes = 23;
|
2023-04-03 19:51:02 +02:00
|
|
|
|
|
|
|
result.terrainsCount = 12; // +Highlands +Wasteland
|
|
|
|
result.skillsCount = 29; // + Interference
|
2023-04-03 17:56:49 +02:00
|
|
|
result.factionsCount = 10; // + Cove
|
2023-04-04 12:45:31 +02:00
|
|
|
result.creaturesCount = 171; // + Cove + neutrals
|
|
|
|
|
2023-04-10 13:01:09 +02:00
|
|
|
if(hotaVersion < 3)
|
2023-04-04 12:45:31 +02:00
|
|
|
{
|
|
|
|
result.artifactsCount = 163; // + HotA artifacts
|
2023-06-20 14:09:42 +02:00
|
|
|
result.heroesCount = 178; // + Cove
|
2023-07-17 15:22:43 +02:00
|
|
|
result.heroesPortraitsCount = 186; // + Cove
|
2023-04-04 12:45:31 +02:00
|
|
|
}
|
|
|
|
if(hotaVersion == 3)
|
|
|
|
{
|
|
|
|
result.artifactsCount = 165; // + HotA artifacts
|
2023-06-20 14:09:42 +02:00
|
|
|
result.heroesCount = 179; // + Cove + Giselle
|
2023-05-25 23:38:00 +02:00
|
|
|
result.heroesPortraitsCount = 188; // + Cove + Giselle
|
2023-04-04 12:45:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
assert((result.heroesCount + 7) / 8 == result.heroesBytes);
|
|
|
|
assert((result.artifactsCount + 7) / 8 == result.artifactsBytes);
|
2023-04-03 17:56:49 +02:00
|
|
|
|
2023-04-02 18:56:10 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|