1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-05 15:05:40 +02:00

Fix client & server compilation

This commit is contained in:
Ivan Savenko 2023-10-05 18:18:14 +03:00
parent 0a10fc30b8
commit 910ad50417
23 changed files with 112 additions and 108 deletions

View File

@ -242,13 +242,13 @@ uint64_t evaluateArtifactArmyValue(CArtifactInstance * art)
return 1500;
auto statsValue =
10 * art->valOfBonuses(BonusType::MOVEMENT, 1)
10 * art->valOfBonuses(BonusType::MOVEMENT, BonusSubtypes::heroMovementLand)
+ 1200 * art->valOfBonuses(BonusType::STACKS_SPEED)
+ 700 * art->valOfBonuses(BonusType::MORALE)
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::ATTACK))
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::DEFENSE))
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::KNOWLEDGE))
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, static_cast<int>(PrimarySkill::SPELL_POWER))
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::ATTACK))
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::DEFENSE))
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::KNOWLEDGE))
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::SPELL_POWER))
+ 500 * art->valOfBonuses(BonusType::LUCK);
auto classValue = 0;

View File

@ -984,7 +984,7 @@ std::vector<CGPathNode *> AINodeStorage::calculateTeleportations(
struct TowmPortalFinder
{
const std::vector<CGPathNode *> & initialNodes;
MasteryLevel townPortalSkillLevel;
MasteryLevel::Type townPortalSkillLevel;
uint64_t movementNeeded;
const ChainActor * actor;
const CGHeroInstance * hero;
@ -1006,7 +1006,7 @@ struct TowmPortalFinder
townPortal = spellID.toSpell();
// TODO: Copy/Paste from TownPortalMechanics
townPortalSkillLevel = MasteryLevel(hero->getSpellSchoolLevel(townPortal));
townPortalSkillLevel = MasteryLevel::Type(hero->getSpellSchoolLevel(townPortal));
movementNeeded = GameConstants::BASE_MOVEMENT_COST * (townPortalSkillLevel >= MasteryLevel::EXPERT ? 2 : 3);
}

View File

@ -118,14 +118,12 @@ Determines chance for affected heroes to learn spell casted by enemy hero after
Allows affected heroes to learn spell casted by enemy hero after battle
- subtype: must be set to -1
- val: maximal level of spell that can be learned
### LEARN_MEETING_SPELL_LIMIT
Allows affected heroes to learn spells from each other during hero exchange
- subtype: must be set to -1
- val: maximal level of spell that can be learned
### ROUGH_TERRAIN_DISCOUNT

View File

@ -60,6 +60,15 @@ static const TBonusSubtype visionsTowns; // 2
static const TBonusSubtype immunityBattleWide; // 0
static const TBonusSubtype immunityEnemyHero; // 1
static const TBonusSubtype transmutationPerHealth; // 0
static const TBonusSubtype transmutationPerUnit; // 1
static const TBonusSubtype destructionKillPercentage; // 0
static const TBonusSubtype destructionKillAmount; // 1
static const TBonusSubtype soulStealPermanent; // 0
static const TBonusSubtype soulStealBattle; // 1
TBonusSubtype spellLevel(int level);
TBonusSubtype creatureLevel(int level);

View File

@ -81,7 +81,7 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
else if(deprecatedSubtype == SecondarySkill::SORCERY || deprecatedSubtypeStr == "skill.sorcery")
{
type = BonusType::SPELL_DAMAGE;
subtype = TBonusSubtype(ESpellSchool::ANY);
subtype = TBonusSubtype(SpellSchool::ANY);
}
else if(deprecatedSubtype == SecondarySkill::SCHOLAR || deprecatedSubtypeStr == "skill.scholar")
type = BonusType::LEARN_MEETING_SPELL_LIMIT;
@ -120,22 +120,22 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
else if(deprecatedSubtype == SecondarySkill::AIR_MAGIC || deprecatedSubtypeStr == "skill.airMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = TBonusSubtype(ESpellSchool::AIR);
subtype = TBonusSubtype(SpellSchool::AIR);
}
else if(deprecatedSubtype == SecondarySkill::WATER_MAGIC || deprecatedSubtypeStr == "skill.waterMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = TBonusSubtype(ESpellSchool::WATER);
subtype = TBonusSubtype(SpellSchool::WATER);
}
else if(deprecatedSubtype == SecondarySkill::FIRE_MAGIC || deprecatedSubtypeStr == "skill.fireMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = TBonusSubtype(ESpellSchool::FIRE);
subtype = TBonusSubtype(SpellSchool::FIRE);
}
else if(deprecatedSubtype == SecondarySkill::EARTH_MAGIC || deprecatedSubtypeStr == "skill.earthMagic")
{
type = BonusType::MAGIC_SCHOOL_SKILL;
subtype = TBonusSubtype(ESpellSchool::EARTH);
subtype = TBonusSubtype(SpellSchool::EARTH);
}
else if (deprecatedSubtype == SecondarySkill::ARTILLERY || deprecatedSubtypeStr == "skill.artillery")
{

View File

@ -978,7 +978,6 @@ public:
// Deprecated
// TODO: remove
using ESpellSchool = SpellSchool;
using ETownType = FactionID;
using EGameResID = GameResID;
using River = RiverId;

View File

@ -28,7 +28,7 @@ CIdentifierStorage::CIdentifierStorage()
for (auto i = 0; i < GameConstants::DEFAULT_SCHOOLS; ++i)
registerObject(ModScope::scopeBuiltin(), "spellSchool", SpellConfig::SCHOOL[i].jsonName, SpellConfig::SCHOOL[i].id);
registerObject(ModScope::scopeBuiltin(), "spellSchool", "any", SpellSchool(ESpellSchool::ANY));
registerObject(ModScope::scopeBuiltin(), "spellSchool", "any", SpellSchool(SpellSchool::ANY));
for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i)
registerObject(ModScope::scopeBuiltin(), "resource", GameConstants::RESOURCE_NAMES[i], i);

View File

@ -42,19 +42,19 @@ static const std::string LEVEL_NAMES[] = {"none", "basic", "advanced", "expert"}
const spells::SchoolInfo SCHOOL[4] =
{
{
ESpellSchool::AIR,
SpellSchool::AIR,
"air"
},
{
ESpellSchool::FIRE,
SpellSchool::FIRE,
"fire"
},
{
ESpellSchool::WATER,
SpellSchool::WATER,
"water"
},
{
ESpellSchool::EARTH,
SpellSchool::EARTH,
"earth"
}
};
@ -62,10 +62,10 @@ const spells::SchoolInfo SCHOOL[4] =
//order as described in http://bugs.vcmi.eu/view.php?id=91
static const SpellSchool SCHOOL_ORDER[4] =
{
ESpellSchool::AIR, //=0
ESpellSchool::FIRE, //=1
ESpellSchool::EARTH,//=3(!)
ESpellSchool::WATER //=2(!)
SpellSchool::AIR, //=0
SpellSchool::FIRE, //=1
SpellSchool::EARTH,//=3(!)
SpellSchool::WATER //=2(!)
};
} //namespace SpellConfig

View File

@ -229,7 +229,6 @@ void CGameHandler::levelUpCommander (const CCommanderInstance * c, int skill)
return;
}
scp.accumulatedBonus.subtype = 0;
scp.accumulatedBonus.additionalInfo = 0;
scp.accumulatedBonus.duration = BonusDuration::PERMANENT;
scp.accumulatedBonus.turnsRemain = 0;
@ -249,11 +248,11 @@ void CGameHandler::levelUpCommander (const CCommanderInstance * c, int skill)
{
case ECommander::ATTACK:
scp.accumulatedBonus.type = BonusType::PRIMARY_SKILL;
scp.accumulatedBonus.subtype = static_cast<int>(PrimarySkill::ATTACK);
scp.accumulatedBonus.subtype = TBonusSubtype(PrimarySkill::ATTACK);
break;
case ECommander::DEFENSE:
scp.accumulatedBonus.type = BonusType::PRIMARY_SKILL;
scp.accumulatedBonus.subtype = static_cast<int>(PrimarySkill::DEFENSE);
scp.accumulatedBonus.subtype = TBonusSubtype(PrimarySkill::DEFENSE);
break;
case ECommander::HEALTH:
scp.accumulatedBonus.type = BonusType::STACK_HEALTH;
@ -261,7 +260,6 @@ void CGameHandler::levelUpCommander (const CCommanderInstance * c, int skill)
break;
case ECommander::DAMAGE:
scp.accumulatedBonus.type = BonusType::CREATURE_DAMAGE;
scp.accumulatedBonus.subtype = 0;
scp.accumulatedBonus.valType = BonusValueType::PERCENT_TO_BASE;
break;
case ECommander::SPEED:
@ -788,9 +786,9 @@ void CGameHandler::onNewTurn()
if (!firstTurn) //not first day
{
for (int k = 0; k < GameConstants::RESOURCE_QUANTITY; k++)
for (GameResID k = GameResID::WOOD; k < GameResID::COUNT; k++)
{
n.res[elem.first][k] += h->valOfBonuses(BonusType::GENERATE_RESOURCE, k);
n.res[elem.first][k] += h->valOfBonuses(BonusType::GENERATE_RESOURCE, TBonusSubtype(k));
}
}
}
@ -1539,8 +1537,8 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t
{
const CGHeroInstance * h1 = getHero(fromHero);
const CGHeroInstance * h2 = getHero(toHero);
int h1_scholarSpellLevel = h1->valOfBonuses(BonusType::LEARN_MEETING_SPELL_LIMIT, -1);
int h2_scholarSpellLevel = h2->valOfBonuses(BonusType::LEARN_MEETING_SPELL_LIMIT, -1);
int h1_scholarSpellLevel = h1->valOfBonuses(BonusType::LEARN_MEETING_SPELL_LIMIT);
int h2_scholarSpellLevel = h2->valOfBonuses(BonusType::LEARN_MEETING_SPELL_LIMIT);
if (h1_scholarSpellLevel < h2_scholarSpellLevel)
{

View File

@ -162,11 +162,11 @@ bool BattleActionProcessor::doDefendAction(const CBattleInfoCallback & battle, c
SetStackEffect sse;
sse.battleID = battle.getBattle()->getBattleID();
Bonus defenseBonusToAdd(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 20, -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::PERCENT_TO_ALL);
Bonus bonus2(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, stack->valOfBonuses(BonusType::DEFENSIVE_STANCE), -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
Bonus alternativeWeakCreatureBonus(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 1, -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
Bonus defenseBonusToAdd(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 20, -1, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::PERCENT_TO_ALL);
Bonus bonus2(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, stack->valOfBonuses(BonusType::DEFENSIVE_STANCE), -1, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
Bonus alternativeWeakCreatureBonus(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 1, -1, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
BonusList defence = *stack->getBonuses(Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int32_t>(PrimarySkill::DEFENSE)));
BonusList defence = *stack->getBonuses(Selector::typeSubtype(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::DEFENSE)));
int oldDefenceValue = defence.totalValue();
defence.push_back(std::make_shared<Bonus>(defenseBonusToAdd));
@ -263,7 +263,7 @@ bool BattleActionProcessor::doAttackAction(const CBattleInfoCallback & battle, c
const auto * attackingHero = battle.battleGetFightingHero(ba.side);
if(attackingHero)
{
totalAttacks += attackingHero->valOfBonuses(BonusType::HERO_GRANTS_ATTACKS, stack->creatureIndex());
totalAttacks += attackingHero->valOfBonuses(BonusType::HERO_GRANTS_ATTACKS, TBonusSubtype(stack->creatureId()));
}
const bool firstStrike = destinationStack->hasBonusOfType(BonusType::FIRST_STRIKE);
@ -355,7 +355,7 @@ bool BattleActionProcessor::doShootAction(const CBattleInfoCallback & battle, co
const auto * attackingHero = battle.battleGetFightingHero(ba.side);
if(attackingHero)
{
totalRangedAttacks += attackingHero->valOfBonuses(BonusType::HERO_GRANTS_ATTACKS, stack->creatureIndex());
totalRangedAttacks += attackingHero->valOfBonuses(BonusType::HERO_GRANTS_ATTACKS, TBonusSubtype(stack->creatureId()));
}
for(int i = 1; i < totalRangedAttacks; ++i)
@ -382,13 +382,13 @@ bool BattleActionProcessor::doCatapultAction(const CBattleInfoCallback & battle,
return false;
std::shared_ptr<const Bonus> catapultAbility = stack->getBonusLocalFirst(Selector::type()(BonusType::CATAPULT));
if(!catapultAbility || catapultAbility->subtype < 0)
if(!catapultAbility || catapultAbility->subtype == TBonusSubtype::NONE)
{
gameHandler->complain("We do not know how to shoot :P");
}
else
{
const CSpell * spell = SpellID(catapultAbility->subtype).toSpell();
const CSpell * spell = catapultAbility->subtype.as<SpellID>().toSpell();
spells::BattleCast parameters(&battle, stack, spells::Mode::SPELL_LIKE_ATTACK, spell); //We can shot infinitely by catapult
auto shotLevel = stack->valOfBonuses(Selector::typeSubtype(BonusType::CATAPULT_EXTRA_SHOTS, catapultAbility->subtype));
parameters.setSpellLevel(shotLevel);
@ -407,7 +407,7 @@ bool BattleActionProcessor::doUnitSpellAction(const CBattleInfoCallback & battle
return false;
std::shared_ptr<const Bonus> randSpellcaster = stack->getBonus(Selector::type()(BonusType::RANDOM_SPELLCASTER));
std::shared_ptr<const Bonus> spellcaster = stack->getBonus(Selector::typeSubtype(BonusType::SPELLCASTER, spellID));
std::shared_ptr<const Bonus> spellcaster = stack->getBonus(Selector::typeSubtype(BonusType::SPELLCASTER, TBonusSubtype(spellID)));
//TODO special bonus for genies ability
if (randSpellcaster && battle.battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_AIMED) == SpellID::NONE)
@ -452,13 +452,13 @@ bool BattleActionProcessor::doHealAction(const CBattleInfoCallback & battle, con
else
destStack = battle.battleGetUnitByPos(target.at(0).hexValue);
if(stack == nullptr || destStack == nullptr || !healerAbility || healerAbility->subtype < 0)
if(stack == nullptr || destStack == nullptr || !healerAbility || healerAbility->subtype == TBonusSubtype::NONE)
{
gameHandler->complain("There is either no healer, no destination, or healer cannot heal :P");
}
else
{
const CSpell * spell = SpellID(healerAbility->subtype).toSpell();
const CSpell * spell = healerAbility->subtype.as<SpellID>().toSpell();
spells::BattleCast parameters(&battle, stack, spells::Mode::SPELL_LIKE_ATTACK, spell); //We can heal infinitely by first aid tent
auto dest = battle::Destination(destStack, target.at(0).hexValue);
parameters.setSpellLevel(0);
@ -907,7 +907,7 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
const auto * owner = battle.battleGetFightingHero(attacker->unitSide());
if(owner)
{
int chance = owner->valOfBonuses(BonusType::BONUS_DAMAGE_CHANCE, attacker->creatureIndex());
int chance = owner->valOfBonuses(BonusType::BONUS_DAMAGE_CHANCE, TBonusSubtype(attacker->creatureId()));
if (chance > gameHandler->getRandomGenerator().nextInt(99))
bat.flags |= BattleAttack::BALLISTA_DOUBLE_DMG;
}
@ -931,7 +931,7 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
{
//this is need for displaying hit animation
bat.flags |= BattleAttack::SPELL_LIKE;
bat.spellID = SpellID(bonus->subtype);
bat.spellID = bonus->subtype.as<SpellID>();
//TODO: should spell override creature`s projectile?
@ -962,7 +962,7 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
{
//this is need for displaying affect animation
bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
bsa.spellID = SpellID(bonus->subtype);
bsa.spellID = bonus->subtype.as<SpellID>();
}
}
}
@ -1084,7 +1084,7 @@ void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bo
TConstBonusListPtr spells = attacker->getBonuses(Selector::type()(attackMode));
for(const auto & sf : *spells)
{
spellsToCast.insert(SpellID(sf->subtype));
spellsToCast.insert(sf->subtype.as<SpellID>());
}
for(SpellID spellID : spellsToCast)
{
@ -1095,7 +1095,7 @@ void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bo
return;
}
int32_t spellLevel = 0;
TConstBonusListPtr spellsByType = attacker->getBonuses(Selector::typeSubtype(attackMode, spellID));
TConstBonusListPtr spellsByType = attacker->getBonuses(Selector::typeSubtype(attackMode, TBonusSubtype(spellID)));
for(const auto & sf : *spellsByType)
{
int meleeRanged;
@ -1113,7 +1113,7 @@ void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bo
if (meleeRanged == 0 || (meleeRanged == 1 && ranged) || (meleeRanged == 2 && !ranged))
castMe = true;
}
int chance = attacker->valOfBonuses((Selector::typeSubtype(attackMode, spellID)));
int chance = attacker->valOfBonuses((Selector::typeSubtype(attackMode, TBonusSubtype(spellID))));
vstd::amin(chance, 100);
const CSpell * spell = SpellID(spellID).toSpell();
@ -1168,7 +1168,7 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
// each gorgon have 10% chance to kill (counted separately in H3) -> binomial distribution
//original formula x = min(x, (gorgons_count + 9)/10);
double chanceToKill = attacker->valOfBonuses(BonusType::DEATH_STARE, 0) / 100.0f;
double chanceToKill = attacker->valOfBonuses(BonusType::DEATH_STARE, BonusSubtypes::deathStareGorgon) / 100.0f;
vstd::amin(chanceToKill, 1); //cap at 100%
std::binomial_distribution<> distribution(attacker->getCount(), chanceToKill);
@ -1179,7 +1179,7 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
int maxToKill = static_cast<int>((attacker->getCount() + cap - 1) / cap); //not much more than chance * count
vstd::amin(staredCreatures, maxToKill);
staredCreatures += (attacker->level() * attacker->valOfBonuses(BonusType::DEATH_STARE, 1)) / defender->level();
staredCreatures += (attacker->level() * attacker->valOfBonuses(BonusType::DEATH_STARE, BonusSubtypes::deathStareCommander)) / defender->level();
if(staredCreatures)
{
//TODO: death stare was not originally available for multiple-hex attacks, but...
@ -1249,9 +1249,9 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
else
resurrectInfo.type = attacker->creatureId();
if(attacker->hasBonusOfType((BonusType::TRANSMUTATION), 0))
if(attacker->hasBonusOfType((BonusType::TRANSMUTATION), BonusSubtypes::transmutationPerHealth))
resurrectInfo.count = std::max((defender->getCount() * defender->getMaxHealth()) / resurrectInfo.type.toCreature()->getMaxHealth(), 1u);
else if (attacker->hasBonusOfType((BonusType::TRANSMUTATION), 1))
else if (attacker->hasBonusOfType((BonusType::TRANSMUTATION), BonusSubtypes::transmutationPerUnit))
resurrectInfo.count = defender->getCount();
else
return; //wrong subtype
@ -1273,21 +1273,21 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
gameHandler->sendAndApply(&fakeEvent);
}
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, 0) || attacker->hasBonusOfType(BonusType::DESTRUCTION, 1))
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillPercentage) || attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillAmount))
{
double chanceToTrigger = 0;
int amountToDie = 0;
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, 0)) //killing by percentage
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillPercentage)) //killing by percentage
{
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, 0) / 100.0f;
int percentageToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(0)))->additionalInfo[0];
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, BonusSubtypes::destructionKillPercentage) / 100.0f;
int percentageToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(BonusSubtypes::destructionKillPercentage)))->additionalInfo[0];
amountToDie = static_cast<int>(defender->getCount() * percentageToDie * 0.01f);
}
else if(attacker->hasBonusOfType(BonusType::DESTRUCTION, 1)) //killing by count
else if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillAmount)) //killing by count
{
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, 1) / 100.0f;
amountToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(1)))->additionalInfo[0];
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, BonusSubtypes::destructionKillAmount) / 100.0f;
amountToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(BonusSubtypes::destructionKillAmount)))->additionalInfo[0];
}
vstd::amin(chanceToTrigger, 1); //cap trigger chance at 100%
@ -1348,12 +1348,13 @@ int64_t BattleActionProcessor::applyBattleEffects(const CBattleInfoCallback & ba
{
//we can have two bonuses - one with subtype 0 and another with subtype 1
//try to use permanent first, use only one of two
for(si32 subtype = 1; subtype >= 0; subtype--)
for(const auto & subtype : { BonusSubtypes::soulStealBattle, BonusSubtypes::soulStealPermanent})
{
if(attackerState->hasBonusOfType(BonusType::SOUL_STEAL, subtype))
{
int64_t toHeal = bsa.killedAmount * attackerState->valOfBonuses(BonusType::SOUL_STEAL, subtype) * attackerState->getMaxHealth();
attackerState->heal(toHeal, EHealLevel::OVERHEAL, ((subtype == 0) ? EHealPower::ONE_BATTLE : EHealPower::PERMANENT));
bool permanent = subtype == BonusSubtypes::soulStealPermanent;
attackerState->heal(toHeal, EHealLevel::OVERHEAL, (permanent ? EHealPower::PERMANENT : EHealPower::ONE_BATTLE));
drainedLife += toHeal;
break;
}
@ -1365,9 +1366,9 @@ int64_t BattleActionProcessor::applyBattleEffects(const CBattleInfoCallback & ba
if(!bat.shot() &&
!def->isClone() &&
def->hasBonusOfType(BonusType::FIRE_SHIELD) &&
!attackerState->hasBonusOfType(BonusType::SPELL_SCHOOL_IMMUNITY, SpellSchool(ESpellSchool::FIRE)) &&
!attackerState->hasBonusOfType(BonusType::NEGATIVE_EFFECTS_IMMUNITY, SpellSchool(ESpellSchool::FIRE)) &&
attackerState->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, SpellSchool(ESpellSchool::FIRE)) < 100 &&
!attackerState->hasBonusOfType(BonusType::SPELL_SCHOOL_IMMUNITY, TBonusSubtype(SpellSchool::FIRE)) &&
!attackerState->hasBonusOfType(BonusType::NEGATIVE_EFFECTS_IMMUNITY, TBonusSubtype(SpellSchool::FIRE)) &&
attackerState->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, TBonusSubtype(SpellSchool::FIRE)) < 100 &&
CStack::isMeleeAttackPossible(attackerState.get(), def) // attacked needs to be adjacent to defender for fire shield to trigger (e.g. Dragon Breath attack)
)
{

View File

@ -144,7 +144,7 @@ void BattleFlowProcessor::trySummonGuardians(const CBattleInfoCallback & battle,
std::shared_ptr<const Bonus> summonInfo = stack->getBonus(Selector::type()(BonusType::SUMMON_GUARDIANS));
auto accessibility = battle.getAccesibility();
CreatureID creatureData = CreatureID(summonInfo->subtype);
CreatureID creatureData = summonInfo->subtype.as<CreatureID>();
std::vector<BattleHex> targetHexes;
const bool targetIsBig = stack->unitType()->isDoubleWide(); //target = creature to guard
const bool guardianIsBig = creatureData.toCreature()->isDoubleWide();
@ -198,7 +198,7 @@ void BattleFlowProcessor::castOpeningSpells(const CBattleInfoCallback & battle)
{
spells::BonusCaster caster(h, b);
const CSpell * spell = SpellID(b->subtype).toSpell();
const CSpell * spell = b->subtype.as<SpellID>().toSpell();
spells::BattleCast parameters(&battle, &caster, spells::Mode::PASSIVE, spell);
parameters.setSpellLevel(3);
@ -380,10 +380,10 @@ bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & bat
}
const CGHeroInstance * curOwner = battle.battleGetOwnerHero(next);
const int stackCreatureId = next->unitType()->getId();
const CreatureID stackCreatureId = next->unitType()->getId();
if ((stackCreatureId == CreatureID::ARROW_TOWERS || stackCreatureId == CreatureID::BALLISTA)
&& (!curOwner || gameHandler->getRandomGenerator().nextInt(99) >= curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, stackCreatureId)))
&& (!curOwner || gameHandler->getRandomGenerator().nextInt(99) >= curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, TBonusSubtype(stackCreatureId))))
{
BattleAction attack;
attack.actionType = EActionType::SHOOT;
@ -428,7 +428,7 @@ bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & bat
return true;
}
if (!curOwner || gameHandler->getRandomGenerator().nextInt(99) >= curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, CreatureID::CATAPULT))
if (!curOwner || gameHandler->getRandomGenerator().nextInt(99) >= curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, TBonusSubtype(CreatureID(CreatureID::CATAPULT))))
{
BattleAction attack;
attack.actionType = EActionType::CATAPULT;
@ -453,7 +453,7 @@ bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & bat
return true;
}
if (!curOwner || gameHandler->getRandomGenerator().nextInt(99) >= curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, CreatureID::FIRST_AID_TENT))
if (!curOwner || gameHandler->getRandomGenerator().nextInt(99) >= curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, TBonusSubtype(CreatureID(CreatureID::FIRST_AID_TENT))))
{
RandomGeneratorUtil::randomShuffle(possibleStacks, gameHandler->getRandomGenerator());
const CStack * toBeHealed = possibleStacks.front();
@ -583,7 +583,7 @@ void BattleFlowProcessor::stackEnchantedTrigger(const CBattleInfoCallback & batt
auto bl = *(st->getBonuses(Selector::type()(BonusType::ENCHANTED)));
for(auto b : bl)
{
const CSpell * sp = SpellID(b->subtype).toSpell();
const CSpell * sp = b->subtype.as<SpellID>().toSpell();
if(!sp)
continue;
@ -719,7 +719,7 @@ void BattleFlowProcessor::stackTurnTrigger(const CBattleInfoCallback & battle, c
while(!bl.empty() && !cast)
{
auto bonus = *RandomGeneratorUtil::nextItem(bl, gameHandler->getRandomGenerator());
auto spellID = SpellID(bonus->subtype);
auto spellID = bonus->subtype.as<SpellID>();
const CSpell * spell = SpellID(spellID).toSpell();
bl.remove_if([&bonus](const Bonus * b)
{

View File

@ -316,9 +316,9 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
if(!finishingBattle->isDraw() && finishingBattle->winnerHero)
{
if (int eagleEyeLevel = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_LEVEL_LIMIT, -1))
if (int eagleEyeLevel = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_LEVEL_LIMIT))
{
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_CHANCE, 0);
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(BonusType::LEARN_BATTLE_SPELL_CHANCE);
for(auto & spellId : battle.getBattle()->getUsedSpells(battle.otherSide(battleResult->winner)))
{
auto spell = spellId.toSpell(VLC->spells());

View File

@ -144,7 +144,7 @@ void PlayerMessageProcessor::cheatGiveSpells(PlayerColor player, const CGHeroIns
//start with level 0 to skip abilities
for (int level = 1; level <= GameConstants::SPELL_LEVELS; level++)
{
giveBonus.bonus.subtype = level;
giveBonus.bonus.subtype = BonusSubtypes::spellLevel(level);
gameHandler->sendAndApply(&giveBonus);
}

View File

@ -55,7 +55,7 @@ public:
void makeNormalCaster()
{
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELLCASTER, BonusSource::CREATURE_ABILITY, DEFAULT_SCHOOL_LEVEL, 0, DEFAULT_SPELL_INDEX));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELLCASTER, BonusSource::CREATURE_ABILITY, DEFAULT_SCHOOL_LEVEL, 0, TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
}
};
@ -171,7 +171,7 @@ TEST_F(UnitStateMagicTest, effectValue)
const int32_t EFFECT_VALUE = 456;
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPECIFIC_SPELL_POWER, BonusSource::CREATURE_ABILITY, EFFECT_VALUE, 0, DEFAULT_SPELL_INDEX));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPECIFIC_SPELL_POWER, BonusSource::CREATURE_ABILITY, EFFECT_VALUE, 0, TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
makeNormalCaster();
EXPECT_EQ(subject.getEffectValue(&spellMock), EFFECT_VALUE * DEFAULT_AMOUNT);

View File

@ -53,8 +53,8 @@ public:
{
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACKS_SPEED, BonusSource::CREATURE_ABILITY, DEFAULT_SPEED, 0));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_ATTACK, 0, static_cast<int>(PrimarySkill::ATTACK)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_DEFENCE, 0, static_cast<int>(PrimarySkill::DEFENSE)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_ATTACK, 0, TBonusSubtype(PrimarySkill::ATTACK)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_DEFENCE, 0, TBonusSubtype(PrimarySkill::DEFENSE)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, DEFAULT_HP, 0));
@ -248,10 +248,10 @@ TEST_F(UnitStateTest, getMinDamage)
setDefaultExpectations();
{
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, 0);
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, BonusSubtypes::creatureDamageBoth);
bonusMock.addNewBonus(bonus);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, 1);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, BonusSubtypes::creatureDamageMin);
bonusMock.addNewBonus(bonus);
}
@ -264,10 +264,10 @@ TEST_F(UnitStateTest, getMaxDamage)
setDefaultExpectations();
{
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, 0);
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, BonusSubtypes::creatureDamageBoth);
bonusMock.addNewBonus(bonus);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, 2);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, BonusSubtypes::creatureDamageMax);
bonusMock.addNewBonus(bonus);
}

View File

@ -107,7 +107,7 @@ TEST_F(CCreatureTest, JsonAddBonus)
{
JsonNode data(JsonNode::JsonType::DATA_STRUCT);
std::shared_ptr<Bonus> b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, 42, 43, BonusValueType::BASE_NUMBER);
std::shared_ptr<Bonus> b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, 42, TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
JsonNode & toAdd = data["bonuses"]["toAdd"];
@ -122,7 +122,7 @@ TEST_F(CCreatureTest, JsonAddBonus)
&& (bonus->source == BonusSource::CREATURE_ABILITY)
&& (bonus->val == 17)
&& (bonus->sid == 42)
&& (bonus->subtype == 43)
&& (bonus->subtype.as<CreatureID>().getNum() == 43)
&& (bonus->valType == BonusValueType::BASE_NUMBER);
};
@ -133,10 +133,10 @@ TEST_F(CCreatureTest, JsonRemoveBonus)
{
JsonNode data(JsonNode::JsonType::DATA_STRUCT);
std::shared_ptr<Bonus> b1 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, 42, 43, BonusValueType::BASE_NUMBER);
std::shared_ptr<Bonus> b1 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, 42, TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
subject->addNewBonus(b1);
std::shared_ptr<Bonus> b2 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 18, 42, 43, BonusValueType::BASE_NUMBER);
std::shared_ptr<Bonus> b2 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 18, 42, TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
subject->addNewBonus(b2);
@ -153,7 +153,7 @@ TEST_F(CCreatureTest, JsonRemoveBonus)
&& (bonus->source == BonusSource::CREATURE_ABILITY)
&& (bonus->val == 17)
&& (bonus->sid == 42)
&& (bonus->subtype == 43)
&& (bonus->subtype.as<CreatureID>().getNum() == 43)
&& (bonus->valType == BonusValueType::BASE_NUMBER);
};
@ -166,7 +166,6 @@ TEST_F(CCreatureTest, JsonRemoveBonus)
&& (bonus->source == BonusSource::CREATURE_ABILITY)
&& (bonus->val == 18)
&& (bonus->sid == 42)
&& (bonus->subtype == 43)
&& (bonus->valType == BonusValueType::BASE_NUMBER);
};

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, SpellSchool(ESpellSchool::ANY)));
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, TBonusSubtype(SpellSchool::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, SpellSchool(ESpellSchool::AIR)));
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, TBonusSubtype(SpellSchool::AIR)));
EXPECT_CALL(actualCaster, getAllBonuses(_, _, _, _)).Times(AtLeast(1));
EXPECT_CALL(actualCaster, getTreeVersion()).Times(AtLeast(0));

View File

@ -71,9 +71,9 @@ protected:
TEST_P(TimedApplyTest, ChangesBonuses)
{
Bonus testBonus1(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, 0, static_cast<int>(PrimarySkill::KNOWLEDGE));
Bonus testBonus1(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, 0, TBonusSubtype(PrimarySkill::KNOWLEDGE));
Bonus testBonus2(BonusDuration::N_TURNS, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, 0, static_cast<int>(PrimarySkill::KNOWLEDGE));
Bonus testBonus2(BonusDuration::N_TURNS, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, 0, TBonusSubtype(PrimarySkill::KNOWLEDGE));
testBonus2.turnsRemain = 4;
JsonNode options(JsonNode::JsonType::DATA_STRUCT);

View File

@ -43,7 +43,7 @@ public:
TEST_P(AbsoluteSpellConditionTest, ChecksAbsoluteCase)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, immuneSpell);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
bonus->additionalInfo = 1;
unitBonuses.addNewBonus(bonus);
@ -57,7 +57,7 @@ TEST_P(AbsoluteSpellConditionTest, ChecksAbsoluteCase)
TEST_P(AbsoluteSpellConditionTest, IgnoresNormalCase)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, immuneSpell);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
unitBonuses.addNewBonus(bonus);
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
}

View File

