Browse Source

* icon in infobox showing that there is hero in town garrison
* fort/citadel/castle screen

Michał W. Urbańczyk 17 năm trước cách đây
mục cha
commit
61e66fa89c
9 tập tin đã thay đổi với 361 bổ sung112 xóa
  1. 2 2
      CAdvmapInterface.cpp
  2. 200 62
      CCastleInterface.cpp
  3. 34 11
      CCastleInterface.h
  4. 8 0
      CGameState.cpp
  5. 88 30
      CPlayerInterface.cpp
  6. 19 4
      CPlayerInterface.h
  7. 3 3
      client/Client.cpp
  8. 5 0
      client/Graphics.cpp
  9. 2 0
      client/Graphics.h

+ 2 - 2
CAdvmapInterface.cpp

@@ -712,8 +712,8 @@ void CInfoBar::draw(const CGObjectInstance * specific)
 	else if (specific->ID == 98)
 	{
 		const CGTownInstance * t = static_cast<const CGTownInstance*>(specific);
-		if(graphics->townWins.find(t->identifier)!=graphics->townWins.end())
-			blitAt(graphics->townWins[t->identifier],pos.x,pos.y);
+		if(graphics->townWins.find(t->id)!=graphics->townWins.end())
+			blitAt(graphics->townWins[t->id],pos.x,pos.y);
 	}
 
 	//SDL_Surface * todr = LOCPLINT->infoWin(specific);

+ 200 - 62
CCastleInterface.cpp

@@ -14,9 +14,14 @@
 #include "hch/CGeneralTextHandler.h"
 #include "CCallback.h"
 #include "client/Graphics.h"
+#include "client/CCreatureAnimation.h"
 #include "CHeroWindow.h"
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/replace.hpp>
+#include <boost/assign/std/vector.hpp> 
+using namespace boost::assign;
+using namespace CSDL_Ext;
+
 extern TTF_Font * GEOR16;
 CBuildingRect::CBuildingRect(Structure *Str)
 :str(Str), moi(false), offset(0)
@@ -456,23 +461,21 @@ void CCastleInterface::buildingClicked(int building)
 	}
 	if(building >= 30)
 	{
-		if(building>36)
-			building-=7;
-		std::vector<std::pair<int,int > > crs;
-		int amount = (const_cast<CGTownInstance*>(town))->strInfo.creatures[building-30]; //trzeba odconstowac, bo inaczej operator [] by sypal :(
-
-		if(town->builtBuildings.find(building+7) != town->builtBuildings.end()) //check if there is an upgraded building
-			crs.push_back(std::make_pair(town->town->upgradedCreatures[building-30],amount));
-
-		crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
-
-		CRecrutationWindow *rw = new CRecrutationWindow(crs,boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
-		rw->activate();
+		LOCPLINT->curint->deactivate();
+		showRecruitmentWindow(building);
 	}
 	else
 	{
 		switch(building)
 		{
+		case 7: case 8: case 9:
+			{
+				CFortScreen *fs = new CFortScreen(this);
+				deactivate();
+				fs->activate();
+				fs->show();
+				break;
+			}
 		case 10: case 11: case 12: case 13:
 			enterHall();
 			break;
@@ -484,9 +487,10 @@ void CCastleInterface::buildingClicked(int building)
 void CCastleInterface::enterHall()
 {
 	deactivate();
-	hallInt = new CHallInterface(this);
-	hallInt->activate();
-	hallInt->show();
+	CHallInterface *h = new CHallInterface(this);
+	subInt = h;
+	h->activate();
+	h->show();
 }
 void CCastleInterface::showAll( SDL_Surface * to/*=NULL*/, bool forceTotalRedraw /*= false*/)
 {
@@ -767,46 +771,23 @@ void CCastleInterface::recreateBuildings()
 		}
 	}
 }
-void CHallInterface::CResDataBar::show(SDL_Surface * to)
-{
-	blitAt(bg,pos.x,pos.y);
-	char * buf = new char[15];
-	for (int i=0;i<7;i++)
-	{
-		SDL_itoa(LOCPLINT->cb->getResourceAmount(i),buf,10);
-		CSDL_Ext::printAtMiddle(buf,pos.x + 50 + 76*i,pos.y+pos.h/2,GEOR13,zwykly);
-	}
-	std::vector<std::string> temp;
-	SDL_itoa(LOCPLINT->cb->getDate(3),buf,10); temp.push_back(std::string(buf));
-	SDL_itoa(LOCPLINT->cb->getDate(2),buf,10); temp.push_back(buf);
-	SDL_itoa(LOCPLINT->cb->getDate(1),buf,10); temp.push_back(buf);
-	CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(
-		CGI->generaltexth->allTexts[62]
-			+": %s, "
-			+ CGI->generaltexth->allTexts[63]
-			+ ": %s, "
-			+	CGI->generaltexth->allTexts[64]
-			+ ": %s",temp)
-		,pos.x+545+(pos.w-545)/2,pos.y+pos.h/2,GEOR13,zwykly);
-	temp.clear();
-	//updateRect(&pos,screen);
-	delete[] buf;
-}
-CHallInterface::CResDataBar::CResDataBar()
-{
-	bg = BitmapHandler::loadBitmap("Z2ESBAR.bmp");
-	SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
-	graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
-	pos.x = 7;
-	pos.y = 575;
-	pos.w = bg->w;
-	pos.h = bg->h;
-}
-CHallInterface::CResDataBar::~CResDataBar()
+
+CRecrutationWindow * CCastleInterface::showRecruitmentWindow( int building )
 {
-	SDL_FreeSurface(bg);
-}
+	if(building>36)
+		building-=7;
+	std::vector<std::pair<int,int > > crs;
+	int amount = (const_cast<CGTownInstance*>(town))->strInfo.creatures[building-30]; //trzeba odconstowac, bo inaczej operator [] by sypal :(
+
+	if(town->builtBuildings.find(building+7) != town->builtBuildings.end()) //check if there is an upgraded building
+		crs.push_back(std::make_pair(town->town->upgradedCreatures[building-30],amount));
 
+	crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
+
+	CRecrutationWindow *rw = new CRecrutationWindow(crs,boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
+	rw->activate();	
+	return rw;
+}
 void CHallInterface::CBuildingBox::hover(bool on)
 {
 	Hoverable::hover(on);
@@ -828,7 +809,7 @@ void CHallInterface::CBuildingBox::clickLeft (tribool down)
 {
 	if(pressedL && (!down))
 	{
-		LOCPLINT->castleInt->hallInt->deactivate();
+		LOCPLINT->castleInt->subInt->deactivate();
 		new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,0);
 	}
 	ClickableL::clickLeft(down);
@@ -837,13 +818,14 @@ void CHallInterface::CBuildingBox::clickRight (tribool down)
 {
 	if(down)
 	{
-		LOCPLINT->castleInt->hallInt->deactivate();
+		LOCPLINT->castleInt->subInt->deactivate();
 		new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,1);
 	}
 	ClickableR::clickRight(down);
 }
 void CHallInterface::CBuildingBox::show(SDL_Surface * to)
 {
+	CHallInterface *hi = static_cast<CHallInterface*>(LOCPLINT->castleInt->subInt);
 	blitAt(LOCPLINT->castleInt->bicons->ourImages[BID].bitmap,pos.x,pos.y);
 	int pom, pom2=-1;
 	switch (state)
@@ -867,10 +849,10 @@ void CHallInterface::CBuildingBox::show(SDL_Surface * to)
 		pom = 3;
 		break;
 	}
-	blitAt(LOCPLINT->castleInt->hallInt->bars->ourImages[pom].bitmap,pos.x-1,pos.y+71);
+	blitAt(hi->bars->ourImages[pom].bitmap,pos.x-1,pos.y+71);
 	if(pom2>=0)
-		blitAt(LOCPLINT->castleInt->hallInt->status->ourImages[pom2].bitmap,pos.x+135, pos.y+54);
-	CSDL_Ext::printAtMiddle(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name,pos.x-1+LOCPLINT->castleInt->hallInt->bars->ourImages[0].bitmap->w/2,pos.y+71+LOCPLINT->castleInt->hallInt->bars->ourImages[0].bitmap->h/2, GEOR13,zwykly);
+		blitAt(hi->status->ourImages[pom2].bitmap,pos.x+135, pos.y+54);
+	CSDL_Ext::printAtMiddle(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name,pos.x-1+hi->bars->ourImages[0].bitmap->w/2,pos.y+71+hi->bars->ourImages[0].bitmap->h/2, GEOR13,zwykly);
 }
 void CHallInterface::CBuildingBox::activate()
 {
@@ -1052,19 +1034,19 @@ void CHallInterface::CBuildWindow::deactivate()
 void CHallInterface::CBuildWindow::Buy()
 {
 	deactivate();
-	LOCPLINT->castleInt->hallInt = NULL;
+	LOCPLINT->castleInt->subInt = NULL;
 	LOCPLINT->castleInt->activate();
 	LOCPLINT->cb->buildBuilding(LOCPLINT->castleInt->town,bid);
 	delete this;
-	delete LOCPLINT->castleInt->hallInt;
+	delete LOCPLINT->castleInt->subInt;
 	LOCPLINT->castleInt->showAll();
 }
 void CHallInterface::CBuildWindow::close()
 {
 	deactivate();
 	delete this;
-	LOCPLINT->castleInt->hallInt->activate();
-	LOCPLINT->castleInt->hallInt->show();
+	LOCPLINT->castleInt->subInt->activate();
+	LOCPLINT->castleInt->subInt->show();
 }
 void CHallInterface::CBuildWindow::clickRight (tribool down)
 {
@@ -1200,3 +1182,159 @@ CHallInterface::CBuildWindow::~CBuildWindow()
 		delete cancel;
 	}
 }
