فهرست منبع

Added some kind of simple chatting functionality through console. Implemented several WoG cheats equivalents:
* woggaladriel -> vcmiainur
* wogoliphaunt -> vcminoldor
* wogshadowfax -> vcminahar
* wogeyeofsauron -> vcmieagles
* wogisengard -> vcmiformenos
* wogsaruman -> vcmiistari
* wogpathofthedead -> vcmiangband

Minor changes.

Michał W. Urbańczyk 17 سال پیش
والد
کامیت
2d01e00284
15فایلهای تغییر یافته به همراه283 افزوده شده و 33 حذف شده
  1. 3 3
      CAdvmapInterface.cpp
  2. 2 2
      CAdvmapInterface.h
  3. 5 0
      CCallback.cpp
  4. 2 0
      CCallback.h
  5. 4 2
      CGameInterface.h
  6. 21 0
      CGameState.cpp
  7. 2 1
      CGameState.h
  8. 9 3
      CMT.cpp
  9. 42 13
      CPlayerInterface.cpp
  10. 4 2
      CPlayerInterface.h
  11. 45 2
      client/Client.cpp
  12. 5 3
      client/Client.h
  13. 31 0
      lib/NetPacks.h
  14. 107 1
      server/CGameHandler.cpp
  15. 1 1
      server/CVCMIServer.cpp

+ 3 - 3
CAdvmapInterface.cpp

@@ -272,7 +272,7 @@ void CMinimap::deactivate()
 	ClickableR::deactivate();
 	Hoverable::deactivate();
 }
-void CMinimap::showTile(int3 pos)
+void CMinimap::showTile(const int3 &pos)
 {
 	int mw = map[0]->w, mh = map[0]->h;
 	double wo = ((double)mw)/CGI->mh->sizes.x, ho = ((double)mh)/CGI->mh->sizes.y;
@@ -282,11 +282,10 @@ void CMinimap::showTile(int3 pos)
 		{
 			if ((pos.x*wo+ii<this->pos.w) && (pos.y*ho+jj<this->pos.h))
 				CSDL_Ext::SDL_PutPixel(FoW[pos.z],pos.x*wo+ii,pos.y*ho+jj,0,0,0,0,0);
-
 		}
 	}
 }
-void CMinimap::hideTile(int3 pos)
+void CMinimap::hideTile(const int3 &pos)
 {
 }
 CTerrainRect::CTerrainRect():currentPath(NULL)
@@ -1331,6 +1330,7 @@ int3 CAdvMapInt::verifyPos(int3 ver)
 
 void CAdvMapInt::select(const CArmedInstance *sel )
 {
+	LOCPLINT->cb->setSelection(sel);
 	centerOn(sel->pos);
 	selection = sel;
 	if(sel->ID==98)

+ 2 - 2
CAdvmapInterface.h

@@ -37,8 +37,8 @@ public:
 	void mouseMoved (const SDL_MouseMotionEvent & sEvent);
 	void activate(); // makes button active
 	void deactivate(); // makes button inactive (but don't deletes)
-	void hideTile(int3 pos); //puts FoW
-	void showTile(int3 pos); //removes FoW
+	void hideTile(const int3 &pos); //puts FoW
+	void showTile(const int3 &pos); //removes FoW
 };
 class CTerrainRect
 	:  public ClickableL, public ClickableR, public Hoverable, public virtual CIntObject, public KeyInterested,

+ 5 - 0
CCallback.cpp

@@ -622,4 +622,9 @@ void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
 {
 	const_cast<CGHeroInstance*>(hero)->army.formation = tight;
 	*cl->serv << ui16(512) << hero->id << ui8(tight);
+}
+
+void CCallback::setSelection(const CArmedInstance * obj)
+{
+	*cl->serv << ui16(514) << obj->id;
 }

+ 2 - 0
CCallback.h

