Browse Source

* major optimization of infoBar drawing
* new day animation (TODO: dorobic zeby pierwsza klatka wchodzila - wkrotce sie tym zajme)
* some stuff for selection window
* minor improvements

Michał W. Urbańczyk 18 years ago
parent
commit
6cd90195f4
4 changed files with 328 additions and 49 deletions
  1. 88 8
      CAdvmapInterface.cpp
  2. 10 3
      CAdvmapInterface.h
  3. 192 30
      CPlayerInterface.cpp
  4. 38 8
      CPlayerInterface.h

+ 88 - 8
CAdvmapInterface.cpp

@@ -16,6 +16,7 @@
 #include <boost/algorithm/string/replace.hpp>
 #include "CLua.h"
 #include "hch/CHeroHandler.h"
+#include <sstream>
 extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts
 
 using namespace boost::logic;
@@ -1173,22 +1174,101 @@ void CResDataBar::draw()
 }
 CInfoBar::CInfoBar()
 {
+	toNextTick = mode = pom = -1;
 	pos.x=605;
 	pos.y=389;
 	pos.w=194;
 	pos.h=186;
+	day = CGI->spriteh->giveDef("NEWDAY.DEF");
+	week1 = CGI->spriteh->giveDef("NEWWEEK1.DEF");
+	week2 = CGI->spriteh->giveDef("NEWWEEK2.DEF");
+	week3 = CGI->spriteh->giveDef("NEWWEEK3.DEF");
+	week4 = CGI->spriteh->giveDef("NEWWEEK4.DEF");
 }
-void CInfoBar::draw(void * specific)
+CInfoBar::~CInfoBar()
 {
-	//if (!specific)
-	//	specific = LOCPLINT->adventureInt->selection.selected;
-	SDL_Surface * todr = LOCPLINT->infoWin(specific);
-	if (!todr)
+	delete day;
+	delete week1;
+	delete week2;
+	delete week3;
+	delete week4;
+}
+void CInfoBar::draw(const CGObjectInstance * specific)
+{
+	if (mode==1)
+	{
+		//blitAt(day->ourImages[pom].bitmap,pos.x+10,pos.y+10);
+		return;
+	}
+	else if (mode==2)
+	{
+		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);
+	}
+	if (!specific)
+		specific = (const CGObjectInstance *)LOCPLINT->adventureInt->selection.selected; 
+	//TODO: to rzutowanie wyglada groznie, ale dziala. Ale nie powinno wygladac groznie.
+
+	if(!specific)
 		return;
-	blitAt(todr,pos.x,pos.y);
-	//SDL_Flip(ekran);
-	SDL_FreeSurface(todr);
+
+	if(specific->ID == 34) //hero
+	{
+		if(LOCPLINT->heroWins.find(specific->subID)!=LOCPLINT->heroWins.end())
+			blitAt(LOCPLINT->heroWins[specific->subID],pos.x,pos.y);
+
+	}
+
+	//SDL_Surface * todr = LOCPLINT->infoWin(specific);
+	//if (!todr)
+	//	return;
+	//blitAt(todr,pos.x,pos.y);
+	//SDL_FreeSurface(todr);
+}
+
+void CInfoBar::newDay(int Day)
+{
+	mode = 1; //showing day
+	pom = 0;
+	TimeInterested::activate();
+	toNextTick = 500;
+	//blitAt(day->ourImages[pom].bitmap,pos.x+10,pos.y+10);
+}
+
+void CInfoBar::showComp(SComponent * comp, int time)
+{
+}
+
+void CInfoBar::tick()
+{
+	if (mode == 1) //new day animation
+	{
+		pom++;
+		if (pom >= day->ourImages.size())
+		{
+			TimeInterested::deactivate();
+			toNextTick = -1;
+			mode = 2;
+			draw();
+			return;
+		}
+		toNextTick = 250;
+		blitAt(day->ourImages[pom].bitmap,pos.x+10,pos.y+10);
+		std::stringstream txt;
+		txt << CGI->generaltexth->allTexts[64] << " " << LOCPLINT->cb->getDate(1);
+		printAtMiddle(txt.str(),700,420,TNRB16,zwykly);
+		if (pom == day->ourImages.size()-1)
+			toNextTick+=750;
+	}
 }
