1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-17 11:56:46 +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 <queue>
#include <sstream> #include <sstream>
#include "lib/CondSh.h" #include "lib/CondSh.h"
#include "lib/NetPacks.h"
#ifndef __GNUC__ #ifndef __GNUC__
const double M_PI = 3.14159265358979323846; const double M_PI = 3.14159265358979323846;
#else #else
@ -24,12 +25,11 @@ const double M_PI = 3.14159265358979323846;
#endif #endif
extern SDL_Surface * screen; extern SDL_Surface * screen;
extern TTF_Font * GEOR13; extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
extern SDL_Color zwykly; extern SDL_Color zwykly;
SDL_Surface * CBattleInterface::cellBorder, * CBattleInterface::cellShade;
CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2) 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); givenCommand = new CondSh<BattleAction *>(NULL);
//initializing armies //initializing armies
@ -157,14 +157,18 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
//prepairing graphic with cell borders //prepairing graphic with cell borders
cellBorders = CSDL_Ext::newSurface(background->w, background->h, cellBorder); 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 i=0; i<11; ++i) //rows
{ {
for(int j=0; j<15; ++j) //columns for(int j=0; j<15; ++j) //columns
{ {
int x = 58 + (i%2==0 ? 22 : 0) + 44*j; int x = 58 + (i%2==0 ? 22 : 0) + 44*j;
int y = 86 + 42 * i; 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 cellX = 0; cellX < cellBorder->w; ++cellX)
{ {
for(int cellY = 0; cellY < cellBorder->h; ++cellY) for(int cellY = 0; cellY < cellBorder->h; ++cellY)
@ -197,6 +201,7 @@ CBattleInterface::~CBattleInterface()
delete bConsoleUp; delete bConsoleUp;
delete bConsoleDown; delete bConsoleDown;
delete console; delete console;
delete resWindow;
delete givenCommand; delete givenCommand;
delete attackingHero; delete attackingHero;
@ -354,6 +359,12 @@ void CBattleInterface::show(SDL_Surface * to)
} }
//units shown //units shown
projectileShowHelper(to);//showing projectiles projectileShowHelper(to);//showing projectiles
//showing window with result of battle
if(resWindow)
{
resWindow->show(to);
}
} }
bool CBattleInterface::reverseCreature(int number, int hex, bool wideTrick) 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); 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) void CBattleInterface::showRange(SDL_Surface * to, int ID)
{ {
/*for(int i=0; i<shadedHexes.size(); ++i) /*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) 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; strictHovered = false;
} }
@ -1358,3 +1377,112 @@ void CBattleConsole::scrollDown(unsigned int by)
if(lastShown + by < texts.size()) if(lastShown + by < texts.size())
lastShown += by; 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 CStack;
class CCallback; class CCallback;
class AdventureMapButton; class AdventureMapButton;
struct BattleResult;
template <typename T> struct CondSh; template <typename T> struct CondSh;
class CBattleHero : public IShowable, public CIntObject class CBattleHero : public IShowable, public CIntObject
@ -69,6 +70,22 @@ public:
void scrollDown(unsigned int by = 1); //scrolls console up by 'by' positions 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 class CBattleInterface : public CMainInterface
{ {
private: private:
@ -121,9 +138,10 @@ public:
bool printCellBorders; //if true, cell borders will be printed bool printCellBorders; //if true, cell borders will be printed
CBattleHex bfield[187]; //11 lines, 17 hexes on each CBattleHex bfield[187]; //11 lines, 17 hexes on each
std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield 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 CondSh<BattleAction *> *givenCommand; //data != NULL if we have i.e. moved current unit
bool myTurn; //if true, interface is active (commands can be ordered bool myTurn; //if true, interface is active (commands can be ordered
CBattleReslutWindow * resWindow; //window of end of battle
//button handle funcs: //button handle funcs:
void bOptionsf(); void bOptionsf();
@ -153,6 +171,8 @@ public:
void newRound(int number); //caled when round is ended; number is the number of round void newRound(int number); //caled when round is ended; number is the number of round
void hexLclicked(int whichOne); //hex only call-in 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 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 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); boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
std::map<int, CStack> ret; std::map<int, CStack> ret;
if(!gs->curB) //there is no battle
{
return ret;
}
for(int g=0; g<gs->curB->stacks.size(); ++g) for(int g=0; g<gs->curB->stacks.size(); ++g)
{ {
ret[gs->curB->stacks[g]->ID] = *(gs->curB->stacks[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) int CGameState::battleGetStack(int pos)
{ {
if(!curB)
return -1;
for(int g=0; g<curB->stacks.size(); ++g) for(int g=0; g<curB->stacks.size(); ++g)
{ {
if(curB->stacks[g]->position == pos || 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) void CPlayerInterface::battleEnd(BattleResult *br)
{ {
boost::unique_lock<boost::mutex> un(*pim); ((CBattleInterface*)curint)->battleFinished(*br);
curint->deactivate(); }
void CPlayerInterface::battleResultQuited()
{
//boost::unique_lock<boost::mutex> un(*pim);
((CBattleInterface*)curint)->resWindow->deactivate();
objsToBlit -= curint; objsToBlit -= curint;
delete curint; delete curint;
curint = adventureInt; curint = adventureInt;

View File

@ -360,6 +360,7 @@ public:
BattleAction activeStack(int stackID); //called when it's turn of that stack BattleAction activeStack(int stackID); //called when it's turn of that stack
void battleAttack(BattleAttack *ba); void battleAttack(BattleAttack *ba);
void battleEnd(BattleResult *br); 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 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 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); void battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting);