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

* more or less fixed spells

* certain hero specialties are still broken
This commit is contained in:
mateuszb 2011-01-20 19:57:12 +00:00
parent 2451c0dea6
commit 824d2b52db
7 changed files with 233 additions and 230 deletions

View File

@ -2788,26 +2788,32 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
{
if(sse.effect.id != -1) //can be -1 for defensive stance effect
int effID = sse.effect.back().id;
if(effID != -1) //can be -1 for defensive stance effect
{
for(std::vector<ui32>::const_iterator ci = sse.stacks.begin(); ci!=sse.stacks.end(); ++ci)
{
displayEffect(CGI->spellh->spells[sse.effect.id]->mainEffectAnim, curInt->cb->battleGetStackByID(*ci)->position);
displayEffect(CGI->spellh->spells[effID]->mainEffectAnim, curInt->cb->battleGetStackByID(*ci)->position);
}
}
else if (sse.effect.source == Bonus::OTHER && sse.effect.type == Bonus::PRIMARY_SKILL && sse.stacks.size() == 1)
else if (sse.stacks.size() == 1 && sse.effect.size() == 1)
{
//defensive stance (I hope)
const CStack * stack = LOCPLINT->cb->battleGetStackByID(*sse.stacks.begin());
int txtid = 120;
const Bonus & bns = sse.effect.back();
if (bns.source == Bonus::OTHER && bns.type == Bonus::PRIMARY_SKILL)
{
//defensive stance (I hope)
const CStack * stack = LOCPLINT->cb->battleGetStackByID(*sse.stacks.begin());
int txtid = 120;
if(stack->count != 1)
txtid++; //move to plural text
if(stack->count != 1)
txtid++; //move to plural text
char txt[4000];
int val = stack->Defense() - (stack->Defense() * 100 )/ (100 + sse.effect.val);
sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(), (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str(), val);
console->addText(txt);
char txt[4000];
int val = stack->Defense() - (stack->Defense() * 100 )/ (100 + bns.val);
sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(), (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str(), val);
console->addText(txt);
}
}

View File

@ -1684,171 +1684,172 @@ const Bonus * CStack::getEffect( ui16 id, int turn /*= 0*/ ) const
return NULL;
}
void CStack::stackEffectToFeature(BonusList & sf, const Bonus & sse)
void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
{
// si32 power = VLC->spellh->spells[sse.id]->powers[sse.val];
// Bonus * bonus = getBonus(Selector::typeSybtype(Bonus::SPECIAL_PECULIAR_ENCHANT, sse.id));
// if (bonus)
// {
// switch(bonus->additionalInfo)
// {
// case 0: //normal
// switch(type->level)
// {
// case 1: case 2:
// power += 3; //it doesn't necessarily make sense for some spells, use it wisely
// break;
// case 3: case 4:
// power += 2;
// break;
// case 5: case 6:
// power += 1;
// break;
// }
// break;
// case 1: //only Coronius as yet
// power = std::max(5 - type->level, 0);
// break;
// }
// }
//
// 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
// if (hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, 41)) //TODO: better handling of bonus percentages
// {
// int damagePercent = dynamic_cast<const CGHeroInstance*>(armyObj)->level * valOfBonuses(Bonus::SPECIAL_BLESS_DAMAGE, 41) / type->level;
// sf.push_back(featureGenerator(Bonus::CREATURE_DAMAGE, 0, damagePercent, sse.turnsRemain));
// sf.back().id = sse.id;
// sf.back().valType = Bonus::PERCENT_TO_ALL;
// }
// 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.val >= 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
// if (bonus) //Coronius
// {
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
// sf.back().id = sse.id;
// }
// sf.push_back(featureGenerator(Bonus::SLAYER, 0, sse.val, 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.val]/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.val, sse.turnsRemain));
// sf.back().id = sse.id;
// break;
// case 60: //hypnotize
// sf.push_back(featureGenerator(Bonus::HYPNOTIZED, 0, sse.val, sse.turnsRemain));
// sf.back().id = sse.id;
// break;
// case 61: //forgetfulness
// sf.push_back(featureGenerator(Bonus::FORGETFULL, 0, sse.val, 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;
// }
si32 power = VLC->spellh->spells[sse.id]->powers[sse.val];
//why, why, WHY this code is here?!?
// Bonus * bonus = getBonus(Selector::typeSybtype(Bonus::SPECIAL_PECULIAR_ENCHANT, sse.id));
// if (bonus)
// {
// switch(bonus->additionalInfo)
// {
// case 0: //normal
// switch(type->level)
// {
// case 1: case 2:
// power += 3; //it doesn't necessarily make sense for some spells, use it wisely
// break;
// case 3: case 4:
// power += 2;
// break;
// case 5: case 6:
// power += 1;
// break;
// }
// break;
// case 1: //only Coronius as yet
// power = std::max(5 - type->level, 0);
// break;
// }
// }
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
// if (hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, 41)) //TODO: better handling of bonus percentages
// {
// int damagePercent = dynamic_cast<const CGHeroInstance*>(armyObj)->level * valOfBonuses(Bonus::SPECIAL_BLESS_DAMAGE, 41) / type->level;
// sf.push_back(featureGenerator(Bonus::CREATURE_DAMAGE, 0, damagePercent, sse.turnsRemain));
// sf.back().id = sse.id;
// sf.back().valType = Bonus::PERCENT_TO_ALL;
// }
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.val >= 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
// if (bonus) //Coronius
// {
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
// sf.back().id = sse.id;
// }
sf.push_back(featureGenerator(Bonus::SLAYER, 0, sse.val, 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.val]/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.val, sse.turnsRemain));
sf.back().id = sse.id;
break;
case 60: //hypnotize
sf.push_back(featureGenerator(Bonus::HYPNOTIZED, 0, sse.val, sse.turnsRemain));
sf.back().id = sse.id;
break;
case 61: //forgetfulness
sf.push_back(featureGenerator(Bonus::FORGETFULL, 0, sse.val, sse.turnsRemain));
sf.back().id = sse.id;
break;
case 62: //blind
sf.push_back(makeFeatureVal(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(makeFeatureVal(Bonus::GENERAL_ATTACK_REDUCTION, Bonus::UNTIL_ATTACK | Bonus::N_TURNS, 0, power, Bonus::SPELL_EFFECT, sse.turnsRemain));
sf.back().id = sse.id;
break;
}
}
ui8 CStack::howManyEffectsSet(ui16 id) const
@ -1904,7 +1905,7 @@ THex CStack::occupiedHex() const
}
BonusList CStack::getSpellBonuses() const
{
return getBonuses(Selector::sourceTypeSel(Bonus::CASTED_SPELL));
return getBonuses(Selector::sourceTypeSel(Bonus::SPELL_EFFECT));
}
std::vector<si32> CStack::activeSpells() const

View File

@ -148,23 +148,23 @@ public:
bool canMove(int turn = 0) const; //if stack can move
ui32 Speed(int turn = 0) const; //get speed of creature with all modificators
BonusList getSpellBonuses() const;
void stackEffectToFeature(BonusList & sf, const Bonus & sse);
static void stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse);
std::vector<si32> activeSpells() const; //returns vector of active spell IDs sorted by time of cast
const CGHeroInstance *getMyHero() const; //if stack belongs to hero (directly or was by him summoned) returns hero, NULL otherwise
static inline Bonus *featureGenerator(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, si32 additionalInfo = 0, si32 limit = Bonus::NO_LIMIT)
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;
hb->source = Bonus::CASTED_SPELL; //right?
Bonus hb = makeFeatureVal(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain, additionalInfo);
hb.effectRange = limit;
hb.source = Bonus::SPELL_EFFECT;
return hb;
}
static inline Bonus *featureGeneratorVT(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, ui8 valType)
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;
ret->source = Bonus::CASTED_SPELL; //right?
Bonus ret = makeFeatureVal(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain);
ret.valType = valType;
ret.source = Bonus::SPELL_EFFECT;
return ret;
}

View File

@ -184,10 +184,9 @@ struct DLL_EXPORT Bonus
};
enum BonusSource
{
ARTIFACT,
ARTIFACT_INSTANCE,
OBJECT,
CASTED_SPELL,
ARTIFACT,
ARTIFACT_INSTANCE,
OBJECT,
CREATURE_ABILITY,
TERRAIN_NATIVE,
TERRAIN_OVERLAY,
@ -458,20 +457,27 @@ namespace NBonus
};
//generates HeroBonus from given data
inline Bonus* makeFeature(Bonus::BonusType type, ui8 duration, si16 subtype, si32 value, Bonus::BonusSource source, ui16 turnsRemain = 0, si32 additionalInfo = 0)
inline Bonus makeFeatureVal(Bonus::BonusType type, ui8 duration, si16 subtype, si32 value, Bonus::BonusSource source, ui16 turnsRemain = 0, si32 additionalInfo = 0)
{
Bonus* sf = new Bonus();
sf->type = type;
sf->duration = duration;
sf->source = source;
sf->turnsRemain = turnsRemain;
sf->subtype = subtype;
sf->val = value;
sf->additionalInfo = additionalInfo;
Bonus sf;
sf.type = type;
sf.duration = duration;
sf.source = source;
sf.turnsRemain = turnsRemain;
sf.subtype = subtype;
sf.val = value;
sf.additionalInfo = additionalInfo;
return sf;
}
//generates HeroBonus from given data
inline Bonus * makeFeature(Bonus::BonusType type, ui8 duration, si16 subtype, si32 value, Bonus::BonusSource source, ui16 turnsRemain = 0, si32 additionalInfo = 0)
{
return new Bonus(makeFeatureVal(type, duration, subtype, value, source, turnsRemain, additionalInfo));
}
class DLL_EXPORT CSelectorsConjunction
{
const CSelector first, second;

View File

@ -1327,7 +1327,7 @@ struct SetStackEffect : public CPackForClient //3010
void applyCl(CClient *cl);
std::vector<ui32> stacks; //affected stacks (IDs)
Bonus effect; //type of effect
std::vector<Bonus> effect; //bonuses to apply
template <typename Handler> void serialize(Handler &h, const int version)
{
h & stacks & effect;

View File

@ -888,7 +888,7 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
//remove effects and restore only those with remaining turns in duration
BonusList tmpEffects = s->bonuses;
s->bonuses.removeSpells(Bonus::CASTED_SPELL);
s->bonuses.removeSpells(Bonus::SPELL_EFFECT);
BOOST_FOREACH(Bonus *it, tmpEffects)
{
@ -1072,7 +1072,7 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
}
}
s->bonuses.removeSpells(Bonus::CASTED_SPELL); //removing all effects
s->bonuses.removeSpells(Bonus::SPELL_EFFECT); //removing all effects
s->bonuses = remainingEff; //assigning effects that should remain
//removing all features from spells
@ -1135,27 +1135,17 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
}
}
void actualizeEffect(CStack * s, Bonus & ef)
void actualizeEffect(CStack * s, const std::vector<Bonus> & ef)
{
//actualizing effects vector
BOOST_FOREACH(Bonus *it, s->bonuses)
{
if(it->id == ef.id)
{
it->turnsRemain = std::max(it->turnsRemain, ef.turnsRemain);
}
}
//actualizing features vector
BonusList sf;
s->stackEffectToFeature(sf, ef);
BOOST_FOREACH(const Bonus *fromEffect, sf)
BOOST_FOREACH(const Bonus &fromEffect, ef)
{
BOOST_FOREACH(Bonus *stackBonus, s->bonuses) //TODO: optimize
{
if(stackBonus->source == Bonus::SPELL_EFFECT && stackBonus->type == fromEffect->type && stackBonus->subtype == fromEffect->subtype)
if(stackBonus->source == Bonus::SPELL_EFFECT && stackBonus->type == fromEffect.type && stackBonus->subtype == fromEffect.subtype)
{
stackBonus->turnsRemain = std::max(stackBonus->turnsRemain, ef.turnsRemain);
stackBonus->turnsRemain = std::max(stackBonus->turnsRemain, fromEffect.turnsRemain);
}
}
}
@ -1169,14 +1159,12 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
CStack *s = gs->curB->getStack(id);
if(s)
{
if(effect.id == 42 || !s->hasBonus(Selector::source(Bonus::CASTED_SPELL, effect.id)))//disrupting ray or not on the list - just add
int id = effect.begin()->id; //effects' source ID
if(id == 47 || !s->hasBonus(Selector::source(Bonus::SPELL_EFFECT, id)))//disrupting ray or not on the list - just add
{
s->addNewBonus(new Bonus(effect));
BonusList sf;
s->stackEffectToFeature(sf, effect);
BOOST_FOREACH(Bonus *fromEffect, sf)
BOOST_FOREACH(Bonus &fromEffect, effect)
{
s->addNewBonus(fromEffect);
s->addNewBonus( new Bonus(fromEffect));
}
}
else //just actualize

View File

@ -3037,7 +3037,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
{
//defensive stance
SetStackEffect sse;
sse.effect = Bonus(Bonus::STACK_GETS_TURN, Bonus::PRIMARY_SKILL, Bonus::OTHER, 20, -1, PrimarySkill::DEFENSE, Bonus::PERCENT_TO_ALL);
sse.effect.push_back( Bonus(Bonus::STACK_GETS_TURN, Bonus::PRIMARY_SKILL, Bonus::OTHER, 20, -1, PrimarySkill::DEFENSE, Bonus::PERCENT_TO_ALL) );
sse.stacks.push_back(ba.stackNumber);
sendAndApply(&sse);
@ -3644,9 +3644,11 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
continue;
sse.stacks.push_back((*it)->ID);
}
sse.effect.id = spellID;
sse.effect.val = spellLvl;
sse.effect.turnsRemain = gs->curB->calculateSpellDuration(spell, caster, usedSpellPower);
Bonus pseudoBonus;
pseudoBonus.id = spellID;
pseudoBonus.val = spellLvl;
pseudoBonus.turnsRemain = gs->curB->calculateSpellDuration(spell, caster, usedSpellPower);
CStack::stackEffectToFeature(sse.effect, pseudoBonus);
if(!sse.stacks.empty())
sendAndApply(&sse);
break;
@ -4444,7 +4446,7 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
COMPLAIN_RET("Destination tile doesn't exist!");
if(!h->movement)
COMPLAIN_RET("Hero needs movement points to cast Dimension Door!");
if(h->getBonusesCount(Bonus::CASTED_SPELL, Spells::DIMENSION_DOOR) >= s->powers[schoolLevel]) //limit casts per turn
if(h->getBonusesCount(Bonus::SPELL_EFFECT, Spells::DIMENSION_DOOR) >= s->powers[schoolLevel]) //limit casts per turn
{
InfoWindow iw;
iw.player = h->tempOwner;
@ -4456,7 +4458,7 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
GiveBonus gb;
gb.id = h->id;
gb.bonus = Bonus(Bonus::ONE_DAY, Bonus::NONE, Bonus::CASTED_SPELL, 0, Spells::DIMENSION_DOOR);
gb.bonus = Bonus(Bonus::ONE_DAY, Bonus::NONE, Bonus::SPELL_EFFECT, 0, Spells::DIMENSION_DOOR);
sendAndApply(&gb);
if(!dest->isClear(curr)) //wrong dest tile
@ -4489,7 +4491,7 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
GiveBonus gb;
gb.id = h->id;
gb.bonus = Bonus(Bonus::ONE_DAY, Bonus::FLYING_MOVEMENT, Bonus::CASTED_SPELL, 0, Spells::FLY, subtype);
gb.bonus = Bonus(Bonus::ONE_DAY, Bonus::FLYING_MOVEMENT, Bonus::SPELL_EFFECT, 0, Spells::FLY, subtype);
sendAndApply(&gb);
}
break;
@ -4499,7 +4501,7 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
GiveBonus gb;
gb.id = h->id;
gb.bonus = Bonus(Bonus::ONE_DAY, Bonus::WATER_WALKING, Bonus::CASTED_SPELL, 0, Spells::FLY, subtype);
gb.bonus = Bonus(Bonus::ONE_DAY, Bonus::WATER_WALKING, Bonus::SPELL_EFFECT, 0, Spells::FLY, subtype);
sendAndApply(&gb);
}
break;