mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
* new spells:
- precision - slayer * refactoring
This commit is contained in:
parent
8c6c0df45e
commit
b0e2d13b4e
@ -476,7 +476,7 @@ void CBattleLogic::MakeStatistics(int currentCreatureId)
|
|||||||
CGHeroInstance *attackerHero = (m_side)? m_hero1 : m_hero2;
|
CGHeroInstance *attackerHero = (m_side)? m_hero1 : m_hero2;
|
||||||
CGHeroInstance *defendingHero = (m_side)? m_hero2 : m_hero1;
|
CGHeroInstance *defendingHero = (m_side)? m_hero2 : m_hero1;
|
||||||
|
|
||||||
int attackDefenseBonus = currentStack->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0) - (st->creature->defence + (defendingHero ? defendingHero->getPrimSkillLevel(1) : 0));
|
int attackDefenseBonus = currentStack->Attack() - st->Defense();
|
||||||
float damageFactor = 1.0f;
|
float damageFactor = 1.0f;
|
||||||
if(attackDefenseBonus < 0) //decreasing dmg
|
if(attackDefenseBonus < 0) //decreasing dmg
|
||||||
{
|
{
|
||||||
|
158
CGameState.cpp
158
CGameState.cpp
@ -445,10 +445,8 @@ std::pair< std::vector<int>, int > BattleInfo::getPath(int start, int dest, bool
|
|||||||
|
|
||||||
CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
|
CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
|
||||||
:ID(I), creature(C), amount(A), baseAmount(A), firstHPleft(C->hitPoints), owner(O), slot(S), attackerOwned(AO), position(-1),
|
:ID(I), creature(C), amount(A), baseAmount(A), firstHPleft(C->hitPoints), owner(O), slot(S), attackerOwned(AO), position(-1),
|
||||||
counterAttacks(1), shots(C->shots), state(), effects()
|
counterAttacks(1), shots(C->shots), state(), effects(), speed(creature->speed), abilities(C->abilities), attack(C->attack), defense(C->defence)
|
||||||
{
|
{
|
||||||
speed = creature->speed;
|
|
||||||
abilities = C->abilities;
|
|
||||||
state.insert(ALIVE);
|
state.insert(ALIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,6 +527,54 @@ si8 CStack::Luck() const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
si32 CStack::Attack() const
|
||||||
|
{
|
||||||
|
si32 ret = attack; //value to be returned
|
||||||
|
|
||||||
|
if(getEffect(56)) //frenzy for attacker
|
||||||
|
{
|
||||||
|
ret += (VLC->spellh->spells[56].powers[getEffect(56)->level]/100.0) * defense;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getEffect(48)) //attacker's prayer handling
|
||||||
|
{
|
||||||
|
ret += VLC->spellh->spells[48].powers[getEffect(48)->level];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getEffect(45)) //weakness handling
|
||||||
|
{
|
||||||
|
ret -= VLC->spellh->spells[45].powers[getEffect(45)->level];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
si32 CStack::Defense() const
|
||||||
|
{
|
||||||
|
si32 ret = defense;
|
||||||
|
|
||||||
|
if(getEffect(56)) //frenzy for defender
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getEffect(48)) //defender's prayer handling
|
||||||
|
{
|
||||||
|
ret += VLC->spellh->spells[48].powers[getEffect(48)->level];
|
||||||
|
}
|
||||||
|
if(getEffect(47)) //defender's disrupting ray handling
|
||||||
|
{
|
||||||
|
int howMany = howManyEffectsSet(47);
|
||||||
|
ret -= VLC->spellh->spells[47].powers[getEffect(47)->level] * howMany;
|
||||||
|
}
|
||||||
|
if(getEffect(46)) //stone skin handling
|
||||||
|
{
|
||||||
|
ret += VLC->spellh->spells[46].powers[getEffect(46)->level];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool CStack::willMove()
|
bool CStack::willMove()
|
||||||
{
|
{
|
||||||
return !vstd::contains(state,DEFENDING)
|
return !vstd::contains(state,DEFENDING)
|
||||||
@ -1699,48 +1745,74 @@ bool CGameState::checkForVisitableDir(const int3 & src, const int3 & dst) const
|
|||||||
|
|
||||||
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
|
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
|
||||||
{
|
{
|
||||||
int attackerAttackBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0),
|
int attackDefenseBonus = attacker->Attack() - defender->Defense(),
|
||||||
defenderDefenseBonus = defender->creature->defence + (defendingHero ? defendingHero->getPrimSkillLevel(1) : 0),
|
|
||||||
attackDefenseBonus = 0,
|
|
||||||
minDmg = attacker->creature->damageMin * attacker->amount,
|
minDmg = attacker->creature->damageMin * attacker->amount,
|
||||||
maxDmg = attacker->creature->damageMax * attacker->amount;
|
maxDmg = attacker->creature->damageMax * attacker->amount;
|
||||||
|
|
||||||
//calculating total attack/defense skills modifier
|
//calculating total attack/defense skills modifier
|
||||||
if(attacker->getEffect(56)) //frenzy for attacker
|
|
||||||
{
|
|
||||||
attackerAttackBonus += (VLC->spellh->spells[56].powers[attacker->getEffect(56)->level]/100.0) *(attacker->creature->defence + (attackerHero ? attackerHero->getPrimSkillLevel(1) : 0));
|
|
||||||
}
|
|
||||||
if(defender->getEffect(56)) //frenzy for defender
|
|
||||||
{
|
|
||||||
defenderDefenseBonus = 0;
|
|
||||||
}
|
|
||||||
attackDefenseBonus = attackerAttackBonus - defenderDefenseBonus;
|
|
||||||
if(defender->getEffect(48)) //defender's prayer handling
|
|
||||||
{
|
|
||||||
attackDefenseBonus -= VLC->spellh->spells[48].powers[defender->getEffect(48)->level];
|
|
||||||
}
|
|
||||||
if(attacker->getEffect(48)) //attacker's prayer handling
|
|
||||||
{
|
|
||||||
attackDefenseBonus += VLC->spellh->spells[48].powers[attacker->getEffect(48)->level];
|
|
||||||
}
|
|
||||||
if(defender->getEffect(47)) //defender's disrupting ray handling
|
|
||||||
{
|
|
||||||
int howMany = defender->howManyEffectsSet(47);
|
|
||||||
attackDefenseBonus += VLC->spellh->spells[47].powers[attacker->getEffect(47)->level] * howMany;
|
|
||||||
}
|
|
||||||
if(defender->getEffect(46)) //stone skin handling
|
|
||||||
{
|
|
||||||
attackDefenseBonus -= VLC->spellh->spells[46].powers[defender->getEffect(46)->level];
|
|
||||||
}
|
|
||||||
if(attacker->getEffect(45)) //weakness handling
|
|
||||||
{
|
|
||||||
attackDefenseBonus -= VLC->spellh->spells[45].powers[attacker->getEffect(45)->level];
|
|
||||||
}
|
|
||||||
if(!shooting && attacker->getEffect(43)) //bloodlust handling
|
if(!shooting && attacker->getEffect(43)) //bloodlust handling
|
||||||
{
|
{
|
||||||
attackDefenseBonus += VLC->spellh->spells[43].powers[attacker->getEffect(43)->level];
|
attackDefenseBonus += VLC->spellh->spells[43].powers[attacker->getEffect(43)->level];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(shooting && attacker->getEffect(44)) //precision handling
|
||||||
|
{
|
||||||
|
attackDefenseBonus += VLC->spellh->spells[44].powers[attacker->getEffect(44)->level];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(attacker->getEffect(55)) //slayer handling
|
||||||
|
{
|
||||||
|
std::vector<int> affectedIds;
|
||||||
|
switch(attacker->getEffect(55)->level)
|
||||||
|
{
|
||||||
|
case 3: //expert
|
||||||
|
{
|
||||||
|
affectedIds.push_back(40); //giant
|
||||||
|
affectedIds.push_back(41); //titan
|
||||||
|
affectedIds.push_back(152); //lord of thunder
|
||||||
|
} //continue adding ...
|
||||||
|
case 2: //advanced
|
||||||
|
{
|
||||||
|
affectedIds.push_back(12); //angel
|
||||||
|
affectedIds.push_back(13); //archangel
|
||||||
|
affectedIds.push_back(54); //devil
|
||||||
|
affectedIds.push_back(55); //arch devil
|
||||||
|
affectedIds.push_back(150); //supreme archangel
|
||||||
|
affectedIds.push_back(153); //antichrist
|
||||||
|
} //continue adding ...
|
||||||
|
case 0: case 1: //none and basic
|
||||||
|
{
|
||||||
|
affectedIds.push_back(26); //green dragon
|
||||||
|
affectedIds.push_back(27); //gold dragon
|
||||||
|
affectedIds.push_back(82); //red dragon
|
||||||
|
affectedIds.push_back(83); //black dragon
|
||||||
|
affectedIds.push_back(96); //behemot
|
||||||
|
affectedIds.push_back(97); //ancient behemot
|
||||||
|
affectedIds.push_back(110); //hydra
|
||||||
|
affectedIds.push_back(111); //chaos hydra
|
||||||
|
affectedIds.push_back(132); //azure dragon
|
||||||
|
affectedIds.push_back(133); //crystal dragon
|
||||||
|
affectedIds.push_back(134); //faerie dragon
|
||||||
|
affectedIds.push_back(135); //rust dragon
|
||||||
|
affectedIds.push_back(151); //diamond dragon
|
||||||
|
affectedIds.push_back(154); //blood dragon
|
||||||
|
affectedIds.push_back(155); //darkness dragon
|
||||||
|
affectedIds.push_back(156); //ghost behemot
|
||||||
|
affectedIds.push_back(157); //hell hydra
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int g=0; g<affectedIds.size(); ++g)
|
||||||
|
{
|
||||||
|
if(defender->creature->idNumber == affectedIds[g])
|
||||||
|
{
|
||||||
|
attackDefenseBonus += VLC->spellh->spells[55].powers[attacker->getEffect(55)->level];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float dmgBonusMultiplier = 1.0f;
|
float dmgBonusMultiplier = 1.0f;
|
||||||
|
|
||||||
//bonus from attack/defense skills
|
//bonus from attack/defense skills
|
||||||
@ -1819,26 +1891,18 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
|
|||||||
//handling spell effects
|
//handling spell effects
|
||||||
if(!shooting && defender->getEffect(27)) //shield
|
if(!shooting && defender->getEffect(27)) //shield
|
||||||
{
|
{
|
||||||
if(defender->getEffect(27)->level<=1) //none or basic
|
dmgBonusMultiplier *= float(VLC->spellh->spells[27].powers[attacker->getEffect(27)->level]) / 100.0f;
|
||||||
dmgBonusMultiplier *= 0.85f;
|
|
||||||
else //adv or expert
|
|
||||||
dmgBonusMultiplier *= 0.7f;
|
|
||||||
}
|
}
|
||||||
else if(shooting && defender->getEffect(28)) //air shield
|
else if(shooting && defender->getEffect(28)) //air shield
|
||||||
{
|
{
|
||||||
if(defender->getEffect(28)->level<=1) //none or basic
|
dmgBonusMultiplier *= float(VLC->spellh->spells[28].powers[attacker->getEffect(28)->level]) / 100.0f;
|
||||||
dmgBonusMultiplier *= 0.75f;
|
|
||||||
else //adv or expert
|
|
||||||
dmgBonusMultiplier *= 0.5f;
|
|
||||||
}
|
}
|
||||||
if(attacker->getEffect(42)) //curse handling (partial, the rest is below)
|
if(attacker->getEffect(42)) //curse handling (partial, the rest is below)
|
||||||
{
|
{
|
||||||
if(attacker->getEffect(42)->level>=2) //adv or expert
|
dmgBonusMultiplier *= 0.8f * float(VLC->spellh->spells[42].powers[attacker->getEffect(42)->level]); //the second factor is 1 or 0
|
||||||
dmgBonusMultiplier *= 0.8f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
minDmg *= dmgBonusMultiplier;
|
minDmg *= dmgBonusMultiplier;
|
||||||
maxDmg *= dmgBonusMultiplier;
|
maxDmg *= dmgBonusMultiplier;
|
||||||
|
|
||||||
|
20
CGameState.h
20
CGameState.h
@ -151,7 +151,9 @@ public:
|
|||||||
ui16 position; //position on battlefield
|
ui16 position; //position on battlefield
|
||||||
ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
|
ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
|
||||||
si16 shots; //how many shots left
|
si16 shots; //how many shots left
|
||||||
ui8 speed;
|
ui8 speed; //speed of stack with hero bonus
|
||||||
|
si32 attack; //attack of stack with hero bonus
|
||||||
|
si32 defense; //defense of stack with hero bonus
|
||||||
si8 morale, luck; //base stack luck/morale
|
si8 morale, luck; //base stack luck/morale
|
||||||
|
|
||||||
std::set<EAbilities> abilities;
|
std::set<EAbilities> abilities;
|
||||||
@ -168,14 +170,16 @@ public:
|
|||||||
};
|
};
|
||||||
std::vector<StackEffect> effects;
|
std::vector<StackEffect> effects;
|
||||||
|
|
||||||
CStack(CCreature * C, int A, int O, int I, bool AO, int S);
|
CStack(CCreature * C, int A, int O, int I, bool AO, int S); //c-tor
|
||||||
CStack() : ID(-1), creature(NULL), amount(-1), baseAmount(-1), firstHPleft(-1), owner(255), slot(255), attackerOwned(true), position(-1), counterAttacks(1), abilities(), state(), effects() {}
|
CStack() : ID(-1), creature(NULL), amount(-1), baseAmount(-1), firstHPleft(-1), owner(255), slot(255), attackerOwned(true), position(-1), counterAttacks(1), abilities(), state(), effects() {} //c-tor
|
||||||
const StackEffect * getEffect(ui16 id) const; //effect id (SP)
|
const StackEffect * getEffect(ui16 id) const; //effect id (SP)
|
||||||
ui8 howManyEffectsSet(ui16 id) const; //returns amount of effects with given id set for this stack
|
ui8 howManyEffectsSet(ui16 id) const; //returns amount of effects with given id set for this stack
|
||||||
bool willMove(); //if stack has remaining move this turn
|
bool willMove(); //if stack has remaining move this turn
|
||||||
ui32 Speed() const;
|
ui32 Speed() const; //get speed of creature with all modificators
|
||||||
si8 Morale() const;
|
si8 Morale() const; //get morale of stack with all modificators
|
||||||
si8 Luck() const;
|
si8 Luck() const; //get luck of stack with all modificators
|
||||||
|
si32 Attack() const; //get attack of stack with all modificators
|
||||||
|
si32 Defense() const; //get defense of stack with all modificators
|
||||||
template <typename Handler> void save(Handler &h, const int version)
|
template <typename Handler> void save(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & creature->idNumber;
|
h & creature->idNumber;
|
||||||
@ -190,13 +194,13 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & ID & amount & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
|
h & ID & amount & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
|
||||||
& shots & morale & luck & speed;
|
& shots & morale & luck & speed & attack & defense;
|
||||||
if(h.saving)
|
if(h.saving)
|
||||||
save(h,version);
|
save(h,version);
|
||||||
else
|
else
|
||||||
load(h,version);
|
load(h,version);
|
||||||
}
|
}
|
||||||
bool alive() const
|
bool alive() const //determines if stack is alive
|
||||||
{
|
{
|
||||||
return vstd::contains(state,ALIVE);
|
return vstd::contains(state,ALIVE);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
41 1 36 0 0 0 X
|
41 1 36 0 0 0 X
|
||||||
42 -1 40 0 0 0 X
|
42 -1 40 0 0 0 X
|
||||||
43 1 4 0 0 0 X
|
43 1 4 0 0 0 X
|
||||||
44 1 -1 0 0 0 X
|
44 1 25 0 0 0 X
|
||||||
45 -1 56 0 0 0 X
|
45 -1 56 0 0 0 X
|
||||||
46 1 54 0 0 0 X
|
46 1 54 0 0 0 X
|
||||||
47 -1 14 0 0 0 X
|
47 -1 14 0 0 0 X
|
||||||
@ -55,7 +55,7 @@
|
|||||||
52 -1 48 0 0 0 X
|
52 -1 48 0 0 0 X
|
||||||
53 1 31 0 0 0 X
|
53 1 31 0 0 0 X
|
||||||
54 -1 19 0 0 0 X
|
54 -1 19 0 0 0 X
|
||||||
55 1 -1 0 0 0 0
|
55 1 28 0 0 0 0
|
||||||
56 1 17 0 0 0 0
|
56 1 17 0 0 0 0
|
||||||
57 -1 -1 0 0 0 0
|
57 -1 -1 0 0 0 0
|
||||||
58 1 -1 0 0 0 X
|
58 1 -1 0 0 0 X
|
||||||
|
@ -835,6 +835,8 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
|||||||
//TODO: check if terrain is native, add bonuses for neutral stacks, bonuses from town
|
//TODO: check if terrain is native, add bonuses for neutral stacks, bonuses from town
|
||||||
stacks.back()->morale = hero1->getCurrentMorale(i->first,false);
|
stacks.back()->morale = hero1->getCurrentMorale(i->first,false);
|
||||||
stacks.back()->luck = hero1->getCurrentLuck(i->first,false);
|
stacks.back()->luck = hero1->getCurrentLuck(i->first,false);
|
||||||
|
stacks.back()->attack += hero1->getPrimSkillLevel(0);
|
||||||
|
stacks.back()->defense += hero1->getPrimSkillLevel(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -884,6 +886,8 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
|||||||
stacks.back()->speed += hero2->valOfBonuses(HeroBonus::STACKS_SPEED);
|
stacks.back()->speed += hero2->valOfBonuses(HeroBonus::STACKS_SPEED);
|
||||||
stacks.back()->morale = hero2->getCurrentMorale(i->first,false);
|
stacks.back()->morale = hero2->getCurrentMorale(i->first,false);
|
||||||
stacks.back()->luck = hero2->getCurrentLuck(i->first,false);
|
stacks.back()->luck = hero2->getCurrentLuck(i->first,false);
|
||||||
|
stacks.back()->attack += hero2->getPrimSkillLevel(0);
|
||||||
|
stacks.back()->defense += hero2->getPrimSkillLevel(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2455,6 +2459,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
case 41: //bless
|
case 41: //bless
|
||||||
case 42: //curse
|
case 42: //curse
|
||||||
case 43: //bloodlust
|
case 43: //bloodlust
|
||||||
|
case 44: //precision
|
||||||
case 45: //weakness
|
case 45: //weakness
|
||||||
case 46: //stone skin
|
case 46: //stone skin
|
||||||
case 47: //disrupting ray
|
case 47: //disrupting ray
|
||||||
@ -2465,6 +2470,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
case 52: //misfortune
|
case 52: //misfortune
|
||||||
case 53: //haste
|
case 53: //haste
|
||||||
case 54: //slow
|
case 54: //slow
|
||||||
|
case 55: //slayer
|
||||||
case 61: //forgetfulness
|
case 61: //forgetfulness
|
||||||
{
|
{
|
||||||
SetStackEffect sse;
|
SetStackEffect sse;
|
||||||
|
Loading…
Reference in New Issue
Block a user