+
 CAdvMapInt::CAdvMapInt(int Player)
 :player(Player),
 statusbar(7,556),

+ 10 - 3
CAdvmapInterface.h

@@ -186,11 +186,19 @@ public:
 	void draw();
 };
 class CInfoBar
-	:public virtual CIntObject
+	:public virtual CIntObject, public TimeInterested
 {
 public:
+	CDefHandler *day, *week1, *week2, *week3, *week4;
+	int mode;
+	int pom;
+
 	CInfoBar();
-	void draw(void * specific=NULL); // if specific==0 function draws info about selected hero/town
+	~CInfoBar();
+	void newDay(int Day);
+	void showComp(SComponent * comp, int time=5000);
+	void tick();
+	void draw(const CGObjectInstance * specific=NULL); // if specific==0 function draws info about selected hero/town
 };
 /*****************************/
 class CAdvMapInt //adventure map interface
@@ -203,7 +211,6 @@ public:
 	int player;
 
 	std::vector<CDefHandler *> gems;
-
 	
 	bool scrollingLeft ;
 	bool scrollingRight ;

+ 192 - 30
CPlayerInterface.cpp

@@ -107,6 +107,73 @@ void SComponent::deactivate()
 {
 	ClickableR::deactivate();
 }
+
+void CSelectableComponent::clickLeft(tribool down)
+{
+	if (down)
+	{
+		select(true);
+
+	}
+}
+CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, SDL_Surface * Border)
+:SComponent(Type,Sub,Val)
+{
+	if (Border) //use custom border
+	{
+		border = Border;
+	}
+	else //we need to draw border
+	{
+		SDL_Surface * symb = SComponent::getImg();
+		border = CSDL_Ext::newSurface(symb->w+2,symb->h+2,symb);
+		SDL_FillRect(border,NULL,0x00FFFF);
+		for (int i=0;i<border->w;i++)
+		{
+			SDL_PutPixel(border,i,0,239,215,123);
+			SDL_PutPixel(border,i,(border->h)-1,239,215,123);
+		}
+		for (int i=0;i<border->h;i++)
+		{
+			SDL_PutPixel(border,0,i,239,215,123);
+			SDL_PutPixel(border,(border->w)-1,i,239,215,123);
+		}
+		SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255));	
+	}
+	selected = false;
+}
+void CSelectableComponent::activate()
+{
+	SComponent::activate();
+	ClickableL::activate();
+}
+void CSelectableComponent::deactivate()
+{
+	SComponent::deactivate();
+	ClickableL::deactivate();
+}
+SDL_Surface * CSelectableComponent::getImg()
+{
+	return myBitmap;
+}
+void CSelectableComponent::select(bool on)
+{
+	if(on != selected)
+	{
+		blitAt(SComponent::getImg(),1,1,myBitmap);
+		if (on)
+		{
+			blitAt(SComponent::getImg(),0,0,border);
+		}
+		selected = on;
+		return;
+	}
+	else 
+	{
+		return;
+	}
+}
+
 void CSimpleWindow::show(SDL_Surface * to)
 {
 	if(!to)
@@ -122,6 +189,28 @@ CSimpleWindow::~CSimpleWindow()
 	}
 }
 
+void CSelWindow::selectionChange(SComponent * to)
+{
+	for (int i=0;i<components.size();i++)
+	{
+		if(components[i]==to)
+			continue;
+		CSelectableComponent * pom = dynamic_cast<CSelectableComponent*>(components[i]);
+		if (!pom)
+			continue;
+		pom->select(false);
+	}
+}
+void CSelWindow::okClicked(tribool down)
+{
+	if(!down)
+		close();
+}
+void CSelWindow::close()
+{
+	//call owner with selection result
+	CInfoWindow::close();
+}
 template <typename T>CSCButton<T>::CSCButton(CDefHandler * img, CIntObject * obj, void(T::*poin)(tribool), T* Delg)
 {
 	ourObj = obj;
@@ -259,7 +348,15 @@ void MotionInterested::deactivate()
 	LOCPLINT->
 		motioninterested.erase(std::find(LOCPLINT->motioninterested.begin(),LOCPLINT->motioninterested.end(),this));
 }