@@ -43,6 +43,7 @@ public:
 	virtual void buyArtifact(const CGHeroInstance *hero, int aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
 	virtual void trade(int mode, int id1, int id2, int val1)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
 	virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
+	virtual void setSelection(const CArmedInstance * obj)=0;
 
 //get info
 	virtual bool verifyPath(CPath * path, bool blockSea)const =0;
@@ -125,6 +126,7 @@ public:
 	void buyArtifact(const CGHeroInstance *hero, int aid);
 	void trade(int mode, int id1, int id2, int val1);
 	void setFormation(const CGHeroInstance * hero, bool tight);
+	void setSelection(const CArmedInstance * obj);
 
 //get info
 	bool verifyPath(CPath * path, bool blockSea) const;

+ 4 - 2
CGameInterface.h

@@ -55,14 +55,16 @@ public:
 	virtual void heroKilled(const CGHeroInstance*){};
 	virtual void heroMoved(const HeroMoveDetails & details){};
 	virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val){};
+	virtual void heroManaPointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after spell casts
+	virtual void heroMovePointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after movement
 	virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
 	virtual void init(ICallback * CB){};
 	virtual void receivedResource(int type, int val){};
 	virtual void showInfoDialog(std::string &text, const std::vector<Component*> &components){};
 	virtual void showSelDialog(std::string &text, const std::vector<Component*> &components, ui32 askID){};
 	virtual void showYesNoDialog(std::string &text, const std::vector<Component*> &components, ui32 askID){};
-	virtual void tileHidden(int3 pos){};
-	virtual void tileRevealed(int3 pos){};
+	virtual void tileHidden(const std::set<int3> &pos){};
+	virtual void tileRevealed(const std::set<int3> &pos){};
 	virtual void yourTurn(){};
 	virtual void availableCreaturesChanged(const CGTownInstance *town){};
 

+ 21 - 0
CGameState.cpp

@@ -407,6 +407,27 @@ void CGameState::applyNL(IPack * pack)
 					hero->spells.erase(sid);
 			break;
 		}
+	case 110:
+		{
+			SetMana *rh = static_cast<SetMana*>(pack);
+			CGHeroInstance *hero = getHero(rh->hid);
+			hero->mana = rh->val;
+			break;
+		}
+	case 111:
+		{
+			SetMovePoints *rh = static_cast<SetMovePoints*>(pack);
+			CGHeroInstance *hero = getHero(rh->hid);
+			hero->movement = rh->val;
+			break;
+		}
+	case 112:
+		{
+			FoWChange *rh = static_cast<FoWChange*>(pack);
+			BOOST_FOREACH(int3 t, rh->tiles)
+				players[rh->player].fogOfWarMap[t.x][t.y][t.z] = rh->mode;
+			break;
+		}
 	case 500:
 		{
 			RemoveObject *rh = static_cast<RemoveObject*>(pack);

+ 2 - 1
CGameState.h

@@ -42,11 +42,12 @@ struct DLL_EXPORT PlayerState
 {
 public:
 	ui8 color, serial;
+	ui32 currentSelection; //id of hero/town, 0xffffffff if none
 	std::vector<std::vector<std::vector<ui8> > >  fogOfWarMap; //true - visible, false - hidden
 	std::vector<si32> resources;
 	std::vector<CGHeroInstance *> heroes;
 	std::vector<CGTownInstance *> towns;
-	PlayerState():color(-1){};
+	PlayerState():color(-1),currentSelection(0xffffffff){};
 };
 
 struct DLL_EXPORT BattleInfo

+ 9 - 3
CMT.cpp

@@ -52,13 +52,14 @@ std::queue<SDL_Event> events;
 boost::mutex eventsM;
 TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
 namespace intpr = boost::interprocess;
-void processCommand(const std::string &message);
+void processCommand(const std::string &message, CClient *&client);
 #ifndef __GNUC__
 int _tmain(int argc, _TCHAR* argv[])
 #else
 int main(int argc, char** argv)
 #endif
 { 
+	CClient *client = NULL;
 	boost::thread *console = NULL;
 	if(argc>2)
 	{
@@ -68,7 +69,7 @@ int main(int argc, char** argv)
 	{
 		logfile = new std::ofstream("VCMI_Client_log.txt");
 		::console = new CConsoleHandler;
-		*::console->cb = &processCommand;
+		*::console->cb = boost::bind(processCommand,_1,boost::ref(client));
 		console = new boost::thread(boost::bind(&CConsoleHandler::run,::console));
 	}
 	tlog0 << "\tConsole and logifle ready!" << std::endl;
@@ -212,6 +213,7 @@ int main(int argc, char** argv)
 		}
 		THC tlog0<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl;
 		CClient cl(c,options);
+		client = &cl;
 		boost::thread t(boost::bind(&CClient::run,&cl));
 		SDL_Event ev;
 		while(1) //main SDL events loop
@@ -239,7 +241,7 @@ int main(int argc, char** argv)
 	}
 }
 
-void processCommand(const std::string &message)
+void processCommand(const std::string &message, CClient *&client)
 {
 	std::istringstream readed;
 	readed.str(message);
@@ -295,4 +297,8 @@ void processCommand(const std::string &message)
 		}
 		tlog0<<"\rExtracting done :)\n";
 	}
+	else if(client && client->serv && client->serv->connected) //send to server
+	{
+		*client->serv << ui16(513) << message;
+	}
 }

+ 42 - 13
CPlayerInterface.cpp

@@ -37,6 +37,12 @@
 #include <cmath>
 #include <queue>
 #include <sstream>
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
 using namespace boost::assign;
 using namespace CSDL_Ext;
 
@@ -1905,11 +1911,24 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
 		adventureInt->infoBar.draw();
 	return;
 }
-
+void CPlayerInterface::heroManaPointsChanged(const CGHeroInstance * hero)
+{
+	boost::unique_lock<boost::recursive_mutex> un(*pim);
+	SDL_FreeSurface(graphics->heroWins[hero->subID]);//TODO: moznaby zmieniac jedynie fragment bitmapy zwiazany z dana umiejetnoscia
+	graphics->heroWins[hero->subID] = infoWin(hero); //a nie przerysowywac calosc. Troche roboty, obecnie chyba nie wartej swieczki.
+	if (adventureInt->selection == hero)
+		adventureInt->infoBar.draw();
+}
+void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
+{
+	boost::unique_lock<boost::recursive_mutex> un(*pim);
+	if(adventureInt == curint)
+		adventureInt->heroList.draw();
+}
 void CPlayerInterface::receivedResource(int type, int val)
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
-	if(!curint->subInt)
+	if(curint==adventureInt || curint==castleInt)
 		adventureInt->resdatabar.draw();
 }
 
@@ -1987,8 +2006,8 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
 			SDL_FreeSurface(graphics->heroWins[hh->subID]);
 			graphics->heroWins[hh->subID] = infoWin(hh);
 		}
-		CHeroWindow * hw = dynamic_cast<CHeroWindow *>(curint->subInt);
-		if(hw)
+		CHeroWindow * hw = adventureInt->heroWindow;
+		if(hw == curint->subInt)
 		{
 			hw->garInt->recreateSlots();
 			hw->garInt->show();
@@ -2019,6 +2038,8 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
 			LOCPLINT->castleInt->garr->recreateSlots();
 		}
 	}
+	if(curint == adventureInt)
+		adventureInt->infoBar.draw();
 }
 void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID, int what) //what: 1 - built, 2 - demolished
 {
@@ -2068,23 +2089,25 @@ void CPlayerInterface::battleNewRound(int round) //called at the beggining of ea
 
 void CPlayerInterface::actionStarted(const BattleAction* action)
 {
+	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	curAction = action;
 	if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))
 		&& battleInt->creAnims[action->stackNumber]->framesInGroup(20)
 		)
 	{
 		battleInt->creAnims[action->stackNumber]->setType(20);
-	if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //deactivating interface when move is started
+	}
+	//if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //deactivating interface when move is started
 	{
 		battleInt->deactivate();
 	}
 }
-}
 
 void CPlayerInterface::actionFinished(const BattleAction* action)
 {
+	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	curAction = NULL;
-	if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
+	//if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
 	{
 		battleInt->activate();
 	}
@@ -2238,15 +2261,21 @@ void CPlayerInterface::removeObjToBlit(IShowable* obj)
 		(std::find(objsToBlit.begin(),objsToBlit.end(),obj));
 	//delete obj;
 }
