Ver código fonte

* started making support for save/load options

Michał W. Urbańczyk 17 anos atrás
pai
commit
333e1d9878
12 arquivos alterados com 485 adições e 278 exclusões
  1. 12 1
      CGameState.h
  2. 4 0
      CLua.h
  3. 9 0
      CMT.cpp
  4. 221 102
      CPreGame.cpp
  5. 14 6
      CPreGame.h
  6. 5 0
      client/Client.cpp
  7. 1 0
      client/Client.h
  8. 17 10
      lib/Connection.cpp
  9. 175 159
      lib/Connection.h
  10. 4 0
      map.h
  11. 9 0
      server/CGameHandler.cpp
  12. 14 0
      server/CGameHandler.h

+ 12 - 1
CGameState.h

@@ -50,6 +50,11 @@ public:
 	std::vector<CGTownInstance *> towns;
 	std::vector<CGHeroInstance *> availableHeroes; //heroes available in taverns
 	PlayerState():color(-1),currentSelection(0xffffffff){};
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & color & serial & currentSelection & fogOfWarMap & resources;
+		//TODO: vectors of heroes/towns
+	}
 };
 
 struct DLL_EXPORT BattleInfo
@@ -156,7 +161,7 @@ private:
 	BattleInfo *curB; //current battle
 	ui32 day; //total number of days in game
 	Mapa * map;
-	std::map<ui8,PlayerState> players; //ID <-> playerstate
+	std::map<ui8,PlayerState> players; //ID <-> player state
 	std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
 	std::vector<ui32> resVals;
 
@@ -191,6 +196,12 @@ private:
 	std::set<int3> tilesToReveal(int3 pos, int radious, int player); //if player==-1 => adds all tiles in radious
 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;
+		//TODO: villages, forts, capitols - will need reloading
+		//TODO: hero pool
+	}
 
 	friend class CCallback;
 	friend class CPathfinder;;

+ 4 - 0
CLua.h

@@ -99,6 +99,10 @@ public:
 	CScriptCallback * cb;
 	CCPPObjectScript(CScriptCallback * CB){cb=CB;};
 	virtual std::vector<int> yourObjects()=0; //returns IDs of objects which are handled by script
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		//TODO: write
+	}
 };
 class CVisitableOPH : public CCPPObjectScript  //once per hero
 {

+ 9 - 0
CMT.cpp

@@ -131,6 +131,9 @@ int main(int argc, char** argv)
 		abilh->loadAbilities();
 		cgi->abilh = abilh;
 		tlog0<<"\tAbility handler: "<<pomtime.getDif()<<std::endl;
+		CGI->preth = new CPreGameTextHandler;
+		CGI->preth->loadTexts();
+		tlog0<<"\tCPreGameTextHandler: "<<pomtime.getDif()<<std::endl;
 		tlog0<<"Preparing first handlers: "<<tmh.getDif()<<std::endl;
 		pomtime.getDif();
 		graphics = new Graphics();
@@ -254,6 +257,12 @@ void processCommand(const std::string &message, CClient *&client)
 			break;
 		}
 	}
+	else if(cn=="save")
+	{
+		std::string fname;
+		readed >> fname;
+		client->save(fname);
+	}
 	else if(message=="get txt")
 	{
 		boost::filesystem::create_directory("Extracted_txts");

+ 221 - 102
CPreGame.cpp

@@ -109,6 +109,11 @@ void HighButton::hover(bool on)
 	SDL_BlitSurface(imgs->ourImages[i].bitmap,NULL,screen,&pos);
 	updateRect(&pos);
 }
+
+HighButton::~HighButton()
+{
+	delete imgs;
+}
 void Button::hover(bool on)
 {
 	HighButton::hover(on);
@@ -136,15 +141,15 @@ void Slider::updateSlid()
 	{
 		myh=perc*((float)pos.h-48)+pos.y+16;
 		SDL_FillRect(screen,&genRect(pos.h-32,pos.w,pos.x,pos.y+16),0);
-		blitAt(slider.imgs->ourImages[0].bitmap,pos.x,(int)myh);
-		slider.pos.y=(int)myh;
+		blitAt(slider->imgs->ourImages[0].bitmap,pos.x,(int)myh);
+		slider->pos.y=(int)myh;
 	}
 	else
 	{
 		myh=perc*((float)pos.w-48)+pos.x+16;
 		SDL_FillRect(screen,&genRect(pos.h,pos.w-32,pos.x+16,pos.y),0);
-		blitAt(slider.imgs->ourImages[0].bitmap,(int)myh,pos.y);
-		slider.pos.x=(int)myh;
+		blitAt(slider->imgs->ourImages[0].bitmap,(int)myh,pos.y);
+		slider->pos.x=(int)myh;
 	}
 	updateRect(&pos);
 }
@@ -169,16 +174,16 @@ Slider::Slider(int x, int y, int h, int amnt, int cap, bool ver)
 	if (ver)
 	{
 		pos = genRect(h,16,x,y);
-		down = Button(genRect(16,16,x,y+h-16),boost::bind(&Slider::moveDown,this),CDefHandler::giveDef("SCNRBDN.DEF"),false);
-		up = Button(genRect(16,16,x,y),boost::bind(&Slider::moveUp,this),CDefHandler::giveDef("SCNRBUP.DEF"),false);
-		slider = Button(genRect(16,16,x,y+16),boost::function<void()>(),CDefHandler::giveDef("SCNRBSL.DEF"),false);
+		down = new Button(genRect(16,16,x,y+h-16),boost::bind(&Slider::moveDown,this),CDefHandler::giveDef("SCNRBDN.DEF"),false);
+		up = new Button(genRect(16,16,x,y),boost::bind(&Slider::moveUp,this),CDefHandler::giveDef("SCNRBUP.DEF"),false);
+		slider = new Button(genRect(16,16,x,y+16),boost::function<void()>(),CDefHandler::giveDef("SCNRBSL.DEF"),false);
 	}
 	else
 	{
 		pos = genRect(16,h,x,y);
-		down = Button(genRect(16,16,x+h-16,y),boost::bind(&Slider::moveDown,this),CDefHandler::giveDef("SCNRBRT.DEF"),false);
-		up = Button(genRect(16,16,x,y),boost::bind(&Slider::moveUp,this),CDefHandler::giveDef("SCNRBLF.DEF"),false);
-		slider = Button(genRect(16,16,x+16,y),boost::function<void()>(),CDefHandler::giveDef("SCNRBSL.DEF"),false);
+		down = new Button(genRect(16,16,x+h-16,y),boost::bind(&Slider::moveDown,this),CDefHandler::giveDef("SCNRBRT.DEF"),false);
+		up = new Button(genRect(16,16,x,y),boost::bind(&Slider::moveUp,this),CDefHandler::giveDef("SCNRBLF.DEF"),false);
+		slider = new Button(genRect(16,16,x+16,y),boost::function<void()>(),CDefHandler::giveDef("SCNRBSL.DEF"),false);
 	}
 	moving = false;
 	whereAreWe=0;
