mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-29 00:41:38 +02:00
* fixed remaining parts of #760
* it's possible to switch active creature during tacts phase by clicking on stack * a few minor fixes after handleHex rewrite
This commit is contained in:
@ -221,7 +221,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
|||||||
console->pos.h = 38;
|
console->pos.h = 38;
|
||||||
if(tacticsMode)
|
if(tacticsMode)
|
||||||
{
|
{
|
||||||
btactNext = new CAdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bTacticNextStack,this), 213 + pos.x, 560 + pos.y, "icm011.def", SDLK_SPACE);
|
btactNext = new CAdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bTacticNextStack,this, (CStack*)NULL), 213 + pos.x, 560 + pos.y, "icm011.def", SDLK_SPACE);
|
||||||
btactEnd = new CAdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bEndTacticPhase,this), 419 + pos.x, 560 + pos.y, "icm012.def", SDLK_RETURN);
|
btactEnd = new CAdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bEndTacticPhase,this), 419 + pos.x, 560 + pos.y, "icm012.def", SDLK_RETURN);
|
||||||
bDefence->block(true);
|
bDefence->block(true);
|
||||||
bWait->block(true);
|
bWait->block(true);
|
||||||
@ -1364,17 +1364,22 @@ void CBattleInterface::newRound(int number)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::giveCommand(ui8 action, BattleHex tile, ui32 stack, si32 additional)
|
void CBattleInterface::giveCommand(ui8 action, BattleHex tile, ui32 stackID, si32 additional)
|
||||||
{
|
{
|
||||||
if(!curInt->cb->battleGetStackByID(stack) && action != 1 && action != 4 && action != 5)
|
const CStack *stack = curInt->cb->battleGetStackByID(stackID);
|
||||||
|
if(!stack && action != BattleAction::HERO_SPELL && action != BattleAction::RETREAT && action != BattleAction::SURRENDER)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stack && stack != activeStack)
|
||||||
|
tlog3 << "Warning: giving an order to a non-active stack?\n";
|
||||||
|
|
||||||
BattleAction * ba = new BattleAction(); //is deleted in CPlayerInterface::activeStack()
|
BattleAction * ba = new BattleAction(); //is deleted in CPlayerInterface::activeStack()
|
||||||
ba->side = defendingHeroInstance ? (curInt->playerID == defendingHeroInstance->tempOwner) : false;
|
ba->side = defendingHeroInstance ? (curInt->playerID == defendingHeroInstance->tempOwner) : false;
|
||||||
ba->actionType = action;
|
ba->actionType = action;
|
||||||
ba->destinationTile = tile;
|
ba->destinationTile = tile;
|
||||||
ba->stackNumber = stack;
|
ba->stackNumber = stackID;
|
||||||
ba->additionalInfo = additional;
|
ba->additionalInfo = additional;
|
||||||
|
|
||||||
//some basic validations
|
//some basic validations
|
||||||
@ -1391,6 +1396,7 @@ void CBattleInterface::giveCommand(ui8 action, BattleHex tile, ui32 stack, si32
|
|||||||
|
|
||||||
if(!tacticsMode)
|
if(!tacticsMode)
|
||||||
{
|
{
|
||||||
|
tlog5 << "Setting command for " << (stack ? stack->nodeName() : "hero") << std::endl;
|
||||||
myTurn = false;
|
myTurn = false;
|
||||||
activeStack = NULL;
|
activeStack = NULL;
|
||||||
givenCommand->setn(ba);
|
givenCommand->setn(ba);
|
||||||
@ -1399,7 +1405,8 @@ void CBattleInterface::giveCommand(ui8 action, BattleHex tile, ui32 stack, si32
|
|||||||
{
|
{
|
||||||
curInt->cb->battleMakeTacticAction(ba);
|
curInt->cb->battleMakeTacticAction(ba);
|
||||||
vstd::clear_pointer(ba);
|
vstd::clear_pointer(ba);
|
||||||
bTacticNextStack();
|
activeStack = NULL;
|
||||||
|
//next stack will be activated when action ends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1415,7 +1422,7 @@ bool CBattleInterface::isTileAttackable(const BattleHex & number) const
|
|||||||
|
|
||||||
bool CBattleInterface::isCatapultAttackable(BattleHex hex) const
|
bool CBattleInterface::isCatapultAttackable(BattleHex hex) const
|
||||||
{
|
{
|
||||||
if(!siegeH)
|
if(!siegeH || tacticsMode)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int wallUnder = curInt->cb->battleGetWallUnderHex(hex);
|
int wallUnder = curInt->cb->battleGetWallUnderHex(hex);
|
||||||
@ -2298,6 +2305,7 @@ void CBattleInterface::projectileShowHelper(SDL_Surface * to)
|
|||||||
|
|
||||||
void CBattleInterface::endAction(const BattleAction* action)
|
void CBattleInterface::endAction(const BattleAction* action)
|
||||||
{
|
{
|
||||||
|
const CStack * stack = curInt->cb->battleGetStackByID(action->stackNumber);
|
||||||
//if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
|
//if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
|
||||||
// {
|
// {
|
||||||
// activate();
|
// activate();
|
||||||
@ -2311,7 +2319,6 @@ void CBattleInterface::endAction(const BattleAction* action)
|
|||||||
}
|
}
|
||||||
if(action->actionType == BattleAction::WALK && creAnims[action->stackNumber]->getType() != 2) //walk or walk & attack
|
if(action->actionType == BattleAction::WALK && creAnims[action->stackNumber]->getType() != 2) //walk or walk & attack
|
||||||
{
|
{
|
||||||
const CStack * stack = curInt->cb->battleGetStackByID(action->stackNumber);
|
|
||||||
pendingAnims.push_back(std::make_pair(new CMovementEndAnimation(this, stack, action->destinationTile), false));
|
pendingAnims.push_back(std::make_pair(new CMovementEndAnimation(this, stack, action->destinationTile), false));
|
||||||
}
|
}
|
||||||
if(action->actionType == BattleAction::CATAPULT) //catapult
|
if(action->actionType == BattleAction::CATAPULT) //catapult
|
||||||
@ -2335,8 +2342,10 @@ void CBattleInterface::endAction(const BattleAction* action)
|
|||||||
|
|
||||||
queue->update();
|
queue->update();
|
||||||
|
|
||||||
if(tacticsMode //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed
|
if(tacticsMode) //stack ended movement in tactics phase -> select the next one
|
||||||
|| action->actionType == BattleAction::HERO_SPELL)
|
bTacticNextStack(stack);
|
||||||
|
|
||||||
|
if( action->actionType == BattleAction::HERO_SPELL) //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed
|
||||||
redrawBackgroundWithHexes(activeStack);
|
redrawBackgroundWithHexes(activeStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2475,6 +2484,7 @@ void CBattleInterface::waitForAnims()
|
|||||||
|
|
||||||
void CBattleInterface::bEndTacticPhase()
|
void CBattleInterface::bEndTacticPhase()
|
||||||
{
|
{
|
||||||
|
activeStack = NULL;
|
||||||
btactEnd->block(true);
|
btactEnd->block(true);
|
||||||
tacticsMode = false;
|
tacticsMode = false;
|
||||||
}
|
}
|
||||||
@ -2484,15 +2494,17 @@ static bool immobile(const CStack *s)
|
|||||||
return !s->Speed(0, true); //should bound stacks be immobile?
|
return !s->Speed(0, true); //should bound stacks be immobile?
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::bTacticNextStack()
|
void CBattleInterface::bTacticNextStack(const CStack *current /*= NULL*/)
|
||||||
{
|
{
|
||||||
|
if(!current)
|
||||||
|
current = activeStack;
|
||||||
|
|
||||||
//no switching stacks when the current one is moving
|
//no switching stacks when the current one is moving
|
||||||
if(animsAreDisplayed.get())
|
waitForAnims();
|
||||||
return;
|
|
||||||
|
|
||||||
TStacks stacksOfMine = tacticianInterface->cb->battleGetStacks(CBattleCallback::ONLY_MINE);
|
TStacks stacksOfMine = tacticianInterface->cb->battleGetStacks(CBattleCallback::ONLY_MINE);
|
||||||
stacksOfMine.erase(std::remove_if(stacksOfMine.begin(), stacksOfMine.end(), &immobile), stacksOfMine.end());
|
stacksOfMine.erase(std::remove_if(stacksOfMine.begin(), stacksOfMine.end(), &immobile), stacksOfMine.end());
|
||||||
TStacks::iterator it = vstd::find(stacksOfMine, activeStack);
|
TStacks::iterator it = vstd::find(stacksOfMine, current);
|
||||||
if(it != stacksOfMine.end() && ++it != stacksOfMine.end())
|
if(it != stacksOfMine.end() && ++it != stacksOfMine.end())
|
||||||
stackActivated(*it);
|
stackActivated(*it);
|
||||||
else
|
else
|
||||||
@ -2605,7 +2617,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
|||||||
else
|
else
|
||||||
isCastingPossible = (curInt->cb->battleCanCastThisSpell(sp, myNumber) == ESpellCastProblem::OK);
|
isCastingPossible = (curInt->cb->battleCanCastThisSpell(sp, myNumber) == ESpellCastProblem::OK);
|
||||||
}
|
}
|
||||||
else if(shere)
|
else if(shere && shere->alive())
|
||||||
{
|
{
|
||||||
//needed for genie, otherwise covered by battleCan*CastThisSpell
|
//needed for genie, otherwise covered by battleCan*CastThisSpell
|
||||||
if(spellSelMode == HOSTILE_CREATURE && shere->owner == sactive->owner
|
if(spellSelMode == HOSTILE_CREATURE && shere->owner == sactive->owner
|
||||||
@ -2694,7 +2706,12 @@ pastCastingSpells:
|
|||||||
{
|
{
|
||||||
if (shere->alive())
|
if (shere->alive())
|
||||||
{
|
{
|
||||||
if(sactive->hasBonusOfType(Bonus::HEALER) && shere->canBeHealed()) //heal
|
if(tacticsMode) //select stack in tactics mdoe
|
||||||
|
{
|
||||||
|
consoleMsg = (boost::format(CGI->generaltexth->allTexts[481]) % shere->getName()).str(); //Select %s
|
||||||
|
realizeAction = [=]{ stackActivated(shere); };
|
||||||
|
}
|
||||||
|
else if(sactive->hasBonusOfType(Bonus::HEALER) && shere->canBeHealed()) //heal
|
||||||
{
|
{
|
||||||
cursorFrame = ECursor::COMBAT_HEAL;
|
cursorFrame = ECursor::COMBAT_HEAL;
|
||||||
consoleMsg = (boost::format(CGI->generaltexth->allTexts[419]) % shere->getName()).str(); //Apply first aid to the %s
|
consoleMsg = (boost::format(CGI->generaltexth->allTexts[419]) % shere->getName()).str(); //Apply first aid to the %s
|
||||||
@ -2717,9 +2734,9 @@ pastCastingSpells:
|
|||||||
{
|
{
|
||||||
hoveredStackAnim->playOnce(CCreatureAnim::MOUSEON);
|
hoveredStackAnim->playOnce(CCreatureAnim::MOUSEON);
|
||||||
lastMouseHoveredStackAnimationTime = curTime;
|
lastMouseHoveredStackAnimationTime = curTime;
|
||||||
mouseHoveredStack = shere->ID;
|
|
||||||
noStackIsHovered = false;
|
|
||||||
}
|
}
|
||||||
|
noStackIsHovered = false;
|
||||||
|
mouseHoveredStack = shere->ID;
|
||||||
} //end of alive
|
} //end of alive
|
||||||
else if (sactive->hasBonusOfType(Bonus::DAEMON_SUMMONING) && sactive->casts)
|
else if (sactive->hasBonusOfType(Bonus::DAEMON_SUMMONING) && sactive->casts)
|
||||||
{
|
{
|
||||||
|
@ -142,7 +142,7 @@ private:
|
|||||||
|
|
||||||
std::list<ProjectileInfo> projectiles; //projectiles flying on battlefield
|
std::list<ProjectileInfo> 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, BattleHex tile, ui32 stack, si32 additional=-1);
|
void giveCommand(ui8 action, BattleHex tile, ui32 stackID, si32 additional=-1);
|
||||||
bool isTileAttackable(const BattleHex & number) const; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles
|
bool isTileAttackable(const BattleHex & number) const; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles
|
||||||
bool isCatapultAttackable(BattleHex hex) const; //returns true if given tile can be attacked by catapult
|
bool isCatapultAttackable(BattleHex hex) const; //returns true if given tile can be attacked by catapult
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ public:
|
|||||||
void bDefencef();
|
void bDefencef();
|
||||||
void bConsoleUpf();
|
void bConsoleUpf();
|
||||||
void bConsoleDownf();
|
void bConsoleDownf();
|
||||||
void bTacticNextStack();
|
void bTacticNextStack(const CStack *current = NULL);
|
||||||
void bEndTacticPhase();
|
void bEndTacticPhase();
|
||||||
//end of button handle funcs
|
//end of button handle funcs
|
||||||
//napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem
|
//napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem
|
||||||
|
@ -729,8 +729,10 @@ void CPlayerInterface::actionFinished(const BattleAction* action)
|
|||||||
|
|
||||||
BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when it's turn of that stack
|
BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when it's turn of that stack
|
||||||
{
|
{
|
||||||
|
tlog5 << "Awaiting command for " << stack->nodeName() << std::endl;
|
||||||
CBattleInterface *b = battleInt;
|
CBattleInterface *b = battleInt;
|
||||||
|
|
||||||
|
assert(!b->givenCommand->get()); //command buffer must be clean (we don't want to use old command)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||||
b->stackActivated(stack);
|
b->stackActivated(stack);
|
||||||
@ -751,6 +753,7 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
|
|||||||
b->givenCommand->data = NULL;
|
b->givenCommand->data = NULL;
|
||||||
|
|
||||||
//return command
|
//return command
|
||||||
|
tlog5 << "Giving command for " << stack->nodeName() << std::endl;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ void BattleInfo::makeBFS(BattleHex start, bool *accessibility, BattleHex *predec
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<BattleHex> BattleInfo::getAccessibility( const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable ) const
|
std::vector<BattleHex> BattleInfo::getAccessibility( const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable /*= NULL*/, bool forPassingBy /*= false*/ ) const
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> ret;
|
std::vector<BattleHex> ret;
|
||||||
bool ac[GameConstants::BFIELD_SIZE];
|
bool ac[GameConstants::BFIELD_SIZE];
|
||||||
@ -314,7 +314,11 @@ std::vector<BattleHex> BattleInfo::getAccessibility( const CStack * stack, bool
|
|||||||
{
|
{
|
||||||
bool rangeFits;
|
bool rangeFits;
|
||||||
if (tacticDistance)
|
if (tacticDistance)
|
||||||
rangeFits = isInTacticRange(i);
|
{
|
||||||
|
rangeFits = pr[i] >= 0; //reachable in terms of obstacles
|
||||||
|
if(!forPassingBy) //only if we're passing through, we may step out of the tactic range -> otherwise check range
|
||||||
|
rangeFits = rangeFits && isInTacticRange(i);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
rangeFits = dist[i] <= stack->Speed(0, true); //we can reach the stack
|
rangeFits = dist[i] <= stack->Speed(0, true); //we can reach the stack
|
||||||
|
|
||||||
@ -1965,9 +1969,9 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleCanCastThisSpellHere( int
|
|||||||
if(spell->id == Spells::ANIMATE_DEAD && !stackUnder->hasBonusOfType(Bonus::UNDEAD))
|
if(spell->id == Spells::ANIMATE_DEAD && !stackUnder->hasBonusOfType(Bonus::UNDEAD))
|
||||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||||
}
|
}
|
||||||
if(spell->getTargetType() == CSpell::CREATURE || spell->getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE)
|
else if(spell->getTargetType() == CSpell::CREATURE || spell->getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE)
|
||||||
{
|
{
|
||||||
if(!stackUnder)
|
if(!stackUnder || !stackUnder->alive())
|
||||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||||
if(spell->isNegative() && stackUnder->owner == player)
|
if(spell->isNegative() && stackUnder->owner == player)
|
||||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||||
|
@ -94,7 +94,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode
|
|||||||
int getAvaliableHex(TCreature creID, bool attackerOwned, int initialPos = -1) const; //find place for summon / clone effects
|
int getAvaliableHex(TCreature creID, bool attackerOwned, int initialPos = -1) const; //find place for summon / clone effects
|
||||||
void makeBFS(BattleHex start, bool*accessibility, BattleHex *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const; //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
|
void makeBFS(BattleHex start, bool*accessibility, BattleHex *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const; //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
|
||||||
std::pair< std::vector<BattleHex>, int > getPath(BattleHex start, BattleHex dest, bool*accessibility, bool flyingCreature, bool twoHex, bool attackerOwned); //returned value: pair<path, length>; length may be different than number of elements in path since flying vreatures jump between distant hexes
|
std::pair< std::vector<BattleHex>, int > getPath(BattleHex start, BattleHex dest, bool*accessibility, bool flyingCreature, bool twoHex, bool attackerOwned); //returned value: pair<path, length>; length may be different than number of elements in path since flying vreatures jump between distant hexes
|
||||||
std::vector<BattleHex> getAccessibility(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL) const; //returns vector of accessible tiles (taking into account the creature range)
|
std::vector<BattleHex> getAccessibility(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL, bool forPassingBy = false) const; //returns vector of accessible tiles (taking into account the creature range)
|
||||||
|
|
||||||
bool isObstacleOnTile(BattleHex tile) const;
|
bool isObstacleOnTile(BattleHex tile) const;
|
||||||
bool isStackBlocked(const CStack * stack) const; //returns true if there is neighboring enemy stack
|
bool isStackBlocked(const CStack * stack) const; //returns true if there is neighboring enemy stack
|
||||||
|
@ -705,7 +705,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
|||||||
|
|
||||||
//initing necessary tables
|
//initing necessary tables
|
||||||
bool accessibility[GameConstants::BFIELD_SIZE];
|
bool accessibility[GameConstants::BFIELD_SIZE];
|
||||||
std::vector<BattleHex> accessible = gs->curB->getAccessibility(curStack, false);
|
std::vector<BattleHex> accessible = gs->curB->getAccessibility(curStack, false, NULL, true);
|
||||||
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
||||||
{
|
{
|
||||||
accessibility[b] = false;
|
accessibility[b] = false;
|
||||||
@ -734,7 +734,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bool accessibilityWithOccupyable[GameConstants::BFIELD_SIZE];
|
bool accessibilityWithOccupyable[GameConstants::BFIELD_SIZE];
|
||||||
std::vector<BattleHex> accOc = gs->curB->getAccessibility(curStack, true);
|
std::vector<BattleHex> accOc = gs->curB->getAccessibility(curStack, true, NULL, true);
|
||||||
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
||||||
{
|
{
|
||||||
accessibilityWithOccupyable[b] = false;
|
accessibilityWithOccupyable[b] = false;
|
||||||
@ -5486,6 +5486,7 @@ void CGameHandler::runBattle()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
tlog5 << "Activating " << next->nodeName() << std::endl;
|
||||||
BattleSetActiveStack sas;
|
BattleSetActiveStack sas;
|
||||||
sas.stack = next->ID;
|
sas.stack = next->ID;
|
||||||
sendAndApply(&sas);
|
sendAndApply(&sas);
|
||||||
|
Reference in New Issue
Block a user