1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

Further serialization code and refactorings.

This commit is contained in:
Michał W. Urbańczyk
2009-01-06 18:42:20 +00:00
parent f853074d20
commit 847a4f222c
17 changed files with 777 additions and 724 deletions

View File

@@ -55,12 +55,12 @@ std::string DLL_EXPORT toString(MetaString &ms)
} }
else if(type == 9) else if(type == 9)
{ {
ret += VLC->objh->mines[ser].first; ret += VLC->generaltexth->mines[ser].first;
continue; continue;
} }
else if(type == 10) else if(type == 10)
{ {
ret += VLC->objh->mines[ser].second; ret += VLC->generaltexth->mines[ser].second;
continue; continue;
} }
else else
@@ -71,22 +71,22 @@ std::string DLL_EXPORT toString(MetaString &ms)
vec = &VLC->generaltexth->allTexts; vec = &VLC->generaltexth->allTexts;
break; break;
case 2: case 2:
vec = &VLC->objh->xtrainfo; vec = &VLC->generaltexth->xtrainfo;
break; break;
case 3: case 3:
vec = &VLC->objh->names; vec = &VLC->generaltexth->names;
break; break;
case 4: case 4:
vec = &VLC->objh->restypes; vec = &VLC->generaltexth->restypes;
break; break;
case 6: case 6:
vec = &VLC->generaltexth->arraytxt; vec = &VLC->generaltexth->arraytxt;
break; break;
case 8: case 8:
vec = &VLC->objh->creGens; vec = &VLC->generaltexth->creGens;
break; break;
case 11: case 11:
vec = &VLC->objh->advobtxt; vec = &VLC->generaltexth->advobtxt;
break; break;
case 12: case 12:
vec = &VLC->generaltexth->artifEvents; vec = &VLC->generaltexth->artifEvents;
@@ -1084,7 +1084,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
//we have to replace normal random object //we have to replace normal random object
cur->ID = ran.first; cur->ID = ran.first;
cur->subID = ran.second; cur->subID = ran.second;
map->defs.insert(cur->defInfo = VLC->dobjinfo->gobjs[ran.first][ran.second]); map->defy.push_back(cur->defInfo = VLC->dobjinfo->gobjs[ran.first][ran.second]);
if(!cur->defInfo) if(!cur->defInfo)
{ {
tlog1<<"*BIG* WARNING: Missing def declaration for "<<cur->ID<<" "<<cur->subID<<std::endl; tlog1<<"*BIG* WARNING: Missing def declaration for "<<cur->ID<<" "<<cur->subID<<std::endl;
@@ -1159,7 +1159,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
map->objects[no]->defInfo->blockMap[5] = 255; map->objects[no]->defInfo->blockMap[5] = 255;
map->addBlockVisTiles(map->objects[no]); map->addBlockVisTiles(map->objects[no]);
} }
map->objects[no]->hoverName = VLC->objh->names[map->objects[no]->ID]; map->objects[no]->hoverName = VLC->generaltexth->names[map->objects[no]->ID];
} }
//std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl; //std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl;
@@ -1245,7 +1245,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
for(int i=0; i<map->allowedHeroes.size(); i++) //add to hids all allowed heroes for(int i=0; i<map->allowedHeroes.size(); i++) //add to hids all allowed heroes
if(map->allowedHeroes[i]) if(map->allowedHeroes[i])
hids.insert(i); hids.insert(i);
for (int i=0; i<map->heroes.size();i++) //heroes instances for (int i=0; i<map->heroes.size();i++) //heroes instances initialization
{ {
if (map->heroes[i]->getOwner()<0) if (map->heroes[i]->getOwner()<0)
{ {
@@ -1452,6 +1452,11 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
} }
} }
for(int i=0; i<map->defy.size(); i++)
{
map->defy[i]->serial = i;
}
for(int i=0; i<map->objects.size(); i++) for(int i=0; i<map->objects.size(); i++)
map->objects[i]->initObj(); map->objects[i]->initObj();
} }

View File

@@ -178,6 +178,11 @@ private:
std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1); CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroesPool & pavailable;
}
} hpool; //we have here all heroes available on this map that are not hired } hpool; //we have here all heroes available on this map that are not hired
boost::shared_mutex *mx; boost::shared_mutex *mx;
@@ -208,12 +213,11 @@ public:
int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & scenarioOps & seed & currentPlayer & day & map & players & resVals; h & scenarioOps & seed & currentPlayer & day & map & players & resVals & hpool;
if(!h.saving) if(!h.saving)
{ {
loadTownDInfos(); loadTownDInfos();
} }
//TODO: hero pool
} }
friend class CCallback; friend class CCallback;

View File

@@ -922,13 +922,18 @@ void MapSel::printMaps(int from, int to, int at, bool abs)
if (!(ourMaps[(i-at)+from].name.length())) if (!(ourMaps[(i-at)+from].name.length()))
ourMaps[(i-at)+from].name = "Unnamed"; ourMaps[(i-at)+from].name = "Unnamed";
CSDL_Ext::printAtMiddle(ourMaps[(i-at)+from].name,192,13,GEOR13,nasz,scenin, 2); CSDL_Ext::printAtMiddle(ourMaps[(i-at)+from].name,192,13,GEOR13,nasz,scenin, 2);
if (ourMaps[(i-at)+from].victoryCondition==winStandard) if (ourMaps[(i-at)+from].victoryCondition.condition == winStandard)
temp=11; temp=11;
else temp=ourMaps[(i-at)+from].victoryCondition; else
temp=ourMaps[(i-at)+from].victoryCondition.condition;
blitAt(Dvic->ourImages[temp].bitmap,285,2,scenin); blitAt(Dvic->ourImages[temp].bitmap,285,2,scenin);
if (ourMaps[(i-at)+from].lossCondition.typeOfLossCon == lossStandard) if (ourMaps[(i-at)+from].lossCondition.typeOfLossCon == lossStandard)
temp=3; temp=3;
else temp=ourMaps[(i-at)+from].lossCondition.typeOfLossCon; else
temp=ourMaps[(i-at)+from].lossCondition.typeOfLossCon;
blitAt(Dloss->ourImages[temp].bitmap,318,2,scenin); blitAt(Dloss->ourImages[temp].bitmap,318,2,scenin);
blitAt(scenin,24,121+(i-at)*25); blitAt(scenin,24,121+(i-at)*25);
@@ -1251,10 +1256,10 @@ void MapSel::printSelectedInfo()
CSDL_Ext::printAt(CGI->generaltexth->allTexts[390],420,406,GEOR13,zwykly); CSDL_Ext::printAt(CGI->generaltexth->allTexts[390],420,406,GEOR13,zwykly);
CSDL_Ext::printAt(CGI->generaltexth->allTexts[391],585,406,GEOR13,zwykly); CSDL_Ext::printAt(CGI->generaltexth->allTexts[391],585,406,GEOR13,zwykly);
int temp = ourMaps[selected].victoryCondition+1; int temp = ourMaps[selected].victoryCondition.condition+1;
if (temp>20) temp=0; if (temp>20) temp=0;
std::string sss = CGI->generaltexth->victoryConditions[temp]; std::string sss = CGI->generaltexth->victoryConditions[temp];
if (temp && ourMaps[selected].vicConDetails->allowNormalVictory) sss+= "/" + CGI->generaltexth->victoryConditions[0]; if (temp && ourMaps[selected].victoryCondition.allowNormalVictory) sss+= "/" + CGI->generaltexth->victoryConditions[0];
CSDL_Ext::printAt(sss,452,310,GEOR13,zwykly); CSDL_Ext::printAt(sss,452,310,GEOR13,zwykly);
@@ -1312,7 +1317,7 @@ void MapSel::printSelectedInfo()
break; break;
} }
blitAt(Dsizes->ourImages[temp].bitmap,714,28); blitAt(Dsizes->ourImages[temp].bitmap,714,28);
temp=ourMaps[selected].victoryCondition; temp = ourMaps[selected].victoryCondition.condition;
if (temp>12) temp=11; if (temp>12) temp=11;
blitAt(Dvic->ourImages[temp].bitmap,420,308); //v blitAt(Dvic->ourImages[temp].bitmap,420,308); //v
temp=ourMaps[selected].lossCondition.typeOfLossCon; temp=ourMaps[selected].lossCondition.typeOfLossCon;

View File

