1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-15 11:46:56 +02:00

* first part of end of battle window

* fixed heap corruption while exiting battle
This commit is contained in:
mateuszb 2008-09-05 16:08:25 +00:00
parent 6633fb86ef
commit 2af92aa170
6 changed files with 171 additions and 10 deletions

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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]);

View File

@ -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 ||

View File

@ -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;

View File

@ -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);