mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
vcmi: skill-agnostic artillery
Now it should work for any creature and with any damage percentage.
This commit is contained in:
parent
9205ef2c91
commit
64ad7558c6
@ -581,13 +581,13 @@
|
||||
"base" : {
|
||||
"effects" : {
|
||||
"main" : {
|
||||
"subtype" : "skill.artillery",
|
||||
"type" : "SECONDARY_SKILL_PREMY",
|
||||
"subtype" : "creature.ballista",
|
||||
"type" : "BONUS_DAMAGE_CHANCE",
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"val2" : {
|
||||
"subtype" : "skill.artillery",
|
||||
"type" : "SECONDARY_SKILL_VAL2",
|
||||
"subtype" : "creature.ballista",
|
||||
"type" : "HERO_GRANTS_ATTACKS",
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"ctrl" : {
|
||||
@ -601,6 +601,12 @@
|
||||
"type" : "MANUAL_CONTROL",
|
||||
"val" : 100,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
},
|
||||
"damagePower" : {
|
||||
"subtype" : "creature.ballista",
|
||||
"type" : "BONUS_DAMAGE_PERCENTAGE",
|
||||
"val" : 100,
|
||||
"valueType" : "BASE_NUMBER"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -317,7 +317,7 @@ public:
|
||||
BONUS_NAME(CATAPULT_EXTRA_SHOTS) /*val - power of catapult effect, requires CATAPULT bonus to work*/\
|
||||
BONUS_NAME(RANGED_RETALIATION) /*allows shooters to perform ranged retaliation*/\
|
||||
BONUS_NAME(BLOCKS_RANGED_RETALIATION) /*disallows ranged retaliation for shooter unit, BLOCKS_RETALIATION bonus is for melee retaliation only*/\
|
||||
BONUS_NAME(SECONDARY_SKILL_VAL2) /*for secondary skills that have multiple effects, like eagle eye (max level and chance)*/ \
|
||||
BONUS_NAME(SECONDARY_SKILL_VAL2) /*deprecated. has no effect, will be converted to actual bonus*/ \
|
||||
BONUS_NAME(MANUAL_CONTROL) /* manually control warmachine with id = subtype, chance = val */ \
|
||||
BONUS_NAME(WIDE_BREATH) /* initial desigh: dragon breath affecting multiple nearby hexes */\
|
||||
BONUS_NAME(FIRST_STRIKE) /* first counterattack, then attack if possible */\
|
||||
@ -342,7 +342,10 @@ public:
|
||||
BONUS_NAME(BEFORE_BATTLE_REPOSITION_BLOCK) /*skill-agnostic tactics, bonus for blocking opposite tactics. For now donble side tactics is TODO.*/\
|
||||
BONUS_NAME(HERO_EXPERIENCE_GAIN_PERCENT) /*skill-agnostic learning, and we can use it as a global effect also*/\
|
||||
BONUS_NAME(UNDEAD_RAISE_PERCENTAGE) /*Percentage of killed enemy creatures to be raised after battle as undead*/\
|
||||
BONUS_NAME(MANA_PER_KNOWLEDGE) /*Rate of translating hero knowledge to mana, used for intelligence and as a global bonus*/\
|
||||
BONUS_NAME(MANA_PER_KNOWLEDGE) /*Percentage rate of translating 10 hero knowledge to mana, used to intelligence and global bonus*/\
|
||||
BONUS_NAME(HERO_GRANTS_ATTACKS) /*If hero can grant additional attacks to creature, value is number of attacks, subtype is creatureID*/\
|
||||
BONUS_NAME(BONUS_DAMAGE_PERCENTAGE) /*If hero can grant conditional damage to creature, value is percentage, subtype is creatureID*/\
|
||||
BONUS_NAME(BONUS_DAMAGE_CHANCE) /*If hero can grant additional damage to creature, value is chance, subtype is creatureID*/\
|
||||
/* end of list */
|
||||
|
||||
|
||||
|
@ -229,8 +229,11 @@ double DamageCalculator::getAttackDeathBlowFactor() const
|
||||
|
||||
double DamageCalculator::getAttackDoubleDamageFactor() const
|
||||
{
|
||||
if(info.doubleDamage)
|
||||
return 1.0;
|
||||
if(info.doubleDamage) {
|
||||
const auto cachingStr = "type_BONUS_DAMAGE_PERCENTAGEs_" + std::to_string(info.attacker->creatureIndex());
|
||||
const auto selector = Selector::typeSubtype(Bonus::BONUS_DAMAGE_PERCENTAGE, info.attacker->creatureIndex());
|
||||
return info.attacker->valOfBonuses(selector, cachingStr) / 100.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
@ -1050,14 +1050,12 @@ void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender,
|
||||
bat.flags |= BattleAttack::DEATH_BLOW;
|
||||
}
|
||||
|
||||
if (attacker->getCreature()->idNumber == CreatureID::BALLISTA)
|
||||
const auto * owner = gs->curB->getHero(attacker->owner);
|
||||
if(owner)
|
||||
{
|
||||
const CGHeroInstance * owner = gs->curB->getHero(attacker->owner);
|
||||
int chance = owner->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::ARTILLERY);
|
||||
int chance = owner->valOfBonuses(Bonus::BONUS_DAMAGE_CHANCE, attacker->creatureIndex());
|
||||
if (chance > getRandomGenerator().nextInt(99))
|
||||
{
|
||||
bat.flags |= BattleAttack::BALLISTA_DOUBLE_DMG;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t drainedLife = 0;
|
||||
@ -4748,6 +4746,14 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
|
||||
//attack
|
||||
int totalAttacks = stack->totalAttacks.getMeleeValue();
|
||||
|
||||
//TODO: move to CUnitState
|
||||
const auto * attackingHero = gs->curB->battleGetFightingHero(ba.side);
|
||||
if(attackingHero)
|
||||
{
|
||||
totalAttacks += attackingHero->valOfBonuses(Bonus::HERO_GRANTS_ATTACKS, stack->creatureIndex());
|
||||
}
|
||||
|
||||
|
||||
const bool firstStrike = destinationStack->hasBonusOfType(Bonus::FIRST_STRIKE);
|
||||
const bool retaliation = destinationStack->ableToRetaliate();
|
||||
for (int i = 0; i < totalAttacks; ++i)
|
||||
@ -4824,26 +4830,18 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
|
||||
{
|
||||
makeAttack(destinationStack, stack, 0, stack->getPosition(), true, true, true);
|
||||
}
|
||||
|
||||
//TODO: move to CUnitState
|
||||
//extra shot(s) for ballista, based on artillery skill
|
||||
if(stack->creatureIndex() == CreatureID::BALLISTA)
|
||||
{
|
||||
const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side);
|
||||
|
||||
if(attackingHero)
|
||||
{
|
||||
int ballistaBonusAttacks = attackingHero->valOfBonuses(Bonus::SECONDARY_SKILL_VAL2, SecondarySkill::ARTILLERY);
|
||||
while(destinationStack->alive() && ballistaBonusAttacks-- > 0)
|
||||
{
|
||||
makeAttack(stack, destinationStack, 0, destination, false, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//allow more than one additional attack
|
||||
|
||||
int totalRangedAttacks = stack->totalAttacks.getRangedValue();
|
||||
|
||||
//TODO: move to CUnitState
|
||||
const auto * attackingHero = gs->curB->battleGetFightingHero(ba.side);
|
||||
if(attackingHero)
|
||||
{
|
||||
totalRangedAttacks += attackingHero->valOfBonuses(Bonus::HERO_GRANTS_ATTACKS, stack->creatureIndex());
|
||||
}
|
||||
|
||||
|
||||
for(int i = 1; i < totalRangedAttacks; ++i)
|
||||
{
|
||||
if(
|
||||
|
Loading…
Reference in New Issue
Block a user