@@ -191,9 +196,9 @@ void Slider::deactivate()
 void Slider::activate()
 {
 	SDL_FillRect(screen,&pos,0);
-	up.show();
-	down.show();
-	slider.show();
+	up->show();
+	down->show();
+	slider->show();
 	//SDL_Flip(screen);
 	CSDL_Ext::update(screen);
 	CPG->interested.push_back(this);
@@ -203,17 +208,17 @@ void Slider::handleIt(SDL_Event sEvent)
 {
 	if ((sEvent.type==SDL_MOUSEBUTTONDOWN) && (sEvent.button.button == SDL_BUTTON_LEFT))
 	{
-		if (isItIn(&down.pos,sEvent.motion.x,sEvent.motion.y))
+		if (isItIn(&down->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			down.press();
+			down->press();
 		}
-		else if (isItIn(&up.pos,sEvent.motion.x,sEvent.motion.y))
+		else if (isItIn(&up->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			up.press();
+			up->press();
 		}
-		else if (isItIn(&slider.pos,sEvent.motion.x,sEvent.motion.y))
+		else if (isItIn(&slider->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			//slider.press();
+			//slider->press();
 			moving=true;
 		}
 		else if (isItIn(&pos,sEvent.motion.x,sEvent.motion.y))
@@ -243,19 +248,19 @@ void Slider::handleIt(SDL_Event sEvent)
 	else if ((sEvent.type==SDL_MOUSEBUTTONUP) && (sEvent.button.button == SDL_BUTTON_LEFT))
 	{
 
-		if ((down.state==1) && isItIn(&down.pos,sEvent.motion.x,sEvent.motion.y))
+		if ((down->state==1) && isItIn(&down->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			this->down.fun();
+			this->down->fun();
 		}
-		if ((up.state==1) && isItIn(&up.pos,sEvent.motion.x,sEvent.motion.y))
+		if ((up->state==1) && isItIn(&up->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			this->up.fun();
+			this->up->fun();
 		}
-		if (down.state==1) down.press(false);
-		if (up.state==1) up.press(false);
+		if (down->state==1) down->press(false);
+		if (up->state==1) up->press(false);
 		if (moving)
 		{
-			//slider.press();
+			//slider->press();
 			moving=false;
 		}
 	}
@@ -324,21 +329,28 @@ void Slider::handleIt(SDL_Event sEvent)
 		}
 
 
-		if (isItIn(&down.pos,sEvent.motion.x,sEvent.motion.y))
+		if (isItIn(&down->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			(this->*down.fun)();
+			(this->*down->fun)();
 		}
-		if (isItIn(&up.pos,sEvent.motion.x,sEvent.motion.y))
+		if (isItIn(&up->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			(this->*up.fun)();
+			(this->*up->fun)();
 		}
-		if (isItIn(&slider.pos,sEvent.motion.x,sEvent.motion.y))
+		if (isItIn(&slider->pos,sEvent.motion.x,sEvent.motion.y))
 		{
-			(this->*slider.fun)();
+			(this->*slider->fun)();
 		}
 
 	}*/
 }
+
+Slider::~Slider()
+{
+	delete up;
+	delete down;
+	delete slider;
+}
 IntBut::IntBut()
 {
 	type=2;
@@ -982,6 +994,7 @@ void MapSel::processMaps(std::vector<std::string> &pliczkiTemp, int &index)
 	static boost::mutex mx;
 	bool areMaps=true;
 	int pom=-1;
+	unsigned char sss[1000];
 	while(areMaps)
 	{
 		mx.lock();
@@ -996,7 +1009,6 @@ void MapSel::processMaps(std::vector<std::string> &pliczkiTemp, int &index)
 			mx.unlock();
 		}
 		gzFile tempf = gzopen(pliczkiTemp[pom].c_str(),"rb");
-		unsigned char * sss = new unsigned char[1000];
 		int iii=0;
 		while(true)
 		{
@@ -1009,13 +1021,22 @@ void MapSel::processMaps(std::vector<std::string> &pliczkiTemp, int &index)
 			else break;
 		}
 		gzclose(tempf);
-		if(iii<50) {tlog3<<"\t\tWarning: corrupted map file: "<<pliczkiTemp[pom]<<std::endl; continue;}
-		if (!sss[4]) continue; //nie ma graczy? mapa niegrywalna //ju¿ to kiedyœ komentowa³em- - to bzdura //tu calkiem pasuje...
+
+		if(iii<50) 
+		{
+			tlog3<<"\t\tWarning: corrupted map file: "<<pliczkiTemp[pom]<<std::endl; 
+			continue;
+		}
+		if (!sss[4])
+		{
+			//tlog3 << "\t\tSkipping " << pliczkiTemp[pom] << " - map marked as unplayable.\n";
+			continue;
+		}
+
 		CMapInfo mi(pliczkiTemp[pom],sss);
 		mx.lock();
 		ourMaps.push_back(mi);
 		mx.unlock();
-		delete[] sss;
 	}
 }
 
@@ -1221,14 +1242,14 @@ void MapSel::printSelectedInfo()
 
 	int temp = ourMaps[selected].victoryCondition+1;
 	if (temp>20) temp=0;
-	std::string sss = CPG->preth->victoryConditions[temp];
-	if (temp && ourMaps[selected].vicConDetails->allowNormalVictory) sss+= "/" + CPG->preth->victoryConditions[0];
+	std::string sss = CGI->preth->victoryConditions[temp];
+	if (temp && ourMaps[selected].vicConDetails->allowNormalVictory) sss+= "/" + CGI->preth->victoryConditions[0];
 	CSDL_Ext::printAt(sss,452,310,GEOR13,zwykly);
 
 
 	temp = ourMaps[selected].lossCondition.typeOfLossCon+1;
 	if (temp>20) temp=0;
-	sss = CPG->preth->lossCondtions[temp];
+	sss = CGI->preth->lossCondtions[temp];
 	CSDL_Ext::printAt(sss,452,370,GEOR13,zwykly);
 
 	//blit descrption
@@ -1245,19 +1266,19 @@ void MapSel::printSelectedInfo()
 	switch (ourMaps[selected].difficulty)
 	{
 	case 0:
-		diff=gdiff(CPG->preth->zelp[24].second);
+		diff=gdiff(CGI->preth->zelp[24].second);
 		break;
 	case 1:
-		diff=gdiff(CPG->preth->zelp[25].second);
+		diff=gdiff(CGI->preth->zelp[25].second);
 		break;
 	case 2:
-		diff=gdiff(CPG->preth->zelp[26].second);
+		diff=gdiff(CGI->preth->zelp[26].second);
 		break;
 	case 3:
-		diff=gdiff(CPG->preth->zelp[27].second);
+		diff=gdiff(CGI->preth->zelp[27].second);
 		break;
 	case 4:
-		diff=gdiff(CPG->preth->zelp[28].second);
+		diff=gdiff(CGI->preth->zelp[28].second);
 		break;
 	}
 	temp=-1;
@@ -1383,6 +1404,7 @@ void CPreGame::showScenList()
 }
 CPreGame::CPreGame()
 {
+	CPG=this;
 	highlighted=NULL;
 	currentTab=NULL;
 	run=true;
@@ -1390,23 +1412,20 @@ CPreGame::CPreGame()
 	tytulowy.r=229;tytulowy.g=215;tytulowy.b=123;tytulowy.unused=0;
 	zwykly.r=255;zwykly.g=255;zwykly.b=255;zwykly.unused=0; //gbr
 	tlo.r=66;tlo.g=44;tlo.b=24;tlo.unused=0;
-	preth = new CPreGameTextHandler;
-	preth->loadTexts();
-	CGI->preth=preth;
-	tlog0<<"\tCPreGame: loading txts: "<<tmh.getDif()<<std::endl;
 	currentMessage=NULL;
 	behindCurMes=NULL;
 	initMainMenu();
 	tlog0<<"\tCPreGame: main menu initialization: "<<tmh.getDif()<<std::endl;
 	initNewMenu();
 	tlog0<<"\tCPreGame: newgame menu initialization: "<<tmh.getDif()<<std::endl;
+	initLoadMenu();
+	tlog0<<"\tCPreGame: loadgame menu initialization: "<<tmh.getDif()<<std::endl;
 	initScenSel();
 	tlog0<<"\tCPreGame: scenario choice initialization: "<<tmh.getDif()<<std::endl;
 	initOptions();
 	tlog0<<"\tCPreGame: scenario options initialization: "<<tmh.getDif()<<std::endl;
 	showMainMenu();
 	tlog0<<"\tCPreGame: displaying main menu: "<<tmh.getDif()<<std::endl;
-	CPG=this;
 	playerName="Player";
 }
 void CPreGame::initOptions()
@@ -1417,44 +1436,6 @@ void CPreGame::initOptions()
 void CPreGame::initScenSel()
 {
 	ourScenSel = new ScenSel();
-	ourScenSel->listShowed=false;
-	if (rand()%2) ourScenSel->background=BitmapHandler::loadBitmap("ZPIC1000.bmp");
-	else ourScenSel->background=BitmapHandler::loadBitmap("ZPIC1001.bmp");
-
-	ourScenSel->pressed=NULL;
-
-	ourScenSel->scenInf=BitmapHandler::loadBitmap("GSELPOP1.bmp");//SDL_LoadBMP("h3bitmap.lod\\GSELPOP1.bmp");
-	ourScenSel->randMap=BitmapHandler::loadBitmap("RANMAPBK.bmp");
-	ourScenSel->options=BitmapHandler::loadBitmap("ADVOPTBK.bmp");
-	SDL_SetColorKey(ourScenSel->scenInf,SDL_SRCCOLORKEY,SDL_MapRGB(ourScenSel->scenInf->format,0,255,255));
-	//SDL_SetColorKey(ourScenSel->scenList,SDL_SRCCOLORKEY,SDL_MapRGB(ourScenSel->scenList->format,0,255,255));
-	SDL_SetColorKey(ourScenSel->randMap,SDL_SRCCOLORKEY,SDL_MapRGB(ourScenSel->randMap->format,0,255,255));
-	SDL_SetColorKey(ourScenSel->options,SDL_SRCCOLORKEY,SDL_MapRGB(ourScenSel->options->format,0,255,255));
-
-	ourScenSel->difficulty = new CPoinGroup();
-	ourScenSel->difficulty->type=1;
-	ourScenSel->selectedDiff=-77;
-	ourScenSel->difficulty->gdzie = &ourScenSel->selectedDiff;
-	ourScenSel->bEasy = IntSelBut(genRect(0,0,506,456),NULL,CDefHandler::giveDef("GSPBUT3.DEF"),true,ourScenSel->difficulty,0);
-	ourScenSel->bNormal = IntSelBut(genRect(0,0,538,456),NULL,CDefHandler::giveDef("GSPBUT4.DEF"),true,ourScenSel->difficulty,1);
-	ourScenSel->bHard = IntSelBut(genRect(0,0,570,456),NULL,CDefHandler::giveDef("GSPBUT5.DEF"),true,ourScenSel->difficulty,2);
-	ourScenSel->bExpert = IntSelBut(genRect(0,0,602,456),NULL,CDefHandler::giveDef("GSPBUT6.DEF"),true,ourScenSel->difficulty,3);
-	ourScenSel->bImpossible = IntSelBut(genRect(0,0,634,456),NULL,CDefHandler::giveDef("GSPBUT7.DEF"),true,ourScenSel->difficulty,4);
-
-	ourScenSel->bBack = Button(genRect(0,0,584,535),boost::bind(&CPreGame::showNewMenu,this),CDefHandler::giveDef("SCNRBACK.DEF"));
-	ourScenSel->bBegin = Button(genRect(0,0,414,535),boost::bind(&CPreGame::begin,this),CDefHandler::giveDef("SCNRBEG.DEF"));
-	ourScenSel->bScens = Button(genRect(0,0,414,81),boost::bind(&CPreGame::showScenList,this),CDefHandler::giveDef("GSPBUTT.DEF"));
-
-	for (int i=0; i<ourScenSel->bScens.imgs->ourImages.size(); i++)
-		CSDL_Ext::printAt(CGI->generaltexth->allTexts[500],25+i,2+i,GEOR13,zwykly,ourScenSel->bScens.imgs->ourImages[i].bitmap); //"Show Available Scenarios"
-	ourScenSel->bRandom = Button(genRect(0,0,414,105),boost::bind(&CPreGame::showScenList,this),CDefHandler::giveDef("GSPBUTT.DEF"));
-	for (int i=0; i<ourScenSel->bRandom.imgs->ourImages.size(); i++)
-		CSDL_Ext::printAt(CGI->generaltexth->allTexts[740],25+i,2+i,GEOR13,zwykly,ourScenSel->bRandom.imgs->ourImages[i].bitmap);
-	ourScenSel->bOptions = Button(genRect(0,0,414,509),boost::bind(&CPreGame::showOptions,this),CDefHandler::giveDef("GSPBUTT.DEF"));
-	for (int i=0; i<ourScenSel->bOptions.imgs->ourImages.size(); i++)
-		CSDL_Ext::printAt(CGI->generaltexth->allTexts[501],25+i,2+i,GEOR13,zwykly,ourScenSel->bOptions.imgs->ourImages[i].bitmap); //"Show Advanced Options"
-
-	CPG=this;
 	tlog5 << "\t\tLoaded graphics\n";
 	ourScenSel->mapsel.init();
 	tlog5 << "\t\tLoaded maps\n";
@@ -1554,8 +1535,6 @@ void CPreGame::initNewMenu()
 	ourNewMenu->highScores = CDefHandler::giveDef("ZTCAMPN.DEF");
 	ourNewMenu->credits = CDefHandler::giveDef("ZTTUTOR.DEF");
 	ourNewMenu->quit = CDefHandler::giveDef("ZTBACK.DEF");
-	ok = CDefHandler::giveDef("IOKAY.DEF");
-	cancel = CDefHandler::giveDef("ICANCEL.DEF");
 	// single scenario
 	ourNewMenu->lNewGame.h=ourNewMenu->newGame->ourImages[0].bitmap->h;
 	ourNewMenu->lNewGame.w=ourNewMenu->newGame->ourImages[0].bitmap->w;
@@ -1627,6 +1606,7 @@ void CPreGame::initMainMenu()
 	ourMainMenu->lLoadGame.w=ourMainMenu->loadGame->ourImages[0].bitmap->w;
 	ourMainMenu->lLoadGame.x=532;
 	ourMainMenu->lLoadGame.y=132;
+	ourMainMenu->fLoadGame=&CPreGame::showLoadMenu;
 	//high scores
 	ourMainMenu->lHighScores.h=ourMainMenu->highScores->ourImages[0].bitmap->h;
 	ourMainMenu->lHighScores.w=ourMainMenu->highScores->ourImages[0].bitmap->w;
@@ -1696,7 +1676,7 @@ void CPreGame::highlightButton(int which, int on)
 void CPreGame::showCenBox (std::string data)
 {
 	CMessage * cmh = new CMessage();
-	SDL_Surface * infoBox = cmh->genMessage(preth->getTitle(data), preth->getDescr(data));
+	SDL_Surface * infoBox = cmh->genMessage(CGI->preth->getTitle(data), CGI->preth->getDescr(data));
 	behindCurMes = CSDL_Ext::newSurface(infoBox->w,infoBox->h,screen);
 	SDL_Rect pos = genRect(infoBox->h,infoBox->w,
 		(screen->w/2)-(infoBox->w/2),(screen->h/2)-(infoBox->h/2));
@@ -1714,7 +1694,7 @@ void CPreGame::showAskBox (std::string data, void(*f1)(),void(*f2)())
 	std::vector<SDL_Rect> * btnspos= new std::vector<SDL_Rect>(0);
 	przyciski->push_back(ok);
 	przyciski->push_back(cancel);
-	SDL_Surface * infoBox = cmh->genMessage(preth->getTitle(data), preth->getDescr(data), yesOrNO, przyciski, btnspos);
+	SDL_Surface * infoBox = cmh->genMessage(CGI->preth->getTitle(data), CGI->preth->getDescr(data), yesOrNO, przyciski, btnspos);
 	behindCurMes = CSDL_Ext::newSurface(infoBox->w,infoBox->h,screen);
 	SDL_Rect pos = genRect(infoBox->h,infoBox->w,
 		(screen->w/2)-(infoBox->w/2),(screen->h/2)-(infoBox->h/2));
@@ -1761,6 +1741,8 @@ CPreGame::menuItems * CPreGame::currentItems()
 		return ourMainMenu;
 	case newGame:
 		return ourNewMenu;
+	case loadGame:
+		return ourLoadMenu;
 	default:
 		return NULL;
 	}
@@ -2065,6 +2047,7 @@ StartInfo CPreGame::runLoop()
 					{
 						highlightButton(2,2);
 						current->highlighted=2;
+						(this->*(current->fLoadGame))();
 					}
 					else if (isItIn(&current->lHighScores,sEvent.motion.x,sEvent.motion.y))
 					{
@@ -2129,31 +2112,31 @@ std::string CPreGame::buttonText(int which)
 		switch (which)
 		{
 		case 0:
-			return CPG->preth->zelp[3].second;
+			return CGI->preth->zelp[3].second;
 		case 1:
-			return CPG->preth->zelp[4].second;
+			return CGI->preth->zelp[4].second;
 		case 2:
-			return CPG->preth->zelp[5].second;
+			return CGI->preth->zelp[5].second;
 		case 3:
-			return CPG->preth->zelp[6].second;
+			return CGI->preth->zelp[6].second;
 		case 4:
-			return CPG->preth->zelp[7].second;
+			return CGI->preth->zelp[7].second;
 		}
 	}
-	else if (state==newGame)
+	else if (state==newGame || state==loadGame)
 	{
 		switch (which)
 		{
 		case 0:
-			return CPG->preth->zelp[10].second;
+			return CGI->preth->zelp[10].second;
 		case 1:
-			return CPG->preth->zelp[11].second;
+			return CGI->preth->zelp[11].second;
 		case 2:
-			return CPG->preth->zelp[12].second;
+			return CGI->preth->zelp[12].second;
 		case 3:
-			return CPG->preth->zelp[13].second;
+			return CGI->preth->zelp[13].second;
 		case 4:
-			return CPG->preth->zelp[14].second;
+			return CGI->preth->zelp[14].second;
 		}
 	}
 	return std::string();
@@ -2224,3 +2207,139 @@ void CPreGame::setTurnLength(int on)
 	}
 	else CSDL_Ext::printAtMiddle("Unlimited",323,563,GEOR13);
 }
+
+void CPreGame::showLoadMenu()
+{
+	if (currentTab/*==&ourScenSel->mapsel*/)
+		currentTab->hide();
+	btns.clear();
+	interested.clear();
+	handleOther=NULL;
+	state = loadGame;
+	SDL_BlitSurface(ourLoadMenu->background,NULL,screen,NULL);
+	SDL_BlitSurface(ourLoadMenu->newGame->ourImages[0].bitmap,NULL,screen,&ourLoadMenu->lNewGame);
+	SDL_BlitSurface(ourLoadMenu->loadGame->ourImages[0].bitmap,NULL,screen,&ourLoadMenu->lLoadGame);
+	SDL_BlitSurface(ourLoadMenu->highScores->ourImages[0].bitmap,NULL,screen,&ourLoadMenu->lHighScores);
+	SDL_BlitSurface(ourLoadMenu->credits->ourImages[0].bitmap,NULL,screen,&ourLoadMenu->lCredits);
+	SDL_BlitSurface(ourLoadMenu->quit->ourImages[0].bitmap,NULL,screen,&ourLoadMenu->lQuit);
+	//SDL_Flip(screen);
+	CSDL_Ext::update(screen);
+	first = true;
+}
+
+void CPreGame::initLoadMenu()
+{
+	ourLoadMenu = new menuItems();
+	ourLoadMenu->bgAd = BitmapHandler::loadBitmap("ZLOADGAM.bmp");
+	ourLoadMenu->background = BitmapHandler::loadBitmap("ZPIC1005.bmp");
+	blitAt(ourLoadMenu->bgAd,114,312,ourLoadMenu->background);
+	//loading menu buttons
+	ourLoadMenu->newGame = CDefHandler::giveDef("ZTSINGL.DEF");
+	ourLoadMenu->loadGame = CDefHandler::giveDef("ZTMULTI.DEF");
+	ourLoadMenu->highScores = CDefHandler::giveDef("ZTCAMPN.DEF");
+	ourLoadMenu->credits = CDefHandler::giveDef("ZTTUTOR.DEF");
+	ourLoadMenu->quit = CDefHandler::giveDef("ZTBACK.DEF");
+	// single scenario
+	ourLoadMenu->lNewGame.h=ourLoadMenu->newGame->ourImages[0].bitmap->h;
+	ourLoadMenu->lNewGame.w=ourLoadMenu->newGame->ourImages[0].bitmap->w;
+	ourLoadMenu->lNewGame.x=545;
+	ourLoadMenu->lNewGame.y=4;
+	ourLoadMenu->fNewGame=&CPreGame::showScenSel;
+	//multiplayer
+	ourLoadMenu->lLoadGame.h=ourLoadMenu->loadGame->ourImages[0].bitmap->h;
+	ourLoadMenu->lLoadGame.w=ourLoadMenu->loadGame->ourImages[0].bitmap->w;
+	ourLoadMenu->lLoadGame.x=568;
+	ourLoadMenu->lLoadGame.y=120;
+	//campaign
+	ourLoadMenu->lHighScores.h=ourLoadMenu->highScores->ourImages[0].bitmap->h;
+	ourLoadMenu->lHighScores.w=ourLoadMenu->highScores->ourImages[0].bitmap->w;
+	ourLoadMenu->lHighScores.x=541;
+	ourLoadMenu->lHighScores.y=233;
+	//tutorial
+	ourLoadMenu->lCredits.h=ourLoadMenu->credits->ourImages[0].bitmap->h;
+	ourLoadMenu->lCredits.w=ourLoadMenu->credits->ourImages[0].bitmap->w;
+	ourLoadMenu->lCredits.x=545;
+	ourLoadMenu->lCredits.y=358;
+	//back
+	ourLoadMenu->lQuit.h=ourLoadMenu->quit->ourImages[0].bitmap->h;
+	ourLoadMenu->lQuit.w=ourLoadMenu->quit->ourImages[0].bitmap->w;
+	ourLoadMenu->lQuit.x=582;
+	ourLoadMenu->lQuit.y=464;
+	ourLoadMenu->fQuit=&CPreGame::showMainMenu;
+
+	ourLoadMenu->highlighted=0;
+}
+
+CPreGame::~CPreGame()
+{
+	delete ourMainMenu;
+	delete ourNewMenu;
+	delete ourLoadMenu;
+
+	delete ok;
+	delete cancel;
+}
+
+CPreGame::menuItems::menuItems()
+{
+}
+
+CPreGame::menuItems::~menuItems()
+{
+	delete this->newGame;
+	delete this->loadGame;
+	delete this->highScores;
+	delete this->credits;
+	delete this->quit;
+	SDL_FreeSurface(bgAd);
+	SDL_FreeSurface(background);
+}
+
+ScenSel::ScenSel()
+:
+	difficulty(new CPoinGroup()),
+	bEasy(genRect(0,0,506,456),NULL,CDefHandler::giveDef("GSPBUT3.DEF"),true,difficulty,0),
+	bNormal(genRect(0,0,538,456),NULL,CDefHandler::giveDef("GSPBUT4.DEF"),true,difficulty,1),
+	bHard(genRect(0,0,570,456),NULL,CDefHandler::giveDef("GSPBUT5.DEF"),true,difficulty,2),
+	bExpert(genRect(0,0,602,456),NULL,CDefHandler::giveDef("GSPBUT6.DEF"),true,difficulty,3),
+	bImpossible(genRect(0,0,634,456),NULL,CDefHandler::giveDef("GSPBUT7.DEF"),true,difficulty,4),
+	bBack(genRect(0,0,584,535),boost::bind(&CPreGame::showNewMenu,CPG),CDefHandler::giveDef("SCNRBACK.DEF")),
+	bBegin(genRect(0,0,414,535),boost::bind(&CPreGame::begin,CPG),CDefHandler::giveDef("SCNRBEG.DEF")),
+	bScens(genRect(0,0,414,81),boost::bind(&CPreGame::showScenList,CPG),CDefHandler::giveDef("GSPBUTT.DEF")),
+	bRandom(genRect(0,0,414,105),boost::bind(&CPreGame::showScenList,CPG),CDefHandler::giveDef("GSPBUTT.DEF")),
+	bOptions(genRect(0,0,414,509),boost::bind(&CPreGame::showOptions,CPG),CDefHandler::giveDef("GSPBUTT.DEF"))
+{
+	pressed=NULL;
+	listShowed=false;
+	if (rand()%2) 
+		background = BitmapHandler::loadBitmap("ZPIC1000.bmp");
+	else 
+		background = BitmapHandler::loadBitmap("ZPIC1001.bmp");
+
+	scenInf = BitmapHandler::loadBitmap("GSELPOP1.bmp");
+	randMap = BitmapHandler::loadBitmap("RANMAPBK.bmp");
+	options = BitmapHandler::loadBitmap("ADVOPTBK.bmp");
+	SDL_SetColorKey(scenInf,SDL_SRCCOLORKEY,SDL_MapRGB(scenInf->format,0,255,255));
+	SDL_SetColorKey(randMap,SDL_SRCCOLORKEY,SDL_MapRGB(randMap->format,0,255,255));
+	SDL_SetColorKey(options,SDL_SRCCOLORKEY,SDL_MapRGB(options->format,0,255,255));
+
+	difficulty->type=1;
+	selectedDiff=-77;
+	difficulty->gdzie = &selectedDiff;
+
+	for (int i=0; i<bScens.imgs->ourImages.size(); i++)
+		CSDL_Ext::printAt(CGI->generaltexth->allTexts[500],25+i,2+i,GEOR13,zwykly,bScens.imgs->ourImages[i].bitmap); //"Show Available Scenarios"
+	for (int i=0; i<bRandom.imgs->ourImages.size(); i++)
+		CSDL_Ext::printAt(CGI->generaltexth->allTexts[740],25+i,2+i,GEOR13,zwykly,bRandom.imgs->ourImages[i].bitmap);
+	for (int i=0; i<bOptions.imgs->ourImages.size(); i++)
+		CSDL_Ext::printAt(CGI->generaltexth->allTexts[501],25+i,2+i,GEOR13,zwykly,bOptions.imgs->ourImages[i].bitmap); //"Show Advanced Options"
+}
+
+ScenSel::~ScenSel()
+{
+	delete difficulty;
+	SDL_FreeSurface(scenInf);
+	SDL_FreeSurface(randMap);
+	SDL_FreeSurface(background);
+	SDL_FreeSurface(options);
+}

+ 14 - 6
CPreGame.h

@@ -28,6 +28,7 @@ struct HighButton
 	int state;
 	HighButton( SDL_Rect Pos, CDefHandler* Imgs, bool Sel=false, int id=-1);
 	HighButton();
+	~HighButton();
 	bool selectable, selected;
 	bool highlightable, highlighted;
 	virtual void show();
@@ -56,8 +57,8 @@ class Slider
 public:
 	bool vertical; // false means horizontal
 	SDL_Rect pos; // position
-	Button up, down, //or left/right
-		slider;
+	Button *up, *down, //or left/right
+		*slider;
 	int positionsAmnt, capacity;// capacity - amount of positions dispplayed at once
 	int whereAreWe; // first displayed thing
 	bool moving;
@@ -70,6 +71,7 @@ public:
 	void deactivate();
 	void activate();
 	Slider(int x, int y, int h, int amnt, int cap, bool ver);
+	~Slider();
 	void updateSlid();
 	void handleIt(SDL_Event sev);
 };
@@ -188,6 +190,7 @@ public:
 	std::vector<SDL_Surface*> scenImgs;
 	//int current;
 	std::vector<CMapInfo> ourMaps;
+	std::vector<CMapInfo> ourGames;
 	IntBut small, medium, large, xlarge, all;
 	SetrButton nrplayer, mapsize, type, name, viccon, loscon;
 	Slider *slid, *descslid;
@@ -210,6 +213,7 @@ public:
 class ScenSel
 {
 public:
+	CPoinGroup * difficulty;
 	bool listShowed;
 	//RanSel ransel;
 	MapSel mapsel;
@@ -217,14 +221,14 @@ public:
 	Button bScens, bOptions, bRandom, bBegin, bBack;
 	IntSelBut	bEasy, bNormal, bHard, bExpert, bImpossible;
 	Button * pressed;
-	CPoinGroup * difficulty;
 	std::vector<Mapa> maps;
 	int selectedDiff;
 	void initRanSel();
 	void showRanSel();
 	void hideRanSel();
 	void genScenList();
-	~ScenSel(){delete difficulty;};
+	ScenSel();
+	~ScenSel();
 } ;
 class CPreGame
 {
@@ -239,7 +243,6 @@ public:
 	std::vector<Slider *> interested;
 	CMusicHandler * mush;
 	std::vector<HighButton *> btns;
-	CPreGameTextHandler * preth ;
 	SDL_Rect * currentMessage;
 	SDL_Surface * behindCurMes;
 	CDefHandler *ok, *cancel;
@@ -247,16 +250,19 @@ public:
 		mainMenu, newGame, loadGame, ScenarioList
 	} state;
 	struct menuItems {
+		menuItems();
+		~menuItems();
 		SDL_Surface * background, *bgAd;
 		CDefHandler *newGame, *loadGame, *highScores,*credits, *quit;
 		SDL_Rect lNewGame, lLoadGame, lHighScores, lCredits, lQuit;
 		ttt fNewGame, fLoadGame, fHighScores, fCredits, fQuit;
 		int highlighted;//0=none; 1=new game; 2=load game; 3=high score; 4=credits; 5=quit
-	} * ourMainMenu, * ourNewMenu;
+	} * ourMainMenu, * ourNewMenu, * ourLoadMenu;
 	ScenSel * ourScenSel;
 	Options * ourOptions;
 	std::string map; //selected map
 	CPreGame(); //c-tor
+	~CPreGame();//d-tor
 	std::string buttonText(int which);
 	menuItems * currentItems();
 	void(CPreGame::*handleOther)(SDL_Event&);
@@ -270,7 +276,9 @@ public:
 	void initOptions();
 	void showOptions();
 	void initNewMenu();
+	void initLoadMenu();
 	void showNewMenu();
+	void showLoadMenu();
 	void showMainMenu();
 	StartInfo runLoop(); // runs mainloop of PreGame
 	void initMainMenu(); //loads components for main menu

+ 5 - 0
client/Client.cpp

@@ -698,3 +698,8 @@ void CClient::close()
 	serv->close();
 	tlog3 << "Our socket has been closed.\n";
 }
+
+void CClient::save(const std::string & fname)
+{
+	*serv << ui16(98) << fname;
+}

+ 1 - 0
client/Client.h

@@ -48,6 +48,7 @@ public:
 	~CClient(void);
 
 	void close();
+	void save(const std::string & fname);
 	void process(int what);
 	void run();
 

+ 17 - 10
lib/Connection.cpp

@@ -3,6 +3,7 @@
 #include "Connection.h"
 #include <boost/asio.hpp>
 #include <boost/thread.hpp>
+#include <fstream>
 using namespace boost;
 using namespace boost::asio::ip;
 
@@ -143,18 +144,24 @@ void CConnection::close()
 		socket = NULL;
 	}
 }
-template <>
-void CConnection::saveSerializable<std::string>(const std::string &data)
+
+CSaveFile::CSaveFile( const std::string &fname )
+	:sfile(new std::ofstream(fname.c_str()))
 {
-	*this << ui32(data.size());
-	write(data.c_str(),data.size());
+	if(!(*sfile))
+	{
+		tlog1 << "Error: cannot open to write " << fname << std::endl;
+		sfile = NULL;
+	}
 }
 
-template <>
-void CConnection::loadSerializable<std::string>(std::string &data)
+CSaveFile::~CSaveFile()
 {
-	ui32 l;
-	*this >> l;
-	data.resize(l);
-	read((void*)data.c_str(),l);
+	delete sfile;
 }
+
+int CSaveFile::write( const void * data, unsigned size )
+{
+	sfile->write((char *)data,size);
+	return size;
+}

+ 175 - 159
lib/Connection.h

@@ -103,6 +103,79 @@ public:
 	template<class T>
 	COSer & operator&(T & t){
 		return * this->This() << t;
+	}	
+	
+
+
+	int write(const void * data, unsigned size);
+	template <typename T>
+	void savePrimitive(const T &data)
+	{
+		this->This()->write(&data,sizeof(data));
+	}
+	template <typename T>
+	void savePointer(const T &data)
+	{
+		*this << *data;
+	}
+	template <typename T>
+	void save(const T &data)
+	{
+		typedef 
+			//if
+			typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
+			mpl::identity<SavePrimitive<Serializer,T> >,
+			//else if
+			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
+			mpl::identity<SavePointer<Serializer,T> >,
+			//else if
+			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
+			mpl::identity<SaveSerializable<Serializer,T> >,
+			//else
+			mpl::identity<SaveWrong<Serializer,T> >
+			>
+			>
+			>::type typex;
+		typex::invoke(* this->This(), data);
+	}
+	template <typename T>
+	void saveSerializable(const T &data)
+	{
+		const_cast<T&>(data).serialize(*this,version);
+	}
+	template <typename T>
+	void saveSerializable(const std::vector<T> &data)
+	{
+		boost::uint32_t length = data.size();
+		*this << length;
+		for(ui32 i=0;i<length;i++)
+			*this << data[i];
+	}
+	template <typename T>
+	void saveSerializable(const std::set<T> &data)
+	{
+		std::set<T> &d = const_cast<std::set<T> &>(data);
+		boost::uint32_t length = d.size();
+		*this << length;
+		for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
+			*this << *i;
+	}
+	void saveSerializable(const std::string &data)
+	{
+		*this << ui32(data.size());
+		this->This()->write(data.c_str(),data.size());
+	}
+	template <typename T1, typename T2>
+	void saveSerializable(const std::pair<T1,T2> &data)
+	{
+		*this << data.first << data.second;
+	}
+	template <typename T1, typename T2>
+	void saveSerializable(const std::map<T1,T2> &data)
+	{
+		*this << ui32(data.size());
+		for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
+			*this << i->first << i->second;
 	}
 };
 template <typename Serializer> class DLL_EXPORT CISer