+
+
+CFortScreen::~CFortScreen()
+{
+	for(int i=0;i<crePics.size();i++)
+		delete crePics[i];
+	for (int i=0;i<recAreas.size();i++)
+		delete recAreas[i];
+	SDL_FreeSurface(bg);
+	delete exit;
+}
+
+void CFortScreen::show( SDL_Surface * to)
+{
+	blitAt(bg,0,0);
+	static unsigned char anim = 1;
+	for (int i=0; i<CREATURES_PER_TOWN; i++)
+	{
+		crePics[i]->blitPic(screen,positions[i].x+159,positions[i].y+4,!(anim%4));
+	}
+	anim++;
+	exit->show();
+}
+
+void CFortScreen::activate()
+{
+	LOCPLINT->curint = this;
+	exit->activate();
+	for (int i=0;i<recAreas.size();i++)
+	{
+		recAreas[i]->activate();
+	}
+	LOCPLINT->objsToBlit -= LOCPLINT->castleInt;
+	LOCPLINT->objsToBlit += this;
+}
+
+void CFortScreen::deactivate()
+{
+	exit->deactivate();
+	for (int i=0;i<recAreas.size();i++)
+	{
+		recAreas[i]->deactivate();
+	}
+	LOCPLINT->objsToBlit -= this;
+	LOCPLINT->objsToBlit += LOCPLINT->castleInt;
+}
+
+void CFortScreen::close()
+{
+	deactivate();
+	delete this;
+	LOCPLINT->castleInt->activate();
+	LOCPLINT->castleInt->showAll();
+}
+CFortScreen::CFortScreen( CCastleInterface * owner )
+{
+	bg = NULL;
+	exit = new AdventureMapButton(CGI->townh->tcommands[8],"",boost::bind(&CFortScreen::close,this),748,556,"TPMAGE1.DEF",false,NULL,false);
+	positions += genRect(126,386,10,22),genRect(126,386,404,22),
+		genRect(126,386,10,155),genRect(126,386,404,155),
+		genRect(126,386,10,288),genRect(126,386,404,288),
+		genRect(126,386,206,421);//genRect(126,386,10,421),genRect(126,386,404,421);
+	draw(owner,true);
+}
+
+void CFortScreen::draw( CCastleInterface * owner, bool first)
+{
+	if(bg)
+		SDL_FreeSurface(bg);
+	char buf[20];
+	memset(buf,0,20);
+	SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPCASTL7.bmp"),
+		*icons =  BitmapHandler::loadBitmap("ZPCAINFO.bmp");
+	SDL_SetColorKey(icons,SDL_SRCCOLORKEY,SDL_MapRGB(icons->format,0,255,255));
+	graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
+	bg = SDL_ConvertSurface(bg2,screen->format,0); 
+	SDL_FreeSurface(bg2);
+	printAtMiddle(CGI->buildh->buildings[owner->town->subID][owner->town->fortLevel()+6]->name,400,13,GEORXX,zwykly,bg);
+	for(int i=0;i<CREATURES_PER_TOWN; i++)
+	{
+		bool upgraded = owner->town->creatureDwelling(i,true);
+		bool present = owner->town->creatureDwelling(i,false);
+		CCreature *c = &CGI->creh->creatures[upgraded ? owner->town->town->upgradedCreatures[i] : owner->town->town->basicCreatures[i]];
+		printAtMiddle(c->namePl,positions[i].x+79,positions[i].y+10,GEOR13,zwykly,bg); //cr. name
+		blitAt(owner->bicons->ourImages[30+i+upgraded*7].bitmap,positions[i].x+4,positions[i].y+21,bg); //dwelling pic
+		printAtMiddle(CGI->buildh->buildings[owner->town->subID][30+i+upgraded*7]->name,positions[i].x+79,positions[i].y+100,GEOR13,zwykly,bg); //dwelling name
+		if(present) //if creature is present print avail able quantity
+		{
+			SDL_itoa(owner->town->strInfo.creatures.find(i)->second,buf,10);
+			printAtMiddle(CGI->generaltexth->allTexts[217] + buf,positions[i].x+79,positions[i].y+118,GEOR13,zwykly,bg);
+		}
+		blitAt(icons,positions[i].x+261,positions[i].y+3,bg);
+
+		//atttack
+		printAt(CGI->generaltexth->allTexts[190],positions[i].x+288,positions[i].y+5,GEOR13,zwykly,bg);
+		SDL_itoa(c->attack,buf,10);
+		printToWR(buf,positions[i].x+381,positions[i].y+18,GEOR13,zwykly,bg);
+
+		//defense
+		printAt(CGI->generaltexth->allTexts[191],positions[i].x+288,positions[i].y+25,GEOR13,zwykly,bg);
+		SDL_itoa(c->defence,buf,10);
+		printToWR(buf,positions[i].x+381,positions[i].y+38,GEOR13,zwykly,bg);
+
+		//damage
+		printAt(CGI->generaltexth->allTexts[199],positions[i].x+288,positions[i].y+46,GEOR13,zwykly,bg);
+		SDL_itoa(c->damageMin,buf,10);
+		int hlp=log10f(c->damageMin)+2;
+		buf[hlp-1]=' '; buf[hlp]='-'; buf[hlp+1]=' ';
+		SDL_itoa(c->damageMax,buf+hlp+2,10);
+		printToWR(buf,positions[i].x+381,positions[i].y+59,GEOR13,zwykly,bg);
+
+		//health
+		printAt(CGI->preth->zelp[439].first,positions[i].x+288,positions[i].y+66,GEOR13,zwykly,bg);
+		SDL_itoa(c->hitPoints,buf,10);
+		printToWR(buf,positions[i].x+381,positions[i].y+79,GEOR13,zwykly,bg);
+
+		//speed
+		printAt(CGI->preth->zelp[441].first,positions[i].x+288,positions[i].y+87,GEOR13,zwykly,bg);
+		SDL_itoa(c->speed,buf,10);
+		printToWR(buf,positions[i].x+381,positions[i].y+100,GEOR13,zwykly,bg);
+
+		if(present)//growth
+		{
+			printAt(CGI->generaltexth->allTexts[194],positions[i].x+288,positions[i].y+107,GEOR13,zwykly,bg);
+			SDL_itoa(owner->town->creatureGrowth(i),buf,10);
+			printToWR(buf,positions[i].x+381,positions[i].y+120,GEOR13,zwykly,bg);
+		}
+		if(first)
+		{
+			crePics.push_back(new CCreaturePic(c,false));
+			if(present)
+			{
+				recAreas.push_back(new RecArea(30+i+upgraded*7));
+				recAreas[recAreas.size()-1]->pos = positions[i];
+			}
+		}
+	}
+	SDL_FreeSurface(icons);
+}
+void CFortScreen::RecArea::clickLeft (tribool down)
+{
+	if(!down)
+	{
+		LOCPLINT->curint->deactivate();
+		CRecrutationWindow *rw = LOCPLINT->castleInt->showRecruitmentWindow(bid);
+		rw->buy->callback += boost::bind(&CFortScreen::draw, static_cast<CFortScreen*>(LOCPLINT->curint), LOCPLINT->castleInt, false);
+	}
+}
+void CFortScreen::RecArea::activate()
+{
+	ClickableL::activate();
+}
+void CFortScreen::RecArea::deactivate()
+{
+	ClickableL::deactivate();
+}

+ 34 - 11
CCastleInterface.h

@@ -55,7 +55,7 @@ public:
 	SDL_Surface * cityBg;
 	const CGTownInstance * town;
 	CStatusBar * statusbar;
-	CHallInterface * hallInt;
+	IShowActivable * subInt;
 	unsigned char animval, count;
 
 	CDefHandler *hall,*fort, *flag;
