1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-29 23:07:48 +02:00

Merge branch 'vcmi:develop' into max_range_spell

This commit is contained in:
Laserlicht
2025-07-03 23:25:06 +02:00
committed by GitHub
212 changed files with 26922 additions and 9310 deletions

View File

@@ -244,7 +244,7 @@ int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti)
}
CGHeroInstance::CGHeroInstance(IGameInfoCallback * cb)
: CArmedInstance(cb),
: CArmedInstance(cb, BonusNodeType::HERO, false),
CArtifactSet(cb),
tacticFormationEnabled(false),
inTownGarrison(false),
@@ -259,7 +259,6 @@ CGHeroInstance::CGHeroInstance(IGameInfoCallback * cb)
turnInfoCache(std::make_unique<TurnInfoCache>(this)),
manaPerKnowledgeCached(this, Selector::type()(BonusType::MANA_PER_KNOWLEDGE_PERCENTAGE))
{
setNodeType(HERO);
ID = Obj::HERO;
secSkills.emplace_back(SecondarySkill::NONE, -1);
}
@@ -913,22 +912,7 @@ void CGHeroInstance::spendMana(ServerCallback * server, const int spellCost) con
bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const
{
const bool isAllowed = cb->isAllowed(spell->getId());
const bool inSpellBook = vstd::contains(spells, spell->getId()) && hasSpellbook();
const bool specificBonus = hasBonusOfType(BonusType::SPELL, BonusSubtypeID(spell->getId()));
bool schoolBonus = false;
spell->forEachSchool([this, &schoolBonus](const SpellSchool & cnf, bool & stop)
{
if(hasBonusOfType(BonusType::SPELLS_OF_SCHOOL, BonusSubtypeID(cnf)))
{
schoolBonus = stop = true;
}
});
const bool levelBonus = hasBonusOfType(BonusType::SPELLS_OF_LEVEL, BonusCustomSubtype::spellLevel(spell->getLevel()));
const bool inSpellBook = spellbookContainsSpell(spell->getId()) && hasSpellbook();
if(spell->isSpecial())
{
@@ -936,9 +920,9 @@ bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const
{//hero has this spell in spellbook
logGlobal->error("Special spell %s in spellbook.", spell->getNameTranslated());
}
return specificBonus;
return hasBonusOfType(BonusType::SPELL, BonusSubtypeID(spell->getId()));
}
else if(!isAllowed)
else if(!cb->isAllowed(spell->getId()))
{
if(inSpellBook)
{
@@ -946,12 +930,8 @@ bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const
//it is normal if set in map editor, but trace it to possible debug of magic guild
logGlobal->trace("Banned spell %s in spellbook.", spell->getNameTranslated());
}
return inSpellBook || specificBonus || schoolBonus || levelBonus;
}
else
{
return inSpellBook || schoolBonus || specificBonus || levelBonus;
}
return !getSourcesForSpell(spell->getId()).empty();
}
bool CGHeroInstance::canLearnSpell(const spells::Spell * spell, bool allowBanned) const
@@ -1265,6 +1245,29 @@ bool CGHeroInstance::spellbookContainsSpell(const SpellID & spell) const
return vstd::contains(spells, spell);
}
std::vector<BonusSourceID> CGHeroInstance::getSourcesForSpell(const SpellID & spellId) const
{
std::vector<BonusSourceID> sources;
if(hasSpellbook() && spellbookContainsSpell(spellId))
sources.emplace_back(getArt(ArtifactPosition::SPELLBOOK)->getId());
for(const auto & bonus : *getBonusesOfType(BonusType::SPELL, spellId))
sources.emplace_back(bonus->sid);
const auto spell = spellId.toSpell();
spell->forEachSchool([this, &sources](const SpellSchool & cnf, bool & stop)
{
for(const auto & bonus : *getBonusesOfType(BonusType::SPELLS_OF_SCHOOL, cnf))
sources.emplace_back(bonus->sid);
});
for(const auto & bonus : *getBonusesOfType(BonusType::SPELLS_OF_LEVEL, BonusCustomSubtype::spellLevel(spell->getLevel())))
sources.emplace_back(bonus->sid);
return sources;
}
void CGHeroInstance::removeSpellbook()
{
spells.clear();