From b95551a0be1ec83725e4632142031196d311d371 Mon Sep 17 00:00:00 2001 From: mateuszb Date: Mon, 10 Mar 2008 20:19:41 +0000 Subject: [PATCH] * another part of Battle interface --- CBattleInterface.cpp | 193 +++++++++++++++++-------------------------- CBattleInterface.h | 21 ++++- CCallback.cpp | 5 ++ CGameState.cpp | 103 ++++++++++++++++++++++- CGameState.h | 12 ++- CPlayerInterface.cpp | 4 +- CPlayerInterface.h | 3 +- mapHandler.cpp | 2 +- 8 files changed, 214 insertions(+), 129 deletions(-) diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index 03cdb3d03..b5ff11dcb 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -6,27 +6,24 @@ #include "AdventureMapButton.h" #include "hch\CHeroHandler.h" #include "hch\CDefHandler.h" +#include "CCallback.h" +#include "CGameState.h" extern SDL_Surface * screen; -CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2) : printCellBorders(true) +CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CCallback * callback, CGHeroInstance *hero1, CGHeroInstance *hero2, const std::vector< CStack* > & stcks) +: printCellBorders(true), cb(callback), stacks(stcks), attackingHeroInstance(hero1), defendingHeroInstance(hero2) { //initializing armies this->army1 = army1; this->army2 = army2; - for(std::map >::iterator i=army1->slots.begin(); i!=army1->slots.end(); ++i) + for(int b=0; bsecond.first->animDefName)); - creAnim1.push_back(new CCreatureAnimation(i->second.first->animDefName)); - creAnim1[creAnim1.size()-1]->setType(2); - } - for(std::map >::iterator i=army2->slots.begin(); i!=army2->slots.end(); ++i) - { - creAnim2.push_back(new CCreatureAnimation(i->second.first->animDefName)); - creAnim2[creAnim2.size()-1]->setType(2); + creAnims.push_back(new CCreatureAnimation(stacks[b]->creature->animDefName)); + creAnims[b]->setType(2); } //preparing menu background and terrain - std::vector< std::string > & backref = CGI->mh->battleBacks[ CGI->mh->ttiles[tile.x][tile.y][tile.z].terType ]; + std::vector< std::string > & backref = CGI->mh->battleBacks[ cb->battleGetBattlefieldType() ]; background = CGI->bitmaph->loadBitmap(backref[ rand() % backref.size()] ); menu = CGI->bitmaph->loadBitmap("CBAR.BMP"); CSDL_Ext::blueToPlayersAdv(menu, hero1->tempOwner); @@ -73,6 +70,14 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, i cellBorder = CSDL_Ext::alphaTransform(cellBorder); cellShade = CGI->bitmaph->loadBitmap("CCELLSHD.BMP"); cellShade = CSDL_Ext::alphaTransform(cellShade); + for(int h=0; h<187; ++h) + { + bfield[h].myNumber = h; + + int x = 14 + ((h/17)%2==0 ? 22 : 0) + 44*(h%17); + int y = 86 + 42 * (h/17); + bfield[h].pos = genRect(cellShade->h, cellShade->w, x, y); + } } CBattleInterface::~CBattleInterface() @@ -95,10 +100,8 @@ CBattleInterface::~CBattleInterface() SDL_FreeSurface(cellBorder); SDL_FreeSurface(cellShade); - for(int g=0; gactivate(); bConsoleUp->activate(); bConsoleDown->activate(); + for(int b=0; b<187; ++b) + { + bfield[b].activate(); + } } void CBattleInterface::deactivate() @@ -125,6 +132,10 @@ void CBattleInterface::deactivate() bDefence->deactivate(); bConsoleUp->deactivate(); bConsoleDown->deactivate(); + for(int b=0; b<187; ++b) + { + bfield[b].deactivate(); + } } void CBattleInterface::show(SDL_Surface * to) @@ -146,6 +157,16 @@ void CBattleInterface::show(SDL_Surface * to) } } } + //printing hovered cell + for(int b=0; b<187; ++b) + { + if(bfield[b].hovered) + { + int x = 14 + ((b/17)%2==0 ? 22 : 0) + 44*(b%17); + int y = 86 + 42 * (b/17); + CSDL_Ext::blit8bppAlphaTo24bpp(cellShade, NULL, to, &genRect(cellShade->h, cellShade->w, x, y)); + } + } //showing menu background blitAt(menu, 0, 556, to); @@ -167,107 +188,11 @@ void CBattleInterface::show(SDL_Surface * to) defendingHero->show(to); //showing units //a lot of work... - switch(creAnim1.size()) //for attacker + for(int j=0; jnextFrame(to, -116, 71, true); //6 - break; - case 2: - creAnim1[0]->nextFrame(to, -94, -55, true); //3 - creAnim1[1]->nextFrame(to, -94, 197, true); //9 - break; - case 3: - creAnim1[0]->nextFrame(to, -94, -55, true); //3 - creAnim1[1]->nextFrame(to, -116, 71, true); //6 - creAnim1[2]->nextFrame(to, -94, 197, true); //9 - break; - case 4: - creAnim1[0]->nextFrame(to, -94, -139, true); //1 - creAnim1[1]->nextFrame(to, -94, 29, true); //5 - creAnim1[2]->nextFrame(to, -94, 113, true); //7 - creAnim1[3]->nextFrame(to, -94, 281, true); //11 - break; - case 5: - creAnim1[0]->nextFrame(to, -94, -139, true); //1 - creAnim1[1]->nextFrame(to, -94, -55, true); //3 - creAnim1[2]->nextFrame(to, -116, 71, true); //6 - creAnim1[3]->nextFrame(to, -94, 197, true); //9 - creAnim1[4]->nextFrame(to, -94, 281, true); //11 - break; - case 6: - creAnim1[0]->nextFrame(to, -94, -139, true); //1 - creAnim1[1]->nextFrame(to, -94, -55, true); //3 - creAnim1[2]->nextFrame(to, -94, 29, true); //5 - creAnim1[3]->nextFrame(to, -94, 113, true); //7 - creAnim1[4]->nextFrame(to, -94, 197, true); //9 - creAnim1[5]->nextFrame(to, -94, 281, true); //11 - break; - case 7: - creAnim1[0]->nextFrame(to, -94, -139, true); //1 - creAnim1[1]->nextFrame(to, -94, -55, true); //3 - creAnim1[2]->nextFrame(to, -94, 29, true); //5 - creAnim1[3]->nextFrame(to, -116, 71, true); //6 - creAnim1[4]->nextFrame(to, -94, 113, true); //7 - creAnim1[5]->nextFrame(to, -94, 197, true); //9 - creAnim1[6]->nextFrame(to, -94, 281, true); //11 - break; - default: //fault - break; - //creAnim1[0]->nextFrame(to, -94, -139); + std::pair coords = CBattleHex::getXYUnitAnim(stacks[j]->position, stacks[j]->owner == attackingHeroInstance->tempOwner); + creAnims[j]->nextFrame(to, coords.first, coords.second, stacks[j]->owner == attackingHeroInstance->tempOwner); } - switch(creAnim2.size()) //for defender - { - case 0: - break; - case 1: - creAnim2[0]->nextFrame(to, 441, 71, false); //6 - break; - case 2: - creAnim2[0]->nextFrame(to, 463, -55, false); //3 - creAnim2[1]->nextFrame(to, 463, 197, false); //9 - break; - case 3: - creAnim2[0]->nextFrame(to, 463, -55, false); //3 - creAnim2[1]->nextFrame(to, 441, 71, false); //6 - creAnim2[2]->nextFrame(to, 463, 197, false); //9 - break; - case 4: - creAnim2[0]->nextFrame(to, 463, -139, false); //1 - creAnim2[1]->nextFrame(to, 463, 29, false); //5 - creAnim2[2]->nextFrame(to, 463, 113, false); //7 - creAnim2[3]->nextFrame(to, 463, 281, false); //11 - break; - case 5: - creAnim2[0]->nextFrame(to, 463, -139, false); //1 - creAnim2[1]->nextFrame(to, 463, -55, false); //3 - creAnim2[2]->nextFrame(to, 441, 71, false); //6 - creAnim2[3]->nextFrame(to, 463, 197, false); //9 - creAnim2[4]->nextFrame(to, 463, 281, false); //11 - break; - case 6: - creAnim2[0]->nextFrame(to, 463, -139, false); //1 - creAnim2[1]->nextFrame(to, 463, -55, false); //3 - creAnim2[2]->nextFrame(to, 463, 29, false); //5 - creAnim2[3]->nextFrame(to, 463, 113, false); //7 - creAnim2[4]->nextFrame(to, 463, 197, false); //9 - creAnim2[5]->nextFrame(to, 463, 281, false); //11 - break; - case 7: - creAnim2[0]->nextFrame(to, 463, -139, false); //1 - creAnim2[1]->nextFrame(to, 463, -55, false); //3 - creAnim2[2]->nextFrame(to, 463, 29, false); //5 - creAnim2[3]->nextFrame(to, 441, 71, false); //6 - creAnim2[4]->nextFrame(to, 463, 113, false); //7 - creAnim2[5]->nextFrame(to, 463, 197, false); //9 - creAnim2[6]->nextFrame(to, 463, 281, false); //11 - break; - default: //fault - break; - //creAnim2[0]->nextFrame(to, 463, -139); - } - //units shown CSDL_Ext::update(); @@ -347,8 +272,6 @@ void CBattleHero::show(SDL_Surface *to) { CSDL_Ext::blit8bppAlphaTo24bpp(flag->ourImages[flagAnim].bitmap, NULL, screen, &genRect(flag->ourImages[flagAnim].bitmap->h, flag->ourImages[flagAnim].bitmap->w, 31, 39)); } - //++flagAnimCount; - //if(flagAnimCount%4==0) { ++flagAnim; flagAnim %= flag->ourImages.size(); @@ -371,6 +294,7 @@ CBattleHero::CBattleHero(std::string defName, int phaseG, int imageG, bool flipG else flag = CGI->spriteh->giveDef("CMFLAGL.DEF"); + //coloring flag and adding transparency for(int i=0; iourImages.size(); ++i) { flag->ourImages[i].bitmap = CSDL_Ext::alphaTransform(flag->ourImages[i].bitmap); @@ -383,3 +307,40 @@ CBattleHero::~CBattleHero() delete dh; delete flag; } + +std::pair CBattleHex::getXYUnitAnim(int hexNum, bool attacker) +{ + std::pair ret = std::make_pair(-500, -500); //returned value + ret.second = -139 + 42 * (hexNum/17); //counting y + //counting x + if(attacker) + { + ret.first = -160 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17); + } + else + { + ret.first = -219 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17); + } + //returning + return ret; +} + +void CBattleHex::activate() +{ + Hoverable::activate(); +} + +void CBattleHex::deactivate() +{ + Hoverable::activate(); +} + +void CBattleHex::hover(bool on) +{ + hovered = on; + Hoverable::hover(on); +} + +CBattleHex::CBattleHex() : myNumber(-1), accesible(true), hovered(false) +{ +} diff --git a/CBattleInterface.h b/CBattleInterface.h index 986c89b41..8564b82b6 100644 --- a/CBattleInterface.h +++ b/CBattleInterface.h @@ -6,6 +6,7 @@ class CCreatureSet; class CGHeroInstance; class CDefHandler; class CStack; +class CCallback; template class AdventureMapButton; class CBattleHero : public IShowable, public CIntObject @@ -21,11 +22,19 @@ public: ~CBattleHero(); //d-tor }; -class CBattleHex +class CBattleHex : public Hoverable { +public: unsigned int myNumber; bool accesible; - CStack * ourStack; + //CStack * ourStack; + bool hovered; + static std::pair getXYUnitAnim(int hexNum, bool attacker); //returns (x, y) of left top corner of animation + //for user interactions + void hover (bool on); + void activate(); + void deactivate(); + CBattleHex(); }; class CBattleObstacle @@ -42,9 +51,13 @@ private: CBattleHero * attackingHero, * defendingHero; SDL_Surface * cellBorder, * cellShade; CCreatureSet * army1, * army2; //fighting armies - std::vector< CCreatureAnimation * > creAnim1, creAnim2; //animations of creatures from fighting armies + CGHeroInstance * attackingHeroInstance, * defendingHeroInstance; + std::vector< CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order like in BattleInfo's stacks) + + CCallback * cb; //our callback for getting info about different things + const std::vector< CStack* > & stacks; //fighting stacks public: - CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor + CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CCallback * callback, CGHeroInstance *hero1, CGHeroInstance *hero2, const std::vector< CStack* > & stcks); //c-tor ~CBattleInterface(); //d-tor //std::vector timeinterested; //animation handling diff --git a/CCallback.cpp b/CCallback.cpp index 6c0d1cd01..8ff33cb45 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -513,6 +513,11 @@ bool CCallback::swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, return true; } +int CCallback::battleGetBattlefieldType() +{ + return CGI->mh->ttiles[CGI->state->curB->tile.x][CGI->state->curB->tile.y][CGI->state->curB->tile.z].terType; +} + int3 CScriptCallback::getPos(CGObjectInstance * ob) { return ob->pos; diff --git a/CGameState.cpp b/CGameState.cpp index 1b8c772f8..690a4aed0 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -30,8 +30,107 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C curB->round = -2; for(std::map >::iterator i = army1->slots.begin(); i!=army1->slots.end(); i++) stacks.push_back(new CStack(i->second.first,i->second.second,0, stacks.size())); + //initialization of positions + switch(army1->slots.size()) //for attacker + { + case 0: + break; + case 1: + stacks[0]->position = 86; //6 + break; + case 2: + stacks[0]->position = 35; //3 + stacks[1]->position = 137; //9 + break; + case 3: + stacks[0]->position = 35; //3 + stacks[1]->position = 86; //6 + stacks[2]->position = 137; //9 + break; + case 4: + stacks[0]->position = 1; //1 + stacks[1]->position = 69; //5 + stacks[2]->position = 103; //7 + stacks[3]->position = 171; //11 + break; + case 5: + stacks[0]->position = 1; //1 + stacks[1]->position = 35; //3 + stacks[2]->position = 86; //6 + stacks[3]->position = 137; //9 + stacks[4]->position = 171; //11 + break; + case 6: + stacks[0]->position = 1; //1 + stacks[1]->position = 35; //3 + stacks[2]->position = 69; //5 + stacks[3]->position = 103; //7 + stacks[4]->position = 137; //9 + stacks[5]->position = 171; //11 + break; + case 7: + stacks[0]->position = 1; //1 + stacks[1]->position = 35; //3 + stacks[2]->position = 69; //5 + stacks[3]->position = 86; //6 + stacks[4]->position = 103; //7 + stacks[5]->position = 137; //9 + stacks[6]->position = 171; //11 + break; + default: //fault + break; + } for(std::map >::iterator i = army2->slots.begin(); i!=army2->slots.end(); i++) stacks.push_back(new CStack(i->second.first,i->second.second,1, stacks.size())); + switch(army2->slots.size()) //for attacker + { + case 0: + break; + case 1: + stacks[0+army1->slots.size()]->position = 100; //6 + break; + case 2: + stacks[0+army1->slots.size()]->position = 49; //3 + stacks[1+army1->slots.size()]->position = 151; //9 + break; + case 3: + stacks[0+army1->slots.size()]->position = 49; //3 + stacks[1+army1->slots.size()]->position = 100; //6 + stacks[2+army1->slots.size()]->position = 151; //9 + break; + case 4: + stacks[0+army1->slots.size()]->position = 15; //1 + stacks[1+army1->slots.size()]->position = 83; //5 + stacks[2+army1->slots.size()]->position = 117; //7 + stacks[3+army1->slots.size()]->position = 185; //11 + break; + case 5: + stacks[0+army1->slots.size()]->position = 15; //1 + stacks[1+army1->slots.size()]->position = 49; //3 + stacks[2+army1->slots.size()]->position = 100; //6 + stacks[3+army1->slots.size()]->position = 151; //9 + stacks[4+army1->slots.size()]->position = 185; //11 + break; + case 6: + stacks[0+army1->slots.size()]->position = 15; //1 + stacks[1+army1->slots.size()]->position = 49; //3 + stacks[2+army1->slots.size()]->position = 83; //5 + stacks[3+army1->slots.size()]->position = 117; //7 + stacks[4+army1->slots.size()]->position = 151; //9 + stacks[5+army1->slots.size()]->position = 185; //11 + break; + case 7: + stacks[0+army1->slots.size()]->position = 15; //1 + stacks[1+army1->slots.size()]->position = 49; //3 + stacks[2+army1->slots.size()]->position = 83; //5 + stacks[3+army1->slots.size()]->position = 100; //6 + stacks[4+army1->slots.size()]->position = 117; //7 + stacks[5+army1->slots.size()]->position = 151; //9 + stacks[6+army1->slots.size()]->position = 185; //11 + break; + default: //fault + break; + } std::stable_sort(stacks.begin(),stacks.end(),cmpst); //for start inform players about battle @@ -50,7 +149,7 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C return; //no witnesses if(CGI->playerint[j->second.serial]->human) { - ((CPlayerInterface*)( CGI->playerint[j->second.serial] ))->battleStart(army1, army2, tile, curB->hero1, curB->hero2, side); + ((CPlayerInterface*)( CGI->playerint[j->second.serial] ))->battleStart(army1, army2, tile, curB->hero1, curB->hero2, side, curB->stacks); } else { @@ -104,4 +203,4 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C delete stacks[i]; delete curB; curB = NULL; -} \ No newline at end of file +} diff --git a/CGameState.h b/CGameState.h index 932e1bd90..36d9b30cf 100644 --- a/CGameState.h +++ b/CGameState.h @@ -1,8 +1,10 @@ #ifndef CGAMESTATE_H #define CGAMESTATE_H + #include "mapHandler.h" #include #include + class CScriptCallback; class CCallback; class CLuaCallback; @@ -11,6 +13,7 @@ class CCreatureSet; class CStack; class CGHeroInstance; class CArmedInstance; + struct PlayerState { public: @@ -22,6 +25,7 @@ public: std::vector towns; PlayerState():color(-1){}; }; + struct BattleInfo { int side1, side2; @@ -32,17 +36,19 @@ struct BattleInfo CCreatureSet * army1, * army2; std::vector stacks; }; + class CStack { public: - int ID; + int ID; //type of creature CCreature * creature; int amount; int owner; - int position; - bool alive; + int position; //position on battlefield + bool alive; //true if it is alive CStack(CCreature * C, int A, int O, int I):creature(C),amount(A),owner(O), alive(true), position(-1), ID(I){}; }; + class CGameState { private: diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index d142268b9..3c9e95beb 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -1851,10 +1851,10 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj) } } -void CPlayerInterface::battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, tribool side) //called by engine when battle starts; side=0 - left, side=1 - right +void CPlayerInterface::battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, tribool side, std::vector< CStack* > & stacks) //called by engine when battle starts; side=0 - left, side=1 - right { curint->deactivate(); - curint = new CBattleInterface(army1,army2,tile,hero1,hero2); + curint = new CBattleInterface(army1,army2,cb,hero1,hero2,stacks); curint->activate(); LOCPLINT->objsToBlit.push_back(dynamic_cast(curint)); } diff --git a/CPlayerInterface.h b/CPlayerInterface.h index 6bee31f70..13c8969c3 100644 --- a/CPlayerInterface.h +++ b/CPlayerInterface.h @@ -11,6 +11,7 @@ class CDefEssential; class CGHeroInstance; class CAdvMapInt; class CCastleInterface; +class CStack; class IShowable { public: @@ -303,7 +304,7 @@ public: void garrisonChanged(const CGObjectInstance * obj); //battles - void battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, tribool side); //called by engine when battle starts; side=0 - left, side=1 - right + void battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, tribool side, std::vector< CStack* > & stacks); //called by engine when battle starts; side=0 - left, side=1 - right void battlefieldPrepared(int battlefieldType, std::vector obstacles); //called when battlefield is prepared, prior the battle beginning 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 actionStarted(Action action);//occurs BEFORE every action taken by any stack or by the hero diff --git a/mapHandler.cpp b/mapHandler.cpp index fb0b9d14a..83b923716 100644 --- a/mapHandler.cpp +++ b/mapHandler.cpp @@ -1150,7 +1150,7 @@ SDL_Surface * CMapHandler::getVisBitmap(int x, int y, PseudoV< PseudoV< PseudoV< //return CSDL_Ext::rotate01(partialHide->ourImages[12].bitmap); //visible left, left - bottom, bottom; right top corner hidden return partialHide->ourImages[38].bitmap; } - else if(visibilityMap[x][y+1][lvl] && visibilityMap[x+1][y][lvl] && visibilityMap[x-1][y][lvl] && visibilityMap[x][y-1][lvl] && visibilityMap[x-1][y-1][lvl] && visibilityMap[x+1][y+1][lvl] && visibilityMap[x+1][y-1][lvl] && visibilityMap[x-1][y+1][lvl]) + else if(visibilityMap[x][y+1][lvl] && visibilityMap[x+1][y][lvl] && visibilityMap[x-1][y][lvl] && visibilityMap[x][y-1][lvl]) { return partialHide->ourImages[10].bitmap; //visible left, right, bottom and top }