-
+void TimeInterested::activate()
+{
+	LOCPLINT->timeinterested.push_back(this);
+}
+void TimeInterested::deactivate()
+{
+	LOCPLINT->
+		timeinterested.erase(std::find(LOCPLINT->timeinterested.begin(),LOCPLINT->timeinterested.end(),this));
+}
 CPlayerInterface::CPlayerInterface(int Player, int serial)
 {
 	playerID=Player;
@@ -291,12 +388,20 @@ void CPlayerInterface::init(ICallback * CB)
 	cb = dynamic_cast<CCallback*>(CB);
 	CGI->localPlayer = serialID;
 	adventureInt = new CAdvMapInt(playerID);
+	
+	std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
+	for(int i=0;i<hh.size();i++)
+	{
+		SDL_Surface * pom = infoWin(hh[i]);
+		heroWins.insert(std::pair<int,SDL_Surface*>(hh[i]->subID,pom));
+	}
 }
 void CPlayerInterface::yourTurn()
 {
 	makingTurn = true;
 	CGI->localPlayer = serialID;
 	unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
+	adventureInt->infoBar.newDay(cb->getDate(1));
 	adventureInt->show();
 	//show rest of things
 
@@ -306,17 +411,26 @@ void CPlayerInterface::yourTurn()
 	SDL_setFramerate(mainFPSmng, 24);
 	SDL_Event sEvent;
 	//framerate keeper initialized
+	timeHandler th;
+	th.getDif();
 	for(;makingTurn;) // main loop
 	{
 		CGI->screenh->updateScreen();
-
+		int tv = th.getDif();
+		for (int i=0;i<timeinterested.size();i++)
+		{
+			if (timeinterested[i]->toNextTick>=0)
+				timeinterested[i]->toNextTick-=tv;
+			if (timeinterested[i]->toNextTick<0)
+				timeinterested[i]->tick();
+		}
 		LOCPLINT->adventureInt->updateScreen = false;
 		while (SDL_PollEvent(&sEvent))  //wait for event...
 		{
 			handleEvent(&sEvent);
 		}
 		++LOCPLINT->adventureInt->animValHitCount; //for animations
-		if(LOCPLINT->adventureInt->animValHitCount == 2)
+		if(LOCPLINT->adventureInt->animValHitCount == 4)
 		{
 			LOCPLINT->adventureInt->animValHitCount = 0;
 			++animVal;
@@ -939,6 +1053,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 		CSDL_Ext::update(ekran);
 		CGI->screenh->updateScreen();
 		LOCPLINT->adventureInt->anim++;
+		adventureInt->animValHitCount=0;
 		SDL_framerateDelay(mainFPSmng); //for animation purposes
 	} //for(int i=1; i<32; i+=4)
 	//main moving done
@@ -1009,46 +1124,69 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 	adventureInt->minimap.draw();
 	adventureInt->heroList.updateMove(ho);
 }
-void CPlayerInterface::heroKilled(const CGHeroInstance*)
+void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
 {
+	heroWins.erase(hero->ID);
 }
 void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
 {
+	if(heroWins.find(hero->subID)==heroWins.end())
+		heroWins.insert(std::pair<int,SDL_Surface*>(hero->subID,infoWin(hero)));
+}
+
+SDL_Surface * CPlayerInterface::drawHeroInfoWin(const CGHeroInstance * curh)
+{
+	char * buf = new char[10];
+	SDL_Surface * ret = copySurface(hInfo);
+	SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
+	blueToPlayersAdv(ret,playerID,1);
+	printAt(curh->name,75,15,GEOR13,zwykly,ret);
+	for (int i=0;i<PRIMARY_SKILLS;i++)
+	{
+		itoa(curh->primSkills[i],buf,10);
+		printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret);
+	}
+	for (std::map<int,std::pair<CCreature*,int> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
+	{
+		blitAt(CGI->creh->smallImgs[(*i).second.first->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
+		itoa((*i).second.second,buf,10);
+		printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret);
+	}
+	blitAt(curh->type->portraitLarge,11,12,ret);
+	itoa(curh->mana,buf,10);
+	printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points
+	delete buf;
+	blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret);
+	blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret);
+	//SDL_SaveBMP(ret,"inf1.bmp");
+	return ret;
+}
+
+SDL_Surface * CPlayerInterface::drawTownInfoWin(const CGTownInstance * curh)
+{
+	return NULL;
 }
 
-SDL_Surface * CPlayerInterface::infoWin(const void * specific) //specific=0 => draws info about selected town/hero //TODO - gdy sie dorobi sensowna hierarchie klas ins. to wywalic tego brzydkiego void*
+SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
 {
 	if (specific)
-		;//TODO: dorobic, ale w ogole to moze lepiej najpierw zastapic tego voida czym innym
+	{
+		switch (specific->ID)
+		{
+		case 34:
+			return drawHeroInfoWin(dynamic_cast<const CGHeroInstance*>(specific));
+			break;
+		default:
+			return NULL;
+			break;
+		}
+	}
 	else
 	{
 		if (adventureInt->selection.type == HEROI_TYPE)
 		{
-			char * buf = new char[10];
-			SDL_Surface * ret = copySurface(hInfo);
-			SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
-			blueToPlayersAdv(ret,playerID,1);
 			const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection.selected;
-			printAt(curh->name,75,15,GEOR13,zwykly,ret);
-			for (int i=0;i<PRIMARY_SKILLS;i++)
-			{
-				itoa(curh->primSkills[i],buf,10);
-				printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret);
-			}
-			for (std::map<int,std::pair<CCreature*,int> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
-			{
-				blitAt(CGI->creh->smallImgs[(*i).second.first->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
-				itoa((*i).second.second,buf,10);
-				printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret);
-			}
-			blitAt(curh->type->portraitLarge,11,12,ret);
-			itoa(curh->mana,buf,10);
-			printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points
-			delete buf;
-			blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret);
-			blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret);
-			//SDL_SaveBMP(ret,"inf1.bmp");
-			return ret;
+			return drawHeroInfoWin(curh);
 		}
 		else if (adventureInt->selection.type == TOWNI_TYPE)
 		{
@@ -1105,6 +1243,17 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 		case (SDLK_u):
 			{
 				adventureInt->underground.clickLeft(true);
+				break;
+			}
+		case (SDLK_m):
+			{
+				adventureInt->moveHero.clickLeft(true);
+				break;
+			}
+		case (SDLK_e):
+			{
+				adventureInt->endTurn.clickLeft(true);
+				break;
 			}
 		}
 	} //keydown end
@@ -1135,6 +1284,17 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 		case (SDLK_u):
 			{
 				adventureInt->underground.clickLeft(false);
+				break;
+			}
+		case (SDLK_m):
+			{
+				adventureInt->moveHero.clickLeft(false);
+				break;
+			}
+		case (SDLK_e):
+			{
+				adventureInt->endTurn.clickLeft(false);
+				break;
 			}
 		}
 	}//keyup end
@@ -1256,6 +1416,8 @@ int3 CPlayerInterface::repairScreenPos(int3 pos)
 }
 void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val)
 {
+	SDL_FreeSurface(heroWins[hero->ID]);//TODO: moznaby zmieniac jedynie fragment bitmapy zwiazany z dana umiejetnoscia
+	heroWins[hero->ID] = infoWin(hero); //a nie przerysowywac calosc. Troche roboty, obecnie chyba nie wartej swieczki.
 	if (adventureInt->selection.selected == hero)
 		adventureInt->infoBar.draw();
 	return;

+ 38 - 8
CPlayerInterface.h

@@ -97,7 +97,14 @@ public:
 	virtual void activate()=0;
 	virtual void deactivate()=0;
 };
