1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-14 02:33:51 +02:00

* (hopefully) fixed battle interface in hotseat mode

* fixed a bug when defending player (human) attacks in battle with two-hex unit from top-right or bottom-right direction
This commit is contained in:
mateuszb 2010-02-19 16:02:34 +00:00
parent 80d42a5313
commit d53e4d7c1a
9 changed files with 307 additions and 193 deletions

File diff suppressed because it is too large Load Diff

View File

@ -300,8 +300,9 @@ class CBattleResultWindow : public CIntObject
private: private:
SDL_Surface * background; SDL_Surface * background;
AdventureMapButton * exit; AdventureMapButton * exit;
CBattleInterface * owner;
public: public:
CBattleResultWindow(const BattleResult & br, const SDL_Rect & pos, const CBattleInterface * owner); //c-tor CBattleResultWindow(const BattleResult & br, const SDL_Rect & pos, CBattleInterface * _owner); //c-tor
~CBattleResultWindow(); //d-tor ~CBattleResultWindow(); //d-tor
void bExitf(); //exit button callback void bExitf(); //exit button callback
@ -362,9 +363,10 @@ public:
SDL_Surface *box; SDL_Surface *box;
SDL_Surface *bg; SDL_Surface *bg;
CBattleInterface * owner;
void showAll(SDL_Surface *to); void showAll(SDL_Surface *to);
CStackQueue(bool Embedded); CStackQueue(bool Embedded, CBattleInterface * _owner);
~CStackQueue(); ~CStackQueue();
void update(); void update();
void blitBg( SDL_Surface * to ); void blitBg( SDL_Surface * to );
@ -383,7 +385,7 @@ private:
CCreatureSet * army1, * army2; //fighting armies CCreatureSet * army1, * army2; //fighting armies
CGHeroInstance * attackingHeroInstance, * defendingHeroInstance; CGHeroInstance * attackingHeroInstance, * defendingHeroInstance;
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID) std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
std::map< int, CDefHandler * > idToProjectile; //projectiles of creaures (creatureID, defhandler) std::map< int, CDefHandler * > idToProjectile; //projectiles of creatures (creatureID, defhandler)
std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation> std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation>
unsigned char animCount; unsigned char animCount;
@ -398,9 +400,9 @@ private:
std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves' std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
bool spellDestSelectMode; //if true, player is choosing destination for his spell bool spellDestSelectMode; //if true, player is choosing destination for his spell
int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle,z -1 - no location int spellSelMode; //0 - any location, 1 - any friendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle,z -1 - no location
BattleAction * spellToCast; //spell for which player is choosing destination BattleAction * spellToCast; //spell for which player is choosing destination
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or cancelled) void endCastingSpell(); //ends casting spell (eg. when spell has been cast or canceled)
void showAliveStack(int ID, const std::map<int, CStack> & stacks, SDL_Surface * to); //helper function for function show void showAliveStack(int ID, const std::map<int, CStack> & stacks, SDL_Surface * to); //helper function for function show
void showPieceOfWall(SDL_Surface * to, int hex, const std::map<int, CStack> & stacks); //helper function for show void showPieceOfWall(SDL_Surface * to, int hex, const std::map<int, CStack> & stacks); //helper function for show
@ -410,7 +412,7 @@ private:
std::list<SProjectileInfo> projectiles; //projectiles flying on battlefield std::list<SProjectileInfo> projectiles; //projectiles flying on battlefield
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1); void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1);
bool isTileAttackable(const int & number) const; //returns true if tile 'number' is neighbouring any tile from active stack's range or is one of these tiles bool isTileAttackable(const int & number) const; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles
bool blockedByObstacle(int hex) const; bool blockedByObstacle(int hex) const;
bool isCatapultAttackable(int hex) const; //returns true if given tile can be attacked by catapult bool isCatapultAttackable(int hex) const; //returns true if given tile can be attacked by catapult
@ -434,13 +436,16 @@ private:
friend class CBattleInterface; friend class CBattleInterface;
} * siegeH; } * siegeH;
CPlayerInterface * attackerInt, * defenderInt; //because LOCPLINT is not enough in hotSeat
public: public:
CPlayerInterface * curInt; //current player interface
std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized> std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
void addNewAnim(CBattleAnimation * anim); //adds new anim to pendingAnims void addNewAnim(CBattleAnimation * anim); //adds new anim to pendingAnims
unsigned int animIDhelper; //for giving IDs for animations unsigned int animIDhelper; //for giving IDs for animations
static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect); //c-tor CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen); //c-tor
~CBattleInterface(); //d-tor ~CBattleInterface(); //d-tor
//std::vector<TimeInterested*> timeinterested; //animation handling //std::vector<TimeInterested*> timeinterested; //animation handling

