mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-15 11:46:56 +02:00
* support for multiple retaliations per turn, unlimited retaliations, counterstrike spell
* stack is not resurrected when it is under a living stack
This commit is contained in:
parent
e892913635
commit
072c1f8d12
@ -528,6 +528,15 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
|
|||||||
:ID(I), creature(C), amount(A), baseAmount(A), firstHPleft(C->hitPoints), owner(O), slot(S), attackerOwned(AO), position(-1),
|
:ID(I), creature(C), amount(A), baseAmount(A), firstHPleft(C->hitPoints), owner(O), slot(S), attackerOwned(AO), position(-1),
|
||||||
counterAttacks(1), shots(C->shots), features(C->abilities)
|
counterAttacks(1), shots(C->shots), features(C->abilities)
|
||||||
{
|
{
|
||||||
|
//additional retaliations
|
||||||
|
for(int h=0; h<C->abilities.size(); ++h)
|
||||||
|
{
|
||||||
|
if(C->abilities[h].type == StackFeature::ADDITIONAL_RETALIATION)
|
||||||
|
{
|
||||||
|
counterAttacks += C->abilities[h].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//alive state indication
|
||||||
state.insert(ALIVE);
|
state.insert(ALIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
|
|||||||
s->state -= WAITING;
|
s->state -= WAITING;
|
||||||
s->state -= MOVED;
|
s->state -= MOVED;
|
||||||
s->state -= HAD_MORALE;
|
s->state -= HAD_MORALE;
|
||||||
s->counterAttacks = 1;
|
s->counterAttacks = 1 + s->valOfFeatures(StackFeature::ADDITIONAL_RETALIATION);
|
||||||
|
|
||||||
//remove effects and restore only those with remaining turns in duration
|
//remove effects and restore only those with remaining turns in duration
|
||||||
std::vector<CStack::StackEffect> tmpEffects = s->effects;
|
std::vector<CStack::StackEffect> tmpEffects = s->effects;
|
||||||
@ -867,9 +867,12 @@ static std::vector<StackFeature> stackEffectToFeature(const CStack::StackEffect
|
|||||||
case 56: //frenzy
|
case 56: //frenzy
|
||||||
sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
|
sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
|
||||||
break;
|
break;
|
||||||
case 60: //hypnotize
|
case 58: //counterstrike
|
||||||
|
sf.push_back(featureGenerator(StackFeature::ADDITIONAL_RETALIATION, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
|
||||||
break;
|
break;
|
||||||
|
case 60: //hypnotize
|
||||||
sf.push_back(featureGenerator(StackFeature::HYPNOTIZED, 0, sse.level, sse.turnsRemain));
|
sf.push_back(featureGenerator(StackFeature::HYPNOTIZED, 0, sse.level, sse.turnsRemain));
|
||||||
|
break;
|
||||||
case 61: //forgetfulness
|
case 61: //forgetfulness
|
||||||
sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
|
sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
|
||||||
break;
|
break;
|
||||||
@ -960,6 +963,20 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
|||||||
for(int g=0; g<healedStacks.size(); ++g)
|
for(int g=0; g<healedStacks.size(); ++g)
|
||||||
{
|
{
|
||||||
CStack * changedStack = gs->curB->stacks[healedStacks[g].stackID];
|
CStack * changedStack = gs->curB->stacks[healedStacks[g].stackID];
|
||||||
|
|
||||||
|
//checking if we resurrect a stack that is under a living stack
|
||||||
|
std::vector<int> access = gs->curB->getAccessibility(changedStack->ID, true);
|
||||||
|
bool acc[BFIELD_SIZE];
|
||||||
|
for(int h=0; h<BFIELD_SIZE; ++h)
|
||||||
|
acc[h] = false;
|
||||||
|
for(int h=0; h<access.size(); ++h)
|
||||||
|
acc[access[h]] = true;
|
||||||
|
if(!changedStack->alive() && !gs->curB->isAccessible(changedStack->position, acc,
|
||||||
|
changedStack->hasFeatureOfType(StackFeature::DOUBLE_WIDE), changedStack->attackerOwned,
|
||||||
|
changedStack->hasFeatureOfType(StackFeature::FLYING), true))
|
||||||
|
return; //position is already occupied
|
||||||
|
|
||||||
|
//applying changes
|
||||||
if(!changedStack->alive())
|
if(!changedStack->alive())
|
||||||
{
|
{
|
||||||
changedStack->state.insert(ALIVE);
|
changedStack->state.insert(ALIVE);
|
||||||
|
@ -2371,9 +2371,9 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
//counterattack
|
//counterattack
|
||||||
if(!curStack->hasFeatureOfType(StackFeature::BLOCKS_RETALIATION)
|
if(!curStack->hasFeatureOfType(StackFeature::BLOCKS_RETALIATION)
|
||||||
&& stackAtEnd->alive()
|
&& stackAtEnd->alive()
|
||||||
&& stackAtEnd->counterAttacks
|
&& ( stackAtEnd->counterAttacks > 0 || stackAtEnd->hasFeatureOfType(StackFeature::UNLIMITED_RETALIATIONS) )
|
||||||
&& !stackAtEnd->hasFeatureOfType(StackFeature::SIEGE_WEAPON)
|
&& !stackAtEnd->hasFeatureOfType(StackFeature::SIEGE_WEAPON)
|
||||||
&& !stackAtEnd->hasFeatureOfType(StackFeature::HYPNOTIZED)) //TODO: support for multiple retaliatons per turn
|
&& !stackAtEnd->hasFeatureOfType(StackFeature::HYPNOTIZED))
|
||||||
{
|
{
|
||||||
prepareAttack(bat,stackAtEnd,curStack);
|
prepareAttack(bat,stackAtEnd,curStack);
|
||||||
bat.flags |= 2;
|
bat.flags |= 2;
|
||||||
@ -2826,6 +2826,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
case 54: //slow
|
case 54: //slow
|
||||||
case 55: //slayer
|
case 55: //slayer
|
||||||
case 56: //frenzy
|
case 56: //frenzy
|
||||||
|
case 58: //counterstrike
|
||||||
case 60: //hypnotize
|
case 60: //hypnotize
|
||||||
case 61: //forgetfulness
|
case 61: //forgetfulness
|
||||||
case 62: //blind
|
case 62: //blind
|
||||||
|
Loading…
x
Reference in New Issue
Block a user