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

* added Necropolis
* townlist in town screen and switching towns
* minor changes

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

+ 202 - 0
AdventureMapButton.h

@@ -3,6 +3,8 @@
 #include "hch\CDefHandler.h"
 #include "CGameInfo.h"
 #include "hch\CLodHandler.h"
+#include "hch\CPreGameTextHandler.h"
+#include "hch/CTownHandler.h"
 template <typename T>
 AdventureMapButton<T>::AdventureMapButton ()
 {
@@ -121,3 +123,203 @@ void AdventureMapButton<T>::deactivate()
 	Hoverable::deactivate();
 	KeyInterested::deactivate();
 }
+template <typename T>
+CTownList<T>::~CTownList()
+{
+	delete arrup;
+	delete arrdo;
+}
+template <typename T>
+CTownList<T>::CTownList(int Size, SDL_Rect * Pos, int arupx, int arupy, int ardox, int ardoy)
+:CList(Size)
+{
+	pos = *Pos;
+	arrup = CGI->spriteh->giveDef("IAM014.DEF");
+	arrdo = CGI->spriteh->giveDef("IAM015.DEF");
+
+	arrupp.x=arupx;
+	arrupp.y=arupy;
+	arrupp.w=arrup->ourImages[0].bitmap->w;
+	arrupp.h=arrup->ourImages[0].bitmap->h;
+	arrdop.x=ardox;
+	arrdop.y=ardoy;
+	arrdop.w=arrdo->ourImages[0].bitmap->w;
+	arrdop.h=arrdo->ourImages[0].bitmap->h;
+	posporx = arrdop.x;
+	pospory = arrupp.y + arrupp.h;
+
+	pressed = indeterminate;
+
+	from = 0;
+	
+}
+template<typename T>
+void CTownList<T>::genList()
+{
+	int howMany = LOCPLINT->cb->howManyTowns();
+	for (int i=0;i<howMany;i++)
+	{
+		items.push_back(LOCPLINT->cb->getTownInfo(i,0));
+	}
+}
+template<typename T>
+void CTownList<T>::select(int which)
+{
+	selected = which;
+	if (which>=items.size()) 
+		return;
+	if(owner)
+		(owner->*fun)();
+}
+template<typename T>
+void CTownList<T>::mouseMoved (SDL_MouseMotionEvent & sEvent)
+{
+	if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
+	{
+		if (from>0)
+			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advTListUp.first);
+		else
+			LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	}
+	else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
+	{
+		if ((items.size()-from)  >  SIZE)
+			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advTListDown.first);
+		else
+			LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	}
+	//if not buttons then heroes
+	int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
+	hx-=pos.x;
+	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
+	float ny = (float)hy/(float)32;
+	if ((ny>SIZE || ny<0) || (from+ny>=items.size()))
+	{
+		LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	};
+	//LOCPLINT->adventureInt->statusbar.print( items[from+ny]->name + ", " + items[from+ny]->town->name ); //TODO - uncomment when pointer to the town type is initialized
+}
+template<typename T>
+void CTownList<T>::clickLeft(tribool down)
+{
+	if (down)
+	{
+		/***************************ARROWS*****************************************/
+		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
+		{
+			blitAt(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
+			pressed = true;
+			return;
+		}
+		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>SIZE))
+		{
+			blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
+			pressed = false;
+			return;
+		}
+		/***************************TOWNS*****************************************/
+		int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
+		hx-=pos.x;
+		hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
+		float ny = (float)hy/(float)32;
+		if (ny>SIZE || ny<0)
+			return;
+		if (SIZE==5 && ((int)(ny+from))==selected && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
+			LOCPLINT->openTownWindow(items[selected]);//print town screen
+		else
+			select(ny+from);
+	}
+	else
+	{
+		if (indeterminate(pressed))
+			return;
+		if (pressed) //up
+		{
+			blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
+			pressed = indeterminate;
+			if (!down)
+			{
+				from--;
+				if (from<0)
+					from=0;
+				draw();
+			}
+		}
+		else if (!pressed) //down
+		{
+			blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
+			pressed = indeterminate;
+			if (!down)
+			{
+				from++;
+				//if (from<items.size()-5)
+				//	from=items.size()-5;
+				draw();
+			}
+		}
+		else
+			throw 0;
+
+	}
+}
+template<typename T>
+void CTownList<T>::clickRight(tribool down)
+{	
+	if (down)
+	{
+		/***************************ARROWS*****************************************/
+		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
+		{
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListUp.second,down,this);
+		}
+		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
+		{
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListDown.second,down,this);
+		}
+	}
+	else
+	{
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListUp.second,down,this);
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListDown.second,down,this);
+	}
+}
+template<typename T>
+void CTownList<T>::hover (bool on)
+{
+}
+template<typename T>
+void CTownList<T>::keyPressed (SDL_KeyboardEvent & key)
+{
+}
+template<typename T>
+void CTownList<T>::draw()
+{	
+	for (int iT=0+from;iT<SIZE+from;iT++)
+	{
+		int i = iT-from;
+		if (iT>=items.size())
+		{
+			blitAt(CGI->townh->getPic(-1),posporx,pospory+i*32);
+			continue;
+		}
+
+		blitAt(CGI->townh->getPic(items[iT]->subID,items[iT]->hasFort(),items[iT]->builded),posporx,pospory+i*32);
+
+		if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
+		{
+			blitAt(CGI->townh->getPic(-2),posporx,pospory+i*32);
+		}
+	}
+	if (from>0)
+		blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
+	else
+		blitAt(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y);
+
+	if (items.size()-from>SIZE)
+		blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
+	else
+		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
+}

+ 16 - 431
CAdvmapInterface.cpp

@@ -19,7 +19,7 @@
 #include <sstream>
 #include "AdventureMapButton.h"
 #include "CHeroWindow.h"
-
+#pragma warning (disable : 4355) 
 extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts
 
 using namespace boost::logic;
@@ -30,435 +30,6 @@ CAdvMapInt::~CAdvMapInt()
 	SDL_FreeSurface(bg);
 	delete heroWindow;
 }
