1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* new spells:

- precision
- slayer
* refactoring
This commit is contained in:
mateuszb 2009-05-01 13:42:41 +00:00
parent 8c6c0df45e
commit b0e2d13b4e
5 changed files with 132 additions and 58 deletions

View File

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

View File

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

View File

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

View File

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

View File

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