@ -49,7 +49,7 @@ TEST_F(BonusConditionTest, ReceptiveIfMatchesType)
TEST_F(BonusConditionTest, ImmuneIfTypeMismatch)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::OTHER, 0, SpellSchool(ESpellSchool::FIRE)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::OTHER, 0, SpellSchool(SpellSchool::FIRE)));
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
}

View File

@ -30,8 +30,8 @@ public:
EXPECT_CALL(spellMock, forEachSchool(NotNull())).Times(AtLeast(1)).WillRepeatedly([](const spells::Spell::SchoolCallback & cb)
{
bool stop = false;
cb(SpellSchool(ESpellSchool::AIR), stop);
cb(SpellSchool(ESpellSchool::FIRE), stop);
cb(SpellSchool(SpellSchool::AIR), stop);
cb(SpellSchool(SpellSchool::FIRE), stop);
});
EXPECT_CALL(mechanicsMock, isPositiveSpell()).WillRepeatedly(Return(isPositive));
@ -56,7 +56,7 @@ TEST_P(ElementalConditionTest, ReceptiveIfNoBonus)
TEST_P(ElementalConditionTest, ImmuneIfBonusMatches)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, SpellSchool(ESpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::AIR)));
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
}
@ -64,7 +64,7 @@ TEST_P(ElementalConditionTest, ImmuneIfBonusMatches)
TEST_P(ElementalConditionTest, NotImmuneIfBonusMismatches)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, SpellSchool(ESpellSchool::WATER)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::WATER)));
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
}
@ -72,7 +72,7 @@ TEST_P(ElementalConditionTest, NotImmuneIfBonusMismatches)
TEST_P(ElementalConditionTest, DependsOnPositivness)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, SpellSchool(ESpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::AIR)));
EXPECT_EQ(isPositive, subject->isReceptive(&mechanicsMock, &unitMock));
}
@ -80,8 +80,8 @@ TEST_P(ElementalConditionTest, DependsOnPositivness)
TEST_P(ElementalConditionTest, ImmuneIfBothBonusesPresent)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, SpellSchool(ESpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, SpellSchool(ESpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::AIR)));
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
}

View File

@ -57,7 +57,7 @@ TEST_P(ImmunityNegationConditionTest, WithHeroNegation)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, 0, 1));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, 0, BonusSubtypes::immunityEnemyHero));
EXPECT_EQ(isMagicalEffect, subject->isReceptive(&mechanicsMock, &unitMock));
}
@ -66,7 +66,7 @@ TEST_P(ImmunityNegationConditionTest, WithBattleWideNegation)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, 0, 0));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, 0, BonusSubtypes::immunityBattleWide));
//This should return if ownerMatches, because anyone should cast onto owner's stacks, but not on enemyStacks
EXPECT_EQ(ownerMatches && isMagicalEffect, subject->isReceptive(&mechanicsMock, &unitMock));

View File

@ -43,7 +43,7 @@ public:
TEST_P(NormalSpellConditionTest, ChecksAbsoluteCase)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, immuneSpell);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
bonus->additionalInfo = 1;
unitBonuses.addNewBonus(bonus);
@ -57,7 +57,7 @@ TEST_P(NormalSpellConditionTest, ChecksAbsoluteCase)
TEST_P(NormalSpellConditionTest, ChecksNormalCase)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, immuneSpell);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
unitBonuses.addNewBonus(bonus);
if(immuneSpell == castSpell)
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));