1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-20 20:23:03 +02:00

MetaIdentifier now uses std::variant internally

This commit is contained in:
Ivan Savenko 2023-10-14 18:13:59 +03:00
parent b394158dc9
commit 80e6485965
61 changed files with 487 additions and 421 deletions

View File

@ -11,7 +11,6 @@
#include <limits>
#include "Nullkiller.h"
#include "../../../lib/bonuses/BonusSubtypes.h"
#include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h"
@ -243,7 +242,7 @@ uint64_t evaluateArtifactArmyValue(CArtifactInstance * art)
return 1500;
auto statsValue =
10 * art->valOfBonuses(BonusType::MOVEMENT, BonusSubtypes::heroMovementLand)
10 * art->valOfBonuses(BonusType::MOVEMENT, BonusSubtypeID::heroMovementLand)
+ 1200 * art->valOfBonuses(BonusType::STACKS_SPEED)
+ 700 * art->valOfBonuses(BonusType::MORALE)
+ 700 * art->valOfBonuses(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::ATTACK))

View File

@ -34,7 +34,6 @@
#include "../../lib/spells/ISpellMechanics.h"
#include "../../lib/battle/BattleAction.h"
#include "../../lib/battle/BattleHex.h"
#include "../../lib/bonuses/BonusSubtypes.h"
#include "../../lib/CStack.h"
#include "../../lib/CondSh.h"
#include "../../lib/TextOperations.h"
@ -535,7 +534,7 @@ void BattleStacksController::stackMoved(const CStack *stack, std::vector<BattleH
addNewAnim(new MovementStartAnimation(owner, stack));
});
if (!stack->hasBonus(Selector::typeSubtype(BonusType::FLYING, BonusSubtypes::movementFlying)))
if (!stack->hasBonus(Selector::typeSubtype(BonusType::FLYING, BonusSubtypeID::movementFlying)))
{
owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [&]()
{

View File

@ -31,7 +31,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/bonuses/BonusList.cpp
${MAIN_LIB_DIR}/bonuses/BonusParams.cpp
${MAIN_LIB_DIR}/bonuses/BonusSelector.cpp
${MAIN_LIB_DIR}/bonuses/BonusSubtypes.cpp
${MAIN_LIB_DIR}/bonuses/BonusSubtypeID.cpp
${MAIN_LIB_DIR}/bonuses/CBonusProxy.cpp
${MAIN_LIB_DIR}/bonuses/CBonusSystemNode.cpp
${MAIN_LIB_DIR}/bonuses/IBonusBearer.cpp
@ -43,7 +43,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/campaign/CampaignState.cpp
${MAIN_LIB_DIR}/constants/EntityIdentifiers.cpp
${MAIN_LIB_DIR}/constants/MetaIdentifier.cpp
${MAIN_LIB_DIR}/events/ApplyDamage.cpp
${MAIN_LIB_DIR}/events/GameResumed.cpp
@ -359,7 +358,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/bonuses/BonusList.h
${MAIN_LIB_DIR}/bonuses/BonusParams.h
${MAIN_LIB_DIR}/bonuses/BonusSelector.h
${MAIN_LIB_DIR}/bonuses/BonusSubtypes.h
${MAIN_LIB_DIR}/bonuses/BonusSubtypeID.h
${MAIN_LIB_DIR}/bonuses/CBonusProxy.h
${MAIN_LIB_DIR}/bonuses/CBonusSystemNode.h
${MAIN_LIB_DIR}/bonuses/IBonusBearer.h

View File

@ -17,7 +17,6 @@
#include "bonuses/BonusList.h"
#include "bonuses/Bonus.h"
#include "bonuses/IBonusBearer.h"
#include "bonuses/BonusSubtypes.h"
#include <vcmi/Creature.h>
#include <vcmi/Faction.h>
@ -72,14 +71,14 @@ int AFactionMember::getDefense(bool ranged) const
int AFactionMember::getMinDamage(bool ranged) const
{
const std::string cachingStr = "type_CREATURE_DAMAGEs_0Otype_CREATURE_DAMAGEs_1";
static const auto selector = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMin));
static const auto selector = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMin));
return getBonusBearer()->valOfBonuses(selector, cachingStr);
}
int AFactionMember::getMaxDamage(bool ranged) const
{
const std::string cachingStr = "type_CREATURE_DAMAGEs_0Otype_CREATURE_DAMAGEs_2";
static const auto selector = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMax));
static const auto selector = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMax));
return getBonusBearer()->valOfBonuses(selector, cachingStr);
}

View File

