2
0
Эх сурвалжийг харах

Fixed issues reported by Zamolxis:
* dismiss Hero works blocked in the castles
* the backpack scrollable arrows aren't available (yellow, clickable) even when backpack is empty.
* added missing info texts for buttons in hero window (and added functionality of enable tactic formations button)
* can select (single click) and enter castle (double click) from the map. Same for hero.
* Hero gets automatically selected after End Turn
* Hero is automatically selected when exiting town
* In Garrison or Hero army: units are selected when we first click on them
Fixed (at least partially) also a problem with disappearing path

Michał W. Urbańczyk 17 жил өмнө
parent
commit
7722d058f0

+ 51 - 7
AdventureMapButton.cpp

@@ -20,11 +20,17 @@ AdventureMapButton::AdventureMapButton ()
 //{
 //	init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ);
 //}
-AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, CFunctionList<void()> Callback, int x, int y, std::string defName, bool activ,  std::vector<std::string> * add, bool playerColoredButton )
+AdventureMapButton::AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, bool activ,  std::vector<std::string> * add, bool playerColoredButton )
 {
-	init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ);
+	std::map<int,std::string> pom;
+	pom[0] = Name;
+	init(Callback, pom, HelpBox, playerColoredButton, defName, add, x, y, activ);
 }
 
+AdventureMapButton::AdventureMapButton( const std::map<int,std::string> &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, bool activ/*=false*/, std::vector<std::string> * add /*= NULL*/, bool playerColoredButton /*= false */ )
+{
+	init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ);
+}
 
 void AdventureMapButton::clickLeft (tribool down)
 {
@@ -62,11 +68,14 @@ void AdventureMapButton::clickRight (tribool down)
 void AdventureMapButton::hover (bool on)
 {
 	Hoverable::hover(on);
-	if(name.size()) //if there is no name, there is nohing to display also
+	std::string *name = (vstd::contains(hoverTexts,state)) 
+							? (&hoverTexts[state]) 
+							: (vstd::contains(hoverTexts,0) ? (&hoverTexts[0]) : NULL);
+	if(name) //if there is no name, there is nohing to display also
 	{
 		if (on)
-			LOCPLINT->statusbar->print(name);
-		else if (LOCPLINT->statusbar->getCurrent()==name)
+			LOCPLINT->statusbar->print(*name);
+		else if ( LOCPLINT->statusbar->getCurrent()==(*name) )
 			LOCPLINT->statusbar->clear();
 	}
 }
@@ -96,7 +105,7 @@ void AdventureMapButton::deactivate()
 	KeyInterested::deactivate();
 }
 
