1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

* artillery skill fixed

This commit is contained in:
mateuszb 2011-02-24 15:33:03 +00:00
parent ba7eb6ce49
commit ab4418917a
5 changed files with 54 additions and 37 deletions

View File

@ -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];
}
}
}

View File

@ -383,7 +383,7 @@ std::pair< std::vector<THex>, 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

View File

@ -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 <min dmg, max dmg>
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 <min dmg, max dmg>
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 <min dmg, max dmg>
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 <min dmg, max dmg>
void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount)
std::set<CStack*> 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);

View File

@ -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<StacksHealedOrResurrected> 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<BattleStackAttacked> 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
//{

View File

@ -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;