-void CPlayerInterface::tileRevealed(int3 pos)
+void CPlayerInterface::tileRevealed(const std::set<int3> &pos)
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
-	adventureInt->minimap.showTile(pos);
+	for(std::set<int3>::const_iterator i=pos.begin(); i!=pos.end();i++)
+		adventureInt->minimap.showTile(*i);
+	if(curint == adventureInt)
+		adventureInt->minimap.draw();
 }
-void CPlayerInterface::tileHidden(int3 pos)
+void CPlayerInterface::tileHidden(const std::set<int3> &pos)
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
-	adventureInt->minimap.hideTile(pos);
+	for(std::set<int3>::const_iterator i=pos.begin(); i!=pos.end();i++)
+		adventureInt->minimap.hideTile(*i);
+	if(curint == adventureInt)
+		adventureInt->minimap.draw();
 }
 void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
 {
@@ -2440,8 +2469,8 @@ void CHeroList::select(int which)
 	LOCPLINT->adventureInt->terrain.currentPath = items[which].second;
 	draw();
 	LOCPLINT->adventureInt->townList.draw();
-
 	LOCPLINT->adventureInt->infoBar.draw(NULL);
+	LOCPLINT->cb->setSelection(items[which].first);
 }
 void CHeroList::clickLeft(tribool down)
 {
@@ -2592,7 +2621,7 @@ void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
 {
 	int ser = LOCPLINT->cb->getHeroSerial(which);
 	ser -= from;
-	int pom = (which->movement)/100;
+	int pom = std::min((which->movement)/100,(int)mobile->ourImages.size()-1);
 	blitAt(mobile->ourImages[pom].bitmap,posmobx,posmoby+ser*32); //move point
 }
 void CHeroList::draw()

+ 4 - 2
CPlayerInterface.h

@@ -353,13 +353,15 @@ public:
 	void heroKilled(const CGHeroInstance* hero);
 	void heroMoved(const HeroMoveDetails & details);
 	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
+	void heroManaPointsChanged(const CGHeroInstance * hero);
+	void heroMovePointsChanged(const CGHeroInstance * hero);
 	void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
 	void receivedResource(int type, int val);
 	void showInfoDialog(std::string &text, const std::vector<Component*> &components);
 	void showSelDialog(std::string &text, const std::vector<Component*> &components, ui32 askID);
 	void showYesNoDialog(std::string &text, const std::vector<Component*> &components, ui32 askID);
-	void tileHidden(int3 pos);
-	void tileRevealed(int3 pos);
+	void tileHidden(const std::set<int3> &pos);
+	void tileRevealed(const std::set<int3> &pos);
 	void yourTurn();
 	void availableCreaturesChanged(const CGTownInstance *town);
 	//for battles

+ 45 - 2
client/Client.cpp

@@ -264,6 +264,42 @@ void CClient::process(int what)
 			gs->apply(&vc);
 			break;
 		}
+	case 110:
+		{
+			SetMana sm;
+			*serv >> sm;
+			tlog5 << "Setting mana value of hero "<<sm.hid<<" to "<<sm.val<<std::endl;
+			gs->apply(&sm);
+			CGHeroInstance *h = gs->getHero(sm.hid);
+			if(vstd::contains(playerint,h->tempOwner))
+				playerint[h->tempOwner]->heroManaPointsChanged(h);
+			break;
+		}
+	case 111:
+		{
+			SetMovePoints smp;
+			*serv >> smp;
+			tlog5 << "Setting movement points of hero "<<smp.hid<<" to "<<smp.val<<std::endl;
+			gs->apply(&smp);
+			CGHeroInstance *h = gs->getHero(smp.hid);
+			if(vstd::contains(playerint,h->tempOwner))
+				playerint[h->tempOwner]->heroMovePointsChanged(h);
+			break;
+		}
+	case 112:
+		{
+			FoWChange fc;
+			*serv >> fc;
+			tlog5 << "Changing FoW of player "<<(int)fc.player<<std::endl;
+			gs->apply(&fc);
+			if(!vstd::contains(playerint,fc.player))
+				break;
+			if(fc.mode)
+				playerint[fc.player]->tileRevealed(fc.tiles);
+			else
+				playerint[fc.player]->tileHidden(fc.tiles);
+			break;
+		}
 	case 500:
 		{
 			RemoveObject rh;
@@ -299,8 +335,7 @@ void CClient::process(int what)
 
 			if(playerint[player])
 			{
-				for(std::set<int3>::iterator i=th->fowRevealed.begin(); i != th->fowRevealed.end(); i++)
-					playerint[player]->tileRevealed(*i);
+				playerint[player]->tileRevealed(th->fowRevealed);
 				//std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),boost::bind(&CGameInterface::tileRevealed,playerint[player],_1));
 			}
 
@@ -395,6 +430,14 @@ void CClient::process(int what)
 				playerint[t->tempOwner]->heroArtifactSetChanged(t);
 			break;
 		}