-void AdventureMapButton::init( CFunctionList<void()> Callback, std::string Name, std::string HelpBox, bool playerColoredButton, std::string defName, std::vector<std::string> * add, int x, int y, bool activ )
+void AdventureMapButton::init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ )
 {
 	callback = Callback;
 	blocked = actOnDown = false;
@@ -105,7 +114,7 @@ void AdventureMapButton::init( CFunctionList<void()> Callback, std::string Name,
 	active=false;
 	ourObj=NULL;
 	state=0;
-	name=Name;
+	hoverTexts = Name;
 	helpBox=HelpBox;
 	colorChange = playerColoredButton;
 	int est = LOCPLINT->playerID;
@@ -152,6 +161,41 @@ void AdventureMapButton::block( bool on )
 	show();
 }
 
+void CHighlightableButton::clickLeft( tribool down )
+{
+	if(blocked)
+		return;
+	if (down)
+		state=1;
+	else
+		state = selected ? 3 : 0;
+	show();
+	if (pressedL && (down==false))
+	{
+		pressedL=state;
+		selected = !selected;
+		state = selected ? 3 : 0;
+		if(selected)
+			callback();
+		else 
+			callback2();
+		if(hoverTexts.size()>1)
+		{
+			hover(false);
+			hover(true);
+		}
+	}
+	else
+	{
+		pressedL=state;
+	}
+} 
+
+CHighlightableButton::CHighlightableButton( const CFunctionList<void()> &onSelect, const CFunctionList<void()> &onDeselect, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ )
+{
+	init(onSelect,Name,HelpBox,playerColoredButton,defName,add,x,y,activ);
+	callback2 = onDeselect;
+}
 void CSlider::sliderClicked()
 {
 	if(!moving)

+ 17 - 6
AdventureMapButton.h

@@ -6,7 +6,7 @@ class AdventureMapButton
 	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
 {
 public:
-	std::string name; //for status bar 
+	std::map<int,std::string> hoverTexts; //state -> text for statusbar
 	std::string helpBox; //for right-click help
 	char key; //key shortcut
 	CFunctionList<void()> callback;
@@ -14,18 +14,29 @@ public:
 		actOnDown; //runs when mouse is pressed down over it, not when up
 
 	void clickRight (tribool down);
-	void clickLeft (tribool down);
-	virtual void hover (bool on);
-	virtual void block(bool on); //if button is blocked then it'll change it's graphic to inactive (offset==2) and won't react on l-clicks
+	virtual void clickLeft (tribool down);
+	void hover (bool on);
+	void block(bool on); //if button is blocked then it'll change it's graphic to inactive (offset==2) and won't react on l-clicks
 	void keyPressed (SDL_KeyboardEvent & key);
 	void activate(); // makes button active
 	void deactivate(); // makes button inactive (but doesn't delete)
 
 	AdventureMapButton(); //c-tor
-	AdventureMapButton( std::string Name, std::string HelpBox, CFunctionList<void()> Callback, int x, int y, std::string defName, bool activ=false,  std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
+	AdventureMapButton( const std::map<int,std::string> &, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, bool activ=false,  std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
+	AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, bool activ=false,  std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
 	//AdventureMapButton( std::string Name, std::string HelpBox, boost::function<void()> Callback, int x, int y, std::string defName, bool activ=false,  std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
 
-	void init( CFunctionList<void()> Callback, std::string Name, std::string HelpBox, bool playerColoredButton, std::string defName, std::vector<std::string> * add, int x, int y, bool activ );
+	void init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ );
+};
+
+class CHighlightableButton 
+	: public AdventureMapButton
+{
+public:
+	CHighlightableButton(const CFunctionList<void()> &onSelect, const CFunctionList<void()> &onDeselect, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ );
+	bool selected;
+	CFunctionList<void()> callback2; //when disselecting
+	void clickLeft (tribool down);
 };
 
 

+ 172 - 61
CAdvmapInterface.cpp

@@ -3,6 +3,7 @@
 #include "client/CBitmapHandler.h"
 #include "CPlayerInterface.h"
 #include "CCastleInterface.h"
+#include "CCursorHandler.h"
 #include "hch/CPreGameTextHandler.h"
 #include "hch/CGeneralTextHandler.h"
 #include "hch/CDefHandler.h"
@@ -291,18 +292,56 @@ void CTerrainRect::clickLeft(tribool down)
 {
 	if ((down==false) || indeterminate(down))
 		return;
-	if (LOCPLINT->adventureInt->selection.type != HEROI_TYPE)
+	int3 mp = whichTileIsIt();
+	if ((mp.x<0) || (mp.y<0))
+		return;
+	std::vector < const CGObjectInstance * > objs = LOCPLINT->cb->getBlockingObjs(mp);
+	if (LOCPLINT->adventureInt->selection->ID != HEROI_TYPE)
 	{
 		if (currentPath)
 		{
+			std::cout<<"Warning: Lost path?" << std::endl;
 			delete currentPath;
 			currentPath = NULL;
 		}
+		for(int i=0; i<objs.size();i++)
+		{
+			if(objs[i]->ID == 98) //town
+			{
+				if(LOCPLINT->adventureInt->selection == (objs[i]))
+				{
+					LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(objs[i]));
+				}
+				else
+				{
+					LOCPLINT->adventureInt->select(static_cast<const CArmedInstance*>(objs[i]));
+					return;
+				}
+			}
+			else if(objs[i]->ID == 34)
+			{
+				LOCPLINT->adventureInt->select(static_cast<const CArmedInstance*>(objs[i]));
+				return;
+			}
+		}
 		return;
 	}
-	int3 mp = whichTileIsIt();
-	if ((mp.x<0) || (mp.y<0))
-		return;
+	else
+	{
+		for(int i=0; i<objs.size();i++)
+		{
+			if(objs[i]->ID == 98) //town
+			{
+				LOCPLINT->adventureInt->select(static_cast<const CArmedInstance*>(objs[i]));
+				return;
+			}
+			else if(objs[i]->ID == 34 && LOCPLINT->adventureInt->selection == (objs[i]))
+			{
+				LOCPLINT->openHeroWindow(static_cast<const CGHeroInstance*>(objs[i]));
+				return;
+			}
+		}
+	}
 	bool mres =true;
 	if (currentPath)
 	{
@@ -310,45 +349,38 @@ void CTerrainRect::clickLeft(tribool down)
 		{ //move
 			CPath sended(*currentPath); //temporary path - engine will operate on it
 			LOCPLINT->pim->unlock();
-			mres = LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection.selected)->type->ID,&sended,1,0);
+			mres = LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection)->type->ID,&sended,1,0);
 			LOCPLINT->pim->lock();
 			if(mres)
 			{
 				delete currentPath;
 				currentPath = NULL;
-				int i=0;
-				for(;i<LOCPLINT->adventureInt->heroList.items.size();i++)
-				{
-					if(LOCPLINT->adventureInt->heroList.items[i].first->subID == ((const CGHeroInstance*)LOCPLINT->adventureInt->selection.selected)->type->ID)
-					{
-						LOCPLINT->adventureInt->heroList.items[i].second = NULL;
-						break;
-					}
-				}
+				LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.getPosOfHero(LOCPLINT->adventureInt->selection)].second = NULL;
 			}
 		}
 		else
 		{
 			delete currentPath;
 			currentPath=NULL;
+			LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.getPosOfHero(LOCPLINT->adventureInt->selection)].second = NULL;
 		}
+		return;
 	}
 	const CGHeroInstance * currentHero = (LOCPLINT->adventureInt->heroList.items.size())?(LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].first):(NULL);
-	if(!currentHero)
-		return;
-	int3 bufpos = currentHero->getPosition(false);
-	//bufpos.x-=1;
-	if (mres)
+	if(currentHero)
 	{
-		vector<Coordinate>* p;
-		p = CGI->pathf->GetPath(Coordinate(bufpos),Coordinate(mp),currentHero);
-
-		//Convert to old format.
-		currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->ConvertToOldFormat(p);
-
-		delete p;
-		//currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->getPath(bufpos,mp,currentHero,1);
+		int3 bufpos = currentHero->getPosition(false);
+		if (mres)
+		{
+			vector<Coordinate>* p;
+			p = CGI->pathf->GetPath(Coordinate(bufpos),Coordinate(mp),currentHero);
+			//Convert to old format.
+			currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->ConvertToOldFormat(p);
+			delete p;
+		}
+		return;
 	}
+	
 }
 void CTerrainRect::clickRight(tribool down)
 {
@@ -369,7 +401,31 @@ void CTerrainRect::mouseMoved (SDL_MouseMotionEvent & sEvent)
 	{
 		LOCPLINT->adventureInt->statusbar.clear();
 	}
-
+	std::vector<const CGObjectInstance *> objs = LOCPLINT->cb->getVisitableObjs(pom); 
+	for(int i=0; i<objs.size();i++)
+	{
+		if(objs[i]->ID == 98) //town
+		{
+			CGI->curh->changeGraphic(0,0);
+			return;
+		}
+	}
+	objs = LOCPLINT->cb->getBlockingObjs(pom);
+	for(int i=0; i<objs.size();i++)
+	{
+		if(objs[i]->ID == 98) //town
+		{
+			CGI->curh->changeGraphic(0,3);
+			return;
+		}
+		else if(objs[i]->ID == 34 //mouse over hero
+			&& (objs[i]==LOCPLINT->adventureInt->selection  ||  LOCPLINT->adventureInt->selection->ID==98)) //this hero is selected or we've selected a town
+		{
+			CGI->curh->changeGraphic(0,2);
+			return;
+		}
+	}
+	CGI->curh->changeGraphic(0,0);
 }
 void CTerrainRect::keyPressed (SDL_KeyboardEvent & key){}
 void CTerrainRect::hover(bool on)