@@ -75,6 +75,8 @@ public:
 	void show(SDL_Surface * to=NULL);
 	void showAll(SDL_Surface * to=NULL, bool forceTotalRedraw = false);
 	void buildingClicked(int building);
+
+	CRecrutationWindow * showRecruitmentWindow(int building);
 	void enterHall();
 	void close();
 	void splitF();
@@ -84,18 +86,10 @@ public:
 	void removeBuilding(int bid);
 	void recreateBuildings();
 };
-
-class CHallInterface : public IShowable, public IActivable
+class CHallInterface : public IShowActivable
 {
 public:
-	class CResDataBar : public IShowable, public CIntObject
-	{
-	public:
-		SDL_Surface *bg;
-		void show(SDL_Surface * to=NULL);
-		CResDataBar();
-		~CResDataBar();
-	} resdatabar;
+	CMinorResDataBar resdatabar;
 
 	class CBuildingBox : public Hoverable, public ClickableL, public ClickableR
 	{
@@ -149,3 +143,32 @@ public:
 	void activate();
 	void deactivate();
 };
+
+class CFortScreen : public IShowActivable
+{
+	class RecArea : public ClickableL
+	{
+	public:
+		int bid;
+		RecArea(int BID):bid(BID){};
+		void clickLeft (tribool down);
+		void activate();
+		void deactivate();
+	};
+public:
+	CMinorResDataBar resdatabar;
+	AdventureMapButton *exit;
+	SDL_Surface * bg;
+	std::vector<SDL_Rect> positions;
+	std::vector<RecArea*> recAreas;
+	std::vector<CCreaturePic*> crePics;
+
+	CFortScreen(CCastleInterface * owner);
+
+	void draw( CCastleInterface * owner, bool first);
+	~CFortScreen();
+	void close();
+	void show(SDL_Surface * to=NULL);
+	void activate();
+	void deactivate();
+};

+ 8 - 0
CGameState.cpp

@@ -376,6 +376,14 @@ void CGameState::applyNL(IPack * pack)
 				int player = h->tempOwner;
 				nitr = std::find(players[player].heroes.begin(), players[player].heroes.end(), h);
 				players[player].heroes.erase(nitr);
+				if(h->visitedTown)
+				{
+					if(h->inTownGarrison)
+						h->visitedTown->garrisonHero = NULL;
+					else
+						h->visitedTown->visitingHero = NULL;
+					h->visitedTown = NULL;
+				}
 			}
 			map->objects[rh->id] = NULL;	
 

+ 88 - 30
CPlayerInterface.cpp

@@ -410,12 +410,18 @@ void CGarrisonInt::recreateSlots()
 {
 	splitting = false;
 	highlighted = NULL;
-	deactiveteSlots();
+	if(active)
+	{
+		deactiveteSlots();
+	}
 	deleteSlots();
 	createSlots();
-	ignoreEvent = true;
-	activeteSlots();
-	show();
+	if(active)
+	{
+		ignoreEvent = true;
+		activeteSlots();
+		show();
+	}
 }
 void CGarrisonInt::splitClick()
 {
@@ -438,6 +444,7 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur,
 	:interx(inx),intery(iny),sur(pomsur),highlighted(NULL),sup(NULL),sdown(NULL),oup(s1),odown(s2),
 	offx(OX),offy(OY)
 {
+	active = false;
 	splitting = false;
 	set1 = LOCPLINT->cb->getGarrison(s1);
 	set2 = LOCPLINT->cb->getGarrison(s2);
@@ -452,6 +459,7 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur,
 
 void CGarrisonInt::activate()
 {
+	active = true;
 	if(sup)
 	{
 		for(int i = 0; i<sup->size(); i++)
@@ -467,6 +475,7 @@ void CGarrisonInt::activate()
 }
 void CGarrisonInt::deactivate()
 {
+	active = false;
 	deactiveteSlots();
 }
 
@@ -999,7 +1008,7 @@ void CPlayerInterface::init(ICallback * CB)
 	for(int i=0;i<tt.size();i++)
 	{
 		SDL_Surface * pom = infoWin(tt[i]);
-		graphics->townWins.insert(std::pair<int,SDL_Surface*>(tt[i]->identifier,pom));
+		graphics->townWins.insert(std::pair<int,SDL_Surface*>(tt[i]->id,pom));
 	}
 }
 void CPlayerInterface::yourTurn()
@@ -1956,19 +1965,23 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 {
 	boost::unique_lock<boost::mutex> un(*pim);
 	//redraw infowindow
-	SDL_FreeSurface(graphics->townWins[town->subID]);
-	graphics->townWins[town->subID] = infoWin(town);
+	SDL_FreeSurface(graphics->townWins[town->id]);
+	graphics->townWins[town->id] = infoWin(town);
 	if(town->garrisonHero)
 	{
 		CGI->mh->hideObject(town->garrisonHero);
-		for(int i=0; i<adventureInt->heroList.items.size();i++)
+		if(adventureInt->heroList.items.size()==1) //it was the only hero
+			adventureInt->townList.select(0);
+		else
 		{
-			if(adventureInt->heroList.items[i].first == town->garrisonHero)
+			for(int i=0; i<adventureInt->heroList.items.size();i++)
 			{
-				adventureInt->heroList.items.erase(adventureInt->heroList.items.begin()+i);
-				if(adventureInt->heroList.selected >= adventureInt->heroList.items.size())
-					adventureInt->heroList.selected--;
-				break;
+				if(adventureInt->heroList.items[i].first == town->garrisonHero)
+				{
+					adventureInt->heroList.items.erase(adventureInt->heroList.items.begin()+i);
+						adventureInt->heroList.selected = adventureInt->heroList.items.size()-1;
+					break;
+				}
 			}
 		}
 	}
@@ -2011,7 +2024,7 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
 			hw->garInt->recreateSlots();
 			hw->garInt->show();
 		}
-		else if(castleInt == curint) //opened town window - redraw town garrsion slots (change is within hero garr)
+		else if(castleInt) //opened town window - redraw town garrsion slots (change is within hero garr)
 		{
 			castleInt->garr->highlighted = NULL;
 			castleInt->garr->recreateSlots();
@@ -2021,17 +2034,16 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
 	else if (obj->ID == 98) //town
 	{
 		const CGTownInstance * tt;
-		if(tt = dynamic_cast<const CGTownInstance*>(obj))
+		if(tt = static_cast<const CGTownInstance*>(obj))
 		{
-			SDL_FreeSurface(graphics->townWins[tt->identifier]);
-			graphics->townWins[tt->identifier] = infoWin(tt);
+			SDL_FreeSurface(graphics->townWins[tt->id]);
+			graphics->townWins[tt->id] = infoWin(tt);
 		}
 
-		const CCastleInterface *ci = dynamic_cast<CCastleInterface*>(curint);
-		if(ci)
+		if(LOCPLINT->castleInt)
 		{
-			ci->garr->highlighted = NULL;
-			ci->garr->recreateSlots();
+			LOCPLINT->castleInt->garr->highlighted = NULL;
+			LOCPLINT->castleInt->garr->recreateSlots();
 		}
 	}
 }
@@ -2689,7 +2701,7 @@ void CTownList::clickRight(tribool down)
 		}
 
 		//show popup
-		CInfoPopup * ip = new CInfoPopup(graphics->townWins[items[from+ny]->identifier],LOCPLINT->current->motion.x-graphics->townWins[items[from+ny]->identifier]->w,LOCPLINT->current->motion.y-graphics->townWins[items[from+ny]->identifier]->h,false);
+		CInfoPopup * ip = new CInfoPopup(graphics->townWins[items[from+ny]->id],LOCPLINT->current->motion.x-graphics->townWins[items[from+ny]->id]->w,LOCPLINT->current->motion.y-graphics->townWins[items[from+ny]->id]->h,false);
 		ip->activate();
 	}
 	else
@@ -2737,8 +2749,8 @@ void CTownList::draw()
 }
 
 
-CCreaturePic::CCreaturePic(CCreature *cre)
-:c(cre)
+CCreaturePic::CCreaturePic(CCreature *cre, bool Big)
+:c(cre),big(Big)
 {
 	anim = new CCreatureAnimation(cre->animDefName);
 }