-void CList::activate()
-{
-	ClickableL::activate();
-	ClickableR::activate();
-	Hoverable::activate();
-	KeyInterested::activate();
-	MotionInterested::activate();
-}; 
-void CList::deactivate()
-{
-	ClickableL::deactivate();
-	ClickableR::deactivate();
-	Hoverable::deactivate();
-	KeyInterested::deactivate();
-	MotionInterested::deactivate();
-}; 
-void CList::clickLeft(tribool down)
-{
-};
-CHeroList::CHeroList()
-{
-	pos = genRect(192,64,609,196);
-	
-	arrupp = genRect(16,64,609,196);
-	arrdop = genRect(16,64,609,372);
- //32px per hero
-	posmobx = 610;
-	posmoby = 213;
-	posporx = 617;
-	pospory = 212;
-	posmanx = 666;
-	posmany = 213;
-	
-	arrup = CGI->spriteh->giveDef("IAM012.DEF");
-	arrdo = CGI->spriteh->giveDef("IAM013.DEF");
-	mobile = CGI->spriteh->giveDef("IMOBIL.DEF");
-	mana = CGI->spriteh->giveDef("IMANA.DEF");
-	empty = CGI->bitmaph->loadBitmap("HPSXXX.bmp");
-	selection = CGI->bitmaph->loadBitmap("HPSYYY.bmp");
-	SDL_SetColorKey(selection,SDL_SRCCOLORKEY,SDL_MapRGB(selection->format,0,255,255));
-	from = 0;
-	pressed = indeterminate;
-}
-
-void CHeroList::init()
-{
-	bg = CSDL_Ext::newSurface(68,193,ekran);
-	SDL_BlitSurface(LOCPLINT->adventureInt->bg,&genRect(193,68,607,196),bg,&genRect(193,68,0,0));
-}
-void CHeroList::genList()
-{
-	int howMany = LOCPLINT->cb->howManyHeroes();
-	for (int i=0;i<howMany;i++)
-	{
-		items.push_back(std::pair<const CGHeroInstance *,CPath *>(LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,i,0),NULL));
-	}
-}
-void CHeroList::select(int which)
-{
-	selected = which;
-	if (which>=items.size()) 
-		return;
-	LOCPLINT->adventureInt->centerOn(items[which].first->pos);
-	LOCPLINT->adventureInt->selection.type = HEROI_TYPE;
-	LOCPLINT->adventureInt->selection.selected = items[which].first;
-	LOCPLINT->adventureInt->terrain.currentPath = items[which].second;
-	draw();
-	LOCPLINT->adventureInt->townList.draw();
-	
-	LOCPLINT->adventureInt->infoBar.draw(NULL);
-}
-void CHeroList::clickLeft(tribool down)
-{
-	if (down)
-	{
-		/***************************ARROWS*****************************************/
-		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
-		{
-			blitAt(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
-			pressed = true;
-			return;
-		}
-		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
-		{
-			blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
-			pressed = false;
-			return;
-		}
-		/***************************HEROES*****************************************/
-		int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
-		hx-=pos.x;
-		hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
-		float ny = (float)hy/(float)32;
-		if (ny>=5 || ny<0)
-			return;
-		if (((int)(ny+from))==selected)
-			LOCPLINT->openHeroWindow(items[selected].first);//print hero screen
-		select(ny+from);
-	}
-	else
-	{
-		if (indeterminate(pressed))
-			return;
-		if (pressed) //up
-		{
-			blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
-			pressed = indeterminate;
-			if (!down)
-			{
-				from--;
-				if (from<0)
-					from=0;
-				draw();
-			}
-		}
-		else if (!pressed) //down
-		{
-			blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
-			pressed = indeterminate;
-			if (!down)
-			{
-				from++;
-				//if (from<items.size()-5)
-				//	from=items.size()-5;
-				draw();
-			}
-		}
-		else
-			throw 0;
-
-	}
-}
-void CHeroList::mouseMoved (SDL_MouseMotionEvent & sEvent)
-{
-	if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
-	{
-		if (from>0)
-			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advHListUp.first);
-		else
-			LOCPLINT->adventureInt->statusbar.clear();
-		return;
-	}
-	else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
-	{
-		if ((items.size()-from)  >  5)
-			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advHListDown.first);
-		else
-			LOCPLINT->adventureInt->statusbar.clear();
-		return;
-	}
-	//if not buttons then heroes
-	int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
-	hx-=pos.x;
-	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
-	float ny = (float)hy/(float)32;
-	if ((ny>5 || ny<0) || (from+ny>=items.size()))
-	{
-		LOCPLINT->adventureInt->statusbar.clear();
-		return;
-	}
-	std::vector<std::string> temp;
-	temp+=(items[from+ny].first->name),(items[from+ny].first->type->heroClass->name);
-	LOCPLINT->adventureInt->statusbar.print( processStr(CGI->generaltexth->allTexts[15],temp) );
-	//select(ny+from);
-}
-void CHeroList::clickRight(tribool down)
-{
-	if (down)
-	{
-		/***************************ARROWS*****************************************/
-		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
-		{
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListUp.second,down,this);
-		}
-		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
-		{
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListDown.second,down,this);
-		}
-	}
-	else
-	{
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListUp.second,down,this);
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListDown.second,down,this);
-	}
-}
-void CHeroList::hover (bool on)
-{
-}
-void CHeroList::keyPressed (SDL_KeyboardEvent & key)
-{
-}
-void CHeroList::updateHList()
-{
-	items.clear();
-	genList();
-}
-void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
-{
-	int ser = LOCPLINT->cb->getHeroSerial(which);
-	ser -= from;
-	int pom = (which->movement)/100;
-	blitAt(mobile->ourImages[pom].bitmap,posmobx,posmoby+ser*32); //move point
-}
-void CHeroList::draw()
-{	
-	for (int iT=0+from;iT<5+from;iT++)
-	{
-		int i = iT-from;
-		if (iT>=items.size())
-		{
-			blitAt(mobile->ourImages[0].bitmap,posmobx,posmoby+i*32);
-			blitAt(mana->ourImages[0].bitmap,posmanx,posmany+i*32);
-			blitAt(empty,posporx,pospory+i*32);
-			continue;
-		}
-		int pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->movement)/100;
-		if (pom>25) pom=25;
-		if (pom<0) pom=0;
-		blitAt(mobile->ourImages[pom].bitmap,posmobx,posmoby+i*32); //move point
-		pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->mana)/5; //bylo: .../10;
-		if (pom>25) pom=25;
-		if (pom<0) pom=0;
-		blitAt(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
-		SDL_Surface * temp = LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->type->portraitSmall;
-		blitAt(temp,posporx,pospory+i*32);
-		if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
-		{
-			blitAt(selection,posporx,pospory+i*32);
-		}
-		//TODO: support for custom portraits
-	}
-	if (from>0)
-		blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
-	else
-		blitAt(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y);
-
-	if (items.size()-from>5)
-		blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
-	else
-		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
-}
-CTownList::CTownList()
-{
-	pos = genRect(192,48,747,196);
-	arrup = CGI->spriteh->giveDef("IAM014.DEF");
-	arrdo = CGI->spriteh->giveDef("IAM015.DEF");
-
-	arrupp.x=747;
-	arrupp.y=196;
-	arrupp.w=arrup->ourImages[0].bitmap->w;
-	arrupp.h=arrup->ourImages[0].bitmap->h;
-	arrdop.x=747;
-	arrdop.y=372;
-	arrdop.w=arrdo->ourImages[0].bitmap->w;
-	arrdop.h=arrdo->ourImages[0].bitmap->h;
-	posporx = 747;
-	pospory = 212;
-
-	pressed = indeterminate;
-
-	from = 0;
-	
-}
-void CTownList::genList()
-{
-	int howMany = LOCPLINT->cb->howManyTowns();
-	for (int i=0;i<howMany;i++)
-	{
-		items.push_back(LOCPLINT->cb->getTownInfo(i,0));
-	}
-}
-void CTownList::select(int which)
-{
-	selected = which;
-	if (which>=items.size()) 
-		return;
-	LOCPLINT->adventureInt->centerOn(items[which]->pos);
-	LOCPLINT->adventureInt->selection.type = TOWNI_TYPE;
-	LOCPLINT->adventureInt->selection.selected = items[which];
-	LOCPLINT->adventureInt->terrain.currentPath = NULL;
-	draw();
-	LOCPLINT->adventureInt->heroList.draw();
-}
-void CTownList::mouseMoved (SDL_MouseMotionEvent & sEvent)
-{
-	if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
-	{
-		if (from>0)
-			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advTListUp.first);
-		else
-			LOCPLINT->adventureInt->statusbar.clear();
-		return;
-	}
-	else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
-	{
-		if ((items.size()-from)  >  5)
-			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advTListDown.first);
-		else
-			LOCPLINT->adventureInt->statusbar.clear();
-		return;
-	}
-	//if not buttons then heroes
-	int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
-	hx-=pos.x;
-	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
-	float ny = (float)hy/(float)32;
-	if ((ny>5 || ny<0) || (from+ny>=items.size()))
-	{
-		LOCPLINT->adventureInt->statusbar.clear();
-		return;
-	};
-	//LOCPLINT->adventureInt->statusbar.print( items[from+ny]->name + ", " + items[from+ny]->town->name ); //TODO - uncomment when pointer to the town type is initialized
-}
-void CTownList::clickLeft(tribool down)
-{
-	if (down)
-	{
-		/***************************ARROWS*****************************************/
-		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
-		{
-			blitAt(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
-			pressed = true;
-			return;
-		}
-		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
-		{
-			blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
-			pressed = false;
-			return;
-		}
-		/***************************TOWNS*****************************************/
-		int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
-		hx-=pos.x;
-		hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
-		float ny = (float)hy/(float)32;
-		if (ny>5 || ny<0)
-			return;
-		if (((int)(ny+from))==selected)
-			LOCPLINT->openTownWindow(items[selected]);//print town screen
-		else
-			select(ny+from);
-	}
-	else
-	{
-		if (indeterminate(pressed))
-			return;
-		if (pressed) //up
-		{
-			blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
-			pressed = indeterminate;
-			if (!down)
-			{
-				from--;
-				if (from<0)
-					from=0;
-				draw();
-			}
-		}
-		else if (!pressed) //down
-		{
-			blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
-			pressed = indeterminate;
-			if (!down)
-			{
-				from++;
-				//if (from<items.size()-5)
-				//	from=items.size()-5;
-				draw();
-			}
-		}
-		else
-			throw 0;
-
-	}
-}
-void CTownList::clickRight(tribool down)
-{	
-	if (down)
-	{
-		/***************************ARROWS*****************************************/
-		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
-		{
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListUp.second,down,this);
-		}
-		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
-		{
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListDown.second,down,this);
-		}
-	}
-	else
-	{
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListUp.second,down,this);
-			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advTListDown.second,down,this);
-	}
-}
-void CTownList::hover (bool on)
-{
-}
-void CTownList::keyPressed (SDL_KeyboardEvent & key)
-{
-}
-void CTownList::draw()
-{	
-	for (int iT=0+from;iT<5+from;iT++)
-	{
-		int i = iT-from;
-		if (iT>=items.size())
-		{
-			blitAt(CGI->townh->getPic(-1),posporx,pospory+i*32);
-			continue;
-		}
-
-		blitAt(CGI->townh->getPic(items[i]->subID,items[i]->hasFort(),items[i]->builded),posporx,pospory+i*32);
-
-		if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
-		{
-			blitAt(CGI->townh->getPic(-2),posporx,pospory+i*32);
-		}
-	}
-	if (from>0)
-		blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
-	else
-		blitAt(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y);
-
-	if (items.size()-from>5)
-		blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
-	else
-		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
-}
 CMinimap::CMinimap(bool draw)
 {
 	statusbarTxt = CGI->preth->advWorldMap.first;
@@ -1235,8 +806,12 @@ nextHero(CGI->preth->advNextHero.first,CGI->preth->advNextHero.second,
 		  &CAdvMapInt::fnextHero, 679, 324, "IAM000.DEF", this),
 
 endTurn(CGI->preth->advEndTurn.first,CGI->preth->advEndTurn.second,
-		  &CAdvMapInt::fendTurn, 679, 356, "IAM001.DEF", this)
+		  &CAdvMapInt::fendTurn, 679, 356, "IAM001.DEF", this),
+
+townList(5,&genRect(192,48,747,196),747,196,747,372)
 {
+	townList.owner = this;
+	townList.fun = &CAdvMapInt::selectionChanged;
 	LOCPLINT->adventureInt=this;
 	bg = CGI->bitmaph->loadBitmap("ADVMAP.bmp");
 	blueToPlayersAdv(bg,player);
@@ -1401,6 +976,16 @@ void CAdvMapInt::update()
 	//updateRect(&genRect(550,600,6,6));
 }
 
