diff --git a/config/schemas/spell.json b/config/schemas/spell.json index bdc1a9313..8c075e4b6 100644 --- a/config/schemas/spell.json +++ b/config/schemas/spell.json @@ -150,6 +150,10 @@ "rising":{ "type":"boolean", "description": "Rising spell (implicitly sets positive)" + }, + "special":{ + "type": "boolean", + "description": "Special spell. Can be given only by Bonus::SPELL" } } }, diff --git a/config/spell_info.json b/config/spell_info.json index 0b1533014..b1419dfae 100644 --- a/config/spell_info.json +++ b/config/spell_info.json @@ -2170,7 +2170,8 @@ "flags" : { "damage": true, "offensive": true, - "negative": true + "negative": true, + "special": true } }, "counterstrike" : { diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 0c38d1fca..e9a86423a 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -1375,17 +1375,32 @@ bool CGHeroInstance::canCastThisSpell(const CSpell * spell) const if(!getArt(ArtifactPosition::SPELLBOOK)) //if hero has no spellbook return false; - if(vstd::contains(spells, spell->id) //hero has this spell in spellbook - || (spell->air && hasBonusOfType(Bonus::AIR_SPELLS)) // this is air spell and hero can cast all air spells - || (spell->fire && hasBonusOfType(Bonus::FIRE_SPELLS)) // this is fire spell and hero can cast all fire spells - || (spell->water && hasBonusOfType(Bonus::WATER_SPELLS)) // this is water spell and hero can cast all water spells - || (spell->earth && hasBonusOfType(Bonus::EARTH_SPELLS)) // this is earth spell and hero can cast all earth spells - || hasBonusOfType(Bonus::SPELL, spell->id) - || hasBonusOfType(Bonus::SPELLS_OF_LEVEL, spell->level) - ) - return true; + if (spell->isSpecialSpell()) + { + if (vstd::contains(spells, spell->id)) + {//hero has this spell in spellbook + logGlobal->errorStream() << "Special spell in spellbook "<name; + } - return false; + if (hasBonusOfType(Bonus::SPELL, spell->id)) + return true; + + return false; + } + else + { + if(vstd::contains(spells, spell->id) //hero has this spell in spellbook + || (spell->air && hasBonusOfType(Bonus::AIR_SPELLS)) // this is air spell and hero can cast all air spells + || (spell->fire && hasBonusOfType(Bonus::FIRE_SPELLS)) // this is fire spell and hero can cast all fire spells + || (spell->water && hasBonusOfType(Bonus::WATER_SPELLS)) // this is water spell and hero can cast all water spells + || (spell->earth && hasBonusOfType(Bonus::EARTH_SPELLS)) // this is earth spell and hero can cast all earth spells + || hasBonusOfType(Bonus::SPELL, spell->id) + || hasBonusOfType(Bonus::SPELLS_OF_LEVEL, spell->level) + ) + return true; + + return false; + } } /** diff --git a/lib/CSpellHandler.cpp b/lib/CSpellHandler.cpp index c9339954a..3710b42ea 100644 --- a/lib/CSpellHandler.cpp +++ b/lib/CSpellHandler.cpp @@ -701,7 +701,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json) logGlobal->errorStream() << "No positiveness specified, assumed NEUTRAL"; } - + spell->isSpecial = readFlag(flags,"special"); auto find_in_map = [&](std::string name, std::vector &vec) { diff --git a/lib/CSpellHandler.h b/lib/CSpellHandler.h index 059af4151..46b15ebca 100644 --- a/lib/CSpellHandler.h +++ b/lib/CSpellHandler.h @@ -76,6 +76,8 @@ public: inline bool isDamageSpell() const; inline bool isOffensiveSpell() const; + inline bool isSpecialSpell() const; + inline bool hasEffects() const; void getEffects(std::vector &lst, const int level) const; @@ -110,6 +112,8 @@ public: h & effects & immunities & limiters; h & iconImmune; h & absoluteImmunities & defaultProbability; + + h & isSpecial; } friend class CSpellHandler; @@ -127,6 +131,7 @@ private: bool isRising; bool isDamage; bool isOffensive; + bool isSpecial; std::string attributes; //reference only attributes //todo: remove or include in configuration format, currently unused @@ -189,6 +194,11 @@ bool CSpell::isOffensiveSpell() const return isOffensive; } +bool CSpell::isSpecialSpell() const +{ + return isSpecial; +} + bool CSpell::hasEffects() const { return effects.size() && effects[0].size();