mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- Restored Genie random spell
- Fixed crashes in many strange creature-spellcasting scenarios, including stack with multiple cast abilities and Enchanter with non-stadard spell
This commit is contained in:
parent
05311dd30c
commit
cd1a9414ac
@ -1564,8 +1564,11 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
|
||||
case Spells::LIGHTNING_BOLT:
|
||||
case Spells::TITANS_LIGHTNING_BOLT:
|
||||
case Spells::THUNDERBOLT:
|
||||
displayEffect(1, sc->tile);
|
||||
displayEffect(spell.mainEffectAnim, sc->tile);
|
||||
for (auto it = sc->affectedCres.begin(); it != sc->affectedCres.end(); ++it) //in case we have multiple targets
|
||||
{
|
||||
displayEffect(1, curInt->cb->battleGetStackByID(*it, false)->position);
|
||||
displayEffect(spell.mainEffectAnim, curInt->cb->battleGetStackByID(*it, false)->position);
|
||||
}
|
||||
break;
|
||||
case Spells::DISPEL:
|
||||
case Spells::CURE:
|
||||
@ -2668,6 +2671,8 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
bool noStackIsHovered = true; //will cause removing a blue glow
|
||||
|
||||
localActions.clear();
|
||||
illegalActions.clear();
|
||||
|
||||
BOOST_FOREACH (PossibleActions action, possibleActions)
|
||||
{
|
||||
bool legalAction = false; //this action is legal and can't be performed
|
||||
@ -2709,11 +2714,11 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
legalAction = true;
|
||||
break;
|
||||
case HOSTILE_CREATURE_SPELL: //TODO: check spell immunity
|
||||
if (shere && !ourStack && isCastingPossibleHere (sactive, shere, myNumber))
|
||||
if (shere && shere->alive() && !ourStack && isCastingPossibleHere (sactive, shere, myNumber))
|
||||
legalAction = true;
|
||||
break;
|
||||
case FRIENDLY_CREATURE_SPELL:
|
||||
if (shere && ourStack && isCastingPossibleHere (sactive, shere, myNumber))
|
||||
if (shere && shere->alive() && ourStack && isCastingPossibleHere (sactive, shere, myNumber))
|
||||
legalAction = true;
|
||||
break;
|
||||
case RISING_SPELL:
|
||||
@ -2727,7 +2732,6 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
int spellID = curInt->cb->battleGetRandomStackSpell(shere, CBattleInfoCallback::RANDOM_GENIE);
|
||||
if (spellID > -1)
|
||||
{
|
||||
sp = CGI->spellh->spells[spellID];
|
||||
legalAction = true;
|
||||
}
|
||||
}
|
||||
@ -2867,22 +2871,21 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
case HOSTILE_CREATURE_SPELL:
|
||||
case FRIENDLY_CREATURE_SPELL:
|
||||
case RISING_SPELL:
|
||||
case RANDOM_GENIE_SPELL:
|
||||
if (sp)
|
||||
sp = CGI->spellh->spells[creatureCasting ? creatureSpellToCast : spellToCast->additionalInfo]; //necessary if creature has random Genie spell at same time
|
||||
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % sp->name % shere->getName()); //Cast %s on %s
|
||||
switch (sp->id)
|
||||
{
|
||||
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % sp->name % shere->getName()); //Cast %s on %s
|
||||
switch (sp->id)
|
||||
{
|
||||
case Spells::TELEPORT:
|
||||
case Spells::SACRIFICE:
|
||||
secondaryTarget = true;
|
||||
break;
|
||||
}
|
||||
isCastingPossible = true;
|
||||
case Spells::TELEPORT:
|
||||
case Spells::SACRIFICE:
|
||||
secondaryTarget = true;
|
||||
break;
|
||||
}
|
||||
else //spell is random
|
||||
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[301]) % shere->getName()); //Cast a spell on %
|
||||
//we assume that teleport / sacrifice will never be avaliable as random spell
|
||||
isCastingPossible = true;
|
||||
break;
|
||||
case RANDOM_GENIE_SPELL: //we assume that teleport / sacrifice will never be avaliable as random spell
|
||||
sp = NULL;
|
||||
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[301]) % shere->getName()); //Cast a spell on %
|
||||
isCastingPossible = true;
|
||||
break;
|
||||
case TELEPORT:
|
||||
consoleMsg = CGI->generaltexth->allTexts[25]; //Teleport Here
|
||||
@ -2975,7 +2978,14 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
{
|
||||
if(creatureCasting)
|
||||
{
|
||||
giveCommand(BattleAction::MONSTER_SPELL, myNumber, sactive->ID, creatureSpellToCast);
|
||||
if (sp)
|
||||
{
|
||||
giveCommand(BattleAction::MONSTER_SPELL, myNumber, sactive->ID, creatureSpellToCast);
|
||||
}
|
||||
else //unknown random spell
|
||||
{
|
||||
giveCommand(BattleAction::MONSTER_SPELL, myNumber, sactive->ID, curInt->cb->battleGetRandomStackSpell(shere, CBattleInfoCallback::RANDOM_GENIE));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2995,17 +3005,17 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
|
||||
bool CBattleInterface::isCastingPossibleHere (const CStack * sactive, const CStack * shere, BattleHex myNumber)
|
||||
{
|
||||
creatureCasting = (stackCanCastSpell) && (shere != sactive); //is it really useful?
|
||||
creatureCasting = stackCanCastSpell; //is it really useful?
|
||||
|
||||
bool isCastingPossible = true;
|
||||
|
||||
int spellID = -1;
|
||||
if (creatureCasting)
|
||||
{
|
||||
if (creatureSpellToCast > -1)
|
||||
if (creatureSpellToCast > -1 && (shere != sactive)) //can't cast on itself
|
||||
spellID = creatureSpellToCast; //TODO: merge with SpellTocast?
|
||||
}
|
||||
else if(spellDestSelectMode) //hero casting
|
||||
else //hero casting
|
||||
spellID = spellToCast->additionalInfo;
|
||||
|
||||
sp = NULL;
|
||||
|
@ -835,7 +835,8 @@ void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacke
|
||||
if (defender && !i->isSecondary())
|
||||
battleInt->displayEffect(i->effect, defender->position);
|
||||
}
|
||||
StackAttackedInfo to_put = {defender, i->damageAmount, i->killedAmount, attacker, LOCPLINT->curAction->actionType==7, i->killed(), i->willRebirth(), i->cloneKilled()};
|
||||
bool shooting = (LOCPLINT->curAction ? LOCPLINT->curAction->actionType == BattleAction::SHOOT : false); //FIXME: why action is deleted during enchanter cast?
|
||||
StackAttackedInfo to_put = {defender, i->damageAmount, i->killedAmount, attacker, shooting, i->killed(), i->willRebirth(), i->cloneKilled()};
|
||||
arg.push_back(to_put);
|
||||
}
|
||||
|
||||
|
@ -3561,7 +3561,9 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
|
||||
|| (!spell->isPositive() && stack->owner != casterColor))
|
||||
{
|
||||
if(stack->isValidTarget()) //TODO: allow dead targets somewhere in the future
|
||||
{
|
||||
attackedCres.insert(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3619,7 +3621,8 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
|
||||
continue;
|
||||
|
||||
BattleStackAttacked bsa;
|
||||
if ((destination > -1 && (*it)->coversPos(destination)) || spell->range[spellLvl] == "X") //display effect only upon primary target of area spell
|
||||
if ((destination > -1 && (*it)->coversPos(destination)) || (spell->range[spellLvl] == "X" || mode == ECastingMode::ENCHANTER_CASTING))
|
||||
//display effect only upon primary target of area spell
|
||||
{
|
||||
bsa.flags |= BattleStackAttacked::EFFECT;
|
||||
bsa.effect = spell->mainEffectAnim;
|
||||
@ -3632,7 +3635,10 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
|
||||
sc.dmgToDisplay += bsa.damageAmount;
|
||||
}
|
||||
bsa.stackAttacked = (*it)->ID;
|
||||
bsa.attackerID = -1;
|
||||
if (mode == ECastingMode::ENCHANTER_CASTING) //multiple damage spells cast
|
||||
bsa.attackerID = stack->ID;
|
||||
else
|
||||
bsa.attackerID = -1;
|
||||
(*it)->prepareAttacked(bsa);
|
||||
si.stacks.push_back(bsa);
|
||||
}
|
||||
@ -4769,6 +4775,8 @@ void CGameHandler::handleAttackBeforeCasting (const BattleAttack & bat)
|
||||
void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
{
|
||||
const CStack * attacker = gs->curB->getStack(bat.stackAttacking);
|
||||
if (!attacker) //could be already dead
|
||||
return;
|
||||
attackCasting(bat, Bonus::SPELL_AFTER_ATTACK, attacker);
|
||||
|
||||
if(bat.bsa[0].newAmount <= 0)
|
||||
|
Loading…
Reference in New Issue
Block a user