1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

INVINCIBLE bonus

This commit is contained in:
Laserlicht 2024-09-19 03:14:45 +02:00
parent 110def5a1e
commit b36c05df1d
9 changed files with 38 additions and 2 deletions

View File

@ -662,5 +662,7 @@
"core.bonus.WIDE_BREATH.name": "Wide breath",
"core.bonus.WIDE_BREATH.description": "Wide breath attack (multiple hexes)",
"core.bonus.DISINTEGRATE.name": "Disintegrate",
"core.bonus.DISINTEGRATE.description": "No corpse remains after death"
"core.bonus.DISINTEGRATE.description": "No corpse remains after death",
"core.bonus.INVINCIBLE.name": "Invincible",
"core.bonus.INVINCIBLE.description": "Cannot be affected by anything"
}

View File

@ -600,6 +600,15 @@
"icon": "zvs/Lib1.res/DISINTEGRATE"
}
},
"INVINCIBLE":
{
"graphics":
{
"icon": "zvs/Lib1.res/INVINCIBLE"
}
}
}

View File

@ -10,6 +10,10 @@
"cavalryChargeImmunity" :
{
"type" : "CHARGE_IMMUNITY"
},
"invincible" :
{
"type" : "INVINCIBLE"
}
},
"graphics" :

View File

@ -1023,3 +1023,7 @@ Internal bonus, do not use
### DISINTEGRATE
After death of unit no corpse remains
### INVINCIBLE
Cannot be target of attacks and spells and cannot be affected by anything

View File

@ -296,6 +296,9 @@ std::vector<BattleHex> CStack::meleeAttackHexes(const battle::Unit * attacker, c
bool CStack::isMeleeAttackPossible(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos, BattleHex defenderPos)
{
if(defender->hasBonusOfType(BonusType::INVINCIBLE))
return false;
return !meleeAttackHexes(attacker, defender, attackerPos, defenderPos).empty();
}

View File

@ -685,6 +685,9 @@ bool CBattleInfoCallback::battleCanAttack(const battle::Unit * stack, const batt
if (!stack || !target)
return false;
if(target->hasBonusOfType(BonusType::INVINCIBLE))
return false;
if(!battleMatchOwner(stack, target))
return false;
@ -730,6 +733,9 @@ bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker, BattleHe
if(!attacker || !defender)
return false;
if(defender->hasBonusOfType(BonusType::INVINCIBLE))
return false;
if(battleMatchOwner(attacker, defender) && defender->alive())
{
if(battleCanShoot(attacker))

View File

@ -179,6 +179,7 @@ class JsonNode;
BONUS_NAME(RESOURCES_CONSTANT_BOOST) /*Bonus that does not account for propagation and gives extra resources per day. val - resource amount, subtype - resource type*/ \
BONUS_NAME(RESOURCES_TOWN_MULTIPLYING_BOOST) /*Bonus that does not account for propagation and gives extra resources per day with amount multiplied by number of owned towns. val - base resource amount to be multiplied times number of owned towns, subtype - resource type*/ \
BONUS_NAME(DISINTEGRATE) /* after death no corpse remains */ \
BONUS_NAME(INVINCIBLE) /* cannot be target of attacks and spells and cannot be affected by anything */ \
/* end of list */

View File

@ -228,8 +228,11 @@ bool BattleSpellMechanics::canBeCastAt(const Target & target, Problem & problem)
mainTarget = battle()->battleGetUnitByPos(target.front().hexValue, true);
}
if (mainTarget && mainTarget == caster)
if(mainTarget && mainTarget == caster)
return false; // can't cast on self
if(mainTarget && mainTarget->hasBonusOfType(BonusType::INVINCIBLE))
return false;
}
return effects->applicable(problem, this, target, spellTarget);

View File

@ -420,6 +420,10 @@ int64_t CSpell::adjustRawDamage(const spells::Caster * caster, const battle::Uni
ret *= 100 + bearer->valOfBonuses(BonusType::MORE_DAMAGE_FROM_SPELL, BonusSubtypeID(id));
ret /= 100;
}
//invincible
if(bearer->hasBonusOfType(BonusType::INVINCIBLE))
ret = 0;
}
ret = caster->getSpellBonus(this, ret, affectedCreature);
return ret;