@@ -547,7 +603,7 @@ void CTerrainRect::showPath()
 			}
 
 		}
-		if (  ((currentPath->nodes[i].dist)-(*(currentPath->nodes.end()-1)).dist) > ((const CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->movement)
+		if (  ((currentPath->nodes[i].dist)-(*(currentPath->nodes.end()-1)).dist) > ((const CGHeroInstance*)(LOCPLINT->adventureInt->selection))->movement)
 			pn+=25;
 		if (pn>=0)
 		{
@@ -689,18 +745,10 @@ void CInfoBar::draw(const CGObjectInstance * specific)
 	else if (mode==5)
 	{
 		mode = -1;
-		if(!LOCPLINT->adventureInt->selection.selected)
-		{
-			if (LOCPLINT->adventureInt->heroList.items.size())
-			{
-				LOCPLINT->adventureInt->heroList.select(0);
-			}
-		}
-		draw((const CGObjectInstance *)LOCPLINT->adventureInt->selection.selected);
+		draw(LOCPLINT->adventureInt->selection);
 	}
 	if (!specific)
-		specific = (const CGObjectInstance *)LOCPLINT->adventureInt->selection.selected;
-	//TODO: to rzutowanie wyglada groznie, ale dziala. Ale nie powinno wygladac groznie.
+		specific = LOCPLINT->adventureInt->selection;
 
 	if(!specific)
 		return;
@@ -874,6 +922,7 @@ endTurn(CGI->preth->zelp[302].first,CGI->preth->zelp[302].second,
 
 townList(5,&genRect(192,48,747,196),747,196,747,372)
 {
+	selection = NULL;
 	townList.fun = boost::bind(&CAdvMapInt::selectionChanged,this);
 	LOCPLINT->adventureInt=this;
 	bg = BitmapHandler::loadBitmap("ADVMAP.bmp");
@@ -931,12 +980,12 @@ void CAdvMapInt::fsleepWake()
 }
 void CAdvMapInt::fmoveHero()
 {
-	if (selection.type!=HEROI_TYPE)
+	if (selection->ID!=HEROI_TYPE)
 		return;
 	if (!terrain.currentPath)
 		return;
 	CPath sended(*(terrain.currentPath)); //temporary path - engine will operate on it
-	LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection.selected)->type->ID,&sended,1,0);
+	LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection)->type->ID,&sended,1,0);
 }
 void CAdvMapInt::fshowSpellbok()
 {
@@ -1008,6 +1057,7 @@ void CAdvMapInt::show(SDL_Surface *to)
 	minimap.draw();
 	heroList.draw();
 	townList.draw();
+	updateScreen = true;
 	update();
 
 	resdatabar.draw();
@@ -1015,8 +1065,6 @@ void CAdvMapInt::show(SDL_Surface *to)
 	statusbar.show();
 
 	infoBar.draw();
-
-	CSDL_Ext::update(screen);
 }
 void CAdvMapInt::hide()
 {
@@ -1041,24 +1089,71 @@ void CAdvMapInt::hide()
 }
 void CAdvMapInt::update()
 {
-	terrain.show();
-	blitAt(gems[2]->ourImages[LOCPLINT->playerID].bitmap,6,6);
-	blitAt(gems[0]->ourImages[LOCPLINT->playerID].bitmap,6,508);
-	blitAt(gems[1]->ourImages[LOCPLINT->playerID].bitmap,556,508);
-	blitAt(gems[3]->ourImages[LOCPLINT->playerID].bitmap,556,6);
-	//updateRect(&genRect(550,600,6,6));
+	++animValHitCount; //for animations
+	if(animValHitCount == 8)
+	{
+		animValHitCount = 0;
+		++anim;
+		updateScreen = true;
+
+	}
+	++heroAnim;
+	if(scrollingLeft)
+	{
+		if(position.x>-Woff)
+		{
+			position.x--;
+			updateScreen = true;
+			updateMinimap=true;
+		}
+	}
+	if(scrollingRight)
+	{
+		if(position.x<CGI->mh->map->width-19+4)
+		{
+			position.x++;
+			updateScreen = true;
+			updateMinimap=true;
+		}
+	}
+	if(scrollingUp)
+	{
+		if(position.y>-Hoff)
+		{
+			position.y--;
+			updateScreen = true;
+			updateMinimap=true;
+		}
+	}
+	if(scrollingDown)
+	{
+		if(position.y<CGI->mh->map->height-18+4)
+		{
+			position.y++;
+			updateScreen = true;
+			updateMinimap=true;
+		}
+	}
+	if(updateScreen)
+	{	
+		terrain.show();
+		blitAt(gems[2]->ourImages[LOCPLINT->playerID].bitmap,6,6);
+		blitAt(gems[0]->ourImages[LOCPLINT->playerID].bitmap,6,508);
+		blitAt(gems[1]->ourImages[LOCPLINT->playerID].bitmap,556,508);
+		blitAt(gems[3]->ourImages[LOCPLINT->playerID].bitmap,556,6);
+		updateScreen=false;
+	}
+	if (updateMinimap)
+	{
+		minimap.draw();
+		updateMinimap=false;
+	}
 }
 
 void CAdvMapInt::selectionChanged()
 {
 	const CGTownInstance *to = townList.items[townList.selected];
-	centerOn(to->pos);
-	selection.type = TOWNI_TYPE;
-	selection.selected = to;
-	terrain.currentPath = NULL;
-	townList.draw();
-	heroList.draw();
-	infoBar.draw(NULL);
+	select(to);
 }
 void CAdvMapInt::centerOn(int3 on)
 {
@@ -1081,11 +1176,6 @@ void CAdvMapInt::centerOn(int3 on)
 	LOCPLINT->adventureInt->updateScreen=true;
 	updateMinimap=true;
 }
