mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-24 03:47:18 +02:00
* reading disposed/predefined heroes (probably works)
* new discoveries in h3m specification VCMI handles correctly all known maps again :)
This commit is contained in:
parent
ee2a63f26e
commit
33fd0d22a6
@ -412,17 +412,29 @@ void CAmbarCendamo::deh3m()
|
||||
}
|
||||
}
|
||||
}
|
||||
if(map.version>RoE)
|
||||
if(map.version>RoE) //probably reserved for further heroes
|
||||
i+=4;
|
||||
unsigned char disp = 0;
|
||||
if(map.version>=SoD)
|
||||
{
|
||||
disp = bufor[i++];
|
||||
map.disposedHeroes.resize(disp);
|
||||
for(int g=0; g<disp; ++g)
|
||||
{
|
||||
i+=2;
|
||||
map.disposedHeroes[g].ID = bufor[i++];
|
||||
map.disposedHeroes[g].portrait = bufor[i++];
|
||||
int lenbuf = readNormalNr(i); i+=4;
|
||||
i+=lenbuf+1;
|
||||
for (int zz=0; zz<lenbuf; zz++)
|
||||
map.disposedHeroes[g].name+=bufor[i++];
|
||||
int players = bufor[i++];
|
||||
for(int zz=0;zz<8;zz++)
|
||||
{
|
||||
int por = (1<<zz);
|
||||
if(players & por)
|
||||
map.disposedHeroes[g].players[zz] = true;
|
||||
else
|
||||
map.disposedHeroes[g].players[zz] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//allowed heroes have been read
|
||||
@ -503,32 +515,244 @@ void CAmbarCendamo::deh3m()
|
||||
switch(map.version)
|
||||
{
|
||||
case WoG: case SoD: case AB:
|
||||
if(bufor[i]=='\0') //omit 156 bytes of rubbish
|
||||
{
|
||||
if(map.version>AB)
|
||||
i+=156;
|
||||
for(int z=0;z<HEROES_QUANTITY;z++) //disposed heroes
|
||||
{
|
||||
int custom = bufor[i++];
|
||||
if(!custom)
|
||||
continue;
|
||||
CHeroObjInfo * spec = new CHeroObjInfo;
|
||||
spec->type = CGI->heroh->heroes[z];
|
||||
bool isExp = bufor[i]; ++i; //true if hore's experience is greater than 0
|
||||
if(isExp)
|
||||
{
|
||||
spec->experience = readNormalNr(i); i+=4;
|
||||
}
|
||||
else
|
||||
{
|
||||
spec->experience = 0;
|
||||
}
|
||||
bool nonstandardAbilities = bufor[i]; ++i; //true if hero has specified abilities
|
||||
if(nonstandardAbilities)
|
||||
{
|
||||
int howMany = readNormalNr(i); i+=4;
|
||||
for(int yy=0; yy<howMany; ++yy)
|
||||
{
|
||||
spec->abilities.push_back(CGameInfo::mainObj->abilh->abilities[readNormalNr(i, 1)]); ++i;
|
||||
spec->abilityLevels.push_back(readNormalNr(i, 1)); ++i;
|
||||
}
|
||||
}
|
||||
bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts)
|
||||
int artmask = map.version == RoE ? 0xff : 0xffff;
|
||||
int artidlen = map.version == RoE ? 1 : 2;
|
||||
spec->artifWorn.resize(19);
|
||||
if(artSet)
|
||||
{
|
||||
//head art //1
|
||||
int id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[0] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[0] = NULL;
|
||||
//shoulders art //2
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[1] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[1] = NULL;
|
||||
//neck art //3
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[2] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[2] = NULL;
|
||||
//right hand art //4
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[3] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[3] = NULL;
|
||||
//left hand art //5
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[4] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[4] = NULL;
|
||||
//torso art //6
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[5] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[5] = NULL;
|
||||
//right hand ring //7
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[6] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[6] = NULL;
|
||||
//left hand ring //8
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[7] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[7] = NULL;
|
||||
//feet art //9
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[8] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[8] = NULL;
|
||||
//misc1 art //10
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[9] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[9] = NULL;
|
||||
//misc2 art //11
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[10] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[10] = NULL;
|
||||
//misc3 art //12
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[11] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[11] = NULL;
|
||||
//misc4 art //13
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[12] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[12] = NULL;
|
||||
//machine1 art //14
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[13] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[13] = NULL;
|
||||
//machine2 art //15
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[14] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[14] = NULL;
|
||||
//machine3 art //16
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[15] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[15] = NULL;
|
||||
//misc5 art //17
|
||||
if(map.version>=SoD)
|
||||
{
|
||||
i+=2;
|
||||
/*id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artMisc5 = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artMisc5 = NULL;*/
|
||||
}
|
||||
//spellbook
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[17] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[17] = NULL;
|
||||
//19 //???what is that? gap in file or what? - it's probably fifth slot..
|
||||
if(map.version>RoE)
|
||||
{
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifWorn[18] = &(CGameInfo::mainObj->arth->artifacts[id]);
|
||||
else
|
||||
spec->artifWorn[18] = NULL;
|
||||
}
|
||||
else
|
||||
i+=1;
|
||||
//bag artifacts //20
|
||||
int amount = readNormalNr(i, 2); i+=2; //number of artifacts in hero's bag
|
||||
if(amount>0)
|
||||
{
|
||||
for(int ss=0; ss<amount; ++ss)
|
||||
{
|
||||
id = readNormalNr(i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
spec->artifacts.push_back(&(CGameInfo::mainObj->arth->artifacts[id]));
|
||||
else
|
||||
spec->artifacts.push_back(NULL);
|
||||
}
|
||||
}
|
||||
} //artifacts
|
||||
else
|
||||
{
|
||||
spec->artifWorn[8] = NULL;
|
||||
spec->artifWorn[0] = NULL;
|
||||
spec->artifWorn[4] = NULL;
|
||||
spec->artifWorn[7] = NULL;
|
||||
spec->artifWorn[13] = NULL;
|
||||
spec->artifWorn[14] = NULL;
|
||||
spec->artifWorn[15] = NULL;
|
||||
spec->artifWorn[16] = NULL;
|
||||
spec->artifWorn[9] = NULL;
|
||||
spec->artifWorn[10] = NULL;
|
||||
spec->artifWorn[11] = NULL;
|
||||
spec->artifWorn[12] = NULL;
|
||||
spec->artifWorn[18] = NULL;
|
||||
spec->artifWorn[2] = NULL;
|
||||
spec->artifWorn[3] = NULL;
|
||||
spec->artifWorn[6] = NULL;
|
||||
spec->artifWorn[1] = NULL;
|
||||
spec->artifWorn[17] = NULL;
|
||||
spec->artifWorn[5] = NULL;
|
||||
}
|
||||
for(int t=spec->artifacts.size(); t<10; ++t) //it does make sense, even it is not obvious ;]
|
||||
spec->artifacts.push_back(NULL);
|
||||
int customBio = bufor[i++];
|
||||
if(customBio)
|
||||
{
|
||||
int length = readNormalNr(i); i+=4;
|
||||
for (int zz=0; zz<length; zz++)
|
||||
spec->biography+=bufor[i++];
|
||||
}
|
||||
int sex = bufor[i++]; // 0xFF is default, 00 male, 01 female
|
||||
bool areSpells = bufor[i]; ++i;
|
||||
if(areSpells) //TODO: sprawdziæ //seems to be ok - tow
|
||||
{
|
||||
int ist = i;
|
||||
for(i; i<ist+9; ++i)
|
||||
{
|
||||
unsigned char c = bufor[i];
|
||||
for(int yy=0; yy<8; ++yy)
|
||||
{
|
||||
if((i-ist)*8+yy < CGameInfo::mainObj->spellh->spells.size())
|
||||
{
|
||||
if(c == (c|((unsigned char)intPow(2, yy))))
|
||||
spec->spells.push_back(&(CGameInfo::mainObj->spellh->spells[(i-ist)*8+yy]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int customPrimSkills = bufor[i++];
|
||||
if(customPrimSkills)
|
||||
{
|
||||
spec->attack = bufor[i++];
|
||||
spec->defence = bufor[i++];
|
||||
spec->power = bufor[i++];
|
||||
spec->knowledge = bufor[i++];
|
||||
}
|
||||
else
|
||||
{
|
||||
spec->attack = -1;
|
||||
spec->defence = -1;
|
||||
spec->power = -1;
|
||||
spec->knowledge = -1;
|
||||
}
|
||||
map.predefinedHeroes.push_back(spec);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if(map.version!=AB || map.rumors.size()==0) //omit a lot of rubbish in a strage way
|
||||
{
|
||||
int lastFFpos=i;
|
||||
while(i-lastFFpos<350) //i far in terrain bytes
|
||||
{
|
||||
++i;
|
||||
if(bufor[i]==0xff)
|
||||
{
|
||||
lastFFpos=i;
|
||||
}
|
||||
}
|
||||
|
||||
i=lastFFpos;
|
||||
|
||||
while(bufor[i-1]!=0 || bufor[i]>8 || bufor[i+2]>4 || bufor[i+1]==0 || ( bufor[i+2]==0 && bufor[i+3]>0 ) || (bufor[i+4]==0 && bufor[i+5]>0)) //back to terrain bytes
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RoE:
|
||||
i+=0;
|
||||
break;
|
||||
|
2
map.cpp
2
map.cpp
@ -221,7 +221,7 @@ CMapHeader::CMapHeader(unsigned char *map)
|
||||
((VicCona*)this->vicConDetails)->destinationPlace.x = map[i+3];
|
||||
((VicCona*)this->vicConDetails)->destinationPlace.y = map[i+4];
|
||||
((VicCona*)this->vicConDetails)->destinationPlace.z = map[i+5];
|
||||
nr=3;
|
||||
nr=4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
10
map.h
10
map.h
@ -7,6 +7,7 @@
|
||||
#include "hch\CSemiDefHandler.h"
|
||||
#include "hch\CDefHandler.h"
|
||||
class CGDefInfo;
|
||||
class CHeroObjInfo;
|
||||
enum ESortBy{name,playerAm,size,format, viccon,loscon};
|
||||
struct Sresource
|
||||
{
|
||||
@ -150,6 +151,13 @@ struct Rumor
|
||||
std::string name, text;
|
||||
};
|
||||
|
||||
struct DisposedHero
|
||||
{
|
||||
int ID;
|
||||
int portrait; //0xFF - default
|
||||
std::string name;
|
||||
bool players[8]; //who can hire this hero
|
||||
};
|
||||
|
||||
class CMapEvent
|
||||
{
|
||||
@ -176,6 +184,8 @@ struct Mapa
|
||||
TerrainTile** terrain;
|
||||
TerrainTile** undergroungTerrain; // used only if there is underground level
|
||||
std::vector<Rumor> rumors;
|
||||
std::vector<DisposedHero> disposedHeroes;
|
||||
std::vector<CHeroObjInfo*> predefinedHeroes;
|
||||
std::vector<CGDefInfo *> defy; // list of .def files
|
||||
PlayerInfo players[8]; // info about players
|
||||
std::vector<int> teams; // teams[i] = team of player no i
|
||||
|
Loading…
x
Reference in New Issue
Block a user