|
|
 |
 |
 |
 |
|
 |
 |
|
 |
 |
|
 |
|
 |
|
 |

07-09-2010, 12:49 AM
|
Dragon
|
|
Join Date: May 2009
Location: Milky Way
Posts: 539
|
|
COMMITTED: Spell & DoT Shielding
This also includes a fix for the spell rune effects( Bulwark of Alendar) as they were incorrectly also reducing the damage on DoTs.
edit... this didnt fix the problem with spell runes.
edit2... also doesnt seem to apply properly to DoTs and DD, just does the highest one to both(yay for testing at cap for both stats). its late so will fix tomorrow
code...
mob.h - alter this - line 842
Code:
sint32 ReduceMagicalDamage(sint32 damage);
to this
Code:
sint32 ReduceMagicalDamage(sint32 damage, int16 spell_id);
attack.cpp - alter this - line 3177
Code:
damage = ReduceMagicalDamage(damage);
to this
Code:
damage = ReduceMagicalDamage(damage, spell_id);
attack.cpp - alter this - line 2932
Code:
sint32 Mob::ReduceMagicalDamage(sint32 damage)
{
if(damage <= 0 || (!HasSpellRune() && !HasPartialSpellRune()))
{
return damage;
}
int slot = GetBuffSlotFromType(SE_NegateAttacks);
if(slot >= 0 && buffs[slot].magic_rune > 0)
{
if(--buffs[slot].melee_rune == 0)
{
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
return -6;
}
slot = GetBuffSlotFromType(SE_MitigateSpellDamage);
if(slot >= 0)
{
int damage_to_reduce = damage * GetPartialMagicRuneReduction(buffs[slot].spellid) / 100;
if(damage_to_reduce > buffs[slot].magic_rune)
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].magic_rune);
damage -= damage_to_reduce;
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
else
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
" damage remaining.", damage_to_reduce, buffs[slot].magic_rune);
buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
damage -= damage_to_reduce;
}
}
if(damage < 1)
{
return -6;
}
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
while(slot >= 0)
{
int16 magic_rune_left = buffs[slot].magic_rune;
if(magic_rune_left >= damage)
{
magic_rune_left -= damage;
damage = 0;
buffs[slot].magic_rune = magic_rune_left;
break;
}
else
{
if(magic_rune_left > 0)
damage -= magic_rune_left;
BuffFadeBySlot(slot);
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
UpdateRuneFlags();
}
}
return(damage);
}
to this
Code:
sint32 Mob::ReduceMagicalDamage(sint32 damage, int16 spell_id)
{
if(damage <= 0 || (!HasSpellRune() && !HasPartialSpellRune()) && this->itembonuses.SpellDamageShield == 0 && this->itembonuses.DoTShielding == 0)
{
return damage;
}
int slot = GetBuffSlotFromType(SE_NegateAttacks);
if(slot >= 0 && buffs[slot].magic_rune > 0)
{
if(--buffs[slot].melee_rune == 0)
{
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
return -6;
}
for(int i = 0; i < EFFECT_COUNT; i++)
{
// Isolate the Direct Damage effects to be reduced by spell shielding and spell rune effects.
if ((spells[spell_id].buffduration == 0 && spells[spell_id].effectid[i] == SE_CurrentHP) || (spells[spell_id].buffduration > 0 && spells[spell_id].effectid[i] == SE_CurrentHPOnce))
{
damage -= (damage * this->itembonuses.SpellDamageShield / 100);
slot = GetBuffSlotFromType(SE_MitigateSpellDamage);
if(slot >= 0)
{
int damage_to_reduce = damage * GetPartialMagicRuneReduction(buffs[slot].spellid) / 100;
if(damage_to_reduce > buffs[slot].magic_rune)
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].magic_rune);
damage -= damage_to_reduce;
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
else
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
" damage remaining.", damage_to_reduce, buffs[slot].magic_rune);
buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
damage -= damage_to_reduce;
}
}
if(damage < 1)
{
return -6;
}
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
while(slot >= 0)
{
int16 magic_rune_left = buffs[slot].magic_rune;
if(magic_rune_left >= damage)
{
magic_rune_left -= damage;
damage = 0;
buffs[slot].magic_rune = magic_rune_left;
break;
}
else
{
if(magic_rune_left > 0)
damage -= magic_rune_left;
BuffFadeBySlot(slot);
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
UpdateRuneFlags();
}
}
return(damage);
}
// Isolate the DoT effects to be reduced by DoT shielding.
else if (spells[spell_id].buffduration > 0 && spells[spell_id].effectid[i] == SE_CurrentHP)
{
damage -= (damage * this->itembonuses.DoTShielding / 100);
return(damage);
}
}
return(damage);
}
|
 |
|
 |

07-10-2010, 07:00 PM
|
Developer
|
|
Join Date: Mar 2009
Location: -
Posts: 228
|
|
Any chance you could apply the same logic for spell shielding to the following
Spell effect 296 Increase Incomming Spell damage.
Basically it would just be a reverse midigation without having to worry about the rune part.
|
 |
|
 |

07-10-2010, 08:56 PM
|
Dragon
|
|
Join Date: May 2009
Location: Milky Way
Posts: 539
|
|
Yea actually, I needed to fix it as it was easy to get working for single effect spells like Ice Comet(DD) or Horror(DoT) but for spells like Ikaav Venom which have a DD and a DoT component, that was my problem. Then I noticed we have access to the bufftic so it was easy to seperate out those effects and now it is working 100%(as far as I can see), with the added support for SE_SpellVulnerability(or Increase Incoming Spell Damage). This also truly fixes the spell runes being used on DoT ticks as well.
edit... spoke too soon, SpellVulnerability works on clients but doesnt affect nukes cast on NPCs it seems. maybe I can fix it before my edit timer runs out...
... looks like the problem is with the focus code as it only increases spells you can cast on yourself, will have to look into alternative way of limiting what spells are affected by the vulnerability.
Ignore the previous code...
spell effects.cpp - line 2810 - add this
Code:
case SE_SpellVulnerability:
spell effects.cpp - line 3853 - add this
Code:
case SE_SpellVulnerability:
{
if(type == focusSpellVulnerability)
{
value = 1;
}
break;
}
mob.h - line 90 - add this
Code:
focusSpellVulnerability,
mob.h - line 843 - alter this
Code:
sint32 ReduceMagicalDamage(sint32 damage);
to this:
Code:
sint32 AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic);
attack.ccp - line 3189 - alter this
Code:
damage = ReduceMagicalDamage(damage);
to this:
Code:
damage = AffectMagicalDamage(damage, spell_id, iBuffTic);
attack.cpp - line 2932 - replace this function
Code:
sint32 Mob::ReduceMagicalDamage(sint32 damage)
{
...
}
with this:
Code:
sint32 Mob::AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic)
{
if(damage <= 0)
{
return damage;
}
// Increase magical damage before runes
uint32 buff_count = GetMaxTotalSlots();
for(int i = 0; i < buff_count; i++)
{
if(IsEffectInSpell(buffs[i].spellid, SE_SpellVulnerability))
{
sint32 focus = CalcFocusEffect(focusSpellVulnerability, buffs[i].spellid, spell_id);
if(focus == 1)
{
damage += damage * spells[buffs[i].spellid].base[0] / 100;
}
}
}
// If this is a DoT, use DoT Shielding...
if(iBuffTic)
{
damage -= (damage * this->itembonuses.DoTShielding / 100);
}
// This must be a DD then so lets apply Spell Shielding and all the various runes that can block or negate DD spells.
else
{
// See if we block the spell outright first
int slot = GetBuffSlotFromType(SE_NegateAttacks);
if(slot >= 0 && buffs[slot].magic_rune > 0)
{
if(--buffs[slot].melee_rune == 0)
{
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
return -6;
}
// Reduce damage by the Spell Shielding first so that the runes don't take the raw damage.
damage -= (damage * this->itembonuses.SpellDamageShield / 100);
// Do runes now.
slot = GetBuffSlotFromType(SE_MitigateSpellDamage);
if(slot >= 0)
{
int damage_to_reduce = damage * GetPartialMagicRuneReduction(buffs[slot].spellid) / 100;
if(damage_to_reduce > buffs[slot].magic_rune)
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].magic_rune);
damage -= damage_to_reduce;
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
else
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
" damage remaining.", damage_to_reduce, buffs[slot].magic_rune);
buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
damage -= damage_to_reduce;
}
}
if(damage < 1)
{
return -6;
}
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
while(slot >= 0)
{
int16 magic_rune_left = buffs[slot].magic_rune;
if(magic_rune_left >= damage)
{
magic_rune_left -= damage;
damage = 0;
buffs[slot].magic_rune = magic_rune_left;
break;
}
else
{
if(magic_rune_left > 0)
damage -= magic_rune_left;
BuffFadeBySlot(slot);
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
UpdateRuneFlags();
}
}
}
return damage;
}
|
 |
|
 |
 |
|
 |

07-10-2010, 11:44 PM
|
Dragon
|
|
Join Date: May 2009
Location: Milky Way
Posts: 539
|
|
OK this is fully functional as far as I can tell now. The spell and DoT shielding work perfectly, spell runes are limited to DDs and SE_SpellVulnerability works perfect for clients. I added a section to deal with NPCs casting on clients with vulnerabilities as well, its not the most elegant solution however it allows you to have an NPC cast a spell that will make clients vulnerable to DDs or DoTs of any or all resists. To make clients vulnerable to both DDs and DoTs at the same time you would have to implement both SE_LimitInstant and SE_LimitMinDur in the vulnerability spell, however counterintuitive that may be(perhaps is a better way to code it?).
Going to include all the code even though not all changed(figured this would be easiest for others)... bold headers are the ones that have changed from the second post.
spell effects.cpp - line 2810 - add this
Code:
case SE_SpellVulnerability:
spell effects.cpp - line 3853 - add this
Code:
case SE_SpellVulnerability:
{
if(type == focusSpellVulnerability)
{
value = 1;
}
break;
}
mob.h - line 90 - add this
Code:
focusSpellVulnerability,
mob.h - line 843 - alter this
Code:
sint32 ReduceMagicalDamage(sint32 damage);
to this
Code:
sint32 AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic, Mob* attacker);
attack.ccp - line 3189 - alter this
Code:
damage = ReduceMagicalDamage(damage);
to this
Code:
damage = AffectMagicalDamage(damage, spell_id, iBuffTic, attacker);
attack.cpp - line 2932 - replace this function
Code:
sint32 Mob::ReduceMagicalDamage(sint32 damage)
{
...
}
with this
Code:
sint32 Mob::AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic, Mob* attacker)
{
if(damage <= 0)
{
return damage;
}
// Increase magical damage before runes
uint32 buff_count = GetMaxTotalSlots();
for(int i = 0; i < buff_count; i++)
{
if(IsEffectInSpell(buffs[i].spellid, SE_SpellVulnerability))
{
// For Clients, Pets and Bots that are casting the spell, see if the vulnerability affects their spell.
if(!attacker->IsNPC())
{
sint32 focus = attacker->CalcFocusEffect(focusSpellVulnerability, buffs[i].spellid, spell_id);
if(focus == 1)
{
damage += damage * spells[buffs[i].spellid].base[0] / 100;
}
}
// If an NPC is casting the spell on a player that has a vulnerability, relaxed restrictions on focus
// so that either the Client is vulnerable to DoTs or DDs of various resists or all.
else if (attacker->IsNPC())
{
int npc_vulnerable = 0;
for(int j = 0; j < EFFECT_COUNT; j++)
{
switch (spells[buffs[i].spellid].effectid[j])
{
case SE_Blank:
break;
case SE_LimitResist:
if(spells[buffs[i].spellid].base[j])
{
if(spells[spell_id].resisttype == spells[buffs[i].spellid].base[j])
npc_vulnerable = 1;
}
break;
case SE_LimitInstant:
if(!iBuffTic)
{
npc_vulnerable = 1;
break;
}
case SE_LimitMinDur:
if(iBuffTic)
{
npc_vulnerable = 1;
break;
}
default:{
// look pretty
}
}
}
if (npc_vulnerable)
{
damage += damage * spells[buffs[i].spellid].base[0] / 100;
}
}
}
}
// If this is a DoT, use DoT Shielding...
if(iBuffTic)
{
damage -= (damage * this->itembonuses.DoTShielding / 100);
}
// This must be a DD then so lets apply Spell Shielding and all the various runes that can block or negate DD spells.
else
{
// See if we block the spell outright first
int slot = GetBuffSlotFromType(SE_NegateAttacks);
if(slot >= 0 && buffs[slot].magic_rune > 0)
{
if(--buffs[slot].melee_rune == 0)
{
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
return -6;
}
// Reduce damage by the Spell Shielding first so that the runes don't take the raw damage.
damage -= (damage * this->itembonuses.SpellDamageShield / 100);
// Do runes now.
slot = GetBuffSlotFromType(SE_MitigateSpellDamage);
if(slot >= 0)
{
int damage_to_reduce = damage * GetPartialMagicRuneReduction(buffs[slot].spellid) / 100;
if(damage_to_reduce > buffs[slot].magic_rune)
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].magic_rune);
damage -= damage_to_reduce;
BuffFadeBySlot(slot);
UpdateRuneFlags();
}
else
{
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
" damage remaining.", damage_to_reduce, buffs[slot].magic_rune);
buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
damage -= damage_to_reduce;
}
}
if(damage < 1)
{
return -6;
}
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
while(slot >= 0)
{
int16 magic_rune_left = buffs[slot].magic_rune;
if(magic_rune_left >= damage)
{
magic_rune_left -= damage;
damage = 0;
buffs[slot].magic_rune = magic_rune_left;
break;
}
else
{
if(magic_rune_left > 0)
damage -= magic_rune_left;
BuffFadeBySlot(slot);
slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
UpdateRuneFlags();
}
}
}
return damage;
}
|
 |
|
 |
 |
|
 |

07-11-2010, 12:02 AM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
I just want to say thanks for all of the spell effect submissions, Caryatis.
I would add them to the SVN directly myself, but I haven't messed with spell effect code at all, and I normally don't commit stuff unless I fully understand what it is that I am committing and what effect it will have.
Kayen knows spell effects much better than I do and he works on Storm Haven with me. I think I will add all of your submissions to my Live server (as apposed to my test server lol) and let Kayen test them when he has time. Then, if he says they all work as intended and don't seem to break anything else, I will commit them if someone else hasn't already done so.
We all appreciate anyone willing to submit new code to these forums and it is great to see someone who is interested in filling in some of the missing spell effects that have been needed for a long time. We have limited devs here and limited time to add submissions, and I don't want you to feel like the submissions you are posting are being ignored, because they are not. We have been busy with other things lately like working on the new Underfoot client from Steam and other projects here and there.
Hopefully between Kayen and I, we can get these tested and committed to the SVN. That is, if he is willing to test them out, which I assume he is. I think he is drooling to get at your new spell effects 
|
 |
|
 |

07-11-2010, 12:06 AM
|
Administrator
|
|
Join Date: Sep 2006
Posts: 1,348
|
|
I'll take a look at all this stuff soonish. I've just been trying to help get underfoot working is all.
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 12:50 PM.
|
|
 |
|
 |
|
|
|
 |
|
 |
|
 |