From ab4418917a78551071c12e4c6b8ea7e462c0bf88 Mon Sep 17 00:00:00 2001 From: mateuszb Date: Thu, 24 Feb 2011 15:33:03 +0000 Subject: [PATCH] * artillery skill fixed --- CCallback.cpp | 4 ++-- lib/BattleState.cpp | 18 ++++++++++++------ lib/BattleState.h | 6 +++--- lib/NetPacks.h | 25 ++++++++++++++++--------- server/CGameHandler.cpp | 38 +++++++++++++++++++++----------------- 5 files changed, 54 insertions(+), 37 deletions(-) diff --git a/CCallback.cpp b/CCallback.cpp index 70a7f45f3..a5163a701 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -649,7 +649,7 @@ TDmgRange CBattleCallback::battleEstimateDamage(const CStack * attacker, const C defenderHero = gs->curB->heroes[0]; } - TDmgRange ret = gs->curB->calculateDmgRange(attacker, defender, attackerHero, defenderHero, shooting, 0, false); + TDmgRange ret = gs->curB->calculateDmgRange(attacker, defender, attackerHero, defenderHero, shooting, 0, false, false); if(retaliationDmg) { @@ -664,7 +664,7 @@ TDmgRange CBattleCallback::battleEstimateDamage(const CStack * attacker, const C { BattleStackAttacked bsa; bsa.damageAmount = ret.*pairElems[i]; - retaliationDmg->*pairElems[!i] = gs->curB->calculateDmgRange(defender, attacker, bsa.newAmount, attacker->count, attackerHero, defenderHero, false, false, false).*pairElems[!i]; + retaliationDmg->*pairElems[!i] = gs->curB->calculateDmgRange(defender, attacker, bsa.newAmount, attacker->count, attackerHero, defenderHero, false, false, false, false).*pairElems[!i]; } } } diff --git a/lib/BattleState.cpp b/lib/BattleState.cpp index 86a425d30..246abb34a 100644 --- a/lib/BattleState.cpp +++ b/lib/BattleState.cpp @@ -383,7 +383,7 @@ std::pair< std::vector, int > BattleInfo::getPath(THex start, THex dest, b return std::make_pair(path, dist[dest]); } -TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky ) const +TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg ) const { float additiveBonus=1.0f, multBonus=1.0f, minDmg = attacker->getMinDamage() * attackerCount, @@ -528,6 +528,12 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d additiveBonus += 1.0f; } + //ballista double dmg + if(ballistaDoubleDmg) + { + additiveBonus += 1.0f; + } + //handling spell effects if(!shooting && defender->hasBonusOfType(Bonus::GENERAL_DAMAGE_REDUCTION, 0)) //eg. shield { @@ -599,14 +605,14 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d return returnedVal; } -TDmgRange BattleInfo::calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const +TDmgRange BattleInfo::calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg) const { - return calculateDmgRange(attacker, defender, attacker->count, defender->count, attackerHero, defendingHero, shooting, charge, lucky); + return calculateDmgRange(attacker, defender, attacker->count, defender->count, attackerHero, defendingHero, shooting, charge, lucky, ballistaDoubleDmg); } -ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky ) +ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg ) { - TDmgRange range = calculateDmgRange(attacker, defender, attackerHero, defendingHero, shooting, charge, lucky); + TDmgRange range = calculateDmgRange(attacker, defender, attackerHero, defendingHero, shooting, charge, lucky, ballistaDoubleDmg); if(range.first != range.second) { @@ -2215,7 +2221,7 @@ void CStack::prepareAttacked(BattleStackAttacked &bsa) const if(count <= bsa.killedAmount) //stack killed { bsa.newAmount = 0; - bsa.flags |= 1; + bsa.flags |= BattleStackAttacked::KILLED; bsa.killedAmount = count; //we cannot kill more creatures than we have } else diff --git a/lib/BattleState.h b/lib/BattleState.h index 008008b95..31aa201c7 100644 --- a/lib/BattleState.h +++ b/lib/BattleState.h @@ -94,9 +94,9 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode bool isStackBlocked(const CStack * stack) const; //returns true if there is neighboring enemy stack - ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky); //charge - number of hexes travelled before attack (for champion's jousting) - TDmgRange calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair - TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair + ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg); //charge - number of hexes travelled before attack (for champion's jousting) + TDmgRange calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair + TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair void calculateCasualties(std::map *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount) std::set getAttackedCreatures(const CSpell * s, int skillLevel, ui8 attackerOwner, THex destinationTile); //calculates stack affected by given spell static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster, int usedSpellPower); diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 7ab903666..3e4d003c7 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1240,17 +1240,19 @@ struct BattleStackAttacked : public CPackForClient//3005 ui32 stackAttacked, attackerID; ui32 newAmount, newHP, killedAmount, damageAmount; - ui8 flags; //1 - is stack killed; 2 - is there special effect to be shown; - ui32 effect; //set only if flag 2 is present + enum EFlags {KILLED = 1, EFFECT = 2}; + ui8 flags; //uses EFlags (above) + ui32 effect; //set only if flag EFFECT is set std::vector healedStacks; //used when life drain + bool killed() const//if target stack was killed { - return flags & 1; + return flags & KILLED; } bool isEffect() const//if stack has been attacked by a spell { - return flags & 2; + return flags & EFFECT; } bool lifeDrain() const //if this attack involves life drain effect { @@ -1276,24 +1278,29 @@ struct BattleAttack : public CPackForClient//3006 std::vector bsa; ui32 stackAttacking; - ui8 flags; + ui8 flags; //usues Eflags (below) + enum EFlags{SHOT = 1, COUNTER = 2, LUCKY = 4, UNLUCKY = 8, BALLISTA_DOUBLE_DMG = 16}; bool shot() const//distance attack - decrease number of shots { - return flags & 1; + return flags & SHOT; } bool counter() const//is it counterattack? { - return flags & 2; + return flags & COUNTER; } bool lucky() const { - return flags & 4; + return flags & LUCKY; } bool unlucky() const { //TODO: support? - return flags & 8; + return flags & UNLUCKY; + } + bool ballistaDoubleDmg() const //if it's ballista attack and does double dmg + { + return flags & BALLISTA_DOUBLE_DMG; } //bool killed() //if target stack was killed //{ diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 03de2fc4c..35a881cc8 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -520,11 +520,21 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt if(!noLuck && attackerLuck > 0 && rand()%24 < attackerLuck) //TODO?: negative luck option? { - bsa->damageAmount *= 2; - bat.flags |= 4; + bat.flags |= BattleAttack::LUCKY; } - bsa->damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def), bat.shot(), distance, bat.lucky());//counting dealt damage + if(att->getCreature()->idNumber == 146) + { + static const int artilleryLvlToChance[] = {0, 50, 75, 100}; + const CGHeroInstance * owner = gs->curB->getHero(att->owner); + int chance = artilleryLvlToChance[owner->getSecSkillLevel(CGHeroInstance::ARTILLERY)]; + if(chance > rand() % 100) + { + bat.flags |= BattleAttack::BALLISTA_DOUBLE_DMG; + } + } + + bsa->damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def), bat.shot(), distance, bat.lucky(), bat.ballistaDoubleDmg());//counting dealt damage int dmg = bsa->damageAmount; @@ -559,7 +569,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt BattleStackAttacked *bsa = &bat.bsa.back(); bsa->stackAttacked = att->ID; bsa->attackerID = def->ID; - bsa->flags |= 2; + bsa->flags |= BattleStackAttacked::EFFECT; bsa->effect = 11; bsa->damageAmount = (dmg * def->valOfBonuses(Bonus::FIRE_SHIELD)) / 100; @@ -3212,7 +3222,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba ) && !stackAtEnd->hasBonusOfType(Bonus::HYPNOTIZED)) { prepareAttack(bat, stackAtEnd, curStack, 0); - bat.flags |= 2; + bat.flags |= BattleAttack::COUNTER; sendAndApply(&bat); handleAfterAttackCasting(bat); } @@ -3248,23 +3258,17 @@ bool CGameHandler::makeBattleAction( BattleAction &ba ) sendAndApply(&StartAction(ba)); //start shooting BattleAttack bat; - bat.flags |= 1; + bat.flags |= BattleAttack::SHOT; prepareAttack(bat, curStack, destStack, 0); sendAndApply(&bat); //ballista & artillery handling if(destStack->alive() && curStack->getCreature()->idNumber == 146) { - static const int artilleryLvlToChance[] = {0, 50, 75, 100}; - const CGHeroInstance * owner = gs->curB->getHero(curStack->owner); - int chance = artilleryLvlToChance[owner->getSecSkillLevel(CGHeroInstance::ARTILLERY)]; - if(chance > (rand() % 100)) - { - BattleAttack bat2; - bat2.flags |= 1; - prepareAttack(bat2, curStack, destStack, 0); - sendAndApply(&bat2); - } + BattleAttack bat2; + bat2.flags |= BattleAttack::SHOT; + prepareAttack(bat2, curStack, destStack, 0); + sendAndApply(&bat2); } if(curStack->valOfBonuses(Bonus::ADDITIONAL_ATTACK) > 0 //if unit shots twice let's make another shot @@ -3621,7 +3625,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio continue; BattleStackAttacked bsa; - bsa.flags |= 2; + bsa.flags |= BattleStackAttacked::EFFECT; bsa.effect = spell->mainEffectAnim; bsa.damageAmount = gs->curB->calculateSpellDmg(spell, caster, *it, spellLvl, usedSpellPower); bsa.stackAttacked = (*it)->ID;