+	case 513:
+		{
+			ui8 color;
+			std::string message;
+			*serv >> color >> message;
+			tlog4 << "Player "<<(int)color<<" sends a message: " << message << std::endl;
+			break;
+		}
 	case 1001:
 		{
 			SetObjectProperty sop;

+ 5 - 3
client/Client.h

@@ -6,7 +6,8 @@ class CGameState;
 class CGameInterface;
 class CConnection;
 class CCallback;
-
+class CClient;
+void processCommand(const std::string &message, CClient *&client);
 namespace boost
 {
 	class mutex;
@@ -50,6 +51,7 @@ public:
 	void process(int what);
 	void run();
 
-	friend class CCallback;
-	friend class CScriptCallback;
+	friend class CCallback; //handling players actions
+	friend class CScriptCallback; //for objects scripts
+	friend void processCommand(const std::string &message, CClient *&client); //handling console
 };

+ 31 - 0
lib/NetPacks.h

@@ -109,6 +109,37 @@ struct ChangeSpells : public CPack<ChangeSpells> //109
 		h & learn & hid & spells;
 	}
 }; 
+
+struct SetMana : public CPack<SetMana> //110
+{
+	SetMana(){type = 110;};
+	ui32 hid, val;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & val & hid;
+	}
+}; 
+struct SetMovePoints : public CPack<SetMovePoints> //111
+{
+	SetMovePoints(){type = 111;};
+	ui32 hid, val;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & val & hid;
+	}
+}; 
+struct FoWChange : public CPack<FoWChange> //112
+{
+	FoWChange(){type = 112;};
+	std::set<int3> tiles;
+	ui8 player, mode; //mode==0 - hide, mode==1 - reveal
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & tiles & player;
+	}
+}; 
 struct RemoveObject : public CPack<RemoveObject> //500
 {
 	RemoveObject(){type = 500;};

+ 107 - 1
server/CGameHandler.cpp

@@ -899,6 +899,112 @@ upgend:
 					gs->getHero(hid)->army.formation = formation;
 					break;
 				}