-CAdvMapInt::CurrentSelection::CurrentSelection()
-{
-	type=-1;
-	selected=NULL;
-}
 void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * client)
 {
 	if (down)
@@ -1131,3 +1221,24 @@ int3 CAdvMapInt::verifyPos(int3 ver)
 		ver.z=CGI->mh->sizes.z-1;
 	return ver;
 }
+
+void CAdvMapInt::select(const CArmedInstance *sel )
+{
+	centerOn(sel->pos);
+	selection = sel;
+	if(sel->ID==98)
+	{
+		int pos = vstd::findPos(townList.items,sel);
+		townList.selected = pos;
+		terrain.currentPath = NULL;
+	}
+	else
+	{
+		int pos = heroList.getPosOfHero(sel);
+		heroList.selected = pos;
+		terrain.currentPath = heroList.items[pos].second;
+	}
+	townList.draw();
+	heroList.draw();
+	infoBar.draw(NULL);
+}

+ 2 - 6
CAdvmapInterface.h

@@ -144,12 +144,7 @@ public:
 
 	CHeroWindow * heroWindow;
 
-	struct CurrentSelection
-	{
-		int type; //0 - hero, 1 - town
-		const void* selected;
-		CurrentSelection(); //ctor
-	} selection;
+	const CArmedInstance *selection;
 
 	//fuctions binded to buttons
 	void fshowOverview();
@@ -170,6 +165,7 @@ public:
 	void hide(); //deactivates advmap interface
 	void update(); //redraws terrain
 
+	void select(const CArmedInstance *sel);
 	void selectionChanged();
 	void centerOn(int3 on);
 	int3 verifyPos(int3 ver);

+ 18 - 0
CCallback.cpp

@@ -522,4 +522,22 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)
 {
 	if(hero->tempOwner != player) return;
 	*cl->serv << ui16(510) << hero->id << ui32(aid);
+}
+
+std::vector < const CGObjectInstance * > CCallback::getBlockingObjs( int3 pos )
+{
+	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
+	std::vector<const CGObjectInstance *> ret;
+	BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].blockingObjects)
+		ret.push_back(obj);
+	return ret;
+}
+
+std::vector < const CGObjectInstance * > CCallback::getVisitableObjs( int3 pos )
+{
+	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
+	std::vector<const CGObjectInstance *> ret;
+	BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].visitableObjects)
+		ret.push_back(obj);
+	return ret;
 }

+ 4 - 0
CCallback.h

@@ -60,6 +60,8 @@ public:
 	virtual const CCreatureSet* getGarrison(const CGObjectInstance *obj)=0;
 	virtual UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos)=0;
 	virtual const StartInfo * getStartInfo()=0;
+	virtual std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos)=0;
+	virtual std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos)=0;
 
 //battle
 	virtual int battleGetBattlefieldType()=0; //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
@@ -136,6 +138,8 @@ public:
 	const CCreatureSet* getGarrison(const CGObjectInstance *obj);
 	UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos);
 	virtual const StartInfo * getStartInfo();
+	std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos);
+	std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos);
 
 	//battle
 	int battleGetBattlefieldType(); //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship

+ 2 - 0
CCastleInterface.cpp

@@ -452,6 +452,8 @@ void CCastleInterface::close()
 	LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
 	deactivate();
 	LOCPLINT->castleInt = NULL;
+	if(town->visitingHero)
+		LOCPLINT->adventureInt->select(town->visitingHero);
 	LOCPLINT->adventureInt->activate();
 	delete this;
 }

+ 23 - 10
CCursorHandler.cpp

@@ -32,20 +32,33 @@ void CCursorHandler::cursorMove(int x, int y)
 void CCursorHandler::draw1()
 {
 	if(!Show) return;
-	switch(mode)
+	int x = xpos, y = ypos;
+	if(mode==1)
 	{
-	case 0:
-		SDL_BlitSurface(screen,&genRect(32,32,xpos,ypos),help,&genRect(32,32,0,0));
-		blitAt(cursors[mode]->ourImages[number].bitmap,xpos,ypos);
-		break;
-	case 1:
-		SDL_BlitSurface(screen,&genRect(32,32,xpos-16,ypos-16),help,&genRect(32,32,0,0));
-		blitAt(cursors[mode]->ourImages[number].bitmap,xpos-16,ypos-16);
-		break;
+		x-=16;
+		y-=16;
 	}
+	else if(mode==0 && number>0)
+	{
+		x-=12;
+		y-=10;
+	}
+	SDL_BlitSurface(screen,&genRect(32,32,x,y),help,&genRect(32,32,0,0));
+	blitAt(cursors[mode]->ourImages[number].bitmap,x,y);
 }
 void CCursorHandler::draw2()
 {
 	if(!Show) return;
-	blitAt(help,xpos,ypos);
+	int x = xpos, y = ypos;
+	if(mode==1)
+	{
+		x-=16;
+		y-=16;
+	}
+	else if(mode==0 && number>0)
+	{
+		x-=12;
+		y-=10;
+	}
+	blitAt(help,x,y);
 }

+ 20 - 8
CHeroWindow.cpp

@@ -18,6 +18,8 @@
 #include "hch/CHeroHandler.h"
 #include "hch/CLodHandler.h"
 #include "hch/CObjectHandler.h"
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/assign/list_of.hpp>
 #include <boost/assign/std/vector.hpp>
 #include <cstdlib>
 #include <sstream>
