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

SpellSchool: use identifier instead of int

Needs redifinition of MAGIC_SCHOOL_SKILL in all mods
This commit is contained in:
Konstantin P 2023-05-05 21:28:07 +03:00 committed by Konstantin
parent 8600e3035a
commit 057a33c508
24 changed files with 93 additions and 65 deletions

View File

@ -82,11 +82,11 @@ public:
return false;
for(ui8 schoolId = 0; schoolId < 4; schoolId++)
for(auto schoolId = 0; schoolId < GameConstants::DEFAULT_SCHOOLS; schoolId++)
{
if(A->school.at((ESpellSchool)schoolId) && !B->school.at((ESpellSchool)schoolId))
if(A->school.at(SpellSchool(schoolId)) && !B->school.at(SpellSchool(schoolId)))
return true;
if(!A->school.at((ESpellSchool)schoolId) && B->school.at((ESpellSchool)schoolId))
if(!A->school.at(SpellSchool(schoolId)) && B->school.at(SpellSchool(schoolId)))
return false;
}
@ -320,7 +320,7 @@ void CSpellWindow::computeSpellsPerArea()
for(const CSpell * spell : mySpells)
{
if(spell->isCombat() ^ !battleSpellsOnly
&& ((selectedTab == 4) || spell->school.at((ESpellSchool)selectedTab))
&& ((selectedTab == 4) || spell->school.at(SpellSchool(selectedTab)))
)
{
spellsCurSite.push_back(spell);

View File

@ -1185,7 +1185,7 @@
"bonuses" : [
{
"type" : "SPELL_DAMAGE",
"subtype" : 0,
"subtype" : "spellSchool.air",
"val" : 50,
"valueType" : "BASE_NUMBER"
}
@ -1198,7 +1198,7 @@
"bonuses" : [
{
"type" : "SPELL_DAMAGE",
"subtype" : 3,
"subtype" : "spellSchool.earth",
"val" : 50,
"valueType" : "BASE_NUMBER"
}
@ -1211,7 +1211,7 @@
"bonuses" : [
{
"type" : "SPELL_DAMAGE",
"subtype" : 1,
"subtype" : "spellSchool.fire",
"val" : 50,
"valueType" : "BASE_NUMBER"
}
@ -1224,7 +1224,7 @@
"bonuses" : [
{
"type" : "SPELL_DAMAGE",
"subtype" : 2,
"subtype" : "spellSchool.water",
"val" : 50,
"valueType" : "BASE_NUMBER"
}

View File

@ -13,7 +13,7 @@
"bonuses": [
{
"type" : "MAGIC_SCHOOL_SKILL",
"subtype" : 0,
"subtype" : "spellSchool.any",
"val" : 3,
"valueType" : "BASE_NUMBER"
}
@ -29,7 +29,7 @@
"bonuses": [
{
"type" : "MAGIC_SCHOOL_SKILL",
"subtype" : 2,
"subtype" : "spellSchool.fire",
"val" : 3,
"valueType" : "BASE_NUMBER"
}
@ -41,7 +41,7 @@
"bonuses": [
{
"type" : "MAGIC_SCHOOL_SKILL",
"subtype" : 8,
"subtype" : "spellSchool.earth",
"val" : 3,
"valueType" : "BASE_NUMBER"
}
@ -53,7 +53,7 @@
"bonuses": [
{
"type" : "MAGIC_SCHOOL_SKILL",
"subtype" : 1,
"subtype" : "spellSchool.air",
"val" : 3,
"valueType" : "BASE_NUMBER"
}
@ -65,7 +65,7 @@
"bonuses": [
{
"type" : "MAGIC_SCHOOL_SKILL",
"subtype" : 4,
"subtype" : "spellSchool.water",
"val" : 3,
"valueType" : "BASE_NUMBER"
}

View File

@ -10,7 +10,7 @@
"magicResistance" :
{
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : -1,
"subtype" : "spellSchool.any",
"val" : 85
},
"nonliving" :
@ -41,7 +41,7 @@
"magicResistance" :
{
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : -1,
"subtype" : "spellSchool.any",
"val" : 95
},
"nonliving" :

View File

@ -105,7 +105,7 @@
"magicResistance" :
{
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : -1,
"subtype" : "spellSchool.any",
"val" : 50
},
"nonliving" :
@ -137,7 +137,7 @@
"magicResistance" :
{
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : -1,
"subtype" : "spellSchool.any",
"val" : 75
},
"nonliving" :

View File

@ -215,6 +215,7 @@
"spellDamage" :
{
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"val" : 100,
"valueType" : "BASE_NUMBER"
},

View File

@ -186,6 +186,7 @@
"sorcery" : {
"targetSourceType" : "SECONDARY_SKILL",
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"updater" : "TIMES_HERO_LEVEL",
"val" : 5,
"valueType" : "PERCENT_TO_TARGET_TYPE"

View File

@ -262,6 +262,7 @@
"sorcery" : {
"targetSourceType" : "SECONDARY_SKILL",
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"updater" : "TIMES_HERO_LEVEL",
"val" : 5,
"valueType" : "PERCENT_TO_TARGET_TYPE"

View File

@ -261,6 +261,7 @@
"sorcery" : {
"targetSourceType" : "SECONDARY_SKILL",
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"updater" : "TIMES_HERO_LEVEL",
"val" : 5,
"valueType" : "PERCENT_TO_TARGET_TYPE"

View File

@ -192,6 +192,7 @@
"sorcery" : {
"targetSourceType" : "SECONDARY_SKILL",
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"updater" : "TIMES_HERO_LEVEL",
"val" : 5,
"valueType" : "PERCENT_TO_TARGET_TYPE"

View File

@ -135,6 +135,7 @@
"sorcery" : {
"targetSourceType" : "SECONDARY_SKILL",
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"updater" : "TIMES_HERO_LEVEL",
"val" : 5,
"valueType" : "PERCENT_TO_TARGET_TYPE"
@ -239,6 +240,7 @@
"sorcery" : {
"targetSourceType" : "SECONDARY_SKILL",
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"updater" : "TIMES_HERO_LEVEL",
"val" : 5,
"valueType" : "PERCENT_TO_TARGET_TYPE"

View File

@ -406,7 +406,7 @@
"base" : {
"effects" : {
"main" : {
"subtype" : 2,
"subtype" : "spellSchool.fire",
"type" : "MAGIC_SCHOOL_SKILL",
"valueType" : "BASE_NUMBER"
}
@ -434,7 +434,7 @@
"base" : {
"effects" : {
"main" : {
"subtype" : 1,
"subtype" : "spellSchool.air",
"type" : "MAGIC_SCHOOL_SKILL",
"valueType" : "BASE_NUMBER"
}
@ -462,7 +462,7 @@
"base" : {
"effects" : {
"main" : {
"subtype" : 4,
"subtype" : "spellSchool.water",
"type" : "MAGIC_SCHOOL_SKILL",
"valueType" : "BASE_NUMBER"
}
@ -490,7 +490,7 @@
"base" : {
"effects" : {
"main" : {
"subtype" : 8,
"subtype" : "spellSchool.earth",
"type" : "MAGIC_SCHOOL_SKILL",
"valueType" : "BASE_NUMBER"
}
@ -737,6 +737,7 @@
"effects" : {
"main" : {
"type" : "SPELL_DAMAGE",
"subtype" : "spellSchool.any",
"valueType" : "BASE_NUMBER"
}
}

View File

@ -104,7 +104,7 @@
"effects" : {
"spellDamageReduction" : {
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : 0,
"subtype" : "spellSchool.air",
"duration" : "N_TURNS",
"val" : 30
}
@ -147,7 +147,7 @@
"effects" : {
"spellDamageReduction" : {
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : 1,
"subtype" : "spellSchool.fire",
"duration" : "N_TURNS",
"val" : 30
}
@ -190,7 +190,7 @@
"effects" : {
"spellDamageReduction" : {
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : 2,
"subtype" : "spellSchool.water",
"duration" : "N_TURNS",
"val" : 30
}
@ -233,7 +233,7 @@
"effects" : {
"spellDamageReduction" : {
"type" : "SPELL_DAMAGE_REDUCTION",
"subtype" : 3,
"subtype" : "spellSchool.earth",
"duration" : "N_TURNS",
"val" : 30
}

View File

@ -1059,7 +1059,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
b.type = BonusType::FEAR; break;
case 'g':
b.type = BonusType::SPELL_DAMAGE_REDUCTION;
b.subtype = -1; //all magic schools
b.subtype = SpellSchool(ESpellSchool::ANY);
break;
case 'P':
b.type = BonusType::CASTS; break;
@ -1179,7 +1179,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
break;
case 'O':
b.type = BonusType::SPELL_DAMAGE_REDUCTION;
b.subtype = 1; //Fire school
b.subtype = SpellSchool(ESpellSchool::FIRE);
b.val = 100; //Full damage immunity
break;
case 'f':
@ -1192,7 +1192,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
break;
case 'W':
b.type = BonusType::SPELL_DAMAGE_REDUCTION;
b.subtype = 2; //Water school
b.subtype = SpellSchool(ESpellSchool::WATER);
b.val = 100; //Full damage immunity
break;
case 'w':
@ -1201,7 +1201,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
break;
case 'E':
b.type = BonusType::SPELL_DAMAGE_REDUCTION;
b.subtype = 3; //Earth school
b.subtype = SpellSchool(ESpellSchool::EARTH);
b.val = 100; //Full damage immunity
break;
case 'e':
@ -1210,7 +1210,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
break;
case 'A':
b.type = BonusType::SPELL_DAMAGE_REDUCTION;
b.subtype = 0; //Air school
b.subtype = SpellSchool(ESpellSchool::AIR);
b.val = 100; //Full damage immunity
break;
case 'a':
@ -1219,7 +1219,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
break;
case 'D':
b.type = BonusType::SPELL_DAMAGE_REDUCTION;
b.subtype = -1; //all
b.subtype = SpellSchool(ESpellSchool::ANY);
b.val = 100; //Full damage immunity
break;
case '0':

View File

@ -7,6 +7,7 @@
* Full text of license available in license.txt file, in main folder
*
*/
#include "GameConstants.h"
#include "StdInc.h"
#include "CModHandler.h"
#include "mapObjects/CObjectClassesHandler.h"
@ -745,6 +746,12 @@ void CModInfo::setEnabled(bool on)
CModHandler::CModHandler() : content(std::make_shared<CContentHandler>())
{
//TODO: moddable spell schools
for (auto i = 0; i < GameConstants::DEFAULT_SCHOOLS; ++i)
identifiers.registerObject(CModHandler::scopeBuiltin(), "spellSchool", SpellConfig::SCHOOL[i].jsonName, SpellConfig::SCHOOL[i].id);
identifiers.registerObject(CModHandler::scopeBuiltin(), "spellSchool", "any", SpellSchool(ESpellSchool::ANY));
for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i)
{
identifiers.registerObject(CModHandler::scopeBuiltin(), "resource", GameConstants::RESOURCE_NAMES[i], i);

View File

@ -50,6 +50,7 @@ namespace GameConstants
constexpr int CREATURES_PER_TOWN = 7; //without upgrades
constexpr int SPELL_LEVELS = 5;
constexpr int SPELL_SCHOOL_LEVELS = 4;
constexpr int DEFAULT_SCHOOLS = 4;
constexpr int CRE_LEVELS = 10; // number of creature experience levels
constexpr int HERO_GOLD_COST = 2500;
@ -1296,14 +1297,17 @@ class Obstacle : public BaseForID<Obstacle, si32>
DLL_LINKAGE static Obstacle fromString(const std::string & identifier);
};
enum class ESpellSchool: ui8
enum class ESpellSchool: int8_t
{
ANY = -1,
AIR = 0,
FIRE = 1,
WATER = 2,
EARTH = 3
EARTH = 3,
};
using SpellSchool = Identifier<ESpellSchool>;
enum class EMetaclass: ui8
{
INVALID = 0,

View File

@ -74,7 +74,10 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
valueType = BonusValueType::PERCENT_TO_BASE;
}
else if(deprecatedSubtype == SecondarySkill::SORCERY || deprecatedSubtypeStr == "skill.sorcery")
{
type = BonusType::SPELL_DAMAGE;
subtype = SpellSchool(ESpellSchool::ANY);
}
else if(deprecatedSubtype == SecondarySkill::SCHOLAR || deprecatedSubtypeStr == "skill.scholar")
type = BonusType::LEARN_MEETING_SPELL_LIMIT;
else if(deprecatedSubtype == SecondarySkill::ARCHERY|| deprecatedSubtypeStr == "skill.archery")
@ -112,22 +115,22 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
else if(deprecatedSubtype == SecondarySkill::AIR_MAGIC || deprecatedSubtypeStr == "skill.airMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = 4;
subtype = SpellSchool(ESpellSchool::AIR);
}
else if(deprecatedSubtype == SecondarySkill::WATER_MAGIC || deprecatedSubtypeStr == "skill.waterMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = 1;
subtype = SpellSchool(ESpellSchool::WATER);
}
else if(deprecatedSubtype == SecondarySkill::FIRE_MAGIC || deprecatedSubtypeStr == "skill.fireMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = 2;
subtype = SpellSchool(ESpellSchool::FIRE);
}
else if(deprecatedSubtype == SecondarySkill::EARTH_MAGIC || deprecatedSubtypeStr == "skill.earthMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = 8;
subtype = SpellSchool(ESpellSchool::EARTH);
}
else if (deprecatedSubtype == SecondarySkill::ARTILLERY || deprecatedSubtypeStr == "skill.artillery")
{
@ -215,47 +218,48 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
else if (deprecatedTypeStr == "DIRECT_DAMAGE_IMMUNITY")
{
type = BonusType::SPELL_DAMAGE_REDUCTION;
subtype = SpellSchool(ESpellSchool::ANY);
val = 100;
}
else if (deprecatedTypeStr == "AIR_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = 0;
subtype = SpellSchool(ESpellSchool::AIR);
}
else if (deprecatedTypeStr == "FIRE_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = 1;
subtype = SpellSchool(ESpellSchool::FIRE);
}
else if (deprecatedTypeStr == "WATER_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = 2;
subtype = SpellSchool(ESpellSchool::WATER);
}
else if (deprecatedTypeStr == "EARTH_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = 3;
subtype = SpellSchool(ESpellSchool::EARTH);
}
else if (deprecatedTypeStr == "AIR_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = 0;
subtype = SpellSchool(ESpellSchool::AIR);
}
else if (deprecatedTypeStr == "FIRE_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = 1;
subtype = SpellSchool(ESpellSchool::FIRE);
}
else if (deprecatedTypeStr == "WATER_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = 2;
subtype = SpellSchool(ESpellSchool::WATER);
}
else if (deprecatedTypeStr == "EARTH_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = 3;
subtype = SpellSchool(ESpellSchool::EARTH);
}
else
isConverted = false;

View File

@ -589,7 +589,7 @@ int32_t CGHeroInstance::getSpellSchoolLevel(const spells::Spell * spell, int32_t
spell->forEachSchool([&, this](const spells::SchoolInfo & cnf, bool & stop)
{
int32_t thisSchool = valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, 1 << (static_cast<ui8>(cnf.id))); //FIXME: Bonus shouldn't be additive (Witchking Artifacts : Crown of Skies)
int32_t thisSchool = valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, cnf.id); //FIXME: Bonus shouldn't be additive (Witchking Artifacts : Crown of Skies)
if(thisSchool > skill)
{
skill = thisSchool;
@ -598,7 +598,7 @@ int32_t CGHeroInstance::getSpellSchoolLevel(const spells::Spell * spell, int32_t
}
});
vstd::amax(skill, valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, 0)); //any school bonus
vstd::amax(skill, valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, SpellSchool(ESpellSchool::ANY))); //any school bonus
vstd::amax(skill, valOfBonuses(BonusType::SPELL, spell->getIndex())); //given by artifact or other effect
vstd::amax(skill, 0); //in case we don't know any school
@ -611,7 +611,7 @@ int64_t CGHeroInstance::getSpellBonus(const spells::Spell * spell, int64_t base,
//applying sorcery secondary skill
if(spell->isMagical())
base = static_cast<int64_t>(base * (valOfBonuses(BonusType::SPELL_DAMAGE)) / 100.0);
base = static_cast<int64_t>(base * (valOfBonuses(BonusType::SPELL_DAMAGE, SpellSchool(ESpellSchool::ANY))) / 100.0);
base = static_cast<int64_t>(base * (100 + valOfBonuses(BonusType::SPECIFIC_SPELL_DAMAGE, spell->getIndex())) / 100.0);
@ -619,7 +619,7 @@ int64_t CGHeroInstance::getSpellBonus(const spells::Spell * spell, int64_t base,
spell->forEachSchool([&maxSchoolBonus, this](const spells::SchoolInfo & cnf, bool & stop)
{
vstd::amax(maxSchoolBonus, valOfBonuses(BonusType::SPELL_DAMAGE, vstd::to_underlying(cnf.id)));
vstd::amax(maxSchoolBonus, valOfBonuses(BonusType::SPELL_DAMAGE, cnf.id));
});
base = static_cast<int64_t>(base * (100 + maxSchoolBonus) / 100.0);
@ -708,7 +708,7 @@ bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const
spell->forEachSchool([this, &schoolBonus](const spells::SchoolInfo & cnf, bool & stop)
{
if(hasBonusOfType(BonusType::SPELLS_OF_SCHOOL, vstd::to_underlying(cnf.id)))
if(hasBonusOfType(BonusType::SPELLS_OF_SCHOOL, cnf.id))
{
schoolBonus = stop = true;
}

View File

@ -343,7 +343,7 @@ void TreasurePlacer::addAllPossibleObjects()
std::vector <CSpell *> spells;
for(auto spell : VLC->spellh->objects)
{
if(map.isAllowedSpell(spell->id) && spell->school[static_cast<ESpellSchool>(i)])
if(map.isAllowedSpell(spell->id) && spell->school[SpellSchool(i)])
spells.push_back(spell);
}

View File

@ -35,7 +35,7 @@ int32_t AbilityCaster::getSpellSchoolLevel(const Spell * spell, int32_t * outSel
if(spell->getLevel() > 0)
{
vstd::amax(skill, unit->valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, 0));
vstd::amax(skill, unit->valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, SpellSchool(ESpellSchool::ANY)));
}
vstd::amax(skill, 0);

View File

@ -38,7 +38,7 @@ namespace SpellConfig
{
static const std::string LEVEL_NAMES[] = {"none", "basic", "advanced", "expert"};
static const spells::SchoolInfo SCHOOL[4] =
const spells::SchoolInfo SCHOOL[4] =
{
{
ESpellSchool::AIR,
@ -63,7 +63,7 @@ static const spells::SchoolInfo SCHOOL[4] =
};
//order as described in http://bugs.vcmi.eu/view.php?id=91
static const ESpellSchool SCHOOL_ORDER[4] =
static const SpellSchool SCHOOL_ORDER[4] =
{
ESpellSchool::AIR, //=0
ESpellSchool::FIRE, //=1
@ -150,9 +150,9 @@ spells::AimType CSpell::getTargetType() const
void CSpell::forEachSchool(const std::function<void(const spells::SchoolInfo &, bool &)>& cb) const
{
bool stop = false;
for(ESpellSchool iter : SpellConfig::SCHOOL_ORDER)
for(auto iter : SpellConfig::SCHOOL_ORDER)
{
const spells::SchoolInfo & cnf = SpellConfig::SCHOOL[static_cast<ui8>(iter)];
const spells::SchoolInfo & cnf = SpellConfig::SCHOOL[iter];
if(school.at(cnf.id))
{
cb(cnf, stop);
@ -381,15 +381,15 @@ int64_t CSpell::adjustRawDamage(const spells::Caster * caster, const battle::Uni
//applying protections - when spell has more then one elements, only one protection should be applied (I think)
forEachSchool([&](const spells::SchoolInfo & cnf, bool & stop)
{
if(bearer->hasBonusOfType(BonusType::SPELL_DAMAGE_REDUCTION, static_cast<ui8>(cnf.id)))
if(bearer->hasBonusOfType(BonusType::SPELL_DAMAGE_REDUCTION, cnf.id))
{
ret *= 100 - bearer->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, static_cast<ui8>(cnf.id));
ret *= 100 - bearer->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, cnf.id);
ret /= 100;
stop = true; //only bonus from one school is used
}
});
CSelector selector = Selector::type()(BonusType::SPELL_DAMAGE_REDUCTION).And(Selector::subtype()(-1));
CSelector selector = Selector::typeSubtype(BonusType::SPELL_DAMAGE_REDUCTION, SpellSchool(ESpellSchool::ANY));
//general spell dmg reduction, works only on magical effects
if(bearer->hasBonus(selector) && isMagical())

View File

@ -43,13 +43,18 @@ class IBattleCast;
struct SchoolInfo
{
ESpellSchool id; //backlink
SpellSchool id; //backlink
BonusType immunityBonus;
std::string jsonName;
};
}
namespace SpellConfig
{
extern const spells::SchoolInfo SCHOOL[4];
}
enum class VerticalPosition : ui8{TOP, CENTER, BOTTOM};
class DLL_LINKAGE CSpell : public spells::Spell
@ -185,7 +190,7 @@ public:
si32 level;
std::map<ESpellSchool, bool> school;
std::map<SpellSchool, bool> school;
si32 power; //spell's power

View File

@ -85,11 +85,11 @@ bool Damage::isReceptive(const Mechanics * m, const battle::Unit * unit) const
if(!UnitEffect::isReceptive(m, unit))
return false;
bool isImmune = m->getSpell()->isMagical() && (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, -1) >= 100); //General spell damage immunity
bool isImmune = m->getSpell()->isMagical() && (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, SpellSchool(ESpellSchool::ANY)) >= 100); //General spell damage immunity
//elemental immunity for damage
m->getSpell()->forEachSchool([&](const SchoolInfo & cnf, bool & stop)
{
isImmune |= (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, static_cast<ui8>(cnf.id)) >= 100); //100% reduction is immunity
isImmune |= (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, cnf.id) >= 100); //100% reduction is immunity
});
return !isImmune;

View File

@ -56,7 +56,7 @@ TEST_F(AbilityCasterTest, MagicAbilityAffectedByGenericBonus)
{
EXPECT_CALL(spellMock, getLevel()).WillRepeatedly(Return(1));
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, 0));
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, SpellSchool(ESpellSchool::ANY)));
EXPECT_CALL(actualCaster, getAllBonuses(_, _, _, _)).Times(AtLeast(1));
EXPECT_CALL(actualCaster, getTreeVersion()).Times(AtLeast(0));
@ -70,7 +70,7 @@ TEST_F(AbilityCasterTest, MagicAbilityIngoresSchoolBonus)
{
EXPECT_CALL(spellMock, getLevel()).WillRepeatedly(Return(1));
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, 1));
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, SpellSchool(ESpellSchool::AIR)));
EXPECT_CALL(actualCaster, getAllBonuses(_, _, _, _)).Times(AtLeast(1));
EXPECT_CALL(actualCaster, getTreeVersion()).Times(AtLeast(0));