@@ -120,7 +120,7 @@ void CClient::process(int what)
{ {
SetResource sr; SetResource sr;
*serv >> sr; *serv >> sr;
tlog5 << "Set amount of "<<CGI->objh->restypes[sr.resid] tlog5 << "Set amount of "<<CGI->generaltexth->restypes[sr.resid]
<< " of player "<<(unsigned)sr.player <<" to "<<sr.val<<std::endl; << " of player "<<(unsigned)sr.player <<" to "<<sr.val<<std::endl;
gs->apply(&sr); gs->apply(&sr);
playerint[sr.player]->receivedResource(sr.resid,sr.val); playerint[sr.player]->receivedResource(sr.resid,sr.val);

View File

@@ -7,7 +7,7 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
extern CLodHandler * bitmaph; extern CLodHandler * bitmaph;
unsigned int readNr(std::string &in, unsigned int &it) unsigned int readNr(std::string &in, int &it)
{ {
int last=it; int last=it;
for(;last<in.size();last++) for(;last<in.size();last++)
@@ -24,7 +24,7 @@ unsigned int readNr(std::string &in, unsigned int &it)
ss >> last; ss >> last;
return last; return last;
} }
CBuilding * readBg(std::string &buf, unsigned int& it) CBuilding * readBg(std::string &buf, int& it)
{ {
CBuilding * nb = new CBuilding(); CBuilding * nb = new CBuilding();
nb->resources.resize(RESOURCE_QUANTITY); nb->resources.resize(RESOURCE_QUANTITY);
@@ -37,7 +37,8 @@ CBuilding * readBg(std::string &buf, unsigned int& it)
void CBuildingHandler::loadBuildings() void CBuildingHandler::loadBuildings()
{ {
std::string buf = bitmaph->getTextFile("BUILDING.TXT"), temp; std::string buf = bitmaph->getTextFile("BUILDING.TXT"), temp;
unsigned int andame = buf.size(), it=0; //buf iterator unsigned int andame = buf.size();
int it=0; //buf iterator
temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//read 2 lines of file info temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//read 2 lines of file info

View File

@@ -18,6 +18,7 @@ bool CGDefInfo::isVisitable()
} }
CGDefInfo::CGDefInfo() CGDefInfo::CGDefInfo()
{ {
serial = -1;
visitDir = (8|16|32|64|128); //4,5,6,7,8 - any not-from-up direction visitDir = (8|16|32|64|128); //4,5,6,7,8 - any not-from-up direction
} }
void CDefObjInfoHandler::load() void CDefObjInfoHandler::load()

View File

@@ -10,16 +10,17 @@ class DLL_EXPORT CGDefInfo
public: public:
std::string name; std::string name;
unsigned char visitMap[6]; ui8 visitMap[6];
unsigned char blockMap[6]; ui8 blockMap[6];
unsigned char visitDir; //directions from which object can be entered, format same as for moveDir in CGHeroInstance(but 0 - 7) ui8 visitDir; //directions from which object can be entered, format same as for moveDir in CGHeroInstance(but 0 - 7)
int id, subid; //of object described by this defInfo si32 id, subid; //of object described by this defInfo
int terrainAllowed, //on which terrain it is possible to place object si32 serial;
si32 terrainAllowed, //on which terrain it is possible to place object
terrainMenu; //in which menus in map editor object will be showed terrainMenu; //in which menus in map editor object will be showed
int width, height; //tiles si32 width, height; //tiles
int type; //(0- ground, 1- towns, 2-creatures, 3- heroes, 4-artifacts, 5- resources) si32 type; //(0- ground, 1- towns, 2-creatures, 3- heroes, 4-artifacts, 5- resources)
CDefHandler * handler; CDefHandler * handler;
int printPriority; si32 printPriority;
bool isVisitable(); bool isVisitable();
bool operator<(const CGDefInfo& por) bool operator<(const CGDefInfo& por)
{ {
@@ -30,7 +31,8 @@ public:
} }
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & name & visitMap & blockMap & visitDir & id & subid &terrainAllowed & terrainMenu & width & height & type & printPriority; h & name & serial & visitMap & blockMap & visitDir & id & subid &terrainAllowed
& terrainMenu & width & height & type & printPriority;
} }
CGDefInfo(); CGDefInfo();
}; };
@@ -39,7 +41,6 @@ class DLL_EXPORT CDefObjInfoHandler
public: public:
std::map<int,std::map<int,CGDefInfo*> > gobjs; std::map<int,std::map<int,CGDefInfo*> > gobjs;
std::map<int,CGDefInfo*> castles; std::map<int,CGDefInfo*> castles;
//std::vector<DefObjInfo> objs;
void load(); void load();

View File

@@ -8,7 +8,7 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
std::string readTo(std::string &in, unsigned int &it, char end) std::string readTo(std::string &in, int &it, char end)
{ {
int pom = it; int pom = it;
int last = in.find_first_of(end,it); int last = in.find_first_of(end,it);
@@ -174,7 +174,7 @@ void CGeneralTextHandler::loadTexts()
loadToIt(hTxts[iii].biography,buf,i,3); loadToIt(hTxts[iii].biography,buf,i,3);
} }
unsigned it; int it;
buf = bitmaph->getTextFile("BLDGNEUT.TXT"); buf = bitmaph->getTextFile("BLDGNEUT.TXT");
andame = buf.size(), it=0; andame = buf.size(), it=0;
@@ -250,9 +250,9 @@ void CGeneralTextHandler::loadTexts()
hcommands.push_back(tmp); hcommands.push_back(tmp);
} }
std::istringstream ins, names; std::istringstream ins, namess;
ins.str(bitmaph->getTextFile("TOWNTYPE.TXT")); ins.str(bitmaph->getTextFile("TOWNTYPE.TXT"));
names.str(bitmaph->getTextFile("TOWNNAME.TXT")); namess.str(bitmaph->getTextFile("TOWNNAME.TXT"));
int si=0; int si=0;
char bufname[75]; char bufname[75];
while (!ins.eof()) while (!ins.eof())
@@ -263,9 +263,85 @@ void CGeneralTextHandler::loadTexts()
for (int i=0; i<NAMES_PER_TOWN; i++) for (int i=0; i<NAMES_PER_TOWN; i++)
{ {
names.getline(bufname,50); namess.getline(bufname,50);
townNames[si].push_back(std::string(bufname).substr(0,strlen(bufname)-1)); townNames[si].push_back(std::string(bufname).substr(0,strlen(bufname)-1));
} }
si++; si++;
} }
tlog5 << "\t\tReading OBJNAMES \n";
buf = bitmaph->getTextFile("OBJNAMES.TXT");
it=0; //hope that -1 will not break this
while (it<buf.length()-1)
{
std::string nobj;
loadToIt(nobj, buf, it, 3);
if(nobj.size() && (nobj[nobj.size()-1]==(char)10 || nobj[nobj.size()-1]==(char)13 || nobj[nobj.size()-1]==(char)9))
{
nobj = nobj.substr(0, nobj.size()-1);
}
names.push_back(nobj);
}
tlog5 << "\t\tReading ADVEVENT \n";
buf = bitmaph->getTextFile("ADVEVENT.TXT");
it=0;
std::string temp;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
if (temp[0]=='\"')
{
temp = temp.substr(1,temp.length()-2);
}
boost::algorithm::replace_all(temp,"\"\"","\"");
advobtxt.push_back(temp);
}
tlog5 << "\t\tReading XTRAINFO \n";
buf = bitmaph->getTextFile("XTRAINFO.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
xtrainfo.push_back(temp);
}
tlog5 << "\t\tReading MINENAME \n";
buf = bitmaph->getTextFile("MINENAME.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
mines.push_back(std::pair<std::string,std::string>(temp,""));
}
tlog5 << "\t\tReading MINEEVNT \n";
buf = bitmaph->getTextFile("MINEEVNT.TXT");
it=0;
i=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
temp = temp.substr(1,temp.length()-2);
mines[i++].second = temp;
}
tlog5 << "\t\tReading RESTYPES \n";
buf = bitmaph->getTextFile("RESTYPES.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
restypes.push_back(temp);
}
tlog5 << "\t\tReading ZCRGN1 \n";
buf = bitmaph->getTextFile("ZCRGN1.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
creGens.push_back(temp);
}
} }

View File

@@ -4,7 +4,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode); DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode);
std::string readTo(std::string &in, unsigned int &it, char end); std::string readTo(std::string &in, int &it, char end);
class DLL_EXPORT CGeneralTextHandler //Handles general texts class DLL_EXPORT CGeneralTextHandler //Handles general texts
{ {
public: public:
@@ -37,6 +37,15 @@ public:
std::vector<std::pair<std::string,std::string> > zelp; std::vector<std::pair<std::string,std::string> > zelp;
std::string lossCondtions[4]; std::string lossCondtions[4];
std::string victoryConditions[14]; std::string victoryConditions[14];
//objects
std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i
std::vector<std::string> creGens; //names of creatures' generators
std::vector<std::string> advobtxt;
std::vector<std::string> xtrainfo;
std::vector<std::string> restypes;
std::vector<std::pair<std::string,std::string> > mines; //first - name; second - event description
std::string getTitle(std::string text); std::string getTitle(std::string text);
std::string getDescr(std::string text); std::string getDescr(std::string text);

View File

@@ -44,75 +44,6 @@ void IObjectInterface::initObj()
void CObjectHandler::loadObjects() void CObjectHandler::loadObjects()
{ {
VLC->objh = this;
// int ID=0; //TODO use me
tlog5 << "\t\tReading OBJNAMES \n";
std::string buf = bitmaph->getTextFile("OBJNAMES.TXT");
int it=0; //hope that -1 will not break this
while (it<buf.length()-1)
{
std::string nobj;
loadToIt(nobj, buf, it, 3);
if(nobj.size() && (nobj[nobj.size()-1]==(char)10 || nobj[nobj.size()-1]==(char)13 || nobj[nobj.size()-1]==(char)9))
{
nobj = nobj.substr(0, nobj.size()-1);
}
names.push_back(nobj);
}
tlog5 << "\t\tReading ADVEVENT \n";
buf = bitmaph->getTextFile("ADVEVENT.TXT");
it=0;
std::string temp;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
if (temp[0]=='\"')
{
temp = temp.substr(1,temp.length()-2);
}
boost::algorithm::replace_all(temp,"\"\"","\"");
advobtxt.push_back(temp);
}
tlog5 << "\t\tReading XTRAINFO \n";
buf = bitmaph->getTextFile("XTRAINFO.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
xtrainfo.push_back(temp);
}
tlog5 << "\t\tReading MINENAME \n";
buf = bitmaph->getTextFile("MINENAME.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
mines.push_back(std::pair<std::string,std::string>(temp,""));
}
tlog5 << "\t\tReading MINEEVNT \n";
buf = bitmaph->getTextFile("MINEEVNT.TXT");
it=0;
int i=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
temp = temp.substr(1,temp.length()-2);
mines[i++].second = temp;
}
tlog5 << "\t\tReading RESTYPES \n";
buf = bitmaph->getTextFile("RESTYPES.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
restypes.push_back(temp);
}
tlog5 << "\t\tReading cregens \n"; tlog5 << "\t\tReading cregens \n";
cregens.resize(110); //TODO: hardcoded value - change cregens.resize(110); //TODO: hardcoded value - change
for(size_t i=0; i < cregens.size(); ++i) for(size_t i=0; i < cregens.size(); ++i)
@@ -128,15 +59,6 @@ void CObjectHandler::loadObjects()
} }
ifs.close(); ifs.close();
ifs.clear(); ifs.clear();
tlog5 << "\t\tReading ZCRGN1 \n";
buf = bitmaph->getTextFile("ZCRGN1.TXT");
it=0;
while (it<buf.length()-1)
{
loadToIt(temp,buf,it,3);
creGens.push_back(temp);
}
tlog5 << "\t\tDone loading objects!\n"; tlog5 << "\t\tDone loading objects!\n";
} }
int CGObjectInstance::getOwner() const int CGObjectInstance::getOwner() const
@@ -994,7 +916,7 @@ const std::string & CGVisitableOPH::getHoverText() const
default: default:
throw "Wrong CGVisitableOPH object ID!\n"; throw "Wrong CGVisitableOPH object ID!\n";
} }
hoverName = VLC->objh->names[ID] + " " + VLC->objh->xtrainfo[pom]; hoverName = VLC->generaltexth->names[ID] + " " + VLC->generaltexth->xtrainfo[pom];
const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
if(h) if(h)
{ {
@@ -1110,7 +1032,7 @@ void CGMine::initObj()
void CGResource::initObj() void CGResource::initObj()
{ {
blockVisit = true; blockVisit = true;
hoverName = VLC->objh->restypes[subID]; hoverName = VLC->generaltexth->restypes[subID];
if(!amount) if(!amount)
{ {
@@ -1146,7 +1068,7 @@ void CGResource::onHeroVisit( const CGHeroInstance * h ) const
sii.player = h->tempOwner; sii.player = h->tempOwner;
sii.c = Component(2,subID,amount,0); sii.c = Component(2,subID,amount,0);
sii.text << std::pair<ui8,ui32>(11,113); sii.text << std::pair<ui8,ui32>(11,113);
sii.text.replacements.push_back(VLC->objh->restypes[subID]); sii.text.replacements.push_back(VLC->generaltexth->restypes[subID]);
cb->showCompInfo(&sii); cb->showCompInfo(&sii);
cb->removeObject(id); cb->removeObject(id);
} }

View File

@@ -119,7 +119,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & hoverName & pos & ID & subID & id & animPhaseShift & tempOwner & blockVisit; h & hoverName & pos & ID & subID & id & animPhaseShift & tempOwner & blockVisit;
//TODO: definfo //definfo is handled by map serializer
} }
}; };
@@ -131,6 +131,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<CGObjectInstance&>(*this);
h & army; h & army;
} }
}; };
@@ -176,10 +177,17 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<CArmedInstance&>(*this);
h & exp & level & name & biography & portrait & mana & primSkills & secSkills & movement h & exp & level & name & biography & portrait & mana & primSkills & secSkills & movement
& identifier & sex & inTownGarrison & artifacts & artifWorn & spells; & identifier & sex & inTownGarrison & artifacts & artifWorn & spells;
//TODO: type
//TODO: visited town ui8 standardType = (VLC->heroh->heroes[subID] == type);
h & standardType;
if(!standardType)
h & type;
else if(!h.saving)
type = VLC->heroh->heroes[subID];
//visitied town pointer will be restored by map serialization method
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -246,10 +254,18 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<CArmedInstance&>(*this);
h & name & builded & destroyed & identifier & alignment & forbiddenBuildings & builtBuildings h & name & builded & destroyed & identifier & alignment & forbiddenBuildings & builtBuildings
& possibleSpells & obligatorySpells & spells & strInfo & events; & possibleSpells & obligatorySpells & spells & strInfo & events;
//TODO: town
//TODO: garrison/visiting hero ui8 standardType = (&VLC->townh->towns[subID] == town);
h & standardType;
if(!standardType)
h & town;
else if(!h.saving)
town = &VLC->townh->towns[subID];
//garrison/visiting hero pointers will be restored in the map serialization
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -290,32 +306,41 @@ public:
void onNAHeroVisit(int heroID, bool alreadyVisited) const; void onNAHeroVisit(int heroID, bool alreadyVisited) const;
void initObj(); void initObj();
void treeSelected(int heroID, int resType, int resVal, int expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog void treeSelected(int heroID, int resType, int resVal, int expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & visitors & ttype;
}
}; };
class DLL_EXPORT CGEvent : public CGObjectInstance //event objects class DLL_EXPORT CGEvent : public CGObjectInstance //event objects
{ {
public: public:
bool areGuarders; //true if there are
CCreatureSet guarders; CCreatureSet guarders;
bool isMessage; //true if there is a message
std::string message; std::string message;
unsigned int gainedExp; ui32 gainedExp;
int manaDiff; //amount of gained / lost mana si32 manaDiff; //amount of gained / lost mana
int moraleDiff; //morale modifier si32 moraleDiff; //morale modifier
int luckDiff; //luck modifier si32 luckDiff; //luck modifier
int wood, mercury, ore, sulfur, crystal, gems, gold; //gained / lost resources std::vector<si32> resources;//gained / lost resources
unsigned int attack; //added attack points std::vector<si32> primskills;//gained / lost resources
unsigned int defence; //added defence points std::vector<si32> abilities; //gained abilities
unsigned int power; //added power points std::vector<si32> abilityLevels; //levels of gained abilities
unsigned int knowledge; //added knowledge points std::vector<si32> artifacts; //gained artifacts
std::vector<int> abilities; //gained abilities std::vector<si32> spells; //gained spells
std::vector<int> abilityLevels; //levels of gained abilities
std::vector<int> artifacts; //gained artifacts
std::vector<int> spells; //gained spells
CCreatureSet creatures; //gained creatures CCreatureSet creatures; //gained creatures
unsigned char availableFor; //players whom this event is available for ui8 availableFor; //players whom this event is available for
bool computerActivate; //true if computre player can activate this event ui8 computerActivate; //true if computre player can activate this event
bool humanActivate; //true if human player can activate this event ui8 humanActivate; //true if human player can activate this event
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & guarders & message & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills
& abilities & abilityLevels & artifacts & spells & creatures & availableFor
& computerActivate & humanActivate;
}
}; };
class DLL_EXPORT CGCreature : public CArmedInstance //creatures on map class DLL_EXPORT CGCreature : public CArmedInstance //creatures on map
@@ -332,6 +357,12 @@ public:
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void endBattle(BattleResult *result) const; void endBattle(BattleResult *result) const;
void initObj(); void initObj();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArmedInstance&>(*this);
h & identifier & character & message & resources & gainedArtifact & neverFlees & notGrowingTeam;
}
}; };
@@ -340,42 +371,39 @@ class DLL_EXPORT CGSignBottle : public CGObjectInstance //signs and ocean bottle
//TODO: generate default message if sign is 'empty' //TODO: generate default message if sign is 'empty'
public: public:
std::string message; std::string message;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & message;
}
}; };
class DLL_EXPORT CGSeerHut : public CGObjectInstance, public CQuest class DLL_EXPORT CGSeerHut : public CGObjectInstance, public CQuest
{ {
public: public:
char rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature ui8 rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature
//for reward 1
int r1exp; si32 rID;
//for reward 2 si32 rVal;
int r2mana;
//for reward 3 template <typename Handler> void serialize(Handler &h, const int version)
int r3morale; {
//for reward 4 h & static_cast<CGObjectInstance&>(*this) & static_cast<CQuest&>(*this);
int r4luck; h & rewardType & rID & rVal;
//for reward 5 }
unsigned char r5type; //0 - wood, 1 - mercury, 2 - ore, 3 - sulfur, 4 - crystal, 5 - gems, 6 - gold
int r5amount;
//for reward 6
unsigned char r6type; //0 - attack, 1 - defence, 2 - power, 3 - knowledge
int r6amount;
//for reward 7
int r7ability; //ability id
unsigned char r7level; //1 - basic, 2 - advanced, 3 - expert
//for reward 8
int r8art;//artifact id
//for reward 9
int r9spell;//spell id
//for reward 10
int r10creature; //creature id
int r10amount;
}; };
class DLL_EXPORT CGWitchHut : public CGObjectInstance class DLL_EXPORT CGWitchHut : public CGObjectInstance
{ {
public: public:
std::vector<int> allowedAbilities; std::vector<si32> allowedAbilities;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & allowedAbilities;
}
}; };
@@ -387,12 +415,24 @@ public:
ui8 r0type; ui8 r0type;
ui32 r1; //Ability ID ui32 r1; //Ability ID
ui32 r2; //Spell ID ui32 r2; //Spell ID
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & bonusType & r0type & r1 & r2;
}
}; };
class DLL_EXPORT CGGarrison : public CArmedInstance class DLL_EXPORT CGGarrison : public CArmedInstance
{ {
public: public:
bool removableUnits; ui8 removableUnits;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArmedInstance&>(*this);
h & removableUnits;
}
}; };
class DLL_EXPORT CGArtifact : public CArmedInstance class DLL_EXPORT CGArtifact : public CArmedInstance
@@ -402,31 +442,56 @@ public:
ui32 spell; //if it's spell scroll ui32 spell; //if it's spell scroll
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void initObj(); void initObj();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArmedInstance&>(*this);
h & message & spell;
}
}; };
class DLL_EXPORT CGResource : public CArmedInstance class DLL_EXPORT CGResource : public CArmedInstance
{ {
public: public:
int amount; //0 if random ui32 amount; //0 if random
std::string message; std::string message;
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void initObj(); void initObj();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArmedInstance&>(*this);
h & amount & message;
}
}; };
class DLL_EXPORT CGPickable : public CGObjectInstance //campfire, treasure chest class DLL_EXPORT CGPickable : public CGObjectInstance //campfire, treasure chest
{ {
public:
ui32 type, val1, val2; ui32 type, val1, val2;
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void initObj(); void initObj();
void chosen(int which, int heroID) const; void chosen(int which, int heroID) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & type & val1 & val2;
}
}; };
class DLL_EXPORT CGShrine : public CGObjectInstance class DLL_EXPORT CGShrine : public CGObjectInstance
{ {
public: public:
unsigned char spell; //number of spell or 255 if random ui8 spell; //number of spell or 255 if random
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & spell;
}
}; };
class DLL_EXPORT CGPandoraBox : public CArmedInstance class DLL_EXPORT CGPandoraBox : public CArmedInstance
@@ -435,22 +500,33 @@ public:
std::string message; std::string message;
//gained things: //gained things:
unsigned int gainedExp; ui32 gainedExp;
int manaDiff; si32 manaDiff; //amount of gained / lost mana
int moraleDiff; si32 moraleDiff; //morale modifier
int luckDiff; si32 luckDiff; //luck modifier
int wood, mercury, ore, sulfur, crystal, gems, gold; std::vector<si32> resources;//gained / lost resources
int attack, defence, power, knowledge; std::vector<si32> primskills;//gained / lost resources
std::vector<int> abilities; std::vector<si32> abilities; //gained abilities
std::vector<int> abilityLevels; std::vector<si32> abilityLevels; //levels of gained abilities
std::vector<int> artifacts; std::vector<si32> artifacts; //gained artifacts
std::vector<int> spells; std::vector<si32> spells; //gained spells
CCreatureSet creatures; CCreatureSet creatures; //gained creatures
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArmedInstance&>(*this);
h & message & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills
& abilities & abilityLevels & artifacts & spells & creatures;
}
}; };
class DLL_EXPORT CGQuestGuard : public CGObjectInstance, public CQuest class DLL_EXPORT CGQuestGuard : public CGObjectInstance, public CQuest
{ {
public: public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CQuest&>(*this) & static_cast<CGObjectInstance&>(*this);
}
}; };
class DLL_EXPORT CGMine : public CArmedInstance class DLL_EXPORT CGMine : public CArmedInstance
@@ -459,6 +535,10 @@ public:
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void newTurn() const; void newTurn() const;
void initObj(); void initObj();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArmedInstance&>(*this);
}
}; };
class DLL_EXPORT CGVisitableOPW : public CGObjectInstance //objects visitable OPW class DLL_EXPORT CGVisitableOPW : public CGObjectInstance //objects visitable OPW
@@ -468,6 +548,12 @@ public:
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void newTurn() const; void newTurn() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & visited;
}
}; };
class DLL_EXPORT CGTeleport : public CGObjectInstance //teleports and subterranean gates class DLL_EXPORT CGTeleport : public CGObjectInstance //teleports and subterranean gates
@@ -476,20 +562,18 @@ public:
static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void initObj(); void initObj();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
}
}; };
class DLL_EXPORT CObjectHandler class DLL_EXPORT CObjectHandler
{ {
public: public:
std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i
std::vector<int> cregens; //type 17. dwelling subid -> creature ID std::vector<int> cregens; //type 17. dwelling subid -> creature ID
void loadObjects(); void loadObjects();
std::vector<std::string> creGens; //names of creatures' generators
std::vector<std::string> advobtxt;
std::vector<std::string> xtrainfo;
std::vector<std::string> restypes;
std::vector<std::pair<std::string,std::string> > mines; //first - name; second - event description
}; };