@@ -125,7 +198,94 @@ public:
 	template<class T>
 	CISer & operator&(T & t){
 		return * this->This() >> t;
+	}	
+
+	int write(const void * data, unsigned size);
+	template <typename T>
+	void load(T &data)
+	{
+		typedef 
+			//if
+			typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
+			mpl::identity<LoadPrimitive<Serializer,T> >,
+			//else if
+			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
+			mpl::identity<LoadPointer<Serializer,T> >,
+			//else if
+			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
+			mpl::identity<LoadSerializable<Serializer,T> >,
+			//else
+			mpl::identity<LoadWrong<Serializer,T> >
+			>
+			>
+			>::type typex;
+		typex::invoke(* this->This(), data);
+	}
+	template <typename T>
+	void loadPrimitive(T &data)
+	{
+		this->This()->read(&data,sizeof(data));
+	}
+	template <typename T>
+	void loadSerializable(T &data)
+	{
+		data.serialize(*this,version);
+	}	
+	template <typename T>
+	void loadPointer(T &data)
+	{
+		tlog5<<"Allocating memory for pointer!"<<std::endl;
+		typedef typename boost::remove_pointer<T>::type npT;
+		data = new npT;
+		*this >> *data;
+	}
+	template <typename T>
+	void loadSerializable(std::vector<T> &data)
+	{
+		boost::uint32_t length;
+		*this >> length;
+		data.resize(length);
+		for(ui32 i=0;i<length;i++)
+			*this >> data[i];
+	}
+	template <typename T>
+	void loadSerializable(std::set<T> &data)
+	{
+		boost::uint32_t length;
+		*this >> length;
+		T ins;
+		for(ui32 i=0;i<length;i++)
+		{
+			*this >> ins;
+			data.insert(ins);
+		}
+	}
+	template <typename T1, typename T2>
+	void loadSerializable(std::pair<T1,T2> &data)
+	{
+		*this >> data.first >> data.second;
+	}
+
+	template <typename T1, typename T2>
+	void loadSerializable(std::map<T1,T2> &data)
+	{
+		ui32 length;
+		*this >> length;
+		T1 t;
+		for(int i=0;i<length;i++)
+		{
+			*this >> t;
+			*this >> data[t];
+		}
+	}
+	void loadSerializable(std::string &data)
+	{
+		ui32 l;
+		*this >> l;
+		data.resize(l);
+		this->This()->read((void*)data.c_str(),l);
 	}