View File

@ -1069,7 +1069,7 @@ void CKingdomInterface::CHeroItem::CArtPlace::clickLeft(tribool down, bool previ
{ {
if(type == 0) if(type == 0)
{ {
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), hero->hero); CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), hero->hero, LOCPLINT);
GH.pushInt(spellWindow); GH.pushInt(spellWindow);
} }
else else

View File

@ -69,6 +69,9 @@ extern std::queue<SDL_Event*> events;
extern boost::mutex eventsM; extern boost::mutex eventsM;
CPlayerInterface * LOCPLINT; CPlayerInterface * LOCPLINT;
CBattleInterface * CPlayerInterface::battleInt;
enum EMoveState {STOP_MOVE, WAITING_MOVE, CONTINUE_MOVE, DURING_MOVE}; enum EMoveState {STOP_MOVE, WAITING_MOVE, CONTINUE_MOVE, DURING_MOVE};
CondSh<EMoveState> stillMoveHero; //used during hero movement CondSh<EMoveState> stillMoveHero; //used during hero movement
@ -530,11 +533,15 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID,
void CPlayerInterface::battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool 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, bool side) //called by engine when battle starts; side=0 - left, side=1 - right
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
while(showingDialog->get()) while(showingDialog->get())
SDL_Delay(20); SDL_Delay(20);
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
/*battleInt = */new CBattleInterface(army1, army2, hero1, hero2, genRect(600, 800, (conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2));
CGI->musich->playMusicFromSet(CGI->musich->battleMusics, -1); CGI->musich->playMusicFromSet(CGI->musich->battleMusics, -1);
GH.pushInt(battleInt); GH.pushInt(battleInt);
} }
@ -545,6 +552,11 @@ void CPlayerInterface::battlefieldPrepared(int battlefieldType, std::vector<CObs
void CPlayerInterface::battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks) void CPlayerInterface::battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
for(int b=0; b<healedStacks.size(); ++b) for(int b=0; b<healedStacks.size(); ++b)
{ {
const CStack * healed = cb->battleGetStackByID(healedStacks[b].first); const CStack * healed = cb->battleGetStackByID(healedStacks[b].first);
@ -558,12 +570,22 @@ void CPlayerInterface::battleStacksHealedRes(const std::vector<std::pair<ui32, u
void CPlayerInterface::battleNewStackAppeared(int stackID) void CPlayerInterface::battleNewStackAppeared(int stackID)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
//changing necessary things in battle interface //changing necessary things in battle interface
battleInt->newStack(stackID); battleInt->newStack(stackID);
} }
void CPlayerInterface::battleObstaclesRemoved(const std::set<si32> & removedObstacles) void CPlayerInterface::battleObstaclesRemoved(const std::set<si32> & removedObstacles)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
for(std::set<si32>::const_iterator it = removedObstacles.begin(); it != removedObstacles.end(); ++it) for(std::set<si32>::const_iterator it = removedObstacles.begin(); it != removedObstacles.end(); ++it)
{ {
for(std::map< int, CDefHandler * >::iterator itBat = battleInt->idToObstacle.begin(); itBat != battleInt->idToObstacle.end(); ++itBat) for(std::map< int, CDefHandler * >::iterator itBat = battleInt->idToObstacle.begin(); itBat != battleInt->idToObstacle.end(); ++itBat)
@ -581,11 +603,21 @@ void CPlayerInterface::battleObstaclesRemoved(const std::set<si32> & removedObst
void CPlayerInterface::battleCatapultAttacked(const CatapultAttack & ca) void CPlayerInterface::battleCatapultAttacked(const CatapultAttack & ca)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
battleInt->stackIsCatapulting(ca); battleInt->stackIsCatapulting(ca);
} }
void CPlayerInterface::battleStacksRemoved(const BattleStacksRemoved & bsr) void CPlayerInterface::battleStacksRemoved(const BattleStacksRemoved & bsr)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
for(std::set<ui32>::const_iterator it = bsr.stackIDs.begin(); it != bsr.stackIDs.end(); ++it) //for each removed stack for(std::set<ui32>::const_iterator it = bsr.stackIDs.begin(); it != bsr.stackIDs.end(); ++it) //for each removed stack
{ {
battleInt->stackRemoved(*it); battleInt->stackRemoved(*it);
@ -594,12 +626,22 @@ void CPlayerInterface::battleStacksRemoved(const BattleStacksRemoved & bsr)
void CPlayerInterface::battleNewRound(int round) //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn void CPlayerInterface::battleNewRound(int round) //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
battleInt->newRound(round); battleInt->newRound(round);
} }
void CPlayerInterface::actionStarted(const BattleAction* action) void CPlayerInterface::actionStarted(const BattleAction* action)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
curAction = new BattleAction(*action); curAction = new BattleAction(*action);
battleInt->startAction(action); battleInt->startAction(action);
@ -607,6 +649,11 @@ void CPlayerInterface::actionStarted(const BattleAction* action)
void CPlayerInterface::actionFinished(const BattleAction* action) void CPlayerInterface::actionFinished(const BattleAction* action)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
delete curAction; delete curAction;
curAction = NULL; curAction = NULL;
@ -615,6 +662,7 @@ void CPlayerInterface::actionFinished(const BattleAction* action)
BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack
{ {
CBattleInterface *b = battleInt; CBattleInterface *b = battleInt;
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
@ -646,27 +694,52 @@ BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn
void CPlayerInterface::battleEnd(BattleResult *br) void CPlayerInterface::battleEnd(BattleResult *br)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
battleInt->battleFinished(*br); battleInt->battleFinished(*br);
} }
void CPlayerInterface::battleStackMoved(int ID, int dest, int distance, bool end) void CPlayerInterface::battleStackMoved(int ID, int dest, int distance, bool end)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
battleInt->stackMoved(ID, dest, end, distance); battleInt->stackMoved(ID, dest, end, distance);
} }
void CPlayerInterface::battleSpellCast(SpellCast *sc) void CPlayerInterface::battleSpellCast(SpellCast *sc)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
battleInt->spellCast(sc); battleInt->spellCast(sc);
} }
void CPlayerInterface::battleStacksEffectsSet(SetStackEffect & sse) void CPlayerInterface::battleStacksEffectsSet(SetStackEffect & sse)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
battleInt->battleStacksEffectsSet(sse); battleInt->battleStacksEffectsSet(sse);
} }
void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa) void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
tlog5 << "CPlayerInterface::battleStackAttacked - locking..."; tlog5 << "CPlayerInterface::battleStackAttacked - locking...";
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
tlog5 << "done!\n"; tlog5 << "done!\n";
@ -694,6 +767,11 @@ void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
} }
void CPlayerInterface::battleAttack(BattleAttack *ba) void CPlayerInterface::battleAttack(BattleAttack *ba)
{ {
if(LOCPLINT != this)
{ //another local interface should do this
return;
}
tlog5 << "CPlayerInterface::battleAttack - locking..."; tlog5 << "CPlayerInterface::battleAttack - locking...";
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
tlog5 << "done!\n"; tlog5 << "done!\n";

View File

@ -123,7 +123,7 @@ public:
CAdvMapInt * adventureInt; CAdvMapInt * adventureInt;
CCastleInterface * castleInt; //NULL if castle window isn't opened CCastleInterface * castleInt; //NULL if castle window isn't opened
CBattleInterface * battleInt; //NULL if no battle static CBattleInterface * battleInt; //NULL if no battle
FPSmanager * mainFPSmng; //to keep const framerate FPSmanager * mainFPSmng; //to keep const framerate
CInGameConsole * cingconsole; CInGameConsole * cingconsole;

View File

@ -30,13 +30,15 @@
extern SDL_Surface * screen; extern SDL_Surface * screen;
extern SDL_Color tytulowy, zwykly, darkTitle; extern SDL_Color tytulowy, zwykly, darkTitle;
SpellbookInteractiveArea::SpellbookInteractiveArea(const SDL_Rect & myRect, boost::function<void()> funcL, const std::string & textR, boost::function<void()> funcHon, boost::function<void()> funcHoff) SpellbookInteractiveArea::SpellbookInteractiveArea(const SDL_Rect & myRect, boost::function<void()> funcL,
const std::string & textR, boost::function<void()> funcHon, boost::function<void()> funcHoff, CPlayerInterface * _myInt)
{ {
pos = myRect; pos = myRect;
onLeft = funcL; onLeft = funcL;
textOnRclick = textR; textOnRclick = textR;
onHoverOn = funcHon; onHoverOn = funcHon;
onHoverOff = funcHoff; onHoverOff = funcHoff;
myInt = _myInt;
} }
void SpellbookInteractiveArea::clickLeft(tribool down, bool previousState) void SpellbookInteractiveArea::clickLeft(tribool down, bool previousState)
@ -49,7 +51,7 @@ void SpellbookInteractiveArea::clickLeft(tribool down, bool previousState)
void SpellbookInteractiveArea::clickRight(tribool down, bool previousState) void SpellbookInteractiveArea::clickRight(tribool down, bool previousState)
{ {
LOCPLINT->adventureInt->handleRightClick(textOnRclick, down, this); myInt->adventureInt->handleRightClick(textOnRclick, down, this);
} }
void SpellbookInteractiveArea::hover(bool on) void SpellbookInteractiveArea::hover(bool on)
@ -79,11 +81,12 @@ void SpellbookInteractiveArea::deactivate()
deactivateHover(); deactivateHover();
} }
CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHero, bool openOnBattleSpells): CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells):
battleSpellsOnly(openOnBattleSpells), battleSpellsOnly(openOnBattleSpells),
selectedTab(4), selectedTab(4),
spellSite(0), spellSite(0),
myHero(_myHero) myHero(_myHero),
myInt(_myInt)
{ {
//initializing castable spells //initializing castable spells
for(ui32 v=0; v<CGI->spellh->spells.size(); ++v) for(ui32 v=0; v<CGI->spellh->spells.size(); ++v)
@ -231,29 +234,29 @@ CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHe
statusBar = new CStatusBar(7 + pos.x, 569 + pos.y, "Spelroll.bmp"); statusBar = new CStatusBar(7 + pos.x, 569 + pos.y, "Spelroll.bmp");
SDL_Rect temp_rect = genRect(45, 35, 479 + pos.x, 405 + pos.y); SDL_Rect temp_rect = genRect(45, 35, 479 + pos.x, 405 + pos.y);
exitBtn = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fexitb, this), CGI->generaltexth->zelp[460].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[460].first)), boost::bind(&CStatusBar::clear, statusBar)); exitBtn = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fexitb, this), CGI->generaltexth->zelp[460].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[460].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(45, 35, 221 + pos.x, 405 + pos.y); temp_rect = genRect(45, 35, 221 + pos.x, 405 + pos.y);
battleSpells = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fbattleSpellsb, this), CGI->generaltexth->zelp[453].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[453].first)), boost::bind(&CStatusBar::clear, statusBar)); battleSpells = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fbattleSpellsb, this), CGI->generaltexth->zelp[453].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[453].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(45, 35, 355 + pos.x, 405 + pos.y); temp_rect = genRect(45, 35, 355 + pos.x, 405 + pos.y);
adventureSpells = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fadvSpellsb, this), CGI->generaltexth->zelp[452].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[452].first)), boost::bind(&CStatusBar::clear, statusBar)); adventureSpells = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fadvSpellsb, this), CGI->generaltexth->zelp[452].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[452].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(45, 35, 418 + pos.x, 405 + pos.y); temp_rect = genRect(45, 35, 418 + pos.x, 405 + pos.y);
manaPoints = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fmanaPtsb, this), CGI->generaltexth->zelp[459].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[459].first)), boost::bind(&CStatusBar::clear, statusBar)); manaPoints = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fmanaPtsb, this), CGI->generaltexth->zelp[459].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[459].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(36, 56, 549 + pos.x, 94 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 94 + pos.y);
selectSpellsA = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsAb, this), CGI->generaltexth->zelp[454].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[454].first)), boost::bind(&CStatusBar::clear, statusBar)); selectSpellsA = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsAb, this), CGI->generaltexth->zelp[454].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[454].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(36, 56, 549 + pos.x, 151 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 151 + pos.y);
selectSpellsE = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsEb, this), CGI->generaltexth->zelp[457].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[457].first)), boost::bind(&CStatusBar::clear, statusBar)); selectSpellsE = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsEb, this), CGI->generaltexth->zelp[457].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[457].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(36, 56, 549 + pos.x, 210 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 210 + pos.y);
selectSpellsF = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsFb, this), CGI->generaltexth->zelp[455].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[455].first)), boost::bind(&CStatusBar::clear, statusBar)); selectSpellsF = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsFb, this), CGI->generaltexth->zelp[455].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[455].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(36, 56, 549 + pos.x, 270 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 270 + pos.y);
selectSpellsW = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsWb, this), CGI->generaltexth->zelp[456].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[456].first)), boost::bind(&CStatusBar::clear, statusBar)); selectSpellsW = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsWb, this), CGI->generaltexth->zelp[456].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[456].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(36, 56, 549 + pos.x, 330 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 330 + pos.y);
selectSpellsAll = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsAllb, this), CGI->generaltexth->zelp[458].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[458].first)), boost::bind(&CStatusBar::clear, statusBar)); selectSpellsAll = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fspellsAllb, this), CGI->generaltexth->zelp[458].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[458].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(leftCorner->h, leftCorner->w, 97 + pos.x, 77 + pos.y); temp_rect = genRect(leftCorner->h, leftCorner->w, 97 + pos.x, 77 + pos.y);
lCorner = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fLcornerb, this), CGI->generaltexth->zelp[450].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[450].first)), boost::bind(&CStatusBar::clear, statusBar)); lCorner = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fLcornerb, this), CGI->generaltexth->zelp[450].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[450].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
temp_rect = genRect(rightCorner->h, rightCorner->w, 487 + pos.x, 72 + pos.y); temp_rect = genRect(rightCorner->h, rightCorner->w, 487 + pos.x, 72 + pos.y);
rCorner = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fRcornerb, this), CGI->generaltexth->zelp[451].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[451].first)), boost::bind(&CStatusBar::clear, statusBar)); rCorner = new SpellbookInteractiveArea(temp_rect, boost::bind(&CSpellWindow::fRcornerb, this), CGI->generaltexth->zelp[451].second, boost::bind(&CStatusBar::print, statusBar, (CGI->generaltexth->zelp[451].first)), boost::bind(&CStatusBar::clear, statusBar), myInt);
//areas for spells //areas for spells
int xpos = 117 + pos.x, ypos = 90 + pos.y; int xpos = 117 + pos.x, ypos = 90 + pos.y;
@ -464,7 +467,7 @@ void CSpellWindow::show(SDL_Surface *to)
blitAt(schoolBorders[bestSchool]->ourImages[bestslvl].bitmap, spellAreas[b]->pos.x, spellAreas[b]->pos.y, to); blitAt(schoolBorders[bestSchool]->ourImages[bestslvl].bitmap, spellAreas[b]->pos.x, spellAreas[b]->pos.y, to);
SDL_Color firstLineColor, secondLineColor; SDL_Color firstLineColor, secondLineColor;
if(LOCPLINT->cb->getSpellCost(spell, myHero) > myHero->mana) //hero cannot cast this spell if(myInt->cb->getSpellCost(spell, myHero) > myHero->mana) //hero cannot cast this spell
{ {
firstLineColor = zwykly; firstLineColor = zwykly;
secondLineColor = darkTitle; secondLineColor = darkTitle;
@ -480,7 +483,7 @@ void CSpellWindow::show(SDL_Surface *to)
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[171 + spell->level], spellAreas[b]->pos.x + 39, spellAreas[b]->pos.y + 82, FONT_TINY, secondLineColor, to); CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[171 + spell->level], spellAreas[b]->pos.x + 39, spellAreas[b]->pos.y + 82, FONT_TINY, secondLineColor, to);
//printing cost //printing cost
std::ostringstream ss; std::ostringstream ss;
ss<<CGI->generaltexth->allTexts[387]<<": "<<LOCPLINT->cb->getSpellCost(spell, myHero); ss<<CGI->generaltexth->allTexts[387]<<": "<<myInt->cb->getSpellCost(spell, myHero);
CSDL_Ext::printAtMiddle(ss.str(), spellAreas[b]->pos.x + 39, spellAreas[b]->pos.y + 94, FONT_TINY, secondLineColor, to); CSDL_Ext::printAtMiddle(ss.str(), spellAreas[b]->pos.x + 39, spellAreas[b]->pos.y + 94, FONT_TINY, secondLineColor, to);
} }
@ -665,13 +668,13 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
{ {
if(!down && mySpell!=-1) if(!down && mySpell!=-1)
{ {
int spellCost = LOCPLINT->cb->getSpellCost(&CGI->spellh->spells[mySpell], owner->myHero); int spellCost = owner->myInt->cb->getSpellCost(&CGI->spellh->spells[mySpell], owner->myHero);
//we will cast a spell //we will cast a spell
if(LOCPLINT->battleInt && LOCPLINT->cb->battleCanCastSpell() && spellCost <= owner->myHero->mana) //if battle window is open if(owner->myInt->battleInt && owner->myInt->cb->battleCanCastSpell() && spellCost <= owner->myHero->mana) //if battle window is open
{ {
int spell = mySpell; int spell = mySpell;
owner->fexitb(); owner->fexitb();
LOCPLINT->battleInt->castThisSpell(spell); owner->myInt->battleInt->castThisSpell(spell);
} }
else else
{ {
@ -681,7 +684,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
std::vector<SComponent*> comps; std::vector<SComponent*> comps;
char msgBuf[500]; char msgBuf[500];
sprintf(msgBuf, CGI->generaltexth->allTexts[206].c_str(), spellCost, owner->myHero->mana); sprintf(msgBuf, CGI->generaltexth->allTexts[206].c_str(), spellCost, owner->myHero->mana);
LOCPLINT->showInfoDialog(std::string(msgBuf), comps); owner->myInt->showInfoDialog(std::string(msgBuf), comps);
} }
} }
} }
@ -692,7 +695,7 @@ void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState)
if(down && mySpell != -1) if(down && mySpell != -1)
{ {
std::string dmgInfo; std::string dmgInfo;
int causedDmg = LOCPLINT->cb->estimateSpellDamage( &CGI->spellh->spells[mySpell] ); int causedDmg = owner->myInt->cb->estimateSpellDamage( &CGI->spellh->spells[mySpell] );
if(causedDmg == 0) if(causedDmg == 0)
dmgInfo = ""; dmgInfo = "";
else else
@ -702,7 +705,7 @@ void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState)
} }
SDL_Surface *spellBox = CMessage::drawBoxTextBitmapSub( SDL_Surface *spellBox = CMessage::drawBoxTextBitmapSub(
LOCPLINT->playerID, owner->myInt->playerID,
CGI->spellh->spells[mySpell].descriptions[0] + dmgInfo, this->owner->spells->ourImages[mySpell].bitmap, CGI->spellh->spells[mySpell].descriptions[0] + dmgInfo, this->owner->spells->ourImages[mySpell].bitmap,
CGI->spellh->spells[mySpell].name,30,30); CGI->spellh->spells[mySpell].name,30,30);
CInfoPopup *vinya = new CInfoPopup(spellBox, true); CInfoPopup *vinya = new CInfoPopup(spellBox, true);

View File

@ -29,6 +29,7 @@ private:
std::string textOnRclick; std::string textOnRclick;
boost::function<void()> onHoverOn; boost::function<void()> onHoverOn;
boost::function<void()> onHoverOff; boost::function<void()> onHoverOff;
CPlayerInterface * myInt;
public: public:
void clickLeft(tribool down, bool previousState); void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState); void clickRight(tribool down, bool previousState);
@ -36,7 +37,8 @@ public:
void activate(); void activate();
void deactivate(); void deactivate();
SpellbookInteractiveArea(const SDL_Rect & myRect, boost::function<void()> funcL, const std::string & textR, boost::function<void()> funcHon, boost::function<void()> funcHoff);//c-tor SpellbookInteractiveArea(const SDL_Rect & myRect, boost::function<void()> funcL, const std::string & textR,
boost::function<void()> funcHon, boost::function<void()> funcHoff, CPlayerInterface * _myInt);//c-tor
}; };
class CSpellWindow : public CIntObject class CSpellWindow : public CIntObject
@ -84,8 +86,11 @@ private:
void turnPageLeft(); void turnPageLeft();
void turnPageRight(); void turnPageRight();
CPlayerInterface * myInt;
public: public:
CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHero, bool openOnBattleSpells = true); //c-tor
CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells = true); //c-tor
~CSpellWindow(); //d-tor ~CSpellWindow(); //d-tor
void fexitb(); void fexitb();