-
+class TimeInterested: public virtual CIntObject
+{
+public:
+	int toNextTick;
+	virtual void tick()=0;
+	virtual void activate();
+	virtual void deactivate();
+};
 template <typename T> class CSCButton: public CButtonBase, public ClickableL //prosty guzik, ktory tylko zmienia obrazek
 {
 public:
@@ -117,12 +124,17 @@ class CInfoWindow : public CSimpleWindow //text + comp. + ok button
 public:
 	CSCButton<CInfoWindow> okb;
 	std::vector<SComponent*> components;
-	void okClicked(tribool down);
-	void close();
+	virtual void okClicked(tribool down);
+	virtual void close();
 	CInfoWindow();
 	~CInfoWindow();
 };
-
+class CSelWindow : public CInfoWindow //component selection window
+{
+	void selectionChange(SComponent * to);
+	void okClicked(tribool down);
+	void close();
+};
 class SComponent : public ClickableR
 {
 public:
@@ -138,11 +150,24 @@ public:
 
 	SComponent(Etype Type, int Subtype, int Val);
 	//SComponent(const & SComponent r);
-	SDL_Surface * getImg();
 	
 	void clickRight (tribool down);
+	virtual SDL_Surface * getImg();
+	virtual void activate();
+	virtual void deactivate();
+};
+
+class CSelectableComponent : public SComponent, public ClickableL
+{
+public:
+	bool selected;
+	SDL_Surface * border, *myBitmap;
+	void clickLeft(tribool down);
+	CSelectableComponent(Etype Type, int Sub, int Val, SDL_Surface * Border=NULL);
 	void activate();
 	void deactivate();
+	void select(bool on);
+	SDL_Surface * getImg();
 };
 
 class CPlayerInterface : public CGameInterface
@@ -161,29 +186,34 @@ public:
 	std::vector<Hoverable*> hoverable;
 	std::vector<KeyInterested*> keyinterested;
 	std::vector<MotionInterested*> motioninterested;
+	std::vector<TimeInterested*> timeinterested;
 	std::vector<IShowable*> objsToBlit;
 
 	SDL_Surface * hInfo;
 	std::vector<std::pair<int, int> > slotsPos;
 	CDefEssential *luck22, *luck30, *luck42, *luck82,
 		*morale22, *morale30, *morale42, *morale82;
+	std::map<int,SDL_Surface*> heroWins;
+	//std::map<int,SDL_Surface*> townWins;
 
 	//overloaded funcs from Interface
 	void yourTurn();
 	void heroMoved(const HeroMoveDetails & details);
 	void tileRevealed(int3 pos);
 	void tileHidden(int3 pos);
-	void heroKilled(const CGHeroInstance*);
-	void heroCreated(const CGHeroInstance*);
+	void heroKilled(const CGHeroInstance* hero);
+	void heroCreated(const CGHeroInstance* hero);
 	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
 	void receivedResource(int type, int val);
 	
-	SDL_Surface * infoWin(const void * specific); //specific=0 => draws info about selected town/hero //TODO - gdy sie dorobi sensowna hierarchie klas ins. to wywalic tego brzydkiego void*
+	SDL_Surface * infoWin(const CGObjectInstance * specific); //specific=0 => draws info about selected town/hero //TODO - gdy sie dorobi sensowna hierarchie klas ins. to wywalic tego brzydkiego void*
 	void handleEvent(SDL_Event * sEvent);
 	void init(ICallback * CB);
 	int3 repairScreenPos(int3 pos);
 	void showInfoDialog(std::string text, std::vector<SComponent*> & components);
 	void removeObjToBlit(IShowable* obj);
+	SDL_Surface * drawHeroInfoWin(const CGHeroInstance * curh);
+	SDL_Surface * drawTownInfoWin(const CGTownInstance * curh);
 
 	CPlayerInterface(int Player, int serial);
 };