@ -20,7 +20,6 @@
#include "CCreatureHandler.h"
#include "CGeneralTextHandler.h"
#include "spells/CSpellHandler.h"
#include "bonuses/BonusSubtypes.h"
template class std::vector<VCMI_LIB_WRAP_NAMESPACE(CBonusType)>;
@ -169,10 +168,10 @@ ImagePath CBonusTypeHandler::bonusToGraphics(const std::shared_ptr<Bonus> & bonu
}
case BonusType::GENERAL_DAMAGE_REDUCTION:
{
if (bonus->subtype == BonusSubtypes::damageTypeMelee)
if (bonus->subtype == BonusSubtypeID::damageTypeMelee)
fileName = "DamageReductionMelee.bmp";
if (bonus->subtype == BonusSubtypes::damageTypeRanged)
if (bonus->subtype == BonusSubtypeID::damageTypeRanged)
fileName = "DamageReductionRanged.bmp";
break;

View File

@ -19,7 +19,6 @@
#include "constants/StringConstants.h"
#include "bonuses/Limiters.h"
#include "bonuses/Updaters.h"
#include "bonuses/BonusSubtypes.h"
#include "serializer/JsonDeserializer.h"
#include "serializer/JsonUpdater.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
@ -126,13 +125,13 @@ int32_t CCreature::getBaseDefense() const
int32_t CCreature::getBaseDamageMin() const
{
static const auto SELECTOR = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMin).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
static const auto SELECTOR = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMin).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
return getExportedBonusList().valOfBonuses(SELECTOR);
}
int32_t CCreature::getBaseDamageMax() const
{
static const auto SELECTOR = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMax).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
static const auto SELECTOR = Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMax).And(Selector::sourceTypeSel(BonusSource::CREATURE_ABILITY));
return getExportedBonusList().valOfBonuses(SELECTOR);
}
@ -294,7 +293,7 @@ CCreature::CCreature()
void CCreature::addBonus(int val, BonusType type)
{
addBonus(val, type, TBonusSubtype::NONE);
addBonus(val, type, TBonusSubtype());
}
void CCreature::addBonus(int val, BonusType type, TBonusSubtype subtype)
@ -357,10 +356,10 @@ void CCreature::updateFrom(const JsonNode & data)
addBonus(configNode["defense"].Integer(), BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::DEFENSE));
if(!configNode["damage"]["min"].isNull())
addBonus(configNode["damage"]["min"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMin);
addBonus(configNode["damage"]["min"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMin);
if(!configNode["damage"]["max"].isNull())
addBonus(configNode["damage"]["max"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMax);
addBonus(configNode["damage"]["max"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMax);
if(!configNode["shots"].isNull())
addBonus(configNode["shots"].Integer(), BonusType::SHOTS);
@ -613,8 +612,8 @@ CCreature * CCreatureHandler::loadFromJson(const std::string & scope, const Json
cre->addBonus(node["attack"].Integer(), BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::ATTACK));
cre->addBonus(node["defense"].Integer(), BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::DEFENSE));
cre->addBonus(node["damage"]["min"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMin);
cre->addBonus(node["damage"]["max"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMax);
cre->addBonus(node["damage"]["min"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMin);
cre->addBonus(node["damage"]["max"].Integer(), BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMax);
assert(node["damage"]["min"].Integer() <= node["damage"]["max"].Integer());
@ -1039,11 +1038,11 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
break;
case 'M': //Max damage
b.type = BonusType::CREATURE_DAMAGE;
b.subtype = BonusSubtypes::creatureDamageMax;
b.subtype = BonusSubtypeID::creatureDamageMax;
break;
case 'm': //Min damage
b.type = BonusType::CREATURE_DAMAGE;
b.subtype = BonusSubtypes::creatureDamageMin;
b.subtype = BonusSubtypeID::creatureDamageMin;
break;
case 'S':
b.type = BonusType::STACKS_SPEED; break;
@ -1060,7 +1059,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
break;
case 'E':
b.type = BonusType::DEATH_STARE;
b.subtype = BonusSubtypes::deathStareGorgon;
b.subtype = BonusSubtypeID::deathStareGorgon;
break;
case 'F':
b.type = BonusType::FEAR; break;
@ -1107,7 +1106,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
b.type = BonusType::MIND_IMMUNITY; break;
case 'r':
b.type = BonusType::REBIRTH; //on/off? makes sense?
b.subtype = BonusSubtypes::rebirthRegular;
b.subtype = BonusSubtypeID::rebirthRegular;
b.val = 20; //arbitrary value
break;
case 'R':

View File

@ -17,7 +17,6 @@
#include "CGeneralTextHandler.h"
#include "StartInfo.h" // for StartInfo
#include "battle/BattleInfo.h" // for BattleInfo
#include "bonuses/BonusSubtypes.h"
#include "NetPacks.h" // for InfoWindow
#include "GameSettings.h"
#include "TerrainHandler.h"
@ -269,7 +268,7 @@ bool CGameInfoCallback::getTownInfo(const CGObjectInstance * town, InfoAboutTown
{
const auto * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject);
if(nullptr != selectedHero)
detailed = selectedHero->hasVisions(town, BonusSubtypes::visionsTowns);
detailed = selectedHero->hasVisions(town, BonusSubtypeID::visionsTowns);
}
dest.initFromTown(dynamic_cast<const CGTownInstance *>(town), detailed);
@ -323,7 +322,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
{
const auto * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject);
if(nullptr != selectedHero)
if(selectedHero->hasVisions(hero, BonusSubtypes::visionsHeroes))
if(selectedHero->hasVisions(hero, BonusSubtypeID::visionsHeroes))
infoLevel = InfoAboutHero::EInfoLevel::DETAILED;
}

View File

@ -17,7 +17,6 @@
#include "CGeneralTextHandler.h"
#include "battle/BattleInfo.h"
#include "bonuses/BonusSubtypes.h"
#include "spells/CSpellHandler.h"
#include "NetPacks.h"
@ -221,7 +220,7 @@ void CStack::prepareAttacked(BattleStackAttacked & bsa, vstd::RNG & rand, const
resurrectedCount += 1;
}
if(customState->hasBonusOfType(BonusType::REBIRTH, BonusSubtypes::rebirthSpecial))
if(customState->hasBonusOfType(BonusType::REBIRTH, BonusSubtypeID::rebirthSpecial))
{
// resurrect at least one Sacred Phoenix
vstd::amax(resurrectedCount, 1);

View File

@ -23,7 +23,6 @@
#include "filesystem/Filesystem.h"
#include "bonuses/Bonus.h"
#include "bonuses/Propagators.h"
#include "bonuses/BonusSubtypes.h"
#include "ResourceSet.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
@ -561,7 +560,7 @@ void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building) const
b = createBonus(building, BonusType::PRIMARY_SKILL, +2, TBonusSubtype(PrimarySkill::DEFENSE));
break;
case BuildingSubID::LIGHTHOUSE:
b = createBonus(building, BonusType::MOVEMENT, +500, BonusSubtypes::heroMovementSea, playerPropagator);
b = createBonus(building, BonusType::MOVEMENT, +500, BonusSubtypeID::heroMovementSea, playerPropagator);
break;
}
@ -571,7 +570,7 @@ void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building) const
std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType type, int val) const
{
return createBonus(build, type, val, TBonusSubtype::NONE, emptyPropagator());
return createBonus(build, type, val, TBonusSubtype(), emptyPropagator());
}
std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType type, int val, TBonusSubtype subtype) const
@ -583,17 +582,18 @@ std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, BonusType ty
{
std::ostringstream descr;
descr << build->getNameTranslated();
return createBonusImpl(build->bid, type, val, prop, descr.str(), subtype);
return createBonusImpl(build->bid, build->town->faction->getId(), type, val, prop, descr.str(), subtype);
}
std::shared_ptr<Bonus> CTownHandler::createBonusImpl(const BuildingID & building,
const FactionID & faction,
BonusType type,
int val,
TPropagatorPtr & prop,
const std::string & description,
TBonusSubtype subtype) const
{
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, type, BonusSource::TOWN_STRUCTURE, val, TBonusSourceID(building), subtype, description);
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, type, BonusSource::TOWN_STRUCTURE, val, BuildingTypeUniqueID(faction, building), subtype, description);
if(prop)
b->addPropagator(prop);
@ -605,7 +605,7 @@ void CTownHandler::loadSpecialBuildingBonuses(const JsonNode & source, BonusList
{
for(const auto & b : source.Vector())
{
auto bonus = JsonUtils::parseBuildingBonus(b, building->bid, building->getNameTranslated());
auto bonus = JsonUtils::parseBuildingBonus(b, building->town->faction->getId(), building->bid, building->getNameTranslated());
if(bonus == nullptr)
continue;

View File

@ -395,6 +395,7 @@ class DLL_LINKAGE CTownHandler : public CHandlerBase<FactionID, Faction, CFactio
std::shared_ptr<Bonus> createBonus(CBuilding * build, BonusType type, int val, TBonusSubtype subtype) const;
std::shared_ptr<Bonus> createBonus(CBuilding * build, BonusType type, int val, TBonusSubtype subtype, TPropagatorPtr & prop) const;
std::shared_ptr<Bonus> createBonusImpl(const BuildingID & building,
const FactionID & faction,
BonusType type,
int val,
TPropagatorPtr & prop,

View File

@ -421,21 +421,21 @@ static void loadBonusSubtype(TBonusSubtype & subtype, BonusType type, const Json
{
if (node.isNull())
{
subtype = TBonusSubtype::NONE;
subtype = TBonusSubtype();
return;
}
if (!node.isString())
{
logMod->warn("Bonus subtype must be string!");
subtype = TBonusSubtype::NONE;
subtype = TBonusSubtype();
return;
}
VLC->identifiers()->requestIdentifier(node, [&subtype, node](int32_t identifier)
{
assert(0); //TODO
subtype = TBonusSubtype("type", node.String(), identifier);
subtype = BonusSubtypeID(identifier);
});
}
@ -735,13 +735,13 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
return b;
}
std::shared_ptr<Bonus> JsonUtils::parseBuildingBonus(const JsonNode & ability, const BuildingID & building, const std::string & description)
std::shared_ptr<Bonus> JsonUtils::parseBuildingBonus(const JsonNode & ability, const FactionID & faction, const BuildingID & building, const std::string & description)
{
/* duration = BonusDuration::PERMANENT
source = BonusSource::TOWN_STRUCTURE
bonusType, val, subtype - get from json
*/
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::NONE, BonusSource::TOWN_STRUCTURE, 0, TBonusSourceID(building), description);
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::NONE, BonusSource::TOWN_STRUCTURE, 0, BuildingTypeUniqueID(faction, building), description);
if(!parseBonus(ability, b.get()))
return nullptr;

View File

@ -129,7 +129,7 @@ namespace JsonUtils
{
DLL_LINKAGE std::shared_ptr<Bonus> parseBonus(const JsonVector & ability_vec);
DLL_LINKAGE std::shared_ptr<Bonus> parseBonus(const JsonNode & ability);
DLL_LINKAGE std::shared_ptr<Bonus> parseBuildingBonus(const JsonNode & ability, const BuildingID & building, const std::string & description);
DLL_LINKAGE std::shared_ptr<Bonus> parseBuildingBonus(const JsonNode & ability, const FactionID & faction, const BuildingID & building, const std::string & description);
DLL_LINKAGE bool parseBonus(const JsonNode & ability, Bonus * placement);
DLL_LINKAGE std::shared_ptr<ILimiter> parseLimiter(const JsonNode & limiter);
DLL_LINKAGE CSelector parseSelector(const JsonNode &ability);

View File

@ -2201,7 +2201,7 @@ void BattleTriggerEffect::applyGs(CGameState * gs) const
}
case BonusType::POISON:
{
auto b = st->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, TBonusSubtype(SpellID(SpellID::POISON)))
auto b = st->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, SpellID(SpellID::POISON))
.And(Selector::type()(BonusType::STACK_HEALTH)));
if (b)
b->val = val;

View File

@ -442,9 +442,9 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const
//native terrain bonuses
static auto nativeTerrain = std::make_shared<CreatureTerrainLimiter>();
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACKS_SPEED, BonusSource::TERRAIN_NATIVE, 1, TBonusSourceID::NONE)->addLimiter(nativeTerrain));
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::ATTACK))->addLimiter(nativeTerrain));
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::DEFENSE))->addLimiter(nativeTerrain));
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACKS_SPEED, BonusSource::TERRAIN_NATIVE, 1, TBonusSourceID())->addLimiter(nativeTerrain));
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, TBonusSourceID(), TBonusSubtype(PrimarySkill::ATTACK))->addLimiter(nativeTerrain));
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, TBonusSourceID(), TBonusSubtype(PrimarySkill::DEFENSE))->addLimiter(nativeTerrain));
//////////////////////////////////////////////////////////////////////////
//tactics

View File

@ -16,8 +16,6 @@
#include "../NetPacks.h"
#include "../CCreatureHandler.h"
#include "../bonuses/BonusSubtypes.h"
#include "../serializer/JsonDeserializer.h"
#include "../serializer/JsonSerializer.h"
@ -342,8 +340,8 @@ CUnitState::CUnitState():
health(this),
shots(this),
totalAttacks(this, Selector::type()(BonusType::ADDITIONAL_ATTACK), 1),
minDamage(this, Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMin)), 0),
maxDamage(this, Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypes::creatureDamageMax)), 0),
minDamage(this, Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMin)), 0),
maxDamage(this, Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageBoth).Or(Selector::typeSubtype(BonusType::CREATURE_DAMAGE, BonusSubtypeID::creatureDamageMax)), 0),
attack(this, Selector::typeSubtype(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::ATTACK)), 0),
defence(this, Selector::typeSubtype(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::DEFENSE)), 0),
inFrenzy(this, Selector::type()(BonusType::IN_FRENZY)),

View File

@ -14,7 +14,6 @@
#include "Unit.h"
#include "../bonuses/Bonus.h"
#include "../bonuses/BonusSubtypes.h"
#include "../mapObjects/CGTownInstance.h"
#include "../spells/CSpellHandler.h"
#include "../GameSettings.h"
@ -207,11 +206,11 @@ double DamageCalculator::getAttackOffenseArcheryFactor() const
if(info.shooting)
{
const std::string cachingStrArchery = "type_PERCENTAGE_DAMAGE_BOOSTs_1";
static const auto selectorArchery = Selector::typeSubtype(BonusType::PERCENTAGE_DAMAGE_BOOST, BonusSubtypes::damageTypeRanged);
static const auto selectorArchery = Selector::typeSubtype(BonusType::PERCENTAGE_DAMAGE_BOOST, BonusSubtypeID::damageTypeRanged);
return info.attacker->valOfBonuses(selectorArchery, cachingStrArchery) / 100.0;
}
const std::string cachingStrOffence = "type_PERCENTAGE_DAMAGE_BOOSTs_0";
static const auto selectorOffence = Selector::typeSubtype(BonusType::PERCENTAGE_DAMAGE_BOOST, BonusSubtypes::damageTypeMelee);
static const auto selectorOffence = Selector::typeSubtype(BonusType::PERCENTAGE_DAMAGE_BOOST, BonusSubtypeID::damageTypeMelee);
return info.attacker->valOfBonuses(selectorOffence, cachingStrOffence) / 100.0;
}
@ -283,7 +282,7 @@ double DamageCalculator::getDefenseSkillFactor() const
double DamageCalculator::getDefenseArmorerFactor() const
{
const std::string cachingStrArmorer = "type_GENERAL_DAMAGE_REDUCTIONs_N1_NsrcSPELL_EFFECT";
static const auto selectorArmorer = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypes::damageTypeAll).And(Selector::sourceTypeSel(BonusSource::SPELL_EFFECT).Not());
static const auto selectorArmorer = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypeID::damageTypeAll).And(Selector::sourceTypeSel(BonusSource::SPELL_EFFECT).Not());
return info.defender->valOfBonuses(selectorArmorer, cachingStrArmorer) / 100.0;
}
@ -291,10 +290,10 @@ double DamageCalculator::getDefenseArmorerFactor() const
double DamageCalculator::getDefenseMagicShieldFactor() const
{
const std::string cachingStrMeleeReduction = "type_GENERAL_DAMAGE_REDUCTIONs_0";
static const auto selectorMeleeReduction = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypes::damageTypeMelee);
static const auto selectorMeleeReduction = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypeID::damageTypeMelee);
const std::string cachingStrRangedReduction = "type_GENERAL_DAMAGE_REDUCTIONs_1";
static const auto selectorRangedReduction = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypes::damageTypeRanged);
static const auto selectorRangedReduction = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypeID::damageTypeRanged);
//handling spell effects - shield and air shield
if(info.shooting)
@ -388,7 +387,7 @@ double DamageCalculator::getDefensePetrificationFactor() const
{
// Creatures that are petrified by a Basilisk's Petrifying attack or a Medusa's Stone gaze take 50% damage (R8 = 0.50) from ranged and melee attacks. Taking damage also deactivates the effect.
const std::string cachingStrAllReduction = "type_GENERAL_DAMAGE_REDUCTIONs_N1_srcSPELL_EFFECT";
static const auto selectorAllReduction = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypes::damageTypeAll).And(Selector::sourceTypeSel(BonusSource::SPELL_EFFECT));
static const auto selectorAllReduction = Selector::typeSubtype(BonusType::GENERAL_DAMAGE_REDUCTION, BonusSubtypeID::damageTypeAll).And(Selector::sourceTypeSel(BonusSource::SPELL_EFFECT));
return info.defender->valOfBonuses(selectorAllReduction, cachingStrAllReduction) / 100.0;
}

