1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

First version of sea witch / sorceress ability

This commit is contained in:
Dydzio 2024-01-07 19:20:32 +01:00
parent b32c7beb05
commit bb925e4cb0
4 changed files with 71 additions and 9 deletions

View File

@ -791,7 +791,7 @@ void BattleInterface::waitForAnimations()
}
assert(!hasAnimations());
assert(awaitingEvents.empty());
//assert(awaitingEvents.empty());
if (!awaitingEvents.empty())
{

View File

@ -57,7 +57,7 @@ class JsonNode;
BONUS_NAME(MAGIC_RESISTANCE) /*in % (value)*/ \
BONUS_NAME(CHANGES_SPELL_COST_FOR_ALLY) /*in mana points (value) , eg. mage*/ \
BONUS_NAME(CHANGES_SPELL_COST_FOR_ENEMY) /*in mana points (value) , eg. pegasus */ \
BONUS_NAME(SPELL_AFTER_ATTACK) /* subtype - spell id, value - chance %, addInfo[0] - level, addInfo[1] -> [0 - all attacks, 1 - shot only, 2 - melee only] */ \
BONUS_NAME(SPELL_AFTER_ATTACK) /* subtype - spell id, value - chance %, addInfo[0] - level, addInfo[1] -> [0 - all attacks, 1 - shot only, 2 - melee only], addInfo[2] -> backup spell layer (default none [-1]) */ \
BONUS_NAME(SPELL_BEFORE_ATTACK) /* subtype - spell id, value - chance %, addInfo[0] - level, addInfo[1] -> [0 - all attacks, 1 - shot only, 2 - melee only] */ \
BONUS_NAME(SPELL_RESISTANCE_AURA) /*eg. unicorns, value - resistance bonus in % for adjacent creatures*/ \
BONUS_NAME(LEVEL_SPELL_IMMUNITY) /*creature is immune to all spell with level below or equal to value of this bonus */ \

View File

@ -1119,19 +1119,81 @@ void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const
handleAfterAttackCasting(battle, ranged, attacker, defender);
}
void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bool ranged, BonusType attackMode, const battle::Unit * attacker, const battle::Unit * defender)
void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bool ranged, BonusType attackMode, const battle::Unit * attacker, const CStack * defender)
{
if(attacker->hasBonusOfType(attackMode))
{
std::set<SpellID> spellsToCast;
TConstBonusListPtr spells = attacker->getBonuses(Selector::type()(attackMode));
for(const auto & sf : *spells)
std::array<std::vector<std::shared_ptr<Bonus>>, 6> spellsWithBackupLayers =
{
if (sf->subtype.as<SpellID>() != SpellID())
spellsToCast.insert(sf->subtype.as<SpellID>());
else
logMod->error("Invalid spell to cast during attack!");
{
std::vector<std::shared_ptr<Bonus>>(),
std::vector<std::shared_ptr<Bonus>>(),
std::vector<std::shared_ptr<Bonus>>(),
std::vector<std::shared_ptr<Bonus>>(),
std::vector<std::shared_ptr<Bonus>>(),
std::vector<std::shared_ptr<Bonus>>()
}
};
int lastBackupLayer = -1;
for(int i = 0; i < spells->size(); i++)
{
std::shared_ptr<Bonus> bonus = spells->operator[](i);
int layer = bonus->additionalInfo[2];
vstd::abetween(layer, -1, 4);
spellsWithBackupLayers[layer+1].push_back(bonus);
if(layer > lastBackupLayer)
lastBackupLayer = layer;
}
auto addSpellsFromLayer = [&](int layer) -> void
{
if(layer + 1 >= spellsWithBackupLayers.size() )
{
logMod->error(std::string("Wrong layer in addSpellsFromLayer: ") + std::to_string(layer));
return;
}
for(const auto & spell : spellsWithBackupLayers[layer+1])
{
if (spell->subtype.as<SpellID>() != SpellID())
spellsToCast.insert(spell->subtype.as<SpellID>());
else
logMod->error("Invalid spell to cast during attack!");
}
};
addSpellsFromLayer(-1);
for(int spellLayer = 0; spellLayer <= lastBackupLayer; spellLayer++)
{
if(spellsWithBackupLayers[spellLayer+1].empty())
continue;
if(spellLayer < lastBackupLayer)
{
bool areCurrentLayerSpellsApplied = std::all_of(spellsWithBackupLayers[spellLayer+1].begin(), spellsWithBackupLayers[spellLayer+1].end(),
[&](const std::shared_ptr<Bonus> spell)
{
std::vector<SpellID> activeSpells = defender->activeSpells();
auto spellIterator = vstd::find(activeSpells, spell->subtype.as<SpellID>());
bool value = spellIterator != activeSpells.end();
return value;
});
if(areCurrentLayerSpellsApplied)
continue;
}
addSpellsFromLayer(spellLayer);
break;
}
for(SpellID spellID : spellsToCast)
{
bool castMe = false;

View File

@ -44,7 +44,7 @@ class BattleActionProcessor : boost::noncopyable
void handleAttackBeforeCasting(const CBattleInfoCallback & battle, bool ranged, const CStack * attacker, const CStack * defender);
void handleAfterAttackCasting(const CBattleInfoCallback & battle, bool ranged, const CStack * attacker, const CStack * defender);
void attackCasting(const CBattleInfoCallback & battle, bool ranged, BonusType attackMode, const battle::Unit * attacker, const battle::Unit * defender);
void attackCasting(const CBattleInfoCallback & battle, bool ranged, BonusType attackMode, const battle::Unit * attacker, const CStack * defender);
// damage, drain life & fire shield; returns amount of drained life
int64_t applyBattleEffects(const CBattleInfoCallback & battle, BattleAttack & bat, std::shared_ptr<battle::CUnitState> attackerState, FireShieldInfo & fireShield, const CStack * def, int distance, bool secondary);