+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();
+}
 void CAdvMapInt::centerOn(int3 on)
 {
 	on.x -= (LOCPLINT->adventureInt->terrain.tilesw/2);

+ 2 - 61
CAdvmapInterface.h

@@ -35,66 +35,6 @@ public:
 	AdventureMapButton( std::string Name, std::string HelpBox, void(T::*Function)(), int x, int y, std::string defName, T* Owner, bool activ=false,  std::vector<std::string> * add = NULL );//c-tor
 };
 /*****************************/
-class CList 
-	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public virtual CIntObject, public MotionInterested
-{
-public:
-	SDL_Surface * bg;
-	CDefHandler *arrup, *arrdo;
-	SDL_Surface *empty, *selection; 
-	SDL_Rect arrupp, arrdop; //positions of arrows
-	int posw, posh; //position width/height
-	int selected, //id of selected position, <0 if none
-		from; 
-	tribool pressed; //true=up; false=down; indeterminate=none
-
-	void clickLeft(tribool down);
-	void activate(); 
-	void deactivate();
-	virtual void mouseMoved (SDL_MouseMotionEvent & sEvent)=0;
-	virtual void genList()=0;
-	virtual void select(int which)=0;
-	virtual void draw()=0;
-};
-class CHeroList 
-	: public CList
-{
-public:
-	CDefHandler *mobile, *mana;
-	std::vector<std::pair<const CGHeroInstance*, CPath *> > items;
-	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
-
-	CHeroList();
-	void genList();
-	void select(int which);
-	void mouseMoved (SDL_MouseMotionEvent & sEvent);
-	void clickLeft(tribool down);
-	void clickRight(tribool down);
-	void hover (bool on);
-	void keyPressed (SDL_KeyboardEvent & key);
-	void updateHList();
-	void updateMove(const CGHeroInstance* which); //draws move points bar
-	void redrawAllOne(int which);
-	void draw();
-	void init();
-};
-class CTownList 
-	: public CList
-{
-public: 
-	std::vector<const CGTownInstance*> items;
-	int posporx,pospory;
-
-	CTownList();
-	void genList();
-	void select(int which);
-	void mouseMoved (SDL_MouseMotionEvent & sEvent);
-	void clickLeft(tribool down);
-	void clickRight(tribool down);
-	void hover (bool on);
-	void keyPressed (SDL_KeyboardEvent & key);
-	void draw();
-};
 class CMinimap
 	: public ClickableL, public ClickableR, public Hoverable, public MotionInterested, public virtual CIntObject
 {
@@ -220,7 +160,7 @@ public:
 	CResDataBar resdatabar;
 	
 	CHeroList heroList;
-	CTownList townList;	
+	CTownList<CAdvMapInt> townList;	
 	CInfoBar infoBar;
 
 	CHeroWindow * heroWindow;
@@ -251,6 +191,7 @@ public:
 	void hide(); //deactivates advmap interface
 	void update(); //redraws terrain
 
+	void selectionChanged();
 	void centerOn(int3 on);
 	int3 verifyPos(int3 ver);
 	void handleRightClick(std::string text, tribool down, CIntObject * client);

+ 1 - 1
CCallback.cpp

@@ -421,7 +421,7 @@ int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance
 				S2->slots.erase(p2);
 			if(s1->tempOwner<PLAYER_LIMIT)
 				CGI->playerint[s1->tempOwner]->garrisonChanged(s1);
-			if(s2->tempOwner<PLAYER_LIMIT)
+			if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
 				CGI->playerint[s2->tempOwner]->garrisonChanged(s2);
 			return 0;
 		}