View File

@ -150,7 +150,7 @@ JsonNode Bonus::toJsonNode() const
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
// only add values that might reasonably be found in config files
root["type"].String() = vstd::findKey(bonusNameMap, type);
if(subtype != TBonusSubtype::NONE)
if(subtype != TBonusSubtype())
root["subtype"].String() = subtype.toString();
if(additionalInfo != CAddInfo::NONE)
root["addInfo"] = additionalInfoToJson(type, additionalInfo);
@ -158,7 +158,7 @@ JsonNode Bonus::toJsonNode() const
root["sourceType"].String() = vstd::findKey(bonusSourceMap, source);
if(targetSourceType != BonusSource::OTHER)
root["targetSourceType"].String() = vstd::findKey(bonusSourceMap, targetSourceType);
if(sid != TBonusSourceID::NONE)
if(sid != TBonusSourceID())
root["sourceID"].String() = sid.toString();
if(val != 0)
root["val"].Integer() = val;
@ -184,11 +184,11 @@ JsonNode Bonus::toJsonNode() const
}
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID ID)
: Bonus(Duration, Type, Src, Val, ID, TBonusSubtype::NONE, std::string())
: Bonus(Duration, Type, Src, Val, ID, TBonusSubtype(), std::string())
{}
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID ID, std::string Desc)
: Bonus(Duration, Type, Src, Val, ID, TBonusSubtype::NONE, Desc)
: Bonus(Duration, Type, Src, Val, ID, TBonusSubtype(), Desc)
{}
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID ID, TBonusSubtype Subtype)

View File

@ -10,7 +10,9 @@
#pragma once
#include "BonusEnum.h"
#include "BonusSubtypeID.h"
#include "../constants/MetaIdentifier.h"
#include "../constants/EntityIdentifiers.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -23,8 +25,8 @@ class IUpdater;
class BonusList;
class CSelector;
using TBonusSubtype = MetaIdentifier;
using TBonusSourceID = MetaIdentifier;
using TBonusSubtype = MetaIdentifier<BonusSubtypeID, SpellID, CreatureID, PrimarySkill, TerrainId, GameResID, SpellSchool>;
using TBonusSourceID = MetaIdentifier<BonusSourceID, SpellID, CreatureID, ArtifactID, CampaignScenarioID, SecondarySkill, HeroTypeID, Obj, ObjectInstanceID, BuildingTypeUniqueID, BattleField>;
using TBonusListPtr = std::shared_ptr<BonusList>;
using TConstBonusListPtr = std::shared_ptr<const BonusList>;
using TLimiterPtr = std::shared_ptr<ILimiter>;

View File

@ -275,4 +275,4 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const BonusList &bonusL
return out;
}
VCMI_LIB_NAMESPACE_END
VCMI_LIB_NAMESPACE_END

View File

@ -111,4 +111,4 @@ public:
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const BonusList &bonusList);
VCMI_LIB_NAMESPACE_END
VCMI_LIB_NAMESPACE_END

View File

