/*************************************************************************** datastoring.cpp - description ------------------- begin : dim feb 22 16:56:00 CET 2003 copyright : (C) 2002 by Romain Vinot email : vinot@aist.enst.fr ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef _WIN32 #pragma warning (disable : 4786) #endif #ifdef _WIN32 #include "zlib.h" #else #include #endif #define SAVEGAME_VERSION 1.05 #include #include #include #include #include "datastoring.h" #include "gamemanager.h" #include "rand.h" #include "board.h" #include "level.h" #include "guiboard.h" #include "guicommandline.h" DataStoring::DataStoring() { QString fn = homeDir + DIR_DELIMITER + "sessions.cfg"; QString strdoc; gzFile f = gzopen(fn,"rb"); if (!f) { // Write an empty list on file. savePbemGameList(); } else { char car; while (gzread(f,&car,1)>0) strdoc+=car; gzclose(f); QDomDocument doc( "PbemGameList" ); if ( doc.setContent( strdoc ) ) { // List is not empty. QDomElement current = doc.documentElement().firstChild().toElement(); while (!current.isNull()) { int id = current.attribute("id").toInt(); int nbturn = current.attribute("nbturn").toInt(); Turn tu = string2turn(current.attribute("turn")); pbems[id] = pair(nbturn,tu); current = current.nextSibling().toElement(); } } } } DataStoring::~DataStoring() {} QString DataStoring::getPref(QString att) { map::iterator it=prefs.find(att); if (it==prefs.end()) return ""; else return it->second; } void DataStoring::addPref(QString att, QString val) { prefs[att] = val; savePrefsOnFile(); } void DataStoring::savePrefs(void) { checkCurrentPrefs(); savePrefsOnFile(); } void DataStoring::savePrefsOnFile(void) { QDomDocument doc("Preferences"); QDomProcessingInstruction proc = doc.createProcessingInstruction("xml", "version = '1.0'"); doc.appendChild(proc); QDomElement root = doc.createElement("Preferences"); doc.appendChild(root); for (map::iterator it=prefs.begin(); it!=prefs.end(); it++){ QDomElement pref = doc.createElement("pref"); pref.setAttribute("attribute",it->first); pref.setAttribute("value",it->second); root.appendChild(pref); } QFile fi(homeDir + DIR_DELIMITER + "prefs.xml"); if (fi.open(IO_WriteOnly)) { QTextStream ts(&fi); ts << doc.toString(); fi.close(); } } int DataStoring::getNewPbemId(void) { if (pbems.size()==0) return 1; return pbems.rbegin()->first+1; } void DataStoring::addPbem(int pbemid, int nbturn, Turn tu) { if (pbems.find(pbemid)!=pbems.end()) { cout << "This id has already been chosen. I can't use it as a new pbem."; man->guicmd->printPopupMessage("An error has occured during loading of pbem game."); exit(0); } pbems[pbemid] = pair(nbturn,tu); savePbemGameList(); } void DataStoring::updatePbem(int pbemid, int nbturn, Turn tu) { if (pbems.find(pbemid)==pbems.end()) { cout << "Error : This file does not match any pbem you are playing.\n"; pbems[pbemid] = pair(nbturn,tu); } else { pbems[pbemid].first=nbturn; pbems[pbemid].second=tu; } savePbemGameList(); } void DataStoring::savePbemGameList(void) { QDomDocument doc("PbemGameList"); QDomProcessingInstruction proc = doc.createProcessingInstruction("xml", "version = '1.0'"); doc.appendChild(proc); QDomElement root = doc.createElement("PbemGameList"); doc.appendChild(root); for (map >::iterator it=pbems.begin(); it!=pbems.end(); it++){ QDomElement pref = doc.createElement("pbem"); pref.setAttribute("id",it->first); pref.setAttribute("nbturn",it->second.first); pref.setAttribute("turn",turn2string(it->second.second)); root.appendChild(pref); } // Write XML doc on compressed file. QString filename = homeDir + DIR_DELIMITER + "sessions.cfg"; gzFile f = gzopen(filename,"wb8"); QByteArray a; QTextStream ts(a, IO_WriteOnly); ts << doc.toString(); char *toread = a.data(); gzwrite(f,toread,a.size()); gzclose(f); } pair* DataStoring::getPbemFromList(int pId) { map >::iterator it=pbems.find(pId); if (it==pbems.end()) return 0; else return &(it->second); } void DataStoring::Save(QDomDocument &doc) { // Create the QDomDocument. QDomProcessingInstruction proc = doc.createProcessingInstruction("xml", "version = '1.0'"); doc.appendChild(proc); QDomElement root = doc.createElement("savegame"); root.setAttribute("version",SAVEGAME_VERSION); root.setAttribute("gametype",gameType2string(man->type)); doc.appendChild(root); // Save the board. QDomElement xmlboard = doc.createElement("board"); xmlboard.setAttribute("xmax",board->Xmax); xmlboard.setAttribute("ymax",board->Ymax); SaveBoard(doc,xmlboard); root.appendChild(xmlboard); // Save gamemanager and level object. QDomElement xmlman = doc.createElement("gamemanager"); SaveGameManager(doc,xmlman); root.appendChild(xmlman); QDomElement xmllev = doc.createElement("level"); SaveLevel(doc,xmllev); root.appendChild(xmllev); } void DataStoring::SaveGameState(void) { savedoc = new QDomDocument("savegame"); QDomProcessingInstruction proc = savedoc->createProcessingInstruction("xml", "version = '1.0'"); savedoc->appendChild(proc); QDomElement root = savedoc->createElement("savegame"); root.setAttribute("version",SAVEGAME_VERSION); root.setAttribute("gametype",gameType2string(man->type)); savedoc->appendChild(root); // Save the board. QDomElement xmlboard = savedoc->createElement("board"); xmlboard.setAttribute("xmax",board->Xmax); xmlboard.setAttribute("ymax",board->Ymax); SaveBoard(*savedoc,xmlboard); root.appendChild(xmlboard); // Save gamemanager and level object. QDomElement xmlman = savedoc->createElement("gamemanager"); SaveGameManager(*savedoc,xmlman); root.appendChild(xmlman); QDomElement xmllev = savedoc->createElement("level"); SaveLevel(*savedoc,xmllev); root.appendChild(xmllev); } QDomDocument* DataStoring::SaveWithRecord(void) { QDomElement root = savedoc->documentElement(); QDomElement xmlman = root.namedItem("gamemanager").toElement(); QDomElement xmlreplay = savedoc->createElement("replaylist"); for(list::iterator i=man->replays.begin(); i!=man->replays.end();i++) { QDomElement rep = savedoc->createElement("replay"); rep.setAttribute("replay",*i); xmlreplay.appendChild(rep); } xmlman.appendChild(xmlreplay); xmlman.setAttribute("random_seed",QString::number(Rand::seedvalue)); return savedoc; } void DataStoring::SaveGameManager(QDomDocument &doc, QDomElement &xmlman) { xmlman.setAttribute("gametype",gameType2string(man->type)); xmlman.setAttribute("heuristurn",(man->heuris)?"yes":"no"); xmlman.setAttribute("turn",turn2string(man->turn)); xmlman.setAttribute("nbturns",man->nbTurns); xmlman.setAttribute("maxcreaid",man->maxCreaId); xmlman.setAttribute("cmdpts",man->cmdPts); xmlman.setAttribute("pbemid_marine",man->pbemidMarine); xmlman.setAttribute("pbemid_genestealer",man->pbemidGenestealer); xmlman.setAttribute("email",man->email); xmlman.setAttribute("random_seed", Rand::seedvalue); if (man->type==PBEM) xmlman.setAttribute("cheat",man->cheatProtection); if (man->type==PBEM && man->cheatProtection==2 && man->hasCheated) xmlman.setAttribute("hascheated","yes"); QDomElement cardlist = doc.createElement("cardlist"); xmlman.appendChild(cardlist); for(vector::iterator i=man->currBlipCard;i!=man->blipCards.end();i++) { QDomElement card = doc.createElement("card"); card.setAttribute("nbgen",*i); cardlist.appendChild(card); } QDomElement waitingentries = doc.createElement("waitingentrylist"); xmlman.appendChild(waitingentries); for (set::iterator it=man->currentWaitingEntries.begin(); it!=man->currentWaitingEntries.end(); it++) { QDomElement entry = doc.createElement("waitingentry"); entry.setAttribute("position",*it); waitingentries.appendChild(entry); } } void DataStoring::SaveBoard(QDomDocument &doc, QDomElement &liste) { map > cases=board->cases; for (map >::iterator it_case=cases.begin(); it_case!=cases.end(); it_case++) { if (it_case->second.size()==0) { // This is an empty square. QDomElement obj = doc.createElement("emptysquare"); obj.setAttribute("position",it_case->first); liste.appendChild(obj); } for (set::iterator it_obj=it_case->second.begin(); it_obj!=it_case->second.end(); it_obj++) { switch ((*it_obj)->Type()) { case DOOR: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case BULKHEAD: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case EXTENSIBLE: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case ENTRYZONE: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case EXIT: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case FLAME: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case CAT: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case BLIP: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case GENESTEALER: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case BOLTERMARINE: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case SERGEANT: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; case FLAMER: SaveObject(doc,liste,dynamic_cast(*it_obj)); break; default: break; } } } // Put the dead tiles (only for QT version) SaveDeadTiles(doc,liste); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, Door *obj) { QDomElement xmldoor = doc.createElement("door"); xmldoor.setAttribute("position",obj->position); xmldoor.setAttribute("vertical",(obj->isVertical)?"yes":"no"); xmldoor.setAttribute("state",(obj->state==OPEN)?"open":"close"); liste.appendChild(xmldoor); } void DataStoring::SaveObject(QDomDocument &doc,QDomElement &lst,Bulkhead *obj) { QDomElement xmlbulk = doc.createElement("bulkhead"); xmlbulk.setAttribute("position",obj->position); xmlbulk.setAttribute("vertical",(obj->isVertical)?"yes":"no"); xmlbulk.setAttribute("state",(obj->state==OPEN)?"open":"close"); xmlbulk.setAttribute("can_open",(obj->stateCanBeOpened)?"yes":"no"); xmlbulk.setAttribute("can_close",(obj->stateCanBeClosed)?"yes":"no"); lst.appendChild(xmlbulk); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, ExtensibleObject *obj) { QDomElement xmlext = doc.createElement("extensible"); xmlext.setAttribute("position",obj->position); xmlext.setAttribute("desc",obj->desc); xmlext.setAttribute("graphic",obj->graphic); xmlext.setAttribute("empty",(obj->stateIsEmpty)?"yes":"no"); xmlext.setAttribute("attackable",(obj->stateIsAttackable)?"yes":"no"); xmlext.setAttribute("shootable",obj->stateIsShootable); xmlext.setAttribute("fireable",(obj->stateIsFireable)?"yes":"no"); xmlext.setAttribute("takeable",obj->stateCanBeTaken); xmlext.setAttribute("removeable",obj->stateDropable); xmlext.setAttribute("transferable",obj->stateTransferable); xmlext.setAttribute("shootwith",(obj->stateShootWith)?"yes":"no"); xmlext.setAttribute("usedoorwith",(obj->stateUseDoorWith)?"yes":"no"); xmlext.setAttribute("istaken",(obj->isTaken)?"yes":"no"); liste.appendChild(xmlext); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, EntryZone *entry) { QDomElement xmlez = doc.createElement("entryzone"); xmlez.setAttribute("position",entry->position); xmlez.setAttribute("direction",dir2string(entry->graphicalDir)); xmlez.setAttribute("maxblip",entry->maxblip); liste.appendChild(xmlez); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, Exit *exit) { QDomElement xmlexit = doc.createElement("exit"); xmlexit.setAttribute("position",exit->position); xmlexit.setAttribute("direction",dir2string(exit->graphicalDir)); xmlexit.setAttribute("turn",turn2string(exit->passingTurn)); for(map >::iterator it=exit->out.begin(); it!=exit->out.end(); it++) for (list::iterator ite=it->second.begin(); ite!=it->second.end(); ite++) { QDomElement out = doc.createElement("exitedunit"); out.attribute("type",type2string(it->first)); out.setAttribute("id",*ite); xmlexit.appendChild(out); } liste.appendChild(xmlexit); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, Flame *fla) { QDomElement xmlfla = doc.createElement("flame"); xmlfla.setAttribute("position",fla->position); xmlfla.setAttribute("nbflames",fla->nbFlames); xmlfla.setAttribute("transparent",(fla->isTransparent)?"yes":"no"); liste.appendChild(xmlfla); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, ModuleCAT *cat) { QDomElement xmlcat = doc.createElement("cat"); xmlcat.setAttribute("position",cat->position); xmlcat.setAttribute("id",cat->id); xmlcat.setAttribute("initturn",cat->initTurn); xmlcat.setAttribute("selected",(cat->selected)?"yes":"no"); xmlcat.setAttribute("donesomething",(cat->hasDoneSomething)?"yes":"no"); xmlcat.setAttribute("actionpts",cat->actionPts); xmlcat.setAttribute("taken","no"); xmlcat.setAttribute("istaken",(cat->isTaken)?"yes":"no"); liste.appendChild(xmlcat); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, Blip *bl) { QDomElement xmlblip = doc.createElement("blip"); xmlblip.setAttribute("position",bl->position); xmlblip.setAttribute("id",bl->id); xmlblip.setAttribute("initturn",bl->initTurn); xmlblip.setAttribute("selected",(bl->selected)?"yes":"no"); xmlblip.setAttribute("donesomething",(bl->hasDoneSomething)?"yes":"no"); xmlblip.setAttribute("actionpts",bl->actionPts); xmlblip.setAttribute("taken",(bl->taken)?"yes":"no"); xmlblip.setAttribute("nbgen",bl->nbGen); liste.appendChild(xmlblip); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, Genestealer *gen) { QDomElement xmlgen = doc.createElement("genestealer"); xmlgen.setAttribute("position",gen->position); xmlgen.setAttribute("id",gen->id); xmlgen.setAttribute("initturn",gen->initTurn); xmlgen.setAttribute("selected",(gen->selected)?"yes":"no"); xmlgen.setAttribute("donesomething",(gen->hasDoneSomething)?"yes":"no"); xmlgen.setAttribute("actionpts",gen->actionPts); xmlgen.setAttribute("taken",(gen->taken)?"yes":"no"); xmlgen.setAttribute("orientation",dir2string(gen->orientation)); xmlgen.setAttribute("history",history2string(gen->history)); liste.appendChild(xmlgen); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, BolterMarine *bolt) { QDomElement xmlbolt = doc.createElement("bolter"); xmlbolt.setAttribute("position",bolt->position); xmlbolt.setAttribute("id",bolt->id); xmlbolt.setAttribute("initturn",bolt->initTurn); xmlbolt.setAttribute("selected",(bolt->selected)?"yes":"no"); xmlbolt.setAttribute("donesomething",(bolt->hasDoneSomething)?"yes":"no"); xmlbolt.setAttribute("actionpts",bolt->actionPts); xmlbolt.setAttribute("taken",(bolt->taken)?"yes":"no"); xmlbolt.setAttribute("orientation",dir2string(bolt->orientation)); xmlbolt.setAttribute("history",history2string(bolt->history)); xmlbolt.setAttribute("previoustarget",bolt->previousTargetCase); xmlbolt.setAttribute("jammed",(bolt->jammed)?"yes":"no"); liste.appendChild(xmlbolt); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, Sergeant *serg) { QDomElement xmlserg = doc.createElement("sergeant"); xmlserg.setAttribute("position",serg->position); xmlserg.setAttribute("id",serg->id); xmlserg.setAttribute("initturn",serg->initTurn); xmlserg.setAttribute("selected",(serg->selected)?"yes":"no"); xmlserg.setAttribute("donesomething",(serg->hasDoneSomething)?"yes":"no"); xmlserg.setAttribute("actionpts",serg->actionPts); xmlserg.setAttribute("taken",(serg->taken)?"yes":"no"); xmlserg.setAttribute("orientation",dir2string(serg->orientation)); xmlserg.setAttribute("history",history2string(serg->history)); xmlserg.setAttribute("previoustarget",serg->previousTargetCase); xmlserg.setAttribute("jammed",(serg->jammed)?"yes":"no"); liste.appendChild(xmlserg); } void DataStoring::SaveObject(QDomDocument &doc, QDomElement &liste, FlamerMarine *flam) { QDomElement xmlflam = doc.createElement("flamer"); xmlflam.setAttribute("position",flam->position); xmlflam.setAttribute("id",flam->id); xmlflam.setAttribute("initturn",flam->initTurn); xmlflam.setAttribute("selected",(flam->selected)?"yes":"no"); xmlflam.setAttribute("donesomething",(flam->hasDoneSomething)?"yes":"no"); xmlflam.setAttribute("actionpts",flam->actionPts); xmlflam.setAttribute("taken",(flam->taken)?"yes":"no"); xmlflam.setAttribute("orientation",dir2string(flam->orientation)); xmlflam.setAttribute("history",history2string(flam->history)); xmlflam.setAttribute("previoustarget",flam->previousTargetCase); xmlflam.setAttribute("ammunition",flam->ammunition); xmlflam.setAttribute("charger",flam->charger); for(list::iterator it=flam->currentFiring.begin(); it!=flam->currentFiring.end(); it++) { QDomElement fl = doc.createElement("currentfiring"); fl.setAttribute("position",(*it)->position); xmlflam.appendChild(fl); } liste.appendChild(xmlflam); } void DataStoring::SaveLevel(QDomDocument &doc, QDomElement &xlev) { Level *lvl = man->level; QDomElement global = doc.createElement("global"); global = lvl->global.cloneNode(true).toElement(); xlev.appendChild(global); CheckXMLLevel(doc, global); QDomElement marine_cfg = doc.createElement("marine_cfg"); marine_cfg = lvl->marine_cfg.cloneNode(true).toElement(); xlev.appendChild(marine_cfg); CheckXMLLevel(doc,marine_cfg); QDomElement gen_cfg = doc.createElement("genestealer_cfg"); gen_cfg = lvl->genestealer_cfg.cloneNode(true).toElement(); xlev.appendChild(gen_cfg); CheckXMLLevel(doc,gen_cfg); QDomElement kills = doc.createElement("killlist"); for (int i=0; i< NB_OBJECT_TYPE; i++) { if (man->level->num_killed[i]!=0) { QDomElement kill = doc.createElement("kill"); kill.setAttribute("unit",i); kill.setAttribute("nb",man->level->num_killed[i]); kills.appendChild(kill); } } xlev.appendChild(kills); } void DataStoring::CheckXMLLevel(QDomDocument &doc, QDomElement &elem) { if (elem.tagName()=="ref") { QDomElement father = elem.parentNode().toElement(); if (father.tagName()=="zone") { Level *level = man->level; QString name = elem.attribute("name"); LvlZone* zone = dynamic_cast(&**level->getRef(name)); father.removeChild(elem); set* cases = zone->getCases(); for (set::iterator it=cases->begin(); it!=cases->end(); it++) { QDomElement c = doc.createElement("case"); c.setAttribute("x",*it%board->Xmax); c.setAttribute("y",*it/board->Xmax); father.appendChild(c); } } else if (father.tagName()=="zone_set") { Level *level = man->level; QString name = elem.attribute("name"); LvlZoneList* zones = dynamic_cast(&**level->getRef(name)); father.removeChild(elem); for (list::iterator it=zones->zone_list.begin(); it!=zones->zone_list.end(); it++) { QDomElement z = doc.createElement("zone"); for (set::iterator ite=(*it)->cases.begin(); ite!=(*it)->cases.end(); ite++){ QDomElement c = doc.createElement("case"); c.setAttribute("x",*ite%board->Xmax); c.setAttribute("y",*ite/board->Xmax); z.appendChild(c); } father.appendChild(z); } } } else { QDomNode n = elem.firstChild(); while( !n.isNull() ) { QDomElement current = n.toElement(); if( !current.isNull() ) { // the node was really an element. CheckXMLLevel(doc,current); } n = n.nextSibling(); } } } bool DataStoring::LoadFromFilename(const char *filename) { QString strdoc; gzFile f = gzopen(filename,"rb"); if (!f) { cout << "Error when opening file " << filename << endl; return false; } char car; while (gzread(f,&car,1)>0) strdoc+=car; gzclose(f); return LoadFromContent(strdoc); } bool DataStoring::LoadFromContent(const QString &strdoc) { guic = man->guic; guicmd = man->guicmd; QDomDocument doc; if (!doc.setContent(strdoc)) { cout << "Error when loading file." << endl; return false; } // File has been successfully loaded. We can delete the previous game // to load this one. if (man->inGame) { board->removeAll(); man->removeAll(); } man->inGame = true; // First, locate the primary nodes QDomElement root = doc.documentElement(); float version = root.attribute("version","+Inf").toFloat(); if (version > SAVEGAME_VERSION) { QString str; QTextStream res(&str,IO_WriteOnly); res << "Savegame format version is " << version << "\nI can't read version superior to " << SAVEGAME_VERSION << "\nPlease update your program.\n"; guicmd->printPopupMessage(str); return false; } QDomElement current = doc.documentElement().firstChild().toElement(); while (!current.isNull()) { QString elem = current.tagName(); if (elem=="gamemanager") LoadGameManager(current,version); else if (elem=="level") LoadLevel(current,version); else if (elem=="board") LoadBoard(current,version); current = current.nextSibling().toElement(); } // Put back the pointer to taken object. for (vector::iterator it=hasTaken.begin(); it != hasTaken.end(); it++) { int caseId = (*it)->getPosition(); set *objs = board->getObject(caseId); for (set::iterator ite=objs->begin(); ite!=objs->end(); ite++) { if (((*ite)->Type()==EXTENSIBLE && dynamic_cast(*ite)->isTaken) || ((*ite)->Type()==CAT && dynamic_cast(*ite)->isTaken)) (*it)->taken = *ite; } } // Put the flame pointer to flamers. for (vector > >::iterator i1=flames.begin(); i1!=flames.end(); i1++) { FlamerMarine *unit = i1->first; for (vector::iterator i2=i1->second.begin(); i2!=i1->second.end(); i2++) { set *objs = board->getObject(*i2); for (set::iterator i3=objs->begin(); i3!=objs->end(); i3++) { if ((*i3)->Type()==FLAME) unit->currentFiring.push_back(dynamic_cast(*i3)); } } } // Set the correct turn phase for every unit. for (map::iterator i4=man->liste.begin(); i4!=man->liste.end();i4++) { i4->second->currentTurn = man->turn; } return true; } void DataStoring::LoadGameManager(QDomElement &xmlman,float version) { man->type = string2gameType(xmlman.attribute("gametype","hotseat")); man->heuris = (xmlman.attribute("heuristurn")=="yes"); man->turn = string2turn(xmlman.attribute("turn")); man->nbTurns = xmlman.attribute("nbturns").toInt(); man->maxCreaId = xmlman.attribute("maxcreaid").toInt(); man->cmdPts = xmlman.attribute("cmdpts").toInt(); int pbemid = xmlman.attribute("pbemid","0").toInt(); if (pbemid) { // From 1.4.1 level. man->pbemidMarine = pbemid; man->pbemidGenestealer = pbemid; } else { man->pbemidMarine = xmlman.attribute("pbemid_marine").toInt(); man->pbemidGenestealer = xmlman.attribute("pbemid_genestealer").toInt(); } man->email = xmlman.attribute("email"); Rand::setSeed(xmlman.attribute("random_seed","0").toInt()); if (man->type==PBEM) man->cheatProtection = xmlman.attribute("cheat","1").toInt(); if (man->type==PBEM && man->cheatProtection==2 && xmlman.attribute("hascheated","no")=="yes") guicmd->printPopupMessage("Warning :\nYour opponent has open your previous" " savegame more than once."); QDomElement current = xmlman.firstChild().toElement(); if (version==1) { while (!current.isNull()) { int nbGen = current.attribute("nbgen").toInt(); man->blipCards.push_back(nbGen); current = current.nextSibling().toElement(); } } else { while (!current.isNull()) { if (current.tagName()=="cardlist") { QDomElement sub = current.firstChild().toElement(); while (!sub.isNull()) { int nbGen = sub.attribute("nbgen").toInt(); man->blipCards.push_back(nbGen); sub = sub.nextSibling().toElement(); } } else if (current.tagName()=="waitingentrylist") { QDomElement sub = current.firstChild().toElement(); while (!sub.isNull()) { int pos = sub.attribute("position").toInt(); man->currentWaitingEntries.insert(pos); sub = sub.nextSibling().toElement(); } } else if (current.tagName()=="replaylist") { QDomElement sub = current.firstChild().toElement(); while (!sub.isNull()) { QString rep = sub.attribute("replay"); man->replays.push_back(rep); sub = sub.nextSibling().toElement(); } } current = current.nextSibling().toElement(); } } man->currBlipCard = man->blipCards.begin(); man->listChanged = true; } void DataStoring::LoadLevel(QDomElement &xmllev, float version) { man->level->InitFromSaveGame(xmllev); QDomElement current = xmllev.namedItem("killlist").toElement(); // man->level->num_killed.clear(); if (!current.isNull()) { current = current.firstChild().toElement(); while (!current.isNull()) { int unit = current.attribute("unit").toInt(); int nb = current.attribute("nb").toInt(); man->level->num_killed[unit]=nb; current = current.nextSibling().toElement(); } } } void DataStoring::LoadBoard(QDomElement &xmlb, float version) { int xmax = xmlb.attribute("xmax").toInt(); int ymax = xmlb.attribute("ymax").toInt(); board->setMax(xmax,ymax); man->guib->Init(); QDomElement current = xmlb.firstChild().toElement(); while (!current.isNull()) { QString elem = current.tagName(); if (elem=="emptysquare") { int pos = current.attribute("position").toInt(); board->addCase(pos); } else if (elem=="dead_tiles") LoadDeadTiles(current); else if (elem=="door") LoadDoor(current); else if (elem=="bulkhead") LoadBulkhead(current); else if (elem=="extensible") LoadExtensible(current); else if (elem=="entryzone") LoadEntryzone(current); else if (elem=="exit") LoadExit(current); else if (elem=="flame") LoadFlame(current); else if (elem=="cat") LoadCat(current); else if (elem=="blip") LoadBlip(current); else if (elem=="genestealer") LoadGenestealer(current); else if (elem=="bolter") LoadBolter(current); else if (elem=="sergeant") LoadSergeant(current); else if (elem=="flamer") LoadFlamer(current); current = current.nextSibling().toElement(); } } void DataStoring::LoadDeadTiles(QDomElement &liste) { QDomElement current = liste.firstChild().toElement(); while (!current.isNull()) { int pos = current.attribute("position").toInt(); if (current.tagName()=="dead_marine") man->guib->setKilled(pos,true); else if (current.tagName()=="dead_genestealer") man->guib->setKilled(pos,false); current = current.nextSibling().toElement(); } } void DataStoring::LoadDoor(QDomElement &obj) { int pos = obj.attribute("position").toInt(); bool vertical = (obj.attribute("vertical") == "yes"); DoorState st = (obj.attribute("state")=="open")?OPEN:CLOSE; Door *door = new Door(guic,guicmd,pos,vertical,st); board->addObject(door); } void DataStoring::LoadBulkhead(QDomElement &obj) { int pos = obj.attribute("position").toInt(); bool vertical = (obj.attribute("vertical") == "yes"); DoorState st = (obj.attribute("state")=="open")?OPEN:CLOSE; bool canOpen = (obj.attribute("can_open")=="yes"); bool canClose = (obj.attribute("can_close")=="yes"); Bulkhead *b = new Bulkhead(guic,guicmd,pos,st,vertical,canOpen,canClose); board->addObject(b); } void DataStoring::LoadExtensible(QDomElement &obj) { int pos = obj.attribute("position").toInt(); ExtensibleObject *ext = new ExtensibleObject(guic,guicmd,pos); ext->desc = obj.attribute("desc"); ext->graphic = obj.attribute("graphic"); ext->stateIsEmpty = (obj.attribute("empty")=="yes"); ext->stateIsAttackable = (obj.attribute("attackable")=="yes"); ext->stateIsShootable = obj.attribute("shootable").toInt(); ext->stateIsFireable = (obj.attribute("fireable")=="yes"); ext->stateCanBeTaken = obj.attribute("takeable").toInt(); ext->stateDropable = obj.attribute("dropable").toInt(); ext->stateTransferable = obj.attribute("transferable").toInt(); ext->stateShootWith = (obj.attribute("shootwith")=="yes"); ext->stateUseDoorWith = (obj.attribute("usedoorwith")=="yes"); ext->isTaken = (obj.attribute("istaken")=="yes"); board->addObject(ext); if (ext->stateCanBeTaken) guicmd->setObjectButtonsVisible(true); } void DataStoring::LoadEntryzone(QDomElement &obj) { int pos = obj.attribute("position").toInt(); Direction dir = string2dir(obj.attribute("direction")); int maxblip = obj.attribute("maxblip").toInt(); EntryZone *ez = new EntryZone(guic,guicmd,pos,dir,maxblip); board->addObject(ez); } void DataStoring::LoadExit(QDomElement &obj) { int pos = obj.attribute("position").toInt(); Direction dir = string2dir(obj.attribute("direction")); Turn tu = string2turn(obj.attribute("turn")); Exit *ex = new Exit(guic,guicmd,pos,tu,dir); QDomElement current = obj.firstChild().toElement(); while (!current.isNull()) { ObjectType ty = string2type(current.attribute("type")); int id = current.attribute("id").toInt(); ex->out[ty].push_back(id); man->exitedUnits[ty].push_back(id); current = current.nextSibling().toElement(); } board->addObject(ex); } void DataStoring::LoadFlame(QDomElement &obj) { int pos = obj.attribute("position").toInt(); Flame *fl = new Flame(guic,guicmd,pos); fl->nbFlames = obj.attribute("nbflames").toInt(); fl->isTransparent = (obj.attribute("transparent")=="yes"); man->flames[pos] = fl; board->addObject(fl); } void DataStoring::LoadCat(QDomElement &obj) { int pos = obj.attribute("position").toInt(); int id = obj.attribute("id").toInt(); ModuleCAT *cat = new ModuleCAT(guic,guicmd,pos,id); cat->initTurn = obj.attribute("initturn").toInt(); cat->selected = (obj.attribute("selected")=="yes"); cat->hasDoneSomething = (obj.attribute("donesomething")=="yes"); cat->actionPts = obj.attribute("actionpts").toInt(); if (obj.attribute("taken")=="yes") hasTaken.push_back(cat); cat->isTaken = (obj.attribute("istaken")=="yes"); board->addObject(cat); man->liste[id] = cat; if (cat->selected) man->selected = cat; guicmd->setObjectButtonsVisible(true); } void DataStoring::LoadBlip(QDomElement &obj) { int pos = obj.attribute("position").toInt(); int id = obj.attribute("id").toInt(); int nbgen = obj.attribute("nbgen").toInt(); Blip *blip = new Blip(guic,guicmd,pos,id,nbgen); blip->initTurn = obj.attribute("initturn").toInt(); blip->selected = (obj.attribute("selected")=="yes"); blip->hasDoneSomething = (obj.attribute("donesomething")=="yes"); blip->actionPts = obj.attribute("actionpts").toInt(); if (obj.attribute("taken")=="yes") hasTaken.push_back(blip); board->addObject(blip); man->liste[id] = blip; if (blip->selected) man->selected = blip; } void DataStoring::LoadGenestealer(QDomElement &obj) { int pos = obj.attribute("position").toInt(); int id = obj.attribute("id").toInt(); Direction dir = string2dir(obj.attribute("orientation")); Genestealer *gen = new Genestealer(guic,guicmd,pos,id,dir); gen->initTurn = obj.attribute("initturn").toInt(); gen->selected = (obj.attribute("selected")=="yes"); gen->hasDoneSomething = (obj.attribute("donesomething")=="yes"); gen->actionPts = obj.attribute("actionpts").toInt(); gen->history = string2history(obj.attribute("history")); if (obj.attribute("taken")=="yes") hasTaken.push_back(gen); board->addObject(gen); man->liste[id] = gen; if (gen->selected) man->selected = gen; } void DataStoring::LoadBolter(QDomElement &obj) { int pos = obj.attribute("position").toInt(); int id = obj.attribute("id").toInt(); Direction dir = string2dir(obj.attribute("orientation")); BolterMarine *bolt = new BolterMarine(guic,guicmd,pos,id,dir,&(man->cmdPts)); bolt->initTurn = obj.attribute("initturn").toInt(); bolt->selected = (obj.attribute("selected")=="yes"); bolt->hasDoneSomething = (obj.attribute("donesomething")=="yes"); bolt->actionPts = obj.attribute("actionpts").toInt(); bolt->history = string2history(obj.attribute("history")); bolt->previousTargetCase = obj.attribute("previoustarget").toInt(); bolt->jammed = (obj.attribute("jammed")=="yes"); if (obj.attribute("taken")=="yes") hasTaken.push_back(bolt); board->addObject(bolt); man->liste[id] = bolt; if (bolt->selected) man->selected = bolt; } void DataStoring::LoadSergeant(QDomElement &obj) { int pos = obj.attribute("position").toInt(); int id = obj.attribute("id").toInt(); Direction dir = string2dir(obj.attribute("orientation")); Sergeant *serg = new Sergeant(guic,guicmd,pos,id,dir,&(man->cmdPts)); serg->initTurn = obj.attribute("initturn").toInt(); serg->selected = (obj.attribute("selected")=="yes"); serg->hasDoneSomething = (obj.attribute("donesomething")=="yes"); serg->actionPts = obj.attribute("actionpts").toInt(); serg->history = string2history(obj.attribute("history")); serg->previousTargetCase = obj.attribute("previoustarget").toInt(); serg->jammed = (obj.attribute("jammed")=="yes"); if (obj.attribute("taken")=="yes") hasTaken.push_back(serg); board->addObject(serg); man->liste[id] = serg; if (serg->selected) man->selected = serg; } void DataStoring::LoadFlamer(QDomElement &obj) { int pos = obj.attribute("position").toInt(); int id = obj.attribute("id").toInt(); Direction dir = string2dir(obj.attribute("orientation")); FlamerMarine *flam = new FlamerMarine(guic,guicmd,pos,id,dir,&(man->cmdPts),0); flam->initTurn = obj.attribute("initturn").toInt(); flam->selected = (obj.attribute("selected")=="yes"); flam->hasDoneSomething = (obj.attribute("donesomething")=="yes"); flam->actionPts = obj.attribute("actionpts").toInt(); flam->history = string2history(obj.attribute("history")); flam->previousTargetCase = obj.attribute("previoustarget").toInt(); flam->ammunition = obj.attribute("ammunition").toInt(); flam->charger = obj.attribute("charger").toInt(); if (obj.attribute("taken")=="yes") hasTaken.push_back(flam); QDomElement current = obj.firstChild().toElement(); vector fl; while (!current.isNull()) { fl.push_back(current.attribute("position").toInt()); current = current.nextSibling().toElement(); } if (fl.size()!=0) flames.push_back(pair >(flam,fl)); board->addObject(flam); man->liste[id] = flam; if (flam->selected) man->selected = flam; }