+ 30 - 9
CCastleInterface.cpp

@@ -8,7 +8,6 @@
 #include "hch/CTownHandler.h"
 #include "AdventureMapButton.h"
 #include <sstream>
-
 CBuildingRect::CBuildingRect(Structure *Str)
 :str(Str)
 {	
@@ -151,23 +150,32 @@ public:
 } srthlp ;
 
 CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
-{
-	hBuild = NULL;
-	count=0;
-	town = Town;
+{	
 	townInt = CGI->bitmaph->loadBitmap("TOWNSCRN.bmp");
-	cityBg = CGI->bitmaph->loadBitmap(getBgName(town->subID));
+	cityBg = CGI->bitmaph->loadBitmap(getBgName(Town->subID));
 	hall = CGI->spriteh->giveDef("ITMTL.DEF");
 	fort = CGI->spriteh->giveDef("ITMCL.DEF");
 	bigTownPic =  CGI->spriteh->giveDef("ITPT.DEF");
 	flag =  CGI->spriteh->giveDef("CREST58.DEF");
-	CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
+	townlist = new CTownList<CCastleInterface>(3,&genRect(128,48,744,414),744,414,744,526);
 	exit = new AdventureMapButton<CCastleInterface>
 		(CGI->townh->tcommands[8],"",&CCastleInterface::close,744,544,"TSBTNS.DEF",this,false);
 	split = new AdventureMapButton<CCastleInterface>
-		(CGI->townh->tcommands[8],"",&CCastleInterface::splitF,744,382,"TSBTNS.DEF",this,false);
-	exit->bitmapOffset = 4;
+		(CGI->townh->tcommands[3],"",&CCastleInterface::splitF,744,382,"TSBTNS.DEF",this,false);
 	statusbar = new CStatusBar(8,555,"TSTATBAR.bmp",732);
+
+	townlist->owner = this;
+	townlist->fun = &CCastleInterface::townChange;
+	townlist->genList();
+	townlist->selected = getIndexOf(townlist->items,Town);
+	if((townlist->selected+1) > townlist->SIZE)
+		townlist->from = townlist->selected -  townlist->SIZE + 1;
+	hBuild = NULL;
+	count=0;
+	town = Town;
+
+	CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
+	exit->bitmapOffset = 4;
 	std::set< std::pair<int,int> > s; //group - id
 
 
@@ -251,6 +259,8 @@ CCastleInterface::~CCastleInterface()
 	delete bigTownPic;
 	delete flag;
 	delete garr;
+	delete townlist;
+	delete statusbar;
 	for(int i=0;i<buildings.size();i++)
 	{
 		delete buildings[i];
@@ -276,6 +286,7 @@ void CCastleInterface::showAll(SDL_Surface * to)
 	blitAt(cityBg,0,0,to);
 	blitAt(townInt,0,374,to);
 	LOCPLINT->adventureInt->resdatabar.draw();
+	townlist->draw();
 
 	int pom;
 
@@ -353,6 +364,14 @@ void CCastleInterface::showAll(SDL_Surface * to)
 	//}
 	show();
 }
+void CCastleInterface::townChange()
+{
+	const CGTownInstance * nt = townlist->items[townlist->selected];
+	deactivate();
+	LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
+	delete this;
+	LOCPLINT->castleInt = new CCastleInterface(nt,true);
+}
 void CCastleInterface::show(SDL_Surface * to)
 {
 	if (!to)
@@ -393,6 +412,7 @@ void CCastleInterface::show(SDL_Surface * to)
 }
 void CCastleInterface::activate()
 {
+	townlist->activate();
 	garr->activate();
 	LOCPLINT->curint = this;
 	LOCPLINT->statusbar = statusbar;
@@ -403,6 +423,7 @@ void CCastleInterface::activate()
 }
 void CCastleInterface::deactivate()
 {
+	townlist->deactivate();
 	garr->deactivate();
 	exit->deactivate();
 	split->deactivate();

+ 3 - 0
CCastleInterface.h

@@ -39,6 +39,8 @@ public:
 	CDefHandler *hall,*fort,
 		*bigTownPic, *flag;
 
+	CTownList<CCastleInterface> * townlist;
+
 	CGarrisonInt * garr;
 	AdventureMapButton<CCastleInterface> * exit, *split;
 
@@ -46,6 +48,7 @@ public:
 
 	CCastleInterface(const CGTownInstance * Town, bool Activate=true);
 	~CCastleInterface();
+	void townChange();
 	void show(SDL_Surface * to=NULL);
 	void showAll(SDL_Surface * to=NULL);
 	void close();

+ 1 - 1
CHeroWindow.cpp

@@ -200,7 +200,7 @@ void CHeroWindow::setHero(const CGHeroInstance *hero)
 
 	delete garInt;
 	garInt = new CGarrisonInt(80, 493, 8, 0, curBack, 13, 482, curHero);
-
+	garInt->update = false;
 	for(int g=0; g<primSkillAreas.size(); ++g)
 	{
 		primSkillAreas[g]->bonus = hero->primSkills[g];

+ 2 - 3
CMT.cpp

@@ -280,7 +280,7 @@ int _tmain(int argc, _TCHAR* argv[])
 { 
 	//std::ios_base::sync_with_stdio(0);
 	//CLuaHandler luatest;
-	//luatest.test();
+	//luatest.test(); 
 	
 		//CBIKHandler cb;
 		//cb.open("CSECRET.BIK");
@@ -294,6 +294,7 @@ int _tmain(int argc, _TCHAR* argv[])
 	float i;
 	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO/*|SDL_INIT_EVENTTHREAD*/)==0)
 	{
+		screen = SDL_SetVideoMode(800,600,24,SDL_SWSURFACE|SDL_DOUBLEBUF/*|SDL_FULLSCREEN*/);
 		CPG=NULL;
 		TTF_Init();
 		atexit(TTF_Quit);
@@ -305,7 +306,6 @@ int _tmain(int argc, _TCHAR* argv[])
 		GEOR16 = TTF_OpenFont("Fonts\\georgia.ttf",16);
 		GEORXX = TTF_OpenFont("Fonts\\tnrb.ttf",22);
 		GEORM = TTF_OpenFont("Fonts\\georgia.ttf",10);
-
 		CMusicHandler * mush = new CMusicHandler;  //initializing audio
 		mush->initMusics();
 		//audio initialized 
@@ -316,7 +316,6 @@ int _tmain(int argc, _TCHAR* argv[])
 		}*/
 
 		//screen2 = SDL_SetVideoMode(800,600,24,SDL_SWSURFACE|SDL_DOUBLEBUF/*|SDL_FULLSCREEN*/);
-		screen = SDL_SetVideoMode(800,600,24,SDL_SWSURFACE|SDL_DOUBLEBUF/*|SDL_FULLSCREEN*/);
 		//screen = SDL_ConvertSurface(screen2, screen2->format, SDL_SWSURFACE);
 		ekran = screen;
 

+ 253 - 2
CPlayerInterface.cpp

@@ -21,6 +21,7 @@
 #include "timeHandler.h"
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/replace.hpp>
+#include "hch\CPreGameTextHandler.h"
 using namespace CSDL_Ext;
 
 extern TTF_Font * GEOR16;
@@ -155,14 +156,16 @@ void CGarrisonSlot::show()
 		printTo(buf,pos.x+56,pos.y+62,GEOR16,zwykly);
 		if(owner->highlighted==this)
 			blitAt(CGI->creh->bigImgs[-1],pos);
-		updateRect(&pos,ekran);
+		if(owner->update)
+			updateRect(&pos,ekran);
 		delete [] buf;
 	}
 	else
 	{
 		SDL_Rect jakis1 = genRect(pos.h,pos.w,owner->offx+ID*(pos.w+owner->interx),owner->offy+upg*(pos.h+owner->intery)), jakis2 = pos;
 		SDL_BlitSurface(owner->sur,&jakis1,ekran,&jakis2);
-		SDL_UpdateRect(ekran,pos.x,pos.y,pos.w,pos.h);
+		if(owner->update)
+			SDL_UpdateRect(ekran,pos.x,pos.y,pos.w,pos.h);
 	}
 }
 CGarrisonInt::~CGarrisonInt()
@@ -312,6 +315,7 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur,
 	set1 = LOCPLINT->cb->getGarrison(s1);
 	set2 = LOCPLINT->cb->getGarrison(s2);
 	ignoreEvent = false;
+	update = true;
 	pos.x=(x);
 	pos.y=(y);
 	pos.w=(58);
@@ -1961,4 +1965,251 @@ void CStatusBar::show()
 std::string CStatusBar::getCurrent()
 {
 	return current;
+}
+void CList::activate()
+{
+	ClickableL::activate();
+	ClickableR::activate();
+	Hoverable::activate();
+	KeyInterested::activate();
+	MotionInterested::activate();
+}; 
+void CList::deactivate()
+{
+	ClickableL::deactivate();
+	ClickableR::deactivate();
+	Hoverable::deactivate();
+	KeyInterested::deactivate();
+	MotionInterested::deactivate();
+}; 
+void CList::clickLeft(tribool down)
+{
+};
+CList::CList(int Size)
+:SIZE(Size)
+{
+}
+CHeroList::CHeroList(int Size)
+:CList(Size)
+{
+	pos = genRect(192,64,609,196);
+	
+	arrupp = genRect(16,64,609,196);
+	arrdop = genRect(16,64,609,372);
+ //32px per hero
+	posmobx = 610;
+	posmoby = 213;
+	posporx = 617;
+	pospory = 212;
+	posmanx = 666;
+	posmany = 213;
+	
+	arrup = CGI->spriteh->giveDef("IAM012.DEF");
+	arrdo = CGI->spriteh->giveDef("IAM013.DEF");
+	mobile = CGI->spriteh->giveDef("IMOBIL.DEF");
+	mana = CGI->spriteh->giveDef("IMANA.DEF");
+	empty = CGI->bitmaph->loadBitmap("HPSXXX.bmp");
+	selection = CGI->bitmaph->loadBitmap("HPSYYY.bmp");
+	SDL_SetColorKey(selection,SDL_SRCCOLORKEY,SDL_MapRGB(selection->format,0,255,255));
+	from = 0;
+	pressed = indeterminate;
+}
+
+void CHeroList::init()
+{
+	bg = CSDL_Ext::newSurface(68,193,ekran);
+	SDL_BlitSurface(LOCPLINT->adventureInt->bg,&genRect(193,68,607,196),bg,&genRect(193,68,0,0));
+}
+void CHeroList::genList()
+{
+	int howMany = LOCPLINT->cb->howManyHeroes();
+	for (int i=0;i<howMany;i++)
+	{
+		items.push_back(std::pair<const CGHeroInstance *,CPath *>(LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,i,0),NULL));
+	}
+}
+void CHeroList::select(int which)
+{
+	selected = which;
+	if (which>=items.size()) 
+		return;
+	LOCPLINT->adventureInt->centerOn(items[which].first->pos);
+	LOCPLINT->adventureInt->selection.type = HEROI_TYPE;
+	LOCPLINT->adventureInt->selection.selected = items[which].first;
+	LOCPLINT->adventureInt->terrain.currentPath = items[which].second;
+	draw();
+	LOCPLINT->adventureInt->townList.draw();
+	
+	LOCPLINT->adventureInt->infoBar.draw(NULL);
+}
+void CHeroList::clickLeft(tribool down)
+{
+	if (down)
+	{
+		/***************************ARROWS*****************************************/
+		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
+		{
+			blitAt(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
+			pressed = true;
+			return;
+		}
+		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
+		{
+			blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
+			pressed = false;
+			return;
+		}
+		/***************************HEROES*****************************************/
+		int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
+		hx-=pos.x;
+		hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
+		float ny = (float)hy/(float)32;
+		if (ny>=5 || ny<0)
+			return;
+		if (((int)(ny+from))==selected && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
+			LOCPLINT->openHeroWindow(items[selected].first);//print hero screen
+		select(ny+from);
+	}
+	else
+	{
+		if (indeterminate(pressed))
+			return;
+		if (pressed) //up
+		{
+			blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
+			pressed = indeterminate;
+			if (!down)
+			{
+				from--;
+				if (from<0)
+					from=0;
+				draw();
+			}
+		}
+		else if (!pressed) //down
+		{
+			blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
+			pressed = indeterminate;
+			if (!down)
+			{
+				from++;
+				//if (from<items.size()-5)
+				//	from=items.size()-5;
+				draw();
+			}
+		}
+		else
+			throw 0;
+
+	}
+}
+void CHeroList::mouseMoved (SDL_MouseMotionEvent & sEvent)
+{
+	if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
+	{
+		if (from>0)
+			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advHListUp.first);
+		else
+			LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	}
+	else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
+	{
+		if ((items.size()-from)  >  5)
+			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advHListDown.first);
+		else
+			LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	}
+	//if not buttons then heroes
+	int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
+	hx-=pos.x;
+	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
+	float ny = (float)hy/(float)32;
+	if ((ny>5 || ny<0) || (from+ny>=items.size()))
+	{
+		LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	}
+	std::vector<std::string> temp;
+	temp.push_back(items[from+ny].first->name);
+	temp.push_back(items[from+ny].first->type->heroClass->name);
+	LOCPLINT->adventureInt->statusbar.print( processStr(CGI->generaltexth->allTexts[15],temp) );
+	//select(ny+from);
+}
+void CHeroList::clickRight(tribool down)
+{
+	if (down)
+	{
+		/***************************ARROWS*****************************************/
+		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
+		{
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListUp.second,down,this);
+		}
+		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
+		{
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListDown.second,down,this);
+		}
+	}
+	else
+	{
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListUp.second,down,this);
+			LOCPLINT->adventureInt->handleRightClick(CGI->preth->advHListDown.second,down,this);
+	}
+}
+void CHeroList::hover (bool on)
+{
+}
+void CHeroList::keyPressed (SDL_KeyboardEvent & key)
+{
+}
+void CHeroList::updateHList()
+{
+	items.clear();
+	genList();
+}
+void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
+{
+	int ser = LOCPLINT->cb->getHeroSerial(which);
+	ser -= from;
+	int pom = (which->movement)/100;
+	blitAt(mobile->ourImages[pom].bitmap,posmobx,posmoby+ser*32); //move point
+}
+void CHeroList::draw()
+{	
+	for (int iT=0+from;iT<5+from;iT++)
+	{
+		int i = iT-from;
+		if (iT>=items.size())
+		{
+			blitAt(mobile->ourImages[0].bitmap,posmobx,posmoby+i*32);
+			blitAt(mana->ourImages[0].bitmap,posmanx,posmany+i*32);
+			blitAt(empty,posporx,pospory+i*32);
+			continue;
+		}
+		int pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->movement)/100;
+		if (pom>25) pom=25;
+		if (pom<0) pom=0;
+		blitAt(mobile->ourImages[pom].bitmap,posmobx,posmoby+i*32); //move point
+		pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->mana)/5; //bylo: .../10;
+		if (pom>25) pom=25;
+		if (pom<0) pom=0;
+		blitAt(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
+		SDL_Surface * temp = LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->type->portraitSmall;
+		blitAt(temp,posporx,pospory+i*32);
+		if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
+		{
+			blitAt(selection,posporx,pospory+i*32);
+		}
+		//TODO: support for custom portraits
+	}
+	if (from>0)
+		blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
+	else
+		blitAt(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y);
+
+	if (items.size()-from>5)
+		blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
+	else
+		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
 }

