mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Bonus Source ID now uses metaidentifier
This commit is contained in:
parent
77facf9387
commit
b394158dc9
@ -71,7 +71,7 @@ float HeroManager::evaluateSecSkill(SecondarySkill skill, const CGHeroInstance *
|
||||
|
||||
float HeroManager::evaluateSpeciality(const CGHeroInstance * hero) const
|
||||
{
|
||||
auto heroSpecial = Selector::source(BonusSource::HERO_SPECIAL, hero->type->getIndex());
|
||||
auto heroSpecial = Selector::source(BonusSource::HERO_SPECIAL, TBonusSourceID(hero->type->getId()));
|
||||
auto secondarySkillBonus = Selector::targetSourceType()(BonusSource::SECONDARY_SKILL);
|
||||
auto specialSecondarySkillBonuses = hero->getBonuses(heroSpecial.And(secondarySkillBonus));
|
||||
auto secondarySkillBonuses = hero->getBonuses(Selector::sourceTypeSel(BonusSource::SECONDARY_SKILL));
|
||||
@ -83,7 +83,7 @@ float HeroManager::evaluateSpeciality(const CGHeroInstance * hero) const
|
||||
|
||||
if(hasBonus)
|
||||
{
|
||||
SecondarySkill bonusSkill = SecondarySkill(bonus->sid);
|
||||
SecondarySkill bonusSkill = bonus->sid.as<SecondarySkill>();
|
||||
float bonusScore = wariorSkillsScores.evaluateSecSkill(hero, bonusSkill);
|
||||
|
||||
if(bonusScore > 0)
|
||||
|
@ -433,14 +433,14 @@ void ApplyClientNetPackVisitor::visitRemoveBonus(RemoveBonus & pack)
|
||||
{
|
||||
case GiveBonus::ETarget::HERO:
|
||||
{
|
||||
const CGHeroInstance *h = gs.getHero(ObjectInstanceID(pack.id));
|
||||
const CGHeroInstance *h = gs.getHero(ObjectInstanceID(pack.whoID));
|
||||
callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroBonusChanged, h, pack.bonus, false);
|
||||
}
|
||||
break;
|
||||
case GiveBonus::ETarget::PLAYER:
|
||||
{
|
||||
//const PlayerState *p = gs.getPlayerState(pack.id);
|
||||
callInterfaceIfPresent(cl, PlayerColor(pack.id), &IGameEventsReceiver::playerBonusChanged, pack.bonus, false);
|
||||
callInterfaceIfPresent(cl, PlayerColor(pack.whoID), &IGameEventsReceiver::playerBonusChanged, pack.bonus, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ bool BattleStacksController::stackNeedsAmountBox(const CStack * stack) const
|
||||
|
||||
std::shared_ptr<IImage> BattleStacksController::getStackAmountBox(const CStack * stack)
|
||||
{
|
||||
std::vector<si32> activeSpells = stack->activeSpells();
|
||||
std::vector<SpellID> activeSpells = stack->activeSpells();
|
||||
|
||||
if ( activeSpells.empty())
|
||||
return amountNormal;
|
||||
@ -798,7 +798,7 @@ void BattleStacksController::removeExpiredColorFilters()
|
||||
{
|
||||
if (!filter.persistent)
|
||||
{
|
||||
if (filter.source && !filter.target->hasBonus(Selector::source(BonusSource::SPELL_EFFECT, filter.source->id), Selector::all))
|
||||
if (filter.source && !filter.target->hasBonus(Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(filter.source->id)), Selector::all))
|
||||
return true;
|
||||
if (filter.effect == ColorFilter::genEmptyShifter())
|
||||
return true;
|
||||
|
@ -548,7 +548,7 @@ void BattleWindow::bSpellf()
|
||||
|
||||
if (blockingBonus->source == BonusSource::ARTIFACT)
|
||||
{
|
||||
const auto artID = ArtifactID(blockingBonus->sid);
|
||||
const auto artID = blockingBonus->sid.as<ArtifactID>();
|
||||
//If we have artifact, put name of our hero. Otherwise assume it's the enemy.
|
||||
//TODO check who *really* is source of bonus
|
||||
std::string heroName = myHero->hasArt(artID) ? myHero->getNameTranslated() : owner.enemyHero().name;
|
||||
|
@ -208,10 +208,10 @@ CStackWindow::ActiveSpellsSection::ActiveSpellsSection(CStackWindow * owner, int
|
||||
|
||||
//spell effects
|
||||
int printed=0; //how many effect pics have been printed
|
||||
std::vector<si32> spells = battleStack->activeSpells();
|
||||
for(si32 effect : spells)
|
||||
std::vector<SpellID> spells = battleStack->activeSpells();
|
||||
for(SpellID effect : spells)
|
||||
{
|
||||
const spells::Spell * spell = CGI->spells()->getByIndex(effect);
|
||||
const spells::Spell * spell = CGI->spells()->getById(effect);
|
||||
|
||||
std::string spellText;
|
||||
|
||||
@ -224,7 +224,7 @@ CStackWindow::ActiveSpellsSection::ActiveSpellsSection(CStackWindow * owner, int
|
||||
spellText = CGI->generaltexth->allTexts[610]; //"%s, duration: %d rounds."
|
||||
boost::replace_first(spellText, "%s", spell->getNameTranslated());
|
||||
//FIXME: support permanent duration
|
||||
int duration = battleStack->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT,effect))->turnsRemain;
|
||||
int duration = battleStack->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(effect)))->turnsRemain;
|
||||
boost::replace_first(spellText, "%d", std::to_string(duration));
|
||||
|
||||
spellIcons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SpellInt"), effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed));
|
||||
|
@ -548,7 +548,7 @@ This is a list of all game identifiers available to modders. Note that only iden
|
||||
|
||||
### primSkill
|
||||
|
||||
Deprected, please use primarySkill instead
|
||||
Deprecated, please use primarySkill instead
|
||||
|
||||
- primSkill.attack
|
||||
- primSkill.defence
|
||||
@ -619,7 +619,7 @@ Deprected, please use primarySkill instead
|
||||
|
||||
### skill
|
||||
|
||||
Deprected, please use secondarySkill instead
|
||||
Deprecated, please use secondarySkill instead
|
||||
|
||||
- skill.airMagic
|
||||
- skill.archery
|
||||
|
@ -145,7 +145,7 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createScroll(const SpellID & sid)
|
||||
{
|
||||
auto ret = new CArtifactInstance(VLC->arth->objects[ArtifactID::SPELL_SCROLL]);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELL,
|
||||
BonusSource::ARTIFACT_INSTANCE, -1, ArtifactID::SPELL_SCROLL, TBonusSubtype(sid));
|
||||
BonusSource::ARTIFACT_INSTANCE, -1, TBonusSourceID(ArtifactID(ArtifactID::SPELL_SCROLL)), TBonusSubtype(sid));
|
||||
ret->addNewBonus(bonus);
|
||||
return ret;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ BattleFieldInfo * BattleFieldHandler::loadFromJson(const std::string & scope, co
|
||||
auto bonus = JsonUtils::parseBonus(b);
|
||||
|
||||
bonus->source = BonusSource::TERRAIN_OVERLAY;
|
||||
bonus->sid = info->getIndex();
|
||||
bonus->sid = TBonusSourceID(info->getId());
|
||||
bonus->duration = BonusDuration::ONE_BATTLE;
|
||||
|
||||
info->bonuses.push_back(bonus);
|
||||
|
@ -751,7 +751,7 @@ void CArtHandler::afterLoadFinalization()
|
||||
{
|
||||
assert(art == objects[art->id]);
|
||||
assert(bonus->source == BonusSource::ARTIFACT);
|
||||
bonus->sid = art->id;
|
||||
bonus->sid = TBonusSourceID(art->id);
|
||||
}
|
||||
}
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
|
@ -299,7 +299,7 @@ void CCreature::addBonus(int val, BonusType type)
|
||||
|
||||
void CCreature::addBonus(int val, BonusType type, TBonusSubtype subtype)
|
||||
{
|
||||
auto selector = Selector::typeSubtype(type, subtype).And(Selector::source(BonusSource::CREATURE_ABILITY, getIndex()));
|
||||
auto selector = Selector::typeSubtype(type, subtype).And(Selector::source(BonusSource::CREATURE_ABILITY, TBonusSourceID(getId())));
|
||||
BonusList & exported = getExportedBonusList();
|
||||
|
||||
BonusList existing;
|
||||
@ -307,7 +307,7 @@ void CCreature::addBonus(int val, BonusType type, TBonusSubtype subtype)
|
||||
|
||||
if(existing.empty())
|
||||
{
|
||||
auto added = std::make_shared<Bonus>(BonusDuration::PERMANENT, type, BonusSource::CREATURE_ABILITY, val, getIndex(), subtype, BonusValueType::BASE_NUMBER);
|
||||
auto added = std::make_shared<Bonus>(BonusDuration::PERMANENT, type, BonusSource::CREATURE_ABILITY, val, TBonusSourceID(getId()), subtype, BonusValueType::BASE_NUMBER);
|
||||
addNewBonus(added);
|
||||
}
|
||||
else
|
||||
@ -791,9 +791,9 @@ void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects)
|
||||
}
|
||||
do //parse everything that's left
|
||||
{
|
||||
auto sid = static_cast<ui32>(parser.readNumber()); //id = this particular creature ID
|
||||
CreatureID sid = static_cast<ui32>(parser.readNumber()); //id = this particular creature ID
|
||||
|
||||
b.sid = sid;
|
||||
b.sid = TBonusSourceID(sid);
|
||||
bl.clear();
|
||||
loadStackExp(b, bl, parser);
|
||||
for(const auto & b : bl)
|
||||
@ -899,7 +899,7 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
||||
{
|
||||
auto b = JsonUtils::parseBonus(ability.second);
|
||||
b->source = BonusSource::CREATURE_ABILITY;
|
||||
b->sid = creature->getIndex();
|
||||
b->sid = TBonusSourceID(creature->getId());
|
||||
b->duration = BonusDuration::PERMANENT;
|
||||
creature->addNewBonus(b);
|
||||
}
|
||||
@ -917,7 +917,7 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
||||
{
|
||||
auto b = JsonUtils::parseBonus(ability);
|
||||
b->source = BonusSource::CREATURE_ABILITY;
|
||||
b->sid = creature->getIndex();
|
||||
b->sid = TBonusSourceID(creature->getId());
|
||||
b->duration = BonusDuration::PERMANENT;
|
||||
creature->addNewBonus(b);
|
||||
}
|
||||
|
@ -605,7 +605,7 @@ void CHeroHandler::loadHeroSpecialty(CHero * hero, const JsonNode & node)
|
||||
{
|
||||
bonus->duration = BonusDuration::PERMANENT;
|
||||
bonus->source = BonusSource::HERO_SPECIAL;
|
||||
bonus->sid = hero->getIndex();
|
||||
bonus->sid = TBonusSourceID(hero->getId());
|
||||
return bonus;
|
||||
};
|
||||
|
||||
|
@ -93,7 +93,7 @@ SecondarySkill CSkill::getId() const
|
||||
void CSkill::addNewBonus(const std::shared_ptr<Bonus> & b, int level)
|
||||
{
|
||||
b->source = BonusSource::SECONDARY_SKILL;
|
||||
b->sid = id;
|
||||
b->sid = TBonusSourceID(id);
|
||||
b->duration = BonusDuration::PERMANENT;
|
||||
b->description = getNameTranslated();
|
||||
levels[level-1].effects.push_back(b);
|
||||
|
@ -121,23 +121,23 @@ BattleHex::EDir CStack::destShiftDir() const
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<si32> CStack::activeSpells() const
|
||||
std::vector<SpellID> CStack::activeSpells() const
|
||||
{
|
||||
std::vector<si32> ret;
|
||||
std::vector<SpellID> ret;
|
||||
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "!type_" << vstd::to_underlying(BonusType::NONE) << "source_" << vstd::to_underlying(BonusSource::SPELL_EFFECT);
|
||||
CSelector selector = Selector::sourceType()(BonusSource::SPELL_EFFECT)
|
||||
.And(CSelector([](const Bonus * b)->bool
|
||||
{
|
||||
return b->type != BonusType::NONE && SpellID(b->sid).toSpell() && !SpellID(b->sid).toSpell()->isAdventure();
|
||||
return b->type != BonusType::NONE && b->sid.as<SpellID>().toSpell() && !b->sid.as<SpellID>().toSpell()->isAdventure();
|
||||
}));
|
||||
|
||||
TConstBonusListPtr spellEffects = getBonuses(selector, Selector::all, cachingStr.str());
|
||||
for(const auto & it : *spellEffects)
|
||||
{
|
||||
if(!vstd::contains(ret, it->sid)) //do not duplicate spells with multiple effects
|
||||
ret.push_back(it->sid);
|
||||
if(!vstd::contains(ret, it->sid.as<SpellID>())) //do not duplicate spells with multiple effects
|
||||
ret.push_back(it->sid.as<SpellID>());
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
|
||||
ui32 level() const;
|
||||
si32 magicResistance() const override; //include aura of resistance
|
||||
std::vector<si32> activeSpells() const; //returns vector of active spell IDs sorted by time of cast
|
||||
std::vector<SpellID> activeSpells() const; //returns vector of active spell IDs sorted by time of cast
|
||||
const CGHeroInstance * getMyHero() const; //if stack belongs to hero (directly or was by him summoned) returns hero, nullptr otherwise
|
||||
|
||||
static std::vector<BattleHex> meleeAttackHexes(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos = BattleHex::INVALID, BattleHex defenderPos = BattleHex::INVALID);
|
||||
|
@ -50,6 +50,30 @@ const std::map<std::string, CBuilding::ETowerHeight> CBuilding::TOWER_TYPES =
|
||||
{ "skyship", CBuilding::HEIGHT_SKYSHIP }
|
||||
};
|
||||
|
||||
BuildingTypeUniqueID::BuildingTypeUniqueID(FactionID factionID, BuildingID buildingID ):
|
||||
BuildingTypeUniqueID(factionID.getNum() * 0x10000 + buildingID.getNum())
|
||||
{
|
||||
assert(factionID.getNum() >= 0);
|
||||
assert(factionID.getNum() < 0x10000);
|
||||
assert(buildingID.getNum() >= 0);
|
||||
assert(buildingID.getNum() < 0x10000);
|
||||
}
|
||||
|
||||
BuildingID BuildingTypeUniqueID::getBuilding() const
|
||||
{
|
||||
return BuildingID(getNum() % 0x10000);
|
||||
}
|
||||
|
||||
FactionID BuildingTypeUniqueID::getFaction() const
|
||||
{
|
||||
return FactionID(getNum() / 0x10000);
|
||||
}
|
||||
|
||||
const BuildingTypeUniqueID CBuilding::getUniqueTypeID() const
|
||||
{
|
||||
return BuildingTypeUniqueID(town->faction->getId(), bid);
|
||||
}
|
||||
|
||||
std::string CBuilding::getJsonKey() const
|
||||
{
|
||||
return modScope + ':' + identifier;;
|
||||
@ -569,7 +593,7 @@ std::shared_ptr<Bonus> CTownHandler::createBonusImpl(const BuildingID & building
|
||||
const std::string & description,
|
||||
TBonusSubtype subtype) const
|
||||
{
|
||||
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, type, BonusSource::TOWN_STRUCTURE, val, building, subtype, description);
|
||||
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, type, BonusSource::TOWN_STRUCTURE, val, TBonusSourceID(building), subtype, description);
|
||||
|
||||
if(prop)
|
||||
b->addPropagator(prop);
|
||||
@ -586,7 +610,7 @@ void CTownHandler::loadSpecialBuildingBonuses(const JsonNode & source, BonusList
|
||||
if(bonus == nullptr)
|
||||
continue;
|
||||
|
||||
bonus->sid = Bonus::getSid32(building->town->faction->getIndex(), building->bid);
|
||||
bonus->sid = TBonusSourceID(building->getUniqueTypeID());
|
||||
//JsonUtils::parseBuildingBonus produces UNKNOWN type propagator instead of empty.
|
||||
if(bonus->propagator != nullptr
|
||||
&& bonus->propagator->getPropagatorType() == CBonusSystemNode::ENodeTypes::UNKNOWN)
|
||||
@ -650,7 +674,7 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
|
||||
ret->subId = BuildingSubID::CUSTOM_VISITING_BONUS;
|
||||
|
||||
for(auto & bonus : ret->onVisitBonuses)
|
||||
bonus->sid = Bonus::getSid32(ret->town->faction->getIndex(), ret->bid);
|
||||
bonus->sid = TBonusSourceID(ret->getUniqueTypeID());
|
||||
}
|
||||
|
||||
if(source["type"].String() == "configurable" && ret->subId == BuildingSubID::NONE)
|
||||
|
@ -37,9 +37,6 @@ class JsonSerializeFormat;
|
||||
/// a typical building encountered in every castle ;]
|
||||
/// this is structure available to both client and server
|
||||
/// contains all mechanics-related data about town structures
|
||||
|
||||
|
||||
|
||||
class DLL_LINKAGE CBuilding
|
||||
{
|
||||
std::string modScope;
|
||||
@ -84,6 +81,8 @@ public:
|
||||
|
||||
CBuilding() : town(nullptr), mode(BUILD_NORMAL) {};
|
||||
|
||||
const BuildingTypeUniqueID getUniqueTypeID() const;
|
||||
|
||||
std::string getJsonKey() const;
|
||||
|
||||
std::string getNameTranslated() const;
|
||||
|
@ -439,9 +439,9 @@ static void loadBonusSubtype(TBonusSubtype & subtype, BonusType type, const Json
|
||||
});
|
||||
}
|
||||
|
||||
static void loadBonusSourceInstance(int32_t & sourceInstance, BonusSource sourceType, const JsonNode & node)
|
||||
static void loadBonusSourceInstance(TBonusSourceID & sourceInstance, BonusSource sourceType, const JsonNode & node)
|
||||
{
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
||||
std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonVector & ability_vec)
|
||||
@ -741,7 +741,7 @@ std::shared_ptr<Bonus> JsonUtils::parseBuildingBonus(const JsonNode & ability, c
|
||||
source = BonusSource::TOWN_STRUCTURE
|
||||
bonusType, val, subtype - get from json
|
||||
*/
|
||||
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::NONE, BonusSource::TOWN_STRUCTURE, 0, building, description);
|
||||
auto b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::NONE, BonusSource::TOWN_STRUCTURE, 0, TBonusSourceID(building), description);
|
||||
|
||||
if(!parseBonus(ability, b.get()))
|
||||
return nullptr;
|
||||
@ -858,8 +858,6 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
|
||||
|
||||
b->turnsRemain = static_cast<si32>(ability["turns"].Float());
|
||||
|
||||
b->sid = static_cast<si32>(ability["sourceID"].Float());
|
||||
|
||||
if(!ability["description"].isNull())
|
||||
{
|
||||
if (ability["description"].isString())
|
||||
@ -897,6 +895,8 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
|
||||
if (!value->isNull())
|
||||
b->source = static_cast<BonusSource>(parseByMap(bonusSourceMap, value, "source type "));
|
||||
|
||||
loadBonusSourceInstance(b->sid, b->source, ability["sourceID"]);
|
||||
|
||||
value = &ability["targetSourceType"];
|
||||
if (!value->isNull())
|
||||
b->targetSourceType = static_cast<BonusSource>(parseByMap(bonusSourceMap, value, "target type "));
|
||||
@ -978,7 +978,7 @@ CSelector JsonUtils::parseSelector(const JsonNode & ability)
|
||||
}
|
||||
value = &ability["sourceType"];
|
||||
std::optional<BonusSource> src = std::nullopt; //Fixes for GCC false maybe-uninitialized
|
||||
std::optional<si32> id = std::nullopt;
|
||||
std::optional<TBonusSourceID> id = std::nullopt;
|
||||
if(value->isString())
|
||||
{
|
||||
auto it = bonusSourceMap.find(value->String());
|
||||
|
@ -496,8 +496,8 @@ struct DLL_LINKAGE RemoveBonus : public CPackForClient
|
||||
ui32 whoID = 0; //hero, town or player id - whoever loses bonus
|
||||
|
||||
//vars to identify bonus: its source
|
||||
ui8 source = 0;
|
||||
ui32 id = 0; //source id
|
||||
BonusSource source;
|
||||
TBonusSourceID id; //source id
|
||||
|
||||
//used locally: copy of removed bonus
|
||||
Bonus bonus;
|
||||
|
@ -1119,7 +1119,7 @@ void RemoveBonus::applyGs(CGameState *gs)
|
||||
|
||||
for(const auto & b : bonuses)
|
||||
{
|
||||
if(vstd::to_underlying(b->source) == source && b->sid == id)
|
||||
if(b->source == source && b->sid == id)
|
||||
{
|
||||
bonus = *b; //backup bonus (to show to interfaces later)
|
||||
node->removeBonus(b);
|
||||
@ -2201,7 +2201,7 @@ void BattleTriggerEffect::applyGs(CGameState * gs) const
|
||||
}
|
||||
case BonusType::POISON:
|
||||
{
|
||||
auto b = st->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, SpellID::POISON)
|
||||
auto b = st->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, TBonusSubtype(SpellID(SpellID::POISON)))
|
||||
.And(Selector::type()(BonusType::STACK_HEALTH)));
|
||||
if (b)
|
||||
b->val = val;
|
||||
|
@ -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, 0)->addLimiter(nativeTerrain));
|
||||
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, 0, TBonusSubtype(PrimarySkill::ATTACK))->addLimiter(nativeTerrain));
|
||||
curB->addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::PRIMARY_SKILL, BonusSource::TERRAIN_NATIVE, 1, 0, TBonusSubtype(PrimarySkill::DEFENSE))->addLimiter(nativeTerrain));
|
||||
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));
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//tactics
|
||||
@ -802,7 +802,7 @@ void BattleInfo::setUnitState(uint32_t id, const JsonNode & data, int64_t health
|
||||
auto selector = [](const Bonus * b)
|
||||
{
|
||||
//Special case: DISRUPTING_RAY is absolutely permanent
|
||||
return b->source == BonusSource::SPELL_EFFECT && b->sid != SpellID::DISRUPTING_RAY;
|
||||
return b->source == BonusSource::SPELL_EFFECT && b->sid.as<SpellID>() != SpellID::DISRUPTING_RAY;
|
||||
};
|
||||
changedStack->removeBonusesRecursive(selector);
|
||||
}
|
||||
|
@ -1658,7 +1658,7 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(CRandomGenerator & rand, c
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "source_" << vstd::to_underlying(BonusSource::SPELL_EFFECT) << "id_" << spellID.num;
|
||||
|
||||
if(subject->hasBonus(Selector::source(BonusSource::SPELL_EFFECT, spellID), Selector::all, cachingStr.str())
|
||||
if(subject->hasBonus(Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(spellID)), Selector::all, cachingStr.str())
|
||||
//TODO: this ability has special limitations
|
||||
|| !(spellID.toSpell()->canBeCast(this, spells::Mode::CREATURE_ACTIVE, subject)))
|
||||
continue;
|
||||
|
@ -347,7 +347,7 @@ CUnitState::CUnitState():
|
||||
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)),
|
||||
cloneLifetimeMarker(this, Selector::type()(BonusType::NONE).And(Selector::source(BonusSource::SPELL_EFFECT, SpellID::CLONE))),
|
||||
cloneLifetimeMarker(this, Selector::type()(BonusType::NONE).And(Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(SpellID(SpellID::CLONE))))),
|
||||
cloneID(-1)
|
||||
{
|
||||
|
||||
@ -513,7 +513,7 @@ bool CUnitState::isGhost() const
|
||||
|
||||
bool CUnitState::isFrozen() const
|
||||
{
|
||||
return hasBonus(Selector::source(BonusSource::SPELL_EFFECT, SpellID::STONE_GAZE), Selector::all);
|
||||
return hasBonus(Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(SpellID(SpellID::STONE_GAZE))), Selector::all);
|
||||
}
|
||||
|
||||
bool CUnitState::isValidTarget(bool allowDead) const
|
||||
|
@ -314,7 +314,7 @@ double DamageCalculator::getDefenseRangePenaltiesFactor() const
|
||||
auto isAdvancedAirShield = [](const Bonus* bonus)
|
||||
{
|
||||
return bonus->source == BonusSource::SPELL_EFFECT
|
||||
&& bonus->sid == SpellID::AIR_SHIELD
|
||||
&& bonus->sid == TBonusSourceID(SpellID(SpellID::AIR_SHIELD))
|
||||
&& bonus->val >= MasteryLevel::ADVANCED;
|
||||
};
|
||||
|
||||
|
@ -100,19 +100,19 @@ std::string Bonus::Description(std::optional<si32> customValue) const
|
||||
switch(source)
|
||||
{
|
||||
case BonusSource::ARTIFACT:
|
||||
str << ArtifactID(sid).toArtifact(VLC->artifacts())->getNameTranslated();
|
||||
str << sid.as<ArtifactID>().toArtifact(VLC->artifacts())->getNameTranslated();
|
||||
break;
|
||||
case BonusSource::SPELL_EFFECT:
|
||||
str << SpellID(sid).toSpell(VLC->spells())->getNameTranslated();
|
||||
str << sid.as<SpellID>().toSpell(VLC->spells())->getNameTranslated();
|
||||
break;
|
||||
case BonusSource::CREATURE_ABILITY:
|
||||
str << CreatureID(sid).toCreature(VLC->creatures())->getNamePluralTranslated();
|
||||
str << sid.as<CreatureID>().toCreature(VLC->creatures())->getNamePluralTranslated();
|
||||
break;
|
||||
case BonusSource::SECONDARY_SKILL:
|
||||
str << VLC->skills()->getByIndex(sid)->getNameTranslated();
|
||||
str << VLC->skills()->getById(sid.as<SecondarySkill>())->getNameTranslated();
|
||||
break;
|
||||
case BonusSource::HERO_SPECIAL:
|
||||
str << VLC->heroTypes()->getByIndex(sid)->getNameTranslated();
|
||||
str << VLC->heroTypes()->getById(sid.as<HeroTypeID>())->getNameTranslated();
|
||||
break;
|
||||
default:
|
||||
//todo: handle all possible sources
|
||||
@ -158,8 +158,8 @@ JsonNode Bonus::toJsonNode() const
|
||||
root["sourceType"].String() = vstd::findKey(bonusSourceMap, source);
|
||||
if(targetSourceType != BonusSource::OTHER)
|
||||
root["targetSourceType"].String() = vstd::findKey(bonusSourceMap, targetSourceType);
|
||||
if(sid != 0)
|
||||
root["sourceID"].Integer() = sid;
|
||||
if(sid != TBonusSourceID::NONE)
|
||||
root["sourceID"].String() = sid.toString();
|
||||
if(val != 0)
|
||||
root["val"].Integer() = val;
|
||||
if(valType != BonusValueType::ADDITIVE_VALUE)
|
||||
@ -183,19 +183,19 @@ JsonNode Bonus::toJsonNode() const
|
||||
return root;
|
||||
}
|
||||
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID)
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID ID)
|
||||
: Bonus(Duration, Type, Src, Val, ID, TBonusSubtype::NONE, std::string())
|
||||
{}
|
||||
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc)
|
||||
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::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, TBonusSubtype Subtype)
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID ID, TBonusSubtype Subtype)
|
||||
: Bonus(Duration, Type, Src, Val, ID, Subtype, std::string())
|
||||
{}
|
||||
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, TBonusSubtype Subtype, std::string Desc):
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID ID, TBonusSubtype Subtype, std::string Desc):
|
||||
duration(Duration),
|
||||
type(Type),
|
||||
subtype(Subtype),
|
||||
@ -208,7 +208,7 @@ Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32
|
||||
targetSourceType = BonusSource::OTHER;
|
||||
}
|
||||
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 ID, TBonusSubtype Subtype, BonusValueType ValType):
|
||||
Bonus::Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID ID, TBonusSubtype Subtype, BonusValueType ValType):
|
||||
duration(Duration),
|
||||
type(Type),
|
||||
subtype(Subtype),
|
||||
@ -239,7 +239,7 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
|
||||
out << "\tSubtype: " << bonus.subtype.toString() << "\n";
|
||||
printField(duration.to_ulong());
|
||||
printField(source);
|
||||
printField(sid);
|
||||
out << "\tSource ID: " << bonus.sid.toString() << "\n";
|
||||
if(bonus.additionalInfo != CAddInfo::NONE)
|
||||
out << "\taddInfo: " << bonus.additionalInfo.toString() << "\n";
|
||||
printField(turnsRemain);
|
||||
|
@ -24,6 +24,7 @@ class BonusList;
|
||||
class CSelector;
|
||||
|
||||
using TBonusSubtype = MetaIdentifier;
|
||||
using TBonusSourceID = MetaIdentifier;
|
||||
using TBonusListPtr = std::shared_ptr<BonusList>;
|
||||
using TConstBonusListPtr = std::shared_ptr<const BonusList>;
|
||||
using TLimiterPtr = std::shared_ptr<ILimiter>;
|
||||
@ -62,7 +63,7 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
||||
BonusSource source = BonusSource::OTHER; //source type" uses BonusSource values - what gave that bonus
|
||||
BonusSource targetSourceType;//Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE.
|
||||
si32 val = 0;
|
||||
ui32 sid = 0; //source id: id of object/artifact/spell
|
||||
TBonusSourceID sid; //source id: id of object/artifact/spell
|
||||
BonusValueType valType = BonusValueType::ADDITIVE_VALUE;
|
||||
std::string stacking; // bonuses with the same stacking value don't stack (e.g. Angel/Archangel morale bonus)
|
||||
|
||||
@ -76,11 +77,11 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
||||
|
||||
std::string description;
|
||||
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 sourceID);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 sourceID, std::string Desc);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 sourceID, TBonusSubtype subtype);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 sourceID, TBonusSubtype subtype, std::string Desc);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, ui32 sourceID, TBonusSubtype subtype, BonusValueType ValType);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID sourceID);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID sourceID, std::string Desc);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID sourceID, TBonusSubtype subtype);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID sourceID, TBonusSubtype subtype, std::string Desc);
|
||||
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, TBonusSourceID sourceID, TBonusSubtype subtype, BonusValueType ValType);
|
||||
Bonus() = default;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -167,20 +168,6 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
||||
{
|
||||
val += Val;
|
||||
}
|
||||
STRONG_INLINE static ui32 getSid32(ui32 high, ui32 low)
|
||||
{
|
||||
return (high << 16) + low;
|
||||
}
|
||||
|
||||
STRONG_INLINE static ui32 getHighFromSid32(ui32 sid)
|
||||
{
|
||||
return sid >> 16;
|
||||
}
|
||||
|
||||
STRONG_INLINE static ui32 getLowFromSid32(ui32 sid)
|
||||
{
|
||||
return sid & 0x0000FFFF;
|
||||
}
|
||||
|
||||
std::string Description(std::optional<si32> customValue = {}) const;
|
||||
JsonNode toJsonNode() const;
|
||||
|
@ -66,10 +66,10 @@ namespace Selector
|
||||
.And(CSelectFieldEqual<CAddInfo>(&Bonus::additionalInfo)(info));
|
||||
}
|
||||
|
||||
CSelector DLL_LINKAGE source(BonusSource source, ui32 sourceID)
|
||||
CSelector DLL_LINKAGE source(BonusSource source, TBonusSourceID sourceID)
|
||||
{
|
||||
return CSelectFieldEqual<BonusSource>(&Bonus::source)(source)
|
||||
.And(CSelectFieldEqual<ui32>(&Bonus::sid)(sourceID));
|
||||
.And(CSelectFieldEqual<TBonusSourceID>(&Bonus::sid)(sourceID));
|
||||
}
|
||||
|
||||
CSelector DLL_LINKAGE sourceTypeSel(BonusSource source)
|
||||
|
@ -136,7 +136,7 @@ namespace Selector
|
||||
|
||||
CSelector DLL_LINKAGE typeSubtype(BonusType Type, TBonusSubtype Subtype);
|
||||
CSelector DLL_LINKAGE typeSubtypeInfo(BonusType type, TBonusSubtype subtype, const CAddInfo & info);
|
||||
CSelector DLL_LINKAGE source(BonusSource source, ui32 sourceID);
|
||||
CSelector DLL_LINKAGE source(BonusSource source, TBonusSourceID sourceID);
|
||||
CSelector DLL_LINKAGE sourceTypeSel(BonusSource source);
|
||||
CSelector DLL_LINKAGE valueType(BonusValueType valType);
|
||||
|
||||
|
@ -82,10 +82,10 @@ bool IBonusBearer::hasBonusOfType(BonusType type, TBonusSubtype subtype) const
|
||||
return hasBonus(s, cachingStr);
|
||||
}
|
||||
|
||||
bool IBonusBearer::hasBonusFrom(BonusSource source, ui32 sourceID) const
|
||||
bool IBonusBearer::hasBonusFrom(BonusSource source, TBonusSourceID sourceID) const
|
||||
{
|
||||
boost::format fmt("source_%did_%d");
|
||||
fmt % static_cast<int>(source) % sourceID;
|
||||
boost::format fmt("source_%did_%s");
|
||||
fmt % static_cast<int>(source) % sourceID.toString();
|
||||
|
||||
return hasBonus(Selector::source(source,sourceID), fmt.str());
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
bool hasBonusOfType(BonusType type) const;//determines if hero has a bonus of given type (and optionally subtype)
|
||||
int valOfBonuses(BonusType type, TBonusSubtype subtype) const; //subtype -> subtype of bonus;
|
||||
bool hasBonusOfType(BonusType type, TBonusSubtype subtype) const;//determines if hero has a bonus of given type (and optionally subtype)
|
||||
bool hasBonusFrom(BonusSource source, ui32 sourceID) const;
|
||||
bool hasBonusFrom(BonusSource source, TBonusSourceID sourceID) const;
|
||||
|
||||
virtual int64_t getTreeVersion() const = 0;
|
||||
};
|
||||
|
@ -303,10 +303,10 @@ ILimiter::EDecision FactionLimiter::limit(const BonusLimitationContext &context)
|
||||
switch(context.b.source)
|
||||
{
|
||||
case BonusSource::CREATURE_ABILITY:
|
||||
return bearer->getFaction() == CreatureID(context.b.sid).toCreature()->getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
return bearer->getFaction() == context.b.sid.as<CreatureID>().toCreature()->getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
|
||||
case BonusSource::TOWN_STRUCTURE:
|
||||
return bearer->getFaction() == FactionID(Bonus::getHighFromSid32(context.b.sid)) ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
return bearer->getFaction() == context.b.sid.as<BuildingTypeUniqueID>().getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
|
||||
//TODO: other sources of bonuses
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ public:
|
||||
BonusType type;
|
||||
TBonusSubtype subtype;
|
||||
BonusSource source;
|
||||
si32 sid;
|
||||
TBonusSourceID sid;
|
||||
bool isSubtypeRelevant; //check for subtype only if this is true
|
||||
bool isSourceRelevant; //check for bonus source only if this is true
|
||||
bool isSourceIDRelevant; //check for bonus source only if this is true
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
|
||||
enum class CampaignVersion : uint8_t
|
||||
{
|
||||
NONE = 0,
|
||||
@ -48,10 +50,4 @@ enum class CampaignBonusType : int8_t
|
||||
HERO
|
||||
};
|
||||
|
||||
enum class CampaignScenarioID : int8_t
|
||||
{
|
||||
NONE = -1,
|
||||
// no members - fake enum to create integer type that is not implicitly convertible to int
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
const CampaignScenarioID CampaignScenarioID::NONE(-1);
|
||||
const BattleID BattleID::NONE(-1);
|
||||
const QueryID QueryID::NONE(-1);
|
||||
const QueryID QueryID::CLIENT(-2);
|
||||
|
@ -157,11 +157,14 @@ public:
|
||||
using Identifier<BattleID>::Identifier;
|
||||
DLL_LINKAGE static const BattleID NONE;
|
||||
};
|
||||
class ObjectInstanceID : public Identifier<ObjectInstanceID>
|
||||
class DLL_LINKAGE ObjectInstanceID : public Identifier<ObjectInstanceID>
|
||||
{
|
||||
public:
|
||||
using Identifier<ObjectInstanceID>::Identifier;
|
||||
DLL_LINKAGE static const ObjectInstanceID NONE;
|
||||
static const ObjectInstanceID NONE;
|
||||
|
||||
static si32 decode(const std::string & identifier);
|
||||
static std::string encode(const si32 index);
|
||||
};
|
||||
|
||||
class HeroClassID : public Identifier<HeroClassID>
|
||||
@ -292,6 +295,8 @@ class SecondarySkill : public IdentifierWithEnum<SecondarySkill, SecondarySkillB
|
||||
public:
|
||||
using IdentifierWithEnum<SecondarySkill, SecondarySkillBase>::IdentifierWithEnum;
|
||||
static std::string entityType();
|
||||
static si32 decode(const std::string& identifier);
|
||||
static std::string encode(const si32 index);
|
||||
};
|
||||
|
||||
class DLL_LINKAGE PrimarySkill : public Identifier<PrimarySkill>
|
||||
@ -396,6 +401,10 @@ class BuildingID : public IdentifierWithEnum<BuildingID, BuildingIDBase>
|
||||
{
|
||||
public:
|
||||
using IdentifierWithEnum<BuildingID, BuildingIDBase>::IdentifierWithEnum;
|
||||
|
||||
DLL_LINKAGE static si32 decode(const std::string & identifier);
|
||||
DLL_LINKAGE static std::string encode(const si32 index);
|
||||
static std::string entityType();
|
||||
};
|
||||
|
||||
class ObjBase : public IdentifierBase
|
||||
@ -814,13 +823,13 @@ public:
|
||||
};
|
||||
|
||||
class BattleFieldInfo;
|
||||
class BattleField : public Identifier<BattleField>
|
||||
class DLL_LINKAGE BattleField : public Identifier<BattleField>
|
||||
{
|
||||
public:
|
||||
using Identifier<BattleField>::Identifier;
|
||||
|
||||
DLL_LINKAGE static const BattleField NONE;
|
||||
DLL_LINKAGE const BattleFieldInfo * getInfo() const;
|
||||
static const BattleField NONE;
|
||||
const BattleFieldInfo * getInfo() const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE BoatId : public Identifier<BoatId>
|
||||
@ -921,6 +930,25 @@ public:
|
||||
static std::string entityType();
|
||||
};
|
||||
|
||||
class BuildingTypeUniqueID : public Identifier<BuildingTypeUniqueID>
|
||||
{
|
||||
public:
|
||||
BuildingTypeUniqueID(FactionID faction, BuildingID building );
|
||||
|
||||
BuildingID getBuilding() const;
|
||||
FactionID getFaction() const;
|
||||
|
||||
using Identifier<BuildingTypeUniqueID>::Identifier;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CampaignScenarioID : public Identifier<CampaignScenarioID>
|
||||
{
|
||||
public:
|
||||
using Identifier<CampaignScenarioID>::Identifier;
|
||||
|
||||
static const CampaignScenarioID NONE;
|
||||
};
|
||||
|
||||
// Deprecated
|
||||
// TODO: remove
|
||||
using ETownType = FactionID;
|
||||
|
@ -20,16 +20,14 @@ MetaIdentifier::MetaIdentifier():
|
||||
{}
|
||||
|
||||
MetaIdentifier::MetaIdentifier(const std::string & entityType, const std::string & identifier)
|
||||
: entityType(entityType)
|
||||
, stringForm(identifier)
|
||||
: stringForm(identifier)
|
||||
, integerForm(-1)
|
||||
{
|
||||
onDeserialized();
|
||||
}
|
||||
|
||||
MetaIdentifier::MetaIdentifier(const std::string & entityType, const std::string & identifier, int32_t value)
|
||||
: entityType(entityType)
|
||||
, stringForm(identifier)
|
||||
: stringForm(identifier)
|
||||
, integerForm(value)
|
||||
{
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
/// This class represents field that may contain value of multiple different identifer types
|
||||
class DLL_LINKAGE MetaIdentifier
|
||||
{
|
||||
std::string entityType;
|
||||
std::string stringForm;
|
||||
int32_t integerForm;
|
||||
|
||||
@ -30,10 +29,8 @@ public:
|
||||
MetaIdentifier(const std::string & entityType, const std::string & identifier, int32_t value);
|
||||
|
||||
template<typename IdentifierType>
|
||||
explicit MetaIdentifier(const IdentifierType & identifier )
|
||||
: entityType(IdentifierType::entityType())
|
||||
, integerForm(identifier.getNum())
|
||||
, stringForm(IdentifierType::encode(identifier.getNum()))
|
||||
explicit MetaIdentifier(const IdentifierType & identifier)
|
||||
: integerForm(identifier.getNum())
|
||||
{
|
||||
static_assert(std::is_base_of<IdentifierBase, IdentifierType>::value, "MetaIdentifier can only be constructed from Identifer class");
|
||||
}
|
||||
@ -51,7 +48,7 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & stringForm;
|
||||
h & integerForm;
|
||||
|
||||
if (!h.saving)
|
||||
onDeserialized();
|
||||
|
@ -655,7 +655,7 @@ void CGameState::initGlobalBonuses()
|
||||
{
|
||||
auto bonus = JsonUtils::parseBonus(b.second);
|
||||
bonus->source = BonusSource::GLOBAL;//for all
|
||||
bonus->sid = -1; //there is one global object
|
||||
bonus->sid = TBonusSourceID::NONE; //there is one global object
|
||||
globalEffects.addNewBonus(bonus);
|
||||
}
|
||||
VLC->creh->loadCrExpBon(globalEffects);
|
||||
|
@ -314,8 +314,8 @@ void CGameStateCampaign::giveCampaignBonusToHero(CGHeroInstance * hero)
|
||||
if(val == 0)
|
||||
continue;
|
||||
|
||||
int currentScenario = static_cast<int>(*gameState->scenarioOps->campState->currentScenario());
|
||||
auto bb = std::make_shared<Bonus>( BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CAMPAIGN_BONUS, val, currentScenario, TBonusSubtype(g) );
|
||||
auto currentScenario = *gameState->scenarioOps->campState->currentScenario();
|
||||
auto bb = std::make_shared<Bonus>( BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CAMPAIGN_BONUS, val, TBonusSourceID(currentScenario), TBonusSubtype(g) );
|
||||
hero->addNewBonus(bb);
|
||||
}
|
||||
break;
|
||||
|
@ -50,7 +50,7 @@ void CRewardableConstructor::configureObject(CGObjectInstance * object, CRandomG
|
||||
for (auto & bonus : rewardInfo.reward.bonuses)
|
||||
{
|
||||
bonus.source = BonusSource::OBJECT;
|
||||
bonus.sid = rewardableObject->ID;
|
||||
bonus.sid = TBonusSourceID(rewardableObject->ID);
|
||||
}
|
||||
}
|
||||
assert(!rewardableObject->configuration.info.empty());
|
||||
|
@ -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, -1);
|
||||
b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, 0, TBonusSourceID::NONE);
|
||||
addNewBonus(b);
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
|
||||
//-1 modifier for any Undead unit in army
|
||||
const ui8 UNDEAD_MODIFIER_ID = -2;
|
||||
const TBonusSourceID UNDEAD_MODIFIER_ID( "", "", -2);
|
||||
auto undeadModifier = getExportedBonusList().getFirst(Selector::source(BonusSource::ARMY, UNDEAD_MODIFIER_ID));
|
||||
if(hasUndead)
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
gbonus.id = hero->id.getNum();
|
||||
gbonus.bonus.duration = BonusDuration::ONE_BATTLE;
|
||||
gbonus.bonus.source = BonusSource::OBJECT;
|
||||
gbonus.bonus.sid = ID;
|
||||
gbonus.bonus.sid = TBonusSourceID(ID);
|
||||
gbonus.bonus.type = BonusType::MORALE;
|
||||
gbonus.bonus.val = -1;
|
||||
switch (ID)
|
||||
@ -239,7 +239,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
case Obj::PYRAMID:
|
||||
{
|
||||
GiveBonus gb;
|
||||
gb.bonus = Bonus(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, -2, id.getNum(), VLC->generaltexth->arraytxt[70]);
|
||||
gb.bonus = Bonus(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, -2, TBonusSourceID(id), VLC->generaltexth->arraytxt[70]);
|
||||
gb.id = hero->id.getNum();
|
||||
cb->giveHeroBonus(&gb);
|
||||
textID = 107;
|
||||
|
@ -370,7 +370,7 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
|
||||
{
|
||||
auto bonus = JsonUtils::parseBonus(b.second);
|
||||
bonus->source = BonusSource::HERO_BASE_SKILL;
|
||||
bonus->sid = id.getNum();
|
||||
bonus->sid = TBonusSourceID(id);
|
||||
bonus->duration = BonusDuration::PERMANENT;
|
||||
addNewBonus(bonus);
|
||||
}
|
||||
@ -590,7 +590,7 @@ void CGHeroInstance::recreateSecondarySkillsBonuses()
|
||||
|
||||
void CGHeroInstance::updateSkillBonus(const SecondarySkill & which, int val)
|
||||
{
|
||||
removeBonuses(Selector::source(BonusSource::SECONDARY_SKILL, which));
|
||||
removeBonuses(Selector::source(BonusSource::SECONDARY_SKILL, TBonusSourceID(which)));
|
||||
auto skillBonus = (*VLC->skillh)[which]->at(val).effects;
|
||||
for(const auto & b : skillBonus)
|
||||
addNewBonus(std::make_shared<Bonus>(*b));
|
||||
@ -1014,7 +1014,7 @@ void CGHeroInstance::pushPrimSkill( PrimarySkill which, int val )
|
||||
if(hasBonus(sel))
|
||||
removeBonuses(sel);
|
||||
|
||||
addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::HERO_BASE_SKILL, val, id.getNum(), TBonusSubtype(which)));
|
||||
addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::HERO_BASE_SKILL, val, TBonusSourceID(id), TBonusSubtype(which)));
|
||||
}
|
||||
|
||||
EAlignment CGHeroInstance::getAlignment() const
|
||||
|
@ -222,7 +222,7 @@ void CGObjectInstance::giveDummyBonus(const ObjectInstanceID & heroID, BonusDura
|
||||
gbonus.id = heroID.getNum();
|
||||
gbonus.bonus.duration = duration;
|
||||
gbonus.bonus.source = BonusSource::OBJECT;
|
||||
gbonus.bonus.sid = ID;
|
||||
gbonus.bonus.sid = TBonusSourceID(ID);
|
||||
cb->giveHeroBonus(&gbonus);
|
||||
}
|
||||
|
||||
|
@ -227,11 +227,11 @@ void CGPandoraBox::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
int val;
|
||||
handler.serializeInt("morale", val, 0);
|
||||
if(val)
|
||||
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, id);
|
||||
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, TBonusSourceID(id));
|
||||
|
||||
handler.serializeInt("luck", val, 0);
|
||||
if(val)
|
||||
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, id);
|
||||
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, TBonusSourceID(id));
|
||||
|
||||
vinfo.reward.resources.serializeJson(handler, "resources");
|
||||
{
|
||||
|
@ -144,10 +144,10 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
|
||||
switch (this->bType)
|
||||
{
|
||||
case BuildingSubID::STABLES:
|
||||
if(!h->hasBonusFrom(BonusSource::OBJECT, Obj::STABLES)) //does not stack with advMap Stables
|
||||
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, Obj::STABLES, BonusSubtypes::heroMovementLand, VLC->generaltexth->arraytxt[100]);
|
||||
gb.bonus = Bonus(BonusDuration::ONE_WEEK, BonusType::MOVEMENT, BonusSource::OBJECT, 600, TBonusSourceID(Obj(Obj::STABLES)), BonusSubtypes::heroMovementLand, VLC->generaltexth->arraytxt[100]);
|
||||
gb.id = heroID.getNum();
|
||||
cb->giveHeroBonus(&gb);
|
||||
|
||||
@ -236,7 +236,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
|
||||
|
||||
case BuildingSubID::CUSTOM_VISITING_BONUS:
|
||||
const auto building = town->getTown()->buildings.at(bID);
|
||||
if(!h->hasBonusFrom(BonusSource::TOWN_STRUCTURE, Bonus::getSid32(building->town->faction->getIndex(), building->bid)))
|
||||
if(!h->hasBonusFrom(BonusSource::TOWN_STRUCTURE, TBonusSourceID(building->getUniqueTypeID())))
|
||||
{
|
||||
const auto & bonuses = building->onVisitBonuses;
|
||||
applyBonuses(const_cast<CGHeroInstance *>(h), bonuses);
|
||||
@ -307,7 +307,7 @@ void CTownRewardableBuilding::initObj(CRandomGenerator & rand)
|
||||
for (auto & bonus : rewardInfo.reward.bonuses)
|
||||
{
|
||||
bonus.source = BonusSource::TOWN_STRUCTURE;
|
||||
bonus.sid = bID;
|
||||
bonus.sid = TBonusSourceID(building->getUniqueTypeID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -394,7 +394,10 @@ bool CTownRewardableBuilding::wasVisitedBefore(const CGHeroInstance * contextHer
|
||||
case Rewardable::VISIT_PLAYER:
|
||||
return false; //not supported
|
||||
case Rewardable::VISIT_BONUS:
|
||||
return contextHero->hasBonusFrom(BonusSource::TOWN_STRUCTURE, Bonus::getSid32(town->town->faction->getIndex(), bID));
|
||||
{
|
||||
const auto building = town->getTown()->buildings.at(bID);
|
||||
return contextHero->hasBonusFrom(BonusSource::TOWN_STRUCTURE, TBonusSourceID(building->getUniqueTypeID()));
|
||||
}
|
||||
case Rewardable::VISIT_HERO:
|
||||
return visitors.find(contextHero->id) != visitors.end();
|
||||
case Rewardable::VISIT_LIMITER:
|
||||
|
@ -788,7 +788,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, -1);
|
||||
b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::MORALE, BonusSource::ARMY, 0, TBonusSourceID::NONE);
|
||||
addNewBonus(b);
|
||||
}
|
||||
|
||||
|
@ -676,9 +676,9 @@ void CGSeerHut::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
if(metaTypeName == "mana")
|
||||
reward.manaDiff = val;
|
||||
if(metaTypeName == "morale")
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, id);
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, TBonusSourceID(id));
|
||||
if(metaTypeName == "luck")
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, id);
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, TBonusSourceID(id));
|
||||
if(metaTypeName == "resource")
|
||||
{
|
||||
auto rawId = *VLC->identifiers()->getIdentifier(ModScope::scopeMap(), fullIdentifier, false);
|
||||
|
@ -197,7 +197,7 @@ bool CRewardableObject::wasVisitedBefore(const CGHeroInstance * contextHero) con
|
||||
case Rewardable::VISIT_PLAYER:
|
||||
return vstd::contains(cb->getPlayerState(contextHero->getOwner())->visitedObjects, ObjectInstanceID(id));
|
||||
case Rewardable::VISIT_BONUS:
|
||||
return contextHero->hasBonusFrom(BonusSource::OBJECT, ID);
|
||||
return contextHero->hasBonusFrom(BonusSource::OBJECT, TBonusSourceID(ID));
|
||||
case Rewardable::VISIT_HERO:
|
||||
return contextHero->visitedObjects.count(ObjectInstanceID(id));
|
||||
case Rewardable::VISIT_LIMITER:
|
||||
@ -234,7 +234,7 @@ bool CRewardableObject::wasVisited(const CGHeroInstance * h) const
|
||||
switch (configuration.visitMode)
|
||||
{
|
||||
case Rewardable::VISIT_BONUS:
|
||||
return h->hasBonusFrom(BonusSource::OBJECT, ID);
|
||||
return h->hasBonusFrom(BonusSource::OBJECT, TBonusSourceID(ID));
|
||||
case Rewardable::VISIT_HERO:
|
||||
return h->visitedObjects.count(ObjectInstanceID(id));
|
||||
case Rewardable::VISIT_LIMITER:
|
||||
|
@ -988,14 +988,14 @@ void CGSirens::initObj(CRandomGenerator & rand)
|
||||
|
||||
std::string CGSirens::getHoverText(const CGHeroInstance * hero) const
|
||||
{
|
||||
return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(BonusSource::OBJECT,ID));
|
||||
return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(BonusSource::OBJECT, TBonusSourceID(ID)));
|
||||
}
|
||||
|
||||
void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
if(h->hasBonusFrom(BonusSource::OBJECT,ID)) //has already visited Sirens
|
||||
if(h->hasBonusFrom(BonusSource::OBJECT, TBonusSourceID(ID))) //has already visited Sirens
|
||||
{
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT,133);
|
||||
@ -1180,8 +1180,8 @@ void CGLighthouse::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
RemoveBonus rb(GiveBonus::ETarget::PLAYER);
|
||||
rb.whoID = oldOwner.getNum();
|
||||
rb.source = vstd::to_underlying(BonusSource::OBJECT);
|
||||
rb.id = id.getNum();
|
||||
rb.source = BonusSource::OBJECT;
|
||||
rb.id = TBonusSourceID(id);
|
||||
cb->sendAndApply(&rb);
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1204,7 @@ void CGLighthouse::giveBonusTo(const PlayerColor & player, bool onInit) const
|
||||
gb.id = player.getNum();
|
||||
gb.bonus.duration = BonusDuration::PERMANENT;
|
||||
gb.bonus.source = BonusSource::OBJECT;
|
||||
gb.bonus.sid = id.getNum();
|
||||
gb.bonus.sid = TBonusSourceID(id);
|
||||
gb.bonus.subtype = BonusSubtypes::heroMovementSea;
|
||||
|
||||
// FIXME: This is really dirty hack
|
||||
|
@ -1040,9 +1040,9 @@ void CMapLoaderH3M::readBoxContent(CGPandoraBox * object, const int3 & mapPositi
|
||||
reward.heroExperience = reader->readUInt32();
|
||||
reward.manaDiff = reader->readInt32();
|
||||
if(auto val = reader->readUInt8())
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, idToBeGiven);
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, TBonusSourceID(idToBeGiven));
|
||||
if(auto val = reader->readUInt8())
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, idToBeGiven);
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, TBonusSourceID(idToBeGiven));
|
||||
|
||||
reader->readResourses(reward.resources);
|
||||
for(int x = 0; x < GameConstants::PRIMARY_SKILLS; ++x)
|
||||
@ -2008,12 +2008,12 @@ void CMapLoaderH3M::readSeerHutQuest(CGSeerHut * hut, const int3 & position, con
|
||||
}
|
||||
case ESeerHutRewardType::MORALE:
|
||||
{
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, reader->readUInt8(), idToBeGiven);
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, reader->readUInt8(), TBonusSourceID(idToBeGiven));
|
||||
break;
|
||||
}
|
||||
case ESeerHutRewardType::LUCK:
|
||||
{
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, reader->readUInt8(), idToBeGiven);
|
||||
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, reader->readUInt8(), TBonusSourceID(idToBeGiven));
|
||||
break;
|
||||
}
|
||||
case ESeerHutRewardType::RESOURCES:
|
||||
|
@ -312,7 +312,7 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "source_" << vstd::to_underlying(BonusSource::SPELL_EFFECT) << "id_" << owner->id.num;
|
||||
|
||||
if(parameters.caster->getHeroCaster()->getBonuses(Selector::source(BonusSource::SPELL_EFFECT, owner->id), Selector::all, cachingStr.str())->size() >= owner->getLevelPower(schoolLevel)) //limit casts per turn
|
||||
if(parameters.caster->getHeroCaster()->getBonuses(Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(owner->id)), Selector::all, cachingStr.str())->size() >= owner->getLevelPower(schoolLevel)) //limit casts per turn
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = parameters.caster->getCasterOwner();
|
||||
@ -324,7 +324,7 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
|
||||
|
||||
GiveBonus gb;
|
||||
gb.id = parameters.caster->getCasterUnitId();
|
||||
gb.bonus = Bonus(BonusDuration::ONE_DAY, BonusType::NONE, BonusSource::SPELL_EFFECT, 0, owner->id);
|
||||
gb.bonus = Bonus(BonusDuration::ONE_DAY, BonusType::NONE, BonusSource::SPELL_EFFECT, 0, TBonusSourceID(owner->id));
|
||||
env->apply(&gb);
|
||||
|
||||
if(!dest->isClear(curr)) //wrong dest tile
|
||||
|
@ -476,7 +476,7 @@ bool BattleSpellMechanics::counteringSelector(const Bonus * bonus) const
|
||||
|
||||
for(const SpellID & id : owner->counteredSpells)
|
||||
{
|
||||
if(bonus->sid == id.toEnum())
|
||||
if(bonus->sid.as<SpellID>() == id)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -925,7 +925,7 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode &
|
||||
auto b = JsonUtils::parseBonus(bonusNode);
|
||||
const bool usePowerAsValue = bonusNode["val"].isNull();
|
||||
|
||||
b->sid = spell->id; //for all
|
||||
b->sid = TBonusSourceID(spell->id); //for all
|
||||
b->source = BonusSource::SPELL_EFFECT;//for all
|
||||
|
||||
if(usePowerAsValue)
|
||||
@ -940,7 +940,7 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode &
|
||||
auto b = JsonUtils::parseBonus(bonusNode);
|
||||
const bool usePowerAsValue = bonusNode["val"].isNull();
|
||||
|
||||
b->sid = spell->id; //for all
|
||||
b->sid = TBonusSourceID(spell->id); //for all
|
||||
b->source = BonusSource::SPELL_EFFECT;//for all
|
||||
|
||||
if(usePowerAsValue)
|
||||
|
@ -490,11 +490,11 @@ bool BaseMechanics::adaptProblem(ESpellCastProblem source, Problem & target) con
|
||||
{
|
||||
//The %s prevents %s from casting 3rd level or higher spells.
|
||||
text.appendLocalString(EMetaText::GENERAL_TXT, 536);
|
||||
text.replaceLocalString(EMetaText::ART_NAMES, b->sid);
|
||||
text.replaceLocalString(EMetaText::ART_NAMES, b->sid.as<ArtifactID>());
|
||||
caster->getCasterName(text);
|
||||
target.add(std::move(text), spells::Problem::NORMAL);
|
||||
}
|
||||
else if(b && b->source == BonusSource::TERRAIN_OVERLAY && VLC->battlefields()->getByIndex(b->sid)->identifier == "cursed_ground")
|
||||
else if(b && b->source == BonusSource::TERRAIN_OVERLAY && VLC->battlefields()->getById(b->sid.as<BattleField>())->identifier == "cursed_ground")
|
||||
{
|
||||
text.appendLocalString(EMetaText::GENERAL_TXT, 537);
|
||||
target.add(std::move(text), spells::Problem::NORMAL);
|
||||
|
@ -260,7 +260,7 @@ public:
|
||||
builder << "source_" << vstd::to_underlying(BonusSource::SPELL_EFFECT) << "id_" << spellID.num;
|
||||
cachingString = builder.str();
|
||||
|
||||
selector = Selector::source(BonusSource::SPELL_EFFECT, spellID.num);
|
||||
selector = Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(spellID));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -94,7 +94,7 @@ void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
|
||||
SetStackEffect sse;
|
||||
sse.battleID = m->battle()->getBattle()->getBattleID();
|
||||
|
||||
Bonus lifeTimeMarker(BonusDuration::N_TURNS, BonusType::NONE, BonusSource::SPELL_EFFECT, 0, SpellID::CLONE); //TODO: use special bonus type
|
||||
Bonus lifeTimeMarker(BonusDuration::N_TURNS, BonusType::NONE, BonusSource::SPELL_EFFECT, 0, TBonusSourceID(SpellID(SpellID::CLONE))); //TODO: use special bonus type
|
||||
lifeTimeMarker.turnsRemain = m->getEffectDuration();
|
||||
std::vector<Bonus> buffer;
|
||||
buffer.push_back(lifeTimeMarker);
|
||||
|
@ -90,7 +90,7 @@ std::shared_ptr<const BonusList> Dispel::getBonuses(const Mechanics * m, const b
|
||||
{
|
||||
if(bonus->source == BonusSource::SPELL_EFFECT)
|
||||
{
|
||||
const Spell * sourceSpell = SpellID(bonus->sid).toSpell(m->spells());
|
||||
const Spell * sourceSpell = bonus->sid.as<SpellID>().toSpell(m->spells());
|
||||
if(!sourceSpell)
|
||||
return false;//error
|
||||
|
||||
|
@ -84,12 +84,12 @@ void Moat::convertBonus(const Mechanics * m, std::vector<Bonus> & converted) con
|
||||
|
||||
if(m->battle()->battleGetDefendedTown() && m->battle()->battleGetSiegeLevel() >= CGTownInstance::CITADEL)
|
||||
{
|
||||
nb.sid = Bonus::getSid32(m->battle()->battleGetDefendedTown()->getFaction(), BuildingID::CITADEL);
|
||||
nb.sid = TBonusSourceID(m->battle()->battleGetDefendedTown()->town->buildings.at(BuildingID::CITADEL)->getUniqueTypeID());
|
||||
nb.source = BonusSource::TOWN_STRUCTURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
nb.sid = m->getSpellIndex(); //for all
|
||||
nb.sid = TBonusSourceID(m->getSpellId()); //for all
|
||||
nb.source = BonusSource::SPELL_EFFECT;//for all
|
||||
}
|
||||
std::set<BattleHex> flatMoatHexes;
|
||||
|
@ -222,14 +222,14 @@ void Timed::convertBonus(const Mechanics * m, int32_t & duration, std::vector<Bo
|
||||
nb.turnsRemain = duration;
|
||||
vstd::amax(maxDuration, nb.turnsRemain);
|
||||
|
||||
nb.sid = m->getSpellIndex(); //for all
|
||||
nb.sid = TBonusSourceID(m->getSpellId()); //for all
|
||||
nb.source = BonusSource::SPELL_EFFECT;//for all
|
||||
|
||||
//fix to original config: shield should display damage reduction
|
||||
if((nb.sid == SpellID::SHIELD || nb.sid == SpellID::AIR_SHIELD) && (nb.type == BonusType::GENERAL_DAMAGE_REDUCTION))
|
||||
if((nb.sid.as<SpellID>() == SpellID::SHIELD || nb.sid.as<SpellID>() == SpellID::AIR_SHIELD) && (nb.type == BonusType::GENERAL_DAMAGE_REDUCTION))
|
||||
nb.val = 100 - nb.val;
|
||||
//we need to know who cast Bind
|
||||
else if(nb.sid == SpellID::BIND && nb.type == BonusType::BIND_EFFECT && m->caster->getHeroCaster() == nullptr)
|
||||
else if(nb.sid.as<SpellID>() == SpellID::BIND && nb.type == BonusType::BIND_EFFECT && m->caster->getHeroCaster() == nullptr)
|
||||
nb.additionalInfo = m->caster->getCasterUnitId();
|
||||
|
||||
converted.push_back(nb);
|
||||
|
@ -333,7 +333,7 @@ void RewardsWidget::saveCurrentVisitInfo(int index)
|
||||
auto dur = bonusDurationMap.at(ui->bonuses->item(i, 0)->text().toStdString());
|
||||
auto typ = bonusNameMap.at(ui->bonuses->item(i, 1)->text().toStdString());
|
||||
auto val = ui->bonuses->item(i, 2)->data(Qt::UserRole).toInt();
|
||||
vinfo.reward.bonuses.emplace_back(dur, typ, BonusSource::OBJECT, val, object.id);
|
||||
vinfo.reward.bonuses.emplace_back(dur, typ, BonusSource::OBJECT, val, TBonusSourceID(object.id));
|
||||
}
|
||||
|
||||
vinfo.limiter.dayOfWeek = ui->lDayOfWeek->currentIndex();
|
||||
|
@ -163,9 +163,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, -1, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::PERCENT_TO_ALL);
|
||||
Bonus bonus2(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, stack->valOfBonuses(BonusType::DEFENSIVE_STANCE), -1, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
|
||||
Bonus alternativeWeakCreatureBonus(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 1, -1, TBonusSubtype(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE);
|
||||
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);
|
||||
|
||||
BonusList defence = *stack->getBonuses(Selector::typeSubtype(BonusType::PRIMARY_SKILL, TBonusSubtype(PrimarySkill::DEFENSE)));
|
||||
int oldDefenceValue = defence.totalValue();
|
||||
|
@ -663,7 +663,7 @@ void BattleFlowProcessor::stackTurnTrigger(const CBattleInfoCallback & battle, c
|
||||
|
||||
if (st->hasBonusOfType(BonusType::POISON))
|
||||
{
|
||||
std::shared_ptr<const Bonus> b = st->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, SpellID::POISON).And(Selector::type()(BonusType::STACK_HEALTH)));
|
||||
std::shared_ptr<const Bonus> b = st->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT, TBonusSourceID(SpellID(SpellID::POISON))).And(Selector::type()(BonusType::STACK_HEALTH)));
|
||||
if (b) //TODO: what if not?...
|
||||
{
|
||||
bte.val = std::max (b->val - 10, -(st->valOfBonuses(BonusType::POISON)));
|
||||
|
@ -141,7 +141,7 @@ 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, 0);
|
||||
giveBonus.bonus = Bonus(BonusDuration::PERMANENT, BonusType::SPELLS_OF_LEVEL, BonusSource::OTHER, 0, TBonusSourceID::NONE);
|
||||
//start with level 0 to skip abilities
|
||||
for (int level = 1; level <= GameConstants::SPELL_LEVELS; level++)
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
|
||||
void makeWarMachine()
|
||||
{
|
||||
addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SIEGE_WEAPON, BonusSource::CREATURE_ABILITY, 1, 0));
|
||||
addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SIEGE_WEAPON, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID::NONE));
|
||||
}
|
||||
|
||||
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, 0));
|
||||
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit1.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
unit2.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::HYPNOTIZED, BonusSource::CREATURE_ABILITY, 0, TBonusSourceID::NONE));
|
||||
|
||||
setDefaultExpectations();
|
||||
|
||||
|
@ -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, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, UNIT_HEALTH, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 300, TBonusSourceID::NONE));
|
||||
|
||||
EXPECT_CALL(mock, unitBaseAmount()).WillRepeatedly(Return(1));
|
||||
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
void makeNormalCaster()
|
||||
{
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELLCASTER, BonusSource::CREATURE_ABILITY, DEFAULT_SCHOOL_LEVEL, 0, TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELLCASTER, BonusSource::CREATURE_ABILITY, DEFAULT_SCHOOL_LEVEL, TBonusSourceID::NONE, 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, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CASTS, BonusSource::CREATURE_ABILITY, 567, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_SPELL_POWER, BonusSource::CREATURE_ABILITY, EFFECT_POWER, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_ENCHANT_POWER, BonusSource::CREATURE_ABILITY, ENCHANT_POWER, TBonusSourceID::NONE));
|
||||
|
||||
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, 0, TBonusSubtype(SpellID(DEFAULT_SPELL_INDEX))));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPECIFIC_SPELL_POWER, BonusSource::CREATURE_ABILITY, EFFECT_VALUE, TBonusSourceID::NONE, 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, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CASTS, BonusSource::CREATURE_ABILITY, 1, TBonusSourceID::NONE));
|
||||
|
||||
initUnit();
|
||||
|
||||
|
@ -52,12 +52,12 @@ public:
|
||||
|
||||
void setDefaultExpectations()
|
||||
{
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACKS_SPEED, BonusSource::CREATURE_ABILITY, DEFAULT_SPEED, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACKS_SPEED, BonusSource::CREATURE_ABILITY, DEFAULT_SPEED, TBonusSourceID::NONE));
|
||||
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_ATTACK, 0, TBonusSubtype(PrimarySkill::ATTACK)));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::CREATURE_ABILITY, DEFAULT_DEFENCE, 0, TBonusSubtype(PrimarySkill::DEFENSE)));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::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::STACK_HEALTH, BonusSource::CREATURE_ABILITY, DEFAULT_HP, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, DEFAULT_HP, TBonusSourceID::NONE));
|
||||
|
||||
EXPECT_CALL(infoMock, unitBaseAmount()).WillRepeatedly(Return(DEFAULT_AMOUNT));
|
||||
EXPECT_CALL(infoMock, unitType()).WillRepeatedly(Return(pikeman));
|
||||
@ -67,8 +67,8 @@ public:
|
||||
|
||||
void makeShooter(int32_t ammo)
|
||||
{
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOOTER, BonusSource::CREATURE_ABILITY, 1, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SHOTS, BonusSource::CREATURE_ABILITY, ammo, 0));
|
||||
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));
|
||||
}
|
||||
|
||||
void initUnit()
|
||||
@ -180,7 +180,7 @@ TEST_F(UnitStateTest, attackWithFrenzy)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, TBonusSourceID::NONE));
|
||||
|
||||
int expectedAttack = static_cast<int>(DEFAULT_ATTACK + 0.5 * DEFAULT_DEFENCE);
|
||||
|
||||
@ -192,7 +192,7 @@ TEST_F(UnitStateTest, defenceWithFrenzy)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, 0));
|
||||
bonusMock.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::IN_FRENZY, BonusSource::SPELL_EFFECT, 50, TBonusSourceID::NONE));
|
||||
|
||||
int expectedDefence = 0;
|
||||
|
||||
@ -205,7 +205,7 @@ TEST_F(UnitStateTest, additionalAttack)
|
||||
setDefaultExpectations();
|
||||
|
||||
{
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, 0);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID::NONE);
|
||||
|
||||
bonusMock.addNewBonus(bonus);
|
||||
}
|
||||
@ -219,7 +219,7 @@ TEST_F(UnitStateTest, additionalMeleeAttack)
|
||||
setDefaultExpectations();
|
||||
|
||||
{
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, 0);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID::NONE);
|
||||
bonus->effectRange = BonusLimitEffect::ONLY_MELEE_FIGHT;
|
||||
|
||||
bonusMock.addNewBonus(bonus);
|
||||
@ -234,7 +234,7 @@ TEST_F(UnitStateTest, additionalRangedAttack)
|
||||
setDefaultExpectations();
|
||||
|
||||
{
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, 0);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::ADDITIONAL_ATTACK, BonusSource::SPELL_EFFECT, 41, TBonusSourceID::NONE);
|
||||
bonus->effectRange = BonusLimitEffect::ONLY_DISTANCE_FIGHT;
|
||||
|
||||
bonusMock.addNewBonus(bonus);
|
||||
@ -249,10 +249,10 @@ TEST_F(UnitStateTest, getMinDamage)
|
||||
setDefaultExpectations();
|
||||
|
||||
{
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, BonusSubtypes::creatureDamageBoth);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, TBonusSourceID::NONE, BonusSubtypes::creatureDamageBoth);
|
||||
bonusMock.addNewBonus(bonus);
|
||||
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, BonusSubtypes::creatureDamageMin);
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, TBonusSourceID::NONE, BonusSubtypes::creatureDamageMin);
|
||||
bonusMock.addNewBonus(bonus);
|
||||
}
|
||||
|
||||
@ -265,10 +265,10 @@ TEST_F(UnitStateTest, getMaxDamage)
|
||||
setDefaultExpectations();
|
||||
|
||||
{
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, 0, BonusSubtypes::creatureDamageBoth);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, 30, TBonusSourceID::NONE, BonusSubtypes::creatureDamageBoth);
|
||||
bonusMock.addNewBonus(bonus);
|
||||
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, 0, BonusSubtypes::creatureDamageMax);
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::CREATURE_DAMAGE, BonusSource::SPELL_EFFECT, -20, TBonusSourceID::NONE, BonusSubtypes::creatureDamageMax);
|
||||
bonusMock.addNewBonus(bonus);
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ TEST_F(CCreatureTest, JsonAddBonus)
|
||||
{
|
||||
JsonNode data(JsonNode::JsonType::DATA_STRUCT);
|
||||
|
||||
std::shared_ptr<Bonus> b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, 42, TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
|
||||
std::shared_ptr<Bonus> b = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, TBonusSourceID(CreatureID(42)), TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
|
||||
|
||||
JsonNode & toAdd = data["bonuses"]["toAdd"];
|
||||
|
||||
@ -121,7 +121,7 @@ TEST_F(CCreatureTest, JsonAddBonus)
|
||||
&& (bonus->type == BonusType::BLOCKS_RETALIATION)
|
||||
&& (bonus->source == BonusSource::CREATURE_ABILITY)
|
||||
&& (bonus->val == 17)
|
||||
&& (bonus->sid == 42)
|
||||
&& (bonus->sid.as<CreatureID>().getNum() == 42)
|
||||
&& (bonus->subtype.as<CreatureID>().getNum() == 43)
|
||||
&& (bonus->valType == BonusValueType::BASE_NUMBER);
|
||||
};
|
||||
@ -133,10 +133,10 @@ TEST_F(CCreatureTest, JsonRemoveBonus)
|
||||
{
|
||||
JsonNode data(JsonNode::JsonType::DATA_STRUCT);
|
||||
|
||||
std::shared_ptr<Bonus> b1 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, 42, TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
|
||||
std::shared_ptr<Bonus> b1 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 17, TBonusSourceID(CreatureID(42)), TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
|
||||
subject->addNewBonus(b1);
|
||||
|
||||
std::shared_ptr<Bonus> b2 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 18, 42, TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
|
||||
std::shared_ptr<Bonus> b2 = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::BLOCKS_RETALIATION, BonusSource::CREATURE_ABILITY, 18, TBonusSourceID(CreatureID(42)), TBonusSubtype(CreatureID(43)), BonusValueType::BASE_NUMBER);
|
||||
subject->addNewBonus(b2);
|
||||
|
||||
|
||||
@ -152,7 +152,7 @@ TEST_F(CCreatureTest, JsonRemoveBonus)
|
||||
&& (bonus->type == BonusType::BLOCKS_RETALIATION)
|
||||
&& (bonus->source == BonusSource::CREATURE_ABILITY)
|
||||
&& (bonus->val == 17)
|
||||
&& (bonus->sid == 42)
|
||||
&& (bonus->sid.as<CreatureID>().getNum() == 42)
|
||||
&& (bonus->subtype.as<CreatureID>().getNum() == 43)
|
||||
&& (bonus->valType == BonusValueType::BASE_NUMBER);
|
||||
};
|
||||
@ -165,7 +165,7 @@ TEST_F(CCreatureTest, JsonRemoveBonus)
|
||||
&& (bonus->type == BonusType::BLOCKS_RETALIATION)
|
||||
&& (bonus->source == BonusSource::CREATURE_ABILITY)
|
||||
&& (bonus->val == 18)
|
||||
&& (bonus->sid == 42)
|
||||
&& (bonus->sid.as<CreatureID>().getNum() == 42)
|
||||
&& (bonus->valType == BonusValueType::BASE_NUMBER);
|
||||
};
|
||||
|
||||
|
@ -56,7 +56,7 @@ TEST_F(AbilityCasterTest, MagicAbilityAffectedByGenericBonus)
|
||||
{
|
||||
EXPECT_CALL(spellMock, getLevel()).WillRepeatedly(Return(1));
|
||||
|
||||
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, TBonusSubtype(SpellSchool::ANY)));
|
||||
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::ANY)));
|
||||
|
||||
EXPECT_CALL(actualCaster, getAllBonuses(_, _, _, _)).Times(AtLeast(1));
|
||||
EXPECT_CALL(actualCaster, getTreeVersion()).Times(AtLeast(0));
|
||||
@ -70,7 +70,7 @@ TEST_F(AbilityCasterTest, MagicAbilityIngoresSchoolBonus)
|
||||
{
|
||||
EXPECT_CALL(spellMock, getLevel()).WillRepeatedly(Return(1));
|
||||
|
||||
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, TBonusSubtype(SpellSchool::AIR)));
|
||||
casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::AIR)));
|
||||
|
||||
EXPECT_CALL(actualCaster, getAllBonuses(_, _, _, _)).Times(AtLeast(1));
|
||||
EXPECT_CALL(actualCaster, getTreeVersion()).Times(AtLeast(0));
|
||||
|
@ -138,7 +138,7 @@ public:
|
||||
EXPECT_EQ(marker.duration, BonusDuration::N_TURNS);
|
||||
EXPECT_EQ(marker.turnsRemain, effectDuration);
|
||||
EXPECT_EQ(marker.source, BonusSource::SPELL_EFFECT);
|
||||
EXPECT_EQ(marker.sid, SpellID::CLONE);
|
||||
EXPECT_EQ(marker.sid, TBonusSourceID(SpellID(SpellID::CLONE)));
|
||||
}
|
||||
|
||||
void setDefaultExpectations()
|
||||
|
@ -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, 0));
|
||||
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
|
||||
EXPECT_CALL(targetUnit, unitId()).WillRepeatedly(Return(unitId));
|
||||
EXPECT_CALL(targetUnit, unitBaseAmount()).WillRepeatedly(Return(unitAmount));
|
||||
EXPECT_CALL(targetUnit, alive()).WillRepeatedly(Return(true));
|
||||
|
@ -74,7 +74,7 @@ TEST_F(DispelTest, ApplicableToAliveUnitWithTimedEffect)
|
||||
|
||||
auto & unit = unitsFake.add(BattleSide::ATTACKER);
|
||||
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, negativeID.toEnum()));
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, TBonusSourceID(SpellID(negativeID))));
|
||||
|
||||
EXPECT_CALL(unit, isValidTarget(Eq(false))).WillOnce(Return(true));
|
||||
|
||||
@ -101,7 +101,7 @@ TEST_F(DispelTest, IgnoresOwnEffects)
|
||||
}
|
||||
auto & unit = unitsFake.add(BattleSide::ATTACKER);
|
||||
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, neutralID.toEnum()));
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, TBonusSourceID(SpellID(neutralID))));
|
||||
|
||||
EXPECT_CALL(unit, isValidTarget(Eq(false))).Times(AtMost(1)).WillRepeatedly(Return(true));
|
||||
|
||||
@ -182,23 +182,23 @@ TEST_F(DispelApplyTest, RemovesEffects)
|
||||
EXPECT_CALL(unit1, unitId()).Times(AtLeast(1)).WillRepeatedly(Return(unitIds[1]));
|
||||
|
||||
{
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, negativeID.toEnum());
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, TBonusSourceID(negativeID));
|
||||
expectedBonus[0].emplace_back(*bonus);
|
||||
unit0.addNewBonus(bonus);
|
||||
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, negativeID.toEnum());
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 1, TBonusSourceID(negativeID));
|
||||
expectedBonus[0].emplace_back(*bonus);
|
||||
unit0.addNewBonus(bonus);
|
||||
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::N_TURNS, BonusType::GENERAL_ATTACK_REDUCTION, BonusSource::SPELL_EFFECT, 3, negativeID.toEnum());
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::N_TURNS, BonusType::GENERAL_ATTACK_REDUCTION, BonusSource::SPELL_EFFECT, 3, TBonusSourceID(negativeID));
|
||||
expectedBonus[0].emplace_back(*bonus);
|
||||
unit0.addNewBonus(bonus);
|
||||
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 5, positiveID.toEnum());
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::SPELL_EFFECT, 5, TBonusSourceID(positiveID));
|
||||
expectedBonus[1].emplace_back(*bonus);
|
||||
unit1.addNewBonus(bonus);
|
||||
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::N_TURNS, BonusType::GENERAL_ATTACK_REDUCTION, BonusSource::SPELL_EFFECT, 3, positiveID.toEnum());
|
||||
bonus = std::make_shared<Bonus>(BonusDuration::N_TURNS, BonusType::GENERAL_ATTACK_REDUCTION, BonusSource::SPELL_EFFECT, 3, TBonusSourceID(positiveID));
|
||||
expectedBonus[1].emplace_back(*bonus);
|
||||
unit1.addNewBonus(bonus);
|
||||
}
|
||||
|
@ -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, 0));
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 200, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
|
||||
|
||||
unitsFake.setDefaultBonusExpectations();
|
||||
|
||||
|
@ -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, 0));
|
||||
targetUnit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHP, TBonusSourceID::NONE));
|
||||
|
||||
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, 0));
|
||||
victim.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, victimUnitHP, TBonusSourceID::NONE));
|
||||
|
||||
EXPECT_CALL(*battleFake, setUnitState(Eq(unitId), _, Eq(expectedHealValue))).Times(1);
|
||||
|
||||
|
@ -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, 0));
|
||||
acquired->addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
unit.addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, unitHealth, TBonusSourceID::NONE));
|
||||
|
||||
{
|
||||
EXPECT_CALL(unit, acquire()).WillOnce(Return(acquired));
|
||||
|
@ -71,9 +71,9 @@ protected:
|
||||
|
||||
TEST_P(TimedApplyTest, ChangesBonuses)
|
||||
{
|
||||
Bonus testBonus1(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, 0, TBonusSubtype(PrimarySkill::KNOWLEDGE));
|
||||
Bonus testBonus1(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::KNOWLEDGE));
|
||||
|
||||
Bonus testBonus2(BonusDuration::N_TURNS, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, 0, TBonusSubtype(PrimarySkill::KNOWLEDGE));
|
||||
Bonus testBonus2(BonusDuration::N_TURNS, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 3, TBonusSourceID::NONE, TBonusSubtype(PrimarySkill::KNOWLEDGE));
|
||||
testBonus2.turnsRemain = 4;
|
||||
|
||||
JsonNode options(JsonNode::JsonType::DATA_STRUCT);
|
||||
@ -103,7 +103,7 @@ TEST_P(TimedApplyTest, ChangesBonuses)
|
||||
for(auto & bonus : expectedBonus)
|
||||
{
|
||||
bonus.source = BonusSource::SPELL_EFFECT;
|
||||
bonus.sid = spellIndex;
|
||||
bonus.sid = TBonusSourceID(SpellID(spellIndex));
|
||||
}
|
||||
|
||||
if(cumulative)
|
||||
|
@ -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, 0);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 3, TBonusSourceID::NONE);
|
||||
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, 0);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 5, TBonusSourceID::NONE);
|
||||
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, 0);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE);
|
||||
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, 0);
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE);
|
||||
unitBonuses.addNewBonus(bonus);
|
||||
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
TEST_P(AbsoluteSpellConditionTest, ChecksAbsoluteCase)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
|
||||
bonus->additionalInfo = 1;
|
||||
|
||||
unitBonuses.addNewBonus(bonus);
|
||||
@ -57,7 +57,7 @@ TEST_P(AbsoluteSpellConditionTest, ChecksAbsoluteCase)
|
||||
TEST_P(AbsoluteSpellConditionTest, IgnoresNormalCase)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
|
||||
unitBonuses.addNewBonus(bonus);
|
||||
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
|
@ -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, 0));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_DAMAGE_REDUCTION, BonusSource::OTHER, 100, TBonusSourceID::NONE));
|
||||
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, SpellSchool(SpellSchool::FIRE)));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::OTHER, 0, TBonusSourceID(SpellSchool::FIRE)));
|
||||
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ TEST_P(ElementalConditionTest, ReceptiveIfNoBonus)
|
||||
TEST_P(ElementalConditionTest, ImmuneIfBonusMatches)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::AIR)));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::AIR)));
|
||||
|
||||
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
@ -64,7 +64,7 @@ TEST_P(ElementalConditionTest, ImmuneIfBonusMatches)
|
||||
TEST_P(ElementalConditionTest, NotImmuneIfBonusMismatches)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::WATER)));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, TBonusSourceID::NONE, TBonusSubtype(SpellSchool::WATER)));
|
||||
|
||||
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
@ -72,7 +72,7 @@ TEST_P(ElementalConditionTest, NotImmuneIfBonusMismatches)
|
||||
TEST_P(ElementalConditionTest, DependsOnPositivness)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, 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)));
|
||||
|
||||
EXPECT_EQ(isPositive, subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
@ -80,8 +80,8 @@ TEST_P(ElementalConditionTest, DependsOnPositivness)
|
||||
TEST_P(ElementalConditionTest, ImmuneIfBothBonusesPresent)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_SCHOOL_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::AIR)));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATIVE_EFFECTS_IMMUNITY, BonusSource::SPELL_EFFECT, 0, 0, TBonusSubtype(SpellSchool::AIR)));
|
||||
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)));
|
||||
|
||||
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ TEST_P(ImmunityNegationConditionTest, WithHeroNegation)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, 0, BonusSubtypes::immunityEnemyHero));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, TBonusSourceID::NONE, BonusSubtypes::immunityEnemyHero));
|
||||
|
||||
EXPECT_EQ(isMagicalEffect, subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
@ -67,7 +67,7 @@ TEST_P(ImmunityNegationConditionTest, WithBattleWideNegation)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, 0, BonusSubtypes::immunityBattleWide));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::NEGATE_ALL_NATURAL_IMMUNITIES, BonusSource::OTHER, 0, TBonusSourceID::NONE, BonusSubtypes::immunityBattleWide));
|
||||
|
||||
//This should return if ownerMatches, because anyone should cast onto owner's stacks, but not on enemyStacks
|
||||
EXPECT_EQ(ownerMatches && isMagicalEffect, subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
|
@ -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, 0));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 3, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 5, TBonusSourceID::NONE));
|
||||
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, 0));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::LEVEL_SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE));
|
||||
if(isMagicalEffect)
|
||||
EXPECT_CALL(mechanicsMock, getSpellLevel()).Times(AtLeast(1)).WillRepeatedly(Return(2));
|
||||
EXPECT_EQ(!isMagicalEffect, subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
TEST_P(NormalSpellConditionTest, ChecksAbsoluteCase)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
|
||||
bonus->additionalInfo = 1;
|
||||
|
||||
unitBonuses.addNewBonus(bonus);
|
||||
@ -57,7 +57,7 @@ TEST_P(NormalSpellConditionTest, ChecksAbsoluteCase)
|
||||
TEST_P(NormalSpellConditionTest, ChecksNormalCase)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, 0, TBonusSubtype(SpellID(immuneSpell)));
|
||||
auto bonus = std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::SPELL_IMMUNITY, BonusSource::OTHER, 4, TBonusSourceID::NONE, TBonusSubtype(SpellID(immuneSpell)));
|
||||
unitBonuses.addNewBonus(bonus);
|
||||
if(immuneSpell == castSpell)
|
||||
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
|
@ -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, 0));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::RECEPTIVE, BonusSource::OTHER, 0, TBonusSourceID::NONE));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -45,7 +45,7 @@ TEST_F(SpellEffectConditionTest, ImmuneByDefault)
|
||||
TEST_F(SpellEffectConditionTest, ReceptiveIfHasEffectFromDesiredSpell)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::SPELL_EFFECT, 3, SpellID::AGE));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::SPELL_EFFECT, 3, TBonusSourceID(SpellID(SpellID::AGE))));
|
||||
|
||||
EXPECT_TRUE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
@ -53,14 +53,14 @@ TEST_F(SpellEffectConditionTest, ReceptiveIfHasEffectFromDesiredSpell)
|
||||
TEST_F(SpellEffectConditionTest, ImmuneIfHasEffectFromOtherSpell)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::SPELL_EFFECT, 3, SpellID::AIR_SHIELD));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::SPELL_EFFECT, 3, TBonusSourceID(SpellID(SpellID::AIR_SHIELD))));
|
||||
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
|
||||
TEST_F(SpellEffectConditionTest, ImmuneIfHasNoSpellEffects)
|
||||
{
|
||||
setDefaultExpectations();
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 3, 0));
|
||||
unitBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::STACK_HEALTH, BonusSource::CREATURE_ABILITY, 3, TBonusSourceID::NONE));
|
||||
EXPECT_FALSE(subject->isReceptive(&mechanicsMock, &unitMock));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user