1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Initial unconditionally working version

This commit is contained in:
Dydzio
2024-09-22 15:07:44 +02:00
parent 894c88defc
commit 1a2d349267
5 changed files with 92 additions and 21 deletions

View File

@@ -725,18 +725,48 @@ bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker) const
|| attacker->hasBonusOfType(BonusType::FREE_SHOOTING));
}
bool CBattleInfoCallback::battleCanTargetEmptyHex(const battle::Unit * attacker) const
{
RETURN_IF_NOT_BATTLE(false);
if(attacker->hasBonusOfType(BonusType::SPELL_LIKE_ATTACK))
{
auto bonus = attacker->getBonus(Selector::type()(BonusType::SPELL_LIKE_ATTACK));
const CSpell * spell = bonus->subtype.as<SpellID>().toSpell();
if(spell->isDamage())
{
spells::BattleCast cast(this, attacker, spells::Mode::SPELL_LIKE_ATTACK, spell);
if(vstd::find(spell->battleMechanics(&cast)->getTargetTypes(), spells::AimType::LOCATION) != spell->battleMechanics(&cast)->getTargetTypes().end())
{
return true;
}
}
}
return false;
}
bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker, BattleHex dest) const
{
RETURN_IF_NOT_BATTLE(false);
const battle::Unit * defender = battleGetUnitByPos(dest);
if(!attacker || !defender)
if(!attacker)
return false;
if(defender->hasBonusOfType(BonusType::INVINCIBLE))
return false;
bool emptyHexAreaAttack = battleCanTargetEmptyHex(attacker);
if(battleMatchOwner(attacker, defender) && defender->alive())
if(!emptyHexAreaAttack)
{
if(!defender)
return false;
if(defender->hasBonusOfType(BonusType::INVINCIBLE))
return false;
}
if(emptyHexAreaAttack || (battleMatchOwner(attacker, defender) && defender->alive()))
{
if(battleCanShoot(attacker))
{
@@ -747,7 +777,11 @@ bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker, BattleHe
}
int shootingRange = limitedRangeBonus->val;
return isEnemyUnitWithinSpecifiedRange(attacker->getPosition(), defender, shootingRange);
if(defender)
return isEnemyUnitWithinSpecifiedRange(attacker->getPosition(), defender, shootingRange);
else
return isHexWithinSpecifiedRange(attacker->getPosition(), dest, shootingRange);
}
}
@@ -1593,6 +1627,14 @@ bool CBattleInfoCallback::isEnemyUnitWithinSpecifiedRange(BattleHex attackerPosi
return false;
}
bool CBattleInfoCallback::isHexWithinSpecifiedRange(BattleHex attackerPosition, BattleHex targetPosition, unsigned int range) const
{
if(BattleHex::getDistance(attackerPosition, targetPosition) <= range)
return true;
return false;
}
BattleHex CBattleInfoCallback::wallPartToBattleHex(EWallPart part) const
{
RETURN_IF_NOT_BATTLE(BattleHex::INVALID);