From 2af92aa17006e204662d2160623e5ad9af8f54ad Mon Sep 17 00:00:00 2001 From: mateuszb Date: Fri, 5 Sep 2008 16:08:25 +0000 Subject: [PATCH] * first part of end of battle window * fixed heap corruption while exiting battle --- CBattleInterface.cpp | 142 ++++++++++++++++++++++++++++++++++++++++--- CBattleInterface.h | 22 ++++++- CCallback.cpp | 5 ++ CGameState.cpp | 2 + CPlayerInterface.cpp | 9 ++- CPlayerInterface.h | 1 + 6 files changed, 171 insertions(+), 10 deletions(-) diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index 6a8b7f13f..c890eaf39 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -16,6 +16,7 @@ #include #include #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(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; gformat->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; icellShade) { - 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 >::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 >::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(); +} diff --git a/CBattleInterface.h b/CBattleInterface.h index 6b93ffb13..f1abac1b4 100644 --- a/CBattleInterface.h +++ b/CBattleInterface.h @@ -9,6 +9,7 @@ class CDefHandler; class CStack; class CCallback; class AdventureMapButton; +struct BattleResult; template 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 *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; }; diff --git a/CCallback.cpp b/CCallback.cpp index 66dfeeac7..55ed83f2e 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -456,6 +456,11 @@ std::map CCallback::battleGetStacks() { boost::shared_lock lock(*gs->mx); std::map ret; + if(!gs->curB) //there is no battle + { + return ret; + } + for(int g=0; gcurB->stacks.size(); ++g) { ret[gs->curB->stacks[g]->ID] = *(gs->curB->stacks[g]); diff --git a/CGameState.cpp b/CGameState.cpp index 204b4cdcd..d9616bb86 100644 --- a/CGameState.cpp +++ b/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; gstacks.size(); ++g) { if(curB->stacks[g]->position == pos || diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index 0a2b1aa60..10786b9ab 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -2008,8 +2008,13 @@ BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn void CPlayerInterface::battleEnd(BattleResult *br) { - boost::unique_lock un(*pim); - curint->deactivate(); + ((CBattleInterface*)curint)->battleFinished(*br); +} + +void CPlayerInterface::battleResultQuited() +{ + //boost::unique_lock un(*pim); + ((CBattleInterface*)curint)->resWindow->deactivate(); objsToBlit -= curint; delete curint; curint = adventureInt; diff --git a/CPlayerInterface.h b/CPlayerInterface.h index 330aba524..c402a6c91 100644 --- a/CPlayerInterface.h +++ b/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);