mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
- MIND_IMMUNITY bonus replaces separate protectons from various spells
- Creature Window can handle descriptions of spellcasting abilities
This commit is contained in:
parent
1cbd7e94e4
commit
855cebfe81
@ -49,8 +49,13 @@
|
||||
{ "id": "WATER_IMMUNITY", "name": "Immune to Water", "description": "" },
|
||||
{ "id": "AIR_IMMUNITY", "name": "Immune to Air", "description": "" },
|
||||
{ "id": "EARTH_IMMUNITY", "name": "Immune to Earth", "description": "" },
|
||||
{ "id": "MIND_IMMUNITY", "name": "Immune to mind spells", "description": "" },
|
||||
{ "id": "DIRECT_DAMAGE_IMMUNITY", "name": "Direct Damage Immunity", "description": "Immune to direct damage spells" },
|
||||
{ "id": "RECEPTIVE", "name": "Receptive", "description": "No Immunity to Friendly Spells" },
|
||||
{ "id": "REBIRTH", "name": "Rebirth (%d%)", "description": "Stack will rise after death" }
|
||||
{ "id": "REBIRTH", "name": "Rebirth (%d%)", "description": "Stack will rise after death" },
|
||||
{ "id": "SPELLCASTER", "name": "Spellcaster (%s)", "description": "Can cast spells" },
|
||||
{ "id": "ENCHANTER", "name": "Enchanter (%s)", "description": "Casts mass spell every turn" },
|
||||
{ "id": "RANDOM_SPELLCASTER", "name": "Random spellcaster", "description": "Can cast random spell" },
|
||||
{ "id": "DAEMON_SUMMONING", "name": "Summoner (%s)", "description": "Can rise creatures from corpses" }
|
||||
]
|
||||
}
|
||||
|
@ -2171,6 +2171,11 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInst
|
||||
if (battleTestElementalImmunity(subject, spell, Bonus::AIR_IMMUNITY, damageSpell))
|
||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||
}
|
||||
if (vstd::contains(VLC->spellh->mindSpells, spell->id))
|
||||
{
|
||||
if (subject->hasBonusOfType(Bonus::MIND_IMMUNITY))
|
||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||
}
|
||||
|
||||
if (vstd::contains(VLC->spellh->risingSpells, spell->id))
|
||||
{
|
||||
|
@ -586,12 +586,8 @@ void CArtHandler::addBonuses()
|
||||
ART_LUCK(46,+1); //Clover of Fortune
|
||||
ART_LUCK(47,+1); //Cards of Prophecy
|
||||
ART_LUCK(48,+1); //Ladybird of Luck
|
||||
ART_MORALE(49,+1); //Badge of Courage -> +1 morale and immunity to hostile mind spells:
|
||||
giveArtBonus(49,Bonus::SPELL_IMMUNITY,0,50);//sorrow
|
||||
giveArtBonus(49,Bonus::SPELL_IMMUNITY,0,59);//berserk
|
||||
giveArtBonus(49,Bonus::SPELL_IMMUNITY,0,60);//hypnotize
|
||||
giveArtBonus(49,Bonus::SPELL_IMMUNITY,0,61);//forgetfulness
|
||||
giveArtBonus(49,Bonus::SPELL_IMMUNITY,0,62);//blind
|
||||
ART_MORALE(49,+1); //Badge of Courage -> +1 morale
|
||||
giveArtBonus(49,Bonus::MIND_IMMUNITY,0); //immunity to hostile mind spells:
|
||||
ART_MORALE(50,+1); //Crest of Valor
|
||||
ART_MORALE(51,+1); //Glyph of Gallantry
|
||||
|
||||
|
@ -19,17 +19,6 @@ extern CLodHandler * bitmaph;
|
||||
*
|
||||
*/
|
||||
|
||||
static std::vector<int> getMindSpells()
|
||||
{
|
||||
std::vector<int> ret;
|
||||
ret.push_back(50); //sorrow
|
||||
ret.push_back(59); //berserk
|
||||
ret.push_back(60); //hypnotize
|
||||
ret.push_back(61); //forgetfulness
|
||||
ret.push_back(62); //blind
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCreatureHandler::CCreatureHandler()
|
||||
{
|
||||
VLC->creh = this;
|
||||
@ -395,11 +384,7 @@ void CCreatureHandler::loadCreatures()
|
||||
ncre.addBonus(0, Bonus::ATTACKS_ALL_ADJACENT);
|
||||
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IMMUNE_TO_MIND_SPELLS"))
|
||||
{
|
||||
std::vector<int> mindSpells = getMindSpells();
|
||||
for(int g=0; g<mindSpells.size(); ++g)
|
||||
ncre.addBonus(0, Bonus::SPELL_IMMUNITY, mindSpells[g]); //giants are immune to mind spells
|
||||
}
|
||||
ncre.addBonus(0, Bonus::MIND_IMMUNITY); //giants are immune to mind spells
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IMMUNE_TO_FIRE_SPELLS"))
|
||||
ncre.addBonus(0, Bonus::FIRE_IMMUNITY);
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "HAS_EXTENDED_ATTACK"))
|
||||
@ -751,11 +736,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
|
||||
b.type = Bonus::NO_MORALE; break;
|
||||
case 'p': //Mind spells
|
||||
case 'P':
|
||||
{
|
||||
loadMindImmunity(b, bl, src, it);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
b.type = Bonus::MIND_IMMUNITY; break;
|
||||
case 'r':
|
||||
b.type = Bonus::REBIRTH; //on/off? makes sense?
|
||||
b.subtype = 0;
|
||||
@ -954,34 +935,6 @@ 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.sid]; //odd workaround
|
||||
|
||||
b.type = Bonus::SPELL_IMMUNITY;
|
||||
b.val = Bonus::BASE_NUMBER;
|
||||
si32 curVal;
|
||||
|
||||
b.val = 0; //on-off ability, no value specified
|
||||
loadToIt (curVal, src, it, 4); // 0 level is never active
|
||||
for (int i = 1; i < 11; ++i)
|
||||
{
|
||||
loadToIt (curVal, src, it, 4);
|
||||
if (curVal == 1)
|
||||
{
|
||||
b.limiter.reset (new RankRangeLimiter(i));
|
||||
break; //only one limiter here
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> mindSpells = getMindSpells(); //multiplicate spells
|
||||
for (int g=0; g < mindSpells.size(); ++g)
|
||||
{
|
||||
b.subtype = mindSpells[g];
|
||||
cre->getBonusList().push_back(new Bonus(b));
|
||||
}
|
||||
}
|
||||
|
||||
int CCreatureHandler::stringToNumber(std::string & s)
|
||||
{
|
||||
boost::algorithm::replace_first(s,"#",""); //drop hash character
|
||||
|
@ -121,7 +121,6 @@ public:
|
||||
void loadAnimationInfo();
|
||||
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
|
||||
void loadStackExp(Bonus & b, BonusList & bl, std::string & src, int & it);
|
||||
void loadMindImmunity(Bonus & b, BonusList & bl, std::string & src, int & it); //multiple bonuses at once
|
||||
int stringToNumber(std::string & s);//help function for parsing CREXPBON.txt
|
||||
|
||||
bool isGood (si8 faction) const;
|
||||
|
@ -643,6 +643,7 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
|
||||
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))));
|
||||
break;
|
||||
case Bonus::HATE:
|
||||
case Bonus::DAEMON_SUMMONING:
|
||||
boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl);
|
||||
break;
|
||||
case Bonus::LEVEL_SPELL_IMMUNITY:
|
||||
@ -650,9 +651,9 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
|
||||
break;
|
||||
case Bonus::SPELL_AFTER_ATTACK:
|
||||
case Bonus::SPELL_BEFORE_ATTACK:
|
||||
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
|
||||
break;
|
||||
case Bonus::SPELL_IMMUNITY:
|
||||
case Bonus::SPELLCASTER:
|
||||
case Bonus::ENCHANTER:
|
||||
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
|
||||
break;
|
||||
case Bonus::MAGIC_RESISTANCE:
|
||||
@ -685,10 +686,13 @@ std::string CStackInstance::bonusToGraphics(Bonus *bonus) const
|
||||
fileName = "E_BREATH.bmp"; break;
|
||||
case Bonus::SPELL_AFTER_ATTACK:
|
||||
fileName = "E_CAST.bmp"; break;
|
||||
//"E_CAST1.bmp"
|
||||
case Bonus::ENCHANTER:
|
||||
case Bonus::RANDOM_SPELLCASTER:
|
||||
fileName = "E_CAST1.bmp"; break;
|
||||
case Bonus::SPELL_BEFORE_ATTACK:
|
||||
fileName ="E_CAST2.bmp"; break;
|
||||
//"E_CASTER.bmp"
|
||||
case Bonus::SPELLCASTER:
|
||||
fileName = "E_CASTER.bmp"; break;
|
||||
case Bonus::JOUSTING:
|
||||
fileName = "E_CHAMP.bmp"; break;
|
||||
case Bonus::DOUBLE_DAMAGE_CHANCE:
|
||||
@ -733,7 +737,8 @@ std::string CStackInstance::bonusToGraphics(Bonus *bonus) const
|
||||
fileName = "E_MANA.bmp"; break;
|
||||
case Bonus::NO_MELEE_PENALTY:
|
||||
fileName = "E_MELEE.bmp"; break;
|
||||
//"E_MIND.bmp"
|
||||
case Bonus::MIND_IMMUNITY:
|
||||
fileName = "E_MIND.bmp"; break;
|
||||
case Bonus::SELF_MORALE:
|
||||
fileName = "E_MINOT.bmp"; break;
|
||||
case Bonus::NO_MORALE:
|
||||
@ -843,8 +848,6 @@ std::string CStackInstance::bonusToGraphics(Bonus *bonus) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
//"E_SPWATER.bmp"
|
||||
//"E_SPWATER1.bmp"
|
||||
//"E_SUMMON.bmp"
|
||||
//"E_SUMMON1.bmp"
|
||||
//"E_SUMMON2.bmp"
|
||||
|
@ -318,4 +318,5 @@ void CSpellHandler::loadSpells()
|
||||
|
||||
damageSpells += 11, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 57, 77;
|
||||
risingSpells += 38, 39, 40;
|
||||
mindSpells += 50, 59, 60, 61, 62;
|
||||
}
|
||||
|
@ -83,10 +83,11 @@ public:
|
||||
std::vector< ConstTransitivePtr<CSpell> > spells;
|
||||
std::set<TSpell> damageSpells; //they inflict damage and require particular threatment
|
||||
std::set<TSpell> risingSpells; //they affect dead stacks and need special target selection
|
||||
std::set<TSpell> mindSpells;
|
||||
void loadSpells();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & spells & damageSpells & risingSpells;
|
||||
h & spells & damageSpells & risingSpells & mindSpells;
|
||||
}
|
||||
};
|
||||
|
@ -112,6 +112,7 @@ namespace PrimarySkill
|
||||
BONUS_NAME(WATER_IMMUNITY) \
|
||||
BONUS_NAME(EARTH_IMMUNITY) \
|
||||
BONUS_NAME(AIR_IMMUNITY) \
|
||||
BONUS_NAME(MIND_IMMUNITY) \
|
||||
BONUS_NAME(FIRE_SHIELD) \
|
||||
BONUS_NAME(UNDEAD) \
|
||||
BONUS_NAME(HP_REGENERATION) /*creature regenerates val HP every new round*/ \
|
||||
|
Loading…
Reference in New Issue
Block a user