@@ -46,10 +48,10 @@ CHeroWindow::CHeroWindow(int playerColor):
 	questlogButton = new AdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CHeroWindow::questlog,this), 379, 437, "hsbtns4.def", false, NULL, false);
 
 	gar1button = new AdventureMapButton(CGI->generaltexth->heroscrn[23], CGI->generaltexth->heroscrn[29], boost::bind(&CHeroWindow::gar1,this), 546, 491, "hsbtns6.def", false, NULL, false);
-	gar2button = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::gar2,this), 604, 491, "hsbtns8.def", false, NULL, false);
 	gar3button = new AdventureMapButton(CGI->generaltexth->heroscrn[24], CGI->generaltexth->heroscrn[30], boost::bind(&CHeroWindow::gar3,this), 546, 527, "hsbtns7.def", false, NULL, false);
-	gar4button = new AdventureMapButton(std::string(), CGI->generaltexth->heroscrn[32], boost::function<void()>(), 604, 527, "hsbtns9.def", false, NULL, false);
-
+	gar2button = new CHighlightableButton(0, 0, map_list_of(0,CGI->generaltexth->heroscrn[26])(3,CGI->generaltexth->heroscrn[25]), CGI->generaltexth->heroscrn[31], false, "hsbtns8.def", NULL, 604, 491, false);
+	gar4button = new AdventureMapButton(CGI->generaltexth->allTexts[256], CGI->generaltexth->heroscrn[32], boost::function<void()>(), 604, 527, "hsbtns9.def", false, NULL, false);
+	boost::algorithm::replace_first(gar4button->hoverTexts[0],"%s",CGI->generaltexth->allTexts[43]);
 	leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::leftArtRoller,this), 379, 364, "hsbtns3.def", false, NULL, false);
 	rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::rightArtRoller,this), 632, 364, "hsbtns5.def", false, NULL, false);
 
@@ -195,9 +197,12 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
 	}
 	curHero = hero;
 
+	gar2button->callback.clear();
+	gar2button->callback2.clear();
+
 	char * prhlp = new char[200];
 	sprintf(prhlp, CGI->generaltexth->heroscrn[16].c_str(), curHero->name.c_str(), curHero->type->heroClass->name.c_str());
-	dismissButton->name = std::string(prhlp);
+	dismissButton->hoverTexts[0] = std::string(prhlp);
 	delete [] prhlp;
 
 	prhlp = new char[200];
@@ -293,6 +298,17 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
 		backpack.push_back(add);
 	}
 	activeArtPlace = NULL;
+	dismissButton->block(hero->visitedTown);
+	leftArtRoll->block(hero->artifacts.size()<6);
+	rightArtRoll->block(hero->artifacts.size()<6);
+	if(hero->getSecSkillLevel(19)<0)
+		gar2button->block(true);
+	else
+	{
+		gar2button->block(false);
+		gar2button->callback = boost::bind(vstd::assign<bool,bool>,boost::ref(hero->tacticFormationEnabled), true);
+		gar2button->callback2 = boost::bind(vstd::assign<bool,bool>,boost::ref(hero->tacticFormationEnabled), true);
+	}
 	redrawCurBack();
 }
 
@@ -426,10 +442,6 @@ void CHeroWindow::gar1()
 {
 }
 
-void CHeroWindow::gar2()
-{
-}
-
 void CHeroWindow::gar3()
 {
 }

+ 2 - 1
CHeroWindow.h

@@ -111,8 +111,9 @@ class CHeroWindow: public IShowActivable, public virtual CIntObject
 	std::vector<LRClickableAreaWTextComp *> secSkillAreas;
 public:
 	AdventureMapButton * quitButton, * dismissButton, * questlogButton, //general
-		* gar1button, * gar2button, * gar3button, //garrison / formation handling
+		* gar1button, * gar3button, //garrison / formation handling
 		* leftArtRoll, * rightArtRoll;
+	CHighlightableButton *gar2button;
 	int player;
 	CHeroWindow(int playerColor); //c-tor
 	~CHeroWindow(); //d-tor

+ 67 - 157
CPlayerInterface.cpp

@@ -422,7 +422,7 @@ void CGarrisonInt::recreateSlots()
 	createSlots();
 	if(active)
 	{
-		ignoreEvent = true;
+		//ignoreEvent = true;
 		activeteSlots();
 		show();
 	}
@@ -831,56 +831,6 @@ void CSelWindow::close()
 	delete this;
 	//call owner with selection result
 }