+
 };
 
 template<typename Ser,typename T>
@@ -195,165 +355,28 @@ struct LoadWrong
 };
 
 
+class DLL_EXPORT CSaveFile
+	: public COSer<CSaveFile>
+{
+	void dummyMagicFunction()
+	{
+		*this << std::string("This function makes stuff working.");
+	}
+public:
+	std::ofstream *sfile;
+	CSaveFile(const std::string &fname);
+	~CSaveFile();
+	int write(const void * data, unsigned size);
+};
+
 class DLL_EXPORT CConnection
 	:public CISer<CConnection>, public COSer<CConnection>
 {
-
-
 	std::ostream &out;
 	CConnection(void);
 	void init();
 public:
 	boost::mutex *rmx, *wmx; // read/write mutexes
-
-	template <typename T>
-	void savePrimitive(const T &data)
-	{
-		write(&data,sizeof(data));
-	}
-	template <typename T>
-	void loadPrimitive(T &data)
-	{
-		read(&data,sizeof(data));
-	}
-
-	
-	
-	template <typename T>
-	void saveSerializable(const T &data)
-	{
-		const_cast<T&>(data).serialize(*static_cast<COSer<CConnection>*>(this),version);
-	}
-	template <typename T>
-	void loadSerializable(T &data)
-	{
-		data.serialize(*static_cast<CISer<CConnection>*>(this),version);
-	}	
-	template <typename T>
-	void savePointer(const T &data)
-	{
-		*this << *data;
-	}
-	template <typename T>
-	void loadPointer(T &data)
-	{
-		tlog5<<"Allocating memory for pointer!"<<std::endl;
-		typedef typename boost::remove_pointer<T>::type npT;
-		data = new npT;
-		*this >> *data;
-	}
-	template <typename T>
-	void saveSerializable(const std::vector<T> &data)
-	{
-		boost::uint32_t length = data.size();
-		*this << length;
-		for(ui32 i=0;i<length;i++)
-			*this << data[i];
-	}
-	template <typename T>
-	void loadSerializable(std::vector<T> &data)
-	{
-		boost::uint32_t length;
-		*this >> length;
-		data.resize(length);
-		for(ui32 i=0;i<length;i++)
-			*this >> data[i];
-	}
-	
-	template <typename T>
-	void saveSerializable(const std::set<T> &data)
-	{
-		std::set<T> &d = const_cast<std::set<T> &>(data);
-		boost::uint32_t length = d.size();
-		*this << length;
-		for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
-			*this << *i;
-	}
-	template <typename T>
-	void loadSerializable(std::set<T> &data)
-	{
-		boost::uint32_t length;
-		*this >> length;
-		T ins;
-		for(ui32 i=0;i<length;i++)
-		{
-			*this >> ins;
-			data.insert(ins);
-		}
-	}
-	
-	template <typename T1, typename T2>
-	void saveSerializable(const std::pair<T1,T2> &data)
-	{
-		*this << data.first << data.second;
-	}
-	template <typename T1, typename T2>
-	void loadSerializable(std::pair<T1,T2> &data)
-	{
-		*this >> data.first >> data.second;
-	}
-	
-	template <typename T1, typename T2>
-	void saveSerializable(const std::map<T1,T2> &data)
-	{
-		*this << ui32(data.size());
-		for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
-			*this << i->first << i->second;
-	}
-	template <typename T1, typename T2>
-	void loadSerializable(std::map<T1,T2> &data)
-	{
-		ui32 length;
-		*this >> length;
-		T1 t;
-		for(int i=0;i<length;i++)
-		{
-			*this >> t;
-			*this >> data[t];
-		}
-	}
-	template <typename T>
-	void save(const T &data)
-	{
-		typedef 
-			//if
-			typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
-				mpl::identity<SavePrimitive<CConnection,T> >,
-			//else if
-			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
-				mpl::identity<SavePointer<CConnection,T> >,
-			//else if
-			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
-				mpl::identity<SaveSerializable<CConnection,T> >,
-			//else
-				mpl::identity<SaveWrong<CConnection,T> >
-			>
-			>
-			>::type typex;
-		typex::invoke(*this, data);
-	}
-
-	template <typename T>
-	void load(T &data)
-	{
-		typedef 
-			//if
-			typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
-				mpl::identity<LoadPrimitive<CConnection,T> >,
-			//else if
-			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
-				mpl::identity<LoadPointer<CConnection,T> >,
-			//else if
-			typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
-				mpl::identity<LoadSerializable<CConnection,T> >,
-			//else
-				mpl::identity<LoadWrong<CConnection,T> >
-			>
-			>
-			>::type typex;
-		typex::invoke(*this, data);
-	}
-
 	boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp>  > * socket;
 	bool logging;
 	bool connected;
@@ -374,11 +397,4 @@ public:
 	int readLine(void * data, unsigned maxSize);
 	void close();
 	~CConnection(void);
-};
-
-template<> DLL_EXPORT 
-void CConnection::saveSerializable<std::string>(const std::string &data);
-template <>DLL_EXPORT 
-void CConnection::loadSerializable<std::string>(std::string &data);
-
-
+};

