From ee6d7ae6bae35974f553bd23cc86e66189c18de4 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 2 Jul 2014 08:42:18 -0400 Subject: [PATCH 1/9] Implemented SE_Sanctuary - Places caster at bottom hate list, effect fades if caster cast spell on targets other than self. --- changelog.txt | 3 +++ common/spdat.h | 4 ++-- zone/bonuses.cpp | 8 ++++++++ zone/common.h | 1 + zone/spell_effects.cpp | 36 ++++++++++++++++++++++++++++++++++++ zone/spells.cpp | 3 +++ 6 files changed, 53 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 0a22ccf8d..08527447b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 07/2/2014 == +Kayen: Implemented SE_Sanctuary - Places caster at bottom hate list, effect fades if caster cast spell on targets other than self. + == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/common/spdat.h b/common/spdat.h index 75d351fc2..0c2cf4b1f 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -455,11 +455,11 @@ typedef enum { #define SE_MitigateDamageShield 305 // implemented - off hand attacks only (Shielding Resistance) //#define SE_ArmyOfTheDead 306 // *not implemented NecroAA - This ability calls up to five shades of nearby corpses back to life to serve the necromancer. The soulless abominations will mindlessly fight the target until called back to the afterlife some time later. The first rank summons up to three shades that serve for 60 seconds, and each additional rank adds one more possible shade and increases their duration by 15 seconds //#define SE_Appraisal 307 // *not implemented Rogue AA - This ability allows you to estimate the selling price of an item you are holding on your cursor. -#define SE_SuspendMinion 308 // not implemented as bonus +#define SE_SuspendMinion 308 // implemented #define SE_GateCastersBindpoint 309 // implemented - Gate to casters bind point #define SE_ReduceReuseTimer 310 // implemented #define SE_LimitCombatSkills 311 // implemented - Excludes focus from procs (except if proc is a memorizable spell) -//#define SE_Sanctuary 312 // *not implemented +#define SE_Sanctuary 312 // implemented - Places caster at bottom hate list, effect fades if cast cast spell on targets other than self. #define SE_ForageAdditionalItems 313 // implemented[AA] - chance to forage additional items #define SE_Invisibility2 314 // implemented - fixed duration invisible #define SE_InvisVsUndead2 315 // implemented - fixed duration ITU diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index a316c4b3b..0e521a6db 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2856,6 +2856,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne newbon->PetMeleeMitigation += effect_value; break; + case SE_Sanctuary: + newbon->Sanctuary = true; + break; + //Special custom cases for loading effects on to NPC from 'npc_spels_effects' table if (IsAISpellEffect) { @@ -4330,6 +4334,10 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) itembonuses.FinishingBlowLvl[1] = effect_value; break; + case SE_Sanctuary: + spellbonuses.Sanctuary = effect_value; + break; + } } } diff --git a/zone/common.h b/zone/common.h index 88600492e..0768a0835 100644 --- a/zone/common.h +++ b/zone/common.h @@ -372,6 +372,7 @@ struct StatBonuses { int16 DStacker[1]; // For buff stack blocking 0=Exists 1=Effect_value bool BerserkSPA; // berserk effect int16 Metabolism; // Food/drink consumption rates. + bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others. // AAs int8 Packrat; //weight reduction for items, 1 point = 10% diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 090fb4b75..7bb227bd0 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2732,6 +2732,22 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) break; } + case SE_Sanctuary: + { + std::list npc_list; + entity_list.GetNPCList(npc_list); + + for(std::list::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) { + + NPC* npc = *itr; + + if (npc && npc->CheckAggro(this)) + npc->SetHate(caster, 1); + + } + break; + } + // Handled Elsewhere case SE_ImmuneFleeing: case SE_NegateSpellEffect: @@ -2960,6 +2976,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_Berserk: case SE_Vampirism: case SE_Metabolism: + case SE_FinishingBlow: + case SE_FinishingBlowLvl: + case SE_Assassinate: + case SE_AssassinateLevel: { break; } @@ -3604,6 +3624,22 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste break; } + case SE_Sanctuary: + { + std::list npc_list; + entity_list.GetNPCList(npc_list); + + for(std::list::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) { + + NPC* npc = *itr; + + if (npc && npc->CheckAggro(this)) + npc->SetHate(caster, 1); + + } + break; + } + default: { // do we need to do anyting here? diff --git a/zone/spells.cpp b/zone/spells.cpp index 59dbb6625..6a87f2409 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -183,6 +183,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, CastToNPC()->AI_Event_SpellCastFinished(false, casting_spell_slot); return(false); } + //It appears that the Sanctuary effect is removed by a check on the client side (keep this however for redundancy) + if (spellbonuses.Sanctuary && (spells[spell_id].targettype != ST_Self && GetTarget() != this) || IsDetrimentalSpell(spell_id)) + BuffFadeByEffect(SE_Sanctuary); if(IsClient()){ int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id); From 4a49a11e73e495bd3c27813dd904710069eefa89 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 2 Jul 2014 11:18:50 -0400 Subject: [PATCH 2/9] Implemented SE_ResourceTap - Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end. --- changelog.txt | 2 +- common/spdat.h | 2 +- zone/mob.h | 1 + zone/spell_effects.cpp | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/changelog.txt b/changelog.txt index 08527447b..ac53a761b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,7 +2,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 07/2/2014 == Kayen: Implemented SE_Sanctuary - Places caster at bottom hate list, effect fades if caster cast spell on targets other than self. - +Kayen: Implemented SE_ResourceTap - Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end. == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/common/spdat.h b/common/spdat.h index 0c2cf4b1f..3b9d88995 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -604,7 +604,7 @@ typedef enum { #define SE_TriggerSpellThreshold 454 // implemented Trigger effect on X amount of spell damage taken #define SE_AddHatePct 455 // implemented Modify total hate by % #define SE_AddHateOverTimePct 456 // implemented Modify total hate by % over time. -//#define SE_ResourceTap 457 // not used +#define SE_ResourceTap 457 // implemented Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end. //#define SE_FactionModPct 458 // not used #define SE_DamageModifier2 459 // implemented - Modifies melee damage by skill type diff --git a/zone/mob.h b/zone/mob.h index 5c1240e83..4f7b47c03 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -229,6 +229,7 @@ public: bool TryDispel(uint8 caster_level, uint8 buff_level, int level_modifier); void SpellProjectileEffect(); bool TrySpellProjectile(Mob* spell_target, uint16 spell_id); + void ResourceTap(int32 damage, uint16 spell_id); //Buff void BuffProcess(); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 7bb227bd0..498e5d7ec 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -224,9 +224,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) dmg = (int32) (dmg * partial / 100); //handles AAs and what not... - if(caster) + if(caster) { dmg = caster->GetActSpellDamage(spell_id, dmg, this); - + caster->ResourceTap(-dmg, spell_id); + } + dmg = -dmg; Damage(caster, dmg, spell_id, spell.skill, false, buffslot, false); } @@ -3367,6 +3369,8 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste if(caster->IsNPC()) effect_value = caster->CastToNPC()->GetActSpellDamage(spell_id, effect_value, this); + + caster->ResourceTap(-effect_value, spell_id); } effect_value = -effect_value; @@ -6283,4 +6287,28 @@ bool Mob::TrySpellProjectile(Mob* spell_target, uint16 spell_id){ return true; } +void Mob::ResourceTap(int32 damage, uint16 spellid){ + //'this' = caster + if (!IsValidSpell(spellid)) + return; + for (int i = 0; i <= EFFECT_COUNT; i++) + { + if (spells[spellid].effectid[i] == SE_ResourceTap){ + + damage += (damage * spells[spellid].base[i])/100; + + if (spells[spellid].max[i] && (damage > spells[spellid].max[i])) + damage = spells[spellid].max[i]; + + if (spells[spellid].base2[i] == 0) //HP Tap + SetHP((GetHP()+ damage)); + + if (spells[spellid].base2[i] == 1) //Mana Tap + SetMana(GetMana() + damage); + + if (spells[spellid].base2[i] == 2 && IsClient()) //Endurance Tap + CastToClient()->SetEndurance(CastToClient()->GetEndurance() + damage); + } + } +} From 35e72692c1a6fd415c93284bff9218d309e34e3e Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 2 Jul 2014 11:54:59 -0400 Subject: [PATCH 3/9] Implemented SE_FactionModPct - Modifies faction gains and losses by percent. --- changelog.txt | 1 + common/spdat.h | 2 +- zone/bonuses.cpp | 26 ++++++++++++++++++++++++++ zone/client.cpp | 3 +++ zone/common.h | 1 + 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index ac53a761b..26da2b13c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,6 +3,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) == 07/2/2014 == Kayen: Implemented SE_Sanctuary - Places caster at bottom hate list, effect fades if caster cast spell on targets other than self. Kayen: Implemented SE_ResourceTap - Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end. +Kayen: Implemented SE_FactionModPct - Modifies faction gains and losses by percent. == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/common/spdat.h b/common/spdat.h index 3b9d88995..c579a1af7 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -605,7 +605,7 @@ typedef enum { #define SE_AddHatePct 455 // implemented Modify total hate by % #define SE_AddHateOverTimePct 456 // implemented Modify total hate by % over time. #define SE_ResourceTap 457 // implemented Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end. -//#define SE_FactionModPct 458 // not used +#define SE_FactionModPct 458 // implemented Modifies faction gains and losses by percent. #define SE_DamageModifier2 459 // implemented - Modifies melee damage by skill type // LAST diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 0e521a6db..e27378207 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1315,6 +1315,16 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) newbon->PetMeleeMitigation += base1; break; + case SE_FactionModPct: + { + if((base1 < 0) && (newbon->FactionModPct > base1)) + newbon->FactionModPct = base1; + + else if(newbon->FactionModPct < base1) + newbon->FactionModPct = base1; + break; + } + } } } @@ -2860,6 +2870,16 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne newbon->Sanctuary = true; break; + case SE_FactionModPct: + { + if((effect_value < 0) && (newbon->FactionModPct > effect_value)) + newbon->FactionModPct = effect_value; + + else if(newbon->FactionModPct < effect_value) + newbon->FactionModPct = effect_value; + break; + } + //Special custom cases for loading effects on to NPC from 'npc_spels_effects' table if (IsAISpellEffect) { @@ -4338,6 +4358,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) spellbonuses.Sanctuary = effect_value; break; + case SE_FactionModPct: + spellbonuses.FactionModPct = effect_value; + itembonuses.FactionModPct = effect_value; + aabonuses.FactionModPct = effect_value; + break; + } } } diff --git a/zone/client.cpp b/zone/client.cpp index 4ec3ce2d7..12a9ada67 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7629,6 +7629,9 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui if(npc_value[i] != 0) { tmpValue = current_value + mod + npc_value[i]; + int16 FactionModPct = spellbonuses.FactionModPct + itembonuses.FactionModPct + aabonuses.FactionModPct; + tmpValue += (tmpValue * FactionModPct) / 100; + // Make sure faction hits don't go to GMs... if (m_pp.gm==1 && (tmpValue < current_value)) { tmpValue = current_value; diff --git a/zone/common.h b/zone/common.h index 0768a0835..9cb80211a 100644 --- a/zone/common.h +++ b/zone/common.h @@ -373,6 +373,7 @@ struct StatBonuses { bool BerserkSPA; // berserk effect int16 Metabolism; // Food/drink consumption rates. bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others. + int16 FactionModPct; // Modifies amount of faction gained. // AAs int8 Packrat; //weight reduction for items, 1 point = 10% From 542c0913d6bf2560eb3067dcf58243a0865a4e23 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 2 Jul 2014 14:00:50 -0400 Subject: [PATCH 4/9] Re-Implemented SE_TriggerMeleeThreshold and SE_TriggerSpellThreshold correctly - Trigger spell if owner of buff takes more than the specified damage amount in a SINGLE hit, then fade the buff. --- changelog.txt | 2 ++ common/spdat.h | 4 ++-- zone/attack.cpp | 37 +++++-------------------------------- zone/bonuses.cpp | 24 ++++-------------------- zone/mob.cpp | 3 +-- zone/mob.h | 1 + 6 files changed, 15 insertions(+), 56 deletions(-) diff --git a/changelog.txt b/changelog.txt index 26da2b13c..e6d342c55 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,6 +4,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) Kayen: Implemented SE_Sanctuary - Places caster at bottom hate list, effect fades if caster cast spell on targets other than self. Kayen: Implemented SE_ResourceTap - Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end. Kayen: Implemented SE_FactionModPct - Modifies faction gains and losses by percent. +Kayen: Re-Implemented SE_TriggerMeleeThreshold and SE_TriggerSpellThreshold correctly - Trigger spell if owner of buff +takes more than the specified damage amount in a SINGLE hit, then fade the buff. == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/common/spdat.h b/common/spdat.h index c579a1af7..1b202f19a 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -600,8 +600,8 @@ typedef enum { #define SE_MitigateDotDamage 450 // implemented DOT spell mitigation rune with max value #define SE_MeleeThresholdGuard 451 // implemented Partial Melee Rune that only is lowered if melee hits are over X amount of damage #define SE_SpellThresholdGuard 452 // implemented Partial Spell Rune that only is lowered if spell hits are over X amount of damage -#define SE_TriggerMeleeThreshold 453 // implemented Trigger effect on X amount of melee damage taken -#define SE_TriggerSpellThreshold 454 // implemented Trigger effect on X amount of spell damage taken +#define SE_TriggerMeleeThreshold 453 // implemented Trigger effect on X amount of melee damage taken in a single hit +#define SE_TriggerSpellThreshold 454 // implemented Trigger effect on X amount of spell damage taken in a single hit #define SE_AddHatePct 455 // implemented Modify total hate by % #define SE_AddHateOverTimePct 456 // implemented Modify total hate by % over time. #define SE_ResourceTap 457 // implemented Coverts a percent of dmg from dmg spells(DD/DoT) to hp/mana/end. diff --git a/zone/attack.cpp b/zone/attack.cpp index 7b641bd96..fdbc46d24 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3251,20 +3251,6 @@ int32 Mob::ReduceDamage(int32 damage) } } - if (spellbonuses.TriggerMeleeThreshold[2]){ - slot = spellbonuses.TriggerMeleeThreshold[1]; - - if (slot >= 0) { - if(damage > buffs[slot].melee_rune) { - if(!TryFadeEffect(slot)) - BuffFadeBySlot(slot); - } - else{ - buffs[slot].melee_rune = (buffs[slot].melee_rune - damage); - } - } - } - if(damage < 1) return -6; @@ -3393,27 +3379,13 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi } } - if (spellbonuses.TriggerSpellThreshold[2]){ - slot = spellbonuses.TriggerSpellThreshold[1]; - - if (slot >= 0) { - if(damage > buffs[slot].magic_rune) { - if(!TryFadeEffect(slot)) - BuffFadeBySlot(slot); - } - else{ - buffs[slot].magic_rune = (buffs[slot].magic_rune - damage); - } - } - } - if(damage < 1) return 0; if (spellbonuses.AbsorbMagicAtt[0] && spellbonuses.AbsorbMagicAtt[1] >= 0) damage = RuneAbsorb(damage, SE_AbsorbMagicAtt); - + if(damage < 1) return 0; } @@ -3599,6 +3571,8 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons if(spell_id == SPELL_UNKNOWN) { damage = ReduceDamage(damage); mlog(COMBAT__HITS, "Melee Damage reduced to %d", damage); + ReduceAllDamage(damage); + TryTriggerThreshHold(damage, SE_TriggerMeleeThreshold, attacker); } else { int32 origdmg = damage; damage = AffectMagicalDamage(damage, spell_id, iBuffTic, attacker); @@ -3610,14 +3584,13 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons //Kayen: Probably need to add a filter for this - Not sure if this msg is correct but there should be a message for spell negate/runes. Message(263, "%s tries to cast on YOU, but YOUR magical skin absorbs the spell.",attacker->GetCleanName()); } - + ReduceAllDamage(damage); + TryTriggerThreshHold(damage, SE_TriggerSpellThreshold, attacker); } if (skill_used) CheckNumHitsRemaining(NUMHIT_IncomingHitSuccess); - ReduceAllDamage(damage); - if(IsClient() && CastToClient()->sneaking){ CastToClient()->sneaking = false; SendAppearancePacket(AT_Sneak, 0); diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index e27378207..01e2e4f91 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2425,24 +2425,12 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne } case SE_TriggerMeleeThreshold: - { - if (newbon->TriggerMeleeThreshold[2] < base2){ - newbon->TriggerMeleeThreshold[0] = effect_value; - newbon->TriggerMeleeThreshold[1] = buffslot; - newbon->TriggerMeleeThreshold[2] = base2; - } + newbon->TriggerMeleeThreshold = true; break; - } case SE_TriggerSpellThreshold: - { - if (newbon->TriggerSpellThreshold[2] < base2){ - newbon->TriggerSpellThreshold[0] = effect_value; - newbon->TriggerSpellThreshold[1] = buffslot; - newbon->TriggerSpellThreshold[2] = base2; - } + newbon->TriggerSpellThreshold = true; break; - } case SE_ShieldBlock: newbon->ShieldBlock += effect_value; @@ -4218,15 +4206,11 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) break; case SE_TriggerMeleeThreshold: - spellbonuses.TriggerMeleeThreshold[0] = effect_value; - spellbonuses.TriggerMeleeThreshold[1] = effect_value; - spellbonuses.TriggerMeleeThreshold[2] = effect_value; + spellbonuses.TriggerMeleeThreshold = effect_value; break; case SE_TriggerSpellThreshold: - spellbonuses.TriggerSpellThreshold[0] = effect_value; - spellbonuses.TriggerSpellThreshold[1] = effect_value; - spellbonuses.TriggerSpellThreshold[2] = effect_value; + spellbonuses.TriggerSpellThreshold = effect_value; break; case SE_DivineAura: diff --git a/zone/mob.cpp b/zone/mob.cpp index ee468a0e6..5272b373f 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3452,8 +3452,7 @@ bool Mob::TryFadeEffect(int slot) { for(int i = 0; i < EFFECT_COUNT; i++) { - if (spells[buffs[slot].spellid].effectid[i] == SE_CastOnWearoff || spells[buffs[slot].spellid].effectid[i] == SE_EffectOnFade - || spells[buffs[slot].spellid].effectid[i] == SE_TriggerMeleeThreshold || spells[buffs[slot].spellid].effectid[i] == SE_TriggerSpellThreshold) + if (spells[buffs[slot].spellid].effectid[i] == SE_CastOnWearoff || spells[buffs[slot].spellid].effectid[i] == SE_EffectOnFade) { uint16 spell_id = spells[buffs[slot].spellid].base[i]; BuffFadeBySlot(slot); diff --git a/zone/mob.h b/zone/mob.h index 4f7b47c03..4d6983643 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -230,6 +230,7 @@ public: void SpellProjectileEffect(); bool TrySpellProjectile(Mob* spell_target, uint16 spell_id); void ResourceTap(int32 damage, uint16 spell_id); + void TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker); //Buff void BuffProcess(); From 8453d5bc4889d8505915f14fc3e91bdaf93b572f Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 2 Jul 2014 21:38:26 -0400 Subject: [PATCH 5/9] Renamed various Cast on Fade spell effects to more accurately describe their functions. Missing code from prior commit. --- common/spdat.cpp | 8 ++--- zone/common.h | 4 +-- zone/mob.cpp | 2 +- zone/spell_effects.cpp | 74 ++++++++++++++++++++++++++++++------------ 4 files changed, 61 insertions(+), 27 deletions(-) diff --git a/common/spdat.cpp b/common/spdat.cpp index 3c4989a67..49cb8fe16 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -1003,7 +1003,7 @@ bool IsSuspendableSpell(uint16 spell_id) uint32 GetMorphTrigger(uint32 spell_id) { for (int i = 0; i < EFFECT_COUNT; ++i) - if (spells[spell_id].effectid[i] == SE_ImprovedSpellEffect) + if (spells[spell_id].effectid[i] == SE_CastOnFadeEffect) return spells[spell_id].base[i]; return 0; @@ -1012,9 +1012,9 @@ uint32 GetMorphTrigger(uint32 spell_id) bool IsCastonFadeDurationSpell(uint16 spell_id) { for (int i = 0; i < EFFECT_COUNT; ++i) { - if (spells[spell_id].effectid[i] == SE_ImprovedSpellEffect - || spells[spell_id].effectid[i] == SE_BossSpellTrigger - || spells[spell_id].effectid[i] == SE_CastOnWearoff){ + if (spells[spell_id].effectid[i] == SE_CastOnFadeEffect + || spells[spell_id].effectid[i] == SE_CastOnFadeEffectNPC + || spells[spell_id].effectid[i] == SE_CastOnFadeEffectAlways){ return true; } diff --git a/zone/common.h b/zone/common.h index 9cb80211a..10b3d2200 100644 --- a/zone/common.h +++ b/zone/common.h @@ -348,8 +348,8 @@ struct StatBonuses { uint16 SpellThresholdGuard[3]; // 0 = Mitigation value 1 = Buff Slot 2 = Min damage to trigger. uint16 MitigateSpellRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per spell 3 = Rune Amt uint16 MitigateDotRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per tick 3 = Rune Amt - uint32 TriggerMeleeThreshold[3]; // 0 = Spell Effect ID 1 = Buff slot 2 = Damage Amount to Trigger - uint32 TriggerSpellThreshold[3]; // 0 = Spell Effect ID 1 = Buff slot 2 = Damage Amount to Trigger + bool TriggerMeleeThreshold; // Has Melee Threshhold + bool TriggerSpellThreshold; // Has Spell Threshhold uint16 ManaAbsorbPercentDamage[2]; // 0 = Mitigation value 1 = Buff Slot int16 ShieldBlock; // Chance to Shield Block int16 BlockBehind; // Chance to Block Behind (with our without shield) diff --git a/zone/mob.cpp b/zone/mob.cpp index 5272b373f..cf7b2d243 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3452,7 +3452,7 @@ bool Mob::TryFadeEffect(int slot) { for(int i = 0; i < EFFECT_COUNT; i++) { - if (spells[buffs[slot].spellid].effectid[i] == SE_CastOnWearoff || spells[buffs[slot].spellid].effectid[i] == SE_EffectOnFade) + if (spells[buffs[slot].spellid].effectid[i] == SE_CastOnFadeEffectAlways || spells[buffs[slot].spellid].effectid[i] == SE_CastOnRuneFadeEffect) { uint16 spell_id = spells[buffs[slot].spellid].base[i]; BuffFadeBySlot(slot); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 498e5d7ec..c30d03432 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -1317,18 +1317,6 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) break; } - case SE_TriggerMeleeThreshold: - { - buffs[buffslot].melee_rune = spells[spell_id].base2[i]; - break; - } - - case SE_TriggerSpellThreshold: - { - buffs[buffslot].magic_rune = spells[spell_id].base2[i]; - break; - } - case SE_DistanceRemoval: { buffs[buffslot].caston_x = int(GetX()); @@ -2864,10 +2852,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_FcTwincast: case SE_DelayDeath: case SE_InterruptCasting: - case SE_ImprovedSpellEffect: - case SE_BossSpellTrigger: - case SE_CastOnWearoff: - case SE_EffectOnFade: + case SE_CastOnFadeEffect: + case SE_CastOnFadeEffectNPC: + case SE_CastOnFadeEffectAlways: + case SE_CastOnRuneFadeEffect: case SE_MaxHPChange: case SE_SympatheticProc: case SE_FcDamageAmt: @@ -2982,6 +2970,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_FinishingBlowLvl: case SE_Assassinate: case SE_AssassinateLevel: + case SE_FactionModPct: { break; } @@ -3569,9 +3558,9 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste break; } // These effects always trigger when they fade. - case SE_ImprovedSpellEffect: - case SE_BossSpellTrigger: - case SE_CastOnWearoff: + case SE_CastOnFadeEffect: + case SE_CastOnFadeEffectNPC: + case SE_CastOnFadeEffectAlways: { if (ticsremaining == 1) { @@ -5378,7 +5367,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, uint32 buff_slot, uint16 spell_id) 2: [Outgoing Hit Attempts] (185=SE_DamageModifer, 184=SE_HitChance) 3: [Incoming Spells] (180=SE_ResistSpellChance, 296=SE_FcSpellVulnerability) //Note: Determinetal spells only unless proven otherwise 4: [Outgoing Spells] - 5: [Outgoing Hit Successes] (220=SE_SkillDamageAmount, 178=SE_MeleeLifetap, 121=SE_ReverseDS, ?373=SE_CastOnWearoff) + 5: [Outgoing Hit Successes] (220=SE_SkillDamageAmount, 178=SE_MeleeLifetap, 121=SE_ReverseDS, ?373=SE_CastOnFadeEffectAlways) 6: [Incoming Hit Successes] (59=SE_DamageShield, 197=SE_SkillDamageTaken, 162=define SE_MitigateMeleeDamage) 7: [Matching Spells] *When focus is triggered (focus effects) 8: [Incoming Hits or Spells] (329=SE_ManaAbsorbPercentDamage) @@ -6312,3 +6301,48 @@ void Mob::ResourceTap(int32 damage, uint16 spellid){ } } } + +void Mob::TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker){ + + if (damage <= 0) + return; + + if ((SE_TriggerMeleeThreshold == effect_id) && !spellbonuses.TriggerMeleeThreshold ) + return; + else if ((SE_TriggerSpellThreshold == effect_id) && !spellbonuses.TriggerSpellThreshold) + return; + + int buff_count = GetMaxTotalSlots(); + + for(int slot = 0; slot < buff_count; slot++) { + + if(IsValidSpell(buffs[slot].spellid)){ + + for(int i = 0; i < EFFECT_COUNT; i++){ + + if (spells[buffs[slot].spellid].effectid[i] == effect_id){ + + uint16 spell_id = spells[buffs[slot].spellid].base[i]; + + if (damage > spells[buffs[slot].spellid].base2[i]){ + + BuffFadeBySlot(slot); + + if (IsValidSpell(spell_id)) { + + if (IsBeneficialSpell(spell_id)) + SpellFinished(spell_id, this, 10, 0, -1, spells[spell_id].ResistDiff); + + else if(attacker) + SpellFinished(spell_id, attacker, 10, 0, -1, spells[spell_id].ResistDiff); + } + } + } + } + } + } +} + + + + \ No newline at end of file From ee741048e960b9ee13a49d10ffe00e3e9b6852b6 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Thu, 3 Jul 2014 08:48:27 -0400 Subject: [PATCH 6/9] Implemented SE_LimitSpellClass - Focus Limits spell to pre defined categories. (3=Cures,3=Offensive, 6=Lifetap) --- common/spdat.cpp | 18 ++++++ common/spdat.h | 15 ++--- zone/mob.h | 2 + zone/spell_effects.cpp | 121 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 139 insertions(+), 17 deletions(-) diff --git a/common/spdat.cpp b/common/spdat.cpp index 49cb8fe16..75f1e9b88 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -157,6 +157,24 @@ bool IsFearSpell(uint16 spell_id) return IsEffectInSpell(spell_id, SE_Fear); } +bool IsCureSpell(uint16 spell_id) +{ + const SPDat_Spell_Struct &sp = spells[spell_id]; + + bool CureEffect = false; + + for(int i = 0; i < EFFECT_COUNT; i++){ + if (sp.effectid[i] == SE_DiseaseCounter || sp.effectid[i] == SE_PoisonCounter + || sp.effectid[i] == SE_CurseCounter || sp.effectid[i] == SE_CorruptionCounter) + CureEffect = true; + } + + if (CureEffect && IsBeneficialSpell(spell_id)) + return true; + + return false; +} + bool IsSlowSpell(uint16 spell_id) { const SPDat_Spell_Struct &sp = spells[spell_id]; diff --git a/common/spdat.h b/common/spdat.h index 1b202f19a..69b6573b0 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -36,7 +36,7 @@ #define EFFECT_COUNT 12 #define MAX_SPELL_TRIGGER 12 // One for each slot(only 6 for AA since AA use 2) #define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists. -#define MaxLimitInclude 12 //Number(x 0.5) of focus Limiters that have inclusive checksm used when calcing focus effects +#define MaxLimitInclude 16 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects const int Z_AGGRO=10; @@ -436,7 +436,7 @@ typedef enum { #define SE_FcDamageAmt 286 // implemented - adds direct spell damage #define SE_SpellDurationIncByTic 287 // implemented #define SE_SpecialAttackKBProc 288 // implemented[AA] - Chance to to do a knockback from special attacks [AA Dragon Punch]. -#define SE_ImprovedSpellEffect 289 // implemented - Triggers only if fades after natural duration. +#define SE_CastOnFadeEffect 289 // implemented - Triggers only if fades after natural duration. #define SE_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap #define SE_Purify 291 // implemented - Removes determental effects #define SE_StrikeThrough2 292 // implemented[AA] - increasing chance of bypassing an opponent's special defenses, such as dodge, block, parry, and riposte. @@ -480,7 +480,7 @@ typedef enum { #define SE_CriticalDamageMob 330 // implemented #define SE_Salvage 331 // implemented - chance to recover items that would be destroyed in failed tradeskill combine //#define SE_SummonToCorpse 332 // *not implemented AA - Call of the Wild (Druid/Shaman Res spell with no exp) -#define SE_EffectOnFade 333 // implemented +#define SE_CastOnRuneFadeEffect 333 // implemented #define SE_BardAEDot 334 // implemented #define SE_BlockNextSpellFocus 335 // implemented - base1 chance to block next spell ie Puratus (8494) //#define SE_IllusionaryTarget 336 // not used @@ -520,11 +520,11 @@ typedef enum { #define SE_ResistCorruption 370 // implemented #define SE_AttackSpeed4 371 // implemented - stackable slow effect 'Inhibit Melee' //#define SE_ForageSkill 372 // *not implemented[AA] Will increase the skill cap for those that have the Forage skill and grant the skill and raise the cap to those that do not. -#define SE_CastOnWearoff 373 // implemented - Triggers only if fades after natural duration. +#define SE_CastOnFadeEffectAlways 373 // implemented - Triggers if fades after natural duration OR from rune/numhits fades. #define SE_ApplyEffect 374 // implemented #define SE_DotCritDmgIncrease 375 // implemented - Increase damage of DoT critical amount //#define SE_Fling 376 // *not implemented - used in 2 test spells (12945 | Movement Test Spell 1) -#define SE_BossSpellTrigger 377 // implemented - Triggers only if fades after natural duration. +#define SE_CastOnFadeEffectNPC 377 // implemented - Triggers only if fades after natural duration (On live these are usually players spells that effect an NPC). #define SE_SpellEffectResistChance 378 // implemented - Increase chance to resist specific spell effect (base1=value, base2=spell effect id) #define SE_ShadowStepDirectional 379 // implemented - handled by client #define SE_Knockdown 380 // implemented - small knock back(handled by client) @@ -550,8 +550,8 @@ typedef enum { #define SE_HealGroupFromMana 400 // implemented - Drains mana and heals for each point of mana drained #define SE_ManaDrainWithDmg 401 // implemented - Deals damage based on the amount of mana drained #define SE_EndDrainWithDmg 402 // implemented - Deals damage for the amount of endurance drained -//#define SE_LimitSpellClass 403 // *not implemented - unclear what this refers too (not 'right click' spell bar) -//#define SE_LimitSpellSubclass 404 // *not implemented - unclear what this refers too (not 'right click' spell bar) +#define SE_LimitSpellClass 403 // implemented - Limits to specific types of spells (see CheckSpellCategory) +#define SE_LimitSpellSubclass 404 // *not implemented - Limits to specific types of spells (see CheckSpellCategory) [Categories NOT defined yet] #define SE_TwoHandBluntBlock 405 // implemented - chance to block attacks when using two hand blunt weapons (similiar to shield block) #define SE_CastonNumHitFade 406 // implemented - casts a spell when a buff fades due to its numhits being depleted #define SE_CastonFocusEffect 407 // implemented - casts a spell if focus limits are met (ie triggers when a focus effects is applied) @@ -787,6 +787,7 @@ bool IsSummonSpell(uint16 spellid); bool IsEvacSpell(uint16 spellid); bool IsDamageSpell(uint16 spellid); bool IsFearSpell(uint16 spellid); +bool IsCureSpell(uint16 spellid); bool BeneficialSpell(uint16 spell_id); bool GroupOnlySpell(uint16 spell_id); int GetSpellEffectIndex(uint16 spell_id, int effect); diff --git a/zone/mob.h b/zone/mob.h index 4d6983643..0476a20dc 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -231,6 +231,8 @@ public: bool TrySpellProjectile(Mob* spell_target, uint16 spell_id); void ResourceTap(int32 damage, uint16 spell_id); void TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker); + bool CheckSpellCategory(uint16 spell_id, int category_id, int effect_id); + //Buff void BuffProcess(); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index c30d03432..dcc6b6e1b 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2971,6 +2971,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_Assassinate: case SE_AssassinateLevel: case SE_FactionModPct: + case SE_LimitSpellClass: { break; } @@ -4128,6 +4129,8 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) 6/7 SE_LimitTarget 8/9 SE_LimitSpellGroup: 10/11 SE_LimitCastingSkill: + 12/13 SE_LimitSpellClass: + 14/15 SE_LimitSpellSubClass: Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes */ int FocusCount = 0; @@ -4322,16 +4325,40 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) break; case SE_LimitCastingSkill: - if(base1 < 0) { - if(-base1 == spell.skill) - LimitFailure = true; - } - else { - LimitInclude[10] = true; - if(base1 == spell.skill) - LimitInclude[11] = true; - } - break; + if(base1 < 0) { + if(-base1 == spell.skill) + LimitFailure = true; + } + else { + LimitInclude[10] = true; + if(base1 == spell.skill) + LimitInclude[11] = true; + } + break; + + case SE_LimitSpellClass: + if(base1 < 0) { //Exclude + if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass)); + return(0); + } + else { + LimitInclude[12] = true; + if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass)); //Include + LimitInclude[13] = true; + } + break; + + case SE_LimitSpellSubclass: + if(base1 < 0) { //Exclude + if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass)); + return(0); + } + else { + LimitInclude[14] = true; + if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass)); //Include + LimitInclude[15] = true; + } + break; case SE_LimitClass: //Do not use this limit more then once per spell. If multiple class, treat value like items would. @@ -4575,6 +4602,8 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo 6/7 SE_LimitTarget 8/9 SE_LimitSpellGroup: 10/11 SE_LimitCastingSkill: + 12/13 SE_LimitSpellClass: + 14/15 SE_LimitSpellSubClass: Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes */ @@ -4764,6 +4793,30 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo Caston_spell_id = focus_spell.base[i]; break; + case SE_LimitSpellClass: + if(focus_spell.base[i] < 0) { //Exclude + if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellClass)); + return(0); + } + else { + LimitInclude[12] = true; + if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellClass)); //Include + LimitInclude[13] = true; + } + break; + + case SE_LimitSpellSubclass: + if(focus_spell.base[i] < 0) { //Exclude + if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellSubclass)); + return(0); + } + else { + LimitInclude[14] = true; + if (CheckSpellCategory(spell_id, focus_spell.base[i], SE_LimitSpellSubclass)); //Include + LimitInclude[15] = true; + } + break; + //handle effects case SE_ImprovedDamage: @@ -6343,6 +6396,54 @@ void Mob::TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker){ } } +bool Mob::CheckSpellCategory(uint16 spell_id, int category_id, int effect_id){ + if (!IsValidSpell(spell_id) || !category_id) + return false; + int effectid = 0; + int category = 0; + + /*Category ID SE_LimitSpellClass [(+) Include (-) Exclude] + 1 = UNK + 2 = Cures + 3 = Offensive Spells + 4 = UNK + 5 = UNK + 6 = Lifetap + */ + + /*Category ID SE_LimitSpellSubClass [(+) Include (-) Exclude] + 5 = UNK + 8 = UNK + */ + + if (effect_id == SE_LimitSpellClass) { + + switch(category_id) + { + case 2: + if (IsCureSpell(spell_id)) + return true; + break; + + case 3: + if (IsDetrimentalSpell(spell_id)) + return true; + break; + + case 6: + if (spells[spell_id].targettype == ST_Tap || spells[spell_id].targettype == ST_TargetAETap) + return true; + break; + } + } + + else if (effect_id == SE_LimitSpellSubclass) { + //Pending Implementation when category types are figured out. + return false; + } + + return false; +} \ No newline at end of file From 0d2127f874f389fc7144d25385e8c9eeb5a935d0 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Thu, 3 Jul 2014 10:55:59 -0400 Subject: [PATCH 7/9] Changed SE_LimitMaxMana to SE_MeleeVulnerability - Weakness/Mitigation verse melee damage (Despite lives SPA lable as the former it clearly is not what the effect does from all spell examples) --- changelog.txt | 3 +++ common/spdat.h | 2 +- zone/bonuses.cpp | 8 ++++++++ zone/common.h | 1 + zone/mob.cpp | 7 ++++++- zone/spell_effects.cpp | 12 +----------- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/changelog.txt b/changelog.txt index e6d342c55..56307b361 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,6 +6,9 @@ Kayen: Implemented SE_ResourceTap - Coverts a percent of dmg from dmg spells(DD/ Kayen: Implemented SE_FactionModPct - Modifies faction gains and losses by percent. Kayen: Re-Implemented SE_TriggerMeleeThreshold and SE_TriggerSpellThreshold correctly - Trigger spell if owner of buff takes more than the specified damage amount in a SINGLE hit, then fade the buff. +Kayen: Implemented SE_LimitSpellClass - Focus Limits spell to pre defined categories. (3=Cures,3=Offensive, 6=Lifetap) +Kayen: Changed SE_LimitMaxMana to SE_MeleeVulnerability - Weakness/Mitigation verse melee damage +(Despite lives SPA lable as the former it clearly is not what the effect does from all spell examples) == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/common/spdat.h b/common/spdat.h index 69b6573b0..02dca8ff7 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -538,7 +538,7 @@ typedef enum { //#define SE_SummonCorpseZone 388 // *not implemented - summons a corpse from any zone(nec AA) #define SE_FcTimerRefresh 389 // implemented - Refresh spell icons //#define SE_FcTimerLockout 390 // *not implemented - Sets recast timers to specific value, focus limited. -#define SE_LimitManaMax 391 // implemented +#define SE_MeleeVulnerability 391 // implemented [Live SPA has this as LimitManaMax however that is clearly not the effect used] #define SE_FcHealAmt 392 // implemented - Adds or removes healing from spells #define SE_FcHealPctIncoming 393 // implemented - HealRate with focus restrictions. #define SE_FcHealAmtIncoming 394 // implemented - Adds/Removes amount of healing on target by X value with foucs restrictions. diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 01e2e4f91..48a3d95e1 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1315,6 +1315,10 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) newbon->PetMeleeMitigation += base1; break; + case SE_MeleeVulnerability: + newbon->MeleeVulnerability += base1; + break; + case SE_FactionModPct: { if((base1 < 0) && (newbon->FactionModPct > base1)) @@ -2854,6 +2858,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne newbon->PetMeleeMitigation += effect_value; break; + case SE_MeleeVulnerability: + newbon->MeleeVulnerability += effect_value; + break; + case SE_Sanctuary: newbon->Sanctuary = true; break; diff --git a/zone/common.h b/zone/common.h index 10b3d2200..e3a9dfb09 100644 --- a/zone/common.h +++ b/zone/common.h @@ -374,6 +374,7 @@ struct StatBonuses { int16 Metabolism; // Food/drink consumption rates. bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others. int16 FactionModPct; // Modifies amount of faction gained. + int16 MeleeVulnerability; // Weakness/mitigation to melee damage // AAs int8 Packrat; //weight reduction for items, 1 point = 10% diff --git a/zone/mob.cpp b/zone/mob.cpp index cf7b2d243..59e02568b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3419,6 +3419,8 @@ int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used) { int skilldmg_mod = 0; + int16 MeleeVuln = spellbonuses.MeleeVulnerability + itembonuses.MeleeVulnerability + aabonuses.MeleeVulnerability; + // All skill dmg mod + Skill specific skilldmg_mod += itembonuses.SkillDmgTaken[HIGHEST_SKILL+1] + spellbonuses.SkillDmgTaken[HIGHEST_SKILL+1] + itembonuses.SkillDmgTaken[skill_used] + spellbonuses.SkillDmgTaken[skill_used]; @@ -3427,6 +3429,8 @@ int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used) if ((SkillDmgTaken_Mod[skill_used]) || (SkillDmgTaken_Mod[HIGHEST_SKILL+1])) skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1]; + skilldmg_mod += MeleeVuln; + if(skilldmg_mod < -100) skilldmg_mod = -100; @@ -3452,7 +3456,8 @@ bool Mob::TryFadeEffect(int slot) { for(int i = 0; i < EFFECT_COUNT; i++) { - if (spells[buffs[slot].spellid].effectid[i] == SE_CastOnFadeEffectAlways || spells[buffs[slot].spellid].effectid[i] == SE_CastOnRuneFadeEffect) + if (spells[buffs[slot].spellid].effectid[i] == SE_CastOnFadeEffectAlways || + spells[buffs[slot].spellid].effectid[i] == SE_CastOnRuneFadeEffect) { uint16 spell_id = spells[buffs[slot].spellid].base[i]; BuffFadeBySlot(slot); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index dcc6b6e1b..8c49414d7 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2942,7 +2942,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_FcIncreaseNumHits: case SE_CastonFocusEffect: case SE_FcHealAmtIncoming: - case SE_LimitManaMax: + case SE_MeleeVulnerability: case SE_DoubleRangedAttack: case SE_ShieldEquipHateMod: case SE_ShieldEquipDmgMod: @@ -4287,11 +4287,6 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) LimitFailure = true; break; - case SE_LimitManaMax: - if(spell.mana > base1) - LimitFailure = true; - break; - case SE_LimitTarget: if (base1 < 0) { if (-base1 == spell.targettype) //Exclude @@ -4718,11 +4713,6 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo return 0; break; - case SE_LimitManaMax: - if(spell.mana > focus_spell.base[i]) - return 0; - break; - case SE_LimitTarget: if (focus_spell.base[i] < 0) { if (-focus_spell.base[i] == spell.targettype) //Exclude From 28493488acd3c81ed2b8f3b34de6f1f0151e8f33 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Thu, 3 Jul 2014 11:00:23 -0400 Subject: [PATCH 8/9] Updated SE_BardAEDot to no longer damage target while target is moving (consistent with live) --- changelog.txt | 1 + zone/spell_effects.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 56307b361..c86b926fa 100644 --- a/changelog.txt +++ b/changelog.txt @@ -9,6 +9,7 @@ takes more than the specified damage amount in a SINGLE hit, then fade the buff. Kayen: Implemented SE_LimitSpellClass - Focus Limits spell to pre defined categories. (3=Cures,3=Offensive, 6=Lifetap) Kayen: Changed SE_LimitMaxMana to SE_MeleeVulnerability - Weakness/Mitigation verse melee damage (Despite lives SPA lable as the former it clearly is not what the effect does from all spell examples) +Kayen: Updated SE_BardAEDot to no longer damage target while target is moving (consistent with live) == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 8c49414d7..dfe8489c0 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2328,6 +2328,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) // SE_CurrentHP is calculated at first tick if its a dot/buff if (buffslot >= 0) break; + //This effect does no damage if target is moving. + if (IsMoving()) + break; // for offensive spells check if we have a spell rune on int32 dmg = effect_value; @@ -3391,7 +3394,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste { effect_value = CalcSpellEffectValue(spell_id, i, caster_level, caster); - if (invulnerable || /*effect_value > 0 ||*/ DivineAura()) + if (IsMoving() || invulnerable || /*effect_value > 0 ||*/ DivineAura()) break; if(effect_value < 0) { From 5a30d3ed034e0ea848674190fe32967196a12f38 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Thu, 3 Jul 2014 11:37:38 -0400 Subject: [PATCH 9/9] Update SE_InterruptCasting: Will now work for instant spells (as well as over time). --- changelog.txt | 1 + zone/spell_effects.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index c86b926fa..1e371109d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -10,6 +10,7 @@ Kayen: Implemented SE_LimitSpellClass - Focus Limits spell to pre defined catego Kayen: Changed SE_LimitMaxMana to SE_MeleeVulnerability - Weakness/Mitigation verse melee damage (Despite lives SPA lable as the former it clearly is not what the effect does from all spell examples) Kayen: Updated SE_BardAEDot to no longer damage target while target is moving (consistent with live) +Kayen: Update SE_InterruptCasting: Will now work for instant spells (as well as over time). == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index dfe8489c0..61333edfd 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2712,6 +2712,16 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) break; } + case SE_InterruptCasting:{ + if (buffslot >= 0) + break; + + if(IsCasting() && MakeRandomInt(0, 100) <= spells[spell_id].base[i]) + InterruptSpell(); + + break; + } + case SE_MassGroupBuff:{ SetMGB(true); @@ -2854,7 +2864,6 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_ApplyEffect: case SE_FcTwincast: case SE_DelayDeath: - case SE_InterruptCasting: case SE_CastOnFadeEffect: case SE_CastOnFadeEffectNPC: case SE_CastOnFadeEffectAlways: