예제 #1
0
        public static void FixSealsAndJudgements()
        {
            CreateSealCalculators();

            // Only one Judgement per Paladin can be active at any one time
            AuraHandler.AddAuraCasterGroup(AllJudgements);

            // only one seal can be active at a time
            SealAuraId = AuraHandler.AddAuraGroup(AllSeals);

            // applying of seals allows the carrier to use judgements
            AllowJudgementEffectHandler.AddTo(AllSeals);

            // Judgements trigger this spell to "unleash" the seal
            SpellHandler.Apply(spell =>
            {
                spell.AddTargetTriggerSpells(SpellId.Judgement_5);
                spell.AttributesExB &= ~SpellAttributesExB.RequiresBehindTarget;
            }, AllJudgements);

            // these 2 seals' 3rd effect should trigger the debuff but have wrong settings
            SpellHandler.Apply(spell =>
            {
                var triggerEffect            = spell.Effects[2];
                triggerEffect.AuraType       = AuraType.ProcTriggerSpell;
                triggerEffect.TriggerSpellId = (SpellId)triggerEffect.BasePoints;
            },
                               SpellLineId.PaladinSealOfVengeance, SpellLineId.PaladinSealOfRighteousness);

            // Seal Of Righteousness is a positive aura and should be reapplied
            SpellHandler.Apply(spell =>
            {
                spell.HasBeneficialEffects = true;
            }, SpellLineId.PaladinSealOfRighteousness);

            /*
             * Most Judgements' ProcTriggerSpells need to be changed to use customized values, depending on spellpower, weapon damage etc...
             *
             *              - SpellLineId.PaladinSealOfJustice
             *                      -> Should work
             *              - SpellLineId.PaladinSealOfWisdom
             *                      -> Should work
             *
             *              - SpellLineId.PaladinSealOfRighteousness:
             *                      -> ClassSkillJudgementOfRighteousnessRank1: Dmg + ${$cond($eq($HND,1),0.85*($m1*1.2*1.03*$MWS/100)+0.03*($MW+$mw)/2-1,1.2*($m1*1.2*1.03*$MWS/100)+0.03*($MW+$mw)/2+1)}
             *
             *              - SpellLineId.PaladinSealOfLight:
             *                      -> EffectSealOfLight heals for ${0.15*$AP+0.15*$SPH}
             *
             *              - SpellLineId.PaladinSealOfVengeance:
             *                      -> ClassSkillJudgementOfVengeanceRank1:
             *                              - Dmg + ${(0.013*$SPH+0.025*$AP)*6} + 10% for each application of Blood Corruption on the target
             *                              - Once stacked to $31803u times, each of the Paladin's attacks also deals $42463s1% weapon damage as additional Holy damage.
             *
             *              - SpellLineId.PaladinRetributionSealOfCommand
             *                      -> All melee attacks deal ${0.36*$mw} to ${0.36*$MW} additional Holy damage.  When used with attacks or abilities that strike a single target, this additional Holy damage will strike up to 2 additional targets.
             */
        }
예제 #2
0
        public static void FixWarrior()
        {
            // Charge doesn't generate rage
            SpellLineId.WarriorCharge.Apply(spell =>
            {
                var effect = spell.GetEffect(SpellEffectType.Dummy);
                if (effect != null)
                {
                    effect.EffectType = SpellEffectType.Energize;
                    //effect.SpellEffectHandlerCreator =
                    //(cast, efct) => new EnergizeEffectHandler(cast, efct);
                    effect.MiscValue = (int)PowerType.Rage;
                }
            });

            // Slam has the wrong effect type
            SpellLineId.WarriorSlam.Apply(spell =>
            {
                var effect = spell.GetEffect(SpellEffectType.Dummy);
                if (effect != null)
                {
                    effect.EffectType = SpellEffectType.NormalizedWeaponDamagePlus;
                }
            });

            // Enrage and Wrecking Crew proc effects don't stack
            AuraHandler.AddAuraGroup(
                SpellId.EffectEnrageRank1_3, SpellId.EffectEnrageRank2_3, SpellId.EffectEnrageRank3_2,
                SpellId.EffectEnrageRank4_2, SpellId.EffectEnrageRank5_2,
                SpellId.EffectEnrageRank1, SpellId.EffectEnrageRank2, SpellId.EffectEnrageRank3,
                SpellId.EffectEnrageRank4, SpellId.EffectEnrageRank5);

            // Intimidating Shout should not have a single enemy target
            SpellLineId.WarriorChallengingShout.Apply(spell => spell.ForeachEffect(
                                                          effect => { effect.ImplicitTargetA = ImplicitSpellTargetType.AllEnemiesAroundCaster; }));

            // thunder clap should add about 15% AP to damage
            SpellLineId.WarriorThunderClap.Apply(spell => {
                var effect        = spell.AddEffect(SpellEffectType.Dummy, ImplicitSpellTargetType.AllEnemiesAroundCaster);
                effect.Radius     = 8;
                effect.BasePoints = 15;
                effect.SpellEffectHandlerCreator = (cast, effct) => new SchoolDamageByAPPctEffectHandler(cast, effct);
            });

            // Retaliation needs to retaliate
            SpellLineId.WarriorRetaliation.Apply(spell => {
                var effect    = spell.GetEffect(AuraType.Dummy);
                effect.IsProc = true;
                effect.AuraEffectHandlerCreator = () => new RetaliationEffectHandler();
            });

            // cleave should attack two enemies
            SpellLineId.WarriorCleave.Apply(spell =>
            {
                spell.Effects[0].ChainTargets = 2;
            });
        }
