1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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)
{
ret += VLC->objh->mines[ser].first;
ret += VLC->generaltexth->mines[ser].first;
continue;
}
else if(type == 10)
{
ret += VLC->objh->mines[ser].second;
ret += VLC->generaltexth->mines[ser].second;
continue;
}
else
@ -71,22 +71,22 @@ std::string DLL_EXPORT toString(MetaString &ms)
vec = &VLC->generaltexth->allTexts;
break;
case 2:
vec = &VLC->objh->xtrainfo;
vec = &VLC->generaltexth->xtrainfo;
break;
case 3:
vec = &VLC->objh->names;
vec = &VLC->generaltexth->names;
break;
case 4:
vec = &VLC->objh->restypes;
vec = &VLC->generaltexth->restypes;
break;
case 6:
vec = &VLC->generaltexth->arraytxt;
break;
case 8:
vec = &VLC->objh->creGens;
vec = &VLC->generaltexth->creGens;
break;
case 11:
vec = &VLC->objh->advobtxt;
vec = &VLC->generaltexth->advobtxt;
break;
case 12:
vec = &VLC->generaltexth->artifEvents;
@ -1084,7 +1084,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
//we have to replace normal random object
cur->ID = ran.first;
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)
{
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->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;
@ -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
if(map->allowedHeroes[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)
{
@ -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++)
map->objects[i]->initObj();
}

View File

@ -178,6 +178,11 @@ private:
std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
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
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
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)
{
loadTownDInfos();
}
//TODO: hero pool
}
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()))
ourMaps[(i-at)+from].name = "Unnamed";
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;
else temp=ourMaps[(i-at)+from].victoryCondition;
else
temp=ourMaps[(i-at)+from].victoryCondition.condition;
blitAt(Dvic->ourImages[temp].bitmap,285,2,scenin);
if (ourMaps[(i-at)+from].lossCondition.typeOfLossCon == lossStandard)
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(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[391],585,406,GEOR13,zwykly);
int temp = ourMaps[selected].victoryCondition+1;
int temp = ourMaps[selected].victoryCondition.condition+1;
if (temp>20) temp=0;
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);
@ -1312,7 +1317,7 @@ void MapSel::printSelectedInfo()
break;
}
blitAt(Dsizes->ourImages[temp].bitmap,714,28);
temp=ourMaps[selected].victoryCondition;
temp = ourMaps[selected].victoryCondition.condition;
if (temp>12) temp=11;
blitAt(Dvic->ourImages[temp].bitmap,420,308); //v
temp=ourMaps[selected].lossCondition.typeOfLossCon;

View File