View File

@@ -146,7 +146,7 @@ void CConnection::close()
} }
CSaveFile::CSaveFile( const std::string &fname ) CSaveFile::CSaveFile( const std::string &fname )
:sfile(new std::ofstream(fname.c_str())) :sfile(new std::ofstream(fname.c_str(),std::ios::binary))
{ {
if(!(*sfile)) if(!(*sfile))
{ {
@@ -164,4 +164,25 @@ int CSaveFile::write( const void * data, unsigned size )
{ {
sfile->write((char *)data,size); sfile->write((char *)data,size);
return size; return size;
}
CLoadFile::CLoadFile( const std::string &fname )
:sfile(new std::ifstream(fname.c_str(),std::ios::binary))
{
if(!(*sfile))
{
tlog1 << "Error: cannot open to read " << fname << std::endl;
sfile = NULL;
}
}
CLoadFile::~CLoadFile()
{
delete sfile;
}
int CLoadFile::read( const void * data, unsigned size )
{
sfile->read((char *)data,size);
return size;
} }

View File

@@ -185,7 +185,10 @@ public:
template <typename T> template <typename T>
void savePointer(const T &data) void savePointer(const T &data)
{ {
*this << *data; ui8 hlp = (data!=NULL);
*this << hlp;
if(hlp)
*this << *data;
} }
template <typename T> template <typename T>
void save(const T &data) void save(const T &data)
@@ -231,15 +234,8 @@ public:
} }
void saveSerializable(const std::string &data) void saveSerializable(const std::string &data)
{ {
if(!data.length()) *this << ui32(data.length());
{ this->This()->write(data.c_str(),data.size());
*this << ui8(0);
}
else
{
*this << ui32(data.length());
this->This()->write(data.c_str(),data.size());
}
} }
template <typename T1, typename T2> template <typename T1, typename T2>
void saveSerializable(const std::pair<T1,T2> &data) void saveSerializable(const std::pair<T1,T2> &data)
@@ -311,6 +307,14 @@ public:
template <typename T> template <typename T>
void loadPointer(T &data) void loadPointer(T &data)
{ {
ui8 hlp;
*this >> hlp;
if(!hlp)
{
data = NULL;
return;
}
tlog5<<"Allocating memory for pointer!"<<std::endl; tlog5<<"Allocating memory for pointer!"<<std::endl;
typedef typename boost::remove_pointer<T>::type npT; typedef typename boost::remove_pointer<T>::type npT;
data = new npT; data = new npT;
@@ -357,14 +361,10 @@ public:
} }
void loadSerializable(std::string &data) void loadSerializable(std::string &data)
{ {
ui8 length[4]; ui32 length;
*this >> length[0]; *this >> length;
if(!length[0]) return; data.resize(length);
*this >> length[1]; this->This()->read((void*)data.c_str(),length);
*this >> length[2];
*this >> length[3];
data.resize(*((ui32*)length));
this->This()->read((void*)data.c_str(),*((ui32*)length));
} }
}; };
@@ -384,6 +384,20 @@ public:
int write(const void * data, unsigned size); int write(const void * data, unsigned size);
}; };
class DLL_EXPORT CLoadFile
: public CISer<CLoadFile>
{
void dummyMagicFunction()
{
*this >> std::string("This function makes stuff working.");
}
public:
std::ifstream *sfile;
CLoadFile(const std::string &fname);
~CLoadFile();
int read(const void * data, unsigned size);
};
class DLL_EXPORT CConnection class DLL_EXPORT CConnection
:public CISer<CConnection>, public COSer<CConnection> :public CISer<CConnection>, public COSer<CConnection>
{ {

623
map.cpp
View File

@@ -206,37 +206,54 @@ CCreatureSet readCreatureSet(unsigned char * bufor, int &i, int number, bool ver
} }
CMapHeader::CMapHeader(unsigned char *map) CMapHeader::CMapHeader(unsigned char *map)
{ {
this->version = (Eformat)map[0]; //wersja mapy int i=0;
this->areAnyPLayers = map[4]; //seems to be invalid initFromMemory(map,i);
this->height = this->width = map[5]; // wymiary mapy }
this->twoLevel = map[9]; //czy sa lochy
int length = map[10]; //name length CMapHeader::CMapHeader()
int i=14, pom; {
while (i-14<length) //read name areAnyPLayers = difficulty = levelLimit = howManyTeams = 0;
this->name+=map[i++]; height = width = twoLevel = -1;
length = map[i] + map[i+1]*256; //description length }
i+=4;
for (pom=0;pom<length;pom++) void CMapHeader::initFromMemory( unsigned char *bufor, int &i )
this->description+=map[i++]; {
this->difficulty = map[i++]; // reading map difficulty version = (Eformat)(readNormalNr(bufor,i)); i+=4; //map version
if(version!=RoE) areAnyPLayers = readChar(bufor,i); //invalid on some maps
{ height = width = (readNormalNr(bufor,i)); i+=4; // wymiary mapy
this->levelLimit = map[i++]; // hero level limit twoLevel = readChar(bufor,i); //czy sa lochy
} int pom;
name = readString(bufor,i);
description= readString(bufor,i);
difficulty = readChar(bufor,i); // reading map difficulty
if(version != RoE)
levelLimit = readChar(bufor,i); // hero level limit
else else
{
levelLimit = 0; levelLimit = 0;
loadPlayerInfo(pom, bufor, i);
loadViCLossConditions(bufor, i);
howManyTeams=bufor[i++]; //read number of teams
if(howManyTeams>0) //read team numbers
{
for(int rr=0; rr<8; ++rr)
{
players[rr].team=bufor[i++];
}
} }
}
void CMapHeader::loadPlayerInfo( int &pom, unsigned char * bufor, int &i )
{
for (pom=0;pom<8;pom++) for (pom=0;pom<8;pom++)
{ {
this->players[pom].canHumanPlay = map[i++]; players[pom].canHumanPlay = bufor[i++];
this->players[pom].canComputerPlay = map[i++]; players[pom].canComputerPlay = bufor[i++];
if ((!(this->players[pom].canHumanPlay || this->players[pom].canComputerPlay))) if ((!(players[pom].canHumanPlay || players[pom].canComputerPlay)))
{ {
memset(&players[pom],0,sizeof(PlayerInfo));
switch(version) switch(version)
{ {
case SoD: case WoG: case SoD: case WoG:
i+=13; i+=13;
break; break;
case AB: case AB:
@@ -249,204 +266,186 @@ CMapHeader::CMapHeader(unsigned char *map)
continue; continue;
} }
this->players[pom].AITactic = map[i++]; players[pom].AITactic = bufor[i++];
if(version == SoD || version == WoG) if(version == SoD || version == WoG)
i++; players[pom].p7= bufor[i++];
else
players[pom].p7= -1;
this->players[pom].allowedFactions = 0; players[pom].allowedFactions = 0;
this->players[pom].allowedFactions += map[i++]; players[pom].allowedFactions += bufor[i++];
if(version != RoE) if(version != RoE)
this->players[pom].allowedFactions += (map[i++])*256; players[pom].allowedFactions += (bufor[i++])*256;
this->players[pom].isFactionRandom = map[i++]; players[pom].isFactionRandom = bufor[i++];
this->players[pom].hasMainTown = map[i++]; players[pom].hasMainTown = bufor[i++];
if (this->players[pom].hasMainTown) if (players[pom].hasMainTown)
{ {
if(version != RoE) if(version != RoE)
{ {
this->players[pom].generateHeroAtMainTown = map[i++]; players[pom].generateHeroAtMainTown = bufor[i++];
this->players[pom].generateHero = map[i++]; players[pom].generateHero = bufor[i++];
} }
this->players[pom].posOfMainTown.x = map[i++]; else
this->players[pom].posOfMainTown.y = map[i++]; {
this->players[pom].posOfMainTown.z = map[i++]; players[pom].generateHeroAtMainTown = false;
players[pom].generateHero = false;
}
players[pom].posOfMainTown.x = bufor[i++];
players[pom].posOfMainTown.y = bufor[i++];
players[pom].posOfMainTown.z = bufor[i++];
} }
players[pom].p8= map[i++]; players[pom].p8= bufor[i++];
players[pom].p9= map[i++]; players[pom].p9= bufor[i++];
if(players[pom].p9!=0xff) if(players[pom].p9!=0xff)
{ {
players[pom].mainHeroPortrait = map[i++]; players[pom].mainHeroPortrait = bufor[i++];
int nameLength = map[i++]; int nameLength = bufor[i++];
i+=3; i+=3;
for (int pp=0;pp<nameLength;pp++) for (int pp=0;pp<nameLength;pp++)
players[pom].mainHeroName+=map[i++]; players[pom].mainHeroName+=bufor[i++];
} }
if(version!=RoE) if(version != RoE)
{ {
i++; ////heroes placeholders //domostwa i++; ////unknown byte
int heroCount = map[i++]; int heroCount = bufor[i++];
i+=3; i+=3;
for (int pp=0;pp<heroCount;pp++) for (int pp=0;pp<heroCount;pp++)
{ {
SheroName vv; SheroName vv;
vv.heroID=map[i++]; vv.heroID=bufor[i++];
int hnl = map[i++]; int hnl = bufor[i++];
i+=3; i+=3;
for (int zz=0;zz<hnl;zz++) for (int zz=0;zz<hnl;zz++)
{ {
vv.heroName+=map[i++]; vv.heroName+=bufor[i++];
} }
this->players[pom].heroesNames.push_back(vv); players[pom].heroesNames.push_back(vv);
} }
} }
} }
this->victoryCondition = (EvictoryConditions)map[i++]; }
if (this->victoryCondition != winStandard) //specific victory conditions
void CMapHeader::loadViCLossConditions( unsigned char * bufor, int &i)
{
victoryCondition.condition = (EvictoryConditions)bufor[i++];
if (victoryCondition.condition != winStandard) //specific victory conditions
{ {
int nr; int nr;
switch (this->victoryCondition) //read victory conditions switch (victoryCondition.condition) //read victory conditions
{ {
case artifact: case artifact:
{ {
this->vicConDetails = new VicCon0(); victoryCondition.ID = bufor[i+2];
((VicCon0*)this->vicConDetails)->ArtifactID = map[i+2];
nr=(version==RoE ? 1 : 2); nr=(version==RoE ? 1 : 2);
break; break;
} }
case gatherTroop: case gatherTroop:
{ {
this->vicConDetails = new VicCon1(); int temp1 = bufor[i+2];
int temp1 = map[i+2]; int temp2 = bufor[i+3];
int temp2 = map[i+3]; victoryCondition.ID = bufor[i+2];
((VicCon1*)this->vicConDetails)->monsterID = map[i+2]; victoryCondition.count = readNormalNr(bufor, i+(version==RoE ? 3 : 4));
((VicCon1*)this->vicConDetails)->neededQuantity=readNormalNr(map, i+(version==RoE ? 3 : 4));
nr=(version==RoE ? 5 : 6); nr=(version==RoE ? 5 : 6);
break; break;
} }
case gatherResource: case gatherResource:
{ {
this->vicConDetails = new VicCon2(); victoryCondition.ID = bufor[i+2];
((VicCon2*)this->vicConDetails)->resourceID = map[i+2]; victoryCondition.count = readNormalNr(bufor, i+3);
((VicCon2*)this->vicConDetails)->neededQuantity=readNormalNr(map, i+3);
nr=5; nr=5;
break; break;
} }
case buildCity: case buildCity:
{ {
this->vicConDetails = new VicCon3(); victoryCondition.pos.x = bufor[i+2];
((VicCon3*)this->vicConDetails)->posOfCity.x = map[i+2]; victoryCondition.pos.y = bufor[i+3];
((VicCon3*)this->vicConDetails)->posOfCity.y = map[i+3]; victoryCondition.pos.z = bufor[i+4];
((VicCon3*)this->vicConDetails)->posOfCity.z = map[i+4]; victoryCondition.count = bufor[i+5];
((VicCon3*)this->vicConDetails)->councilNeededLevel = map[i+5]; victoryCondition.ID = bufor[i+6];
((VicCon3*)this->vicConDetails)->fortNeededLevel = map[i+6];
nr=5; nr=5;
break; break;
} }
case buildGrail: case buildGrail:
{ {
this->vicConDetails = new VicCon4(); if (bufor[i+4]>2)
if (map[i+4]>2) victoryCondition.pos = int3(-1,-1,-1);
((VicCon4*)this->vicConDetails)->anyLocation = true;
else else
{ {
((VicCon4*)this->vicConDetails)->whereBuildGrail.x = map[i+2]; victoryCondition.pos.x = bufor[i+2];
((VicCon4*)this->vicConDetails)->whereBuildGrail.y = map[i+3]; victoryCondition.pos.y = bufor[i+3];
((VicCon4*)this->vicConDetails)->whereBuildGrail.z = map[i+4]; victoryCondition.pos.z = bufor[i+4];
} }
nr=3; nr=3;
break; break;
} }
case beatHero: case beatHero:
{
this->vicConDetails = new VicCon5();
((VicCon5*)this->vicConDetails)->locationOfHero.x = map[i+2];
((VicCon5*)this->vicConDetails)->locationOfHero.y = map[i+3];
((VicCon5*)this->vicConDetails)->locationOfHero.z = map[i+4];
nr=3;
break;
}
case captureCity: case captureCity:
{
this->vicConDetails = new VicCon6();
((VicCon6*)this->vicConDetails)->locationOfTown.x = map[i+2];
((VicCon6*)this->vicConDetails)->locationOfTown.y = map[i+3];
((VicCon6*)this->vicConDetails)->locationOfTown.z = map[i+4];
nr=3;
break;
}
case beatMonster: case beatMonster:
{ {
this->vicConDetails = new VicCon7(); victoryCondition.pos.x = bufor[i+2];
((VicCon7*)this->vicConDetails)->locationOfMonster.x = map[i+2]; victoryCondition.pos.y = bufor[i+3];
((VicCon7*)this->vicConDetails)->locationOfMonster.y = map[i+3]; victoryCondition.pos.z = bufor[i+4];
((VicCon7*)this->vicConDetails)->locationOfMonster.z = map[i+4];
nr=3; nr=3;
break; break;
} }
case takeDwellings: case takeDwellings:
{
this->vicConDetails = new CspecificVictoryConidtions();
nr=3;
break;
}
case takeMines: case takeMines:
{ {
this->vicConDetails = new CspecificVictoryConidtions();
nr=3; nr=3;
break; break;
} }
case transportItem: case transportItem:
{ {
this->vicConDetails = new VicCona(); victoryCondition.ID = bufor[i+2];
((VicCona*)this->vicConDetails)->artifactID = map[i+2]; victoryCondition.pos.x = bufor[i+3];
((VicCona*)this->vicConDetails)->destinationPlace.x = map[i+3]; victoryCondition.pos.y = bufor[i+4];
((VicCona*)this->vicConDetails)->destinationPlace.y = map[i+4]; victoryCondition.pos.z = bufor[i+5];
((VicCona*)this->vicConDetails)->destinationPlace.z = map[i+5];
nr=4; nr=4;
break; break;
} }
} }
this->vicConDetails->allowNormalVictory = map[i++]; victoryCondition.allowNormalVictory = bufor[i++];
this->vicConDetails->appliesToAI = map[i++]; victoryCondition.appliesToAI = bufor[i++];
i+=nr; i+=nr;
} }
this->lossCondition.typeOfLossCon = (ElossCon)map[i++]; lossCondition.typeOfLossCon = (ElossCon)bufor[i++];
switch (this->lossCondition.typeOfLossCon) //read loss conditions switch (lossCondition.typeOfLossCon) //read loss conditions
{ {
case lossCastle: case lossCastle:
{ {
this->lossCondition.castlePos.x=map[i++]; lossCondition.castlePos.x=bufor[i++];
this->lossCondition.castlePos.y=map[i++]; lossCondition.castlePos.y=bufor[i++];
this->lossCondition.castlePos.z=map[i++]; lossCondition.castlePos.z=bufor[i++];
} break;
}
case lossHero: case lossHero:
{ {
this->lossCondition.heroPos.x=map[i++]; lossCondition.heroPos.x=bufor[i++];
this->lossCondition.heroPos.y=map[i++]; lossCondition.heroPos.y=bufor[i++];
this->lossCondition.heroPos.z=map[i++]; lossCondition.heroPos.z=bufor[i++];
} break;
}
case timeExpires: case timeExpires:
{ {
this->lossCondition.timeLimit = readNormalNr(map, i++,2); lossCondition.timeLimit = readNormalNr(bufor,i++,2);
i++; i++;
} break;
}
this->howManyTeams=map[i++]; //read number of teams
if(this->howManyTeams>0) //read team numbers
{
for(int rr=0; rr<8; ++rr)
{
this->players[rr].team=map[i++];
} }
} }
} }
void Mapa::initFromBytes(unsigned char * bufor) void Mapa::initFromBytes(unsigned char * bufor)
{ {
int i=0;
initFromMemory(bufor,i);
timeHandler th; timeHandler th;
th.getDif(); th.getDif();
int i=0;
readHeader(bufor, i); readHeader(bufor, i);
tlog0<<"\tReading header: "<<th.getDif()<<std::endl; tlog0<<"\tReading header: "<<th.getDif()<<std::endl;
@@ -555,6 +554,10 @@ Mapa::Mapa(std::string filename)
initFromBytes(initTable); initFromBytes(initTable);
} }
Mapa::Mapa()
{
}
CGHeroInstance * Mapa::getHero(int ID, int mode) CGHeroInstance * Mapa::getHero(int ID, int mode)
{ {
if (mode != 0) if (mode != 0)
@@ -602,64 +605,64 @@ int Mapa::loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj )
{ {
case 1: case 1:
{ {
hut->r1exp = readNormalNr(bufor,i); i+=4; hut->rVal = readNormalNr(bufor,i); i+=4;
break; break;
} }
case 2: case 2:
{ {
hut->r2mana = readNormalNr(bufor,i); i+=4; hut->rVal = readNormalNr(bufor,i); i+=4;
break; break;
} }
case 3: case 3:
{ {
hut->r3morale = bufor[i]; ++i; hut->rVal = bufor[i]; ++i;
break; break;
} }
case 4: case 4:
{ {
hut->r4luck = bufor[i]; ++i; hut->rVal = bufor[i]; ++i;
break; break;
} }
case 5: case 5:
{ {
hut->r5type = bufor[i]; ++i; hut->rID = bufor[i]; ++i;
hut->r5amount = readNormalNr(bufor,i, 3); i+=3; hut->rVal = readNormalNr(bufor,i, 3); i+=3;
i+=1; i+=1;
break; break;
} }
case 6: case 6:
{ {
hut->r6type = bufor[i]; ++i; hut->rID = bufor[i]; ++i;
hut->r6amount = bufor[i]; ++i; hut->rVal = bufor[i]; ++i;
break; break;
} }
case 7: case 7:
{ {
hut->r7ability = bufor[i]; ++i; hut->rID = bufor[i]; ++i;
hut->r7level = bufor[i]; ++i; hut->rVal = bufor[i]; ++i;
break; break;
} }
case 8: case 8:
{ {
hut->r8art = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2); hut->rID = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2);
break; break;
} }
case 9: case 9:
{ {
hut->r9spell = bufor[i]; ++i; hut->rID = bufor[i]; ++i;
break; break;
} }
case 10: case 10:
{ {
if(version>RoE) if(version>RoE)
{ {
hut->r10creature = readNormalNr(bufor,i, 2); i+=2; hut->rID = readNormalNr(bufor,i, 2); i+=2;
hut->r10amount = readNormalNr(bufor,i, 2); i+=2; hut->rVal = readNormalNr(bufor,i, 2); i+=2;
} }
else else
{ {
hut->r10creature = bufor[i]; ++i; hut->rID = bufor[i]; ++i;
hut->r10amount = readNormalNr(bufor,i, 2); i+=2; hut->rVal = readNormalNr(bufor,i, 2); i+=2;
} }
break; break;
} }
@@ -975,233 +978,6 @@ void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
nhi->movement = -1; nhi->movement = -1;
} }
void Mapa::loadPlayerInfo( int &pom, unsigned char * bufor, int &i )
{
for (pom=0;pom<8;pom++)
{
players[pom].canHumanPlay = bufor[i++];
players[pom].canComputerPlay = bufor[i++];
if ((!(players[pom].canHumanPlay || players[pom].canComputerPlay)))
{
memset(&players[pom],0,sizeof(PlayerInfo));
switch(version)
{
case SoD: case WoG:
i+=13;
break;
case AB:
i+=12;
break;
case RoE:
i+=6;
break;
}
continue;
}
players[pom].AITactic = bufor[i++];
if(version == SoD || version == WoG)
players[pom].p7= bufor[i++];
else
players[pom].p7= -1;
players[pom].allowedFactions = 0;
players[pom].allowedFactions += bufor[i++];
if(version != RoE)
players[pom].allowedFactions += (bufor[i++])*256;
players[pom].isFactionRandom = bufor[i++];
players[pom].hasMainTown = bufor[i++];
if (players[pom].hasMainTown)
{
if(version != RoE)
{
players[pom].generateHeroAtMainTown = bufor[i++];
players[pom].generateHero = bufor[i++];
}
else
{
players[pom].generateHeroAtMainTown = false;
players[pom].generateHero = false;
}
players[pom].posOfMainTown.x = bufor[i++];
players[pom].posOfMainTown.y = bufor[i++];
players[pom].posOfMainTown.z = bufor[i++];
}
players[pom].p8= bufor[i++];
players[pom].p9= bufor[i++];
if(players[pom].p9!=0xff)
{
players[pom].mainHeroPortrait = bufor[i++];
int nameLength = bufor[i++];
i+=3;
for (int pp=0;pp<nameLength;pp++)
players[pom].mainHeroName+=bufor[i++];
}
if(version != RoE)
{
i++; ////unknown byte
int heroCount = bufor[i++];
i+=3;
for (int pp=0;pp<heroCount;pp++)
{
SheroName vv;
vv.heroID=bufor[i++];
int hnl = bufor[i++];
i+=3;
for (int zz=0;zz<hnl;zz++)
{
vv.heroName+=bufor[i++];
}
players[pom].heroesNames.push_back(vv);
}
}
}
}
void Mapa::loadViCLossConditions( unsigned char * bufor, int &i)
{
victoryCondition = (EvictoryConditions)bufor[i++];
if (victoryCondition != winStandard) //specific victory conditions
{
int nr;
switch (victoryCondition) //read victory conditions
{
case artifact:
{
vicConDetails = new VicCon0();
((VicCon0*)vicConDetails)->ArtifactID = bufor[i+2];
nr=(version==RoE ? 1 : 2);
break;
}
case gatherTroop:
{
vicConDetails = new VicCon1();
int temp1 = bufor[i+2];
int temp2 = bufor[i+3];
((VicCon1*)vicConDetails)->monsterID = bufor[i+2];
((VicCon1*)vicConDetails)->neededQuantity=readNormalNr(bufor,i+(version==RoE ? 3 : 4));
nr=(version==RoE ? 5 : 6);
break;
}
case gatherResource:
{
vicConDetails = new VicCon2();
((VicCon2*)vicConDetails)->resourceID = bufor[i+2];
((VicCon2*)vicConDetails)->neededQuantity=readNormalNr(bufor,i+3);
nr=5;
break;
}
case buildCity:
{
vicConDetails = new VicCon3();
((VicCon3*)vicConDetails)->posOfCity.x = bufor[i+2];
((VicCon3*)vicConDetails)->posOfCity.y = bufor[i+3];
((VicCon3*)vicConDetails)->posOfCity.z = bufor[i+4];
((VicCon3*)vicConDetails)->councilNeededLevel = bufor[i+5];
((VicCon3*)vicConDetails)->fortNeededLevel = bufor[i+6];
nr=5;
break;
}
case buildGrail:
{
vicConDetails = new VicCon4();
if (bufor[i+4]>2)
((VicCon4*)vicConDetails)->anyLocation = true;
else
{
((VicCon4*)vicConDetails)->whereBuildGrail.x = bufor[i+2];
((VicCon4*)vicConDetails)->whereBuildGrail.y = bufor[i+3];
((VicCon4*)vicConDetails)->whereBuildGrail.z = bufor[i+4];
}
nr=3;
break;
}
case beatHero:
{
vicConDetails = new VicCon5();
((VicCon5*)vicConDetails)->locationOfHero.x = bufor[i+2];
((VicCon5*)vicConDetails)->locationOfHero.y = bufor[i+3];
((VicCon5*)vicConDetails)->locationOfHero.z = bufor[i+4];
nr=3;
break;
}
case captureCity:
{
vicConDetails = new VicCon6();
((VicCon6*)vicConDetails)->locationOfTown.x = bufor[i+2];
((VicCon6*)vicConDetails)->locationOfTown.y = bufor[i+3];
((VicCon6*)vicConDetails)->locationOfTown.z = bufor[i+4];
nr=3;
break;
}
case beatMonster:
{
vicConDetails = new VicCon7();
((VicCon7*)vicConDetails)->locationOfMonster.x = bufor[i+2];
((VicCon7*)vicConDetails)->locationOfMonster.y = bufor[i+3];
((VicCon7*)vicConDetails)->locationOfMonster.z = bufor[i+4];
nr=3;
break;
}
case takeDwellings:
{
vicConDetails = new CspecificVictoryConidtions();
nr=0;
break;
}
case takeMines:
{
vicConDetails = new CspecificVictoryConidtions();
nr=0;
break;
}
case transportItem:
{
vicConDetails = new VicCona();
((VicCona*)vicConDetails)->artifactID = bufor[i+2];
((VicCona*)vicConDetails)->destinationPlace.x = bufor[i+3];
((VicCona*)vicConDetails)->destinationPlace.y = bufor[i+4];
((VicCona*)vicConDetails)->destinationPlace.z = bufor[i+5];
nr=4;
break;
}
}
vicConDetails->allowNormalVictory = bufor[i++];
vicConDetails->appliesToAI = bufor[i++];
i+=nr;
}
lossCondition.typeOfLossCon = (ElossCon)bufor[i++];
switch (lossCondition.typeOfLossCon) //read loss conditions
{
case lossCastle:
{
lossCondition.castlePos.x=bufor[i++];
lossCondition.castlePos.y=bufor[i++];
lossCondition.castlePos.z=bufor[i++];
break;
}
case lossHero:
{
lossCondition.heroPos.x=bufor[i++];
lossCondition.heroPos.y=bufor[i++];
lossCondition.heroPos.z=bufor[i++];
break;
}
case timeExpires:
{
lossCondition.timeLimit = readNormalNr(bufor,i++,2);
i++;
break;
}
}
}
void Mapa::readRumors( unsigned char * bufor, int &i) void Mapa::readRumors( unsigned char * bufor, int &i)
{ {
int rumNr = readNormalNr(bufor,i,4);i+=4; int rumNr = readNormalNr(bufor,i,4);i+=4;
@@ -1220,36 +996,6 @@ void Mapa::readRumors( unsigned char * bufor, int &i)
void Mapa::readHeader( unsigned char * bufor, int &i) void Mapa::readHeader( unsigned char * bufor, int &i)
{ {
version = (Eformat)(readNormalNr(bufor,i)); i+=4; //map version
areAnyPLayers = readChar(bufor,i); //invalid on some maps
height = width = (readNormalNr(bufor,i)); i+=4; // wymiary mapy
twoLevel = readChar(bufor,i); //czy sa lochy
terrain = new TerrainTile**[width]; // allocate memory
for (int ii=0;ii<width;ii++)
{
terrain[ii] = new TerrainTile*[height]; // allocate memory
for(int jj=0;jj<height;jj++)
terrain[ii][jj] = new TerrainTile[twoLevel+1];
}
int pom;
name = readString(bufor,i);
description= readString(bufor,i);
difficulty = readChar(bufor,i); // reading map difficulty
if(version != RoE)
levelLimit = readChar(bufor,i); // hero level limit
else
levelLimit = 0;
loadPlayerInfo(pom, bufor, i);
loadViCLossConditions(bufor, i);
howManyTeams=bufor[i++]; //read number of teams
if(howManyTeams>0) //read team numbers
{
for(int rr=0; rr<8; ++rr)
{
players[rr].team=bufor[i++];
}
}
//reading allowed heroes (20 bytes) //reading allowed heroes (20 bytes)
int ist; int ist;
@@ -1467,6 +1213,14 @@ void Mapa::readPredefinedHeroes( unsigned char * bufor, int &i)
void Mapa::readTerrain( unsigned char * bufor, int &i) void Mapa::readTerrain( unsigned char * bufor, int &i)
{ {
terrain = new TerrainTile**[width]; // allocate memory
for (int ii=0;ii<width;ii++)
{
terrain[ii] = new TerrainTile*[height]; // allocate memory
for(int jj=0;jj<height;jj++)
terrain[ii][jj] = new TerrainTile[twoLevel+1];
}
for (int c=0; c<width; c++) // reading terrain for (int c=0; c<width; c++) // reading terrain
{ {
for (int z=0; z<height; z++) for (int z=0; z<height; z++)
@@ -1577,40 +1331,37 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
int messLong = readNormalNr(bufor,i, 4); i+=4; int messLong = readNormalNr(bufor,i, 4); i+=4;
if(messLong>0) if(messLong>0)
{ {
evnt->isMessage = true;
for(int yy=0; yy<messLong; ++yy) for(int yy=0; yy<messLong; ++yy)
{ {
evnt->message +=bufor[i+yy]; evnt->message +=bufor[i+yy];
} }
i+=messLong; i+=messLong;
} }
evnt->areGuarders = bufor[i]; ++i; if(bufor[i++])
if(evnt->areGuarders)
{ {
evnt->guarders = readCreatureSet(bufor,i,7,(version>RoE)); evnt->guarders = readCreatureSet(bufor,i,7,(version>RoE));
} }
i+=4; i+=4;
} }
else
{
evnt->isMessage = false;
evnt->areGuarders = false;
}
evnt->gainedExp = readNormalNr(bufor,i, 4); i+=4; evnt->gainedExp = readNormalNr(bufor,i, 4); i+=4;
evnt->manaDiff = readNormalNr(bufor,i, 4); i+=4; evnt->manaDiff = readNormalNr(bufor,i, 4); i+=4;
evnt->moraleDiff = readNormalNr(bufor,i, 1, true); ++i; evnt->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
evnt->luckDiff = readNormalNr(bufor,i, 1, true); ++i; evnt->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
evnt->wood = readNormalNr(bufor,i); i+=4;
evnt->mercury = readNormalNr(bufor,i); i+=4; evnt->resources.resize(RESOURCE_QUANTITY);
evnt->ore = readNormalNr(bufor,i); i+=4; for(int x=0; x<7; x++)
evnt->sulfur = readNormalNr(bufor,i); i+=4; {
evnt->crystal = readNormalNr(bufor,i); i+=4; evnt->resources[x] = readNormalNr(bufor,i);
evnt->gems = readNormalNr(bufor,i); i+=4; i+=4;
evnt->gold = readNormalNr(bufor,i); i+=4; }
evnt->attack = readNormalNr(bufor,i, 1); ++i;
evnt->defence = readNormalNr(bufor,i, 1); ++i; evnt->primskills.resize(PRIMARY_SKILLS);
evnt->power = readNormalNr(bufor,i, 1); ++i; for(int x=0; x<4; x++)
evnt->knowledge = readNormalNr(bufor,i, 1); ++i; {
evnt->primskills[x] = readNormalNr(bufor,i, 1);
i++;
}
int gabn; //number of gained abilities int gabn; //number of gained abilities
gabn = readNormalNr(bufor,i, 1); ++i; gabn = readNormalNr(bufor,i, 1); ++i;
for(int oo = 0; oo<gabn; ++oo) for(int oo = 0; oo<gabn; ++oo)
@@ -1618,18 +1369,22 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
evnt->abilities.push_back(readNormalNr(bufor,i, 1)); ++i; evnt->abilities.push_back(readNormalNr(bufor,i, 1)); ++i;
evnt->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i; evnt->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i;
} }
int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts
for(int oo = 0; oo<gart; ++oo) for(int oo = 0; oo<gart; ++oo)
{ {
evnt->artifacts.push_back(readNormalNr(bufor,i, (version == RoE ? 1 : 2))); i+=(version == RoE ? 1 : 2); evnt->artifacts.push_back(readNormalNr(bufor,i, (version == RoE ? 1 : 2))); i+=(version == RoE ? 1 : 2);
} }
int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells
for(int oo = 0; oo<gspel; ++oo) for(int oo = 0; oo<gspel; ++oo)
{ {
evnt->spells.push_back(readNormalNr(bufor,i, 1)); ++i; evnt->spells.push_back(readNormalNr(bufor,i, 1)); ++i;
} }
int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures
evnt->creatures = readCreatureSet(bufor,i,gcre,(version>RoE)); evnt->creatures = readCreatureSet(bufor,i,gcre,(version>RoE));
i+=8; i+=8;
evnt->availableFor = readNormalNr(bufor,i, 1); ++i; evnt->availableFor = readNormalNr(bufor,i, 1); ++i;
evnt->computerActivate = readNormalNr(bufor,i, 1); ++i; evnt->computerActivate = readNormalNr(bufor,i, 1); ++i;
@@ -1886,18 +1641,22 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
box->gainedExp = readNormalNr(bufor,i, 4); i+=4; box->gainedExp = readNormalNr(bufor,i, 4); i+=4;
box->manaDiff = readNormalNr(bufor,i, 4); i+=4; box->manaDiff = readNormalNr(bufor,i, 4); i+=4;
box->moraleDiff = readNormalNr(bufor,i, 1, true); ++i; box->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
box->luckDiff = readNormalNr(bufor,i, 1, true); ++i; box->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
box->wood = readNormalNr(bufor,i); i+=4;
box->mercury = readNormalNr(bufor,i); i+=4; box->resources.resize(RESOURCE_QUANTITY);
box->ore = readNormalNr(bufor,i); i+=4; for(int x=0; x<7; x++)
box->sulfur = readNormalNr(bufor,i); i+=4; {
box->crystal = readNormalNr(bufor,i); i+=4; box->resources[x] = readNormalNr(bufor,i);
box->gems = readNormalNr(bufor,i); i+=4; i+=4;
box->gold = readNormalNr(bufor,i); i+=4; }
box->attack = readNormalNr(bufor,i, 1); ++i;
box->defence = readNormalNr(bufor,i, 1); ++i; box->primskills.resize(PRIMARY_SKILLS);
box->power = readNormalNr(bufor,i, 1); ++i; for(int x=0; x<4; x++)
box->knowledge = readNormalNr(bufor,i, 1); ++i; {
box->primskills[x] = readNormalNr(bufor,i, 1);
i++;
}
int gabn; //number of gained abilities int gabn; //number of gained abilities
gabn = readNormalNr(bufor,i, 1); ++i; gabn = readNormalNr(bufor,i, 1); ++i;
for(int oo = 0; oo<gabn; ++oo) for(int oo = 0; oo<gabn; ++oo)

289
map.h
View File

@@ -84,6 +84,12 @@ struct DLL_EXPORT TerrainTile
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & tertype & terview & nuine & rivDir & malle &roadDir & siodmyTajemniczyBajt; h & tertype & terview & nuine & rivDir & malle &roadDir & siodmyTajemniczyBajt;
if(!h.saving)
{
visitable = blocked = false;
//these flags (and obj vectors) will be restored in map serialization
}
} }
}; };
struct DLL_EXPORT SheroName //name of starting hero struct DLL_EXPORT SheroName //name of starting hero
@@ -132,53 +138,22 @@ struct DLL_EXPORT LossCondition
h & typeOfLossCon & castlePos & heroPos & timeLimit; h & typeOfLossCon & castlePos & heroPos & timeLimit;
} }
}; };
struct DLL_EXPORT CspecificVictoryConidtions struct DLL_EXPORT CVictoryCondition
{ {
bool allowNormalVictory; EvictoryConditions condition; //ID of condition
bool appliesToAI; ui8 allowNormalVictory, appliesToAI;
};
struct DLL_EXPORT VicCon0 : public CspecificVictoryConidtions //acquire artifact int3 pos; //pos of city to upgrade (3); pos of town to build grail, {-1,-1,-1} if not relevant (4); hero pos (5); town pos(6); monster pos (7); destination pos(8)
{ ui32 ID; //artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8)
int ArtifactID; ui32 count; //needed count for creatures (1) / resource (2); upgraded town hall level (3);
};
struct DLL_EXPORT VicCon1 : public CspecificVictoryConidtions //accumulate creatures
{ template <typename Handler> void serialize(Handler &h, const int version)
int monsterID; {
int neededQuantity; h & condition & allowNormalVictory & appliesToAI & pos & ID & count;
}; }
struct DLL_EXPORT VicCon2 : public CspecificVictoryConidtions // accumulate resources
{
int resourceID;
int neededQuantity;
};
struct DLL_EXPORT VicCon3 : public CspecificVictoryConidtions // upgrade specific town
{
int3 posOfCity;
int councilNeededLevel; //0 - town; 1 - city; 2 - capitol
int fortNeededLevel;// 0 - fort; 1 - citadel; 2 - castle
};
struct DLL_EXPORT VicCon4 : public CspecificVictoryConidtions // build grail structure
{
bool anyLocation;
int3 whereBuildGrail;
};
struct DLL_EXPORT VicCon5 : public CspecificVictoryConidtions // defeat a specific hero
{
int3 locationOfHero;
};
struct DLL_EXPORT VicCon6 : public CspecificVictoryConidtions // capture a specific town
{
int3 locationOfTown;
};
struct DLL_EXPORT VicCon7 : public CspecificVictoryConidtions // defeat a specific monster
{
int3 locationOfMonster;
};
struct DLL_EXPORT VicCona : public CspecificVictoryConidtions //transport specific artifact
{
int artifactID;
int3 destinationPlace;
}; };
struct DLL_EXPORT Rumor struct DLL_EXPORT Rumor
{ {
std::string name, text; std::string name, text;
@@ -222,21 +197,24 @@ class DLL_EXPORT CMapHeader
{ {
public: public:
Eformat version; // version of map Eformat Eformat version; // version of map Eformat
bool areAnyPLayers; // if there are any playable players on map ui8 areAnyPLayers; // if there are any playable players on map
int height, width; si32 height, width, twoLevel; //sizes
bool twoLevel; // if map has underground level
std::string name; //name of map std::string name; //name of map
std::string description; //and description std::string description; //and description
int difficulty; // 0 easy - 4 impossible ui8 difficulty; // 0 easy - 4 impossible
int levelLimit; ui8 levelLimit;
LossCondition lossCondition; LossCondition lossCondition;
EvictoryConditions victoryCondition; //victory conditions CVictoryCondition victoryCondition; //victory conditions
CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
PlayerInfo players[8]; // info about players PlayerInfo players[8]; // info about players
std::vector<int> teams; // teams[i] = team of player no i std::vector<ui8> teams; // teams[i] = team of player no i
int howManyTeams; ui8 howManyTeams;
void initFromMemory(unsigned char *bufor, int &i);
void loadViCLossConditions( unsigned char * bufor, int &i);
void loadPlayerInfo( int &pom, unsigned char * bufor, int &i);
CMapHeader(unsigned char *map); //an argument is a reference to string described a map (unpacked) CMapHeader(unsigned char *map); //an argument is a reference to string described a map (unpacked)
CMapHeader();
}; };
class DLL_EXPORT CMapInfo : public CMapHeader class DLL_EXPORT CMapInfo : public CMapHeader
{ {
public: public:
@@ -287,7 +265,7 @@ public:
return (a.width<b.width); return (a.width<b.width);
break; break;
case _viccon: case _viccon:
return (a.victoryCondition<b.victoryCondition); return (a.victoryCondition.condition < b.victoryCondition.condition);
break; break;
case _name: case _name:
return (a.name<b.name); return (a.name<b.name);
@@ -299,29 +277,14 @@ public:
}; };
mapSorter(ESortBy es):sortBy(es){}; mapSorter(ESortBy es):sortBy(es){};
}; };
struct DLL_EXPORT Mapa struct DLL_EXPORT Mapa : public CMapHeader
{ {
Eformat version; // version of map Eformat
ui32 checksum; ui32 checksum;
ui32 twoLevel; // if map has underground level
ui8 difficulty; // 0 easy - 4 impossible
ui8 levelLimit;
ui8 areAnyPLayers; // if there are any playable players on map
std::string name; //name of map
std::string description; //and description
ui32 height, width;
TerrainTile*** terrain; TerrainTile*** terrain;
std::vector<Rumor> rumors; std::vector<Rumor> rumors;
std::vector<DisposedHero> disposedHeroes; std::vector<DisposedHero> disposedHeroes;
std::vector<CGHeroInstance*> predefinedHeroes; std::vector<CGHeroInstance*> predefinedHeroes;
std::vector<CGDefInfo *> defy; // list of .def files with definitions from .h3m (may be custom) std::vector<CGDefInfo *> defy; // list of .def files with definitions from .h3m (may be custom)
std::set<CGDefInfo *> defs; // other defInfos - for randomized objects, objects added or modified by scripts
PlayerInfo players[8]; // info about players
std::vector<ui8> teams; // teams[i] = team of player no i
LossCondition lossCondition;
EvictoryConditions victoryCondition; //victory conditions
CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
ui8 howManyTeams;
std::vector<ui8> allowedSpell; //allowedSpell[spell_ID] - if the spell is allowed std::vector<ui8> allowedSpell; //allowedSpell[spell_ID] - if the spell is allowed
std::vector<ui8> allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact is allowed std::vector<ui8> allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact is allowed
std::vector<ui8> allowedAbilities; //allowedAbilities[ability_ID] - if the ability is allowed std::vector<ui8> allowedAbilities; //allowedAbilities[ability_ID] - if the ability is allowed
@@ -345,8 +308,6 @@ struct DLL_EXPORT Mapa
void readPredefinedHeroes( unsigned char * bufor, int &i); void readPredefinedHeroes( unsigned char * bufor, int &i);
void readHeader( unsigned char * bufor, int &i); void readHeader( unsigned char * bufor, int &i);
void readRumors( unsigned char * bufor, int &i); void readRumors( unsigned char * bufor, int &i);
void loadViCLossConditions( unsigned char * bufor, int &i);
void loadPlayerInfo( int &pom, unsigned char * bufor, int &i);
void loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i); void loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
void loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i); void loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj); int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj);
@@ -355,13 +316,20 @@ struct DLL_EXPORT Mapa
void addBlockVisTiles(CGObjectInstance * obj); void addBlockVisTiles(CGObjectInstance * obj);
void removeBlockVisTiles(CGObjectInstance * obj); void removeBlockVisTiles(CGObjectInstance * obj);
Mapa(std::string filename); //creates map structure from .h3m file Mapa(std::string filename); //creates map structure from .h3m file
Mapa();
CGHeroInstance * getHero(int ID, int mode=0); CGHeroInstance * getHero(int ID, int mode=0);
bool isInTheMap(int3 pos); bool isInTheMap(int3 pos);
template <typename Handler> void serialize(Handler &h, const int version) template <typename TObject, typename Handler> void serializeObj(Handler &h, const int version, TObject ** obj)
{ {
h & version & name & description & width & height & twoLevel & difficulty & levelLimit & rumors & defy & defs h & *obj;
& players & teams & lossCondition & victoryCondition & howManyTeams & allowedSpell & allowedAbilities }
& allowedArtifact &allowedHeroes & events & grailPos; template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & version & name & description & width & height & twoLevel & difficulty & levelLimit & areAnyPLayers & rumors;
h & players & teams & lossCondition & victoryCondition & howManyTeams & allowedSpell
& allowedAbilities & allowedArtifact & allowedHeroes & events & grailPos;
//TODO: viccondetails //TODO: viccondetails
if(h.saving) if(h.saving)
{ {
@@ -386,7 +354,172 @@ struct DLL_EXPORT Mapa
for (int k = 0; k <= twoLevel ; k++) for (int k = 0; k <= twoLevel ; k++)
h & terrain[i][j][k]; h & terrain[i][j][k];
} }
//TODO: recreate blockvis maps
//definfos
std::vector<CGDefInfo*> defs;
if(h.saving) //create vector with all defs used on map
{
for(int i=0; i<objects.size(); i++)
objects[i]->defInfo->serial = -1; //set serial to serial -1 - indicates that def is not present in defs vector
for(int i=0; i<objects.size(); i++)
{
CGDefInfo *cur = objects[i]->defInfo;
if(cur->serial < 0)
{
cur->serial = defs.size();
defs.push_back(cur);
}
}
}
h & ((h.saving) ? defs : defy);
//objects
if(h.saving)
{
ui32 hlp = objects.size();
h & hlp;
}
else
{
ui32 hlp;
h & hlp;
objects.resize(hlp);
}
h & CGTeleport::objs;
for(int i=0; i<objects.size(); i++)
{
CGObjectInstance *&obj = objects[i];
ui32 hlp;
si32 shlp;
h & (h.saving ? (hlp=obj->ID) : hlp);
switch(hlp)
{
#define SERIALIZE(TYPE) ( serializeObj<TYPE>( h,version,(TYPE**) (&obj) ) )
case 34: case 70: case 62:
SERIALIZE(CGHeroInstance);
break;
case 98: case 77:
SERIALIZE(CGTownInstance);
break;
case 26: //for event objects
SERIALIZE(CGEvent);
break;
case 51: //Mercenary Camp
case 23: //Marletto Tower
case 61: // Star Axis
case 32: // Garden of Revelation
case 100: //Learning Stone
case 102: //Tree of Knowledge
SERIALIZE(CGVisitableOPH);
break;
case 55: //mystical garden
case 112://windmill
case 109://water wheel
SERIALIZE(CGVisitableOPW);
break;
case 43: //teleport
case 44: //teleport
case 45: //teleport
case 103://subterranean gate
SERIALIZE(CGTeleport);
break;
case 12: //campfire
case 101: //treasure chest
SERIALIZE(CGPickable);
break;
case 54: //Monster
case 71: case 72: case 73: case 74: case 75: // Random Monster 1 - 4
case 162: case 163: case 164:
SERIALIZE(CGCreature);
break;
case 59: case 91: //ocean bottle and sign
SERIALIZE(CGSignBottle);
break;
case 83: //seer's hut
SERIALIZE(CGSeerHut);
break;
case 113: //witch hut
SERIALIZE(CGWitchHut);
break;
case 81: //scholar
SERIALIZE(CGScholar);
break;
case 33: case 219: //garrison
SERIALIZE(CGGarrison);
break;
case 5: //artifact
case 65: case 66: case 67: case 68: case 69: //random artifact
case 93: //spell scroll
SERIALIZE(CGArtifact);
break;
case 76: case 79: //random resource; resource
SERIALIZE(CGResource);
break;
case 53:
SERIALIZE(CGMine);
break;
case 88: case 89: case 90: //spell shrine
SERIALIZE(CGShrine);
break;
case 6:
SERIALIZE(CGPandoraBox);
break;
case 217:
case 216:
case 218:
//TODO cregen
SERIALIZE(CGObjectInstance);
break;
case 215:
SERIALIZE(CGQuestGuard);
break;
default:
SERIALIZE(CGObjectInstance);
}
#undef SERIALIZE
//definfo
h & (h.saving ? (shlp=obj->defInfo->serial) : shlp); //read / write pos of definfo in defs vector
if(!h.saving)
obj->defInfo = defy[shlp];
}
if(!h.saving)
{
for(int i=0; i<objects.size(); i++)
{
if(objects[i]->ID == 34)
heroes.push_back(static_cast<CGHeroInstance*>(objects[i]));
else if(objects[i]->ID == 98)
towns.push_back(static_cast<CGTownInstance*>(objects[i]));
addBlockVisTiles(objects[i]); //recreate blockvis map
}
for(int i=0; i<heroes.size(); i++) //if hero is visiting/garrisoned in town set appropriate pointers
{
int3 vistile = heroes[i]->pos; vistile.x++;
for(int j=0; j<towns.size(); j++)
{
if(vistile == towns[j]->pos) //hero stands on the town entrance
{
if(heroes[i]->inTownGarrison)
towns[j]->garrisonHero = heroes[i];
else
towns[j]->visitingHero = heroes[i];
heroes[i]->visitedTown = towns[j];
}
}
}
}
} }
}; };
#endif // __MAP_H__ #endif // __MAP_H__