예제 #3
0
        /// <summary>
        /// Sends yet unknown information about a new object,
        /// such as Aura packets
        /// </summary>
        /// <param name="obj"></param>
        private void SendUnknownState(WorldObject obj)
        {
            if (obj is Unit)
            {
                var unit = (Unit)obj;

                if (unit.Auras.VisibleAuraCount > 0)
                {
                    AuraHandler.SendAllAuras(this, unit);
                }
            }
        }
예제 #4
0
        public static void FixDeathKnight()
        {
            //Forceful Reflection is missing stat values
            SpellHandler.Apply(spell =>
            {
                spell.Effects[0].MiscValue  = (int)CombatRating.Parry;
                spell.Effects[0].MiscValueB = (int)StatType.Strength;
            },
                               SpellId.ClassSkillForcefulDeflectionPassive);

            // Only one Presence may be active at a time
            AuraHandler.AddAuraGroup(SpellLineId.DeathKnightBloodPresence, SpellLineId.DeathKnightFrostPresence, SpellLineId.DeathKnightUnholyPresence);
        }
예제 #5
0
        public static void FixPaladin()
        {
            FixBlessings();
            FixStrongBuffs();
            FixHolyShock();

            // Players may only have one Hand on them per Paladin at any one time
            AuraHandler.AddAuraCasterGroup(
                SpellLineId.PaladinHandOfFreedom,
                SpellLineId.PaladinHandOfProtection,
                SpellLineId.PaladinHandOfReckoning,
                SpellLineId.PaladinHandOfSacrifice,
                SpellLineId.PaladinHandOfSalvation);
        }
예제 #6
0
        private static void FixBlessings()
        {
            // Normal and Greater blessings are mutually exclusive
            AuraHandler.AddAuraGroup(SpellLineId.PaladinBlessingOfKings, SpellLineId.PaladinGreaterBlessingOfKings);
            AuraHandler.AddAuraGroup(SpellLineId.PaladinBlessingOfMight, SpellLineId.PaladinGreaterBlessingOfMight);
            AuraHandler.AddAuraGroup(SpellLineId.PaladinBlessingOfWisdom, SpellLineId.PaladinGreaterBlessingOfWisdom);

            // only one blessing per pala
            AuraHandler.AddAuraCasterGroup(
                SpellLineId.PaladinBlessingOfKings,
                SpellLineId.PaladinBlessingOfMight,
                SpellLineId.PaladinBlessingOfWisdom,
                SpellLineId.PaladinGreaterBlessingOfKings,
                SpellLineId.PaladinGreaterBlessingOfMight,
                SpellLineId.PaladinGreaterBlessingOfWisdom,
                SpellLineId.PaladinGreaterBlessingOfSanctuary);

            // Sanctuary is a bit more complicated
            SpellHandler.Apply(spell =>
            {
                // first effect should mod damage taken
                var firstEffect = spell.Effects[0];
                if (firstEffect.EffectType == SpellEffectType.Dummy)
                {
                    firstEffect.EffectType = SpellEffectType.ApplyAura;
                    firstEffect.AuraType   = AuraType.ModDamageTakenPercent;
                }

                // Custom proc (target = the one who is blessed):
                // "When the target blocks, parries, or dodges a melee attack the target will gain $57319s1% of maximum displayed mana."
                spell.AddProcHandler(new TriggerSpellProcHandlerTemplate(
                                         SpellHandler.Get(SpellId.BlessingOfSanctuary),
                                         spell.ProcTriggerFlags,
                                         ProcHandler.DodgeBlockOrParryValidator
                                         ));

                // add str & stam
                var strEff        = spell.AddAuraEffect(AuraType.ModStatPercent, ImplicitSpellTargetType.SingleFriend);
                strEff.MiscValue  = (int)StatType.Strength;
                strEff.BasePoints = 10;

                var stamEff        = spell.AddAuraEffect(AuraType.ModStatPercent, ImplicitSpellTargetType.SingleFriend);
                stamEff.MiscValue  = (int)StatType.Stamina;
                stamEff.BasePoints = 10;
            },
                               SpellLineId.PaladinProtectionBlessingOfSanctuary,
                               SpellLineId.PaladinGreaterBlessingOfSanctuary);
        }
예제 #7
0
        public static void FixHunter()
        {
            // taming has an invalid target
            SpellHandler.Apply(spell =>
            {
                spell.GetEffect(AuraType.PeriodicTriggerSpell).ImplicitTargetA = ImplicitSpellTargetType.SingleEnemy;
            }, SpellId.ClassSkillTameBeast);

            // Only one Aspect can be active at a time
            AuraHandler.AddAuraGroup(SpellLineId.HunterAspectOfTheBeast, SpellLineId.HunterAspectOfTheCheetah,
                                     SpellLineId.HunterAspectOfTheDragonhawk, SpellLineId.HunterAspectOfTheHawk,
                                     SpellLineId.HunterAspectOfTheMonkey,
                                     SpellLineId.HunterAspectOfThePack, SpellLineId.HunterAspectOfTheViper,
                                     SpellLineId.HunterAspectOfTheWild);

            // Only one Sting per Hunter can be active on any one target
            AuraHandler.AddAuraGroup(SpellLineId.HunterSurvivalWyvernSting, SpellLineId.HunterSerpentSting,
                                     SpellLineId.HunterScorpidSting, SpellLineId.HunterViperSting, SpellLineId.HunterSerpentSting);

            // Sealed cooldowns
            SpellLineId.HunterScorpidSting.Apply(spell =>
            {
                spell.CooldownTime = 0;
            });

            SpellLineId.HunterConcussiveShot.Apply(spell =>
            {
                spell.CooldownTime = 12000;
            });

            SpellLineId.HunterSerpentSting.Apply(spell =>
            {
                spell.CooldownTime = 0;
            });

            SpellLineId.HunterViperSting.Apply(spell =>
            {
                spell.CooldownTime = 15000;
            });


            // Expose Weakness aura applied on the target  - Seems the spell has changed
            //SpellHandler.Apply(spell => spell.Effects[0].ImplicitTargetA = ImplicitTargetType.SingleEnemy,
            //                   SpellId.ExposeWeakness_2);
        }
예제 #8
0
 /// <summary>
 /// Called within Map Context.
 /// Sends initial packets
 /// </summary>
 private void OnLogin()
 {
     InstanceHandler.SendDungeonDifficulty(this);
     CharacterHandler.SendVerifyWorld(this);
     AccountDataHandler.SendAccountDataTimes(m_client);
     VoiceChatHandler.SendSystemStatus(this, VoiceSystemStatus.Disabled);
     // SMSG_GUILD_EVENT
     // SMSG_GUILD_BANK_LIST
     CharacterHandler.SendBindUpdate(this, BindLocation);
     TutorialHandler.SendTutorialFlags(this);
     SpellHandler.SendSpellsAndCooldowns(this);
     CharacterHandler.SendActionButtons(this);
     FactionHandler.SendFactionList(this);
     // SMSG_INIT_WORLD_STATES
     // SMSG_EQUIPMENT_SET_LIST
     AchievementHandler.SendAchievementData(this);
     // SMSG_EXPLORATION_EXPERIENCE
     CharacterHandler.SendTimeSpeed(this);
     TalentHandler.SendTalentGroupList(m_talents);
     AuraHandler.SendAllAuras(this);
     // SMSG_PET_GUIDS
 }
예제 #9
0
            protected override void Apply()
            {
                base.Apply();
                var chr = (Character)m_aura.Owner;

                if (chr != null)
                {
                    var aura = chr.Auras[SpellId.ResurrectionSickness];
                    if (aura != null)
                    {
                        if (chr.Level < 20)
                        {
                            aura.Duration = (chr.Level - 10) * 60000;
                            AuraHandler.SendAuraUpdate(aura.Owner, aura);
                        }
                        else
                        {
                            aura.Duration = 600000;
                            AuraHandler.SendAuraUpdate(aura.Owner, aura);
                        }
                    }
                }
            }
예제 #10
0
        protected override void Remove(bool cancelled)
        {
            base.Remove(cancelled);
            var chr = m_aura.Owner as Character;

            if (chr != null)
            {
                chr.Auras.Remove(SpellLineId.RogueVanish);

                //Overkill
                var overkill = chr.Auras[SpellId.ClassSkillOverkill];
                if (overkill != null)
                {
                    overkill.Duration = 20000;                    //20 sec
                    AuraHandler.SendAuraUpdate(m_aura.Owner, overkill);
                }
                //Master of Subtlety
                if (chr.Auras[SpellId.MasterOfSubtlety] != null)
                {
                    chr.SpellCast.Trigger(SpellId.MasterOfSubtlety_2, chr);                    //trigger periodic dummy
                }
            }
        }
예제 #11
0
        public static void FixIt()
        {
            // Improved Berserker Range can only be proc'ed by Berserker Rage
            SpellLineId.WarriorFuryImprovedBerserkerRage.Apply(spell =>
            {
                spell.AddCasterProcSpells(SpellLineId.WarriorBerserkerRage);
            });

            // Blood Thirst deals damage in % of AP and triggers a proc aura
            // It's proc'ed heal spell heals in % and not a flat value
            SpellLineId.WarriorFuryBloodthirst.Apply(spell =>
            {
                var effect = spell.GetEffect(SpellEffectType.SchoolDamage);
                effect.SpellEffectHandlerCreator = (cast, eff) => new SchoolDamageByAPPctEffectHandler(cast, eff);

                var triggerEffect            = spell.GetEffect(SpellEffectType.Dummy);
                triggerEffect.EffectType     = SpellEffectType.TriggerSpell;
                triggerEffect.TriggerSpellId = SpellId.ClassSkillBloodthirst;
            });
            SpellHandler.Apply(spell =>
            {
                var effect        = spell.GetEffect(SpellEffectType.Heal);
                effect.EffectType = SpellEffectType.RestoreHealthPercent;
                effect.BasePoints = 0;                  // only 1%
            }, SpellId.EffectClassSkillBloodthirst);

            // Intercept should also deal "${$AP*0.12} damage"
            SpellLineId.WarriorIntercept.Apply(spell =>
            {
                var effect           = spell.AddEffect(SpellEffectType.SchoolDamage, ImplicitSpellTargetType.SingleEnemy);
                effect.APValueFactor = 0.12f;
            });

            // There is only one shout per warrior
            AuraHandler.AddAuraCasterGroup(SpellLineId.WarriorBattleShout, SpellLineId.WarriorCommandingShout);
        }
예제 #12
0
        public static void Initialize2()
        {
            LoadOverrides();
            var learnSpells = new List <Spell>(5900);

            // set TriggerSpells and find TriggerSpell effects
            foreach (var spell in ById)
            {
                if (spell == null)
                {
                    continue;
                }
                spell.Initialize();

                if (spell.IsTeachSpell)
                {
                    learnSpells.Add(spell);
                }
                if (spell.DOEffect != null)
                {
                    DOSpells[spell.SpellId] = spell;
                }
            }

            AuraHandler.RegisterAuraUIDEvaluators();

            // 2nd init
            foreach (var spell in ById)
            {
                if (spell != null)
                {
                    spell.Init2();
                }
            }
            SkillHandler.Initialize2();
        }
