Procházet zdrojové kódy

* first part of end of battle window
* fixed heap corruption while exiting battle

mateuszb před 17 roky
rodič
revize
2af92aa170
6 změnil soubory, kde provedl 171 přidání a 10 odebrání
  1. 135 7
      CBattleInterface.cpp
  2. 21 1
      CBattleInterface.h
  3. 5 0
      CCallback.cpp
  4. 2 0
      CGameState.cpp
  5. 7 2
      CPlayerInterface.cpp
  6. 1 0
      CPlayerInterface.h

+ 135 - 7
CBattleInterface.cpp

@@ -16,6 +16,7 @@
 #include <queue>
 #include <sstream>
 #include "lib/CondSh.h"
+#include "lib/NetPacks.h"
 #ifndef __GNUC__
 const double M_PI = 3.14159265358979323846;
 #else
@@ -24,12 +25,11 @@ const double M_PI = 3.14159265358979323846;
 #endif
 
 extern SDL_Surface * screen;
-extern TTF_Font * GEOR13;
+extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
 extern SDL_Color zwykly;
-SDL_Surface * CBattleInterface::cellBorder, * CBattleInterface::cellShade;
 
 CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2)
-: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL), attackingInfo(NULL), myTurn(false)
+: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL), attackingInfo(NULL), myTurn(false), resWindow(NULL)
 {
 	givenCommand = new CondSh<BattleAction *>(NULL);
 	//initializing armies
@@ -157,14 +157,18 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
 
 	//prepairing graphic with cell borders
 	cellBorders = CSDL_Ext::newSurface(background->w, background->h, cellBorder);
-	*cellBorders->format->palette = *cellBorder->format->palette;
+	//copying palette
+	for(int g=0; g<cellBorder->format->palette->ncolors; ++g) //we assume that cellBorders->format->palette->ncolors == 256
+	{
+		cellBorders->format->palette->colors[g] = cellBorder->format->palette->colors[g];
+	}
+	//palette copied
 	for(int i=0; i<11; ++i) //rows
 	{
 		for(int j=0; j<15; ++j) //columns
 		{
 			int x = 58 + (i%2==0 ? 22 : 0) + 44*j;
 			int y = 86 + 42 * i;
-			//SDL_BlitSurface(cellBorder, NULL, cellBorders, &genRect(cellBorder->h, cellBorder->w, x, y));
 			for(int cellX = 0; cellX < cellBorder->w; ++cellX)
 			{
 				for(int cellY = 0; cellY < cellBorder->h; ++cellY)
@@ -197,6 +201,7 @@ CBattleInterface::~CBattleInterface()
 	delete bConsoleUp;
 	delete bConsoleDown;
 	delete console;
+	delete resWindow;
 	delete givenCommand;
 
 	delete attackingHero;
@@ -354,6 +359,12 @@ void CBattleInterface::show(SDL_Surface * to)
 	}
 	//units shown
 	projectileShowHelper(to);//showing projectiles
+
+	//showing window with result of battle
+	if(resWindow)
+	{
+		resWindow->show(to);
+	}
 }
 
 bool CBattleInterface::reverseCreature(int number, int hex, bool wideTrick)
@@ -864,6 +875,14 @@ void CBattleInterface::stackIsShooting(int ID, int dest)
 	attackingInfo->maxframe = creAnims[ID]->framesInGroup(attackingInfo->shootingGroup);
 }
 
+void CBattleInterface::battleFinished(const BattleResult& br)
+{
+	deactivate();
+
+	resWindow = new CBattleReslutWindow(br, genRect(561, 470, 165, 19), this);
+	resWindow->activate();
+}
+
 void CBattleInterface::showRange(SDL_Surface * to, int ID)
 {
 	/*for(int i=0; i<shadedHexes.size(); ++i)
@@ -1189,9 +1208,9 @@ CBattleHex::CBattleHex() : myNumber(-1), accesible(true), hovered(false), strict
 
 void CBattleHex::mouseMoved(SDL_MouseMotionEvent &sEvent)
 {
-	if(CBattleInterface::cellShade)
+	if(myInterface->cellShade)
 	{
-		if(CSDL_Ext::SDL_GetPixel(CBattleInterface::cellShade, sEvent.x-pos.x, sEvent.y-pos.y) == 0) //hovered pixel is outside hex
+		if(CSDL_Ext::SDL_GetPixel(myInterface->cellShade, sEvent.x-pos.x, sEvent.y-pos.y) == 0) //hovered pixel is outside hex
 		{
 			strictHovered = false;
 		}
@@ -1358,3 +1377,112 @@ void CBattleConsole::scrollDown(unsigned int by)
 	if(lastShown + by < texts.size())
 		lastShown += by;
 }
+
+CBattleReslutWindow::CBattleReslutWindow(const BattleResult &br, SDL_Rect & pos, const CBattleInterface * owner)
+{
+	this->pos = pos;
+	background = BitmapHandler::loadBitmap("CPRESULT.BMP", true);
+	graphics->blueToPlayersAdv(background, LOCPLINT->playerID);
+	SDL_Surface * pom = SDL_ConvertSurface(background, screen->format, screen->flags);
+	SDL_FreeSurface(background);
+	background = pom;
+	exit = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleReslutWindow::bExitf,this), 549, 524, "iok6432.def", false, NULL, false);
+
+	if(br.winner==0) //attacker won
+	{
+		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 60, 122, GEOR16, zwykly, background);
+		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 410, 122, GEOR16, zwykly, background);
+	}
+	else //if(br.winner==1)
+	{
+		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 60, 122, GEOR16, zwykly, background);
+		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 410, 122, GEOR16, zwykly, background);
+	}
+
+	
+	CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[407], 235, 299, GEOR16, tytulowy, background);
+	CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[408], 235, 329, GEOR16, zwykly, background);
+	CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[409], 235, 426, GEOR16, zwykly, background);
+
+	std::string attackerName, defenderName;
+
+	if(owner->attackingHeroInstance) //a hero attacked
+	{
+		SDL_BlitSurface(graphics->portraitLarge[owner->attackingHeroInstance->portrait], NULL, background, &genRect(64, 58, 21, 38));
+		//setting attackerName
+		attackerName = owner->attackingHeroInstance->name;
+	}
+	else //a monster attacked
+	{
+		int bestMonsterID = -1;
+		int bestPower = 0;
+		for(std::map<si32,std::pair<ui32,si32> >::const_iterator it = owner->army1->slots.begin(); it!=owner->army1->slots.end(); ++it)
+		{
+			if( CGI->creh->creatures[it->first].AIValue > bestPower)
+			{
+				bestPower = CGI->creh->creatures[it->first].AIValue;
+				bestMonsterID = it->first;
+			}
+		}
+		SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &genRect(64, 58, 21, 38));
+		//setting attackerName
+		attackerName =  CGI->creh->creatures[bestMonsterID].namePl;
+	}
+	if(owner->defendingHeroInstance) //a hero defended
+	{
+		SDL_BlitSurface(graphics->portraitLarge[owner->defendingHeroInstance->portrait], NULL, background, &genRect(64, 58, 391, 38));
+		//setting defenderName
+		defenderName = owner->defendingHeroInstance->name;
+	}
+	else //a monster defended
+	{
+		int bestMonsterID = -1;
+		int bestPower = 0;
+		for(std::map<si32,std::pair<ui32,si32> >::const_iterator it = owner->army2->slots.begin(); it!=owner->army2->slots.end(); ++it)
+		{
+			if( CGI->creh->creatures[it->first].AIValue > bestPower)
+			{
+				bestPower = CGI->creh->creatures[it->first].AIValue;
+				bestMonsterID = it->first;
+			}
+		}
+		SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &genRect(64, 58, 391, 38));
+		//setting defenderName
+		defenderName =  CGI->creh->creatures[bestMonsterID].namePl;
+	}
+
+	//printing attacker and defender's names
+	CSDL_Ext::printAtMiddle(attackerName, 156, 44, GEOR16, zwykly, background);
+	CSDL_Ext::printAtMiddle(defenderName, 314, 44, GEOR16, zwykly, background);
+
+}
+
+CBattleReslutWindow::~CBattleReslutWindow()
+{
+	SDL_FreeSurface(background);
+}
+
+void CBattleReslutWindow::activate()
+{
+	exit->activate();
+}
+
+void CBattleReslutWindow::deactivate()
+{
+	exit->deactivate();
+}
+
+void CBattleReslutWindow::show(SDL_Surface *to)
+{
+	//evaluating to
+	if(!to)
+		to = screen;
+
+	SDL_BlitSurface(background, NULL, to, &pos);
+	exit->show(to);
+}
+
+void CBattleReslutWindow::bExitf()
+{
+	LOCPLINT->battleResultQuited();
+}

+ 21 - 1
CBattleInterface.h

@@ -9,6 +9,7 @@ class CDefHandler;
 class CStack;
 class CCallback;
 class AdventureMapButton;
+struct BattleResult;
 template <typename T> struct CondSh;
 
 class CBattleHero : public IShowable, public CIntObject
@@ -69,6 +70,22 @@ public:
 	void scrollDown(unsigned int by = 1); //scrolls console up by 'by' positions
 };
 
+class CBattleReslutWindow : public IShowable, public CIntObject, public IActivable
+{
+private:
+	SDL_Surface * background;
+	AdventureMapButton * exit;
+public:
+	CBattleReslutWindow(const BattleResult & br, SDL_Rect & pos, const CBattleInterface * owner); //c-tor
+	~CBattleReslutWindow(); //d-tor
+
+	void bExitf();
+
+	void activate();
+	void deactivate();
+	void show(SDL_Surface * to = 0);
+};
+
 class CBattleInterface : public CMainInterface
 {
 private:
@@ -121,9 +138,10 @@ public:
 	bool printCellBorders; //if true, cell borders will be printed
 	CBattleHex bfield[187]; //11 lines, 17 hexes on each
 	std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
-	static SDL_Surface * cellBorder, * cellShade;
+	SDL_Surface * cellBorder, * cellShade;
 	CondSh<BattleAction *> *givenCommand; //data != NULL if we have i.e. moved current unit
 	bool myTurn; //if true, interface is active (commands can be ordered
+	CBattleReslutWindow * resWindow; //window of end of battle
 
 	//button handle funcs:
 	void bOptionsf();
@@ -153,6 +171,8 @@ public:
 	void newRound(int number); //caled when round is ended; number is the number of round
 	void hexLclicked(int whichOne); //hex only call-in
 	void stackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest
+	void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed
 
 	friend class CBattleHex;
+	friend class CBattleReslutWindow;
 };

+ 5 - 0
CCallback.cpp

@@ -456,6 +456,11 @@ std::map<int, CStack> CCallback::battleGetStacks()
 {
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	std::map<int, CStack> ret;
+	if(!gs->curB) //there is no battle
+	{
+		return ret;
+	}
+
 	for(int g=0; g<gs->curB->stacks.size(); ++g)
 	{
 		ret[gs->curB->stacks[g]->ID] = *(gs->curB->stacks[g]);

+ 2 - 0
CGameState.cpp

@@ -1200,6 +1200,8 @@ bool CGameState::battleShootCreatureStack(int ID, int dest)
 
 int CGameState::battleGetStack(int pos)
 {
+	if(!curB)
+		return -1;
 	for(int g=0; g<curB->stacks.size(); ++g)
 	{
 		if(curB->stacks[g]->position == pos ||

+ 7 - 2
CPlayerInterface.cpp

@@ -2008,8 +2008,13 @@ BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn
 
 void CPlayerInterface::battleEnd(BattleResult *br)
 {
-	boost::unique_lock<boost::mutex> un(*pim);
-	curint->deactivate();
+	((CBattleInterface*)curint)->battleFinished(*br);
+}
+
+void CPlayerInterface::battleResultQuited()
+{
+	//boost::unique_lock<boost::mutex> un(*pim);
+	((CBattleInterface*)curint)->resWindow->deactivate();
 	objsToBlit -= curint;
 	delete curint;
 	curint = adventureInt;

+ 1 - 0
CPlayerInterface.h

@@ -360,6 +360,7 @@ public:
 	BattleAction activeStack(int stackID); //called when it's turn of that stack
 	void battleAttack(BattleAttack *ba);
 	void battleEnd(BattleResult *br);
+	void battleResultQuited();
 	void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
 	void battleStackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest
 	void battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting);