Browse Source

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 years ago
parent
commit
7722d058f0

+ 51 - 7
AdventureMapButton.cpp

@@ -20,11 +20,17 @@ AdventureMapButton::AdventureMapButton ()
 //{
 //{
 //	init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ);
 //	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)
 void AdventureMapButton::clickLeft (tribool down)
 {
 {
@@ -62,11 +68,14 @@ void AdventureMapButton::clickRight (tribool down)
 void AdventureMapButton::hover (bool on)
 void AdventureMapButton::hover (bool on)
 {
 {
 	Hoverable::hover(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)
 		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();
 			LOCPLINT->statusbar->clear();
 	}
 	}
 }
 }
@@ -96,7 +105,7 @@ void AdventureMapButton::deactivate()
 	KeyInterested::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;
 	callback = Callback;
 	blocked = actOnDown = false;
 	blocked = actOnDown = false;
@@ -105,7 +114,7 @@ void AdventureMapButton::init( CFunctionList<void()> Callback, std::string Name,
 	active=false;
 	active=false;
 	ourObj=NULL;
 	ourObj=NULL;
 	state=0;
 	state=0;
-	name=Name;
+	hoverTexts = Name;
 	helpBox=HelpBox;
 	helpBox=HelpBox;
 	colorChange = playerColoredButton;
 	colorChange = playerColoredButton;
 	int est = LOCPLINT->playerID;
 	int est = LOCPLINT->playerID;
@@ -152,6 +161,41 @@ void AdventureMapButton::block( bool on )
 	show();
 	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()
 void CSlider::sliderClicked()
 {
 {
 	if(!moving)
 	if(!moving)

+ 17 - 6
AdventureMapButton.h

@@ -6,7 +6,7 @@ class AdventureMapButton
 	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
 	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
 {
 {
 public:
 public:
-	std::string name; //for status bar 
+	std::map<int,std::string> hoverTexts; //state -> text for statusbar
 	std::string helpBox; //for right-click help
 	std::string helpBox; //for right-click help
 	char key; //key shortcut
 	char key; //key shortcut
 	CFunctionList<void()> callback;
 	CFunctionList<void()> callback;
@@ -14,18 +14,29 @@ public:
 		actOnDown; //runs when mouse is pressed down over it, not when up
 		actOnDown; //runs when mouse is pressed down over it, not when up
 
 
 	void clickRight (tribool down);
 	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 keyPressed (SDL_KeyboardEvent & key);
 	void activate(); // makes button active
 	void activate(); // makes button active
 	void deactivate(); // makes button inactive (but doesn't delete)
 	void deactivate(); // makes button inactive (but doesn't delete)
 
 
 	AdventureMapButton(); //c-tor
 	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
 	//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 "client/CBitmapHandler.h"
 #include "CPlayerInterface.h"
 #include "CPlayerInterface.h"
 #include "CCastleInterface.h"
 #include "CCastleInterface.h"
+#include "CCursorHandler.h"
 #include "hch/CPreGameTextHandler.h"
 #include "hch/CPreGameTextHandler.h"
 #include "hch/CGeneralTextHandler.h"
 #include "hch/CGeneralTextHandler.h"
 #include "hch/CDefHandler.h"
 #include "hch/CDefHandler.h"
@@ -291,18 +292,56 @@ void CTerrainRect::clickLeft(tribool down)
 {
 {
 	if ((down==false) || indeterminate(down))
 	if ((down==false) || indeterminate(down))
 		return;
 		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)
 		if (currentPath)
 		{
 		{
+			std::cout<<"Warning: Lost path?" << std::endl;
 			delete currentPath;
 			delete currentPath;
 			currentPath = NULL;
 			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;
 		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;
 	bool mres =true;
 	if (currentPath)
 	if (currentPath)
 	{
 	{
@@ -310,45 +349,38 @@ void CTerrainRect::clickLeft(tribool down)
 		{ //move
 		{ //move
 			CPath sended(*currentPath); //temporary path - engine will operate on it
 			CPath sended(*currentPath); //temporary path - engine will operate on it
 			LOCPLINT->pim->unlock();
 			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();
 			LOCPLINT->pim->lock();
 			if(mres)
 			if(mres)
 			{
 			{
 				delete currentPath;
 				delete currentPath;
 				currentPath = NULL;
 				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
 		else
 		{
 		{
 			delete currentPath;
 			delete currentPath;
 			currentPath=NULL;
 			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);
 	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)
 void CTerrainRect::clickRight(tribool down)
 {
 {
@@ -369,7 +401,31 @@ void CTerrainRect::mouseMoved (SDL_MouseMotionEvent & sEvent)
 	{
 	{
 		LOCPLINT->adventureInt->statusbar.clear();
 		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::keyPressed (SDL_KeyboardEvent & key){}
 void CTerrainRect::hover(bool on)
 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;
 			pn+=25;
 		if (pn>=0)
 		if (pn>=0)
 		{
 		{
@@ -689,18 +745,10 @@ void CInfoBar::draw(const CGObjectInstance * specific)
 	else if (mode==5)
 	else if (mode==5)
 	{
 	{
 		mode = -1;
 		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)
 	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)
 	if(!specific)
 		return;
 		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)
 townList(5,&genRect(192,48,747,196),747,196,747,372)
 {
 {
+	selection = NULL;
 	townList.fun = boost::bind(&CAdvMapInt::selectionChanged,this);
 	townList.fun = boost::bind(&CAdvMapInt::selectionChanged,this);
 	LOCPLINT->adventureInt=this;
 	LOCPLINT->adventureInt=this;
 	bg = BitmapHandler::loadBitmap("ADVMAP.bmp");
 	bg = BitmapHandler::loadBitmap("ADVMAP.bmp");
@@ -931,12 +980,12 @@ void CAdvMapInt::fsleepWake()
 }
 }
 void CAdvMapInt::fmoveHero()
 void CAdvMapInt::fmoveHero()
 {
 {
-	if (selection.type!=HEROI_TYPE)
+	if (selection->ID!=HEROI_TYPE)
 		return;
 		return;
 	if (!terrain.currentPath)
 	if (!terrain.currentPath)
 		return;
 		return;
 	CPath sended(*(terrain.currentPath)); //temporary path - engine will operate on it
 	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()
 void CAdvMapInt::fshowSpellbok()
 {
 {
@@ -1008,6 +1057,7 @@ void CAdvMapInt::show(SDL_Surface *to)
 	minimap.draw();
 	minimap.draw();
 	heroList.draw();
 	heroList.draw();
 	townList.draw();
 	townList.draw();
+	updateScreen = true;
 	update();
 	update();
 
 
 	resdatabar.draw();
 	resdatabar.draw();
@@ -1015,8 +1065,6 @@ void CAdvMapInt::show(SDL_Surface *to)
 	statusbar.show();
 	statusbar.show();
 
 
 	infoBar.draw();
 	infoBar.draw();
-
-	CSDL_Ext::update(screen);
 }
 }
 void CAdvMapInt::hide()
 void CAdvMapInt::hide()
 {
 {
@@ -1041,24 +1089,71 @@ void CAdvMapInt::hide()
 }
 }
 void CAdvMapInt::update()
 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()
 void CAdvMapInt::selectionChanged()
 {
 {
 	const CGTownInstance *to = townList.items[townList.selected];
 	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)
 void CAdvMapInt::centerOn(int3 on)
 {
 {
@@ -1081,11 +1176,6 @@ void CAdvMapInt::centerOn(int3 on)
 	LOCPLINT->adventureInt->updateScreen=true;
 	LOCPLINT->adventureInt->updateScreen=true;
 	updateMinimap=true;
 	updateMinimap=true;
 }
 }
-CAdvMapInt::CurrentSelection::CurrentSelection()
-{
-	type=-1;
-	selected=NULL;
-}
 void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * client)
 void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * client)
 {
 {
 	if (down)
 	if (down)
@@ -1131,3 +1221,24 @@ int3 CAdvMapInt::verifyPos(int3 ver)
 		ver.z=CGI->mh->sizes.z-1;
 		ver.z=CGI->mh->sizes.z-1;
 	return ver;
 	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;
 	CHeroWindow * heroWindow;
 
 
-	struct CurrentSelection
-	{
-		int type; //0 - hero, 1 - town
-		const void* selected;
-		CurrentSelection(); //ctor
-	} selection;
+	const CArmedInstance *selection;
 
 
 	//fuctions binded to buttons
 	//fuctions binded to buttons
 	void fshowOverview();
 	void fshowOverview();
@@ -170,6 +165,7 @@ public:
 	void hide(); //deactivates advmap interface
 	void hide(); //deactivates advmap interface
 	void update(); //redraws terrain
 	void update(); //redraws terrain
 
 
+	void select(const CArmedInstance *sel);
 	void selectionChanged();
 	void selectionChanged();
 	void centerOn(int3 on);
 	void centerOn(int3 on);
 	int3 verifyPos(int3 ver);
 	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;
 	if(hero->tempOwner != player) return;
 	*cl->serv << ui16(510) << hero->id << ui32(aid);
 	*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 const CCreatureSet* getGarrison(const CGObjectInstance *obj)=0;
 	virtual UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos)=0;
 	virtual UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos)=0;
 	virtual const StartInfo * getStartInfo()=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
 //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
 	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);
 	const CCreatureSet* getGarrison(const CGObjectInstance *obj);
 	UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos);
 	UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos);
 	virtual const StartInfo * getStartInfo();
 	virtual const StartInfo * getStartInfo();
+	std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos);
+	std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos);
 
 
 	//battle
 	//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
 	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));
 	LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
 	deactivate();
 	deactivate();
 	LOCPLINT->castleInt = NULL;
 	LOCPLINT->castleInt = NULL;
+	if(town->visitingHero)
+		LOCPLINT->adventureInt->select(town->visitingHero);
 	LOCPLINT->adventureInt->activate();
 	LOCPLINT->adventureInt->activate();
 	delete this;
 	delete this;
 }
 }

+ 23 - 10
CCursorHandler.cpp

@@ -32,20 +32,33 @@ void CCursorHandler::cursorMove(int x, int y)
 void CCursorHandler::draw1()
 void CCursorHandler::draw1()
 {
 {
 	if(!Show) return;
 	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()
 void CCursorHandler::draw2()
 {
 {
 	if(!Show) return;
 	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/CHeroHandler.h"
 #include "hch/CLodHandler.h"
 #include "hch/CLodHandler.h"
 #include "hch/CObjectHandler.h"
 #include "hch/CObjectHandler.h"
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/assign/list_of.hpp>
 #include <boost/assign/std/vector.hpp>
 #include <boost/assign/std/vector.hpp>
 #include <cstdlib>
 #include <cstdlib>
 #include <sstream>
 #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);
 	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);
 	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);
 	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);
 	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);
 	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;
 	curHero = hero;
 
 
+	gar2button->callback.clear();
+	gar2button->callback2.clear();
+
 	char * prhlp = new char[200];
 	char * prhlp = new char[200];
 	sprintf(prhlp, CGI->generaltexth->heroscrn[16].c_str(), curHero->name.c_str(), curHero->type->heroClass->name.c_str());
 	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;
 	delete [] prhlp;
 
 
 	prhlp = new char[200];
 	prhlp = new char[200];
@@ -293,6 +298,17 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
 		backpack.push_back(add);
 		backpack.push_back(add);
 	}
 	}
 	activeArtPlace = NULL;
 	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();
 	redrawCurBack();
 }
 }
 
 
@@ -426,10 +442,6 @@ void CHeroWindow::gar1()
 {
 {
 }
 }
 
 
-void CHeroWindow::gar2()
-{
-}
-
 void CHeroWindow::gar3()
 void CHeroWindow::gar3()
 {
 {
 }
 }

+ 2 - 1
CHeroWindow.h

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

+ 67 - 157
CPlayerInterface.cpp

@@ -422,7 +422,7 @@ void CGarrisonInt::recreateSlots()
 	createSlots();
 	createSlots();
 	if(active)
 	if(active)
 	{
 	{
-		ignoreEvent = true;
+		//ignoreEvent = true;
 		activeteSlots();
 		activeteSlots();
 		show();
 		show();
 	}
 	}
@@ -831,56 +831,6 @@ void CSelWindow::close()
 	delete this;
 	delete this;
 	//call owner with selection result
 	//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()
 CButtonBase::CButtonBase()
 {
 {
 	bitmapOffset = 0;
 	bitmapOffset = 0;
@@ -1037,9 +987,11 @@ void CPlayerInterface::yourTurn()
 {
 {
 	LOCPLINT = this;
 	LOCPLINT = this;
 	makingTurn = true;
 	makingTurn = true;
-	unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
-	unsigned char & heroAnimVal = LOCPLINT->adventureInt->heroAnim;
 	adventureInt->infoBar.newDay(cb->getDate(1));
 	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();
 	adventureInt->activate();
 	//show rest of things
 	//show rest of things
 
 
@@ -1047,45 +999,13 @@ void CPlayerInterface::yourTurn()
 	mainFPSmng = new FPSmanager;
 	mainFPSmng = new FPSmanager;
 	SDL_initFramerate(mainFPSmng);
 	SDL_initFramerate(mainFPSmng);
 	SDL_setFramerate(mainFPSmng, 48);
 	SDL_setFramerate(mainFPSmng, 48);
-	SDL_Event sEvent;
 	//framerate keeper initialized
 	//framerate keeper initialized
 	timeHandler th;
 	timeHandler th;
 	th.getDif();
 	th.getDif();
 	for(;makingTurn;) // main loop
 	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();
 		pim->lock();
-
 		int tv = th.getDif();
 		int tv = th.getDif();
 		for (int i=0;i<timeinterested.size();i++)
 		for (int i=0;i<timeinterested.size();i++)
 		{
 		{
@@ -1104,61 +1024,7 @@ void CPlayerInterface::yourTurn()
 		eventsM.unlock();
 		eventsM.unlock();
 		if (curint == adventureInt) //stuff for advMapInt
 		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++)
 		for(int i=0;i<objsToBlit.size();i++)
 			objsToBlit[i]->show();
 			objsToBlit[i]->show();
@@ -1241,10 +1107,11 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 		ho->moveDir = getDir(details.src,details.dst);
 		ho->moveDir = getDir(details.src,details.dst);
 		ho->isStanding = true;
 		ho->isStanding = true;
 		adventureInt->heroList.draw();
 		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;
 			delete adventureInt->terrain.currentPath;
 			adventureInt->terrain.currentPath = NULL;
 			adventureInt->terrain.currentPath = NULL;
+			adventureInt->heroList.items[adventureInt->heroList.getPosOfHero(ho)].second = NULL;
 		}
 		}
 		return;
 		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-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);
 			subRect(hp.x, hp.y, hp.z, genRect(32, 32, 65+i, 32), ho->id);
 		}
 		}
+		adventureInt->updateScreen = true;
 		LOCPLINT->adventureInt->update(); //updating screen
 		LOCPLINT->adventureInt->update(); //updating screen
 		CSDL_Ext::update(screen);
 		CSDL_Ext::update(screen);
 		//CGI->screenh->updateScreen();
 		//CGI->screenh->updateScreen();
@@ -1693,16 +1561,16 @@ SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //spe
 	}
 	}
 	else
 	else
 	{
 	{
-		switch (adventureInt->selection.type)
+		switch (adventureInt->selection->ID)
 		{
 		{
 		case HEROI_TYPE:
 		case HEROI_TYPE:
 			{
 			{
-				const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection.selected;
+				const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection;
 				return graphics->drawHeroInfoWin(curh);
 				return graphics->drawHeroInfoWin(curh);
 			}
 			}
 		case TOWNI_TYPE:
 		case TOWNI_TYPE:
 			{
 			{
-				return graphics->drawTownInfoWin((const CGTownInstance *)adventureInt->selection.selected);
+				return graphics->drawTownInfoWin((const CGTownInstance *)adventureInt->selection);
 			}
 			}
 		default:
 		default:
 			return NULL;
 			return NULL;
@@ -1713,18 +1581,21 @@ SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //spe
 
 
 void CPlayerInterface::handleMouseMotion(SDL_Event *sEvent)
 void CPlayerInterface::handleMouseMotion(SDL_Event *sEvent)
 {
 {
+	std::vector<int> hlp;
 	for (int i=0; i<hoverable.size();i++)
 	for (int i=0; i<hoverable.size();i++)
 	{
 	{
 		if (isItIn(&hoverable[i]->pos,sEvent->motion.x,sEvent->motion.y))
 		if (isItIn(&hoverable[i]->pos,sEvent->motion.x,sEvent->motion.y))
 		{
 		{
 			if (!hoverable[i]->hovered)
 			if (!hoverable[i]->hovered)
-				hoverable[i]->hover(true);
+				hlp.push_back(i);
 		}
 		}
 		else if (hoverable[i]->hovered)
 		else if (hoverable[i]->hovered)
 		{
 		{
 			hoverable[i]->hover(false);
 			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++)
 	for(int i=0; i<motioninterested.size();i++)
 	{
 	{
 		if (motioninterested[i]->strongInterest || isItIn(&motioninterested[i]->pos,sEvent->motion.x,sEvent->motion.y))
 		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);
 	boost::unique_lock<boost::mutex> un(*pim);
 	SDL_FreeSurface(graphics->heroWins[hero->subID]);//TODO: moznaby zmieniac jedynie fragment bitmapy zwiazany z dana umiejetnoscia
 	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.
 	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();
 		adventureInt->infoBar.draw();
 	return;
 	return;
 }
 }
@@ -2274,9 +2145,44 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
 	boost::unique_lock<boost::mutex> un(*pim);
 	boost::unique_lock<boost::mutex> un(*pim);
 	if(curint->subInt == adventureInt->heroWindow)
 	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)
 CStatusBar::CStatusBar(int x, int y, std::string name, int maxw)
 {
 {
@@ -2388,7 +2294,8 @@ void CHeroList::select(int which)
 	if (which<0)
 	if (which<0)
 	{
 	{
 		selected = which;
 		selected = which;
-		LOCPLINT->adventureInt->selection.selected = LOCPLINT->adventureInt->terrain.currentPath = NULL;
+		LOCPLINT->adventureInt->selection = NULL;
+		LOCPLINT->adventureInt->terrain.currentPath = NULL;
 		draw();
 		draw();
 		LOCPLINT->adventureInt->infoBar.draw(NULL);
 		LOCPLINT->adventureInt->infoBar.draw(NULL);
 	}
 	}
@@ -2396,8 +2303,7 @@ void CHeroList::select(int which)
 		return;
 		return;
 	selected = which;
 	selected = which;
 	LOCPLINT->adventureInt->centerOn(items[which].first->pos);
 	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;
 	LOCPLINT->adventureInt->terrain.currentPath = items[which].second;
 	draw();
 	draw();
 	LOCPLINT->adventureInt->townList.draw();
 	LOCPLINT->adventureInt->townList.draw();
@@ -2428,7 +2334,7 @@ void CHeroList::clickLeft(tribool down)
 		int ny = hy/32;
 		int ny = hy/32;
 		if (ny>=5 || ny<0)
 		if (ny>=5 || ny<0)
 			return;
 			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
 			LOCPLINT->openHeroWindow(items[selected].first);//print hero screen
 		select(ny+from);
 		select(ny+from);
 	}
 	}
@@ -2579,7 +2485,7 @@ void CHeroList::draw()
 		blitAt(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
 		blitAt(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
 		SDL_Surface * temp = graphics->portraitSmall[cur->portrait];
 		SDL_Surface * temp = graphics->portraitSmall[cur->portrait];
 		blitAt(temp,posporx,pospory+i*32);
 		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);
 			blitAt(selection,posporx,pospory+i*32);
 		}
 		}
@@ -2596,6 +2502,10 @@ void CHeroList::draw()
 		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
 		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()
 CTownList::~CTownList()
@@ -2701,7 +2611,7 @@ void CTownList::clickLeft(tribool down)
 		int ny = hy/32;
 		int ny = hy/32;
 		if (ny>SIZE || ny<0)
 		if (ny>SIZE || ny<0)
 			return;
 			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
 			LOCPLINT->openTownWindow(items[selected]);//print town screen
 		else
 		else
 			select(ny+from);
 			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);
 		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);
 			blitAt(graphics->getPic(-2),posporx,pospory+i*32);
 		}
 		}

+ 2 - 16
CPlayerInterface.h

@@ -155,20 +155,6 @@ public:
 	virtual void activate();
 	virtual void activate();
 	virtual void deactivate();
 	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
 class CInfoWindow : public CSimpleWindow //text + comp. + ok button
 { //window able to delete its components when closed
 { //window able to delete its components when closed
 public:
 public:
@@ -367,7 +353,6 @@ public:
 	void tileHidden(int3 pos);
 	void tileHidden(int3 pos);
 	void tileRevealed(int3 pos);
 	void tileRevealed(int3 pos);
 	void yourTurn();
 	void yourTurn();
-
 	//for battles
 	//for battles
 	//void actionFinished(BattleAction action);//occurs AFTER every action taken by any stack or by the hero
 	//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
 	//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 showComp(SComponent comp);
 	void openTownWindow(const CGTownInstance * town); //shows townscreen
 	void openTownWindow(const CGTownInstance * town); //shows townscreen
 	void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
 	void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
@@ -449,6 +434,7 @@ public:
 	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
 	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
 
 
 	CHeroList(int Size = 5);
 	CHeroList(int Size = 5);
+	int getPosOfHero(const CArmedInstance* h);
 	void genList();
 	void genList();
 	void select(int which);
 	void select(int which);
 	void mouseMoved (SDL_MouseMotionEvent & sEvent);
 	void mouseMoved (SDL_MouseMotionEvent & sEvent);

+ 2 - 0
client/Client.cpp

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

+ 4 - 0
client/FunctionList.h

@@ -32,6 +32,10 @@ public:
 	//	funcs.push_back(first);
 	//	funcs.push_back(first);
 	//	return first;
 	//	return first;
 	//}
 	//}
+	void clear()
+	{
+		funcs.clear();
+	}
 	operator bool() const
 	operator bool() const
 	{
 	{
 		return funcs.size();
 		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;
 class CGameInfo;
 extern CGameInfo* CGI;
 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 F_NUMBER = 9; //factions (town types) quantity
 const int PLAYER_LIMIT = 8; //player limit per map
 const int PLAYER_LIMIT = 8; //player limit per map
@@ -132,6 +132,22 @@ namespace vstd
 	{
 	{
 		return std::find(c.begin(),c.end(),i);
 		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>
 	template <typename Container, typename Item>
 	typename Container::iterator find(Container & c, const Item &i)
 	typename Container::iterator find(Container & c, const Item &i)
 	{
 	{
@@ -146,6 +162,21 @@ namespace vstd
 		c.erase(itr);
 		c.erase(itr);
 		return true;
 		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-=;
 using vstd::operator-=;
 #endif //GLOBAL_H
 #endif //GLOBAL_H

+ 1 - 0
int3.h

@@ -1,6 +1,7 @@
 #ifndef INT3_H
 #ifndef INT3_H
 #define INT3_H
 #define INT3_H
 #include <map>
 #include <map>
+#include <vector>
 class CCreature;
 class CCreature;
 class CCreatureSet //seven combined creatures
 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 CScriptCallback::getSelectedHero()
 {	
 {	
 	//int ret;
 	//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 
 	//else 
 	//	ret = -1;;
 	//	ret = -1;;
 	return -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 CLuaCallback::getSelectedHero(lua_State * L) //(),returns int (ID of hero, -1 if no hero is seleceted)
 {
 {
 	//int ret;
 	//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 
 	//else 
 	//	ret = -1;
 	//	ret = -1;
 	//lua_pushinteger(L,ret);
 	//lua_pushinteger(L,ret);