예제 #13
0
        public static void FixMage()
        {
            FixMageGlyphs();

            // The improved counterspell aura should apply to Counterspell only
            SpellLineId.MageArcaneImprovedCounterspell.Apply(spell =>
            {
                spell.AddCasterProcSpells(SpellLineId.MageCounterspell);
            });

            // Cone of cold is missing Range
            SpellLineId.MageConeOfCold.Apply(spell =>
            {
                spell.Range.MaxDist = 10;
            });

            //molten armor buffs Crit rating based on your Spirit
            SpellLineId.MageMoltenArmor.Apply(spell =>
            {
                spell.Effects[2].MiscValue  = (int)StatType.Spirit;
                spell.Effects[2].MiscValueB = (int)CombatRating.SpellCritChance;
            });

            // MageIceBlock applies Hypothermia on every cast
            SpellLineId.MageIceBlock.Apply(spell => spell.AddCasterTriggerSpells(SpellId.Hypothermia));
            SpellHandler.Apply(spell =>
            {
                spell.IsPreventionDebuff = true;
            }, SpellId.Hypothermia);


            // Mage living bomb persists through death and should make boom when removed
            SpellLineId.MageFireLivingBomb.Apply(spell =>
            {
                spell.AttributesExC            = SpellAttributesExC.PersistsThroughDeath;
                spell.CanOverrideEqualAuraRank = false;
            });
            SpellHandler.Apply(spell =>
            {
                spell.Effects[1].TriggerSpellId           = SpellId.ClassSkillLivingBombRank1;
                spell.Effects[1].AuraEffectHandlerCreator =
                    () => new TriggerSpellAfterAuraRemovedHandler();
            }, SpellId.MageFireLivingBombRank1);
            SpellHandler.Apply(spell =>
            {
                spell.Effects[1].TriggerSpellId           = SpellId.ClassSkillLivingBombRank2_2;
                spell.Effects[1].AuraEffectHandlerCreator =
                    () => new TriggerSpellAfterAuraRemovedHandler();
            }, SpellId.ClassSkillLivingBombRank2);
            SpellHandler.Apply(spell =>
            {
                spell.Effects[1].TriggerSpellId           = SpellId.ClassSkillLivingBombRank3_2;
                spell.Effects[1].AuraEffectHandlerCreator =
                    () => new TriggerSpellAfterAuraRemovedHandler();
            }, SpellId.ClassSkillLivingBombRank3);

            // These spells cancel eachother
            AuraHandler.AddAuraGroup(SpellLineId.MageFrostArmor, SpellLineId.MageIceArmor, SpellLineId.MageMageArmor, SpellLineId.MageMoltenArmor);

            // Mana gems don't have a limit
            SpellHandler.Apply(spell =>
            {
                spell.RemoveEffect(SpellEffectType.CreateItem);
                var efct            = spell.GetEffect(SpellEffectType.Dummy);
                efct.EffectType     = SpellEffectType.TriggerSpell;
                efct.TriggerSpellId = (SpellId)efct.CalcEffectValue();
            }, SpellLineId.MageConjureManaGem);
        }
예제 #14
0
        public static void FixWarlock()
        {
            // Curse of Doom cannot be casted on Players and spawns a Demon on target death
            SpellLineId.WarlockCurseOfDoom.Apply(spell =>
            {
                spell.CanCastOnPlayer = false;
                spell.Effects[0].AuraEffectHandlerCreator = () => new SummonDoomguardOnDeathHandler();
            });

            // Armors are mutually exclusive
            AuraHandler.AddAuraGroup(SpellLineId.WarlockFelArmor, SpellLineId.WarlockDemonArmor, SpellLineId.WarlockDemonSkin);

            // can't have more than one of these per caster
            AuraHandler.AddAuraCasterGroup(
                SpellLineId.WarlockCurseOfTongues, SpellLineId.WarlockCurseOfTheElements,
                SpellLineId.WarlockCurseOfDoom, SpellLineId.WarlockCurseOfAgony,
                SpellLineId.WarlockCurseOfWeakness, SpellLineId.WarlockAfflictionCurseOfExhaustion);

            // Shadowflame DoT
            SpellHandler.Apply(spell => spell.AddTargetTriggerSpells(SpellId.Shadowflame_3), SpellId.ClassSkillShadowflameRank1);
            SpellHandler.Apply(spell => spell.AddTargetTriggerSpells(SpellId.Shadowflame_5), SpellId.ClassSkillShadowflameRank2);
            SpellHandler.Apply(spell =>
            {
                spell.Effects[0].ImplicitTargetA = ImplicitSpellTargetType.ConeInFrontOfCaster;
                spell.AddAuraEffect(() => new ApplyImmolateStateHandler(), ImplicitSpellTargetType.SingleEnemy);
            }, SpellId.Shadowflame_3);
            SpellHandler.Apply(spell =>
            {
                spell.Effects[0].ImplicitTargetA = ImplicitSpellTargetType.ConeInFrontOfCaster;
                spell.AddAuraEffect(() => new ApplyImmolateStateHandler(), ImplicitSpellTargetType.SingleEnemy);
            }, SpellId.Shadowflame_5);

            // Incinerate has extra damage if target has Immolate
            SpellLineId.WarlockIncinerate.Apply(spell =>
                                                spell.Effects[0].SpellEffectHandlerCreator = (cast, effect) => new IncreaseDamageIfAuraPresentHandler(cast, effect));

            // Demonic Circle Teleport
            var teleReqSpell = SpellHandler.AddCustomSpell(62388, "DemonicCircleTeleportRequirement");

            teleReqSpell.IsPreventionDebuff = false;
            teleReqSpell.AddAuraEffect(AuraType.Dummy);
            teleReqSpell.Attributes |= SpellAttributes.InvisibleAura;
            teleReqSpell.Durations   = new Spell.DurationEntry {
                Min = 360000, Max = 360000
            };
            SpellHandler.Apply(spell =>
            {
                var efct       = spell.AddEffect(SpellEffectType.Dummy, ImplicitSpellTargetType.None);
                efct.MiscValue = (int)GOEntryId.DemonicCircleSummon;
                efct.SpellEffectHandlerCreator = (cast, effect) => new RecallToGOHandler(cast, effect);
                spell.AddCasterTriggerSpells(teleReqSpell);
            }, SpellId.ClassSkillDemonicCircleTeleport);

            // Demonic Circle Summon
            SpellHandler.Apply(spell => spell.AddCasterTriggerSpells(teleReqSpell.SpellId), SpellLineId.WarlockDemonicCircleSummon);

            //life tap
            SpellHandler.Apply(spell =>
            {
                var spellEffect = spell.GetEffect(SpellEffectType.Dummy);
                spellEffect.SpellEffectHandlerCreator = (cast, effect) => new LifeTapHandler(cast, effect);
            }, SpellLineId.WarlockLifeTap);

            SpellLineId.WarlockImmolate.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ApplyImmolateStateHandler(), ImplicitSpellTargetType.SingleEnemy);
            });

            SpellLineId.WarlockDestructionConflagrate.Apply(spell =>
            {
                var dmgeff         = spell.GetEffect(SpellEffectType.SchoolDamage);
                var periodicdmgeff = spell.GetEffect(AuraType.PeriodicDamage);
                dmgeff.SpellEffectHandlerCreator        = (cast, effect) => new ConflagrateHandler(cast, effect);
                periodicdmgeff.AuraEffectHandlerCreator = () => new ConflagratePeriodicHandler();
            });
        }