+ 4 - 0
map.h

@@ -505,5 +505,9 @@ struct DLL_EXPORT Mapa
 	Mapa(std::string filename); //creates map structure from .h3m file
 	CGHeroInstance * getHero(int ID, int mode=0);
 	bool isInTheMap(int3 pos);
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		//TODO: write
+	}
 };
 #endif //MAPD_H

+ 9 - 0
server/CGameHandler.cpp

@@ -407,6 +407,15 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 			bool blockvis = false;
 			switch(pom)
 			{
+			case 98:
+				{
+					std::string fname;
+					c >> fname;
+					CSaveFile save(fname);
+					save << this;
+					//save << this;
+					break;
+				}
 			case 99: //end!
 				{
 					tlog0 << "We have been requested to close.\n";

+ 14 - 0
server/CGameHandler.h

@@ -24,7 +24,12 @@ struct PlayerStatus
 {
 	bool makingTurn, engagedIntoBattle;
 	std::set<ui32> queries;
+
 	PlayerStatus():makingTurn(false),engagedIntoBattle(false){};
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & makingTurn & engagedIntoBattle & queries;
+	}
 };
 class PlayerStatuses
 {
@@ -32,6 +37,7 @@ public:
 	std::map<ui8,PlayerStatus> players;
 	boost::mutex mx;
 	boost::condition_variable cv; //notifies when any changes are made
+
 	void addPlayer(ui8 player);
 	PlayerStatus operator[](ui8 player);
 	bool hasQueries(ui8 player);
@@ -39,6 +45,10 @@ public:
 	void setFlag(ui8 player, bool PlayerStatus::*flag, bool val);
 	void addQuery(ui8 player, ui32 id);
 	void removeQuery(ui8 player, ui32 id);
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & players;
+	}
 };
 class CGameHandler
 {
@@ -69,6 +79,10 @@ public:
 	~CGameHandler(void);
 	void init(StartInfo *si, int Seed);
 	void handleConnection(std::set<int> players, CConnection &c);
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & QID & gs & cppscripts & states;
+	}
 	template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
 	{
 		gsm.lock();