View File

@@ -445,14 +445,15 @@ void CMapHandler::init()
if(i<ccc) if(i<ccc)
{ {
n = CGI->state->villages[i]; n = CGI->state->villages[i];
map->defs.insert(CGI->state->forts[i]); map->defy.push_back(CGI->state->forts[i]);
} }
else else
n = CGI->state->capitols[i%ccc]; n = CGI->state->capitols[i%ccc];
ifs >> n->name; ifs >> n->name;
if(!n) if(!n)
tlog1 << "*HUGE* Warning - missing town def for " << i << std::endl; tlog1 << "*HUGE* Warning - missing town def for " << i << std::endl;
map->defs.insert(n); else
map->defy.push_back(n);
} }
tlog0<<"\tLoading town def info: "<<th.getDif()<<std::endl; tlog0<<"\tLoading town def info: "<<th.getDif()<<std::endl;
@@ -464,8 +465,14 @@ void CMapHandler::init()
} }
} }
//for(int i=0; i<map->defy.size(); i++)
//{
// map->defy[i]->serial = i;
// processDef(map->defy[i]);
//}
std::for_each(map->defy.begin(),map->defy.end(),processDef); //load h3m defs std::for_each(map->defy.begin(),map->defy.end(),processDef); //load h3m defs
std::for_each(map->defs.begin(),map->defs.end(),processDef); //and non-h3m defs //std::for_each(map->defs.begin(),map->defs.end(),processDef); //and non-h3m defs
tlog0<<"\tUnpacking and handling defs: "<<th.getDif()<<std::endl; tlog0<<"\tUnpacking and handling defs: "<<th.getDif()<<std::endl;
for(int i=0;i<PLAYER_LIMIT;i++) for(int i=0;i<PLAYER_LIMIT;i++)

View File

@@ -409,10 +409,21 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
case 98: case 98:
{ {
std::string fname; std::string fname;
Mapa * mapa;
c >> fname; c >> fname;
CSaveFile save(fname);
save << VLC->arth << VLC->buildh << VLC->creh << VLC->dobjinfo << VLC->heroh {
<< VLC->spellh << VLC->townh << this; CSaveFile save(fname);
save << gs->map;
}
{
CLoadFile load(fname);
load >> mapa;
}
//save << VLC->arth << VLC->buildh << VLC->creh << VLC->dobjinfo << VLC->heroh
// << VLC->spellh << VLC->townh << this;
//save << this; //save << this;
break; break;
} }