@ -120,7 +120,7 @@ void CClient::process(int what)
{
SetResource 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;
gs->apply(&sr);
playerint[sr.player]->receivedResource(sr.resid,sr.val);

View File

@ -7,7 +7,7 @@
#include <sstream>
#include <fstream>
extern CLodHandler * bitmaph;
unsigned int readNr(std::string &in, unsigned int &it)
unsigned int readNr(std::string &in, int &it)
{
int last=it;
for(;last<in.size();last++)
@ -24,7 +24,7 @@ unsigned int readNr(std::string &in, unsigned int &it)
ss >> last;
return last;
}
CBuilding * readBg(std::string &buf, unsigned int& it)
CBuilding * readBg(std::string &buf, int& it)
{
CBuilding * nb = new CBuilding();
nb->resources.resize(RESOURCE_QUANTITY);
@ -37,7 +37,8 @@ CBuilding * readBg(std::string &buf, unsigned int& it)
void CBuildingHandler::loadBuildings()
{
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

View File

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

View File

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

View File

@ -8,7 +8,7 @@
#include <fstream>
#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 last = in.find_first_of(end,it);
@ -174,7 +174,7 @@ void CGeneralTextHandler::loadTexts()
loadToIt(hTxts[iii].biography,buf,i,3);
}
unsigned it;
int it;
buf = bitmaph->getTextFile("BLDGNEUT.TXT");
andame = buf.size(), it=0;
@ -250,9 +250,9 @@ void CGeneralTextHandler::loadTexts()
hcommands.push_back(tmp);
}
std::istringstream ins, names;
std::istringstream ins, namess;
ins.str(bitmaph->getTextFile("TOWNTYPE.TXT"));
names.str(bitmaph->getTextFile("TOWNNAME.TXT"));
namess.str(bitmaph->getTextFile("TOWNNAME.TXT"));
int si=0;
char bufname[75];
while (!ins.eof())
@ -263,9 +263,85 @@ void CGeneralTextHandler::loadTexts()
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));
}
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 <vector>
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
{
public:
@ -37,6 +37,15 @@ public:
std::vector<std::pair<std::string,std::string> > zelp;
std::string lossCondtions[4];
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 getDescr(std::string text);

View File

@ -44,75 +44,6 @@ void IObjectInterface::initObj()
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";
cregens.resize(110); //TODO: hardcoded value - change
for(size_t i=0; i < cregens.size(); ++i)
@ -128,15 +59,6 @@ void CObjectHandler::loadObjects()
}
ifs.close();
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";
}
int CGObjectInstance::getOwner() const
@ -994,7 +916,7 @@ const std::string & CGVisitableOPH::getHoverText() const
default:
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());
if(h)
{
@ -1110,7 +1032,7 @@ void CGMine::initObj()
void CGResource::initObj()
{
blockVisit = true;
hoverName = VLC->objh->restypes[subID];
hoverName = VLC->generaltexth->restypes[subID];
if(!amount)
{
@ -1146,7 +1068,7 @@ void CGResource::onHeroVisit( const CGHeroInstance * h ) const
sii.player = h->tempOwner;
sii.c = Component(2,subID,amount,0);
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->removeObject(id);
}

View File

@ -119,7 +119,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
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)
{
h & static_cast<CGObjectInstance&>(*this);
h & army;
}
};
@ -176,10 +177,17 @@ public:
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
& 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)
{
h & static_cast<CArmedInstance&>(*this);
h & name & builded & destroyed & identifier & alignment & forbiddenBuildings & builtBuildings
& 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 initObj();
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
{
public:
bool areGuarders; //true if there are
CCreatureSet guarders;
bool isMessage; //true if there is a message
std::string message;
unsigned int gainedExp;
int manaDiff; //amount of gained / lost mana
int moraleDiff; //morale modifier
int luckDiff; //luck modifier
int wood, mercury, ore, sulfur, crystal, gems, gold; //gained / lost resources
unsigned int attack; //added attack points
unsigned int defence; //added defence points
unsigned int power; //added power points
unsigned int knowledge; //added knowledge points
std::vector<int> abilities; //gained abilities
std::vector<int> abilityLevels; //levels of gained abilities
std::vector<int> artifacts; //gained artifacts
std::vector<int> spells; //gained spells
ui32 gainedExp;
si32 manaDiff; //amount of gained / lost mana
si32 moraleDiff; //morale modifier
si32 luckDiff; //luck modifier
std::vector<si32> resources;//gained / lost resources
std::vector<si32> primskills;//gained / lost resources
std::vector<si32> abilities; //gained abilities
std::vector<si32> abilityLevels; //levels of gained abilities
std::vector<si32> artifacts; //gained artifacts
std::vector<si32> spells; //gained spells
CCreatureSet creatures; //gained creatures
unsigned char availableFor; //players whom this event is available for
bool computerActivate; //true if computre player can activate this event
bool humanActivate; //true if human player can activate this event
ui8 availableFor; //players whom this event is available for
ui8 computerActivate; //true if computre 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
@ -332,6 +357,12 @@ public:
void onHeroVisit(const CGHeroInstance * h) const;
void endBattle(BattleResult *result) const;
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'
public:
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
{
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
//for reward 1
int r1exp;
//for reward 2
int r2mana;
//for reward 3
int r3morale;
//for reward 4
int r4luck;
//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;
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
si32 rID;
si32 rVal;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this) & static_cast<CQuest&>(*this);
h & rewardType & rID & rVal;
}
};
class DLL_EXPORT CGWitchHut : public CGObjectInstance
{
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;
ui32 r1; //Ability 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
{
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
@ -402,31 +442,56 @@ public:
ui32 spell; //if it's spell scroll
void onHeroVisit(const CGHeroInstance * h) const;
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
{
public:
int amount; //0 if random
ui32 amount; //0 if random
std::string message;
void onHeroVisit(const CGHeroInstance * h) const;
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
{
public:
ui32 type, val1, val2;
void onHeroVisit(const CGHeroInstance * h) const;
void initObj();
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
{
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
@ -435,22 +500,33 @@ public:
std::string message;
//gained things:
unsigned int gainedExp;
int manaDiff;
int moraleDiff;
int luckDiff;
int wood, mercury, ore, sulfur, crystal, gems, gold;
int attack, defence, power, knowledge;
std::vector<int> abilities;
std::vector<int> abilityLevels;
std::vector<int> artifacts;
std::vector<int> spells;
CCreatureSet creatures;
ui32 gainedExp;
si32 manaDiff; //amount of gained / lost mana
si32 moraleDiff; //morale modifier
si32 luckDiff; //luck modifier
std::vector<si32> resources;//gained / lost resources
std::vector<si32> primskills;//gained / lost resources
std::vector<si32> abilities; //gained abilities
std::vector<si32> abilityLevels; //levels of gained abilities
std::vector<si32> artifacts; //gained artifacts
std::vector<si32> spells; //gained spells
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
{
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
@ -459,6 +535,10 @@ public:
void onHeroVisit(const CGHeroInstance * h) const;
void newTurn() const;
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
@ -468,6 +548,12 @@ public:
void onHeroVisit(const CGHeroInstance * h) 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
@ -476,20 +562,18 @@ public:
static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids
void onHeroVisit(const CGHeroInstance * h) const;
void initObj();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
}
};
class DLL_EXPORT CObjectHandler
{
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
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 )
:sfile(new std::ofstream(fname.c_str()))
:sfile(new std::ofstream(fname.c_str(),std::ios::binary))
{
if(!(*sfile))
{
@ -164,4 +164,25 @@ int CSaveFile::write( const void * data, unsigned size )
{
sfile->write((char *)data,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>
void savePointer(const T &data)
{
*this << *data;
ui8 hlp = (data!=NULL);
*this << hlp;
if(hlp)
*this << *data;
}
template <typename T>
void save(const T &data)
@ -231,15 +234,8 @@ public:
}
void saveSerializable(const std::string &data)
{
if(!data.length())
{
*this << ui8(0);
}
else
{
*this << ui32(data.length());
this->This()->write(data.c_str(),data.size());
}
*this << ui32(data.length());
this->This()->write(data.c_str(),data.size());
}
template <typename T1, typename T2>
void saveSerializable(const std::pair<T1,T2> &data)
@ -311,6 +307,14 @@ public:
template <typename T>
void loadPointer(T &data)
{
ui8 hlp;
*this >> hlp;
if(!hlp)
{
data = NULL;
return;
}
tlog5<<"Allocating memory for pointer!"<<std::endl;
typedef typename boost::remove_pointer<T>::type npT;
data = new npT;
@ -357,14 +361,10 @@ public:
}
void loadSerializable(std::string &data)
{
ui8 length[4];
*this >> length[0];
if(!length[0]) return;
*this >> length[1];
*this >> length[2];
*this >> length[3];
data.resize(*((ui32*)length));
this->This()->read((void*)data.c_str(),*((ui32*)length));
ui32 length;
*this >> length;
data.resize(length);
this->This()->read((void*)data.c_str(),length);
}
};
@ -384,6 +384,20 @@ public:
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
: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)
{
this->version = (Eformat)map[0]; //wersja mapy
this->areAnyPLayers = map[4]; //seems to be invalid
this->height = this->width = map[5]; // wymiary mapy
this->twoLevel = map[9]; //czy sa lochy
int i=0;
initFromMemory(map,i);
}
int length = map[10]; //name length
int i=14, pom;
while (i-14<length) //read name
this->name+=map[i++];
length = map[i] + map[i+1]*256; //description length
i+=4;
for (pom=0;pom<length;pom++)
this->description+=map[i++];
this->difficulty = map[i++]; // reading map difficulty
if(version!=RoE)
{
this->levelLimit = map[i++]; // hero level limit
}
CMapHeader::CMapHeader()
{
areAnyPLayers = difficulty = levelLimit = howManyTeams = 0;
height = width = twoLevel = -1;
}
void CMapHeader::initFromMemory( 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
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++];
}
}
}
void CMapHeader::loadPlayerInfo( int &pom, unsigned char * bufor, int &i )
{
for (pom=0;pom<8;pom++)
{
this->players[pom].canHumanPlay = map[i++];
this->players[pom].canComputerPlay = map[i++];
if ((!(this->players[pom].canHumanPlay || this->players[pom].canComputerPlay)))
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:
case SoD: case WoG:
i+=13;
break;
case AB:
@ -249,204 +266,186 @@ CMapHeader::CMapHeader(unsigned char *map)
continue;
}
this->players[pom].AITactic = map[i++];
players[pom].AITactic = bufor[i++];
if(version == SoD || version == WoG)
i++;
players[pom].p7= bufor[i++];
else
players[pom].p7= -1;
this->players[pom].allowedFactions = 0;
this->players[pom].allowedFactions += map[i++];
players[pom].allowedFactions = 0;
players[pom].allowedFactions += bufor[i++];
if(version != RoE)
this->players[pom].allowedFactions += (map[i++])*256;
players[pom].allowedFactions += (bufor[i++])*256;
this->players[pom].isFactionRandom = map[i++];
this->players[pom].hasMainTown = map[i++];
if (this->players[pom].hasMainTown)
players[pom].isFactionRandom = bufor[i++];
players[pom].hasMainTown = bufor[i++];
if (players[pom].hasMainTown)
{
if(version != RoE)
{
this->players[pom].generateHeroAtMainTown = map[i++];
this->players[pom].generateHero = map[i++];
players[pom].generateHeroAtMainTown = bufor[i++];
players[pom].generateHero = bufor[i++];
}
this->players[pom].posOfMainTown.x = map[i++];
this->players[pom].posOfMainTown.y = map[i++];
this->players[pom].posOfMainTown.z = map[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= map[i++];
players[pom].p9= map[i++];
players[pom].p8= bufor[i++];
players[pom].p9= bufor[i++];
if(players[pom].p9!=0xff)
{
players[pom].mainHeroPortrait = map[i++];
int nameLength = map[i++];
i+=3;
players[pom].mainHeroPortrait = bufor[i++];
int nameLength = bufor[i++];
i+=3;
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
int heroCount = map[i++];
i++; ////unknown byte
int heroCount = bufor[i++];
i+=3;
for (int pp=0;pp<heroCount;pp++)
{
SheroName vv;
vv.heroID=map[i++];
int hnl = map[i++];
vv.heroID=bufor[i++];
int hnl = bufor[i++];
i+=3;
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;
switch (this->victoryCondition) //read victory conditions
switch (victoryCondition.condition) //read victory conditions
{
case artifact:
{
this->vicConDetails = new VicCon0();
((VicCon0*)this->vicConDetails)->ArtifactID = map[i+2];
victoryCondition.ID = bufor[i+2];
nr=(version==RoE ? 1 : 2);
break;
}
case gatherTroop:
{
this->vicConDetails = new VicCon1();
int temp1 = map[i+2];
int temp2 = map[i+3];
((VicCon1*)this->vicConDetails)->monsterID = map[i+2];
((VicCon1*)this->vicConDetails)->neededQuantity=readNormalNr(map, i+(version==RoE ? 3 : 4));
int temp1 = bufor[i+2];
int temp2 = bufor[i+3];
victoryCondition.ID = bufor[i+2];
victoryCondition.count = readNormalNr(bufor, i+(version==RoE ? 3 : 4));
nr=(version==RoE ? 5 : 6);
break;
}
case gatherResource:
{
this->vicConDetails = new VicCon2();
((VicCon2*)this->vicConDetails)->resourceID = map[i+2];
((VicCon2*)this->vicConDetails)->neededQuantity=readNormalNr(map, i+3);
victoryCondition.ID = bufor[i+2];
victoryCondition.count = readNormalNr(bufor, i+3);
nr=5;
break;
}
case buildCity:
{
this->vicConDetails = new VicCon3();
((VicCon3*)this->vicConDetails)->posOfCity.x = map[i+2];
((VicCon3*)this->vicConDetails)->posOfCity.y = map[i+3];
((VicCon3*)this->vicConDetails)->posOfCity.z = map[i+4];
((VicCon3*)this->vicConDetails)->councilNeededLevel = map[i+5];
((VicCon3*)this->vicConDetails)->fortNeededLevel = map[i+6];
victoryCondition.pos.x = bufor[i+2];
victoryCondition.pos.y = bufor[i+3];
victoryCondition.pos.z = bufor[i+4];
victoryCondition.count = bufor[i+5];
victoryCondition.ID = bufor[i+6];
nr=5;
break;
}
case buildGrail:
{
this->vicConDetails = new VicCon4();
if (map[i+4]>2)
((VicCon4*)this->vicConDetails)->anyLocation = true;
if (bufor[i+4]>2)
victoryCondition.pos = int3(-1,-1,-1);
else
{
((VicCon4*)this->vicConDetails)->whereBuildGrail.x = map[i+2];
((VicCon4*)this->vicConDetails)->whereBuildGrail.y = map[i+3];
((VicCon4*)this->vicConDetails)->whereBuildGrail.z = map[i+4];
victoryCondition.pos.x = bufor[i+2];
victoryCondition.pos.y = bufor[i+3];
victoryCondition.pos.z = bufor[i+4];
}
nr=3;
break;
}
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:
{
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:
{
this->vicConDetails = new VicCon7();
((VicCon7*)this->vicConDetails)->locationOfMonster.x = map[i+2];
((VicCon7*)this->vicConDetails)->locationOfMonster.y = map[i+3];
((VicCon7*)this->vicConDetails)->locationOfMonster.z = map[i+4];
victoryCondition.pos.x = bufor[i+2];
victoryCondition.pos.y = bufor[i+3];
victoryCondition.pos.z = bufor[i+4];
nr=3;
break;
}
case takeDwellings:
{
this->vicConDetails = new CspecificVictoryConidtions();
nr=3;
break;
}
case takeMines:
{
this->vicConDetails = new CspecificVictoryConidtions();
nr=3;
break;
}
case transportItem:
{
this->vicConDetails = new VicCona();
((VicCona*)this->vicConDetails)->artifactID = map[i+2];
((VicCona*)this->vicConDetails)->destinationPlace.x = map[i+3];
((VicCona*)this->vicConDetails)->destinationPlace.y = map[i+4];
((VicCona*)this->vicConDetails)->destinationPlace.z = map[i+5];
victoryCondition.ID = bufor[i+2];
victoryCondition.pos.x = bufor[i+3];
victoryCondition.pos.y = bufor[i+4];
victoryCondition.pos.z = bufor[i+5];
nr=4;
break;
}
}
this->vicConDetails->allowNormalVictory = map[i++];
this->vicConDetails->appliesToAI = map[i++];
victoryCondition.allowNormalVictory = bufor[i++];
victoryCondition.appliesToAI = bufor[i++];
i+=nr;
}
this->lossCondition.typeOfLossCon = (ElossCon)map[i++];
switch (this->lossCondition.typeOfLossCon) //read loss conditions
lossCondition.typeOfLossCon = (ElossCon)bufor[i++];
switch (lossCondition.typeOfLossCon) //read loss conditions
{
case lossCastle:
{
this->lossCondition.castlePos.x=map[i++];
this->lossCondition.castlePos.y=map[i++];
this->lossCondition.castlePos.z=map[i++];
}
{
lossCondition.castlePos.x=bufor[i++];
lossCondition.castlePos.y=bufor[i++];
lossCondition.castlePos.z=bufor[i++];
break;
}
case lossHero:
{
this->lossCondition.heroPos.x=map[i++];
this->lossCondition.heroPos.y=map[i++];
this->lossCondition.heroPos.z=map[i++];
}
{
lossCondition.heroPos.x=bufor[i++];
lossCondition.heroPos.y=bufor[i++];
lossCondition.heroPos.z=bufor[i++];
break;
}
case timeExpires:
{
this->lossCondition.timeLimit = readNormalNr(map, i++,2);
lossCondition.timeLimit = readNormalNr(bufor,i++,2);
i++;
}
}
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++];
break;
}
}
}
void Mapa::initFromBytes(unsigned char * bufor)
{
int i=0;
initFromMemory(bufor,i);
timeHandler th;
th.getDif();
int i=0;
readHeader(bufor, i);
tlog0<<"\tReading header: "<<th.getDif()<<std::endl;
@ -555,6 +554,10 @@ Mapa::Mapa(std::string filename)
initFromBytes(initTable);
}
Mapa::Mapa()
{
}
CGHeroInstance * Mapa::getHero(int ID, int mode)
{
if (mode != 0)
@ -602,64 +605,64 @@ int Mapa::loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj )
{
case 1:
{
hut->r1exp = readNormalNr(bufor,i); i+=4;
hut->rVal = readNormalNr(bufor,i); i+=4;
break;
}
case 2:
{
hut->r2mana = readNormalNr(bufor,i); i+=4;
hut->rVal = readNormalNr(bufor,i); i+=4;
break;
}
case 3:
{
hut->r3morale = bufor[i]; ++i;
hut->rVal = bufor[i]; ++i;
break;
}
case 4:
{
hut->r4luck = bufor[i]; ++i;
hut->rVal = bufor[i]; ++i;
break;
}
case 5:
{
hut->r5type = bufor[i]; ++i;
hut->r5amount = readNormalNr(bufor,i, 3); i+=3;
hut->rID = bufor[i]; ++i;
hut->rVal = readNormalNr(bufor,i, 3); i+=3;
i+=1;
break;
}
case 6:
{
hut->r6type = bufor[i]; ++i;
hut->r6amount = bufor[i]; ++i;
hut->rID = bufor[i]; ++i;
hut->rVal = bufor[i]; ++i;
break;
}
case 7:
{
hut->r7ability = bufor[i]; ++i;
hut->r7level = bufor[i]; ++i;
hut->rID = bufor[i]; ++i;
hut->rVal = bufor[i]; ++i;
break;
}
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;
}
case 9:
{
hut->r9spell = bufor[i]; ++i;
hut->rID = bufor[i]; ++i;
break;
}
case 10:
{
if(version>RoE)
{
hut->r10creature = readNormalNr(bufor,i, 2); i+=2;
hut->r10amount = readNormalNr(bufor,i, 2); i+=2;
hut->rID = readNormalNr(bufor,i, 2); i+=2;
hut->rVal = readNormalNr(bufor,i, 2); i+=2;
}
else
{
hut->r10creature = bufor[i]; ++i;
hut->r10amount = readNormalNr(bufor,i, 2); i+=2;
hut->rID = bufor[i]; ++i;
hut->rVal = readNormalNr(bufor,i, 2); i+=2;
}
break;
}
@ -975,233 +978,6 @@ void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
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)
{
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)
{
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)
int ist;
@ -1467,6 +1213,14 @@ void Mapa::readPredefinedHeroes( 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 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;
if(messLong>0)
{
evnt->isMessage = true;
for(int yy=0; yy<messLong; ++yy)
{
evnt->message +=bufor[i+yy];
}
i+=messLong;
}
evnt->areGuarders = bufor[i]; ++i;
if(evnt->areGuarders)
if(bufor[i++])
{
evnt->guarders = readCreatureSet(bufor,i,7,(version>RoE));
}
i+=4;
}
else
{
evnt->isMessage = false;
evnt->areGuarders = false;
}
evnt->gainedExp = readNormalNr(bufor,i, 4); i+=4;
evnt->manaDiff = readNormalNr(bufor,i, 4); i+=4;
evnt->moraleDiff = 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->ore = readNormalNr(bufor,i); i+=4;
evnt->sulfur = readNormalNr(bufor,i); i+=4;
evnt->crystal = readNormalNr(bufor,i); i+=4;
evnt->gems = readNormalNr(bufor,i); i+=4;
evnt->gold = readNormalNr(bufor,i); i+=4;
evnt->attack = readNormalNr(bufor,i, 1); ++i;
evnt->defence = readNormalNr(bufor,i, 1); ++i;
evnt->power = readNormalNr(bufor,i, 1); ++i;
evnt->knowledge = readNormalNr(bufor,i, 1); ++i;
evnt->resources.resize(RESOURCE_QUANTITY);
for(int x=0; x<7; x++)
{
evnt->resources[x] = readNormalNr(bufor,i);
i+=4;
}
evnt->primskills.resize(PRIMARY_SKILLS);
for(int x=0; x<4; x++)
{
evnt->primskills[x] = readNormalNr(bufor,i, 1);
i++;
}
int gabn; //number of gained abilities
gabn = readNormalNr(bufor,i, 1); ++i;
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->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i;
}
int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts
for(int oo = 0; oo<gart; ++oo)
{
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
for(int oo = 0; oo<gspel; ++oo)
{
evnt->spells.push_back(readNormalNr(bufor,i, 1)); ++i;
}
int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures
evnt->creatures = readCreatureSet(bufor,i,gcre,(version>RoE));
i+=8;
evnt->availableFor = 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->manaDiff = readNormalNr(bufor,i, 4); i+=4;
box->moraleDiff = 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->ore = readNormalNr(bufor,i); i+=4;
box->sulfur = readNormalNr(bufor,i); i+=4;
box->crystal = readNormalNr(bufor,i); i+=4;
box->gems = readNormalNr(bufor,i); i+=4;
box->gold = readNormalNr(bufor,i); i+=4;
box->attack = readNormalNr(bufor,i, 1); ++i;
box->defence = readNormalNr(bufor,i, 1); ++i;
box->power = readNormalNr(bufor,i, 1); ++i;
box->knowledge = readNormalNr(bufor,i, 1); ++i;
box->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
box->resources.resize(RESOURCE_QUANTITY);
for(int x=0; x<7; x++)
{
box->resources[x] = readNormalNr(bufor,i);
i+=4;
}
box->primskills.resize(PRIMARY_SKILLS);
for(int x=0; x<4; x++)
{
box->primskills[x] = readNormalNr(bufor,i, 1);
i++;
}
int gabn; //number of gained abilities
gabn = readNormalNr(bufor,i, 1); ++i;
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)
{
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
@ -132,53 +138,22 @@ struct DLL_EXPORT LossCondition
h & typeOfLossCon & castlePos & heroPos & timeLimit;
}
};
struct DLL_EXPORT CspecificVictoryConidtions
struct DLL_EXPORT CVictoryCondition
{
bool allowNormalVictory;
bool appliesToAI;
};
struct DLL_EXPORT VicCon0 : public CspecificVictoryConidtions //acquire artifact
{
int ArtifactID;
};
struct DLL_EXPORT VicCon1 : public CspecificVictoryConidtions //accumulate creatures
{
int monsterID;
int neededQuantity;
};
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;
EvictoryConditions condition; //ID of condition
ui8 allowNormalVictory, appliesToAI;
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)
ui32 count; //needed count for creatures (1) / resource (2); upgraded town hall level (3);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & condition & allowNormalVictory & appliesToAI & pos & ID & count;
}
};
struct DLL_EXPORT Rumor
{
std::string name, text;
@ -222,21 +197,24 @@ class DLL_EXPORT CMapHeader
{
public:
Eformat version; // version of map Eformat
bool areAnyPLayers; // if there are any playable players on map
int height, width;
bool twoLevel; // if map has underground level
ui8 areAnyPLayers; // if there are any playable players on map
si32 height, width, twoLevel; //sizes
std::string name; //name of map
std::string description; //and description
int difficulty; // 0 easy - 4 impossible
int levelLimit;
ui8 difficulty; // 0 easy - 4 impossible
ui8 levelLimit;
LossCondition lossCondition;
EvictoryConditions victoryCondition; //victory conditions
CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
CVictoryCondition victoryCondition; //victory conditions
PlayerInfo players[8]; // info about players
std::vector<int> teams; // teams[i] = team of player no i
int howManyTeams;
std::vector<ui8> teams; // teams[i] = team of player no i
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();
};
class DLL_EXPORT CMapInfo : public CMapHeader
{
public:
@ -287,7 +265,7 @@ public:
return (a.width<b.width);
break;
case _viccon:
return (a.victoryCondition<b.victoryCondition);
return (a.victoryCondition.condition < b.victoryCondition.condition);
break;
case _name:
return (a.name<b.name);
@ -299,29 +277,14 @@ public:
};
mapSorter(ESortBy es):sortBy(es){};
};
struct DLL_EXPORT Mapa
struct DLL_EXPORT Mapa : public CMapHeader
{
Eformat version; // version of map Eformat
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;
std::vector<Rumor> rumors;
std::vector<DisposedHero> disposedHeroes;
std::vector<CGHeroInstance*> predefinedHeroes;
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> allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact 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 readHeader( 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 loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj);
@ -355,13 +316,20 @@ struct DLL_EXPORT Mapa
void addBlockVisTiles(CGObjectInstance * obj);
void removeBlockVisTiles(CGObjectInstance * obj);
Mapa(std::string filename); //creates map structure from .h3m file
Mapa();
CGHeroInstance * getHero(int ID, int mode=0);
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
& players & teams & lossCondition & victoryCondition & howManyTeams & allowedSpell & allowedAbilities
& allowedArtifact &allowedHeroes & events & grailPos;
h & *obj;
}
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
if(h.saving)
{
@ -386,7 +354,172 @@ struct DLL_EXPORT Mapa
for (int k = 0; k <= twoLevel ; 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__

View File

@ -445,14 +445,15 @@ void CMapHandler::init()
if(i<ccc)
{
n = CGI->state->villages[i];
map->defs.insert(CGI->state->forts[i]);
map->defy.push_back(CGI->state->forts[i]);
}
else
n = CGI->state->capitols[i%ccc];
ifs >> n->name;
if(!n)
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;
@ -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->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;
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:
{
std::string fname;
Mapa * mapa;
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;
break;
}