@ -13,9 +13,11 @@
#include "BonusEnum.h"
#include "BonusParams.h"
#include "BonusSelector.h"
#include "BonusSubtypes.h"
#include "../ResourceSet.h"
#include "../VCMI_Lib.h"
#include "../modding/IdentifierStorage.h"
#include "../modding/ModScope.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -88,28 +90,28 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
type = BonusType::LEARN_MEETING_SPELL_LIMIT;
else if(deprecatedSubtype == SecondarySkill::ARCHERY|| deprecatedSubtypeStr == "skill.archery")
{
subtype = BonusSubtypes::damageTypeRanged;
subtype = BonusSubtypeID::damageTypeRanged;
type = BonusType::PERCENTAGE_DAMAGE_BOOST;
}
else if(deprecatedSubtype == SecondarySkill::OFFENCE || deprecatedSubtypeStr == "skill.offence")
{
subtype = BonusSubtypes::damageTypeMelee;
subtype = BonusSubtypeID::damageTypeMelee;
type = BonusType::PERCENTAGE_DAMAGE_BOOST;
}
else if(deprecatedSubtype == SecondarySkill::ARMORER || deprecatedSubtypeStr == "skill.armorer")
{
subtype = BonusSubtypes::damageTypeAll;
subtype = BonusSubtypeID::damageTypeAll;
type = BonusType::GENERAL_DAMAGE_REDUCTION;
}
else if(deprecatedSubtype == SecondarySkill::NAVIGATION || deprecatedSubtypeStr == "skill.navigation")
{
subtype = BonusSubtypes::heroMovementSea;
subtype = BonusSubtypeID::heroMovementSea;
valueType = BonusValueType::PERCENT_TO_BASE;
type = BonusType::MOVEMENT;
}
else if(deprecatedSubtype == SecondarySkill::LOGISTICS || deprecatedSubtypeStr == "skill.logistics")
{
subtype = BonusSubtypes::heroMovementLand;
subtype = BonusSubtypeID::heroMovementLand;
valueType = BonusValueType::PERCENT_TO_BASE;
type = BonusType::MOVEMENT;
}
@ -146,12 +148,12 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
else if (deprecatedSubtype == SecondarySkill::FIRST_AID || deprecatedSubtypeStr == "skill.firstAid")
{
type = BonusType::SPECIFIC_SPELL_POWER;
subtype = TBonusSubtype("spell", "firstAid");
subtype = SpellID(*VLC->identifiers()->getIdentifier( ModScope::scopeGame(), "spell", "firstAid"));
}
else if (deprecatedSubtype == SecondarySkill::BALLISTICS || deprecatedSubtypeStr == "skill.ballistics")
{
type = BonusType::CATAPULT_EXTRA_SHOTS;
subtype = TBonusSubtype("spell", "catapultShot");
subtype = SpellID(*VLC->identifiers()->getIdentifier( ModScope::scopeGame(), "spell", "catapultShot"));
}
else
isConverted = false;
@ -170,20 +172,20 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
}
else if (deprecatedTypeStr == "SEA_MOVEMENT")
{
subtype = BonusSubtypes::heroMovementSea;
subtype = BonusSubtypeID::heroMovementSea;
valueType = BonusValueType::ADDITIVE_VALUE;
type = BonusType::MOVEMENT;
}
else if (deprecatedTypeStr == "LAND_MOVEMENT")
{
subtype = BonusSubtypes::heroMovementLand;
subtype = BonusSubtypeID::heroMovementLand;
valueType = BonusValueType::ADDITIVE_VALUE;
type = BonusType::MOVEMENT;
}
else if (deprecatedTypeStr == "MAXED_SPELL")
{
type = BonusType::SPELL;
subtype = TBonusSubtype("spell", deprecatedSubtypeStr);
subtype = SpellID(*VLC->identifiers()->getIdentifier( ModScope::scopeGame(), "spell", deprecatedSubtypeStr));
valueType = BonusValueType::INDEPENDENT_MAX;
val = 3;
}
@ -224,52 +226,52 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
else if (deprecatedTypeStr == "DIRECT_DAMAGE_IMMUNITY")
{
type = BonusType::SPELL_DAMAGE_REDUCTION;
subtype = MetaIdentifier(SpellSchool::ANY);
subtype = TBonusSubtype(SpellSchool::ANY);
val = 100;
}
else if (deprecatedTypeStr == "AIR_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = MetaIdentifier(SpellSchool::AIR);
subtype = TBonusSubtype(SpellSchool::AIR);
}
else if (deprecatedTypeStr == "FIRE_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = MetaIdentifier(SpellSchool::FIRE);
subtype = TBonusSubtype(SpellSchool::FIRE);
}
else if (deprecatedTypeStr == "WATER_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = MetaIdentifier(SpellSchool::WATER);
subtype = TBonusSubtype(SpellSchool::WATER);
}
else if (deprecatedTypeStr == "EARTH_SPELL_DMG_PREMY")
{
type = BonusType::SPELL_DAMAGE;
subtype = MetaIdentifier(SpellSchool::EARTH);
subtype = TBonusSubtype(SpellSchool::EARTH);
}
else if (deprecatedTypeStr == "AIR_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = MetaIdentifier(SpellSchool::AIR);
subtype = TBonusSubtype(SpellSchool::AIR);
}
else if (deprecatedTypeStr == "FIRE_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = MetaIdentifier(SpellSchool::FIRE);
subtype = TBonusSubtype(SpellSchool::FIRE);
}
else if (deprecatedTypeStr == "WATER_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = MetaIdentifier(SpellSchool::WATER);
subtype = TBonusSubtype(SpellSchool::WATER);
}
else if (deprecatedTypeStr == "EARTH_SPELLS")
{
type = BonusType::SPELLS_OF_SCHOOL;
subtype = MetaIdentifier(SpellSchool::EARTH);
subtype = TBonusSubtype(SpellSchool::EARTH);
}
else if (deprecatedTypeStr == "AIR_IMMUNITY")
{
subtype = MetaIdentifier(SpellSchool::AIR);
subtype = TBonusSubtype(SpellSchool::AIR);
switch(deprecatedSubtype)
{
case 0:
@ -285,7 +287,7 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
}
else if (deprecatedTypeStr == "FIRE_IMMUNITY")
{
subtype = MetaIdentifier(SpellSchool::FIRE);
subtype = TBonusSubtype(SpellSchool::FIRE);
switch(deprecatedSubtype)
{
case 0:
@ -301,7 +303,7 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
}
else if (deprecatedTypeStr == "WATER_IMMUNITY")
{
subtype = MetaIdentifier(SpellSchool::WATER);
subtype = TBonusSubtype(SpellSchool::WATER);
switch(deprecatedSubtype)
{
case 0:
@ -317,7 +319,7 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu
}
else if (deprecatedTypeStr == "EARTH_IMMUNITY")
{
subtype = MetaIdentifier(SpellSchool::EARTH);
subtype = TBonusSubtype(SpellSchool::EARTH);
switch(deprecatedSubtype)
{
case 0:

View File

@ -0,0 +1,76 @@
/*
* Bonus.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "BonusSubtypeID.h"
VCMI_LIB_NAMESPACE_BEGIN
const BonusSubtypeID BonusSubtypeID::creatureDamageBoth(0);
const BonusSubtypeID BonusSubtypeID::creatureDamageMin(1);
const BonusSubtypeID BonusSubtypeID::creatureDamageMax(2);
const BonusSubtypeID BonusSubtypeID::damageTypeAll(-1);
const BonusSubtypeID BonusSubtypeID::damageTypeMelee(0);
const BonusSubtypeID BonusSubtypeID::damageTypeRanged(1);
const BonusSubtypeID BonusSubtypeID::heroMovementLand(1);
const BonusSubtypeID BonusSubtypeID::heroMovementSea(0);
const BonusSubtypeID BonusSubtypeID::heroMovementPenalty(2);
const BonusSubtypeID BonusSubtypeID::heroMovementFull(1);
const BonusSubtypeID BonusSubtypeID::deathStareGorgon(0);
const BonusSubtypeID BonusSubtypeID::deathStareCommander(1);
const BonusSubtypeID BonusSubtypeID::rebirthRegular(0);
const BonusSubtypeID BonusSubtypeID::rebirthSpecial(1);
const BonusSubtypeID BonusSubtypeID::visionsMonsters(0);
const BonusSubtypeID BonusSubtypeID::visionsHeroes(1);
const BonusSubtypeID BonusSubtypeID::visionsTowns(2);
const BonusSubtypeID BonusSubtypeID::immunityBattleWide(0);
const BonusSubtypeID BonusSubtypeID::immunityEnemyHero(1);
const BonusSubtypeID BonusSubtypeID::transmutationPerHealth(0);
const BonusSubtypeID BonusSubtypeID::transmutationPerUnit(1);
const BonusSubtypeID BonusSubtypeID::destructionKillPercentage(0);
const BonusSubtypeID BonusSubtypeID::destructionKillAmount(1);
const BonusSubtypeID BonusSubtypeID::soulStealPermanent(0);
const BonusSubtypeID BonusSubtypeID::soulStealBattle(1);
const BonusSubtypeID BonusSubtypeID::movementFlying(0);
const BonusSubtypeID BonusSubtypeID::movementTeleporting(1);
const BonusSourceID BonusSourceID::undeadMoraleDebuff(-2);
BonusSubtypeID BonusSubtypeID::spellLevel(int level)
{
return BonusSubtypeID(level);
}
BonusSubtypeID BonusSubtypeID::creatureLevel(int level)
{
return BonusSubtypeID(level);
}
si32 BonusSubtypeID::decode(const std::string & identifier)
{
return std::stoi(identifier);
}
std::string BonusSubtypeID::encode(const si32 index)
{
return std::to_string(index);
}
si32 BonusSourceID::decode(const std::string & identifier)
{
return std::stoi(identifier);
}
std::string BonusSourceID::encode(const si32 index)
{
return std::to_string(index);
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,78 @@
/*
* BonusSubtypeID.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../constants/EntityIdentifiers.h"
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE BonusSourceID : public Identifier<BonusSourceID>
{
public:
using Identifier<BonusSourceID>::Identifier;
static std::string encode(int32_t index);
static si32 decode(const std::string & identifier);
static const BonusSourceID undeadMoraleDebuff; // -2
};
class DLL_LINKAGE BonusSubtypeID : public Identifier<BonusSubtypeID>
{
public:
using Identifier<BonusSubtypeID>::Identifier;
static std::string encode(int32_t index);
static si32 decode(const std::string & identifier);
static const BonusSubtypeID creatureDamageBoth; // 0
static const BonusSubtypeID creatureDamageMin; // 1
static const BonusSubtypeID creatureDamageMax; // 2
static const BonusSubtypeID damageTypeAll; // -1
static const BonusSubtypeID damageTypeMelee; // 0
static const BonusSubtypeID damageTypeRanged; // 1
static const BonusSubtypeID heroMovementLand; // 1
static const BonusSubtypeID heroMovementSea; // 0
static const BonusSubtypeID heroMovementPenalty; // 2
static const BonusSubtypeID heroMovementFull; // 1
static const BonusSubtypeID deathStareGorgon; // 0
static const BonusSubtypeID deathStareCommander;
static const BonusSubtypeID rebirthRegular; // 0
static const BonusSubtypeID rebirthSpecial; // 1
static const BonusSubtypeID visionsMonsters; // 0
static const BonusSubtypeID visionsHeroes; // 1
static const BonusSubtypeID visionsTowns; // 2
static const BonusSubtypeID immunityBattleWide; // 0
static const BonusSubtypeID immunityEnemyHero; // 1
static const BonusSubtypeID transmutationPerHealth; // 0
static const BonusSubtypeID transmutationPerUnit; // 1
static const BonusSubtypeID destructionKillPercentage; // 0
static const BonusSubtypeID destructionKillAmount; // 1
static const BonusSubtypeID soulStealPermanent; // 0
static const BonusSubtypeID soulStealBattle; // 1
static const BonusSubtypeID movementFlying; // 0
static const BonusSubtypeID movementTeleporting; // 1
static BonusSubtypeID spellLevel(int level);
static BonusSubtypeID creatureLevel(int level);
};
VCMI_LIB_NAMESPACE_END

View File

@ -1,56 +0,0 @@
/*
* Bonus.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "BonusSubtypes.h"
VCMI_LIB_NAMESPACE_BEGIN
const TBonusSubtype BonusSubtypes::creatureDamageBoth("", "", 0);
const TBonusSubtype BonusSubtypes::creatureDamageMin("", "", 1);
const TBonusSubtype BonusSubtypes::creatureDamageMax("", "", 2);
const TBonusSubtype BonusSubtypes::damageTypeAll("", "", -1);
const TBonusSubtype BonusSubtypes::damageTypeMelee("", "", 0);
const TBonusSubtype BonusSubtypes::damageTypeRanged("", "", 1);
const TBonusSubtype BonusSubtypes::heroMovementLand("", "", 1);
const TBonusSubtype BonusSubtypes::heroMovementSea("", "", 0);
const TBonusSubtype BonusSubtypes::heroMovementPenalty("", "", 2);
const TBonusSubtype BonusSubtypes::heroMovementFull("", "", 1);
const TBonusSubtype BonusSubtypes::deathStareGorgon("", "", 0);
const TBonusSubtype BonusSubtypes::deathStareCommander("", "", 1);
const TBonusSubtype BonusSubtypes::rebirthRegular("", "", 0);
const TBonusSubtype BonusSubtypes::rebirthSpecial("", "", 1);
const TBonusSubtype BonusSubtypes::visionsMonsters("", "", 0);
const TBonusSubtype BonusSubtypes::visionsHeroes("", "", 1);
const TBonusSubtype BonusSubtypes::visionsTowns("", "", 2);
const TBonusSubtype BonusSubtypes::immunityBattleWide("", "", 0);
const TBonusSubtype BonusSubtypes::immunityEnemyHero("", "", 1);
const TBonusSubtype BonusSubtypes::transmutationPerHealth("", "", 0);
const TBonusSubtype BonusSubtypes::transmutationPerUnit("", "", 1);
const TBonusSubtype BonusSubtypes::destructionKillPercentage("", "", 0);
const TBonusSubtype BonusSubtypes::destructionKillAmount("", "", 1);
const TBonusSubtype BonusSubtypes::soulStealPermanent("", "", 0);
const TBonusSubtype BonusSubtypes::soulStealBattle("", "", 1);
const TBonusSubtype BonusSubtypes::movementFlying("", "", 0);
const TBonusSubtype BonusSubtypes::movementTeleporting("", "", 1);
TBonusSubtype BonusSubtypes::spellLevel(int level)
{
assert(0); //todo
return TBonusSubtype();
}
TBonusSubtype BonusSubtypes::creatureLevel(int level)
{
assert(0); //todo
return TBonusSubtype();
}
VCMI_LIB_NAMESPACE_END

View File

@ -1,64 +0,0 @@
/*
* BonusSubtypes.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../constants/MetaIdentifier.h"
VCMI_LIB_NAMESPACE_BEGIN
using TBonusSubtype = MetaIdentifier;
class DLL_LINKAGE BonusSubtypes
{
public:
static const TBonusSubtype creatureDamageBoth; // 0
static const TBonusSubtype creatureDamageMin; // 1
static const TBonusSubtype creatureDamageMax; // 2
static const TBonusSubtype damageTypeAll; // -1
static const TBonusSubtype damageTypeMelee; // 0
static const TBonusSubtype damageTypeRanged; // 1
static const TBonusSubtype heroMovementLand; // 1
static const TBonusSubtype heroMovementSea; // 0
static const TBonusSubtype heroMovementPenalty; // 2
static const TBonusSubtype heroMovementFull; // 1
static const TBonusSubtype deathStareGorgon; // 0
static const TBonusSubtype deathStareCommander;
static const TBonusSubtype rebirthRegular; // 0
static const TBonusSubtype rebirthSpecial; // 1
static const TBonusSubtype visionsMonsters; // 0
static const TBonusSubtype visionsHeroes; // 1
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
static const TBonusSubtype movementFlying; // 0
static const TBonusSubtype movementTeleporting; // 1
static TBonusSubtype spellLevel(int level);
static TBonusSubtype creatureLevel(int level);
};
VCMI_LIB_NAMESPACE_END

View File

@ -37,6 +37,8 @@
#include "TerrainHandler.h" //TODO: remove
#include "BattleFieldHandler.h"
#include "ObstacleHandler.h"
#include "CTownHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -134,6 +136,40 @@ std::string HeroClassID::entityType()
return "heroClass";
}
si32 ObjectInstanceID::decode(const std::string & identifier)
{
return std::stoi(identifier);
}
std::string ObjectInstanceID::encode(const si32 index)
{
return std::to_string(index);
}
si32 CampaignScenarioID::decode(const std::string & identifier)
{
return std::stoi(identifier);
}
std::string CampaignScenarioID::encode(const si32 index)
{
return std::to_string(index);
}
std::string Obj::encode(int32_t index)
{
return VLC->objtypeh->getObjectHandlerName(index);
}
si32 Obj::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "objects", identifier);
if(rawId)
return rawId.value();
else
return -1;
}
si32 HeroTypeID::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeMap(), "hero", identifier);
@ -182,6 +218,20 @@ std::string ArtifactID::entityType()
return "artifact";
}
si32 SecondarySkill::decode(const std::string& identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "secondarySkill", identifier);
if(rawId)
return rawId.value();
else
return -1;
}
std::string SecondarySkill::encode(const si32 index)
{
return VLC->skills()->getById(SecondarySkill(index))->getJsonKey();
}
const CCreature * CreatureIDBase::toCreature() const
{
return VLC->creh->objects.at(num);
@ -240,6 +290,20 @@ std::string SpellID::encode(const si32 index)
return VLC->spells()->getByIndex(index)->getJsonKey();
}
si32 BattleField::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "spell", identifier);
if(rawId)
return rawId.value();
else
return -1;
}
std::string BattleField::encode(const si32 index)
{
return VLC->spells()->getByIndex(index)->getJsonKey();
}
std::string SpellID::entityType()
{
return "spell";
@ -257,8 +321,6 @@ bool PlayerColor::isSpectator() const
std::string PlayerColor::toString() const
{
if (num == -1)
return "neutral";
return encode(num);
}
@ -269,6 +331,9 @@ si32 PlayerColor::decode(const std::string & identifier)
std::string PlayerColor::encode(const si32 index)
{
if (index == -1)
return "neutral";
if (index < 0 || index >= std::size(GameConstants::PLAYER_COLOR_NAMES))
{
assert(0);
@ -373,6 +438,18 @@ std::string GameResID::encode(const si32 index)
return GameConstants::RESOURCE_NAMES[index];
}
si32 BuildingTypeUniqueID::decode(const std::string & identifier)
{
assert(0); //TODO
return -1;
}
std::string BuildingTypeUniqueID::encode(const si32 index)
{
assert(0); // TODO
return "";
}
std::string GameResID::entityType()
{
return "resource";

View File

@ -552,10 +552,13 @@ public:
};
};
class Obj : public IdentifierWithEnum<Obj, ObjBase>
class DLL_LINKAGE Obj : public IdentifierWithEnum<Obj, ObjBase>
{
public:
using IdentifierWithEnum<Obj, ObjBase>::IdentifierWithEnum;
static std::string encode(int32_t index);
static si32 decode(const std::string & identifier);
};
class DLL_LINKAGE RoadId : public Identifier<RoadId>
@ -830,6 +833,9 @@ public:
static const BattleField NONE;
const BattleFieldInfo * getInfo() const;
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
};
class DLL_LINKAGE BoatId : public Identifier<BoatId>
@ -935,6 +941,9 @@ class BuildingTypeUniqueID : public Identifier<BuildingTypeUniqueID>
public:
BuildingTypeUniqueID(FactionID faction, BuildingID building );
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
BuildingID getBuilding() const;
FactionID getFaction() const;
@ -946,6 +955,9 @@ class DLL_LINKAGE CampaignScenarioID : public Identifier<CampaignScenarioID>
public:
using Identifier<CampaignScenarioID>::Identifier;
static si32 decode(const std::string & identifier);
static std::string encode(int32_t index);
static const CampaignScenarioID NONE;
};

View File

@ -1,67 +0,0 @@
/*
* EntityIdentifiers.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "MetaIdentifier.h"
VCMI_LIB_NAMESPACE_BEGIN
const MetaIdentifier MetaIdentifier::NONE("", "", -1);
MetaIdentifier::MetaIdentifier():
integerForm(-1)
{}
MetaIdentifier::MetaIdentifier(const std::string & entityType, const std::string & identifier)
: stringForm(identifier)
, integerForm(-1)
{
onDeserialized();
}
MetaIdentifier::MetaIdentifier(const std::string & entityType, const std::string & identifier, int32_t value)
: stringForm(identifier)
, integerForm(value)
{
}
bool MetaIdentifier::operator == (const MetaIdentifier & other) const
{
assert( (stringForm == other.stringForm) ? (integerForm == other.integerForm) : true );
return stringForm == other.stringForm;
}
bool MetaIdentifier::operator != (const MetaIdentifier & other) const
{
return !(*this == other);
}
bool MetaIdentifier::operator < (const MetaIdentifier & other) const
{
assert(0);
}
int32_t MetaIdentifier::getNum() const
{
return integerForm;
}
std::string MetaIdentifier::toString() const
{
return stringForm;
}
void MetaIdentifier::onDeserialized()
{
assert(0); //TODO
}
VCMI_LIB_NAMESPACE_END

View File

@ -14,49 +14,69 @@
VCMI_LIB_NAMESPACE_BEGIN
/// This class represents field that may contain value of multiple different identifer types
template<typename... Types>
class DLL_LINKAGE MetaIdentifier
{
std::string stringForm;
int32_t integerForm;
void onDeserialized();
std::variant<Types...> value;
public:
static const MetaIdentifier NONE;
MetaIdentifier();
MetaIdentifier(const std::string & entityType, const std::string & identifier);
MetaIdentifier(const std::string & entityType, const std::string & identifier, int32_t value);
MetaIdentifier()
{}
template<typename IdentifierType>
explicit MetaIdentifier(const IdentifierType & identifier)
: integerForm(identifier.getNum())
MetaIdentifier(const IdentifierType & identifier)
: value(identifier)
{}
int32_t getNum() const
{
static_assert(std::is_base_of<IdentifierBase, IdentifierType>::value, "MetaIdentifier can only be constructed from Identifer class");
std::optional<int32_t> result;
std::visit([&result] (const auto& v) { result = v.getNum(); }, value);
assert(result.has_value());
return result.value_or(-1);
}
int32_t getNum() const;
std::string toString() const;
std::string toString() const
{
std::optional<std::string> result;
std::visit([&result] (const auto& v) { result = v.encode(v.getNum()); }, value);
assert(result.has_value());
return result.value_or("");
}
template<typename IdentifierType>
IdentifierType as() const
{
static_assert(std::is_base_of<IdentifierBase, IdentifierType>::value, "MetaIdentifier can only be converted to Identifer class");
IdentifierType result(integerForm);
return result;
auto * result = std::get_if<IdentifierType>(&value);
assert(result);
if (result)
return *result;
else
return IdentifierType();
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & integerForm;
if (!h.saving)
onDeserialized();
h & value;
}
bool operator == (const MetaIdentifier & other) const;
bool operator != (const MetaIdentifier & other) const;
bool operator < (const MetaIdentifier & other) const;
bool operator == (const MetaIdentifier & other) const
{
return value == other.value;
}
bool operator != (const MetaIdentifier & other) const
{
return value != other.value;
}
bool operator < (const MetaIdentifier & other) const
{
return value < other.value;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -655,7 +655,7 @@ void CGameState::initGlobalBonuses()
{
auto bonus = JsonUtils::parseBonus(b.second);
bonus->source = BonusSource::GLOBAL;//for all
bonus->sid = TBonusSourceID::NONE; //there is one global object
bonus->sid = TBonusSourceID(); //there is one global object
globalEffects.addNewBonus(bonus);
}
VLC->creh->loadCrExpBon(globalEffects);

View File

@ -488,4 +488,9 @@ std::string CObjectClassesHandler::getObjectHandlerName(si32 type) const
return objects.at(type)->handlerName;
}
std::string CObjectClassesHandler::getJsonKey(si32 type) const
{
return objects.at(type)->getJsonKey();
}
VCMI_LIB_NAMESPACE_END

View File

@ -129,6 +129,8 @@ public:
/// Returns handler string describing the handler (for use in client)
std::string getObjectHandlerName(si32 type) const;
std::string getJsonKey(si32 type) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & objects;

View File

@ -59,7 +59,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
auto b = getExportedBonusList().getFirst(Selector::sourceType()(BonusSource::ARMY).And(Selector::type()(BonusType::MORALE)));
if(!b)
{
b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, 0, TBonusSourceID::NONE);
b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, 0, TBonusSourceID());
addNewBonus(b);
}
@ -120,13 +120,12 @@ void CArmedInstance::updateMoraleBonusFromArmy()
CBonusSystemNode::treeHasChanged();
//-1 modifier for any Undead unit in army
const TBonusSourceID UNDEAD_MODIFIER_ID( "", "", -2);
auto undeadModifier = getExportedBonusList().getFirst(Selector::source(BonusSource::ARMY, UNDEAD_MODIFIER_ID));
auto undeadModifier = getExportedBonusList().getFirst(Selector::source(BonusSource::ARMY, BonusSourceID::undeadMoraleDebuff));
if(hasUndead)
{
if(!undeadModifier)
{
undeadModifier = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, -1, UNDEAD_MODIFIER_ID, VLC->generaltexth->arraytxt[116]);
undeadModifier = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, -1, BonusSourceID::undeadMoraleDebuff, VLC->generaltexth->arraytxt[116]);
undeadModifier->description = undeadModifier->description.substr(0, undeadModifier->description.size()-2);//trim value
addNewBonus(undeadModifier);
}

View File

@ -16,7 +16,6 @@
#include "../CConfigHandler.h"
#include "../GameSettings.h"
#include "../IGameCallback.h"
#include "../bonuses/BonusSubtypes.h"
#include "../serializer/JsonSerializeFormat.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -47,7 +46,7 @@ std::string CGCreature::getHoverText(PlayerColor player) const
std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
{
std::string hoverName;
if(hero->hasVisions(this, BonusSubtypes::visionsMonsters))
if(hero->hasVisions(this, BonusSubtypeID::visionsMonsters))
{
MetaString ms;
ms.appendNumber(stacks.begin()->second->count);

View File

@ -37,7 +37,6 @@
#include "../modding/ModScope.h"
#include "../constants/StringConstants.h"
#include "../battle/Unit.h"
#include "../bonuses/BonusSubtypes.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -250,14 +249,14 @@ void CGHeroInstance::updateArmyMovementBonus(bool onLand, const TurnInfo * ti) c
lowestCreatureSpeed = realLowestSpeed;
//Let updaters run again
treeHasChanged();
ti->updateHeroBonuses(BonusType::MOVEMENT, Selector::subtype()(onLand ? BonusSubtypes::heroMovementLand : BonusSubtypes::heroMovementSea));
ti->updateHeroBonuses(BonusType::MOVEMENT, Selector::subtype()(onLand ? BonusSubtypeID::heroMovementLand : BonusSubtypeID::heroMovementSea));
}
}
int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti) const
{
updateArmyMovementBonus(onLand, ti);
return ti->valOfBonuses(BonusType::MOVEMENT, onLand ? BonusSubtypes::heroMovementLand : BonusSubtypes::heroMovementSea);
return ti->valOfBonuses(BonusType::MOVEMENT, onLand ? BonusSubtypeID::heroMovementLand : BonusSubtypeID::heroMovementSea);
}
CGHeroInstance::CGHeroInstance():
@ -764,7 +763,7 @@ bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const
}
});
const bool levelBonus = hasBonusOfType(BonusType::SPELLS_OF_LEVEL, BonusSubtypes::spellLevel(spell->getLevel()));
const bool levelBonus = hasBonusOfType(BonusType::SPELLS_OF_LEVEL, BonusSubtypeID::spellLevel(spell->getLevel()));
if(spell->isSpecial())
{

View File

@ -15,7 +15,6 @@
#include "../NetPacks.h"
#include "../IGameCallback.h"
#include "../gameState/CGameState.h"
#include "../bonuses/BonusSubtypes.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -147,7 +146,7 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
if(!h->hasBonusFrom(BonusSource::OBJECT, TBonusSourceID(Obj(Obj::STABLES)))) //does not stack with advMap Stables
{
GiveBonus gb;
gb.bonus = Bonus(BonusDuration::ONE_WEEK, BonusType::MOVEMENT, BonusSource::OBJECT, 600, TBonusSourceID(Obj(Obj::STABLES)), BonusSubtypes::heroMovementLand, VLC->generaltexth->arraytxt[100]);
gb.bonus = Bonus(BonusDuration::ONE_WEEK, BonusType::MOVEMENT, BonusSource::OBJECT, 600, TBonusSourceID(Obj(Obj::STABLES)), BonusSubtypeID::heroMovementLand, VLC->generaltexth->arraytxt[100]);
gb.id = heroID.getNum();
cb->giveHeroBonus(&gb);

View File

@ -13,7 +13,6 @@
#include "CGTownBuilding.h"
#include "../spells/CSpellHandler.h"
#include "../bonuses/Bonus.h"
#include "../bonuses/BonusSubtypes.h"
#include "../battle/IBattleInfoCallback.h"
#include "../NetPacks.h"
#include "../CConfigHandler.h"
@ -161,7 +160,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
}
//other *-of-legion-like bonuses (%d to growth cumulative with grail)
TConstBonusListPtr bonuses = getBonuses(Selector::typeSubtype(BonusType::CREATURE_GROWTH, BonusSubtypes::creatureLevel(level)));
TConstBonusListPtr bonuses = getBonuses(Selector::typeSubtype(BonusType::CREATURE_GROWTH, BonusSubtypeID::creatureLevel(level)));
for(const auto & b : *bonuses)
ret.entries.emplace_back(b->val, b->Description());
@ -788,7 +787,7 @@ void CGTownInstance::updateMoraleBonusFromArmy()
auto b = getExportedBonusList().getFirst(Selector::sourceType()(BonusSource::ARMY).And(Selector::type()(BonusType::MORALE)));
if(!b)
{
b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, 0, TBonusSourceID::NONE);
b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, 0, TBonusSourceID());
addNewBonus(b);
}

View File

@ -25,7 +25,6 @@
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../modding/ModScope.h"
#include "../bonuses/BonusSubtypes.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -1205,7 +1204,7 @@ void CGLighthouse::giveBonusTo(const PlayerColor & player, bool onInit) const
gb.bonus.duration = BonusDuration::PERMANENT;
gb.bonus.source = BonusSource::OBJECT;
gb.bonus.sid = TBonusSourceID(id);
gb.bonus.subtype = BonusSubtypes::heroMovementSea;
gb.bonus.subtype = BonusSubtypeID::heroMovementSea;
// FIXME: This is really dirty hack
// Proper fix would be to make CGLighthouse into bonus system node

View File

@ -73,7 +73,7 @@ bool TurnInfo::isLayerAvailable(const EPathfindingLayer & layer) const
bool TurnInfo::hasBonusOfType(BonusType type) const
{
return hasBonusOfType(type, TBonusSubtype::NONE);
return hasBonusOfType(type, TBonusSubtype());
}
bool TurnInfo::hasBonusOfType(BonusType type, TBonusSubtype subtype) const
@ -96,7 +96,7 @@ bool TurnInfo::hasBonusOfType(BonusType type, TBonusSubtype subtype) const
int TurnInfo::valOfBonuses(BonusType type) const
{
return valOfBonuses(type, TBonusSubtype::NONE);
return valOfBonuses(type, TBonusSubtype());
}
int TurnInfo::valOfBonuses(BonusType type, TBonusSubtype subtype) const

View File

@ -17,7 +17,6 @@
#include "../battle/Unit.h"
#include "../bonuses/BonusParams.h"
#include "../bonuses/BonusList.h"
#include "../bonuses/BonusSubtypes.h"
#include "../modding/IdentifierStorage.h"
#include "../modding/ModUtility.h"
@ -293,8 +292,8 @@ class ImmunityNegationCondition : public TargetConditionItemBase
protected:
bool check(const Mechanics * m, const battle::Unit * target) const override
{
const bool battleWideNegation = target->hasBonusOfType(BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSubtypes::immunityBattleWide);
const bool heroNegation = target->hasBonusOfType(BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSubtypes::immunityEnemyHero);
const bool battleWideNegation = target->hasBonusOfType(BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSubtypeID::immunityBattleWide);
const bool heroNegation = target->hasBonusOfType(BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSubtypeID::immunityEnemyHero);
//Non-magical effects is not affected by orb of vulnerability
if(!m->isMagicalEffect())
return false;

View File

@ -20,7 +20,6 @@
#include "../../lib/battle/CBattleInfoCallback.h"
#include "../../lib/battle/IBattleState.h"
#include "../../lib/battle/BattleAction.h"
#include "../../lib/bonuses/BonusSubtypes.h"
#include "../../lib/gameState/CGameState.h"
#include "../../lib/NetPacks.h"
#include "../../lib/spells/AbilityCaster.h"
@ -163,9 +162,9 @@ 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, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::PERCENT_TO_ALL);
Bonus bonus2(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, stack->valOfBonuses(BonusType::DEFENSIVE_STANCE), TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
Bonus alternativeWeakCreatureBonus(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 1, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
Bonus defenseBonusToAdd(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 20, TBonusSourceID(), TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::PERCENT_TO_ALL);
Bonus bonus2(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, stack->valOfBonuses(BonusType::DEFENSIVE_STANCE), TBonusSourceID(), TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
Bonus alternativeWeakCreatureBonus(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 1, TBonusSourceID(), TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
BonusList defence = *stack->getBonuses(Selector::typeSubtype(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::DEFENSE)));
int oldDefenceValue = defence.totalValue();
@ -383,7 +382,7 @@ bool BattleActionProcessor::doCatapultAction(const CBattleInfoCallback & battle,
return false;
std::shared_ptr<const Bonus> catapultAbility = stack->getBonusLocalFirst(Selector::type()(BonusType::CATAPULT));
if(!catapultAbility || catapultAbility->subtype == TBonusSubtype::NONE)
if(!catapultAbility || catapultAbility->subtype == TBonusSubtype())
{
gameHandler->complain("We do not know how to shoot :P");
}
@ -453,7 +452,7 @@ bool BattleActionProcessor::doHealAction(const CBattleInfoCallback & battle, con
else
destStack = battle.battleGetUnitByPos(target.at(0).hexValue);
if(stack == nullptr || destStack == nullptr || !healerAbility || healerAbility->subtype == TBonusSubtype::NONE)
if(stack == nullptr || destStack == nullptr || !healerAbility || healerAbility->subtype == TBonusSubtype())
{
gameHandler->complain("There is either no healer, no destination, or healer cannot heal :P");
}
@ -1169,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, BonusSubtypes::deathStareGorgon) / 100.0f;
double chanceToKill = attacker->valOfBonuses(BonusType::DEATH_STARE, BonusSubtypeID::deathStareGorgon) / 100.0f;
vstd::amin(chanceToKill, 1); //cap at 100%
std::binomial_distribution<> distribution(attacker->getCount(), chanceToKill);
@ -1180,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, BonusSubtypes::deathStareCommander)) / defender->level();
staredCreatures += (attacker->level() * attacker->valOfBonuses(BonusType::DEATH_STARE, BonusSubtypeID::deathStareCommander)) / defender->level();
if(staredCreatures)
{
//TODO: death stare was not originally available for multiple-hex attacks, but...
@ -1250,9 +1249,9 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
else
resurrectInfo.type = attacker->creatureId();
if(attacker->hasBonusOfType((BonusType::TRANSMUTATION), BonusSubtypes::transmutationPerHealth))
if(attacker->hasBonusOfType((BonusType::TRANSMUTATION), BonusSubtypeID::transmutationPerHealth))
resurrectInfo.count = std::max((defender->getCount() * defender->getMaxHealth()) / resurrectInfo.type.toCreature()->getMaxHealth(), 1u);
else if (attacker->hasBonusOfType((BonusType::TRANSMUTATION), BonusSubtypes::transmutationPerUnit))
else if (attacker->hasBonusOfType((BonusType::TRANSMUTATION), BonusSubtypeID::transmutationPerUnit))
resurrectInfo.count = defender->getCount();
else
return; //wrong subtype
@ -1274,21 +1273,21 @@ void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback &
gameHandler->sendAndApply(&fakeEvent);
}
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillPercentage) || attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillAmount))
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypeID::destructionKillPercentage) || attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypeID::destructionKillAmount))
{
double chanceToTrigger = 0;
int amountToDie = 0;
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillPercentage)) //killing by percentage
if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypeID::destructionKillPercentage)) //killing by percentage
{
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, BonusSubtypes::destructionKillPercentage) / 100.0f;
int percentageToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(BonusSubtypes::destructionKillPercentage)))->additionalInfo[0];
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, BonusSubtypeID::destructionKillPercentage) / 100.0f;
int percentageToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(BonusSubtypeID::destructionKillPercentage)))->additionalInfo[0];
amountToDie = static_cast<int>(defender->getCount() * percentageToDie * 0.01f);
}
else if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypes::destructionKillAmount)) //killing by count
else if(attacker->hasBonusOfType(BonusType::DESTRUCTION, BonusSubtypeID::destructionKillAmount)) //killing by count
{
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, BonusSubtypes::destructionKillAmount) / 100.0f;
amountToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(BonusSubtypes::destructionKillAmount)))->additionalInfo[0];
chanceToTrigger = attacker->valOfBonuses(BonusType::DESTRUCTION, BonusSubtypeID::destructionKillAmount) / 100.0f;
amountToDie = attacker->getBonus(Selector::type()(BonusType::DESTRUCTION).And(Selector::subtype()(BonusSubtypeID::destructionKillAmount)))->additionalInfo[0];
}
vstd::amin(chanceToTrigger, 1); //cap trigger chance at 100%
@ -1349,12 +1348,12 @@ 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(const auto & subtype : { BonusSubtypes::soulStealBattle, BonusSubtypes::soulStealPermanent})
for(const auto & subtype : { BonusSubtypeID::soulStealBattle, BonusSubtypeID::soulStealPermanent})
{
if(attackerState->hasBonusOfType(BonusType::SOUL_STEAL, subtype))
{
int64_t toHeal = bsa.killedAmount * attackerState->valOfBonuses(BonusType::SOUL_STEAL, subtype) * attackerState->getMaxHealth();
bool permanent = subtype == BonusSubtypes::soulStealPermanent;
bool permanent = subtype == BonusSubtypeID::soulStealPermanent;
attackerState->heal(toHeal, EHealLevel::OVERHEAL, (permanent ? EHealPower::PERMANENT : EHealPower::ONE_BATTLE));
drainedLife += toHeal;
break;

View File

@ -16,7 +16,6 @@
#include "../../lib/serializer/Connection.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/bonuses/BonusSubtypes.h"
#include "../../lib/modding/IdentifierStorage.h"
#include "../../lib/CPlayerState.h"
#include "../../lib/GameConstants.h"
@ -141,11 +140,11 @@ void PlayerMessageProcessor::cheatGiveSpells(PlayerColor player, const CGHeroIns
///Give all spells with bonus (to allow banned spells)
GiveBonus giveBonus(GiveBonus::ETarget::HERO);
giveBonus.id = hero->id.getNum();
giveBonus.bonus = Bonus(BonusDuration::PERMANENT, BonusType::SPELLS_OF_LEVEL, BonusSource::OTHER, 0, TBonusSourceID::NONE);
giveBonus.bonus = Bonus(BonusDuration::PERMANENT, BonusType::SPELLS_OF_LEVEL, BonusSource::OTHER, 0, TBonusSourceID());
//start with level 0 to skip abilities
for (int level = 1; level <= GameConstants::SPELL_LEVELS; level++)
{
giveBonus.bonus.subtype = BonusSubtypes::spellLevel(level);
giveBonus.bonus.subtype = BonusSubtypeID::spellLevel(level);
gameHandler->sendAndApply(&giveBonus);
}

View File

@ -49,7 +49,7 @@ public:
void makeWarMachine()
{
addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SIEGE_WEAPON, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID::NONE));
addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SIEGE_WEAPON, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID()));
}
void redirectBonusesToFake()
@ -331,7 +331,7 @@ TEST_F(BattleMatchOwnerTest, hypnotizedToSelf)
{
UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
setDefaultExpectations();
@ -362,7 +362,7 @@ TEST_F(BattleMatchOwnerTest, hypnotizedToNormalAlly)
{
UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
@ -382,7 +382,7 @@ TEST_F(BattleMatchOwnerTest, normalToHypnotizedAlly)
EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
setDefaultExpectations();
@ -397,11 +397,11 @@ TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedAlly)
{
UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
UnitFake & unit2 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
setDefaultExpectations();
@ -433,7 +433,7 @@ TEST_F(BattleMatchOwnerTest, hypnotizedToNormalEnemy)
{
UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
@ -453,7 +453,7 @@ TEST_F(BattleMatchOwnerTest, normalToHypnotizedEnemy)
EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
setDefaultExpectations();
@ -468,11 +468,11 @@ TEST_F(BattleMatchOwnerTest, hypnotizedToHypnotizedEnemy)
{
UnitFake & unit1 = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(unit1, unitId()).WillRepeatedly(Return(42));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
UnitFake & unit2 = unitsFake.add(BattleSide::DEFENDER);
EXPECT_CALL(unit2, unitId()).WillRepeatedly(Return(4242));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID()));
setDefaultExpectations();

View File

@ -33,7 +33,7 @@ public:
EXPECT_CALL(mock, getAllBonuses(_, _, _, _)).WillRepeatedly(Invoke(&bonusMock, &BonusBearerMock::getAllBonuses));
EXPECT_CALL(mock, getTreeVersion()).WillRepeatedly(Return(1));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, UNIT_HEALTH, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, UNIT_HEALTH, TBonusSourceID()));
EXPECT_CALL(mock, unitBaseAmount()).WillRepeatedly(Return(UNIT_AMOUNT));
}
@ -239,7 +239,7 @@ TEST_F(HealthTest, singleUnitStack)
EXPECT_CALL(mock, getAllBonuses(_, _, _, _)).WillRepeatedly(Invoke(&bonusMock, &BonusBearerMock::getAllBonuses));
EXPECT_CALL(mock, getTreeVersion()).WillRepeatedly(Return(1));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 300, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 300, TBonusSourceID()));
EXPECT_CALL(mock, unitBaseAmount()).WillRepeatedly(Return(1));

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, TBonusSourceID::NONE, TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELLCASTER, BonusSource::CREATURE_ABILITY, DEFAULT_SCHOOL_LEVEL, TBonusSourceID(), TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
}
};
@ -63,7 +63,7 @@ TEST_F(UnitStateMagicTest, initialNormal)
{
setDefaultExpectations();
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CASTS, BonusSource::CREATURE_ABILITY, 567, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CASTS, BonusSource::CREATURE_ABILITY, 567, TBonusSourceID()));
initUnit();
@ -125,7 +125,7 @@ TEST_F(UnitStateMagicTest, effectPower)
const int32_t EFFECT_POWER = 12 * 100;
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_SPELL_POWER, BonusSource::CREATURE_ABILITY, EFFECT_POWER, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_SPELL_POWER, BonusSource::CREATURE_ABILITY, EFFECT_POWER, TBonusSourceID()));
makeNormalCaster();
EXPECT_EQ(subject.getEffectPower(&spellMock), 12 * DEFAULT_AMOUNT);
@ -148,7 +148,7 @@ TEST_F(UnitStateMagicTest, enchantPower)
const int32_t ENCHANT_POWER = 42;
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_ENCHANT_POWER, BonusSource::CREATURE_ABILITY, ENCHANT_POWER, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_ENCHANT_POWER, BonusSource::CREATURE_ABILITY, ENCHANT_POWER, TBonusSourceID()));
makeNormalCaster();
@ -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, TBonusSourceID::NONE, TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPECIFIC_SPELL_POWER, BonusSource::CREATURE_ABILITY, EFFECT_VALUE, TBonusSourceID(), TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
makeNormalCaster();
EXPECT_EQ(subject.getEffectValue(&spellMock), EFFECT_VALUE * DEFAULT_AMOUNT);
@ -201,7 +201,7 @@ TEST_F(UnitStateMagicTest, spendMana)
{
setDefaultExpectations();
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CASTS, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CASTS, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID()));
initUnit();

View File

@ -12,7 +12,6 @@
#include "mock/mock_BonusBearer.h"
#include "mock/mock_UnitInfo.h"
#include "mock/mock_UnitEnvironment.h"
#include "../../lib/bonuses/BonusSubtypes.h"
#include "../../lib/battle/CUnitState.h"
#include "../../lib/CCreatureHandler.h"
@ -52,12 +51,12 @@ public:
void setDefaultExpectations()
{
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACKS_SPEED, BonusSource::CREATURE_ABILITY, DEFAULT_SPEED, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACKS_SPEED, BonusSource::CREATURE_ABILITY, DEFAULT_SPEED, TBonusSourceID()));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_ATTACK, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::ATTACK)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_DEFENCE, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::DEFENSE)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_ATTACK, TBonusSourceID(), TBonusSubtype(PrimarySkill::ATTACK)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_DEFENCE, TBonusSourceID(), TBonusSubtype(PrimarySkill::DEFENSE)));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, DEFAULT_HP, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, DEFAULT_HP, TBonusSourceID()));
EXPECT_CALL(infoMock, unitBaseAmount()).WillRepeatedly(Return(DEFAULT_AMOUNT));
EXPECT_CALL(infoMock, unitType()).WillRepeatedly(Return(pikeman));
@ -67,8 +66,8 @@ public:
void makeShooter(int32_t ammo)
{
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOOTER, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOTS, BonusSource::CREATURE_ABILITY, ammo, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOOTER, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID()));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOTS, BonusSource::CREATURE_ABILITY, ammo, TBonusSourceID()));
}
void initUnit()
@ -180,7 +179,7 @@ TEST_F(UnitStateTest, attackWithFrenzy)
{
setDefaultExpectations();
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, TBonusSourceID()));
int expectedAttack = static_cast<int>(DEFAULT_ATTACK + 0.5 * DEFAULT_DEFENCE);
@ -192,7 +191,7 @@ TEST_F(UnitStateTest, defenceWithFrenzy)
{
setDefaultExpectations();
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, TBonusSourceID::NONE));
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, TBonusSourceID()));
int expectedDefence = 0;
@ -205,7 +204,7 @@ TEST_F(UnitStateTest, additionalAttack)
setDefaultExpectations();
{
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID::NONE);
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID());
bonusMock.addNewBonus(bonus);
}
@ -219,7 +218,7 @@ TEST_F(UnitStateTest, additionalMeleeAttack)
setDefaultExpectations();
{
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID::NONE);
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID());
bonus->effectRange = BonusLimitEffect::ONLY_MELEE_FIGHT;
bonusMock.addNewBonus(bonus);
@ -234,7 +233,7 @@ TEST_F(UnitStateTest, additionalRangedAttack)
setDefaultExpectations();
{
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID::NONE);
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID());
bonus->effectRange = BonusLimitEffect::ONLY_DISTANCE_FIGHT;
bonusMock.addNewBonus(bonus);
@ -249,10 +248,10 @@ TEST_F(UnitStateTest, getMinDamage)
setDefaultExpectations();
{
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, TBonusSourceID::NONE, BonusSubtypes::creatureDamageBoth);
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, TBonusSourceID(), BonusSubtypeID::creatureDamageBoth);
bonusMock.addNewBonus(bonus);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, TBonusSourceID::NONE, BonusSubtypes::creatureDamageMin);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, TBonusSourceID(), BonusSubtypeID::creatureDamageMin);
bonusMock.addNewBonus(bonus);
}
@ -265,10 +264,10 @@ TEST_F(UnitStateTest, getMaxDamage)
setDefaultExpectations();
{
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, TBonusSourceID::NONE, BonusSubtypes::creatureDamageBoth);
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, TBonusSourceID(), BonusSubtypeID::creatureDamageBoth);
bonusMock.addNewBonus(bonus);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, TBonusSourceID::NONE, BonusSubtypes::creatureDamageMax);
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, TBonusSourceID(), BonusSubtypeID::creatureDamageMax);
bonusMock.addNewBonus(bonus);
}

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

View File

@ -95,7 +95,7 @@ TEST_F(DamageApplyTest, DoesDamageToAliveUnit)
const uint32_t unitId = 42;
auto & targetUnit = unitsFake.add(BattleSide::ATTACKER);
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID()));
EXPECT_CALL(targetUnit, unitId()).WillRepeatedly(Return(unitId));
EXPECT_CALL(targetUnit, unitBaseAmount()).WillRepeatedly(Return(unitAmount));
EXPECT_CALL(targetUnit, alive()).WillRepeatedly(Return(true));
@ -157,7 +157,7 @@ TEST_F(DamageApplyTest, DoesDamageByPercent)
const uint32_t unitId = 42;
auto & targetUnit = unitsFake.add(BattleSide::ATTACKER);
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID()));
EXPECT_CALL(targetUnit, unitId()).WillRepeatedly(Return(unitId));
EXPECT_CALL(targetUnit, unitBaseAmount()).WillRepeatedly(Return(unitAmount));
EXPECT_CALL(targetUnit, getCount()).WillOnce(Return(unitAmount));
@ -202,7 +202,7 @@ TEST_F(DamageApplyTest, DoesDamageByCount)
const uint32_t unitId = 42;
auto & targetUnit = unitsFake.add(BattleSide::ATTACKER);
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID()));
EXPECT_CALL(targetUnit, unitId()).WillRepeatedly(Return(unitId));
EXPECT_CALL(targetUnit, unitBaseAmount()).WillRepeatedly(Return(unitAmount));
EXPECT_CALL(targetUnit, alive()).WillRepeatedly(Return(true));

View File

@ -91,7 +91,7 @@ TEST_F(HealTest, ApplicableIfActuallyResurrects)
EXPECT_CALL(mechanicsMock, getEffectValue()).Times(AtLeast(1)).WillRepeatedly(Return(1000));
EXPECT_CALL(mechanicsMock, isSmart()).WillOnce(Return(false));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID()));
unitsFake.setDefaultBonusExpectations();
EffectTarget target;
@ -117,7 +117,7 @@ TEST_F(HealTest, NotApplicableIfNotEnoughCasualties)
EXPECT_CALL(mechanicsMock, getEffectValue()).Times(AtLeast(1)).WillRepeatedly(Return(999));
EXPECT_CALL(mechanicsMock, isSmart()).WillRepeatedly(Return(false));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID()));
unitsFake.setDefaultBonusExpectations();
EffectTarget target;
@ -143,7 +143,7 @@ TEST_F(HealTest, NotApplicableIfResurrectsLessThanRequired)
EXPECT_CALL(mechanicsMock, getEffectValue()).Times(AtLeast(1)).WillRepeatedly(Return(999));
EXPECT_CALL(mechanicsMock, isSmart()).WillRepeatedly(Return(false));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID()));
unitsFake.setDefaultBonusExpectations();
EffectTarget target;
@ -271,7 +271,7 @@ TEST_F(HealTest, NotApplicableIfEffectValueTooLow)
EXPECT_CALL(unit, getTotalHealth()).WillOnce(Return(200));
EXPECT_CALL(unit, getAvailableHealth()).WillOnce(Return(100));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID()));
EXPECT_CALL(mechanicsMock, getEffectValue()).Times(AtLeast(1)).WillRepeatedly(Return(199));
@ -348,7 +348,7 @@ TEST_P(HealApplyTest, Heals)
EXPECT_CALL(targetUnit, unitId()).WillRepeatedly(Return(unitId));
EXPECT_CALL(targetUnit, unitType()).WillRepeatedly(Return(pikeman));
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID()));
unitsFake.setDefaultBonusExpectations();

View File

@ -179,13 +179,13 @@ TEST_F(SacrificeApplyTest, ResurrectsTarget)
EXPECT_CALL(mechanicsMock, applySpellBonus(_, Eq(&targetUnit))).WillOnce(ReturnArg<0>());
EXPECT_CALL(mechanicsMock, calculateRawEffectValue(_,_)).WillOnce(Return(effectValue));
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID()));
auto & victim = unitsFake.add(BattleSide::ATTACKER);
EXPECT_CALL(victim, unitId()).Times(AtLeast(1)).WillRepeatedly(Return(victimId));
EXPECT_CALL(victim, getCount()).Times(AtLeast(1)).WillRepeatedly(Return(victimCount));
victim.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, victimUnitHP, TBonusSourceID::NONE));
victim.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, victimUnitHP, TBonusSourceID()));
EXPECT_CALL(*battleFake, setUnitState(Eq(unitId), _, Eq(expectedHealValue))).Times(1);

View File

@ -244,12 +244,12 @@ TEST_P(SummonApplyTest, UpdatesOldUnit)
setDefaultExpectaions();
acquired = std::make_shared<battle::UnitFake>();
acquired->addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, TBonusSourceID::NONE));
acquired->addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, TBonusSourceID()));
acquired->redirectBonusesToFake();
acquired->expectAnyBonusSystemCall();
auto & unit = unitsFake.add(BattleSide::ATTACKER);
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, TBonusSourceID::NONE));
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, TBonusSourceID()));
{
EXPECT_CALL(unit, acquire()).WillOnce(Return(acquired));

View File

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

View File

@ -54,7 +54,7 @@ TEST_F(AbsoluteLevelConditionTest, ReceptiveNormalSpell)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 3, TBonusSourceID::NONE);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 3, TBonusSourceID());
bonus->additionalInfo = 1;
unitBonuses.addNewBonus(bonus);
@ -67,7 +67,7 @@ TEST_F(AbsoluteLevelConditionTest, ReceptiveAbility)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 5, TBonusSourceID::NONE);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 5, TBonusSourceID());
bonus->additionalInfo = 1;
unitBonuses.addNewBonus(bonus);
@ -79,7 +79,7 @@ TEST_F(AbsoluteLevelConditionTest, ImmuneNormalSpell)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID());
bonus->additionalInfo = 1;
unitBonuses.addNewBonus(bonus);
@ -90,7 +90,7 @@ TEST_F(AbsoluteLevelConditionTest, ImmuneNormalSpell)
TEST_F(AbsoluteLevelConditionTest, IgnoresNormalCase)
{
setDefaultExpectations();
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE);
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID());
unitBonuses.addNewBonus(bonus);
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
}

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, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID(), 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, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID(), TBonusSubtype(SpellID(immuneSpell)));
unitBonuses.addNewBonus(bonus);
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
}

View File

@ -42,14 +42,14 @@ TEST_F(BonusConditionTest, ImmuneByDefault)
TEST_F(BonusConditionTest, ReceptiveIfMatchesType)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_DAMAGE_REDUCTION, BonusSource::OTHER, 100, TBonusSourceID::NONE));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_DAMAGE_REDUCTION, BonusSource::OTHER, 100, TBonusSourceID()));
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
}
TEST_F(BonusConditionTest, ImmuneIfTypeMismatch)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::OTHER, 0, TBonusSourceID(SpellSchool::FIRE)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::OTHER, 0, TBonusSourceID(), TBonusSubtype(SpellSchool::FIRE)));
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
}

View File

@ -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, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID(), 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, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::WATER)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID(), 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, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID(), 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, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID(), TBonusSubtype(SpellSchool::AIR)));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID(), TBonusSubtype(SpellSchool::AIR)));
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
}

View File

@ -10,7 +10,6 @@
#include "StdInc.h"
#include "TargetConditionItemFixture.h"
#include "../../../lib/bonuses/BonusSubtypes.h"
//FIXME: Orb of vulnerability mechanics is not such trivial (mantis issue 1791)
//TODO: NEGATE_ALL_NATURAL_IMMUNITIES special cases: dispel, chain lightning
@ -58,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, TBonusSourceID::NONE, BonusSubtypes::immunityEnemyHero));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, TBonusSourceID(), BonusSubtypeID::immunityEnemyHero));
EXPECT_EQ(isMagicalEffect, subject->isReceptive(&mechanicsMock, &unitMock));
}
@ -67,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, TBonusSourceID::NONE, BonusSubtypes::immunityBattleWide));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, TBonusSourceID(), BonusSubtypeID::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

@ -56,7 +56,7 @@ TEST_P(NormalLevelConditionTest, DefaultForNormal)
TEST_P(NormalLevelConditionTest, ReceptiveNormal)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 3, TBonusSourceID::NONE));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 3, TBonusSourceID()));
if(isMagicalEffect)
EXPECT_CALL(mechanicsMock, getSpellLevel()).Times(AtLeast(1)).WillRepeatedly(Return(4));
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
@ -66,7 +66,7 @@ TEST_P(NormalLevelConditionTest, ReceptiveNormal)
TEST_P(NormalLevelConditionTest, ReceptiveAbility)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 5, TBonusSourceID::NONE));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 5, TBonusSourceID()));
if(isMagicalEffect)
EXPECT_CALL(mechanicsMock, getSpellLevel()).Times(AtLeast(1)).WillRepeatedly(Return(0));
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
@ -75,7 +75,7 @@ TEST_P(NormalLevelConditionTest, ReceptiveAbility)
TEST_P(NormalLevelConditionTest, ImmuneNormal)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID()));
if(isMagicalEffect)
EXPECT_CALL(mechanicsMock, getSpellLevel()).Times(AtLeast(1)).WillRepeatedly(Return(2));
EXPECT_EQ(!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, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID(), 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, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID(), TBonusSubtype(SpellID(immuneSpell)));
unitBonuses.addNewBonus(bonus);
if(immuneSpell == castSpell)
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));

View File

@ -31,7 +31,7 @@ public:
EXPECT_CALL(unitMock, getTreeVersion()).Times(AtLeast(0));
EXPECT_CALL(mechanicsMock, isPositiveSpell()).WillRepeatedly(Return(isPositive));
if(hasBonus)
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::RECEPTIVE, BonusSource::OTHER, 0, TBonusSourceID::NONE));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::RECEPTIVE, BonusSource::OTHER, 0, TBonusSourceID()));
}
protected:

View File

@ -60,7 +60,7 @@ TEST_F(SpellEffectConditionTest, ImmuneIfHasEffectFromOtherSpell)
TEST_F(SpellEffectConditionTest, ImmuneIfHasNoSpellEffects)
{
setDefaultExpectations();
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 3, TBonusSourceID::NONE));
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 3, TBonusSourceID()));
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
}