From 791ba8e38b45ff3c736b9c736b3f025a494af896 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Sat, 8 Feb 2014 23:26:09 -0500 Subject: [PATCH] Updates to focus effect related code --- changelog.txt | 3 + common/spdat.h | 31 +- zone/bonuses.cpp | 18 +- zone/bot.cpp | 32 +- zone/common.h | 1 + zone/mob.cpp | 4 +- zone/spell_effects.cpp | 788 ++++++++++++++++++----------------------- zone/spells.cpp | 2 +- 8 files changed, 381 insertions(+), 498 deletions(-) diff --git a/changelog.txt b/changelog.txt index 1f71612b5..a3a3ebbb8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/8/2014 == +Kayen: Various updates/fixes/clean-ups to focus effect related code. Focus effect limits should now all work properly. + == 02/7/2014 == Kayen: Revised how heal amount is calculated to properly incorporate all current focus effects/bonuses. diff --git a/common/spdat.h b/common/spdat.h index d8ed6fb17..35f928789 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -36,6 +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 const int Z_AGGRO=10; @@ -289,8 +290,8 @@ typedef enum { #define SE_LimitMinDur 140 // implemented #define SE_LimitInstant 141 // implemented #define SE_LimitMinLevel 142 // implemented -#define SE_LimitCastTime 143 // implemented -#define SE_FfCastTimeMax 144 // not used +#define SE_LimitCastTimeMin 143 // implemented +#define SE_LimitCastTimeMax 144 // implemented (*not used in any known live spell) #define SE_Teleport2 145 // implemented - Banishment of the Pantheon #define SE_ElectricityResist 146 // *not implemented (Lightning Rod: 23233) #define SE_PercentalHeal 147 // implemented @@ -442,7 +443,7 @@ typedef enum { #define SE_FrontalStunResist 293 // implemented[AA] - Reduce chance to be stunned from front. #define SE_CriticalSpellChance 294 // implemented - increase chance to critical hit and critical damage modifier. //#define SE_ReduceTimerSpecial 295 // not used -#define SE_SpellVulnerability 296 // implemented - increase in incoming spell damage +#define SE_FcSpellVulnerability 296 // implemented - increase in incoming spell damage #define SE_FcDamageAmtIncoming 297 // implemented - debuff that adds points damage to spells cast on target (focus effect). #define SE_ChangeHeight 298 // implemented #define SE_WakeTheDead 299 // implemented @@ -457,7 +458,7 @@ typedef enum { #define SE_SuspendMinion 308 // not implemented as bonus #define SE_YetAnotherGate 309 // implemented #define SE_ReduceReuseTimer 310 // implemented -#define SE_CombatSkills 311 // 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_ForageAdditionalItems 313 // implemented[AA] - chance to forage additional items #define SE_Invisibility2 314 // implemented - fixed duration invisible @@ -494,7 +495,7 @@ typedef enum { #define SE_AssassinationLevel 345 // not implemented as bonus - AA Assisination max level to kill #define SE_HeadShotLevel 346 // not implemented as bonus - AA HeadShot max level to kill #define SE_DoubleRangedAttack 347 // implemented - chance at an additional archery attack (consumes arrow) -#define SE_LimitManaCost 348 // implemented +#define SE_LimitManaMin 348 // implemented #define SE_ShieldEquipHateMod 349 // implemented[AA] Increase melee hate when wearing a shield. #define SE_ManaBurn 350 // implemented - Drains mana for damage/heal at a defined ratio up to a defined maximum amount of mana. #define SE_PersistentEffect 351 // *not implemented. creates a trap/totem that casts a spell (spell id + base1?) when anything comes near it. can probably make a beacon for this @@ -535,9 +536,9 @@ typedef enum { #define SE_CastOnCurer 386 // implemented - Casts a spell on the person curing #define SE_CastOnCure 387 // implemented - Casts a spell on the cured person #define SE_SummonCorpseZone 388 // *not implemented - summons a corpse from any zone(nec AA) -#define SE_Forceful_Rejuv 389 // Refresh spell icons -#define SE_SetRecastTimer 390 // *not implemented - Sets recast timers to specific value, focus limited. -#define SE_IncreaseHitDmgTaken 391 // implemented - Most likely a simple negative mitigation modifier (Warlords fury: 23528) +#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_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. @@ -545,12 +546,12 @@ typedef enum { #define SE_FcHealAmtCrit 396 // implemented - Adds a direct healing amount to spells #define SE_PetMeleeMitigation 397 // *not implemented[AA] - additional mitigation to your pets. #define SE_SwarmPetDuration 398 // implemented - Affects the duration of swarm pets -#define SE_Twincast 399 // implemented - cast 2 spells for every 1 +#define SE_FcTwincast 399 // implemented - cast 2 spells for every 1 #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_Ff_SpellClass 403 // *not implemented - -#define SE_LimitExcludeSkill 404 // implemented - Limit a focus to exclude spells cast using a specific skill. +#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_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) @@ -560,16 +561,16 @@ typedef enum { #define SE_LimitClass 411 // implemented - Limits to spells of a certain class (Note: The class value in dbase is +1 in relation to item class value) #define SE_LimitRace 412 // implemented - Limits to spells cast by a certain race (Note: not used in any known live spells) #define SE_FcBaseEffects 413 // implemented - Increases the power of bard songs, skill attacks, runes, bard allowed foci, damage/heal -#define SE_LimitSpellSkill 414 // implemented - Limit a focus to include spells cast using a specific skill. +#define SE_LimitCastingSkill 414 // implemented - Limit a focus to include spells cast using a specific skill. //#define SE_FFItemClass 415 // not used #define SE_ACv2 416 // implemented - New AC spell effect #define SE_ManaRegen_v2 417 // implemented - New mana regen effect #define SE_SkillDamageAmount2 418 // implemented - adds skill damage directly to certain attacks #define SE_AddMeleeProc 419 // implemented - Adds a proc #define SE_FcLimitUse 420 // implemented - increases numhits count by percent (Note: not used in any known live spells) -#define SE_IncreaseNumHits 421 // implemented[AA] - increases number of hits a buff has till fade. (focus) -#define SE_FfLimitUseMin 422 // implemented - limit a focus to require a min amount of numhits value (used with above) -#define SE_FfLimitUseType 423 // implemented - limit a focus to require a certain numhits type +#define SE_FcIncreaseNumHits 421 // implemented[AA] - increases number of hits a buff has till fade. (focus) +#define SE_LimitUseMin 422 // implemented - limit a focus to require a min amount of numhits value (used with above) +#define SE_LimitUseType 423 // implemented - limit a focus to require a certain numhits type #define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace #define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626) #define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 04e8103dc..37af3021d 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1607,10 +1607,6 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne newbon->MeleeMitigation -= effect_value; break; - case SE_IncreaseHitDmgTaken: - newbon->MeleeMitigation += effect_value; - break; - case SE_CriticalHitChance: { @@ -2777,12 +2773,12 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff case SE_TriggerOnCast: //return focusTriggerOnCast; return 0; //This is calculated as an actual bonus - case SE_SpellVulnerability: + case SE_FcSpellVulnerability: return focusSpellVulnerability; case SE_BlockNextSpellFocus: //return focusBlockNextSpell; return 0; //This is calculated as an actual bonus - case SE_Twincast: + case SE_FcTwincast: return focusTwincast; case SE_SympatheticProc: return focusSympatheticProc; @@ -2800,12 +2796,14 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff return focusFcHealPctIncoming; case SE_FcBaseEffects: return focusFcBaseEffects; - case SE_IncreaseNumHits: + case SE_FcIncreaseNumHits: return focusIncreaseNumHits; case SE_FcLimitUse: return focusFcLimitUse; case SE_FcMute: return focusFcMute; + case SE_FcTimerRefresh: + return focusFcTimerRefresh; case SE_FcStunTimeMod: return focusFcStunTimeMod; case SE_FcHealPctCritIncoming: @@ -3119,12 +3117,6 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) aabonuses.MeleeMitigation = effect_value; break; - case SE_IncreaseHitDmgTaken: - spellbonuses.MeleeMitigation = effect_value; - itembonuses.MeleeMitigation = effect_value; - aabonuses.MeleeMitigation = effect_value; - break; - case SE_CriticalHitChance: { for(int e = 0; e < HIGHEST_SKILL+1; e++) diff --git a/zone/bot.cpp b/zone/bot.cpp index 6b040139c..dc34fe2b1 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -6736,7 +6736,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) if((spell.classes[(GetClass()%16) - 1]) < base1) LimitFound = true; break; - case SE_LimitCastTime: + case SE_LimitCastTimeMin: if (spell.cast_time < base1) LimitFound = true; break; @@ -6782,7 +6782,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) } break; - case SE_LimitManaCost: + case SE_LimitManaMin: if(spell.mana < base1) LimitFound = true; break; @@ -6800,7 +6800,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) } break; - case SE_CombatSkills: + case SE_LimitCombatSkills: // 1 is for disciplines only if(base1 == 1 && !IsDiscipline(spell_id)) LimitFound = true; @@ -6817,13 +6817,13 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) break; - case SE_LimitSpellSkill: + case SE_LimitCastingSkill: LimitSpellSkill = true; if(base1 == spell.skill) SpellSkill_Found = true; break; - case SE_LimitExcludeSkill:{ + case SE_LimitSpellSubclass:{ int16 spell_skill = spell.skill * -1; if(base1 == spell_skill) LimitFound = true; @@ -6941,7 +6941,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) } break; } - case SE_SpellVulnerability: + case SE_FcSpellVulnerability: { if(type == focusSpellVulnerability) { @@ -6958,7 +6958,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) } break; } - case SE_Twincast: + case SE_FcTwincast: { if(type == focusTwincast) { @@ -7057,7 +7057,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id) break; } - case SE_IncreaseNumHits: + case SE_FcIncreaseNumHits: { if(type == focusIncreaseNumHits) value = base1; @@ -7338,7 +7338,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel return(0); break; - case SE_LimitCastTime: + case SE_LimitCastTimeMin: if (spells[spell_id].cast_time < (uint16)focus_spell.base[i]) return(0); break; @@ -7398,7 +7398,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel } break; - case SE_LimitManaCost: + case SE_LimitManaMin: if(spell.mana < focus_spell.base[i]) return 0; break; @@ -7413,7 +7413,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel break; - case SE_CombatSkills: + case SE_LimitCombatSkills: // 1 is for disciplines only if(focus_spell.base[i] == 1 && !IsDiscipline(spell_id)) return 0; @@ -7429,13 +7429,13 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel return 0; break; - case SE_LimitSpellSkill: + case SE_LimitCastingSkill: LimitSpellSkill = true; if(focus_spell.base[i] == spell.skill) SpellSkill_Found = true; break; - case SE_LimitExcludeSkill:{ + case SE_LimitSpellSubclass:{ int16 spell_skill = spell.skill * -1; if(focus_spell.base[i] == spell_skill) return 0; @@ -7602,7 +7602,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel break; } - case SE_SpellVulnerability: + case SE_FcSpellVulnerability: { if(bottype == BotfocusSpellVulnerability) { @@ -7619,7 +7619,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel } break; } - case SE_Twincast: + case SE_FcTwincast: { if(bottype == BotfocusTwincast) { @@ -7715,7 +7715,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel break; } - case SE_IncreaseNumHits: + case SE_FcIncreaseNumHits: { if(bottype == BotfocusIncreaseNumHits) value = focus_spell.base[i]; diff --git a/zone/common.h b/zone/common.h index 67aae10e7..c400c5f56 100644 --- a/zone/common.h +++ b/zone/common.h @@ -78,6 +78,7 @@ typedef enum { //focus types focusIncreaseNumHits, focusFcLimitUse, focusFcMute, + focusFcTimerRefresh, focusFcStunTimeMod, focusFcHealPctCritIncoming, focusFcHealAmt, diff --git a/zone/mob.cpp b/zone/mob.cpp index c9f96e6a7..ae306c8dd 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3336,7 +3336,7 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id) int buff_count = GetMaxTotalSlots(); for(int i = 0; i < buff_count; i++) { - if(IsEffectInSpell(buffs[i].spellid, SE_Twincast)) + if(IsEffectInSpell(buffs[i].spellid, SE_FcTwincast)) { int32 focus = CalcFocusEffect(focusTwincast, buffs[i].spellid, spell_id); if(focus > 0) @@ -3378,7 +3378,7 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining) int buff_count = GetMaxTotalSlots(); for(int i = 0; i < buff_count; i++) { - if((IsValidSpell(buffs[i].spellid) && IsEffectInSpell(buffs[i].spellid, SE_SpellVulnerability))){ + if((IsValidSpell(buffs[i].spellid) && IsEffectInSpell(buffs[i].spellid, SE_FcSpellVulnerability))){ int32 focus = caster->CalcFocusEffect(focusSpellVulnerability, buffs[i].spellid, spell_id); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 638e55fe9..213a6d911 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2535,13 +2535,15 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) break; } - case SE_Forceful_Rejuv: + case SE_FcTimerRefresh: { if(IsClient()) { for(unsigned int i =0 ; i < MAX_PP_MEMSPELL; ++i) { if(IsValidSpell(CastToClient()->m_pp.mem_spells[i])) { - CastToClient()->m_pp.spellSlotRefresh[i] = 1; - CastToClient()->GetPTimers().Clear(&database, (pTimerSpellStart + CastToClient()->m_pp.mem_spells[i])); + if (CalcFocusEffect(focusFcTimerRefresh, spell_id, CastToClient()->m_pp.mem_spells[i])){ + CastToClient()->m_pp.spellSlotRefresh[i] = 1; + CastToClient()->GetPTimers().Clear(&database, (pTimerSpellStart + CastToClient()->m_pp.mem_spells[i])); + } } } SetMana(GetMana()); @@ -2825,17 +2827,17 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_LimitMinDur: case SE_LimitInstant: case SE_LimitMinLevel: - case SE_LimitCastTime: - case SE_LimitManaCost: - case SE_CombatSkills: + case SE_LimitCastTimeMin: + case SE_LimitManaMin: + case SE_LimitCombatSkills: case SE_SpellDurationIncByTic: case SE_TriggerOnCast: case SE_HealRate: case SE_SkillDamageTaken: - case SE_SpellVulnerability: + case SE_FcSpellVulnerability: case SE_SpellTrigger: case SE_ApplyEffect: - case SE_Twincast: + case SE_FcTwincast: case SE_DelayDeath: case SE_InterruptCasting: case SE_ImprovedSpellEffect: @@ -2883,11 +2885,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_CriticalHealDecay: case SE_CriticalRegenDecay: case SE_FcDamageAmtIncoming: - case SE_LimitSpellSkill: + case SE_LimitCastingSkill: case SE_MitigateDamageShield: case SE_FcBaseEffects: case SE_LimitClass: - case SE_LimitExcludeSkill: + case SE_LimitSpellSubclass: case SE_BlockBehind: case SE_ShieldBlock: case SE_PetCriticalHit: @@ -2923,10 +2925,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_ChannelChanceSpells: case SE_ChannelChanceItems: case SE_FcHealPctCritIncoming: - case SE_IncreaseNumHits: + case SE_FcIncreaseNumHits: case SE_CastonFocusEffect: case SE_FcHealAmtIncoming: - case SE_IncreaseHitDmgTaken: + case SE_LimitManaMax: case SE_DoubleRangedAttack: case SE_ShieldEquipHateMod: case SE_ShieldEquipDmgMod: @@ -2934,11 +2936,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_LimitRace: case SE_FcLimitUse: case SE_FcMute: - case SE_FfLimitUseType: + case SE_LimitUseType: case SE_FcStunTimeMod: case SE_StunBashChance: case SE_IncreaseChanceMemwipe: case SE_CriticalMend: + case SE_LimitCastTimeMax: { break; } @@ -3341,7 +3344,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste effect_value = CalcSpellEffectValue(spell_id, i, caster_level); if(caster) effect_value = caster->GetActSpellHealing(spell_id, effect_value); - //effect_value += effect_value * (itembonuses.HealRate + spellbonuses.HealRate) / 100; + HealDamage(effect_value, caster); //healing aggro would go here; removed for now break; @@ -3984,7 +3987,8 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) int32 base2 = 0; uint32 slot = 0; - bool LimitFound = false; + bool LimitFailure = false; + bool LimitInclude[MaxLimitInclude] = { false }; int FocusCount = 0; std::map >::const_iterator find_iter = aa_effects.find(aa_ID); @@ -4000,21 +4004,30 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) base2 = iter->second.base2; slot = iter->second.slot; - //AA Foci's can contain multiple focus effects within the same AA. - //To handle this we will not automatically return zero if a limit is found. - //Instead if limit is found and multiple effects, we will reset the limit check - //when the next valid focus effect is found. + /* + AA Foci's can contain multiple focus effects within the same AA. + To handle this we will not automatically return zero if a limit is found. + Instead if limit is found and multiple focus effects, we will reset the limit check + when the next valid focus effect is found. + */ + if (IsFocusEffect(0, 0, true,effect) || (effect == SE_TriggerOnCast)){ FocusCount++; //If limit found on prior check next, else end loop. if (FocusCount > 1){ - if (LimitFound){ + + for(int e = 0; e < MaxLimitInclude; e+=2) { + if (LimitInclude[e] && !LimitInclude[e+1]) + LimitFailure = true; + } + + if (LimitFailure){ value = 0; - LimitFound = false; - LimitSpellSkill = false; - SpellSkill_Found = false; - LimitSpellEffect = false; - SpellEffect_Found = false; + LimitFailure = false; + + for(int e = 0; e < MaxLimitInclude; e++) { + LimitInclude[e] = false; //Reset array + } } else{ @@ -4030,165 +4043,185 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) break; //Handle Focus Limits + case SE_LimitResist: - if(base1) - { - if(spell.resisttype != base1) - LimitFound = true; + if(base1 < 0){ + if(spell.resisttype == -base1) //Exclude + LimitFailure = true; } - break; + else { + LimitInclude[0] = true; + if (spell.resisttype == base1) //Include + LimitInclude[1] = true; + } + break; + case SE_LimitInstant: if(spell.buffduration) - LimitFound = true; - break; + LimitFailure = true; + break; + case SE_LimitMaxLevel: spell_level = spell.classes[(GetClass()%16) - 1]; lvldiff = spell_level - base1; //every level over cap reduces the effect by base2 percent unless from a clicky when ItemCastsUseFocus is true - if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)) - { - if(base2 > 0) - { + if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)) { + if(base2 > 0){ lvlModifier -= base2*lvldiff; if(lvlModifier < 1) - LimitFound = true; - } - else { - LimitFound = true; + LimitFailure = true; } + else + LimitFailure = true; } - break; + break; + case SE_LimitMinLevel: if((spell.classes[(GetClass()%16) - 1]) < base1) - LimitFound = true; - break; - case SE_LimitCastTime: + LimitFailure = true; + break; + + case SE_LimitCastTimeMin: if (spell.cast_time < base1) - LimitFound = true; - break; + LimitFailure = true; + break; + + case SE_LimitCastTimeMax: + if (spell.cast_time > base1) + LimitFailure = true; + break; + case SE_LimitSpell: - // Exclude spell(any but this) - if(base1 < 0) { - if (spell_id == (base1*-1)) - LimitFound = true; - } + if(base1 < 0) { //Exclude + if (spell_id == -base1) + LimitFailure = true; + } else { - // Include Spell(only this) - if (spell_id != base1) - LimitFound = true; + LimitInclude[2] = true; + if (spell_id == base1) //Include + LimitInclude[3] = true; } - break; + break; + case SE_LimitMinDur: if (base1 > CalcBuffDuration_formula(GetLevel(), spell.buffdurationformula, spell.buffduration)) - LimitFound = true; - break; + LimitFailure = true; + break; + case SE_LimitEffect: - // Exclude effect (any but this) - if (base1 < 0) { - if (IsEffectInSpell(spell_id, (base1 * -1))) - LimitFound = true; - } else { - // Include effect (only this) - if (!IsEffectInSpell(spell_id, base1)) - LimitFound = true; + if(base1 < 0){ + if(IsEffectInSpell(spell_id,-base1)) //Exclude + LimitFailure = true; + } + else{ + LimitInclude[4] = true; + if(IsEffectInSpell(spell_id,base1)) //Include + LimitInclude[5] = true; } - break; + break; + case SE_LimitSpellType: switch(base1) { case 0: if (!IsDetrimentalSpell(spell_id)) - LimitFound = true; + LimitFailure = true; break; case 1: if (!IsBeneficialSpell(spell_id)) - LimitFound = true; + LimitFailure = true; break; } - break; + break; - case SE_LimitManaCost: + case SE_LimitManaMin: if(spell.mana < base1) - LimitFound = true; - break; + LimitFailure = true; + break; + + case SE_LimitManaMax: + if(spell.mana > base1) + LimitFailure = true; + break; case SE_LimitTarget: - // Exclude - if(base1 < 0){ - if(-base1 == spell.targettype) - LimitFound = true; - } - // Include - else { - if(base1 != spell.targettype) - LimitFound = true; - } - break; + if (base1 < 0) { + if (-base1 == spell.targettype) //Exclude + LimitFailure = true; + } + else { + LimitInclude[6] = true; + if (base1 == spell.targettype) //Include + LimitInclude[7] = true; + } + break; - case SE_CombatSkills: - // 1 is for disciplines only - if(base1 == 1 && !IsDiscipline(spell_id)) - LimitFound = true; - // 0 is spells only - else if(base1 == 0 && IsDiscipline(spell_id)) - LimitFound = true; - break; + + case SE_LimitCombatSkills: + if (base1 == 0){ + if((spell.cast_time == 0) && (spell.recast_time == 0) && (spell.recovery_time == 0)) //Exclude procs + LimitFailure = true; + } + break; case SE_LimitSpellGroup: - if(base1 > 0 && base1 != spell.spellgroup) - LimitFound = true; - else if(base1 < 0 && base1 == spell.spellgroup) - LimitFound = true; - break; + if(base1 < 0) { + if (-base1 == spell.spellgroup) //Exclude + LimitFailure = true; + } + else { + LimitInclude[8] = true; + if (base1 == spell.spellgroup) //Include + LimitInclude[9] = true; + } + break; - - case SE_LimitSpellSkill: - LimitSpellSkill = true; - if(base1 == spell.skill) - SpellSkill_Found = true; - break; - - case SE_LimitExcludeSkill:{ - int16 spell_skill = spell.skill * -1; - if(base1 == spell_skill) - LimitFound = true; - 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; case SE_LimitClass: //Do not use this limit more then once per spell. If multiple class, treat value like items would. if (!PassLimitClass(base1, GetClass())) - LimitFound = true; - break; + LimitFailure = true; + break; case SE_LimitRace: - if (base1 != GetRace()) - LimitFound = true; - break; + if (base1 != GetRace()) + LimitFailure = true; + break; - case SE_FfLimitUseMin: - if (base1 > spell.numhits) - LimitFound = true; - break; + case SE_LimitUseMin: + if (base1 > spell.numhits) + LimitFailure = true; + break; - case SE_FfLimitUseType: - if (base1 != spell.numhitstype) - LimitFound = true; - break; + case SE_LimitUseType: + if (base1 != spell.numhitstype) + LimitFailure = true; + break; //Handle Focus Effects case SE_ImprovedDamage: if (type == focusImprovedDamage && base1 > value) value = base1; - break; + break; case SE_ImprovedHeal: if (type == focusImprovedHeal && base1 > value) value = base1; - break; + break; case SE_ReduceManaCost: - if (type == focusManaCost ) + if (type == focusManaCost) value = base1; break; @@ -4233,23 +4266,15 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) break; case SE_SpellHateMod: - if (type == focusSpellHateMod) - { - if(value != 0) - { - if(value > 0) - { + if (type == focusSpellHateMod ) { + if(value != 0) { + if(value > 0){ if(base1 > value) - { value = base1; - } } - else - { + else{ if(base1 < value) - { value = base1; - } } } else @@ -4258,196 +4283,123 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id) break; case SE_ReduceReuseTimer: - { if(type == focusReduceRecastTime) value = base1 / 1000; - break; - } case SE_TriggerOnCast: - { - if(type == focusTriggerOnCast) - { + if(type == focusTriggerOnCast){ if(MakeRandomInt(0, 100) <= base1){ value = base2; } else{ value = 0; - LimitFound = true; + LimitFailure = true; } - } break; - } - case SE_SpellVulnerability: - { + } + + case SE_FcSpellVulnerability: if(type == focusSpellVulnerability) - { value = base1; - } break; - } + case SE_BlockNextSpellFocus: - { - if(type == focusBlockNextSpell) - { + if(type == focusBlockNextSpell){ if(MakeRandomInt(1, 100) <= base1) value = 1; } break; - } - case SE_Twincast: - { + + case SE_FcTwincast: if(type == focusTwincast) - { value = base1; - } break; - } - /* case SE_SympatheticProc: - { - if(type == focusSympatheticProc) - { - float ProcChance, ProcBonus; - int16 ProcRateMod = base1; //Baseline is 100 for most Sympathetic foci - int32 cast_time = GetActSpellCasttime(spell_id, spells[spell_id].cast_time); - GetSympatheticProcChances(ProcBonus, ProcChance, cast_time, ProcRateMod); - - if(MakeRandomFloat(0, 1) <= ProcChance) - value = focus_id; - - else - value = 0; - } + //No AA support at this time. break; - } - */ + case SE_FcDamageAmt: - { if(type == focusFcDamageAmt) value = base1; - break; - } case SE_FcDamageAmtCrit: - { if(type == focusFcDamageAmtCrit) value = base1; - break; - } case SE_FcDamageAmtIncoming: - { if(type == focusFcDamageAmtIncoming) value = base1; - break; - } case SE_FcHealAmtIncoming: - { if(type == focusFcHealAmtIncoming) value = base1; - break; - } case SE_FcHealPctCritIncoming: - { if (type == focusFcHealPctCritIncoming) value = base1; - break; - } case SE_FcHealAmtCrit: - { if(type == focusFcHealAmtCrit) value = base1; - break; - } case SE_FcHealAmt: - { if(type == focusFcHealAmt) value = base1; - break; - } case SE_FcHealPctIncoming: - { if(type == focusFcHealPctIncoming) value = base1; - break; - } case SE_FcBaseEffects: - { if (type == focusFcBaseEffects) value = base1; - break; - } + case SE_FcDamagePctCrit: - { if(type == focusFcDamagePctCrit) value = base1; - break; - } - case SE_IncreaseNumHits: - { + case SE_FcIncreaseNumHits: if(type == focusIncreaseNumHits) value = base1; - break; - } - case SE_FcLimitUse: - { if(type == focusFcLimitUse) value = base1; - break; - } - case SE_FcMute: - { if(type == focusFcMute) value = base1; - break; - } case SE_FcStunTimeMod: - { if(type == focusFcStunTimeMod) value = base1; - break; - } } } - if (LimitSpellSkill && !SpellSkill_Found) - LimitFound = true; + for(int e = 0; e < MaxLimitInclude; e+=2) { + if (LimitInclude[e] && !LimitInclude[e+1]) + return 0; + } - if (LimitSpellEffect && !SpellEffect_Found) - LimitFound = true; - - if (LimitFound) + if (LimitFailure) return 0; return(value*lvlModifier/100); @@ -4468,54 +4420,60 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo int lvlModifier = 100; int spell_level = 0; int lvldiff = 0; - bool LimitSpellSkill = false; - bool SpellSkill_Found = false; - bool LimitSpellEffect = false; - bool SpellEffect_Found = false; uint32 Caston_spell_id = 0; + bool LimitInclude[MaxLimitInclude] = { false }; + /* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice spells. + 0/1 SE_LimitResist + 2/3 SE_LimitSpell + 4/5 SE_LimitEffect + 6/7 SE_LimitTarget + 8/9 SE_LimitSpellGroup: + 10/11 SE_LimitCastingSkill: + Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes + */ + for (int i = 0; i < EFFECT_COUNT; i++) { switch (focus_spell.effectid[i]) { + case SE_Blank: break; - //check limits - case SE_LimitResist:{ - if(focus_spell.base[i]){ - if(spell.resisttype != focus_spell.base[i]) - return(0); + case SE_LimitResist: + if(focus_spell.base[i] < 0){ + if (spell.resisttype == -focus_spell.base[i]) //Exclude + return 0; + } + else { + LimitInclude[0] = true; + if (spell.resisttype == focus_spell.base[i]) //Include + LimitInclude[1] = true; } break; - } - case SE_LimitInstant:{ + + case SE_LimitInstant: if(spell.buffduration) - return(0); + return 0; break; - } - case SE_LimitMaxLevel:{ + case SE_LimitMaxLevel: if (IsNPC()) break; spell_level = spell.classes[(GetClass()%16) - 1]; lvldiff = spell_level - focus_spell.base[i]; //every level over cap reduces the effect by focus_spell.base2[i] percent unless from a clicky when ItemCastsUseFocus is true - if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)) - { - if(focus_spell.base2[i] > 0) - { + if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)){ + if(focus_spell.base2[i] > 0){ lvlModifier -= focus_spell.base2[i]*lvldiff; if(lvlModifier < 1) return 0; } else - { return 0; - } } break; - } - + case SE_LimitMinLevel: if (IsNPC()) break; @@ -4523,19 +4481,25 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo return(0); break; - case SE_LimitCastTime: + case SE_LimitCastTimeMin: if (spells[spell_id].cast_time < (uint16)focus_spell.base[i]) return(0); break; + case SE_LimitCastTimeMax: + if (spells[spell_id].cast_time > (uint16)focus_spell.base[i]) + return(0); + break; + case SE_LimitSpell: - if(focus_spell.base[i] < 0) { //exclude spell - if (spell_id == (focus_spell.base[i]*-1)) - return(0); - } else { - //this makes the assumption that only one spell can be explicitly included... - if (spell_id != focus_spell.base[i]) + if(focus_spell.base[i] < 0) { //Exclude + if (spell_id == -focus_spell.base[i]) return(0); + } + else { + LimitInclude[2] = true; + if (spell_id == focus_spell.base[i]) //Include + LimitInclude[3] = true; } break; @@ -4546,37 +4510,19 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo case SE_LimitEffect: if(focus_spell.base[i] < 0){ - if(IsEffectInSpell(spell_id,(focus_spell.base[i] * -1))){ //we limit this effect, can't have + if(IsEffectInSpell(spell_id,-focus_spell.base[i])) //Exclude return 0; } - } else{ - if(focus_spell.base[i] == SE_SummonPet) //summoning haste special case - { //must have one of the three pet effects to qualify - if(!IsEffectInSpell(spell_id, SE_SummonPet) && - !IsEffectInSpell(spell_id, SE_NecPet) && - !IsEffectInSpell(spell_id, SE_SummonBSTPet)) - { - return 0; - } - } - //else if(!SpellEffect_Found && (!IsEffectInSpell(spell_id,focus_spell.base[i])){ //we limit this effect, must have - // return 0; - //} + LimitInclude[4] = true; + if(IsEffectInSpell(spell_id,focus_spell.base[i])) //Include + LimitInclude[5] = true; } - - if(focus_spell.base[i] >= 0){ - LimitSpellEffect = true; - if (IsEffectInSpell(spell_id,focus_spell.base[i])) - SpellEffect_Found = true; - } - break; case SE_LimitSpellType: - switch( focus_spell.base[i] ) - { + switch( focus_spell.base[i]){ case 0: if (!IsDetrimentalSpell(spell_id)) return 0; @@ -4590,50 +4536,59 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo } break; - case SE_LimitManaCost: - if(spell.mana < focus_spell.base[i]) - return 0; + case SE_LimitManaMin: + if(spell.mana < focus_spell.base[i]) + return 0; + break; + + case SE_LimitManaMax: + if(spell.mana > focus_spell.base[i]) + return 0; break; case SE_LimitTarget: - // Exclude - if((focus_spell.base[i] < 0) && -focus_spell.base[i] == spell.targettype) - return 0; - // Include - else if (focus_spell.base[i] > 0 && focus_spell.base[i] != spell.targettype) - return 0; - + if (focus_spell.base[i] < 0) { + if (-focus_spell.base[i] == spell.targettype) //Exclude + return 0; + } + else { + LimitInclude[6] = true; + if (focus_spell.base[i] == spell.targettype) //Include + LimitInclude[7] = true; + } break; - case SE_CombatSkills: - // 1 is for disciplines only - if(focus_spell.base[i] == 1 && !IsDiscipline(spell_id)) - return 0; - // 0 is for spells only - else if(focus_spell.base[i] == 0 && IsDiscipline(spell_id)) + case SE_LimitCombatSkills: + if (focus_spell.base[i] == 0){ + if((spell.cast_time == 0) && (spell.recast_time == 0) && (spell.recovery_time == 0)) //Exclude procs return 0; + } break; case SE_LimitSpellGroup: - if(focus_spell.base[i] > 0 && focus_spell.base[i] != spell.spellgroup) + if(focus_spell.base[i] < 0) { + if (-focus_spell.base[i] == spell.spellgroup) //Exclude return 0; - else if(focus_spell.base[i] < 0 && focus_spell.base[i] == spell.spellgroup) - return 0; - break; - - case SE_LimitSpellSkill: - LimitSpellSkill = true; - if(focus_spell.base[i] == spell.skill) - SpellSkill_Found = true; - break; - - case SE_LimitExcludeSkill:{ - int16 spell_skill = spell.skill * -1; - if(focus_spell.base[i] == spell_skill) - return 0; - break; } + else { + LimitInclude[8] = true; + if (focus_spell.base[i] == spell.spellgroup) //Include + LimitInclude[9] = true; + } + break; + case SE_LimitCastingSkill: + if(focus_spell.base[i] < 0) { + if(-focus_spell.base[i] == spell.skill) + return 0; + } + else { + LimitInclude[10] = true; + if(focus_spell.base[i] == spell.skill) + LimitInclude[11] = true; + } + break; + case SE_LimitClass: //Do not use this limit more then once per spell. If multiple class, treat value like items would. if (!PassLimitClass(focus_spell.base[i], GetClass())) @@ -4645,12 +4600,12 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo return 0; break; - case SE_FfLimitUseMin: + case SE_LimitUseMin: if (focus_spell.base[i] > spell.numhits) return 0; break; - case SE_FfLimitUseType: + case SE_LimitUseType: if (focus_spell.base[i] != spell.numhitstype) return 0; break; @@ -4663,7 +4618,6 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo //handle effects case SE_ImprovedDamage: - // No Spell used this, its handled by different spell effect IDs. if (type == focusImprovedDamage) { // This is used to determine which focus should be used for the random calculation if(best_focus) { @@ -4685,6 +4639,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo } } break; + case SE_ImprovedHeal: if (type == focusImprovedHeal) { if(best_focus) { @@ -4703,6 +4658,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo } } break; + case SE_ReduceManaCost: if (type == focusManaCost) { if(best_focus) { @@ -4724,70 +4680,54 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo case SE_IncreaseSpellHaste: if (type == focusSpellHaste && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_IncreaseSpellDuration: if (type == focusSpellDuration && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_SpellDurationIncByTic: if (type == focusSpellDurByTic && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_SwarmPetDuration: if (type == focusSwarmPetDuration && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_IncreaseRange: if (type == focusRange && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_ReduceReagentCost: if (type == focusReagentCost && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_PetPowerIncrease: if (type == focusPetPower && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_SpellResistReduction: if (type == focusResistRate && focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } break; + case SE_SpellHateMod: - if (type == focusSpellHateMod) - { - if(value != 0) - { - if(value > 0) - { + if (type == focusSpellHateMod){ + if(value != 0){ + if(value > 0){ if(focus_spell.base[i] > value) - { value = focus_spell.base[i]; - } } - else - { + else{ if(focus_spell.base[i] < value) - { value = focus_spell.base[i]; - } } } else @@ -4796,55 +4736,28 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo break; case SE_ReduceReuseTimer: - { if(type == focusReduceRecastTime) value = focus_spell.base[i] / 1000; - break; - } case SE_TriggerOnCast: - { - if(type == focusTriggerOnCast) - { - if(MakeRandomInt(0, 100) <= focus_spell.base[i]) + if(type == focusTriggerOnCast){ + if(MakeRandomInt(1, 100) <= focus_spell.base[i]) value = focus_spell.base2[i]; - else value = 0; } + break; - break; - } - case SE_SpellVulnerability: - { - if(type == focusSpellVulnerability) - { - value = focus_spell.base[i]; - } - break; - } case SE_BlockNextSpellFocus: - { - if(type == focusBlockNextSpell) - { + if(type == focusBlockNextSpell){ if(MakeRandomInt(1, 100) <= focus_spell.base[i]) value = 1; } break; - } - case SE_Twincast: - { - if(type == focusTwincast) - { - value = focus_spell.base[i]; - } - break; - } + case SE_SympatheticProc: - { - if(type == focusSympatheticProc) - { + if(type == focusSympatheticProc) { float ProcChance, ProcBonus; int16 ProcRateMod = focus_spell.base[i]; //Baseline is 100 for most Sympathetic foci int32 cast_time = GetActSpellCasttime(spell_id, spells[spell_id].cast_time); @@ -4857,118 +4770,91 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo value = 0; } break; - } + + case SE_FcSpellVulnerability: + if(type == focusSpellVulnerability) + value = focus_spell.base[i]; + break; + + case SE_FcTwincast: + if(type == focusTwincast) + value = focus_spell.base[i]; + break; + case SE_FcDamageAmt: - { if(type == focusFcDamageAmt) value = focus_spell.base[i]; - break; - } case SE_FcDamageAmtCrit: - { if(type == focusFcDamageAmtCrit) value = focus_spell.base[i]; - break; - } case SE_FcDamageAmtIncoming: - { if(type == focusFcDamageAmtIncoming) value = focus_spell.base[i]; - break; - } case SE_FcHealAmtIncoming: - { if(type == focusFcHealAmtIncoming) value = focus_spell.base[i]; - break; - } - case SE_FcHealPctCritIncoming: - { - if (type == focusFcHealPctCritIncoming) - value = focus_spell.base[i]; - - break; - } - - case SE_FcHealAmtCrit: - { - if(type == focusFcHealAmtCrit) - value = focus_spell.base[i]; - - break; - } - - case SE_FcHealAmt: - { - if(type == focusFcHealAmt) - value = focus_spell.base[i]; - - break; - } - - case SE_FcHealPctIncoming: - { - if(type == focusFcHealPctIncoming) - value = focus_spell.base[i]; - - break; - } - - case SE_FcBaseEffects: - { - if (type == focusFcBaseEffects) - value = focus_spell.base[i]; - - break; - } case SE_FcDamagePctCrit: - { if(type == focusFcDamagePctCrit) value = focus_spell.base[i]; - break; - } - case SE_IncreaseNumHits: - { + case SE_FcHealPctCritIncoming: + if (type == focusFcHealPctCritIncoming) + value = focus_spell.base[i]; + break; + + case SE_FcHealAmtCrit: + if(type == focusFcHealAmtCrit) + value = focus_spell.base[i]; + break; + + case SE_FcHealAmt: + if(type == focusFcHealAmt) + value = focus_spell.base[i]; + break; + + case SE_FcHealPctIncoming: + if(type == focusFcHealPctIncoming) + value = focus_spell.base[i]; + break; + + case SE_FcBaseEffects: + if (type == focusFcBaseEffects) + value = focus_spell.base[i]; + break; + + case SE_FcIncreaseNumHits: if(type == focusIncreaseNumHits) value = focus_spell.base[i]; - break; - } - case SE_FcLimitUse: - { if(type == focusFcLimitUse) value = focus_spell.base[i]; - break; - } case SE_FcMute: - { if(type == focusFcMute) value = focus_spell.base[i]; - break; - } case SE_FcStunTimeMod: - { if(type == focusFcStunTimeMod) value = focus_spell.base[i]; - break; - } + + case SE_FcTimerRefresh: + if(type == focusFcTimerRefresh) + value = focus_spell.base[i]; + break; #if EQDEBUG >= 6 //this spits up a lot of garbage when calculating spell focuses @@ -4977,13 +4863,13 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]); #endif } + } - //Check for spell skill limits. - if (LimitSpellSkill && !SpellSkill_Found) - return 0; - if (LimitSpellEffect && !SpellEffect_Found) - return 0; + for(int e = 0; e < MaxLimitInclude; e+=2) { + if (LimitInclude[e] && !LimitInclude[e+1]) + return 0; + } if (Caston_spell_id){ if(IsValidSpell(Caston_spell_id) && (Caston_spell_id != spell_id)) @@ -5330,7 +5216,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, uint32 buff_slot, uint16 spell_id) Field 175 = numhits type 1: [Incoming Hit Attempts] (323=SE_DefensiveProc, 172=SE_AvoidMeleeChance, 1=SE_ArmorClass, 40=SE_DivineAura) 2: [Outgoing Hit Attempts] (185=SE_DamageModifer, 184=SE_HitChance) - 3: [Incoming Spells] (180=SE_ResistSpellChance, 296=SE_SpellVulnerability) //Note: Determinetal spells only unless proven otherwise + 3: [Incoming Spells] (180=SE_ResistSpellChance, 296=SE_FcSpellVulnerability) //Note: Determinetal spells only unless proven otherwise 4: NONE 5: [Outgoing Hit Successes] (220=SE_SkillDamageAmount, 178=SE_MeleeLifetap, 121=SE_ReverseDS, ?373=SE_CastOnWearoff) 6: [Incoming Hit Successes] (59=SE_DamageShield, 197=SE_SkillDamageTaken, 162=define SE_MitigateMeleeDamage) @@ -5635,7 +5521,7 @@ int32 Mob::GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill, if (!skill_found){ if ((spells[buffs[i].spellid].effectid[e] == SE_LimitToSkill) || - (spells[buffs[i].spellid].effectid[e] == SE_LimitSpellSkill)){ + (spells[buffs[i].spellid].effectid[e] == SE_LimitCastingSkill)){ limit_exists = true; if (spells[buffs[i].spellid].base[e] == skill) diff --git a/zone/spells.cpp b/zone/spells.cpp index 795887e02..d3b24cd78 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -2689,7 +2689,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, effect1 == SE_LimitMinDur || effect1 == SE_LimitInstant || effect1 == SE_LimitMinLevel || - effect1 == SE_LimitCastTime) + effect1 == SE_LimitCastTimeMin) continue; /*