예제 #15
0
        public static void FixIt()
        {
            // Illumination lets the caster "gain mana equal to $s2% of the base cost of the spell", also works for Holy Shock heals
            SpellLineId.PaladinHolyIllumination.Apply(spell =>
            {
                var invalidProcEffect    = spell.GetEffect(AuraType.ProcTriggerSpell);
                invalidProcEffect.IsProc = false;                       // don't proc (refers to non-existing spell)

                var effect    = spell.GetEffect(AuraType.OverrideClassScripts);
                effect.IsProc = true;
                effect.AddToAffectMask(SpellLineId.PaladinHolyHolyShock);                                       // also works for Holy Shock
                effect.AuraEffectHandlerCreator = () => new IlluminationHandler();
            });

            SpellLineId.PaladinRedemption.Apply(spell =>
            {
                var effect             = spell.GetEffect(SpellEffectType.ResurrectFlat);
                effect.ImplicitTargetA = ImplicitSpellTargetType.SingleFriend;
            });

            // Improved Lay On Hands needs the lay on hands spell restriction and correct proc flags
            SpellLineId.PaladinHolyImprovedLayOnHands.Apply(spell =>
            {
                spell.ProcTriggerFlags = ProcTriggerFlags.DoneBeneficialMagicSpell;
                spell.GetEffect(AuraType.ProcTriggerSpell).AddToAffectMask(SpellLineId.PaladinLayOnHands);
            });

            // Sacred Cleansing should proc on Cleanse
            SpellLineId.PaladinHolySacredCleansing.Apply(spell =>
            {
                var procEffect = spell.GetEffect(AuraType.ProcTriggerSpell);
                procEffect.ClearAffectMask();
                //procEffect.AddToAffectMask(SpellLineId.PaladinCleanse);
                procEffect.AddAffectingSpells(SpellLineId.PaladinCleanse);
            });

            // Judgements of the Pure procs on all judgements
            SpellLineId.PaladinHolyJudgementsOfThePure.Apply(spell =>
            {
                var procEff = spell.GetEffect(AuraType.ProcTriggerSpell);
                procEff.ClearAffectMask();
                procEff.AddToAffectMask(SealsAndJudgements.AllJudgements);
            });

            // Holy Wrath "causing ${$m1+0.07*$SPH+0.07*$AP} to ${$M1+0.07*$SPH+0.07*$AP} Holy damage (...)  for $d"
            SpellLineId.PaladinHolyWrath.Apply(spell =>
            {
                var effect                = spell.GetEffect(SpellEffectType.SchoolDamage);
                effect.APValueFactor      = 0.07f;
                effect.SpellPowerValuePct = 7;
            });

            // Exorcism "Causes ${$m1+0.15*$SPH+0.15*$AP} to ${$M1+0.15*$SPH+0.15*$AP}" and crits against demons and the undead
            SpellLineId.PaladinExorcism.Apply(spell =>
            {
                var dmgEffect                = spell.GetEffect(SpellEffectType.SchoolDamage);
                dmgEffect.APValueFactor      = 0.15f;
                dmgEffect.SpellPowerValuePct = 15;

                //var critMonsterEffect =
                spell.AddAuraEffect(() => new CritCreatureMaskHandler(CreatureMask.Demon | CreatureMask.Undead),
                                    dmgEffect.ImplicitTargetA);
            });

            // Lay on Hands applies Forbearance, if used on self
            SpellLineId.PaladinLayOnHands.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ApplySelfForbearanceHandler(), ImplicitSpellTargetType.Self);
            });

            // The buff of Paladin Sacred Shield should proc on hit
            SpellLineId.PaladinSacredShield.Apply(spell =>
            {
                spell.ProcDelay = 6000;
                var effect      = spell.GetEffect(AuraType.Dummy);
                effect.IsProc   = true;
                effect.AuraEffectHandlerCreator = () => new SacredShieldHandler();
            });

            SpellHandler.Apply(spell =>
            {
                var effect       = spell.GetEffect(AuraType.Dummy);
                effect.AuraType  = AuraType.AddModifierFlat;
                effect.MiscValue = (int)SpellModifierType.CritChance;
                effect.AddToAffectMask(SpellLineId.PaladinFlashOfLight);
            }, SpellId.EffectSacredShieldRank1);

            // Only one seal active at a time
            AuraHandler.AddAuraGroup(SpellLineId.PaladinSealOfWisdom, SpellLineId.PaladinSealOfVengeance,
                                     SpellLineId.PaladinSealOfRighteousness,
                                     SpellLineId.PaladinSealOfLight, SpellLineId.PaladinSealOfJustice,
                                     SpellLineId.PaladinSealOfCorruption);
        }
예제 #16
0
        public static void FixIt()
        {
            // Thick Hide needs to be restricted to "cloth and leather items"
            SpellLineId.DruidFeralCombatThickHide.Apply(spell =>
            {
                spell.RequiredItemClass        = ItemClass.Armor;
                spell.RequiredItemSubClassMask = ItemSubClassMask.ArmorCloth | ItemSubClassMask.ArmorLeather;
            });

            // Sharpened Claws only works "while in Bear, Dire Bear or Cat Form"
            SpellLineId.DruidFeralCombatSharpenedClaws.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear | ShapeshiftMask.Cat;
            });

            // Primal Fury is triggered by critical hits and only active in "in Bear and Dire Bear Form"
            SpellLineId.DruidFeralCombatPrimalFury.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear;
            });

            // Heart of the wild: "while in Bear or Dire Bear Form your Stamina is increased by $s3% and while in Cat Form your attack power is increased by $s2%."
            SpellLineId.DruidFeralCombatHeartOfTheWild.Apply(spell =>
            {
                var dummy = spell.GetEffect(SpellEffectType.Dummy);

                // increase 10% of something, depending on the form
                var bearEffect = spell.AddAuraEffect(AuraType.ModTotalStatPercent);
                bearEffect.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear;
                bearEffect.MiscValue  = (int)StatType.Stamina;                                                                                          // increases stamina
                bearEffect.BasePoints = dummy.BasePoints;
                bearEffect.DiceSides  = dummy.DiceSides;

                var catEffect = spell.AddAuraEffect(AuraType.ModAttackPowerPercent);
                catEffect.RequiredShapeshiftMask = ShapeshiftMask.Cat;
                catEffect.BasePoints             = dummy.BasePoints;
                catEffect.DiceSides = dummy.DiceSides;
            });

            // Leader of the Pack toggles an Aura "While in Cat, Bear or Dire Bear Form"
            SpellLineId.DruidFeralCombatLeaderOfThePack.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Cat | ShapeshiftMask.Bear | ShapeshiftMask.DireBear;

                // toggle the party aura, whenever the druid shifts into cat bear or dire bear form:
                spell.GetEffect(AuraType.Dummy).AuraEffectHandlerCreator = () => new ToggleAuraHandler(SpellId.LeaderOfThePack);
            });
            // triggered Aura of LotP: First effect has invalid radius; 2nd effect is the proc effect for the Improved LotP buff
            SpellHandler.Apply(spell =>
            {
                spell.ForeachEffect(effect => effect.Radius = 45);                      // fix radius

                // "heal themselves for $s1% of their total health when they critically hit with a melee or ranged attack"
                spell.ProcTriggerFlags = ProcTriggerFlags.DoneMeleeSpell | ProcTriggerFlags.DoneMeleeAutoAttack | ProcTriggerFlags.DoneRangedAutoAttack | ProcTriggerFlags.DoneRangedSpell;

                // "The healing effect cannot occur more than once every 6 sec"
                spell.ProcDelay = 6000;

                // make this a special proc
                var dummy    = spell.GetEffect(AuraType.Dummy);
                dummy.IsProc = true;
                dummy.AuraEffectHandlerCreator = () => new ImprovedLeaderOfThePackProcHandler();
            },
                               SpellId.LeaderOfThePack);

            // Primal Tenacity has the wrong effect type: "reduces all damage taken while stunned by $s2% while in Cat Form."
            SpellLineId.DruidFeralCombatPrimalTenacity.Apply(spell =>
            {
                var effect      = spell.GetEffect(AuraType.SchoolAbsorb);
                effect.AuraType = AuraType.ModDamageTakenPercent;                               // should reduce damage taken
            });

            // Survival of the Fittest "increases your armor contribution from cloth and leather items in Bear Form and Dire Bear Form by $s3%"
            SpellLineId.DruidFeralCombatSurvivalOfTheFittest.Apply(spell =>
            {
                var effect = spell.GetEffect(SpellEffectType.Dummy);
                effect.RequiredShapeshiftMask   = ShapeshiftMask.Bear | ShapeshiftMask.DireBear;
                effect.AuraEffectHandlerCreator = () => new SurvivalOfTheFittestHandler();
            });

            // Nurturing Instinct simply toggles an aura when in cat form: "and increases healing done to you by $47179s1% while in Cat form."
            SpellHandler.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.NurturingInstinctRank1)).RequiredShapeshiftMask = ShapeshiftMask.Cat;
            },
                               SpellId.DruidFeralCombatNurturingInstinctRank1);
            SpellHandler.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.NurturingInstinctRank2)).RequiredShapeshiftMask = ShapeshiftMask.Cat;
            },
                               SpellId.DruidFeralCombatNurturingInstinctRank2);

            // Infected Wounds: "Your Shred, Maul, and Mangle attacks cause an Infected Wound in the target"
            SpellLineId.DruidFeralCombatInfectedWounds.Apply(spell =>
            {
                var effect = spell.GetEffect(AuraType.ProcTriggerSpell);

                // can only be proc'ed by a certain set of spells:
                effect.AddToAffectMask(SpellLineId.DruidShred, SpellLineId.DruidMaul, SpellLineId.DruidMangleBear, SpellLineId.DruidMangleCat);
            });

            // King of the Jungle has 2 dummies for shapeshift-restricted aura effects
            SpellLineId.DruidFeralCombatKingOfTheJungle.Apply(spell =>
            {
                // "While using your Enrage ability in Bear Form or Dire Bear Form, your damage is increased by $s1%"
                var effect1        = spell.Effects[0];
                effect1.EffectType = SpellEffectType.ApplyAura;
                effect1.AuraType   = AuraType.ModDamageDonePercent;
                effect1.AddToAffectMask(SpellLineId.DruidEnrage);
                effect1.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear;

                // "your Tiger's Fury ability also instantly restores $s2 energy"
                var effect2        = spell.Effects[1];
                effect2.EffectType = SpellEffectType.Energize;
                effect2.AddToAffectMask(SpellLineId.DruidTigersFury);
            });

            // "You cannot use Tiger's Fury while Berserk is active."
            AuraHandler.AddAuraGroup(SpellLineId.DruidTigersFury, SpellLineId.DruidFeralCombatBerserk);

            // Berserk triggers another spell
            SpellLineId.DruidFeralCombatBerserk.Apply(spell =>
            {
                // "causes your Mangle (Bear) ability to hit up to $58923s1 targets"
                spell.AddTriggerSpellEffect(SpellId.Berserk_14);
            });

            FixFeralSwiftness(SpellId.DruidFeralCombatFeralSwiftness, SpellId.FeralSwiftnessPassive1a);
            FixFeralSwiftness(SpellId.DruidFeralCombatFeralSwiftness_2, SpellId.FeralSwiftnessPassive2a);

            // PotP only works in Bear or Dire Bear form
            SpellLineId.DruidFeralCombatProtectorOfThePack.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear;
            });

            // NR only works in Bear or Dire Bear form, procs only on dodge
            SpellLineId.DruidFeralCombatNaturalReaction.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear;

                // only proc the trigger spell on dodge
                var triggerSpellEffect = spell.RemoveEffect(AuraType.ProcTriggerSpell);
                spell.AddProcHandler(new TriggerSpellProcHandlerTemplate(
                                         SpellHandler.Get(triggerSpellEffect.TriggerSpellId),
                                         spell.ProcTriggerFlags,
                                         ProcHandler.DodgeValidator
                                         ));
            });

            // SI only has a dummy
            SpellLineId.DruidFeralCombatSurvivalInstincts.Apply(spell =>
            {
                // "grants you $s1% of your maximum health"
                var dummy      = spell.GetEffect(AuraType.Dummy);
                dummy.AuraType = AuraType.ModIncreaseHealthPercent;

                // "while in Bear Form, Cat Form, or Dire Bear Form"
                spell.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear | ShapeshiftMask.Cat;
            });

            // Rip: Also does damage based on APs and CPs
            SpellLineId.DruidRip.Apply(spell =>
            {
                var effect = spell.GetEffect(AuraType.PeriodicDamage);
                effect.APPerComboPointValueFactor = 0.01f;
            });

            // Rake has + AP damage
            SpellLineId.DruidRake.Apply(spell =>
            {
                // "Rake the target for ${$AP/100+$m1} bleed damage and an additional ${$m2*3+$AP*0.18} damage over $d"
                var dmgEffect           = spell.GetEffect(SpellEffectType.SchoolDamage);
                dmgEffect.APValueFactor = 0.01f;

                var dotEffect           = spell.GetEffect(AuraType.PeriodicDamage);
                dotEffect.APValueFactor = 0.18f / dotEffect.GetMaxTicks();
            });

            // Maul: "Effects which increase Bleed damage also increase Maul damage."
            SpellLineId.DruidMaul.Apply(spell =>
            {
                // TODO: "Causes a high amount of threat"
                spell.GetEffect(SpellEffectType.WeaponDamage).SpellEffectHandlerCreator = (cast, effct) => new AddBleedWeaponDamageHandler(cast, effct);
            });

            // Shred: "Effects which increase Bleed damage also increase Shred damage."
            SpellLineId.DruidShred.Apply(spell =>
            {
                spell.GetEffect(SpellEffectType.WeaponDamage).SpellEffectHandlerCreator = (cast, effct) => new AddBleedWeaponDamageHandler(cast, effct);
            });

            // Bash "interrupts non-player spellcasting for $32747d."
            SpellLineId.DruidBash.Apply(spell =>
            {
                spell.AddTriggerSpellEffect(SpellId.InterruptRank1, ImplicitSpellTargetType.SingleEnemy);
            });

            // FR: "Converts up to 10 rage per second into health for $d.  Each point of rage is converted into ${$m2/10}.1% of max health."
            SpellLineId.DruidFrenziedRegeneration.Apply(spell =>
            {
                var dummy       = spell.GetEffect(SpellEffectType.Dummy);
                dummy.Amplitude = 1000;
                dummy.AuraEffectHandlerCreator = () => new FrenziedGenerationHandler();
            });

            // Save Roar has two dummy effects
            SpellLineId.DruidSavageRoar.Apply(spell =>
            {
                // "Only useable while in Cat Form"
                spell.RequiredShapeshiftMask = ShapeshiftMask.Cat;

                // set correct target type
                spell.GetEffect(SpellEffectType.Dummy).ImplicitTargetA = ImplicitSpellTargetType.Self;

                // aura increases dmg done %
                spell.GetEffect(AuraType.Dummy).AuraType = AuraType.ModDamageDonePercent;
            });

            // Ferocious Bite deals damage per AP & CP: "1 point  : ${$m1+$b1*1+0.07*$AP}-${$M1+$b1*1+0.07*$AP} damage"
            //		"and converts each extra point of energy (up to a maximum of $s2 extra energy) into ${$f1+$AP/410}.1 additional damage"
            SpellLineId.DruidFerociousBite.Apply(spell =>
            {
                // damage is increased by AP & CP
                var dmgEffect = spell.GetEffect(SpellEffectType.SchoolDamage);
                dmgEffect.APPerComboPointValueFactor = 0.07f;
                dmgEffect.SpellEffectHandlerCreator  = (cast, effct) => new FerociousBiteHandler(cast, effct);
            });

            // Cat Form has a periodic effect that should trigger a passive aura
            SpellLineId.DruidCatForm.Apply(spell =>
            {
                spell.RemoveEffect(AuraType.PeriodicTriggerSpell);

                // "increasing melee attack power by $3025s1 plus Agility"
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.ClassSkillCatFormPassivePassive));
            });
            SpellHandler.Apply(spell =>
            {
                // "increasing melee attack power by $3025s1 plus Agility"
                // => Add 100% of agility to AP
                var apMod        = spell.AddAuraEffect(AuraType.ModMeleeAttackPowerByPercentOfStat);
                apMod.MiscValue  = (int)StatType.Agility;
                apMod.BasePoints = 100;
            }, SpellId.ClassSkillCatFormPassivePassive);

            // Flight form also toggles a passive Aura while activated
            SpellLineId.DruidSwiftFlightForm.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.SwiftFlightFormPassivePassive));
            });

            // Lacerate is only usable in Bear form
            SpellLineId.DruidLacerate.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Bear;

                // "Introduced attack power scaling: Every 20 Attack Power adds 1 damage, per stack, over 15 seconds. Mangle further enhances this value."
                spell.GetEffect(AuraType.PeriodicDamage).APValueFactor = 0.05f;
            });

            // Aqua form also toggles a passive Aura while activated
            SpellLineId.DruidAquaticForm.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.ClassSkillAquaticFormPassivePassive));
            });

            // Enrage "reduces base armor by 27% in Bear Form and 16% in Dire Bear Form"
            SpellLineId.DruidEnrage.Apply(spell =>
            {
                var bearEffect                    = spell.AddAuraEffect(AuraType.ModResistancePercent);
                bearEffect.MiscValue              = (int)DamageSchool.Physical;
                bearEffect.BasePoints             = 27;
                bearEffect.RequiredShapeshiftMask = ShapeshiftMask.Bear;

                var direBearEffect                    = spell.AddAuraEffect(AuraType.ModResistancePercent);
                direBearEffect.MiscValue              = (int)DamageSchool.Physical;
                direBearEffect.BasePoints             = 16;
                direBearEffect.RequiredShapeshiftMask = ShapeshiftMask.DireBear;
            });

            // Mangle (Cat) triggers a spell to add a CP
            SpellLineId.DruidMangleCat.Apply(spell =>
            {
                spell.AddTriggerSpellEffect(SpellId.ComboPoint);
            });

            // Dire Bear is missing it's passive Aura
            SpellLineId.DruidDireBearForm.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.ClassSkillDireBearFormPassivePassive));
            });

            // Travel form also requires it's passive Aura
            SpellLineId.DruidTravelForm.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.TravelFormPassivePassive));
            });

            // Savage Defense has wrong trigger flags & it's buff has wrong effect type
            SpellLineId.DruidSavageDefense.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Bear | ShapeshiftMask.DireBear;
            });
            SpellHandler.Apply(spell =>
            {
                spell.GetEffect(AuraType.SchoolAbsorb).AuraType = AuraType.ModDamageTakenPercent;
            }, SpellId.EffectSavageDefense);

            // Flight Form is also missing it's passive Aura
            SpellLineId.DruidFlightForm.Apply(spell =>
            {
                spell.AddAuraEffect(() => new ToggleAuraHandler(SpellId.FlightFormPassivePassive));
            });

            //Wrong Facing Requirement
            SpellLineId.DruidPounce.Apply(spell =>
            {
                spell.AttributesExB = SpellAttributesExB.None;
            });

            // Druid Faerie Fire / Druid Faerie Fire (Feral)
            // Should add stealth/invis immunity to the target.
            SpellHandler.Apply(spell =>
            {
                var stealth = spell.AddAuraEffect(AuraType.DispelImmunity, ImplicitSpellTargetType.SingleEnemy);
                var invis   = spell.AddAuraEffect(AuraType.DispelImmunity, ImplicitSpellTargetType.SingleEnemy);

                stealth.MiscValue = (int)DispelType.Stealth;
                invis.MiscValue   = (int)DispelType.Invisibility;
            }, SpellLineId.DruidFaerieFire, SpellLineId.DruidFaerieFireFeral);

            FixBloodFrenzy();

            // Dash should only be usable while in cat form
            SpellLineId.DruidDash.Apply(spell =>
            {
                spell.RequiredShapeshiftMask = ShapeshiftMask.Cat;
            });
        }