1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Fix the initial creature spells at battle start

Before: built-in spells appear on first move of the creature
After: all built-in spells appear before the first move but after tactics

Example: Air Shield for experienced skeletons
This commit is contained in:
Vadim Markovtsev 2016-10-28 23:37:45 +02:00
parent ab7a0d64eb
commit dccc25268c
2 changed files with 53 additions and 43 deletions

View File

@ -4371,7 +4371,36 @@ bool CGameHandler::makeCustomAction(BattleAction &ba)
return false;
}
void CGameHandler::stackTurnTrigger(const CStack * st)
void CGameHandler::stackAppearTrigger(const CStack *st)
{
auto bl = *(st->getBonuses(Selector::type(Bonus::ENCHANTED)));
for (auto b : bl)
{
SetStackEffect sse;
int val = bl.valOfBonuses(Selector::typeSubtype(b->type, b->subtype));
if (val > 3)
{
for (auto s : gs->curB->battleGetAllStacks())
{
if (battleMatchOwner(st, s, true) && s->isValidTarget()) //all allied
sse.stacks.push_back (s->ID);
}
}
else
sse.stacks.push_back (st->ID);
Bonus pseudoBonus;
pseudoBonus.sid = b->subtype;
pseudoBonus.val = ((val > 3) ? (val - 3) : val);
pseudoBonus.turnsRemain = 50;
st->stackEffectToFeature(sse.effect, pseudoBonus);
if (sse.effect.size())
sendAndApply(&sse);
}
}
void CGameHandler::stackTurnTrigger(const CStack *st)
{
BattleTriggerEffect bte;
bte.stackID = st->ID;
@ -4380,6 +4409,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
bte.additionalInfo = 0;
if (st->alive())
{
stackAppearTrigger(st);
//unbind
if (st->hasBonus(Selector::type(Bonus::BIND_EFFECT)))
{
@ -4502,31 +4532,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
cast = true;
}
};
}
bl = *(st->getBonuses(Selector::type(Bonus::ENCHANTED)));
for (auto b : bl)
{
SetStackEffect sse;
int val = bl.valOfBonuses (Selector::typeSubtype(b->type, b->subtype));
if (val > 3)
{
for (auto s : gs->curB->battleGetAllStacks())
{
if (battleMatchOwner(st, s, true) && s->isValidTarget()) //all allied
sse.stacks.push_back (s->ID);
}
}
else
sse.stacks.push_back (st->ID);
Bonus pseudoBonus;
pseudoBonus.sid = b->subtype;
pseudoBonus.val = ((val > 3) ? (val - 3) : val);
pseudoBonus.turnsRemain = 50;
st->stackEffectToFeature (sse.effect, pseudoBonus);
if (sse.effect.size())
sendAndApply (&sse);
}
}
}
@ -5515,18 +5521,23 @@ bool CGameHandler::swapStacks(const StackLocation &sl1, const StackLocation &sl2
}
}
void CGameHandler::runBattle()
{
void CGameHandler::runBattle() {
setBattle(gs->curB);
assert(gs->curB);
//TODO: pre-tactic stuff, call scripts etc.
//tactic round
{
while(gs->curB->tacticDistance && !battleResult.get())
while (gs->curB->tacticDistance && !battleResult.get())
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
}
//initial stacks appearance triggers, e.g. built-in bonus spells
for (auto stack : gs->curB->stacks)
{
stackAppearTrigger(stack);
}
//spells opening battle
for (int i = 0; i < 2; ++i)
{
@ -5554,7 +5565,7 @@ void CGameHandler::runBattle()
}
//main loop
while(!battleResult.get()) //till the end of the battle ;]
while (!battleResult.get()) //till the end of the battle ;]
{
BattleNextRound bnr;
bnr.round = gs->curB->round + 1;
@ -5573,9 +5584,8 @@ void CGameHandler::runBattle()
//stack loop
const CStack *next;
while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
while (!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
{
std::set <const CStack *> stacksToRemove;
for (auto stack : curB.stacks)
{
@ -5746,7 +5756,7 @@ void CGameHandler::runBattle()
boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
battleMadeAction.data = false;
while(!actionWasMade())
while (!actionWasMade())
{
battleMadeAction.cond.wait(lock);
if (battleGetStackByID(nextId, false) != next)
@ -5778,17 +5788,16 @@ void CGameHandler::runBattle()
)
{
if (getRandomGenerator().nextInt(23) < nextStackMorale) //this stack hasn't got morale this turn
{
BattleTriggerEffect bte;
bte.stackID = next->ID;
bte.effect = Bonus::MORALE;
bte.val = 1;
bte.additionalInfo = 0;
sendAndApply(&bte); //play animation
{
BattleTriggerEffect bte;
bte.stackID = next->ID;
bte.effect = Bonus::MORALE;
bte.val = 1;
bte.additionalInfo = 0;
sendAndApply(&bte); //play animation
++numberOfAsks; //move this stack once more
}
++numberOfAsks; //move this stack once more
}
}
}
--numberOfAsks;

View File

@ -199,7 +199,8 @@ public:
bool makeBattleAction(BattleAction &ba);
bool makeAutomaticAction(const CStack *stack, BattleAction &ba); //used when action is taken by stack without volition of player (eg. unguided catapult attack)
bool makeCustomAction(BattleAction &ba);
void stackTurnTrigger(const CStack * stack);
void stackAppearTrigger(const CStack *stack);
void stackTurnTrigger(const CStack *stack);
void handleDamageFromObstacle(const CObstacleInstance &obstacle, const CStack * curStack); //checks if obstacle is land mine and handles possible consequences
void removeObstacle(const CObstacleInstance &obstacle);
bool queryReply( QueryID qid, ui32 answer, PlayerColor player );