@@ -2748,8 +2760,17 @@ CCreaturePic::~CCreaturePic()
 }
 int CCreaturePic::blitPic(SDL_Surface *to, int x, int y, bool nextFrame)
 {
-	blitAt(graphics->backgrounds[c->faction],x,y);//curx-50,pos.y+130-65);
-	SDL_Rect dst = genRect(130,100,x,y);
+	SDL_Rect dst;
+	if(big)
+	{
+		blitAt(graphics->backgrounds[c->faction],x,y);//curx-50,pos.y+130-65);
+		dst = genRect(130,100,x,y);
+	}
+	else
+	{
+		blitAt(graphics->backgroundsm[c->faction],x,y);//curx-50,pos.y+130-65);
+		dst = genRect(120,100,x,y);
+	}
 	if(c->isDoubleWide())
 		x-=15;
 	return anim->nextFrameMiddle(to,x+70,y+45,true,nextFrame,false,&dst);
@@ -2921,10 +2942,7 @@ CRecrutationWindow::CRecrutationWindow(const std::vector<std::pair<int,int> > &C
 	max = new AdventureMapButton("","",boost::bind(&CRecrutationWindow::Max,this),pos.x+134,pos.y+313,"IRCBTNS.DEF");
 	buy = new AdventureMapButton("","",boost::bind(&CRecrutationWindow::Buy,this),pos.x+212,pos.y+313,"IBY6432.DEF");
 	cancel = new AdventureMapButton("","",boost::bind(&CRecrutationWindow::Cancel,this),pos.x+290,pos.y+313,"ICN6432.DEF");
-	LOCPLINT->curint->deactivate();
-	//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, bool playerColoredButton = true );//c-tor
-}//(int x, int y, int totalw, T*Owner,void(T::*Moved)(int to), int Capacity, int Amount, int Value, bool Horizontal)
+}
 CRecrutationWindow::~CRecrutationWindow()
 {
 	for(int i=0;i<creatures.size();i++)
@@ -3350,4 +3368,44 @@ void CLevelWindow::show(SDL_Surface * to)
 	ok->show();
 	for(int i=0;i<comps.size();i++)
 		comps[i]->show();
+}
+
+void CMinorResDataBar::show(SDL_Surface * to)
+{
+	blitAt(bg,pos.x,pos.y);
+	char * buf = new char[15];
+	for (int i=0;i<7;i++)
+	{
+		SDL_itoa(LOCPLINT->cb->getResourceAmount(i),buf,10);
+		CSDL_Ext::printAtMiddle(buf,pos.x + 50 + 76*i,pos.y+pos.h/2,GEOR13,zwykly);
+	}
+	std::vector<std::string> temp;
+	SDL_itoa(LOCPLINT->cb->getDate(3),buf,10); temp.push_back(std::string(buf));
+	SDL_itoa(LOCPLINT->cb->getDate(2),buf,10); temp.push_back(buf);
+	SDL_itoa(LOCPLINT->cb->getDate(1),buf,10); temp.push_back(buf);
+	CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(
+		CGI->generaltexth->allTexts[62]
+	+": %s, "
+		+ CGI->generaltexth->allTexts[63]
+	+ ": %s, "
+		+	CGI->generaltexth->allTexts[64]
+	+ ": %s",temp)
+		,pos.x+545+(pos.w-545)/2,pos.y+pos.h/2,GEOR13,zwykly);
+	temp.clear();
+	//updateRect(&pos,screen);
+	delete[] buf;
+}
+CMinorResDataBar::CMinorResDataBar()
+{
+	bg = BitmapHandler::loadBitmap("Z2ESBAR.bmp");
+	SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
+	graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
+	pos.x = 7;
+	pos.y = 575;
+	pos.w = bg->w;
+	pos.h = bg->h;
+}
+CMinorResDataBar::~CMinorResDataBar()
+{
+	SDL_FreeSurface(bg);
 }

+ 19 - 4
CPlayerInterface.h

@@ -35,6 +35,7 @@ class IShowable
 {
 public:
 	virtual void show(SDL_Surface * to = NULL)=0;
+	virtual ~IShowable(){};
 };
 
 class IStatusBar
@@ -54,7 +55,11 @@ public:
 	virtual void deactivate()=0;
 	virtual ~IActivable(){};
 };
-
+class IShowActivable : public IShowable, public IActivable
+{
+public:
+	virtual ~IShowActivable(){};
+};
 class CIntObject //interface object
 {
 public:
@@ -458,12 +463,13 @@ public:
 	void draw();
 };
 
-class CCreaturePic //draws 100x130 picture with creature on background, use nextFrame=true to get animation
+class CCreaturePic //draws picture with creature on background, use nextFrame=true to get animation
 {
 public:
+	bool big; //big => 100x130; !big => 100x120
 	CCreature *c;
 	CCreatureAnimation *anim;
-	CCreaturePic(CCreature *cre);
+	CCreaturePic(CCreature *cre, bool Big=true);
 	~CCreaturePic();
 	int blitPic(SDL_Surface *to, int x, int y, bool nextFrame);
 	SDL_Surface * getPic(bool nextFrame);
@@ -569,6 +575,15 @@ public:
 	void show(SDL_Surface * to = NULL);
 };
 
+class CMinorResDataBar : public IShowable, public CIntObject
+{
+public:
+	SDL_Surface *bg;
+	void show(SDL_Surface * to=NULL);
+	CMinorResDataBar();
+	~CMinorResDataBar();
+};
+
 extern CPlayerInterface * LOCPLINT;
 
-#endif //CPLAYERINTERFACE_H
+#endif //CPLAYERINTERFACE_H

+ 3 - 3
client/Client.cpp

@@ -255,14 +255,14 @@ void CClient::process(int what)
 			RemoveObject rh;
 			*serv >> rh;
 			CGObjectInstance *obj = gs->map->objects[rh.id];
+			CGI->mh->removeObject(obj);
+			gs->apply(&rh);
 			if(obj->ID == 34)
 			{
-				CGHeroInstance *h = static_cast<CGHeroInstance*>(gs->map->objects[rh.id]);
+				CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
 				std::cout << "Removing hero with id = "<<(unsigned)rh.id<<std::endl;
 				playerint[h->tempOwner]->heroKilled(h);
 			}
-			CGI->mh->removeObject(obj);
-			gs->apply(&rh);
 			break;
 		}
 	case 501: //hero movement response - we have to notify interfaces and callback

+ 5 - 0
client/Graphics.cpp

@@ -84,6 +84,8 @@ SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh)
 		pom += F_NUMBER*2;
 	if(curh->builded >= MAX_BUILDING_PER_TURN)
 		pom++;
+	if(curh->garrisonHero)
+		blitAt(graphics->heroInGarrison,158,87,ret);
 	blitAt(bigTownPic->ourImages[pom].bitmap,13,13,ret);
 	delete[] buf;
 	return ret;
@@ -161,6 +163,7 @@ Graphics::Graphics()
 	tasks += boost::bind(&Graphics::initializeBattleGraphics,this);
 	tasks += GET_SURFACE(hInfo,"HEROQVBK.bmp");
 	tasks += GET_SURFACE(tInfo,"TOWNQVBK.bmp");
+	tasks += GET_SURFACE(heroInGarrison,"TOWNQKGH.bmp");
 	tasks += GET_DEF(artDefs,"ARTIFACT.DEF");
 	tasks += GET_DEF_ESS(forts,"ITMCLS.DEF");
 	tasks += GET_DEF_ESS(luck22,"ILCK22.DEF");
@@ -189,6 +192,8 @@ Graphics::Graphics()
 	{
 		ifs >> id >> name;
 		tasks += GET_SURFACE(backgrounds[id],name);
+		name.replace(0,5,"TPCAS");
+		tasks += GET_SURFACE(backgroundsm[id],name);
 	}
 
 	CThreadHelper th(&tasks,std::max((unsigned int)1,boost::thread::hardware_concurrency()));

+ 2 - 0
client/Graphics.h

@@ -15,6 +15,7 @@ public:
 	SDL_Color * neutralColor;
 	SDL_Color * playerColorPalette; //palette to make interface colors good - array of size [256]
 	SDL_Surface * hInfo, *tInfo; //hero and town infobox bgs
+	SDL_Surface *heroInGarrison; //icon for town infobox
 	std::vector<std::pair<int, int> > slotsPos; //creature slot positions in infoboxes
 	CDefEssential *luck22, *luck30, *luck42, *luck82,
 		*morale22, *morale30, *morale42, *morale82,
@@ -33,6 +34,7 @@ public:
 	std::map<int,SDL_Surface*> smallImgs; //creature ID -> small 32x32 img of creature; //ID=-2 is for blank (black) img; -1 for the border
 	std::map<int,SDL_Surface*> bigImgs; //creature ID -> big 58x64 img of creature; //ID=-2 is for blank (black) img; -1 for the border
 	std::map<int,SDL_Surface*> backgrounds; //castle ID -> 100x130 background creature image // -1 is for neutral
+	std::map<int,SDL_Surface*> backgroundsm; //castle ID -> 100x120 background creature image // -1 is for neutral
 	//for battles
 	std::vector< std::vector< std::string > > battleBacks; //battleBacks[terType] - vector of possible names for certain terrain type
 	std::vector< std::string > battleHeroes; //battleHeroes[hero type] - name of def that has hero animation for battle