View File

@ -3594,7 +3594,7 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
{ {
if(ourArt->id == 0) if(ourArt->id == 0)
{ {
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), ourOwner->curHero); CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), ourOwner->curHero, LOCPLINT);
GH.pushInt(spellWindow); GH.pushInt(spellWindow);
} }
} }

View File

@ -19,6 +19,9 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp> #include <boost/thread/shared_mutex.hpp>
#include "CConfigHandler.h"
#include "SDL_Extensions.h"
#include "CBattleInterface.h"
//macro to avoid code duplication - calls given method with given arguments if interface for specific player is present //macro to avoid code duplication - calls given method with given arguments if interface for specific player is present
#define INTERFACE_CALL_IF_PRESENT(player,function,...) \ #define INTERFACE_CALL_IF_PRESENT(player,function,...) \
@ -405,6 +408,20 @@ void GarrisonDialog::applyCl(CClient *cl)
void BattleStart::applyCl( CClient *cl ) void BattleStart::applyCl( CClient *cl )
{ {
CPlayerInterface * att, * def;
if(vstd::contains(cl->playerint, info->side1) && cl->playerint[info->side1]->human)
att = static_cast<CPlayerInterface*>( cl->playerint[info->side1] );
else
att = NULL;
if(vstd::contains(cl->playerint, info->side2) && cl->playerint[info->side2]->human)
def = static_cast<CPlayerInterface*>( cl->playerint[info->side2] );
else
def = NULL;
new CBattleInterface(&info->army1, &info->army2, info->heroes[0], info->heroes[1], genRect(600, 800, (conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2), att, def);
if(vstd::contains(cl->playerint,info->side1)) if(vstd::contains(cl->playerint,info->side1))
cl->playerint[info->side1]->battleStart(&info->army1, &info->army2, info->tile, info->heroes[0], info->heroes[1], 0); cl->playerint[info->side1]->battleStart(&info->army1, &info->army2, info->tile, info->heroes[0], info->heroes[1], 0);