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