+ 68 - 1
CPlayerInterface.h

@@ -215,7 +215,7 @@ public:
 
 	SDL_Surface *sur;
 	int offx, offy;
-	bool ignoreEvent;
+	bool ignoreEvent, update;
 
 	const CCreatureSet *set1;
 	const CCreatureSet *set2;
@@ -312,4 +312,71 @@ public:
 	void clear();//clears statusbar and refreshes
 	void show(); //shows statusbar (with current text)
 	std::string getCurrent();
+};
+
+class CList 
+	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public virtual CIntObject, public MotionInterested
+{
+public:
+	SDL_Surface * bg;
+	CDefHandler *arrup, *arrdo;
+	SDL_Surface *empty, *selection; 
+	SDL_Rect arrupp, arrdop; //positions of arrows
+	int posw, posh; //position width/height
+	int selected, //id of selected position, <0 if none
+		from; 
+	const int SIZE;
+	tribool pressed; //true=up; false=down; indeterminate=none
+
+	CList(int Size = 5);
+	void clickLeft(tribool down);
+	void activate(); 
+	void deactivate();
+	virtual void mouseMoved (SDL_MouseMotionEvent & sEvent)=0;
+	virtual void genList()=0;
+	virtual void select(int which)=0;
+	virtual void draw()=0;
+};
+class CHeroList 
+	: public CList
+{
+public:
+	CDefHandler *mobile, *mana;
+	std::vector<std::pair<const CGHeroInstance*, CPath *> > items;
+	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
+
+	CHeroList(int Size = 5);
+	void genList();
+	void select(int which);
+	void mouseMoved (SDL_MouseMotionEvent & sEvent);
+	void clickLeft(tribool down);
+	void clickRight(tribool down);
+	void hover (bool on);
+	void keyPressed (SDL_KeyboardEvent & key);
+	void updateHList();
+	void updateMove(const CGHeroInstance* which); //draws move points bar
+	void redrawAllOne(int which);
+	void draw();
+	void init();
+};
+template<typename T>
+class CTownList 
+	: public CList
+{
+public: 
+	T* owner;
+	void(T::*fun)();
+	std::vector<const CGTownInstance*> items;
+	int posporx,pospory;
+
+	CTownList(int Size, SDL_Rect * Pos, int arupx, int arupy, int ardox, int ardoy);
+	~CTownList();
+	void genList();
+	void select(int which);
+	void mouseMoved (SDL_MouseMotionEvent & sEvent);
+	void clickLeft(tribool down);
+	void clickRight(tribool down);
+	void hover (bool on);
+	void keyPressed (SDL_KeyboardEvent & key);
+	void draw();
 };

+ 7 - 0
SDL_Extensions.h

@@ -13,6 +13,13 @@ void blitAtWR(SDL_Surface * src, SDL_Rect pos, SDL_Surface * dst=ekran);
 void blitAt(SDL_Surface * src, SDL_Rect pos, SDL_Surface * dst=ekran);
 void updateRect (SDL_Rect * rect, SDL_Surface * scr = ekran);
 bool isItIn(const SDL_Rect * rect, int x, int y);
+template <typename T> int getIndexOf(const std::vector<T> & v, const T & val)
+{
+	for(int i=0;i<v.size();i++)
+		if(v[i]==val)
+			return i;
+	return -1;
+}
 SDL_Rect genRect(int hh, int ww, int xx, int yy);
 namespace CSDL_Ext
 {

+ 44 - 2
config/buildings.txt

@@ -92,7 +92,7 @@
 2 23 TBTWEXT2.def 592 189
 2 11 TBTWHAL2.def 0 220
 2 12 TBTWHAL3.def 0 82
-2 12 TBTWHAL4.def 0 82
+2 13 TBTWHAL4.def 0 82
 2 10 TBTWHALL.def 0 259
 2 26 TBTWHOLY.def 237 14
 2 18 TBTWHRD1.def 0 47
@@ -151,4 +151,46 @@
 3 41 TBINUP_4.def 359 244
 3 42 TBINUP_5.def 220 282
 3 43 TBINUP_6.def 420 105
-3 8 TBINCAS2.def 222 44
+3 8 TBINCAS2.def 222 44
+4 16 TBNCBLAK.def 382 252
+4 8 TBNCCAS2.def 139 66
+4 9 TBNCCAS3.def 34 18
+4 7 TBNCCSTL.def 138 66
+4 6 TBNCDOCK.def 617 265
+4 30 TBNCDW_0.def 80 222
+4 31 TBNCDW_1.def 502 223
+4 32 TBNCDW_2.def 0 187
+4 33 TBNCDW_3.def 607 212
+4 34 TBNCDW_4.def 206 207
+4 35 TBNCDW_5.def 0 31
+4 36 TBNCDW_6.def 663 25
+4 21 TBNCEXT0.def 307 61
+4 22 TBNCEXT1.def 247 275
+4 -1 TBNCEXT2.def 25 279
+4 27 TBNCEXT3.def 307 246
+4 28 TBNCEXT4.def 321 255
+4 29 TBNCEXT5.def 475 257
+4 11 TBNCHAL2.def 482 56
+4 12 TBNCHAL3.def 478 26
+4 13 TBNCHAL4.def 481 26
+4 10 TBNCHALL.def 468 76
+4 26 TBNCHOLY.def 410 88
+4 18 TBNCHRD1.def 80 222
+4 19 TBNCHRD2.def 64 222
+4 1 TBNCMAG2.def 341 97
+4 2 TBNCMAG3.def 341 78
+4 3 TBNCMAG4.def 340 62
+4 4 TBNCMAG5.def 343 35
+4 0 TBNCMAGE.def 341 116
+4 14 TBNCMARK.def 347 215
+4 15 TBNCSILO.def 276 185
+4 17 TBNCSPEC.def 18 0
+4 5 TBNCTVRN.def 508 189
+4 37 TBNCUP_0.def 64 222
+4 38 TBNCUP_1.def 498 224
+4 39 TBNCUP_2.def 0 179
+4 40 TBNCUP_3.def 615 193
+4 41 TBNCUP_4.def 222 171
+4 42 TBNCUP_5.def 0 30
+4 43 TBNCUP_6.def 662 23
+4 20 TBNCBOAT.def 617 265

+ 31 - 0
config/buildings2.txt

@@ -108,6 +108,37 @@ CASTLE 3
 35
 42
 END
+CASTLE 4
+17
+0
+1
+2
+3
+4
+7
+8
+9
+32
+39
+26
+15
+14
+34
+41
+16
+5
+33
+40
+31
+38
+6
+30
+18
+37
+19
+22
+20
+END
 EOD
 
 ------------------------------------------------------------------

+ 39 - 1
config/buildings3.txt

@@ -147,4 +147,42 @@
 3	40	TBINUP_3.def	TOIDMN2.bmp	TZIDMN2.bmp
 3	41	TBINUP_4.def	TOIPIT2.bmp	TZIPIT2.bmp
 3	42	TBINUP_5.def	TOIEFR2.bmp	TZIEFR2.bmp
-3	43	TBINUP_6.def	TOIDVL2.bmp	TZIDVL2.bmp
+3	43	TBINUP_6.def	TOIDVL2.bmp	TZIDVL2.bmp
+4	16	TBNCBLAK.def	TONSMITA.bmp	TZNSMITA.bmp
+4	20	TBNCBOAT.def	TONSHPNA.bmp	TZNSHPNA.bmp
+4	8	TBNCCAS2.def	TONCAS2.bmp	TZNCAS2.bmp
+4	9	TBNCCAS3.def	TONCAS3.bmp	TZNCAS3.bmp
+4	7	TBNCCSTL.def	TONCAS1.bmp	TZNCAS1.bmp
+4	6	TBNCDOCK.def	TONSHPBA.bmp	TZNSHPBA.bmp
+4	30	TBNCDW0_.def	TONSKEL1.bmp	TZNSKEL1.bmp
+4	31	TBNCDW_1.def	TONZOMB1.bmp	TZNZOMB1.bmp
+4	32	TBNCDW_2.def	TONWIGH1.bmp	TZNWIGH1.bmp
+4	33	TBNCDW_3.def	TONVAM1.bmp	TZNVAM1.bmp
+4	34	TBNCDW_4.def	TONLICH1.bmp	TZNLICH1.bmp
+4	35	TBNCDW_5.def	TONBKN1.bmp	TZNBKN1.bmp
+4	36	TBNCDW_6.def	TONBON1.bmp	TZNBON1.bmp
+4	21	TBNCEXT0.def	TONNECRA.bmp	TZNNECRA.bmp
+4	22	TBNCEXT1.def	TONSKELT.bmp	TZNSKELT.bmp
+4	11	TBNCHAL2.def	TONHAL2.bmp	TZNHAL2.bmp
+4	12	TBNCHAL3.def	TONHAL3.bmp	TZNHAL3.bmp
+4	13	TBNCHAL4.def	TONHAL4.bmp	TZNHAL4.bmp
+4	10	TBNCHALL.def	TONHAL1.bmp	TZNHAL1.bmp
+4	26	TBNCHOLY.def	TONHOLYA.bmp	TZNHOLYA.bmp
+4	18	TBNCHRD1.def	TONSKE1H.bmp	TZNSKE1H.bmp
+4	19	TBNCHRD2.def	TONSKE2H.bmp	TZNSKE2H.bmp
+4	1	TBNCMAG2.def	TONMAG2.bmp	TZNMAG2.bmp
+4	2	TBNCMAG3.def	TONMAG3.bmp	TZNMAG3.bmp
+4	3	TBNCMAG4.def	TONMAG4.bmp	TZNMAG4.bmp
+4	4	TBNCMAG5.def	TONMAG5.bmp	TZNMAG5.bmp
+4	0	TBNCMAGE.def	TONMAG1.bmp	TZNMAG1.bmp
+4	14	TBNCMARK.def	TONMRK1.bmp	TZNMRK1.bmp
+4	15	TBNCSILO.def	TONMRK2.bmp	TZNMRK2.bmp
+4	17	TBNCSPEC.def	TONSHRDA.bmp	TZNSHRDA.bmp
+4	5	TBNCTVRN.def	TONTAV.bmp	TZNTAV.bmp
+4	37	TBNCUP0_.def	TONSKEL2.bmp	TZNSKEL2.bmp
+4	38	TBNCUP_1.def	TONZOMB2.bmp	TZNZOMB2.bmp
+4	39	TBNCUP_2.def	TONWIGH2.bmp	TZNWIGH2.bmp
+4	40	TBNCUP_3.def	TONVAM2.bmp	TZNVAM2.bmp
+4	41	TBNCUP_4.def	TONLICH2.bmp	TZNLICH2.bmp
+4	42	TBNCUP_5.def	TONBKN2.bmp	TZNBKN2.bmp
+4	43	TBNCUP_6.def	TONBON2.bmp	TZNBON2.bmp

+ 6 - 0
config/buildings4.txt

@@ -65,4 +65,10 @@ GROUP
 39
 24
 25
+CASTLE 4
+GROUP
+30
+37
+18
+19
 EOD

+ 1 - 1
hch/CHeroHandler.cpp

@@ -500,7 +500,7 @@ unsigned int CHeroHandler::level(unsigned int experience)
 	while(experience>=expPerLevel[expPerLevel.size()-1])
 	{
 		experience/=1.2;
-		add+1;
+		add+=1;
 	}
 	for(int i=expPerLevel.size()-1; i>=0; --i)
 	{