-template <typename T>CSCButton<T>::CSCButton(CDefHandler * img, CIntObject * obj, void(T::*poin)(tribool), T* Delg)
-{
-	ourObj = obj;
-	delg = Delg;
-	func = poin;
-	imgs.resize(1);
-	for (int i =0; i<img->ourImages.size();i++)
-	{
-		imgs[0].push_back(img->ourImages[i].bitmap);
-	}
-	pos.w = imgs[0][0]->w;
-	pos.h = imgs[0][0]->h;
-	state = 0;
-}
-template <typename T> void CSCButton<T>::clickLeft (tribool down)
-{
-	if (down)
-	{
-		state=1;
-	}
-	else
-	{
-		state=0;
-	}
-	pressedL=state;
-	show();
-	if (delg)
-		(delg->*func)(down);
-}
-template <typename T> void CSCButton<T>::activate()
-{
-	ClickableL::activate();
-}
-template <typename T> void CSCButton<T>::deactivate()
-{
-	ClickableL::deactivate();
-}
-
-template <typename T> void CSCButton<T>::show(SDL_Surface * to)
-{
-	if (delg) //we blit on our owner's bitmap
-	{
-		blitAt(imgs[curimg][state],posr.x,posr.y,delg->bitmap);
-		//updateRect(&genRect(pos.h,pos.w,posr.x,posr.y),delg->bitmap);
-	}
-	else
-	{
-		CButtonBase::show(to);
-	}
-}
 CButtonBase::CButtonBase()
 {
 	bitmapOffset = 0;
@@ -1037,9 +987,11 @@ void CPlayerInterface::yourTurn()
 {
 	LOCPLINT = this;
 	makingTurn = true;
-	unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
-	unsigned char & heroAnimVal = LOCPLINT->adventureInt->heroAnim;
 	adventureInt->infoBar.newDay(cb->getDate(1));
+	if(adventureInt->heroList.items.size())
+		adventureInt->select(adventureInt->heroList.items[0].first);
+	else
+		adventureInt->select(adventureInt->townList.items[0]);
 	adventureInt->activate();
 	//show rest of things
 
@@ -1047,45 +999,13 @@ void CPlayerInterface::yourTurn()
 	mainFPSmng = new FPSmanager;
 	SDL_initFramerate(mainFPSmng);
 	SDL_setFramerate(mainFPSmng, 48);
-	SDL_Event sEvent;
 	//framerate keeper initialized
 	timeHandler th;
 	th.getDif();
 	for(;makingTurn;) // main loop
 	{
-		//updating water tiles
-		//int wnumber = -1;
-		//for(int s=0; s<CGI->mh->reader->defs.size(); ++s)
-		//{
-		//	if(CGI->mh->reader->defs[s]->defName==std::string("WATRTL.DEF"))
-		//	{
-		//		wnumber = s;
-		//		break;
-		//	}
-		//}
-		//if(wnumber>=0)
-		//{
-		//	for(int g=0; g<CGI->mh->reader->defs[wnumber]->ourImages.size(); ++g)
-		//	{
-		//		SDL_Color tab[32];
-		//		for(int i=0; i<32; ++i)
-		//		{
-		//			tab[i] = CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + (i+1)%32];
-		//		}
-		//		//SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t1.bmp");
-		//		for(int i=0; i<32; ++i)
-		//		{
-		//			CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + i] = tab[i];
-		//		}
-		//		//SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t2.bmp");
-		//		CSDL_Ext::update(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap);
-		//	}
-		//}
-		//water tiles updated
-		//CGI->screenh->updateScreen();
-
+		updateWater();
 		pim->lock();
-
 		int tv = th.getDif();
 		for (int i=0;i<timeinterested.size();i++)
 		{
@@ -1104,61 +1024,7 @@ void CPlayerInterface::yourTurn()
 		eventsM.unlock();
 		if (curint == adventureInt) //stuff for advMapInt
 		{
-			++LOCPLINT->adventureInt->animValHitCount; //for animations
-			if(LOCPLINT->adventureInt->animValHitCount == 8)
-			{
-				LOCPLINT->adventureInt->animValHitCount = 0;
-				++animVal;
-				LOCPLINT->adventureInt->updateScreen = true;
-
-			}
-			++heroAnimVal;
-			if(LOCPLINT->adventureInt->scrollingLeft)
-			{
-				if(LOCPLINT->adventureInt->position.x>-Woff)
-				{
-					LOCPLINT->adventureInt->position.x--;
-					LOCPLINT->adventureInt->updateScreen = true;
-					adventureInt->updateMinimap=true;
-				}
-			}
-			if(LOCPLINT->adventureInt->scrollingRight)
-			{
-				if(LOCPLINT->adventureInt->position.x<CGI->mh->map->width-19+4)
-				{
-					LOCPLINT->adventureInt->position.x++;
-					LOCPLINT->adventureInt->updateScreen = true;
-					adventureInt->updateMinimap=true;
-				}
-			}
-			if(LOCPLINT->adventureInt->scrollingUp)
-			{
-				if(LOCPLINT->adventureInt->position.y>-Hoff)
-				{
-					LOCPLINT->adventureInt->position.y--;
-					LOCPLINT->adventureInt->updateScreen = true;
-					adventureInt->updateMinimap=true;
-				}
-			}
-			if(LOCPLINT->adventureInt->scrollingDown)
-			{
-				if(LOCPLINT->adventureInt->position.y<CGI->mh->map->height-18+4)
-				{
-					LOCPLINT->adventureInt->position.y++;
-					LOCPLINT->adventureInt->updateScreen = true;
-					adventureInt->updateMinimap=true;
-				}
-			}
-			if(LOCPLINT->adventureInt->updateScreen)
-			{
-				adventureInt->update();
-				adventureInt->updateScreen=false;
-			}
-			if (LOCPLINT->adventureInt->updateMinimap)
-			{
-				adventureInt->minimap.draw();
-				adventureInt->updateMinimap=false;
-			}
+			adventureInt->update();
 		}
 		for(int i=0;i<objsToBlit.size();i++)
 			objsToBlit[i]->show();
@@ -1241,10 +1107,11 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 		ho->moveDir = getDir(details.src,details.dst);
 		ho->isStanding = true;
 		adventureInt->heroList.draw();
-		if (adventureInt->terrain.currentPath)
+		if (adventureInt->terrain.currentPath && ho->movement>145) //TODO: better condition on movement - check cost of endtile
 		{
 			delete adventureInt->terrain.currentPath;
 			adventureInt->terrain.currentPath = NULL;
+			adventureInt->heroList.items[adventureInt->heroList.getPosOfHero(ho)].second = NULL;
 		}
 		return;
 	}
@@ -1573,6 +1440,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 			subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 33+i, 32), ho->id);
 			subRect(hp.x, hp.y, hp.z, genRect(32, 32, 65+i, 32), ho->id);
 		}
+		adventureInt->updateScreen = true;
 		LOCPLINT->adventureInt->update(); //updating screen
 		CSDL_Ext::update(screen);
 		//CGI->screenh->updateScreen();
