mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* fixed bugs 470 and 523
* minor improvements
This commit is contained in:
parent
450ae1772c
commit
519a4186de
@ -596,7 +596,7 @@ bool CBattleCallback::battleCanCastSpell()
|
||||
if(!gs->curB) //there is no battle
|
||||
return false;
|
||||
|
||||
return gs->curB->battleCanCastSpell(player) == SpellCasting::OK;
|
||||
return gs->curB->battleCanCastSpell(player, BattleInfo::HERO_CASTING) == SpellCasting::OK;
|
||||
}
|
||||
|
||||
bool CBattleCallback::battleCanFlee()
|
||||
@ -1097,7 +1097,7 @@ SpellCasting::ESpellCastProblem CBattleCallback::battleCanCastThisSpell( const C
|
||||
return SpellCasting::NO_HERO_TO_CAST_SPELL;
|
||||
}
|
||||
|
||||
return gs->curB->battleCanCastThisSpell(player, spell);
|
||||
return gs->curB->battleCanCastThisSpell(player, spell, BattleInfo::HERO_CASTING);
|
||||
}
|
||||
|
||||
si8 CBattleCallback::battleGetTacticDist()
|
||||
|
@ -2859,7 +2859,7 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
|
||||
|
||||
void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
|
||||
{
|
||||
int effID = sse.effect.back().id;
|
||||
int effID = sse.effect.back().sid;
|
||||
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)
|
||||
|
@ -1138,7 +1138,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
|
||||
ch = ci->town->visitingHero;
|
||||
};
|
||||
if (bl.size())
|
||||
summ+=AddToString (CGI->arth->artifacts[bl.front()->id]->Name()+" %+d", descr, bl.totalValue());
|
||||
summ+=AddToString (CGI->arth->artifacts[bl.front()->sid]->Name()+" %+d", descr, bl.totalValue());
|
||||
|
||||
//TODO: player bonuses
|
||||
|
||||
|
2
global.h
2
global.h
@ -313,7 +313,7 @@ namespace SpellCasting
|
||||
{
|
||||
OK, NO_HERO_TO_CAST_SPELL, ALREADY_CASTED_THIS_TURN, NO_SPELLBOOK, ANOTHER_ELEMENTAL_SUMMONED,
|
||||
HERO_DOESNT_KNOW_SPELL, NOT_ENOUGH_MANA, ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL,
|
||||
SECOND_HEROS_SPELL_IMMUNITY, SPELL_LEVEL_LIMIT_EXCEEDED
|
||||
SECOND_HEROS_SPELL_IMMUNITY, SPELL_LEVEL_LIMIT_EXCEEDED, NO_SPELLS_TO_DISPEL
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d
|
||||
|
||||
BOOST_FOREACH(const Bonus *it, stack->bonuses)
|
||||
{
|
||||
if (it->source == Bonus::SPELL_EFFECT && it->id == 28 && it->val >= 2)
|
||||
if (it->source == Bonus::SPELL_EFFECT && it->sid == 28 && it->val >= 2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -1617,32 +1617,48 @@ bool BattleInfo::isInTacticRange( THex dest ) const
|
||||
|| (tacticsSide && dest.getX() < BFIELD_WIDTH - 1 && dest.getX() >= BFIELD_WIDTH - tacticDistance - 1));
|
||||
}
|
||||
|
||||
SpellCasting::ESpellCastProblem BattleInfo::battleCanCastSpell(int player) const
|
||||
SpellCasting::ESpellCastProblem BattleInfo::battleCanCastSpell(int player, ECastingMode mode) const
|
||||
{
|
||||
int side = sides[0] == player ? 0 : 1;
|
||||
|
||||
if(castSpells[side] > 0)
|
||||
return SpellCasting::ALREADY_CASTED_THIS_TURN;
|
||||
if(!heroes[side])
|
||||
return SpellCasting::NO_HERO_TO_CAST_SPELL;
|
||||
if(!heroes[side]->getArt(17))
|
||||
return SpellCasting::NO_SPELLBOOK;
|
||||
switch (mode)
|
||||
{
|
||||
case HERO_CASTING:
|
||||
{
|
||||
if(castSpells[side] > 0)
|
||||
return SpellCasting::ALREADY_CASTED_THIS_TURN;
|
||||
if(!heroes[side])
|
||||
return SpellCasting::NO_HERO_TO_CAST_SPELL;
|
||||
if(!heroes[side]->getArt(17))
|
||||
return SpellCasting::NO_SPELLBOOK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return SpellCasting::OK;
|
||||
}
|
||||
|
||||
SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpell( int player, const CSpell * spell ) const
|
||||
SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpell( int player, const CSpell * spell, ECastingMode mode ) const
|
||||
{
|
||||
SpellCasting::ESpellCastProblem genProblem = battleCanCastSpell(player);
|
||||
SpellCasting::ESpellCastProblem genProblem = battleCanCastSpell(player, mode);
|
||||
if(genProblem != SpellCasting::OK)
|
||||
return genProblem;
|
||||
int cside = sides[0] == player ? 0 : 1; //caster's side
|
||||
const CGHeroInstance * caster = heroes[cside];
|
||||
if(!caster->canCastThisSpell(spell))
|
||||
return SpellCasting::HERO_DOESNT_KNOW_SPELL;
|
||||
|
||||
if(caster->mana < getSpellCost(spell, caster)) //not enough mana
|
||||
return SpellCasting::NOT_ENOUGH_MANA;
|
||||
int cside = sides[0] == player ? 0 : 1; //caster's side
|
||||
switch(mode)
|
||||
{
|
||||
HERO_CASTING:
|
||||
{
|
||||
const CGHeroInstance * caster = heroes[cside];
|
||||
if(!caster->canCastThisSpell(spell))
|
||||
return SpellCasting::HERO_DOESNT_KNOW_SPELL;
|
||||
|
||||
if(caster->mana < getSpellCost(spell, caster)) //not enough mana
|
||||
return SpellCasting::NOT_ENOUGH_MANA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(spell->id < 10) //it's adventure spell (not combat))
|
||||
return SpellCasting::ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL;
|
||||
@ -1673,6 +1689,34 @@ SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpell( int player,
|
||||
return SpellCasting::OK;
|
||||
}
|
||||
|
||||
SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpellHere( int player, const CSpell * spell, ECastingMode mode, THex dest )
|
||||
{
|
||||
SpellCasting::ESpellCastProblem moreGeneralProblem = battleCanCastThisSpell(player, spell, mode);
|
||||
if(moreGeneralProblem != SpellCasting::OK)
|
||||
return moreGeneralProblem;
|
||||
|
||||
const CStack * subject = getStackT(dest, false);
|
||||
//dispel helpful spells
|
||||
if(spell->id == 78)
|
||||
{
|
||||
BonusList spellBon = subject->getSpellBonuses();
|
||||
bool hasPositiveSpell = false;
|
||||
BOOST_FOREACH(const Bonus * b, spellBon)
|
||||
{
|
||||
if(VLC->spellh->spells[b->sid]->positiveness > 0)
|
||||
{
|
||||
hasPositiveSpell = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!hasPositiveSpell)
|
||||
{
|
||||
return SpellCasting::NO_SPELLS_TO_DISPEL;
|
||||
}
|
||||
}
|
||||
return SpellCasting::OK;
|
||||
}
|
||||
|
||||
CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)
|
||||
: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
|
||||
counterAttacks(1)
|
||||
@ -1756,7 +1800,7 @@ const Bonus * CStack::getEffect( ui16 id, int turn /*= 0*/ ) const
|
||||
{
|
||||
BOOST_FOREACH(Bonus *it, bonuses)
|
||||
{
|
||||
if(it->source == Bonus::SPELL_EFFECT && it->id == id)
|
||||
if(it->source == Bonus::SPELL_EFFECT && it->sid == id)
|
||||
{
|
||||
if(!turn || it->turnsRemain > turn)
|
||||
return &(*it);
|
||||
@ -1767,7 +1811,7 @@ const Bonus * CStack::getEffect( ui16 id, int turn /*= 0*/ ) const
|
||||
|
||||
void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
|
||||
{
|
||||
si32 power = VLC->spellh->spells[sse.id]->powers[sse.val];
|
||||
si32 power = VLC->spellh->spells[sse.sid]->powers[sse.val];
|
||||
//why, why, WHY this code is here?!?
|
||||
// Bonus * bonus = getBonus(Selector::typeSybtype(Bonus::SPECIAL_PECULIAR_ENCHANT, sse.id));
|
||||
// if (bonus)
|
||||
@ -1794,142 +1838,142 @@ void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
|
||||
// }
|
||||
// }
|
||||
|
||||
switch(sse.id)
|
||||
switch(sse.sid)
|
||||
{
|
||||
case 27: //shield
|
||||
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 28: //air shield
|
||||
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 29: //fire shield
|
||||
sf.push_back(featureGenerator(Bonus::FIRE_SHIELD, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 30: //protection from air
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 31: //protection from fire
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 32: //protection from water
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 2, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 33: //protection from earth
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 3, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 34: //anti-magic
|
||||
sf.push_back(featureGenerator(Bonus::LEVEL_SPELL_IMMUNITY, 0, power - 1, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
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().sid = sse.sid;
|
||||
// sf.back().valType = Bonus::PERCENT_TO_ALL;
|
||||
// }
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MAXIMUM_DAMAGE, -1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
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;
|
||||
sf.back().sid = sse.sid;
|
||||
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;
|
||||
sf.back().sid = sse.sid;
|
||||
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;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 45: //weakness
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 46: //stone skin
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 47: //disrupting ray
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
sf.back().valType = Bonus::ADDITIVE_VALUE;
|
||||
break;
|
||||
case 48: //prayer
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 49: //mirth
|
||||
sf.push_back(featureGenerator(Bonus::MORALE, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 50: //sorrow
|
||||
sf.push_back(featureGenerator(Bonus::MORALE, 0, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 51: //fortune
|
||||
sf.push_back(featureGenerator(Bonus::LUCK, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 52: //misfortune
|
||||
sf.push_back(featureGenerator(Bonus::LUCK, 0, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 53: //haste
|
||||
sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
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;
|
||||
sf.back().sid = sse.sid;
|
||||
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.back().sid = sse.sid;
|
||||
// }
|
||||
sf.push_back(featureGenerator(Bonus::SLAYER, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
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;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 58: //counterstrike
|
||||
sf.push_back(featureGenerator(Bonus::ADDITIONAL_RETALIATION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 59: //bersek
|
||||
sf.push_back(featureGenerator(Bonus::ATTACKS_NEAREST_CREATURE, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 60: //hypnotize
|
||||
sf.push_back(featureGenerator(Bonus::HYPNOTIZED, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 61: //forgetfulness
|
||||
sf.push_back(featureGenerator(Bonus::FORGETFULL, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().sid = sse.sid;
|
||||
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.back().sid = sse.sid;
|
||||
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;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1938,7 +1982,7 @@ ui8 CStack::howManyEffectsSet(ui16 id) const
|
||||
{
|
||||
ui8 ret = 0;
|
||||
BOOST_FOREACH(const Bonus *it, bonuses)
|
||||
if(it->source == Bonus::SPELL_EFFECT && it->id == id) //effect found
|
||||
if(it->source == Bonus::SPELL_EFFECT && it->sid == id) //effect found
|
||||
{
|
||||
++ret;
|
||||
}
|
||||
@ -1997,8 +2041,8 @@ std::vector<si32> CStack::activeSpells() const
|
||||
BonusList spellEffects = getSpellBonuses();
|
||||
BOOST_FOREACH(const Bonus *it, spellEffects)
|
||||
{
|
||||
if (!vstd::contains(ret, it->id)) //do not duplicate spells with multiple effects
|
||||
ret.push_back(it->id);
|
||||
if (!vstd::contains(ret, it->sid)) //do not duplicate spells with multiple effects
|
||||
ret.push_back(it->sid);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -115,8 +115,11 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
|
||||
si8 canTeleportTo(const CStack * stack, THex destHex, int telportLevel) const; //determines if given stack can teleport to given place
|
||||
bool battleCanShoot(const CStack * stack, THex dest) const; //determines if stack with given ID shoot at the selected destination
|
||||
|
||||
SpellCasting::ESpellCastProblem battleCanCastSpell(int player) const; //returns true if there are no general issues preventing from castng a spell
|
||||
SpellCasting::ESpellCastProblem battleCanCastThisSpell(int player, const CSpell * spell) const; //chcecks if given player can cast given spell
|
||||
enum ECastingMode {HERO_CASTING, AFTER_ATTACK_CASTING};
|
||||
|
||||
SpellCasting::ESpellCastProblem battleCanCastSpell(int player, ECastingMode mode) const; //returns true if there are no general issues preventing from casting a spell
|
||||
SpellCasting::ESpellCastProblem battleCanCastThisSpell(int player, const CSpell * spell, ECastingMode mode) const; //checks if given player can cast given spell
|
||||
SpellCasting::ESpellCastProblem battleCanCastThisSpellHere(int player, const CSpell * spell, ECastingMode mode, THex dest); //checks if given player can cast given spell at given tile in given mode
|
||||
|
||||
bool battleCanFlee(int player) const; //returns true if player can flee from the battle
|
||||
const CStack * battleGetStack(THex pos, bool onlyAlive); //returns stack at given tile
|
||||
|
@ -415,7 +415,7 @@ void CCreatureHandler::loadCreatures()
|
||||
reader >> buf; nsf->subtype = buf;
|
||||
reader >> buf; nsf->additionalInfo = buf;
|
||||
nsf->source = Bonus::CREATURE_ABILITY;
|
||||
nsf->id = cre->idNumber;
|
||||
nsf->sid = cre->idNumber;
|
||||
nsf->duration = Bonus::ONE_BATTLE;
|
||||
nsf->turnsRemain = 0;
|
||||
|
||||
@ -673,7 +673,7 @@ void CCreatureHandler::loadCreatures()
|
||||
do //parse everything that's left
|
||||
{
|
||||
loadToIt(creid, buf, it, 4); //get index
|
||||
b.id = creid; //id = this particular creature ID
|
||||
b.sid = creid; //id = this particular creature ID
|
||||
loadStackExp(b, creatures[creid]->bonuses, buf, it); //add directly to CCreature Node
|
||||
loadToIt (dump2, buf, it, 3); //crop comment
|
||||
} while (it < buf.size());
|
||||
@ -1015,7 +1015,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
|
||||
|
||||
void CCreatureHandler::loadMindImmunity(Bonus & b, BonusList & bl, std::string & src, int & it)
|
||||
{
|
||||
CCreature * cre = creatures[b.id]; //odd workaround
|
||||
CCreature * cre = creatures[b.sid]; //odd workaround
|
||||
|
||||
b.type = Bonus::SPELL_IMMUNITY;
|
||||
b.val = Bonus::BASE_NUMBER;
|
||||
|
@ -461,7 +461,7 @@ void CGObjectInstance::giveDummyBonus(int heroID, ui8 duration) const
|
||||
gbonus.id = heroID;
|
||||
gbonus.bonus.duration = duration;
|
||||
gbonus.bonus.source = Bonus::OBJECT;
|
||||
gbonus.bonus.id = ID;
|
||||
gbonus.bonus.sid = ID;
|
||||
cb->giveHeroBonus(&gbonus);
|
||||
}
|
||||
|
||||
@ -946,7 +946,7 @@ void CGHeroInstance::initObj()
|
||||
{
|
||||
Bonus *bonus = new Bonus();
|
||||
bonus->val = it->val;
|
||||
bonus->id = id; //from the hero, speciality has no unique id
|
||||
bonus->sid = id; //from the hero, speciality has no unique id
|
||||
bonus->duration = Bonus::PERMANENT;
|
||||
bonus->source = Bonus::HERO_SPECIAL;
|
||||
switch (it->type)
|
||||
@ -4548,7 +4548,7 @@ void CGBonusingObject::onHeroVisit( const CGHeroInstance * h ) const
|
||||
gbonus.id = h->id;
|
||||
gbonus.bonus.duration = Bonus::ONE_BATTLE;
|
||||
gbonus.bonus.source = Bonus::OBJECT;
|
||||
gbonus.bonus.id = ID;
|
||||
gbonus.bonus.sid = ID;
|
||||
|
||||
bool second = false;
|
||||
Bonus secondBonus;
|
||||
@ -5766,7 +5766,7 @@ void CBank::onHeroVisit (const CGHeroInstance * h) const
|
||||
gbonus.id = h->id;
|
||||
gbonus.bonus.duration = Bonus::ONE_BATTLE;
|
||||
gbonus.bonus.source = Bonus::OBJECT;
|
||||
gbonus.bonus.id = ID;
|
||||
gbonus.bonus.sid = ID;
|
||||
gbonus.bdescr << "\n" << VLC->generaltexth->arraytxt[98];
|
||||
gbonus.bonus.type = Bonus::MORALE;
|
||||
gbonus.bonus.val = -1;
|
||||
@ -5812,7 +5812,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
|
||||
gbonus.id = h->id;
|
||||
gbonus.bonus.duration = Bonus::ONE_BATTLE;
|
||||
gbonus.bonus.source = Bonus::OBJECT;
|
||||
gbonus.bonus.id = ID;
|
||||
gbonus.bonus.sid = ID;
|
||||
gbonus.bdescr << "\n" << VLC->generaltexth->arraytxt[101];
|
||||
gbonus.bonus.type = Bonus::MORALE;
|
||||
gbonus.bonus.val = -1;
|
||||
@ -5831,7 +5831,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
|
||||
gbonus.id = h->id;
|
||||
gbonus.bonus.duration = Bonus::ONE_BATTLE;
|
||||
gbonus.bonus.source = Bonus::OBJECT;
|
||||
gbonus.bonus.id = ID;
|
||||
gbonus.bonus.sid = ID;
|
||||
gbonus.bdescr << "\n" << VLC->generaltexth->arraytxt[ID];
|
||||
gbonus.bonus.type = Bonus::MORALE;
|
||||
gbonus.bonus.val = -1;
|
||||
@ -6526,7 +6526,7 @@ void CGLighthouse::giveBonusTo( ui8 player ) const
|
||||
gb.id = player;
|
||||
gb.bonus.duration = Bonus::PERMANENT;
|
||||
gb.bonus.source = Bonus::OBJECT;
|
||||
gb.bonus.id = id;
|
||||
gb.bonus.sid = id;
|
||||
cb->sendAndApply(&gb);
|
||||
}
|
||||
|
||||
|
@ -499,7 +499,7 @@ int NBonus::getCount(const CBonusSystemNode *obj, int from, int id)
|
||||
const CSpell * Bonus::sourceSpell() const
|
||||
{
|
||||
if(source == SPELL_EFFECT)
|
||||
return VLC->spellh->spells[id];
|
||||
return VLC->spellh->spells[sid];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -519,18 +519,18 @@ std::string Bonus::Description() const
|
||||
switch(source)
|
||||
{
|
||||
case CREATURE_ABILITY:
|
||||
str << VLC->creh->creatures[id]->namePl;
|
||||
str << VLC->creh->creatures[sid]->namePl;
|
||||
break;
|
||||
case SECONDARY_SKILL:
|
||||
str << VLC->generaltexth->skillName[id] << " secondary skill";
|
||||
str << VLC->generaltexth->skillName[sid] << " secondary skill";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
Bonus::Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype/*=-1*/)
|
||||
: duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), id(ID), description(Desc)
|
||||
: duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), description(Desc)
|
||||
{
|
||||
additionalInfo = -1;
|
||||
turnsRemain = 0;
|
||||
@ -540,7 +540,7 @@ Bonus::Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si
|
||||
}
|
||||
|
||||
Bonus::Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, si32 Subtype/*=-1*/, ui8 ValType /*= ADDITIVE_VALUE*/)
|
||||
: duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), id(ID), valType(ValType)
|
||||
: duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), sid(ID), valType(ValType)
|
||||
{
|
||||
additionalInfo = -1;
|
||||
turnsRemain = 0;
|
||||
@ -596,7 +596,7 @@ namespace Selector
|
||||
|
||||
CSelector DLL_EXPORT source(ui8 source, ui32 sourceID)
|
||||
{
|
||||
return CSelectFieldEqual<ui8>(&Bonus::source, source) && CSelectFieldEqual<ui32>(&Bonus::id, sourceID);
|
||||
return CSelectFieldEqual<ui8>(&Bonus::source, source) && CSelectFieldEqual<ui32>(&Bonus::sid, sourceID);
|
||||
}
|
||||
|
||||
CSelector DLL_EXPORT sourceTypeSel(ui8 source)
|
||||
@ -668,7 +668,7 @@ DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
|
||||
printField(subtype);
|
||||
printField(duration);
|
||||
printField(source);
|
||||
printField(id);
|
||||
printField(sid);
|
||||
printField(additionalInfo);
|
||||
printField(turnsRemain);
|
||||
printField(valType);
|
||||
|
@ -58,7 +58,6 @@ namespace PrimarySkill
|
||||
BONUS_NAME(BLOCK_SPELLS_ABOVE_LEVEL) \
|
||||
BONUS_NAME(WATER_WALKING) /*subtype 1 - without penalty, 2 - with penalty*/ \
|
||||
BONUS_NAME(NO_SHOTING_PENALTY) \
|
||||
BONUS_NAME(DISPEL_IMMUNITY) \
|
||||
BONUS_NAME(NEGATE_ALL_NATURAL_IMMUNITIES) \
|
||||
BONUS_NAME(STACK_HEALTH) \
|
||||
BONUS_NAME(BLOCK_MORALE) \
|
||||
@ -226,7 +225,7 @@ struct DLL_EXPORT Bonus
|
||||
|
||||
ui8 source;//source type" uses BonusSource values - what gave that bonus
|
||||
si32 val;
|
||||
ui32 id; //source id: id of object/artifact/spell
|
||||
ui32 sid; //source id: id of object/artifact/spell
|
||||
ui8 valType; //by ValueType enum
|
||||
|
||||
si32 additionalInfo;
|
||||
@ -256,7 +255,7 @@ struct DLL_EXPORT Bonus
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & duration & type & subtype & source & val & id & description & additionalInfo & turnsRemain & valType & effectRange & limiter;
|
||||
h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter;
|
||||
}
|
||||
|
||||
static bool OneDay(const Bonus *hb)
|
||||
@ -285,7 +284,7 @@ struct DLL_EXPORT Bonus
|
||||
}
|
||||
static bool IsFrom(const Bonus &hb, ui8 source, ui32 id) //if id==0xffffff then id doesn't matter
|
||||
{
|
||||
return hb.source==source && (id==0xffffff || hb.id==id);
|
||||
return hb.source==source && (id==0xffffff || hb.sid==id);
|
||||
}
|
||||
inline bool operator == (const BonusType & cf) const
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ DLL_EXPORT void GiveBonus::applyGs( CGameState *gs )
|
||||
if(!bdescr.message.size()
|
||||
&& bonus.source == Bonus::OBJECT
|
||||
&& (bonus.type == Bonus::LUCK || bonus.type == Bonus::MORALE)
|
||||
&& gs->map->objects[bonus.id]->ID == EVENTI_TYPE) //it's morale/luck bonus from an event without description
|
||||
&& gs->map->objects[bonus.sid]->ID == EVENTI_TYPE) //it's morale/luck bonus from an event without description
|
||||
{
|
||||
descr = VLC->generaltexth->arraytxt[bonus.val > 0 ? 110 : 109]; //+/-%d Temporary until next battle"
|
||||
boost::replace_first(descr,"%d",boost::lexical_cast<std::string>(std::abs(bonus.val)));
|
||||
@ -222,7 +222,7 @@ DLL_EXPORT void RemoveBonus::applyGs( CGameState *gs )
|
||||
|
||||
for(BonusList::iterator i = bonuses.begin(); i != bonuses.end(); i++)
|
||||
{
|
||||
if((*i)->source == source && (*i)->id == id)
|
||||
if((*i)->source == source && (*i)->sid == id)
|
||||
{
|
||||
bonus = **i; //backup bonus (to show to interfaces later)
|
||||
bonuses.erase(i);
|
||||
@ -1052,7 +1052,7 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
//WTF?
|
||||
for (BonusList::iterator it = remainingEff.begin(); it != remainingEff.end(); it++)
|
||||
{
|
||||
if (onlyHelpful && VLC->spellh->spells[ (*it)->id ]->positiveness != 1)
|
||||
if (onlyHelpful && VLC->spellh->spells[ (*it)->sid ]->positiveness != 1)
|
||||
{
|
||||
remainingEff.push_back(*it);
|
||||
}
|
||||
@ -1147,7 +1147,7 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
CStack *s = gs->curB->getStack(id);
|
||||
if(s)
|
||||
{
|
||||
int id = effect.begin()->id; //effects' source ID
|
||||
int id = effect.begin()->sid; //effects' source ID
|
||||
if(id == 47 || !s->hasBonus(Selector::source(Bonus::SPELL_EFFECT, id)))//disrupting ray or not on the list - just add
|
||||
{
|
||||
BOOST_FOREACH(Bonus &fromEffect, effect)
|
||||
@ -1217,7 +1217,7 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
|
||||
for (BonusList::iterator it = changedStack->bonuses.begin(); it != changedStack->bonuses.end(); it++)
|
||||
{
|
||||
if(VLC->spellh->spells[(*it)->id]->positiveness < 0)
|
||||
if(VLC->spellh->spells[(*it)->sid]->positiveness < 0)
|
||||
{
|
||||
changedStack->bonuses.erase(it);
|
||||
}
|
||||
|
@ -3739,7 +3739,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
|
||||
sse.stacks.push_back((*it)->ID);
|
||||
}
|
||||
Bonus pseudoBonus;
|
||||
pseudoBonus.id = spellID;
|
||||
pseudoBonus.sid = spellID;
|
||||
pseudoBonus.val = spellLvl;
|
||||
pseudoBonus.turnsRemain = gs->curB->calculateSpellDuration(spell, caster, usedSpellPower);
|
||||
CStack::stackEffectToFeature(sse.effect, pseudoBonus);
|
||||
@ -3824,7 +3824,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
const CSpell *s = VLC->spellh->spells[ba.additionalInfo];
|
||||
ui8 skill = h->getSpellSchoolLevel(s); //skill level
|
||||
|
||||
SpellCasting::ESpellCastProblem escp = gs->curB->battleCanCastThisSpell(h->tempOwner, s);
|
||||
SpellCasting::ESpellCastProblem escp = gs->curB->battleCanCastThisSpell(h->tempOwner, s, BattleInfo::HERO_CASTING);
|
||||
if(escp != SpellCasting::OK)
|
||||
{
|
||||
tlog2 << "Spell cannot be cast!\n";
|
||||
@ -4408,6 +4408,12 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
int chance = sf->additionalInfo % 1000;
|
||||
//int meleeRanged = sf->additionalInfo / 1000;
|
||||
int destination = oneOfAttacked->position;
|
||||
|
||||
const CSpell * spell = VLC->spellh->spells[spellID];
|
||||
if(gs->curB->battleCanCastThisSpellHere(attacker->owner, spell, BattleInfo::AFTER_ATTACK_CASTING, oneOfAttacked->position)
|
||||
!= SpellCasting::OK)
|
||||
continue;
|
||||
|
||||
//check if spell should be casted (probability handling)
|
||||
if( rand()%100 >= chance )
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user