mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
Moved battle effects to bonus system. May be buggy.
Moved creature damage to bonus system, simplified its handling. Some changes and tweaks. Support for Adela's bless.
This commit is contained in:
@@ -760,13 +760,13 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
|
||||
s->firstHPleft = s->MaxHealth();
|
||||
|
||||
//remove effects and restore only those with remaining turns in duration
|
||||
std::vector<CStack::StackEffect> tmpEffects = s->effects;
|
||||
s->effects.clear();
|
||||
for(int i=0; i < tmpEffects.size(); i++)
|
||||
BonusList tmpEffects = s->bonuses;
|
||||
s->bonuses.removeSpells(Bonus::CASTED_SPELL);
|
||||
for (BonusList::iterator it = tmpEffects.begin(); it != tmpEffects.end(); it++)
|
||||
{
|
||||
tmpEffects[i].turnsRemain--;
|
||||
if(tmpEffects[i].turnsRemain > 0)
|
||||
s->effects.push_back(tmpEffects[i]);
|
||||
it->turnsRemain--;
|
||||
if(it->turnsRemain > 0)
|
||||
s->bonuses.push_back(*it);
|
||||
}
|
||||
|
||||
//the same as above for features
|
||||
@@ -929,17 +929,17 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
CStack *s = gs->curB->getStack(*it);
|
||||
if(s && !vstd::contains(resisted, s->ID)) //if stack exists and it didn't resist
|
||||
{
|
||||
std::vector<CStack::StackEffect> remainingEff;
|
||||
for(int g=0; g< s->effects.size(); ++g)
|
||||
BonusList remainingEff;
|
||||
for (BonusList::iterator it = remainingEff.begin(); it != remainingEff.end(); it++)
|
||||
{
|
||||
if (onlyHelpful && VLC->spellh->spells[ s->effects[g].id ].positiveness != 1)
|
||||
if (onlyHelpful && VLC->spellh->spells[ it->id ].positiveness != 1)
|
||||
{
|
||||
remainingEff.push_back(s->effects[g]);
|
||||
remainingEff.push_back(*it);
|
||||
}
|
||||
|
||||
}
|
||||
s->effects.clear(); //removing all effects
|
||||
s->effects = remainingEff; //assigning effects that should remain
|
||||
s->bonuses.removeSpells(Bonus::CASTED_SPELL); //removing all effects
|
||||
s->bonuses = remainingEff; //assigning effects that should remain
|
||||
|
||||
//removing all features from spells
|
||||
BonusList tmpFeatures = s->bonuses;
|
||||
@@ -1000,169 +1000,23 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
}
|
||||
}
|
||||
|
||||
static inline Bonus featureGenerator(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, si32 additionalInfo = 0, si32 limit = Bonus::NO_LIMIT)
|
||||
{
|
||||
Bonus hb(makeFeature(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain, additionalInfo));
|
||||
hb.effectRange = limit;
|
||||
return hb;
|
||||
}
|
||||
|
||||
static inline Bonus featureGeneratorVT(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, ui8 valType)
|
||||
{
|
||||
Bonus ret(makeFeature(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain));
|
||||
ret.valType = valType;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BonusList stackEffectToFeature(const CStack::StackEffect & sse)
|
||||
{
|
||||
BonusList sf;
|
||||
si32 power = VLC->spellh->spells[sse.id].powers[sse.level];
|
||||
switch(sse.id)
|
||||
{
|
||||
case 27: //shield
|
||||
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 28: //air shield
|
||||
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 29: //fire shield
|
||||
sf.push_back(featureGenerator(Bonus::FIRE_SHIELD, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 30: //protection from air
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 31: //protection from fire
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 32: //protection from water
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 2, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 33: //protection from earth
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 3, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 34: //anti-magic
|
||||
sf.push_back(featureGenerator(Bonus::LEVEL_SPELL_IMMUNITY, 0, power - 1, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 41: //bless
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MAXIMUM_DAMAGE, -1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 42: //curse
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MINIMUM_DAMAGE, -1, -1 * power, sse.turnsRemain, sse.level >= 2 ? 20 : 0));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 43: //bloodlust
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain, 0, Bonus::ONLY_MELEE_FIGHT));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 44: //precision
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain, 0, Bonus::ONLY_DISTANCE_FIGHT));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 45: //weakness
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 46: //stone skin
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 47: //disrupting ray
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 48: //prayer
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 49: //mirth
|
||||
sf.push_back(featureGenerator(Bonus::MORALE, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 50: //sorrow
|
||||
sf.push_back(featureGenerator(Bonus::MORALE, 0, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 51: //fortune
|
||||
sf.push_back(featureGenerator(Bonus::LUCK, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 52: //misfortune
|
||||
sf.push_back(featureGenerator(Bonus::LUCK, 0, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 53: //haste
|
||||
sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 54: //slow
|
||||
sf.push_back(featureGeneratorVT(Bonus::STACKS_SPEED, 0, -1 * ( 100 - power ), sse.turnsRemain, Bonus::PERCENT_TO_ALL));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 55: //slayer
|
||||
sf.push_back(featureGenerator(Bonus::SLAYER, 0, sse.level, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 56: //frenzy
|
||||
sf.push_back(featureGenerator(Bonus::IN_FRENZY, 0, VLC->spellh->spells[56].powers[sse.level]/100.0, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 58: //counterstrike
|
||||
sf.push_back(featureGenerator(Bonus::ADDITIONAL_RETALIATION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 59: //bersek
|
||||
sf.push_back(featureGenerator(Bonus::ATTACKS_NEAREST_CREATURE, 0, sse.level, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 60: //hypnotize
|
||||
sf.push_back(featureGenerator(Bonus::HYPNOTIZED, 0, sse.level, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 61: //forgetfulness
|
||||
sf.push_back(featureGenerator(Bonus::FORGETFULL, 0, sse.level, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 62: //blind
|
||||
sf.push_back(makeFeature(Bonus::NOT_ACTIVE, Bonus::UNITL_BEING_ATTACKED | Bonus::N_TURNS, 0, 0, Bonus::SPELL_EFFECT, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.push_back(makeFeature(Bonus::GENERAL_ATTACK_REDUCTION, Bonus::UNTIL_ATTACK | Bonus::N_TURNS, 0, power, Bonus::SPELL_EFFECT, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
}
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
void actualizeEffect(CStack * s, CStack::StackEffect & ef)
|
||||
void actualizeEffect(CStack * s, Bonus & ef)
|
||||
{
|
||||
//actualizing effects vector
|
||||
for(int g=0; g<s->effects.size(); ++g)
|
||||
for (BonusList::iterator it = s->bonuses.begin(); it != s->bonuses.end(); it++)
|
||||
{
|
||||
if(s->effects[g].id == ef.id)
|
||||
if(it->id == ef.id)
|
||||
{
|
||||
s->effects[g].turnsRemain = std::max(s->effects[g].turnsRemain, ef.turnsRemain);
|
||||
it->turnsRemain = std::max(it->turnsRemain, ef.turnsRemain);
|
||||
}
|
||||
}
|
||||
//actualizing features vector
|
||||
BonusList sf = stackEffectToFeature(ef);
|
||||
BonusList sf;
|
||||
s->stackEffectToFeature(sf, ef);
|
||||
|
||||
BOOST_FOREACH(const Bonus &fromEffect, sf)
|
||||
{
|
||||
BOOST_FOREACH(Bonus &stackBonus, s->bonuses)
|
||||
BOOST_FOREACH(Bonus &stackBonus, s->bonuses) //TODO: optimize
|
||||
{
|
||||
if(stackBonus.source == Bonus::SPELL_EFFECT && stackBonus.type == fromEffect.type && stackBonus.subtype == fromEffect.subtype)
|
||||
{
|
||||
@@ -1173,16 +1027,6 @@ void actualizeEffect(CStack * s, CStack::StackEffect & ef)
|
||||
|
||||
}
|
||||
|
||||
bool containsEff(const std::vector<CStack::StackEffect> & vec, int effectId)
|
||||
{
|
||||
for(int g=0; g<vec.size(); ++g)
|
||||
{
|
||||
if(vec[g].id == effectId)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
{
|
||||
BOOST_FOREACH(ui32 id, stacks)
|
||||
@@ -1190,10 +1034,11 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
CStack *s = gs->curB->getStack(id);
|
||||
if(s)
|
||||
{
|
||||
if(effect.id == 42 || !containsEff(s->effects, effect.id))//disrupting ray or not on the list - just add
|
||||
if(effect.id == 42 || !s->hasBonus(Selector::source(Bonus::CASTED_SPELL, effect.id)))//disrupting ray or not on the list - just add
|
||||
{
|
||||
s->effects.push_back(effect);
|
||||
BonusList sf = stackEffectToFeature(effect);
|
||||
s->bonuses.push_back(effect);
|
||||
BonusList sf;
|
||||
s->stackEffectToFeature(sf, effect);
|
||||
BOOST_FOREACH(const Bonus &fromEffect, sf)
|
||||
{
|
||||
s->bonuses.push_back(fromEffect);
|
||||
@@ -1258,11 +1103,11 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
//removal of negative effects
|
||||
if(resurrected)
|
||||
{
|
||||
for(int h=0; h<changedStack->effects.size(); ++h)
|
||||
for (BonusList::iterator it = changedStack->bonuses.begin(); it != changedStack->bonuses.end(); it++)
|
||||
{
|
||||
if(VLC->spellh->spells[changedStack->effects[h].id].positiveness < 0)
|
||||
if(VLC->spellh->spells[it->id].positiveness < 0)
|
||||
{
|
||||
changedStack->effects.erase(changedStack->effects.begin() + h);
|
||||
changedStack->bonuses.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user