@@ -1693,16 +1561,16 @@ SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //spe
 	}
 	else
 	{
-		switch (adventureInt->selection.type)
+		switch (adventureInt->selection->ID)
 		{
 		case HEROI_TYPE:
 			{
-				const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection.selected;
+				const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection;
 				return graphics->drawHeroInfoWin(curh);
 			}
 		case TOWNI_TYPE:
 			{
-				return graphics->drawTownInfoWin((const CGTownInstance *)adventureInt->selection.selected);
+				return graphics->drawTownInfoWin((const CGTownInstance *)adventureInt->selection);
 			}
 		default:
 			return NULL;
@@ -1713,18 +1581,21 @@ SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //spe
 
 void CPlayerInterface::handleMouseMotion(SDL_Event *sEvent)
 {
+	std::vector<int> hlp;
 	for (int i=0; i<hoverable.size();i++)
 	{
 		if (isItIn(&hoverable[i]->pos,sEvent->motion.x,sEvent->motion.y))
 		{
 			if (!hoverable[i]->hovered)
-				hoverable[i]->hover(true);
+				hlp.push_back(i);
 		}
 		else if (hoverable[i]->hovered)
 		{
 			hoverable[i]->hover(false);
 		}
 	}
+	for(int i=0; i<hlp.size();i++)
+		hoverable[hlp[i]]->hover(true);
 	for(int i=0; i<motioninterested.size();i++)
 	{
 		if (motioninterested[i]->strongInterest || isItIn(&motioninterested[i]->pos,sEvent->motion.x,sEvent->motion.y))
@@ -1942,7 +1813,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
 	boost::unique_lock<boost::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.selected == hero)
+	if (adventureInt->selection == hero)
 		adventureInt->infoBar.draw();
 	return;
 }
@@ -2274,9 +2145,44 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
 	boost::unique_lock<boost::mutex> un(*pim);
 	if(curint->subInt == adventureInt->heroWindow)
 	{
-		//TODO: update hero window properly
-
-	}
+		adventureInt->heroWindow->deactivate();
+		adventureInt->heroWindow->setHero(adventureInt->heroWindow->curHero);
+		adventureInt->heroWindow->activate();
+	}
+}
+
+void CPlayerInterface::updateWater()
+{
+	//updating water tiles
+	//int wnumber = -1;
+	//for(int s=0; s<CGI->mh->reader->defs.size(); ++s)
+	//{
+	//	if(CGI->mh->reader->defs[s]->defName==std::string("WATRTL.DEF"))
+	//	{
+	//		wnumber = s;
+	//		break;
+	//	}
+	//}
+	//if(wnumber>=0)
+	//{
+	//	for(int g=0; g<CGI->mh->reader->defs[wnumber]->ourImages.size(); ++g)
+	//	{
+	//		SDL_Color tab[32];
+	//		for(int i=0; i<32; ++i)
+	//		{
+	//			tab[i] = CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + (i+1)%32];
+	//		}
+	//		//SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t1.bmp");
+	//		for(int i=0; i<32; ++i)
+	//		{
+	//			CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + i] = tab[i];
+	//		}
+	//		//SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t2.bmp");
+	//		CSDL_Ext::update(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap);
+	//	}
+	//}
+	//water tiles updated
+	//CGI->screenh->updateScreen();
 }
 CStatusBar::CStatusBar(int x, int y, std::string name, int maxw)
 {
@@ -2388,7 +2294,8 @@ void CHeroList::select(int which)
 	if (which<0)
 	{
 		selected = which;
-		LOCPLINT->adventureInt->selection.selected = LOCPLINT->adventureInt->terrain.currentPath = NULL;
+		LOCPLINT->adventureInt->selection = NULL;
+		LOCPLINT->adventureInt->terrain.currentPath = NULL;
 		draw();
 		LOCPLINT->adventureInt->infoBar.draw(NULL);
 	}
@@ -2396,8 +2303,7 @@ void CHeroList::select(int which)
 		return;
 	selected = which;
 	LOCPLINT->adventureInt->centerOn(items[which].first->pos);
-	LOCPLINT->adventureInt->selection.type = HEROI_TYPE;
-	LOCPLINT->adventureInt->selection.selected = items[which].first;
+	LOCPLINT->adventureInt->selection = items[which].first;
 	LOCPLINT->adventureInt->terrain.currentPath = items[which].second;
 	draw();
 	LOCPLINT->adventureInt->townList.draw();
@@ -2428,7 +2334,7 @@ void CHeroList::clickLeft(tribool down)
 		int ny = hy/32;
 		if (ny>=5 || ny<0)
 			return;
-		if ( (ny+from)==selected && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
+		if ( (ny+from)==selected && (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE))
 			LOCPLINT->openHeroWindow(items[selected].first);//print hero screen
 		select(ny+from);
 	}
@@ -2579,7 +2485,7 @@ void CHeroList::draw()
 		blitAt(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
 		SDL_Surface * temp = graphics->portraitSmall[cur->portrait];
 		blitAt(temp,posporx,pospory+i*32);
-		if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
+		if ((selected == iT) && (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE))
 		{
 			blitAt(selection,posporx,pospory+i*32);
 		}
@@ -2596,6 +2502,10 @@ void CHeroList::draw()
 		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
 }
 
+int CHeroList::getPosOfHero(const CArmedInstance* h)
+{
+	return vstd::findPos(items,h,boost::bind(vstd::equal<std::pair<const CGHeroInstance*, CPath *>,const CArmedInstance *,const CGHeroInstance*>,_1,&std::pair<const CGHeroInstance*, CPath *>::first,_2));
+}
 
 
 CTownList::~CTownList()
@@ -2701,7 +2611,7 @@ void CTownList::clickLeft(tribool down)
 		int ny = hy/32;
 		if (ny>SIZE || ny<0)
 			return;
-		if (SIZE==5 && (ny+from)==selected && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
+		if (SIZE==5 && (ny+from)==selected && (LOCPLINT->adventureInt->selection->ID == TOWNI_TYPE))
 			LOCPLINT->openTownWindow(items[selected]);//print town screen
 		else
 			select(ny+from);
@@ -2795,7 +2705,7 @@ void CTownList::draw()
 
 		blitAt(graphics->getPic(items[iT]->subID,items[iT]->hasFort(),items[iT]->builded),posporx,pospory+i*32);
 
-		if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
+		if ((selected == iT) && (LOCPLINT->adventureInt->selection->ID == TOWNI_TYPE))
 		{
 			blitAt(graphics->getPic(-2),posporx,pospory+i*32);
 		}

+ 2 - 16
CPlayerInterface.h

@@ -155,20 +155,6 @@ public:
 	virtual void activate();
 	virtual void deactivate();
 };
-template <typename T> class CSCButton: public CButtonBase, public ClickableL //prosty guzik, ktory tylko zmienia obrazek
-{
-public:
-	int3 posr; //position in the bitmap
-	int state;
-	T* delg;
-	void(T::*func)(boost::logic::tribool);
-	CSCButton(CDefHandler * img, CIntObject * obj, void(T::*poin)(boost::logic::tribool), T* Delg=NULL);
-	void clickLeft (boost::logic::tribool down);
-	void activate();
-	void deactivate();
-	void show(SDL_Surface * to = NULL);
-};
-
 class CInfoWindow : public CSimpleWindow //text + comp. + ok button
 { //window able to delete its components when closed
 public:
@@ -367,7 +353,6 @@ public:
 	void tileHidden(int3 pos);
 	void tileRevealed(int3 pos);
 	void yourTurn();
-
 	//for battles
 	//void actionFinished(BattleAction action);//occurs AFTER every action taken by any stack or by the hero
 	//void actionStarted(BattleAction action);//occurs BEFORE every action taken by any stack or by the hero
@@ -383,7 +368,7 @@ public:
 
 
 	//-------------//
-
+	void updateWater();
 	void showComp(SComponent comp);
 	void openTownWindow(const CGTownInstance * town); //shows townscreen
 	void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
@@ -449,6 +434,7 @@ public:
 	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
 
 	CHeroList(int Size = 5);
+	int getPosOfHero(const CArmedInstance* h);
 	void genList();
 	void select(int which);
 	void mouseMoved (SDL_MouseMotionEvent & sEvent);

+ 2 - 0
client/Client.cpp

@@ -545,5 +545,7 @@ void CClient::run()
 
 void CClient::close()
 {
+	boost::unique_lock<boost::mutex>(*serv->wmx);
+	*serv << ui16(99);
 	serv->close();
 }

+ 4 - 0
client/FunctionList.h

@@ -32,6 +32,10 @@ public:
 	//	funcs.push_back(first);
 	//	return first;
 	//}
+	void clear()
+	{
+		funcs.clear();
+	}
 	operator bool() const
 	{
 		return funcs.size();

+ 33 - 2
global.h

@@ -43,8 +43,8 @@ enum EHeroClasses {HERO_KNIGHT, HERO_CLERIC, HERO_RANGER, HERO_DRUID, HERO_ALCHE
 class CGameInfo;
 extern CGameInfo* CGI;
 
-#define HEROI_TYPE (0)
-#define TOWNI_TYPE (1)
+#define HEROI_TYPE (34)
+#define TOWNI_TYPE (98)
 
 const int F_NUMBER = 9; //factions (town types) quantity
 const int PLAYER_LIMIT = 8; //player limit per map
@@ -132,6 +132,22 @@ namespace vstd
 	{
 		return std::find(c.begin(),c.end(),i);
 	}
+	template <typename T1, typename T2>
+	int findPos(const std::vector<T1> & c, const T2 &s)
+	{
+		for(int i=0;i<c.size();i++)
+			if(c[i] == s)
+				return i;
+		return -1;
+	}
+	template <typename T1, typename T2, typename Func>
+	int findPos(const std::vector<T1> & c, const T2 &s, Func &f) //Func(T1,T2) must say if these elements matches
+	{
+		for(int i=0;i<c.size();i++)
+			if(f(c[i],s))
+				return i;
+		return -1;
+	}
 	template <typename Container, typename Item>
 	typename Container::iterator find(Container & c, const Item &i)
 	{
@@ -146,6 +162,21 @@ namespace vstd
 		c.erase(itr);
 		return true;
 	}
+	template <typename t1, typename t2>
+	void assign(t1 &a1, const t2 &a2)
+	{
+		a1 = a2;
+	}
+	template <typename t1, typename t2, typename t3>
+	bool equal(const t1 &a1, const t3 t1::* point, const t2 &a2)
+	{
+		return a1.*point == a2;
+	}
+	template <typename t1, typename t2>
+	bool equal(const t1 &a1, const t2 &a2)
+	{
+		return a1 == a2;
+	}
 }
 using vstd::operator-=;
 #endif //GLOBAL_H

+ 1 - 0
int3.h

@@ -1,6 +1,7 @@
 #ifndef INT3_H
 #define INT3_H
 #include <map>
+#include <vector>
 class CCreature;
 class CCreatureSet //seven combined creatures
 {

+ 4 - 4
server/CScriptCallback.cpp

@@ -88,8 +88,8 @@ void CScriptCallback::showSelectionDialog(SelectionDialog *iw, const CFunctionLi
 int CScriptCallback::getSelectedHero()
 {	
 	//int ret;
-	//if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
-	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
+	//if (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE)
+	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection))->subID;
 	//else 
 	//	ret = -1;;
 	return -1;
@@ -214,8 +214,8 @@ int CLuaCallback::getGnrlText(lua_State * L) //(int which),returns string
 int CLuaCallback::getSelectedHero(lua_State * L) //(),returns int (ID of hero, -1 if no hero is seleceted)
 {
 	//int ret;
-	//if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
-	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
+	//if (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE)
+	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection))->subID;
 	//else 
 	//	ret = -1;
 	//lua_pushinteger(L,ret);