diff --git a/config/skills.json b/config/skills.json index 57e208159..46c867ffb 100644 --- a/config/skills.json +++ b/config/skills.json @@ -666,5 +666,81 @@ } ] } + }, + "tactics" : { + "basic" : { + "description" : "", + "effects" : [ + { + "subtype" : "skill.tactics", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 3, + "valueType" : "BASE_NUMBER" + } + ] + }, + "advanced" : { + "description" : "", + "effects" : [ + { + "subtype" : "skill.tactics", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 5, + "valueType" : "BASE_NUMBER" + } + ] + }, + "expert" : { + "description" : "", + "effects" : [ + { + "subtype" : "skill.tactics", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 7, + "valueType" : "BASE_NUMBER" + } + ] + } + }, + "artillery" : { + "basic" : { + "description" : "", + "effects" : [ + { + "subtype" : "skill.artillery", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 50, + "valueType" : "BASE_NUMBER" + } + ] + }, + "advanced" : { + "description" : "", + "effects" : [ + { + "subtype" : "skill.artillery", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 75, + "valueType" : "BASE_NUMBER" + }, + { + "subtype" : "skill.artillery", + "type" : "SECONDARY_SKILL_VAL2", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ] + }, + "expert" : { + "description" : "", + "effects" : [ + { + "subtype" : "skill.artillery", + "type" : "SECONDARY_SKILL_PREMY", + "val" : 100, + "valueType" : "BASE_NUMBER" + } + ] + } } } diff --git a/lib/CSkillHandler.cpp b/lib/CSkillHandler.cpp index 236a033a9..412aa2cc1 100644 --- a/lib/CSkillHandler.cpp +++ b/lib/CSkillHandler.cpp @@ -256,6 +256,10 @@ std::vector> CSkillHandler::defaultBonus(SecondarySkill s addBonus(1 + level); break; case SecondarySkill::TACTICS: addBonus(1 + 2 * level); break; + case SecondarySkill::ARTILLERY: + addBonus(25 + 25 * level); break; + if(level > 1) // extra attack + addBonus(1, Bonus::SECONDARY_SKILL_VAL2); case SecondarySkill::LEARNING: addBonus(5 * level); break; case SecondarySkill::OFFENCE: diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 760990510..6071bc092 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -880,9 +880,8 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt if (att->getCreature()->idNumber == CreatureID::BALLISTA) { - static const int artilleryLvlToChance[] = {0, 50, 75, 100}; const CGHeroInstance * owner = gs->curB->getHero(att->owner); - int chance = artilleryLvlToChance[owner->getSecSkillLevel(SecondarySkill::ARTILLERY)]; + int chance = owner->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::ARTILLERY); if (chance > getRandomGenerator().nextInt(99)) { bat.flags |= BattleAttack::BALLISTA_DOUBLE_DMG; @@ -4007,19 +4006,18 @@ bool CGameHandler::makeBattleAction(BattleAction &ba) handleAfterAttackCasting(bat); } - //second shot for ballista, only if hero has advanced artillery - - const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side); - - if(destinationStack->alive() - && (stack->getCreature()->idNumber == CreatureID::BALLISTA) - && (attackingHero->getSecSkillLevel(SecondarySkill::ARTILLERY) >= SecSkillLevel::ADVANCED) - ) + //extra shot(s) for ballista, based on artillery skill + if(stack->getCreature()->idNumber == CreatureID::BALLISTA) { - BattleAttack bat2; - bat2.flags |= BattleAttack::SHOT; - prepareAttack(bat2, stack, destinationStack, 0, ba.destinationTile); - sendAndApply(&bat2); + const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side); + int ballistaBonusAttacks = attackingHero->valOfBonuses(Bonus::SECONDARY_SKILL_VAL2, SecondarySkill::ARTILLERY); + while(destinationStack->alive() && ballistaBonusAttacks-- > 0) + { + BattleAttack bat2; + bat2.flags |= BattleAttack::SHOT; + prepareAttack(bat2, stack, destinationStack, 0, ba.destinationTile); + sendAndApply(&bat2); + } } //allow more than one additional attack