+			case 513:
+				{
+					std::string message;
+					c >> message;
+					bool cheated=true;
+					sendDataToClients(ui16(513));
+					sendDataToClients(ui8(*players.begin()));
+					sendDataToClients(message);
+					if(message == "vcmiistari") //give all spells and 999 mana
+					{
+						SetMana sm;
+						ChangeSpells cs;
+						cs.learn = 1;
+						for(int i=0;i<VLC->spellh->spells.size();i++)
+							cs.spells.insert(i);
+						sm.hid = cs.hid = gs->players[*players.begin()].currentSelection;
+						sm.val = 999;
+						if(gs->getHero(cs.hid))
+						{
+							sendAndApply(&cs);
+							sendAndApply(&sm);
+						}
+					}
+					else if(message == "vcmiainur") //gives 5 archangels into each slot
+					{
+						SetGarrisons sg;
+						CGHeroInstance *hero = gs->getHero(gs->players[*players.begin()].currentSelection);
+						if(!hero) break;
+						sg.garrs[hero->id] = hero->army;
+						for(int i=0;i<7;i++)
+							if(!vstd::contains(sg.garrs[hero->id].slots,i))
+								sg.garrs[hero->id].slots[i] = std::pair<ui32,si32>(13,5);
+						sendAndApply(&sg);
+					}
+					else if(message == "vcmiangband") //gives 10 black knightinto each slot
+					{
+						SetGarrisons sg;
+						CGHeroInstance *hero = gs->getHero(gs->players[*players.begin()].currentSelection);
+						if(!hero) break;
+						sg.garrs[hero->id] = hero->army;
+						for(int i=0;i<7;i++)
+							if(!vstd::contains(sg.garrs[hero->id].slots,i))
+								sg.garrs[hero->id].slots[i] = std::pair<ui32,si32>(66,10);
+						sendAndApply(&sg);
+					}
+					else if(message == "vcminoldor") //all war machines
+					{
+						CGHeroInstance *hero = gs->getHero(gs->players[*players.begin()].currentSelection);
+						if(!hero) break;
+						SetHeroArtifacts sha;
+						sha.hid = hero->id;
+						sha.artifacts = hero->artifacts;
+						sha.artifWorn = hero->artifWorn;
+						sha.artifWorn[13] = 4;
+						sha.artifWorn[14] = 5;
+						sha.artifWorn[15] = 6;
+						sendAndApply(&sha);
+					}
+					else if(message == "vcminahar") //1000000 movement points
+					{
+						CGHeroInstance *hero = gs->getHero(gs->players[*players.begin()].currentSelection);
+						if(!hero) break;
+						SetMovePoints smp;
+						smp.hid = hero->id;
+						smp.val = 1000000;
+						sendAndApply(&smp);
+					}
+					else if(message == "vcmiformenos") //give resources
+					{
+						SetResources sr;
+						sr.player = *players.begin();
+						sr.res = gs->players[sr.player].resources;
+						for(int i=0;i<7;i++)
+							sr.res[i] += 100;
+						sr.res[6] += 19900;
+						sendAndApply(&sr);
+					}
+					else if(message == "vcmieagles") //reveal FoW
+					{
+						FoWChange fc;
+						fc.player = *players.begin();
+						for(int i=0;i<gs->map->width;i++)
+							for(int j=0;j<gs->map->height;j++)
+								for(int k=0;k<gs->map->twoLevel+1;k++)
+									if(!gs->players[fc.player].fogOfWarMap[i][j][k])
+										fc.tiles.insert(int3(i,j,k));
+						sendAndApply(&fc);
+					}
+					else
+						cheated = false;
+					if(cheated)
+					{
+						message = "CHEATER!!!";
+						sendDataToClients(ui16(513));
+						sendDataToClients(ui8(*players.begin()));
+						sendDataToClients(message);
+					}
+					break;
+				}
+			case 514:
+				{
+					ui32 id;
+					c >> id;
+					gs->players[*players.begin()].currentSelection = id;
+					break;
+				}
 			case 2001:
 				{
 					ui32 qid, answer;
@@ -1269,7 +1375,7 @@ void CGameHandler::newTurn()
 			NewTurn::Hero hth;
 			hth.id = h->id;
 			hth.move = valMovePoints(h, true); //TODO: check if hero is really on the land
-			hth.mana = std::min(h->mana+1+h->getSecSkillLevel(8), h->manaLimit()); //hero regains 1 mana point + mysticism lvel
+			hth.mana = std::max(h->mana,std::min(h->mana+1+h->getSecSkillLevel(8), h->manaLimit())); //hero regains 1 mana point + mysticism lvel
 			n.heroes.insert(hth);
 			
 			switch(h->getSecSkillLevel(13)) //handle estates - give gols

+ 1 - 1
server/CVCMIServer.cpp

@@ -156,7 +156,7 @@ int main(int argc, char** argv)
 {
 	logfile = new std::ofstream("VCMI_Server_log.txt");
 	console = new CConsoleHandler;
-	boost::thread t(boost::bind(&CConsoleHandler::run,::console));
+	//boost::thread t(boost::bind(&CConsoleHandler::run,::console));
 	if(argc > 1)
 	{
 #ifdef _MSC_VER