diff --git a/Source/Scripts/Spells/DeathKnight.cs b/Source/Scripts/Spells/DeathKnight.cs index c68c49d03..4929f9c6f 100644 --- a/Source/Scripts/Spells/DeathKnight.cs +++ b/Source/Scripts/Spells/DeathKnight.cs @@ -20,6 +20,7 @@ using Game.Entities; using Game.Scripting; using Game.Spells; using System.Collections.Generic; +using Game.Networking.Packets; namespace Scripts.Spells.DeathKnight { @@ -45,7 +46,6 @@ namespace Scripts.Spells.DeathKnight public const uint DeathStrikeOffhand = 66188; public const uint FesteringWound = 194310; public const uint Frost = 137006; - public const uint FrostFever = 55095; public const uint GlyphOfFoulMenagerie = 58642; public const uint GlyphOfTheGeist = 58640; public const uint GlyphOfTheSkeleton = 146652; @@ -111,6 +111,10 @@ namespace Scripts.Spells.DeathKnight [Script] // 48707 - Anti-Magic Shell class spell_dk_anti_magic_shell : AuraScript { + int absorbPct; + ulong maxHealth; + uint absorbedAmount; + public spell_dk_anti_magic_shell() { absorbPct = 0; @@ -126,14 +130,14 @@ namespace Scripts.Spells.DeathKnight public override bool Load() { absorbPct = GetSpellInfo().GetEffect(1).CalcValue(GetCaster()); - maxHealth = (int)GetCaster().GetMaxHealth(); + maxHealth = GetCaster().GetMaxHealth(); absorbedAmount = 0; return true; } void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) { - amount = MathFunctions.CalculatePct(maxHealth, absorbPct); + amount = (int)MathFunctions.CalculatePct(maxHealth, absorbPct); } void Trigger(AuraEffect aurEff, DamageInfo dmgInfo, ref uint absorbAmount) @@ -163,13 +167,9 @@ namespace Scripts.Spells.DeathKnight AfterEffectAbsorb.Add(new EffectAbsorbHandler(Trigger, 0)); AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.SchoolAbsorb, AuraEffectHandleModes.Real)); } - - int absorbPct; - int maxHealth; - uint absorbedAmount; } - [Script] // 127517 - Army Transform // 6.x, does this belong here or in spell_generic? where do we cast this? sniffs say this is only cast when caster has glyph of foul menagerie. + [Script] // 127517 - Army Transform class spell_dk_army_transform : SpellScript { public override bool Validate(SpellInfo spellInfo) @@ -223,7 +223,7 @@ namespace Scripts.Spells.DeathKnight } } - [Script] // 49028 - Dancing Rune Weapon 7.1.5 + [Script] // 49028 - Dancing Rune Weapon class spell_dk_dancing_rune_weapon : AuraScript { public override bool Validate(SpellInfo spellInfo) @@ -262,10 +262,10 @@ namespace Scripts.Spells.DeathKnight if (damageInfo == null || damageInfo.GetDamage() == 0) return; - int amount = (int)(damageInfo.GetDamage() / 2); - SpellNonMeleeDamage log = new SpellNonMeleeDamage(drw, drw.GetVictim(), spellInfo, new Game.Networking.Packets.SpellCastVisual(spellInfo.GetSpellXSpellVisualId(drw), 0), spellInfo.GetSchoolMask()); + int amount = (int)damageInfo.GetDamage() / 2; + SpellNonMeleeDamage log = new SpellNonMeleeDamage(drw, drw.GetVictim(), spellInfo, new SpellCastVisual(spellInfo.GetSpellXSpellVisualId(drw), 0), spellInfo.GetSchoolMask()); log.damage = (uint)amount; - drw.DealDamage(drw.GetVictim(), (uint)amount, null, DamageEffectType.Direct, spellInfo.GetSchoolMask(), spellInfo, true); + drw.DealDamage(drw.GetVictim(), (uint)amount, null, DamageEffectType.SpellDirect, spellInfo.GetSchoolMask(), spellInfo, true); drw.SendSpellNonMeleeDamageLog(log); } @@ -276,7 +276,7 @@ namespace Scripts.Spells.DeathKnight } [Script] // 43265 - Death and Decay - class spell_dk_death_and_decay : SpellScript + class spell_dk_death_and_decay_SpellScript : SpellScript { public override bool Validate(SpellInfo spellInfo) { @@ -287,7 +287,7 @@ namespace Scripts.Spells.DeathKnight { if (GetCaster().HasAura(SpellIds.TighteningGrasp)) { - Position pos = GetExplTargetDest(); + WorldLocation pos = GetExplTargetDest(); if (pos != null) GetCaster().CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SpellIds.TighteningGraspSlow, true); } @@ -298,8 +298,7 @@ namespace Scripts.Spells.DeathKnight OnCast.Add(new CastHandler(HandleDummy)); } } - - [Script] + [Script] // 43265 - Death and Decay class spell_dk_death_and_decay_AuraScript : AuraScript { void HandleDummyTick(AuraEffect aurEff) @@ -327,9 +326,8 @@ namespace Scripts.Spells.DeathKnight { Unit caster = GetCaster(); caster.CastSpell(GetHitUnit(), SpellIds.DeathCoilDamage, true); - AuraEffect unholyAura = caster.GetAuraEffect(SpellIds.Unholy, 6); - if (unholyAura != null) // can be any effect, just here to send SPELL_FAILED_DONT_REPORT on failure + if (unholyAura != null) // can be any effect, just here to send SpellFailedDontReport on failure caster.CastSpell(caster, SpellIds.UnholyVigor, true, null, unholyAura); } @@ -368,7 +366,7 @@ namespace Scripts.Spells.DeathKnight } } - [Script] //49576 - Death Grip Initial + [Script] // 49576 - Death Grip Initial class spell_dk_death_grip_initial : SpellScript { public override bool Validate(SpellInfo spellInfo) @@ -422,14 +420,13 @@ namespace Scripts.Spells.DeathKnight { public override bool Validate(SpellInfo spellInfo) { - return ValidateSpellInfo(SpellIds.DeathStrikeHeal, SpellIds.BloodShieldMastery, SpellIds.BloodShieldAbsorb, - SpellIds.RecentlyUsedDeathStrike, SpellIds.Frost, SpellIds.DeathStrikeOffhand); + return ValidateSpellInfo(SpellIds.DeathStrikeHeal, SpellIds.BloodShieldMastery, SpellIds.BloodShieldAbsorb, SpellIds.RecentlyUsedDeathStrike, SpellIds.Frost, SpellIds.DeathStrikeOffhand); } void HandleHeal(uint effIndex) { Unit caster = GetCaster(); - //TODO: heal = Math.Min(10% health, 20% of all damage taken in last 5 seconds) + //Todo: heal = std::min(10% health, 20% of all damage taken in last 5 seconds) int heal = (int)MathFunctions.CalculatePct(caster.GetMaxHealth(), GetSpellInfo().GetEffect(4).CalcValue()); caster.CastCustomSpell(SpellIds.DeathStrikeHeal, SpellValueMod.BasePoint0, heal, caster, true); @@ -461,14 +458,14 @@ namespace Scripts.Spells.DeathKnight return ValidateSpellInfo(SpellIds.FesteringWound); } - void HandleDummy(uint effIndex) + void HandleScriptEffect(uint effIndex) { GetCaster().CastCustomSpell(SpellIds.FesteringWound, SpellValueMod.AuraStack, GetEffectValue(), GetHitUnit(), TriggerCastFlags.FullMask); } public override void Register() { - OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 2, SpellEffectName.Dummy)); + OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 2, SpellEffectName.Dummy)); } } @@ -544,7 +541,7 @@ namespace Scripts.Spells.DeathKnight } } - [Script] // 121916 - Glyph of the Geist (Unholy) // 6.x, does this belong here or in spell_generic? apply this in creature_template_addon? sniffs say this is always cast on raise dead. + [Script] // 121916 - Glyph of the Geist (Unholy) class spell_dk_pet_geist_transform : SpellScript { public override bool Validate(SpellInfo spellInfo) @@ -573,7 +570,7 @@ namespace Scripts.Spells.DeathKnight } } - [Script] // 147157 Glyph of the Skeleton (Unholy) // 6.x, does this belong here or in spell_generic? apply this in creature_template_addon? sniffs say this is always cast on raise dead. + [Script] // 147157 Glyph of the Skeleton (Unholy) class spell_dk_pet_skeleton_transform : SpellScript { public override bool Validate(SpellInfo spellInfo) @@ -597,7 +594,7 @@ namespace Scripts.Spells.DeathKnight } } - [Script] // 61257 - Runic Power Back on Snare/Root 7.1.5 + [Script] // 61257 - Runic Power Back on Snare/Root class spell_dk_pvp_4p_bonus : AuraScript { public override bool Validate(SpellInfo spellInfo) @@ -650,26 +647,6 @@ namespace Scripts.Spells.DeathKnight } } - [Script] // 115994 - Unholy Blight - class spell_dk_unholy_blight : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.FrostFever, SpellIds.BloodPlague); - } - - void HandleDummy(uint effIndex) - { - GetCaster().CastSpell(GetHitUnit(), SpellIds.FrostFever, true); - GetCaster().CastSpell(GetHitUnit(), SpellIds.BloodPlague, true); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); - } - } - [Script] // 55233 - Vampiric Blood class spell_dk_vampiric_blood : AuraScript { @@ -683,4 +660,4 @@ namespace Scripts.Spells.DeathKnight DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 1, AuraType.ModIncreaseHealth2)); } } -} +} \ No newline at end of file diff --git a/Source/Scripts/Spells/DemonHunter.cs b/Source/Scripts/Spells/DemonHunter.cs index 73454052b..77cbfd7d2 100644 --- a/Source/Scripts/Spells/DemonHunter.cs +++ b/Source/Scripts/Spells/DemonHunter.cs @@ -28,7 +28,7 @@ namespace Scripts.Spells.DemonHunter } [Script] // 197125 - Chaos Strike - class spell_dh_chaos_strike_AuraScript : AuraScript + class spell_dh_chaos_strike : AuraScript { public override bool Validate(SpellInfo spellInfo) { diff --git a/Source/Scripts/Spells/Druid.cs b/Source/Scripts/Spells/Druid.cs index 80e8ad48e..88dc39af7 100644 --- a/Source/Scripts/Spells/Druid.cs +++ b/Source/Scripts/Spells/Druid.cs @@ -30,9 +30,10 @@ namespace Scripts.Spells.Druid public const uint BalanceT10Bonus = 70718; public const uint BalanceT10BonusProc = 70721; public const uint BlessingOfTheClaw = 28750; - public const uint BlessingOfTheRemulos = 40445; - public const uint BlessingOfTheElune = 40446; - public const uint BlessingOfTheCenarius = 40452; + public const uint BlessingOfRemulos = 40445; + public const uint BlessingOfElune = 40446; + public const uint BlessingOfCenarius = 40452; + public const uint CatForm = 768; public const uint Exhilarate = 28742; public const uint FeralChargeBear = 16979; public const uint FeralChargeCat = 49376; @@ -45,18 +46,23 @@ namespace Scripts.Spells.Druid public const uint FormsTrinketMoonkin = 37343; public const uint FormsTrinketNone = 37344; public const uint FormsTrinketTree = 37342; + public const uint GoreProc = 93622; public const uint IdolOfFeralShadows = 34241; public const uint IdolOfWorship = 60774; + public const uint IncarnationKingOfTheJungle = 102543; public const uint Infusion = 37238; public const uint Languish = 71023; public const uint LifebloomEnergize = 64372; public const uint LifebloomFinalHeal = 33778; public const uint LivingSeedHeal = 48503; public const uint LivingSeedProc = 48504; + public const uint Mangle = 33917; public const uint MoonfireDamage = 164812; public const uint RejuvenationT10Proc = 70691; public const uint RestorationT102PBonus = 70658; public const uint SavageRoar = 62071; + public const uint SkullBashCharge = 221514; + public const uint SkullBashInterrupt = 93985; public const uint StampedeBearRank1 = 81016; public const uint StampedeCatRank1 = 81021; public const uint StampedeCatState = 109881; @@ -81,6 +87,54 @@ namespace Scripts.Spells.Druid } } + [Script] // 22568 - Ferocious Bite + class spell_dru_ferocious_bite : SpellScript + { + float _damageMultiplier = 0.0f; + + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.IncarnationKingOfTheJungle) + && Global.SpellMgr.GetSpellInfo(SpellIds.IncarnationKingOfTheJungle, Difficulty.None).GetEffect(1) != null; + } + + void HandleHitTargetBurn(uint effIndex) + { + int newValue = (int)((float)GetEffectValue() * _damageMultiplier); + SetEffectValue(newValue); + } + + void HandleHitTargetDmg(uint effIndex) + { + int newValue = (int)((float)GetHitDamage() * (1.0f + _damageMultiplier)); + SetHitDamage(newValue); + } + + void HandleLaunchTarget(uint effIndex) + { + Unit caster = GetCaster(); + + int maxExtraConsumedPower = GetEffectValue(); + + AuraEffect auraEffect = caster.GetAuraEffect(SpellIds.IncarnationKingOfTheJungle, 1); + if (auraEffect != null) + { + float multiplier = 1.0f + (float)auraEffect.GetAmount() / 100.0f; + maxExtraConsumedPower = (int)((float)maxExtraConsumedPower * multiplier); + SetEffectValue(maxExtraConsumedPower); + } + + _damageMultiplier = Math.Min(caster.GetPower(PowerType.Energy), maxExtraConsumedPower) / maxExtraConsumedPower; + } + + public override void Register() + { + OnEffectLaunchTarget .Add(new EffectHandler(HandleLaunchTarget, 1, SpellEffectName.PowerBurn)); + OnEffectHitTarget .Add(new EffectHandler(HandleHitTargetBurn, 1, SpellEffectName.PowerBurn)); + OnEffectHitTarget .Add(new EffectHandler(HandleHitTargetDmg, 0, SpellEffectName.SchoolDamage)); + } + } + [Script] // 33943 - Flight Form class spell_dru_flight_form : SpellScript { @@ -131,7 +185,7 @@ namespace Scripts.Spells.Druid { PreventDefaultAction(); Unit target = eventInfo.GetActor(); - uint triggerspell = 0; + uint triggerspell; switch (target.GetShapeshiftForm()) { @@ -165,7 +219,34 @@ namespace Scripts.Spells.Druid } } - // 34246 - Idol of the Emerald Queen + [Script] // 210706 - Gore + class spell_dru_gore : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.GoreProc, SpellIds.Mangle); + } + + bool CheckEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo) + { + return RandomHelper.randChance(aurEff.GetAmount()); + } + + void HandleProc(AuraEffect aurEff, ProcEventInfo procInfo) + { + Unit owner = GetTarget(); + owner.CastSpell(owner, SpellIds.GoreProc); + owner.GetSpellHistory().ResetCooldown(SpellIds.Mangle, true); + } + + public override void Register() + { + DoCheckEffectProc .Add(new CheckEffectProcHandler(CheckEffectProc, 0, AuraType.Dummy)); + OnEffectProc .Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); + } + } + + // 34246 - Idol of the Emerald Queen [Script] // 60779 - Idol of Lush Moss class spell_dru_idol_lifebloom : AuraScript { @@ -188,8 +269,7 @@ namespace Scripts.Spells.Druid } } - // 29166 - Innervate - [Script] + [Script] // 29166 - Innervate class spell_dru_innervate : AuraScript { void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) @@ -207,8 +287,56 @@ namespace Scripts.Spells.Druid } } - // 33763 - Lifebloom - [Script] + [Script] // 40442 - Druid Tier 6 Trinket + class spell_dru_item_t6_trinket : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.BlessingOfRemulos, SpellIds.BlessingOfElune, SpellIds.BlessingOfCenarius); + } + + void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) + { + PreventDefaultAction(); + SpellInfo spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo == null) + return; + + uint spellId; + int chance; + + // Starfire + if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000004u)) + { + spellId = SpellIds.BlessingOfRemulos; + chance = 25; + } + // Rejuvenation + else if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000010u)) + { + spellId = SpellIds.BlessingOfElune; + chance = 25; + } + // Mangle (Bear) and Mangle (Cat) + else if (spellInfo.SpellFamilyFlags[1].HasAnyFlag(0x00000440u)) + { + spellId = SpellIds.BlessingOfCenarius; + chance = 40; + } + else + return; + + if (RandomHelper.randChance(chance)) + eventInfo.GetActor().CastSpell((Unit)null, spellId, true, null, aurEff); + } + + public override void Register() + { + OnEffectProc .Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); + } + } + + [Script] // 33763 - Lifebloom class spell_dru_lifebloom : AuraScript { public override bool Validate(SpellInfo spell) @@ -234,11 +362,11 @@ namespace Scripts.Spells.Druid GetTarget().CastCustomSpell(GetTarget(), SpellIds.LifebloomFinalHeal, (int)healAmount, 0, 0, true, null, aurEff, GetCasterGUID()); // restore mana - var costs = GetSpellInfo().CalcPowerCost(caster, GetSpellInfo().GetSchoolMask()); - var m = costs.Find(cost => cost.Power == PowerType.Mana); - if (m != null) + var spellPowerCostList = GetSpellInfo().CalcPowerCost(caster, GetSpellInfo().GetSchoolMask()); + var spellPowerCost = spellPowerCostList.Find(cost => cost.Power == PowerType.Mana); + if (spellPowerCost != null) { - int returnMana = m.Amount * (int)stack / 2; + int returnMana = spellPowerCost.Amount * (int)stack / 2; caster.CastCustomSpell(caster, SpellIds.LifebloomEnergize, returnMana, 0, 0, true, null, aurEff, GetCasterGUID()); } return; @@ -265,11 +393,11 @@ namespace Scripts.Spells.Druid target.CastCustomSpell(target, SpellIds.LifebloomFinalHeal, (int)healAmount, 0, 0, true, null, null, GetCasterGUID()); // restore mana - var costs = GetSpellInfo().CalcPowerCost(caster, GetSpellInfo().GetSchoolMask()); - var m = costs.Find(cost => cost.Power == PowerType.Mana); - if (m != null) + var spellPowerCostList = GetSpellInfo().CalcPowerCost(caster, GetSpellInfo().GetSchoolMask()); + var spellPowerCost = spellPowerCostList.Find(cost => cost.Power == PowerType.Mana); + if (spellPowerCost != null) { - int returnMana = m.Amount * dispelInfo.GetRemovedCharges() / 2; + int returnMana = spellPowerCost.Amount * dispelInfo.GetRemovedCharges() / 2; caster.CastCustomSpell(caster, SpellIds.LifebloomEnergize, returnMana, 0, 0, true, null, null, GetCasterGUID()); } return; @@ -287,8 +415,7 @@ namespace Scripts.Spells.Druid } } - // 48496 - Living Seed - [Script] + [Script] // 48496 - Living Seed class spell_dru_living_seed : AuraScript { public override bool Validate(SpellInfo spellInfo) @@ -309,8 +436,7 @@ namespace Scripts.Spells.Druid } } - // 48504 - Living Seed (Proc) - [Script] + [Script] // 48504 - Living Seed (Proc) class spell_dru_living_seed_proc : AuraScript { public override bool Validate(SpellInfo spellInfo) @@ -344,8 +470,28 @@ namespace Scripts.Spells.Druid } } - // 16972 - Predatory Strikes - [Script] + [Script] // 16864 - Omen of Clarity + class spell_dru_omen_of_clarity : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.BalanceT10Bonus, SpellIds.BalanceT10BonusProc); + } + + void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) + { + Unit target = GetTarget(); + if (target.HasAura(SpellIds.BalanceT10Bonus)) + target.CastSpell((Unit)null, SpellIds.BalanceT10BonusProc, true, null); + } + + public override void Register() + { + OnEffectProc .Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell)); + } + } + + [Script] // 16972 - Predatory Strikes class spell_dru_predatory_strikes : AuraScript { void UpdateAmount(AuraEffect aurEff, AuraEffectHandleModes mode) @@ -362,8 +508,28 @@ namespace Scripts.Spells.Druid } } - // 1079 - Rip - [Script] + [Script] // 5215 - Prowl + class spell_dru_prowl : SpellScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.CatForm); + } + + void HandleOnCast() + { + // Change into cat form + if (GetCaster().GetShapeshiftForm() != ShapeShiftForm.CatForm) + GetCaster().CastSpell(GetCaster(), SpellIds.CatForm); + } + + public override void Register() + { + BeforeCast .Add(new CastHandler(HandleOnCast)); + } + } + + [Script] // 1079 - Rip class spell_dru_rip : AuraScript { public override bool Load() @@ -400,29 +566,7 @@ namespace Scripts.Spells.Druid } } - [Script] // 16864 - Omen of Clarity - class spell_dru_omen_of_clarity : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.BalanceT10Bonus, SpellIds.BalanceT10BonusProc); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - Unit target = GetTarget(); - if (target.HasAura(SpellIds.BalanceT10Bonus)) - target.CastSpell((Unit)null, SpellIds.BalanceT10BonusProc, true, null); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell)); - } - } - - // 52610 - Savage Roar - [Script] + [Script] // 52610 - Savage Roar class spell_dru_savage_roar : SpellScript { SpellCastResult CheckCast() @@ -466,6 +610,26 @@ namespace Scripts.Spells.Druid } } + [Script] // 106839 - Skull Bash + class spell_dru_skull_bash : SpellScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.SkullBashCharge, SpellIds.SkullBashInterrupt); + } + + void HandleDummy(uint effIndex) + { + GetCaster().CastSpell(GetHitUnit(), SpellIds.SkullBashCharge, true); + GetCaster().CastSpell(GetHitUnit(), SpellIds.SkullBashInterrupt, true); + } + + public override void Register() + { + OnEffectHitTarget .Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); + } + } + [Script] // 78892 - Stampede class spell_dru_stampede : AuraScript { @@ -500,8 +664,7 @@ namespace Scripts.Spells.Druid } } - // 50286 - Starfall (Dummy) - [Script] + [Script] // 50286 - Starfall (Dummy) class spell_dru_starfall_dummy : SpellScript { void FilterTargets(List targets) @@ -549,8 +712,7 @@ namespace Scripts.Spells.Druid } } - // 61336 - Survival Instincts - [Script] + [Script] // 61336 - Survival Instincts class spell_dru_survival_instincts : SpellScript { SpellCastResult CheckCast() @@ -579,24 +741,16 @@ namespace Scripts.Spells.Druid void AfterApply(AuraEffect aurEff, AuraEffectHandleModes mode) { Unit target = GetTarget(); - int bp0 = (int)target.CountPctFromMaxHealth(aurEff.GetAmount()); - target.CastCustomSpell(target, SpellIds.SurvivalInstincts, bp0, 0, 0, true); - } - - void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - GetTarget().RemoveAurasDueToSpell(SpellIds.SurvivalInstincts); + target.CastSpell(target, SpellIds.SurvivalInstincts, true); } public override void Register() { AfterEffectApply.Add(new EffectApplyHandler(AfterApply, 0, AuraType.Dummy, AuraEffectHandleModes.ChangeAmountMask)); - AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 0, AuraType.Dummy, AuraEffectHandleModes.ChangeAmountMask)); } } - // 40121 - Swift Flight Form (Passive) - [Script] + [Script] // 40121 - Swift Flight Form (Passive) class spell_dru_swift_flight_passive : AuraScript { public override bool Load() @@ -654,12 +808,12 @@ namespace Scripts.Spells.Druid return; Unit caster = eventInfo.GetActor(); - var costs = spell.GetPowerCost(); - var m = costs.First(cost => cost.Power == PowerType.Mana); - if (m == null) + var spellPowerCostList = spell.GetPowerCost(); + var spellPowerCost = spellPowerCostList.First(cost => cost.Power == PowerType.Mana); + if (spellPowerCost == null) return; - int amount = MathFunctions.CalculatePct(m.Amount, aurEff.GetAmount()); + int amount = MathFunctions.CalculatePct(spellPowerCost.Amount, aurEff.GetAmount()); caster.CastCustomSpell(SpellIds.Exhilarate, SpellValueMod.BasePoint0, amount, null, true, null, aurEff); } @@ -669,7 +823,7 @@ namespace Scripts.Spells.Druid } } - // 37288 - Mana Restore + // 37288 - Mana Restore [Script] // 37295 - Mana Restore class spell_dru_t4_2p_bonus : AuraScript { @@ -690,6 +844,194 @@ namespace Scripts.Spells.Druid } } + [Script] // 70723 - Item - Druid T10 Balance 4P Bonus + class spell_dru_t10_balance_4p_bonus : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.Languish); + } + + void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) + { + PreventDefaultAction(); + + DamageInfo damageInfo = eventInfo.GetDamageInfo(); + if (damageInfo == null || damageInfo.GetDamage() == 0) + return; + + Unit caster = eventInfo.GetActor(); + Unit target = eventInfo.GetProcTarget(); + + SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Languish, GetCastDifficulty()); + int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount()); + amount /= (int)spellInfo.GetMaxTicks(); + // Add remaining ticks to damage done + amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.Languish, AuraType.PeriodicDamage); + + caster.CastCustomSpell(SpellIds.Languish, SpellValueMod.BasePoint0, amount, target, true, null, aurEff); + } + + public override void Register() + { + OnEffectProc .Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); + } + } + + [Script] // 70691 - Item T10 Restoration 4P Bonus + class spell_dru_t10_restoration_4p_bonus : SpellScript + { + public override bool Load() + { + return GetCaster().IsTypeId(TypeId.Player); + } + + void FilterTargets(List targets) + { + if (!GetCaster().ToPlayer().GetGroup()) + { + targets.Clear(); + targets.Add(GetCaster()); + } + else + { + targets.Remove(GetExplTargetUnit()); + List tempTargets = new List(); + foreach (var obj in targets) + if (obj.IsTypeId(TypeId.Player) && GetCaster().IsInRaidWith(obj.ToUnit())) + tempTargets.Add(obj.ToUnit()); + + if (tempTargets.Empty()) + { + targets.Clear(); + FinishCast(SpellCastResult.DontReport); + return; + } + + Unit target = tempTargets.SelectRandom(); + targets.Clear(); + targets.Add(target); + } + } + + public override void Register() + { + OnObjectAreaTargetSelect .Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly)); + } + } + + [Script] // 70664 - Druid T10 Restoration 4P Bonus (Rejuvenation) + class spell_dru_t10_restoration_4p_bonus_dummy : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.RejuvenationT10Proc); + } + + bool CheckProc(ProcEventInfo eventInfo) + { + SpellInfo spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo == null || spellInfo.Id == SpellIds.RejuvenationT10Proc) + return false; + + HealInfo healInfo = eventInfo.GetHealInfo(); + if (healInfo == null || healInfo.GetHeal() == 0) + return false; + + Player caster = eventInfo.GetActor().ToPlayer(); + if (!caster) + return false; + + return caster.GetGroup() || caster != eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) + { + PreventDefaultAction(); + + int amount = (int)eventInfo.GetHealInfo().GetHeal(); + eventInfo.GetActor().CastCustomSpell(SpellIds.RejuvenationT10Proc, SpellValueMod.BasePoint0, amount, null, true, null, aurEff); + } + + public override void Register() + { + DoCheckProc .Add(new CheckProcHandler(CheckProc)); + OnEffectProc .Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); + } + } + + // 1066 - Aquatic Form + // 33943 - Flight Form + // 40120 - Swift Flight Form + [Script] // 165961 - Stag Form + class spell_dru_travel_form_AuraScript : AuraScript + { + uint triggeredSpellId; + + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.FormStag, SpellIds.FormAquatic, SpellIds.FormFlight, SpellIds.FormSwiftFlight); + } + + public override bool Load() + { + return GetCaster().GetTypeId() == TypeId.Player; + } + + void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode) + { + // If it stays 0, it Removes Travel Form dummy in AfterRemove. + triggeredSpellId = 0; + + // We should only handle aura interrupts. + if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Interrupt) + return; + + // Check what form is appropriate + Player player = GetTarget().ToPlayer(); + if (player.IsInWater()) // Aquatic form + triggeredSpellId = SpellIds.FormAquatic; + else if (player.GetSkillValue(SkillType.Riding) >= 225 && CheckLocationForForm(SpellIds.FormFlight) == SpellCastResult.SpellCastOk) // Flight form + triggeredSpellId = player.GetSkillValue(SkillType.Riding) >= 300 ? SpellIds.FormSwiftFlight : SpellIds.FormFlight; + else if (CheckLocationForForm(SpellIds.FormStag) == SpellCastResult.SpellCastOk) // Stag form + triggeredSpellId = SpellIds.FormStag; + + // If chosen form is current aura, just don't Remove it. + if (triggeredSpellId == m_scriptSpellId) + PreventDefaultAction(); + } + + void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode) + { + if (triggeredSpellId == m_scriptSpellId) + return; + + Player player = GetTarget().ToPlayer(); + + if (triggeredSpellId != 0) // Apply new form + player.AddAura(triggeredSpellId, player); + else // If not set, simply Remove Travel Form dummy + player.RemoveAura(SpellIds.TravelForm); + } + + public override void Register() + { + OnEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.ModShapeshift, AuraEffectHandleModes.Real)); + AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 0, AuraType.ModShapeshift, AuraEffectHandleModes.Real)); + } + + SpellCastResult CheckLocationForForm(uint spellId) + { + Player player = GetTarget().ToPlayer(); + SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetCastDifficulty()); + + if (!player.GetMap().IsOutdoors(player.GetPhaseShift(), player.GetPositionX(), player.GetPositionY(), player.GetPositionZ())) + return SpellCastResult.OnlyOutdoors; + + return spellInfo.CheckLocation(player.GetMapId(), player.GetZoneId(), player.GetAreaId(), player); + } + } + [Script] // 783 - Travel Form (dummy) class spell_dru_travel_form_dummy_SpellScript : SpellScript { @@ -764,247 +1106,11 @@ namespace Scripts.Spells.Druid } } - // 1066 - Aquatic Form - // 33943 - Flight Form - // 40120 - Swift Flight Form - [Script] // 165961 - Stag Form - class spell_dru_travel_form_AuraScript : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.FormStag, SpellIds.FormAquatic, SpellIds.FormFlight, SpellIds.FormSwiftFlight); - } - - public override bool Load() - { - return GetCaster().GetTypeId() == TypeId.Player; - } - - void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - // If it stays 0, it Removes Travel Form dummy in AfterRemove. - triggeredSpellId = 0; - - // We should only handle aura interrupts. - if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Interrupt) - return; - - // Check what form is appropriate - Player player = GetTarget().ToPlayer(); - if (player.IsInWater()) // Aquatic form - triggeredSpellId = SpellIds.FormAquatic; - else if (player.GetSkillValue(SkillType.Riding) >= 225 && CheckLocationForForm(SpellIds.FormFlight) == SpellCastResult.SpellCastOk) // Flight form - triggeredSpellId = player.GetSkillValue(SkillType.Riding) >= 300 ? SpellIds.FormSwiftFlight : SpellIds.FormFlight; - else if (CheckLocationForForm(SpellIds.FormStag) == SpellCastResult.SpellCastOk) // Stag form - triggeredSpellId = SpellIds.FormStag; - - // If chosen form is current aura, just don't Remove it. - if (triggeredSpellId == m_scriptSpellId) - PreventDefaultAction(); - } - - void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - if (triggeredSpellId == m_scriptSpellId) - return; - - Player player = GetTarget().ToPlayer(); - - if (triggeredSpellId != 0) // Apply new form - player.AddAura(triggeredSpellId, player); - else // If not set, simply Remove Travel Form dummy - player.RemoveAura(SpellIds.TravelForm); - } - - public override void Register() - { - OnEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.ModShapeshift, AuraEffectHandleModes.Real)); - AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 0, AuraType.ModShapeshift, AuraEffectHandleModes.Real)); - } - - SpellCastResult CheckLocationForForm(uint spell_id) - { - Player player = GetTarget().ToPlayer(); - SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, GetCastDifficulty()); - - if (!player.GetMap().IsOutdoors(player.GetPhaseShift(), player.GetPositionX(), player.GetPositionY(), player.GetPositionZ())) - return SpellCastResult.OnlyOutdoors; - - return spellInfo.CheckLocation(player.GetMapId(), player.GetZoneId(), player.GetAreaId(), player); - } - - uint triggeredSpellId; - } - - [Script] // 40442 - Druid Tier 6 Trinket - class spell_dru_item_t6_trinket : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.BlessingOfTheRemulos, SpellIds.BlessingOfTheElune, SpellIds.BlessingOfTheCenarius); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - SpellInfo spellInfo = eventInfo.GetSpellInfo(); - if (spellInfo == null) - return; - - uint spellId; - int chance; - - // Starfire - if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000004u)) - { - spellId = SpellIds.BlessingOfTheRemulos; - chance = 25; - } - // Rejuvenation - else if (spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000010u)) - { - spellId = SpellIds.BlessingOfTheElune; - chance = 25; - } - // Mangle (Bear) and Mangle (Cat) - else if (spellInfo.SpellFamilyFlags[1].HasAnyFlag(0x00000440u)) - { - spellId = SpellIds.BlessingOfTheCenarius; - chance = 40; - } - else - return; - - if (RandomHelper.randChance(chance)) - eventInfo.GetActor().CastSpell((Unit)null, spellId, true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - - [Script] // 70723 - Item - Druid T10 Balance 4P Bonus - class spell_dru_t10_balance_4p_bonus : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.Languish); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - - DamageInfo damageInfo = eventInfo.GetDamageInfo(); - if (damageInfo == null || damageInfo.GetDamage() == 0) - return; - - Unit caster = eventInfo.GetActor(); - Unit target = eventInfo.GetProcTarget(); - - SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Languish, GetCastDifficulty()); - int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount()); - amount /= (int)spellInfo.GetMaxTicks(); - // Add remaining ticks to damage done - amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.Languish, AuraType.PeriodicDamage); - - caster.CastCustomSpell(SpellIds.Languish, SpellValueMod.BasePoint0, amount, target, true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - - // 70691 - Item T10 Restoration 4P Bonus - [Script] - class spell_dru_t10_restoration_4p_bonus : SpellScript - { - public override bool Load() - { - return GetCaster().IsTypeId(TypeId.Player); - } - - void FilterTargets(List targets) - { - if (GetCaster().ToPlayer().GetGroup() == null) - { - targets.Clear(); - targets.Add(GetCaster()); - } - else - { - targets.Remove(GetExplTargetUnit()); - List tempTargets = new List(); - foreach (var obj in targets) - if (obj.IsTypeId(TypeId.Player) && GetCaster().IsInRaidWith(obj.ToUnit())) - tempTargets.Add(obj.ToUnit()); - - if (tempTargets.Empty()) - { - targets.Clear(); - FinishCast(SpellCastResult.DontReport); - return; - } - - Unit target = tempTargets.SelectRandom(); - targets.Clear(); - targets.Add(target); - } - } - - public override void Register() - { - OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly)); - } - } - - [Script] // 70664 - Druid T10 Restoration 4P Bonus (Rejuvenation) - class spell_dru_t10_restoration_4p_bonus_dummy : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.RejuvenationT10Proc); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - SpellInfo spellInfo = eventInfo.GetSpellInfo(); - if (spellInfo == null || spellInfo.Id == SpellIds.RejuvenationT10Proc) - return false; - - HealInfo healInfo = eventInfo.GetHealInfo(); - if (healInfo == null || healInfo.GetHeal() == 0) - return false; - - Player caster = eventInfo.GetActor().ToPlayer(); - if (!caster) - return false; - - return caster.GetGroup() || caster != eventInfo.GetProcTarget(); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - - int amount = (int)eventInfo.GetHealInfo().GetHeal(); - eventInfo.GetActor().CastCustomSpell(SpellIds.RejuvenationT10Proc, SpellValueMod.BasePoint0, amount, null, true, null, aurEff); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - [Script] // 48438 - Wild Growth class spell_dru_wild_growth : SpellScript { + List _targets; + public override bool Validate(SpellInfo spellInfo) { SpellEffectInfo effectInfo = spellInfo.GetEffect(2); @@ -1046,8 +1152,6 @@ namespace Scripts.Spells.Druid OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly)); OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(SetTargets, 1, Targets.UnitDestAreaAlly)); } - - List _targets; } [Script] diff --git a/Source/Scripts/Spells/Generic.cs b/Source/Scripts/Spells/Generic.cs index af2f4ba25..d62670c16 100644 --- a/Source/Scripts/Spells/Generic.cs +++ b/Source/Scripts/Spells/Generic.cs @@ -150,6 +150,9 @@ namespace Scripts.Spells.Generic public const uint MissEffect = 62977; + //MossCoveredFeet + public const uint FallDown = 6869; + //Netherbloom public const uint NetherBloomPollen1 = 28703; @@ -363,6 +366,8 @@ namespace Scripts.Spells.Generic [Script] class spell_gen_absorb0_hitlimit1 : AuraScript { + int limit; + public override bool Load() { // Max absorb stored in 1 dummy effect @@ -379,8 +384,6 @@ namespace Scripts.Spells.Generic { OnEffectAbsorb.Add(new EffectAbsorbHandler(Absorb, 0)); } - - int limit; } [Script] // 28764 - Adaptive Warding (Frostfire Regalia Set) @@ -415,7 +418,7 @@ namespace Scripts.Spells.Generic { PreventDefaultAction(); - uint spellId = 0; + uint spellId; switch (SharedConst.GetFirstSchoolInMask(eventInfo.GetSchoolMask())) { case SpellSchools.Fire: @@ -501,7 +504,7 @@ namespace Scripts.Spells.Generic AuraEffect aurEff1 = aurEff.GetBase().GetEffect(1); if (aurEff1 != null) aurEff1.ChangeAmount(aurEff1.GetAmount() + 5); - aurEff.SetAmount((int)(100 * aurEff.GetTickNumber())); + aurEff.SetAmount(100 * (int)aurEff.GetTickNumber()); } public override void Register() @@ -550,24 +553,13 @@ namespace Scripts.Spells.Generic { bool CheckAreaTarget(Unit target) { - switch (target.GetEntry()) + return (target.GetEntry()) switch { // alliance - case 14762: // Dun Baldar North Marshal - case 14763: // Dun Baldar South Marshal - case 14764: // Icewing Marshal - case 14765: // Stonehearth Marshal - case 11948: // Vandar Stormspike - // horde - case 14772: // East Frostwolf Warmaster - case 14776: // Tower Point Warmaster - case 14773: // Iceblood Warmaster - case 14777: // West Frostwolf Warmaster - case 11946: // Drek'thar - return true; - default: - return false; - } + // Dun Baldar North Marshal + 14762 or 14763 or 14764 or 14765 or 11948 or 14772 or 14776 or 14773 or 14777 or 11946 => true, + _ => false, + }; } public override void Register() @@ -1003,6 +995,8 @@ namespace Scripts.Spells.Generic [Script("spell_gen_50pct_count_pct_from_max_hp", 50)] class spell_gen_count_pct_from_max_hp : SpellScript { + int _damagePct; + public spell_gen_count_pct_from_max_hp(int damagePct) { _damagePct = damagePct; @@ -1020,8 +1014,6 @@ namespace Scripts.Spells.Generic { OnHit.Add(new HitHandler(RecalculateDamage)); } - - int _damagePct; } [Script] // 63845 - Create Lance @@ -1085,14 +1077,12 @@ namespace Scripts.Spells.Generic { public override bool Validate(SpellInfo spellInfo) { - switch (spellInfo.Id) + return spellInfo.Id switch { - case SpellIds.SunreaverTrigger: - return ValidateSpellInfo(SpellIds.SunreaverFemale, SpellIds.SunreaverMale); - case SpellIds.SilverCovenantTrigger: - return ValidateSpellInfo(SpellIds.SilverCovenantFemale, SpellIds.SilverCovenantMale); - } - return false; + SpellIds.SunreaverTrigger => ValidateSpellInfo(SpellIds.SunreaverFemale, SpellIds.SunreaverMale), + SpellIds.SilverCovenantTrigger => ValidateSpellInfo(SpellIds.SilverCovenantFemale, SpellIds.SilverCovenantMale), + _ => false, + }; } void HandleScript(uint effIndex) @@ -1125,74 +1115,6 @@ namespace Scripts.Spells.Generic } } - [Script] - class spell_gen_defend : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.VisualShield1, SpellIds.VisualShield2, SpellIds.VisualShield3); - } - - void RefreshVisualShields(AuraEffect aurEff, AuraEffectHandleModes mode) - { - if (GetCaster()) - { - Unit target = GetTarget(); - - for (byte i = 0; i < GetSpellInfo().StackAmount; ++i) - target.RemoveAurasDueToSpell(SpellIds.VisualShield1 + i); - - target.CastSpell(target, SpellIds.VisualShield1 + GetAura().GetStackAmount() - 1, true, null, aurEff); - } - else - GetTarget().RemoveAurasDueToSpell(GetId()); - } - - void RemoveVisualShields(AuraEffect aurEff, AuraEffectHandleModes mode) - { - for (byte i = 0; i < GetSpellInfo().StackAmount; ++i) - GetTarget().RemoveAurasDueToSpell(SpellIds.VisualShield1 + i); - } - - void RemoveDummyFromDriver(AuraEffect aurEff, AuraEffectHandleModes mode) - { - Unit caster = GetCaster(); - if (caster) - { - TempSummon vehicle = caster.ToTempSummon(); - if (vehicle) - { - Unit rider = vehicle.GetSummoner(); - if (rider) - rider.RemoveAurasDueToSpell(GetId()); - } - } - } - - public override void Register() - { - /*SpellInfo spell = Global.SpellMgr.GetSpellInfo(m_scriptSpellId); - - // Defend spells cast by NPCs (add visuals) - if (spell.GetEffect(0).ApplyAuraName == AuraType.ModDamagePercentTaken) - { - AfterEffectApply.Add(new EffectApplyHandler(RefreshVisualShields, 0, AuraType.ModDamagePercentTaken, AuraEffectHandleModes.RealOrReapplyMask)); - OnEffectRemove.Add(new EffectApplyHandler(RemoveVisualShields, 0, AuraType.ModDamagePercentTaken, AuraEffectHandleModes.ChangeAmountMask)); - } - - // Remove Defend spell from player when he dismounts - if (spell.GetEffect(2).ApplyAuraName == AuraType.ModDamagePercentTaken) - OnEffectRemove.Add(new EffectApplyHandler(RemoveDummyFromDriver, 2, AuraType.ModDamagePercentTaken, AuraEffectHandleModes.Real)); - - // Defend spells cast by players (add/Remove visuals) - if (spell.GetEffect(1).ApplyAuraName == AuraType.Dummy) - { - AfterEffectApply.Add(new EffectApplyHandler(RefreshVisualShields, 1, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask)); - OnEffectRemove.Add(new EffectApplyHandler(RemoveVisualShields, 1, AuraType.Dummy, AuraEffectHandleModes.ChangeAmountMask)); - }*/ - } - } - [Script] class spell_gen_despawn_self : SpellScript { @@ -1501,6 +1423,8 @@ namespace Scripts.Spells.Generic [Script("spell_faction_champion_dru_lifebloom", SpellIds.FactionChampionsDru)] class spell_gen_lifebloom : AuraScript { + readonly uint _spellId; + public spell_gen_lifebloom(uint spellId) { _spellId = spellId; @@ -1525,8 +1449,6 @@ namespace Scripts.Spells.Generic { AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 0, AuraType.PeriodicHeal, AuraEffectHandleModes.Real)); } - - uint _spellId; } [Script] @@ -1638,6 +1560,27 @@ namespace Scripts.Spells.Generic } } + // 6870 Moss Covered Feet + [Script] // 31399 Moss Covered Feet + class spell_gen_moss_covered_feet : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.FallDown); + } + + void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActionTarget().CastSpell((Unit)null, SpellIds.FallDown, true, null, aurEff); + } + + public override void Register() + { + OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); + } + } + [Script] // 28702 - Netherbloom class spell_gen_netherbloom : SpellScript { @@ -1724,11 +1667,11 @@ namespace Scripts.Spells.Generic return true; } - void onProc(AuraEffect aurEff, ProcEventInfo eventInfo) + void OnProcEffect(AuraEffect aurEff, ProcEventInfo eventInfo) { PreventDefaultAction(); - uint spellId = 0; + uint spellId; switch (SharedConst.GetFirstSchoolInMask(eventInfo.GetSchoolMask())) { case SpellSchools.Holy: @@ -1758,7 +1701,7 @@ namespace Scripts.Spells.Generic public override void Register() { DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(onProc, 0, AuraType.Dummy)); + OnEffectProc.Add(new EffectProcHandler(OnProcEffect, 0, AuraType.Dummy)); } } @@ -1824,7 +1767,7 @@ namespace Scripts.Spells.Generic } // 35201 - Paralytic Poison - class spell_gen_paralytic_poison_AuraScript : AuraScript + class spell_gen_paralytic_poison : AuraScript { public override bool Validate(SpellInfo spellInfo) { @@ -2232,7 +2175,9 @@ namespace Scripts.Spells.Generic [Script] class spell_gen_spectator_cheer_trigger : SpellScript - { + { + readonly static Emote[] EmoteArray = { Emote.OneshotCheer, Emote.OneshotExclamation, Emote.OneshotApplaud }; + void HandleDummy(uint effIndex) { GetCaster().HandleEmoteCommand(EmoteArray[RandomHelper.URand(0, 2)]); @@ -2242,8 +2187,6 @@ namespace Scripts.Spells.Generic { OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); } - - static Emote[] EmoteArray = { Emote.OneshotCheer, Emote.OneshotExclamation, Emote.OneshotApplaud }; } [Script] @@ -2276,6 +2219,8 @@ namespace Scripts.Spells.Generic [Script("spell_gen_summon_earth_elemental", SpellIds.SummonEarthElemental)] class spell_gen_summon_elemental : AuraScript { + readonly uint _spellId; + public spell_gen_summon_elemental(uint spellId) { _spellId = spellId; @@ -2312,8 +2257,6 @@ namespace Scripts.Spells.Generic AfterEffectApply.Add(new EffectApplyHandler(AfterApply, 1, AuraType.Dummy, AuraEffectHandleModes.Real)); AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 1, AuraType.Dummy, AuraEffectHandleModes.Real)); } - - uint _spellId; } [Script] @@ -2418,7 +2361,7 @@ namespace Scripts.Spells.Generic } [Script] - class spell_gen_trigger_exclude_caster_aura_spell_SpellScript : SpellScript + class spell_gen_trigger_exclude_caster_aura_spell : SpellScript { public override bool Validate(SpellInfo spellInfo) { @@ -2438,7 +2381,7 @@ namespace Scripts.Spells.Generic } [Script] - class spell_gen_trigger_exclude_target_aura_spell_SpellScript : SpellScript + class spell_gen_trigger_exclude_target_aura_spell : SpellScript { public override bool Validate(SpellInfo spellInfo) { @@ -2463,6 +2406,8 @@ namespace Scripts.Spells.Generic [Script("spell_wotf_shared_cd", SpellIds.WillOfTheForsakenCooldownTriggerWotf)] class spell_pvp_trinket_wotf_shared_cd : SpellScript { + readonly uint _triggered; + public spell_pvp_trinket_wotf_shared_cd(uint triggered) { _triggered = triggered; @@ -2502,13 +2447,13 @@ namespace Scripts.Spells.Generic { AfterCast.Add(new CastHandler(HandleScript)); } - - uint _triggered; } [Script] class spell_gen_turkey_marker : AuraScript { + readonly List _applyTimes = new List(); + void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode) { // store stack apply times, so we can pop them while they expire @@ -2535,13 +2480,14 @@ namespace Scripts.Spells.Generic AfterEffectApply.Add(new EffectApplyHandler(OnApply, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.RealOrReapplyMask)); OnEffectPeriodic.Add(new EffectPeriodicHandler(OnPeriodic, 0, AuraType.PeriodicDummy)); } - - List _applyTimes = new List(); } [Script] class spell_gen_upper_deck_create_foam_sword : SpellScript { + // green pink blue red yellow + readonly static uint[] itemId = { 45061, 45176, 45177, 45178, 45179 }; + void HandleScript(uint effIndex) { Player player = GetHitPlayer(); @@ -2562,9 +2508,6 @@ namespace Scripts.Spells.Generic { OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect)); } - - // green pink blue red yellow - static uint[] itemId = { 45061, 45176, 45177, 45178, 45179 }; } // 52723 - Vampiric Touch @@ -2705,6 +2648,34 @@ namespace Scripts.Spells.Generic } } + [Script] + class spell_gen_eject_passenger : SpellScript + { + public override bool Validate(SpellInfo spellInfo) + { + SpellEffectInfo effect = spellInfo.GetEffect(0); + if (effect == null || effect.CalcValue() < 1) + return false; + return true; + } + + void EjectPassenger(uint effIndex) + { + Vehicle vehicle = GetHitUnit().GetVehicleKit(); + if (vehicle != null) + { + Unit passenger = vehicle.GetPassenger((sbyte)(GetEffectValue() - 1)); + if (passenger) + passenger.ExitVehicle(); + } + } + + public override void Register() + { + OnEffectHitTarget.Add(new EffectHandler(EjectPassenger, 0, SpellEffectName.ScriptEffect)); + } + } + [Script] class spell_gen_gm_freeze : AuraScript { @@ -2867,15 +2838,12 @@ namespace Scripts.Spells.Generic WeakTrollsBloodElixir = 3219, ElixirOfLionsStrength = 2367, ElixirOfMinorDefense = 673 - }; + } [Script] class spell_gen_mixology_bonus : AuraScript { - public spell_gen_mixology_bonus() - { - bonus = 0; - } + int bonus; public override bool Validate(SpellInfo spellInfo) { @@ -3065,8 +3033,6 @@ namespace Scripts.Spells.Generic } } - int bonus; - public override void Register() { DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, SpellConst.EffectAll, AuraType.Any)); diff --git a/Source/Scripts/Spells/Holiday.cs b/Source/Scripts/Spells/Holiday.cs index be01acd64..462ac2289 100644 --- a/Source/Scripts/Spells/Holiday.cs +++ b/Source/Scripts/Spells/Holiday.cs @@ -326,7 +326,7 @@ namespace Scripts.Spells.Holiday Unit caster = GetCaster(); Unit target = GetHitUnit(); - uint spellId = 0; + uint spellId; bool female = target.GetGender() == Gender.Female; switch (GetSpellInfo().Id) @@ -386,7 +386,7 @@ namespace Scripts.Spells.Holiday OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleTriggerSpell, 2, AuraType.PeriodicTriggerSpell)); } - uint _triggeredSpellId; + readonly uint _triggeredSpellId; bool _handled; } diff --git a/Source/Scripts/Spells/Hunter.cs b/Source/Scripts/Spells/Hunter.cs index 9d30a372e..168e778eb 100644 --- a/Source/Scripts/Spells/Hunter.cs +++ b/Source/Scripts/Spells/Hunter.cs @@ -28,27 +28,15 @@ namespace Scripts.Spells.Hunter struct SpellIds { public const uint AspectCheetahSlow = 186258; - public const uint BestialWrath = 19574; - public const uint ChimeraShotHeal = 53353; public const uint Exhilaration = 109304; public const uint ExhilarationPet = 128594; public const uint ExhilarationR2 = 231546; - public const uint Fire = 82926; - public const uint GenericEnergizeFocus = 91954; - public const uint ImprovedMendPet = 24406; - public const uint LockAndLoad = 56453; public const uint Lonewolf = 155228; public const uint MastersCallTriggered = 62305; public const uint MisdirectionProc = 35079; public const uint PetLastStandTriggered = 53479; - public const uint PetHeartOfThePhoenix = 55709; public const uint PetHeartOfThePhoenixTriggered = 54114; public const uint PetHeartOfThePhoenixDebuff = 55711; - public const uint PetCarrionFeederTriggered = 54045; - public const uint Readiness = 23989; - public const uint SerpentSting = 1978; - public const uint SniperTrainingR1 = 53302; - public const uint SniperTrainingBuffR1 = 64418; public const uint SteadyShotFocus = 77443; public const uint T94PGreatness = 68130; public const uint DraeneiGiftOfTheNaaru = 59543; @@ -75,65 +63,6 @@ namespace Scripts.Spells.Hunter } } - // 53209 - Chimera Shot - [Script] - class spell_hun_chimera_shot : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.ChimeraShotHeal, SpellIds.SerpentSting); - } - - public override bool Load() - { - return GetCaster().IsTypeId(TypeId.Player); - } - - void HandleScriptEffect(uint effIndex) - { - GetCaster().CastSpell(GetCaster(), SpellIds.ChimeraShotHeal, true); - Aura aur = GetHitUnit().GetAura(SpellIds.SerpentSting, GetCaster().GetGUID()); - if (aur != null) - aur.SetDuration(aur.GetSpellInfo().GetMaxDuration(), true); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect)); - } - } - - // 77767 - Cobra Shot - [Script] - class spell_hun_cobra_shot : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.GenericEnergizeFocus, SpellIds.SerpentSting); - } - - public override bool Load() - { - return GetCaster().IsTypeId(TypeId.Player); - } - - void HandleScriptEffect(uint effIndex) - { - GetCaster().CastSpell(GetCaster(), SpellIds.GenericEnergizeFocus, true); - Aura aur = GetHitUnit().GetAura(SpellIds.SerpentSting, GetCaster().GetGUID()); - if (aur != null) - { - int newDuration = aur.GetDuration() + GetEffectValue() * Time.InMilliseconds; - aur.SetDuration(Math.Min(newDuration, aur.GetMaxDuration()), true); - } - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 1, SpellEffectName.ScriptEffect)); - } - } - [Script] // 109304 - Exhilaration class spell_hun_exhilaration : SpellScript { @@ -175,33 +104,6 @@ namespace Scripts.Spells.Hunter } } - // -19572 - Improved Mend Pet - [Script] - class spell_hun_improved_mend_pet : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.ImprovedMendPet); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - return RandomHelper.randChance(GetEffect(0).GetAmount()); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - GetTarget().CastSpell(GetTarget(), SpellIds.ImprovedMendPet, true, null, aurEff); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - // 53478 - Last Stand Pet [Script] class spell_hun_last_stand_pet : SpellScript @@ -375,63 +277,6 @@ namespace Scripts.Spells.Hunter } } - // 23989 - Readiness - [Script] - class spell_hun_readiness : SpellScript - { - public override bool Load() - { - return GetCaster().IsTypeId(TypeId.Player); - } - - void HandleDummy(uint effIndex) - { - // immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath - GetCaster().GetSpellHistory().ResetCooldowns(p => - { - SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(p.Key, GetCastDifficulty()); - - //! If spellId in cooldown map isn't valid, the above will return a null pointer. - if (spellInfo.SpellFamilyName == SpellFamilyNames.Hunter && - spellInfo.Id != SpellIds.Readiness && - spellInfo.Id != SpellIds.BestialWrath && - spellInfo.Id != SpellIds.DraeneiGiftOfTheNaaru && - spellInfo.GetRecoveryTime() > 0) - return true; - return false; - }, true); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); - } - } - - // 82925 - Ready, Set, Aim... - [Script] - class spell_hun_ready_set_aim : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.Fire); - } - - void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode) - { - if (GetStackAmount() == 5) - { - GetTarget().CastSpell(GetTarget(), SpellIds.Fire, true, null, aurEff); - GetTarget().RemoveAura(GetId()); - } - } - - public override void Register() - { - AfterEffectApply.Add(new EffectApplyHandler(OnApply, 0, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask)); - } - } - [Script] // 53480 - Roar of Sacrifice class spell_hun_roar_of_sacrifice : AuraScript { @@ -491,53 +336,6 @@ namespace Scripts.Spells.Hunter } } - // -53302 - Sniper Training - [Script] - class spell_hun_sniper_training : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.SniperTrainingR1, SpellIds.SniperTrainingBuffR1); - } - - void HandlePeriodic(AuraEffect aurEff) - { - PreventDefaultAction(); - if (aurEff.GetAmount() <= 0) - { - uint spellId = SpellIds.SniperTrainingBuffR1 + GetId() - SpellIds.SniperTrainingR1; - Unit target = GetTarget(); - target.CastSpell(target, spellId, true, null, aurEff); - Player playerTarget = GetUnitOwner().ToPlayer(); - if (playerTarget) - { - int baseAmount = aurEff.GetBaseAmount(); - int amount = playerTarget.CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff.GetEffIndex(), baseAmount); - GetEffect(0).SetAmount(amount); - } - } - } - - void HandleUpdatePeriodic(AuraEffect aurEff) - { - Player playerTarget = GetUnitOwner().ToPlayer(); - if (playerTarget) - { - int baseAmount = aurEff.GetBaseAmount(); - int amount = playerTarget.IsMoving() ? - playerTarget.CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff.GetEffIndex(), baseAmount) : - aurEff.GetAmount() - 1; - aurEff.SetAmount(amount); - } - } - - public override void Register() - { - OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicTriggerSpell)); - OnEffectUpdatePeriodic.Add(new EffectUpdatePeriodicHandler(HandleUpdatePeriodic, 0, AuraType.PeriodicTriggerSpell)); - } - } - // 56641 - Steady Shot [Script] class spell_hun_steady_shot : SpellScript @@ -604,26 +402,6 @@ namespace Scripts.Spells.Hunter } } - // 53434 - Call of the Wild - [Script] - class spell_hun_target_only_pet_and_owner : SpellScript - { - void FilterTargets(List targets) - { - targets.Clear(); - targets.Add(GetCaster()); - Unit owner = GetCaster().GetOwner(); - if (owner) - targets.Add(owner); - } - - public override void Register() - { - OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitCasterAreaParty)); - OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 1, Targets.UnitCasterAreaParty)); - } - } - [Script] // 67151 - Item - Hunter T9 4P Bonus (Steady Shot) class spell_hun_t9_4p_bonus : AuraScript { @@ -653,31 +431,4 @@ namespace Scripts.Spells.Hunter OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell)); } } - - // -56333 - T.N.T. - [Script] - class spell_hun_tnt : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.LockAndLoad); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - return RandomHelper.randChance(GetEffect(0).GetAmount()); - } - - void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - GetTarget().CastSpell(GetTarget(), SpellIds.LockAndLoad, true, null, aurEff); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy)); - } - } } diff --git a/Source/Scripts/Spells/Items.cs b/Source/Scripts/Spells/Items.cs index 472e6377f..2c791494f 100644 --- a/Source/Scripts/Spells/Items.cs +++ b/Source/Scripts/Spells/Items.cs @@ -653,7 +653,7 @@ namespace Scripts.Spells.Items uint[][] triggeredSpells = { //CLASS_NONE - new uint[] { }, + Array.Empty(), //CLASS_WARRIOR new uint[] {SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.MartyrComplex }, //CLASS_PALADIN @@ -673,7 +673,7 @@ namespace Scripts.Spells.Items //CLASS_WARLOCK new uint[] {SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia }, //CLASS_UNK - new uint[]{ }, + Array.Empty(), //CLASS_DRUID new uint[] {SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia } }; @@ -818,7 +818,7 @@ namespace Scripts.Spells.Items uint[][] triggeredSpells = { //CLASS_NONE - new uint[] { }, + Array.Empty(), //CLASS_WARRIOR new uint[] {_strengthSpellId, _criticalSpellId, _hasteSpellId }, //CLASS_PALADIN @@ -828,17 +828,17 @@ namespace Scripts.Spells.Items //CLASS_ROGUE new uint[] {_agilitySpellId, _hasteSpellId, _apSpellId }, //CLASS_PRIEST - new uint[] { }, + Array.Empty(), //CLASS_DEATH_KNIGHT new uint[] {_strengthSpellId, _criticalSpellId, _hasteSpellId }, //CLASS_SHAMAN new uint[] {_agilitySpellId, _hasteSpellId, _apSpellId }, //CLASS_MAGE - new uint[] { }, + Array.Empty(), //CLASS_WARLOCK - new uint[] { }, + Array.Empty(), //CLASS_UNK - new uint[] { }, + Array.Empty(), //CLASS_DRUID new uint[] {_strengthSpellId, _agilitySpellId, _hasteSpellId } }; @@ -1781,7 +1781,7 @@ namespace Scripts.Spells.Items Unit target = GetHitUnit(); if (target) { - uint spellId = 0; + uint spellId; uint rand = RandomHelper.URand(0, 99); if (rand < 25) // Fireball (25% chance) spellId = SpellIds.Fireball; diff --git a/Source/Scripts/Spells/Paladin.cs b/Source/Scripts/Spells/Paladin.cs index 3a59cccf4..b4d86a439 100644 --- a/Source/Scripts/Spells/Paladin.cs +++ b/Source/Scripts/Spells/Paladin.cs @@ -67,52 +67,6 @@ namespace Scripts.Spells.Paladin public const uint SealOfRighteousness = 25742; } - // 31821 - Aura Mastery - [Script] - class spell_pal_aura_mastery : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.AuraMasteryImmune); - } - - void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode) - { - GetTarget().CastSpell(GetTarget(), SpellIds.AuraMasteryImmune, true); - } - - void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - GetTarget().RemoveOwnedAura(SpellIds.AuraMasteryImmune, GetCasterGUID()); - } - - public override void Register() - { - AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.AddPctModifier, AuraEffectHandleModes.Real)); - AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.AddPctModifier, AuraEffectHandleModes.Real)); - } - } - - // 64364 - Aura Mastery Immune - [Script] - class spell_pal_aura_mastery_immune : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.ConcentractionAura); - } - - bool CheckAreaTarget(Unit target) - { - return target.HasAura(SpellIds.ConcentractionAura, GetCasterGUID()); - } - - public override void Register() - { - DoCheckAreaTarget.Add(new CheckAreaTargetHandler(CheckAreaTarget)); - } - } - // 37877 - Blessing of Faith [Script] class spell_pal_blessing_of_faith : SpellScript @@ -127,7 +81,7 @@ namespace Scripts.Spells.Paladin Unit unitTarget = GetHitUnit(); if (unitTarget) { - uint spell_id = 0; + uint spell_id; switch (unitTarget.GetClass()) { case Class.Druid: @@ -320,56 +274,6 @@ namespace Scripts.Spells.Paladin } } - // 33695 - Exorcism and Holy Wrath Damage - [Script] - class spell_pal_exorcism_and_holy_wrath_damage : AuraScript - { - void HandleEffectCalcSpellMod(AuraEffect aurEff, ref SpellModifier spellMod) - { - if (spellMod == null) - { - spellMod = new SpellModifier(aurEff.GetBase()); - spellMod.op = SpellModOp.Damage; - spellMod.type = SpellModType.Flat; - spellMod.spellId = GetId(); - spellMod.mask[1] = 0x200002; - } - - spellMod.value = aurEff.GetAmount(); - } - - public override void Register() - { - DoEffectCalcSpellMod.Add(new EffectCalcSpellModHandler(HandleEffectCalcSpellMod, 0, AuraType.Dummy)); - } - } - - // -9799 - Eye for an Eye - [Script] - class spell_pal_eye_for_an_eye : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.EyeForAnEyeDamage); - } - - void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - DamageInfo damageInfo = eventInfo.GetDamageInfo(); - if (damageInfo == null || damageInfo.GetDamage() == 0) - return; - - int damage = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount()); - GetTarget().CastCustomSpell(SpellIds.EyeForAnEyeDamage, SpellValueMod.BasePoint0, damage, eventInfo.GetProcTarget(), true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, m_scriptSpellId == SpellIds.EyeForAnEyeRank1 ? AuraType.Dummy : AuraType.ProcTriggerSpell)); - } - } - // -75806 - Grand Crusader [Script] class spell_pal_grand_crusader : AuraScript @@ -697,80 +601,6 @@ namespace Scripts.Spells.Paladin } } - // 31789 - Righteous Defense - [Script] - class spell_pal_righteous_defense : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.RighteousDefenseTaunt); - } - - SpellCastResult CheckCast() - { - Unit caster = GetCaster(); - if (!caster.IsTypeId(TypeId.Player)) - return SpellCastResult.DontReport; - - Unit target = GetExplTargetUnit(); - if (target) - { - if (!target.IsFriendlyTo(caster) || target.GetAttackers().Empty()) - return SpellCastResult.BadTargets; - } - else - return SpellCastResult.BadTargets; - - return SpellCastResult.SpellCastOk; - } - - void HandleTriggerSpellLaunch(uint effIndex) - { - PreventHitDefaultEffect(effIndex); - } - - void HandleTriggerSpellHit(uint effIndex) - { - PreventHitDefaultEffect(effIndex); - Unit target = GetHitUnit(); - if (target) - GetCaster().CastSpell(target, SpellIds.RighteousDefenseTaunt, true); - } - - public override void Register() - { - OnCheckCast.Add(new CheckCastHandler(CheckCast)); - //! WORKAROUND - //! target select will be executed in hitphase of effect 0 - //! so we must handle trigger spell also in hit phase (default execution in launch phase) - //! see issue #3718 - OnEffectLaunchTarget.Add(new EffectHandler(HandleTriggerSpellLaunch, 1, SpellEffectName.TriggerSpell)); - OnEffectHitTarget.Add(new EffectHandler(HandleTriggerSpellHit, 1, SpellEffectName.TriggerSpell)); - } - } - - // 85285 - Sacred Shield - [Script] - class spell_pal_sacred_shield : SpellScript - { - SpellCastResult CheckCast() - { - Unit caster = GetCaster(); - if (!caster.IsTypeId(TypeId.Player)) - return SpellCastResult.DontReport; - - if (!caster.HealthBelowPct(30)) - return SpellCastResult.CantDoThatRightNow; - - return SpellCastResult.SpellCastOk; - } - - public override void Register() - { - OnCheckCast.Add(new CheckCastHandler(CheckCast)); - } - }; - // 85256 - Templar's Verdict // Updated 4.3.4 [Script] @@ -824,38 +654,6 @@ namespace Scripts.Spells.Paladin } } - // 20154, 21084 - Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) - [Script] - class spell_pal_seal_of_righteousness : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.SealOfCommand); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - return eventInfo.GetProcTarget(); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - - float ap = GetTarget().GetTotalAttackPowerValue(WeaponAttackType.BaseAttack); - int holy = GetTarget().SpellBaseDamageBonusDone(SpellSchoolMask.Holy); - holy += eventInfo.GetProcTarget().SpellBaseDamageBonusTaken(SpellSchoolMask.Holy); - int bp = (int)((ap * 0.022f + 0.044f * holy) * GetTarget().GetBaseAttackTime(WeaponAttackType.BaseAttack) / 1000); - GetTarget().CastCustomSpell(SpellIds.SealOfCommand, SpellValueMod.BasePoint0, bp, eventInfo.GetProcTarget(), true, null, aurEff); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - [Script] // 28789 - Holy Power class spell_pal_t3_6p_bonus : AuraScript { diff --git a/Source/Scripts/Spells/Priest.cs b/Source/Scripts/Spells/Priest.cs index 6f2b0e8b0..2ddf8a40d 100644 --- a/Source/Scripts/Spells/Priest.cs +++ b/Source/Scripts/Spells/Priest.cs @@ -24,57 +24,41 @@ using Game.Spells; using System; using System.Collections.Generic; using System.Linq; +using Game.Maps; namespace Scripts.Spells.Priest { struct SpellIds { - public const uint Absolution = 33167; public const uint AngelicFeatherAreatrigger = 158624; public const uint AngelicFeatherAura = 121557; - public const uint AngelicFeatherTrigger = 121536; public const uint ArmorOfFaith = 28810; public const uint Atonement = 81749; public const uint AtonementHeal = 81751; public const uint AtonementTriggered = 194384; public const uint BlessedHealing = 70772; public const uint BodyAndSoul = 64129; - public const uint BodyAndSoulDispel = 64136; public const uint BodyAndSoulSpeed = 65081; - public const uint CureDisease = 528; - public const uint DispelMagicFriendly = 97690; - public const uint DispelMagicHostile = 97691; - public const uint DivineAegis = 47753; public const uint DivineBlessing = 40440; public const uint DivineWrath = 40441; - public const uint GlyphOfCircleOfHealing = 55675; - public const uint GlyphOfDispelMagic = 55677; - public const uint GlyphOfDispelMagicHeal = 56131; - public const uint GlyphOfLightwell = 55673; - public const uint GlyphOfPrayerOfHealingHeal = 56161; - public const uint GlyphOfShadow = 107906; public const uint GuardianSpiritHeal = 48153; public const uint ItemEfficiency = 37595; - public const uint LeapOfFaith = 73325; public const uint LeapOfFaithEffect = 92832; - public const uint LeapOfFaithEffectTrigger = 92833; - public const uint LeapOfFaithTriggered = 92572; public const uint LevitateEffect = 111759; - public const uint ManaLeechProc = 34650; public const uint OracularHeal = 26170; public const uint PenanceR1 = 47540; public const uint PenanceR1Damage = 47758; public const uint PenanceR1Heal = 47757; + public const uint PrayerOfMendingAura = 41635; + public const uint PrayerOfMendingHeal = 33110; + public const uint PrayerOfMendingJump = 155793; public const uint RenewedHope = 197469; public const uint RenewedHopeEffect = 197470; - public const uint ShadowformVisualWithGlyph = 107904; - public const uint ShadowformVisualWithoutGlyph = 107903; public const uint ShieldDisciplineEnergize = 47755; public const uint ShieldDisciplinePassive = 197045; public const uint SpiritOfRedemption = 27827; public const uint StrengthOfSoul = 197535; public const uint StrengthOfSoulEffect = 197548; - public const uint T9Healing2p = 67201; public const uint ThePenitentAura = 200347; public const uint VampiricEmbraceHeal = 15290; public const uint VampiricTouchDispel = 64085; @@ -116,6 +100,8 @@ namespace Scripts.Spells.Priest [Script] // 81749 - Atonement public class spell_pri_atonement : AuraScript { + List _appliedAtonements = new List(); + public override bool Validate(SpellInfo spellInfo) { return ValidateSpellInfo(SpellIds.AtonementHeal); @@ -150,8 +136,6 @@ namespace Scripts.Spells.Priest OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); } - List _appliedAtonements = new List(); - public void AddAtonementTarget(ObjectGuid target) { _appliedAtonements.Add(target); @@ -208,160 +192,6 @@ namespace Scripts.Spells.Priest } } - [Script] // 64129 - Body and Soul - class spell_pri_body_and_soul : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.CureDisease, SpellIds.BodyAndSoulDispel); - } - - void HandleEffectSpeedProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - // Proc only with Power Word: Shield or Leap of Faith - if (!(eventInfo.GetDamageInfo().GetSpellInfo().SpellFamilyFlags[0].HasAnyFlag(0x1u) || eventInfo.GetDamageInfo().GetSpellInfo().SpellFamilyFlags[2].HasAnyFlag(0x80000u))) - return; - - GetTarget().CastCustomSpell(SpellIds.BodyAndSoulSpeed, SpellValueMod.BasePoint0, aurEff.GetAmount(), eventInfo.GetProcTarget(), true, null, aurEff); - } - - void HandleEffectDispelProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - // Proc only with Cure Disease - if (eventInfo.GetDamageInfo().GetSpellInfo().Id != SpellIds.CureDisease || eventInfo.GetProcTarget() != GetTarget()) - return; - - if (RandomHelper.randChance(aurEff.GetAmount())) - GetTarget().CastSpell(eventInfo.GetProcTarget(), SpellIds.BodyAndSoulDispel, true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleEffectSpeedProc, 0, AuraType.Dummy)); - OnEffectProc.Add(new EffectProcHandler(HandleEffectDispelProc, 1, AuraType.Dummy)); - } - } - - // 34861 - Circle of Healing - [Script] - class spell_pri_circle_of_healing : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.GlyphOfCircleOfHealing); - } - - void FilterTargets(List targets) - { - targets.RemoveAll(obj => - { - Unit target = obj.ToUnit(); - if (target) - return !GetCaster().IsInRaidWith(target); - - return true; - }); - - uint maxTargets = (uint)(GetCaster().HasAura(SpellIds.GlyphOfCircleOfHealing) ? 6 : 5); // Glyph of Circle of Healing - - if (targets.Count > maxTargets) - { - targets.Sort(new HealthPctOrderPred()); - targets.Resize(maxTargets); - } - } - - public override void Register() - { - OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly)); - } - } - - // 527 - Dispel magic - [Script] - class spell_pri_dispel_magic : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.Absolution, SpellIds.GlyphOfDispelMagicHeal, SpellIds.GlyphOfDispelMagic); - } - - SpellCastResult CheckCast() - { - Unit caster = GetCaster(); - Unit target = GetExplTargetUnit(); - - if (!target || (!caster.HasAura(SpellIds.Absolution) && caster != target && target.IsFriendlyTo(caster))) - return SpellCastResult.BadTargets; - return SpellCastResult.SpellCastOk; - } - - void AfterEffectHit(uint effIndex) - { - if (GetHitUnit().IsFriendlyTo(GetCaster())) - { - GetCaster().CastSpell(GetHitUnit(), SpellIds.DispelMagicFriendly, true); - AuraEffect aurEff = GetHitUnit().GetAuraEffect(SpellIds.GlyphOfDispelMagic, 0); - if (aurEff != null) - { - int heal = (int)GetHitUnit().CountPctFromMaxHealth(aurEff.GetAmount()); - GetCaster().CastCustomSpell(SpellIds.GlyphOfDispelMagicHeal, SpellValueMod.BasePoint0, heal, GetHitUnit()); - } - } - else - GetCaster().CastSpell(GetHitUnit(), SpellIds.DispelMagicHostile, true); - } - - public override void Register() - { - OnCheckCast.Add(new CheckCastHandler(CheckCast)); - OnEffectHitTarget.Add(new EffectHandler(AfterEffectHit, 0, SpellEffectName.Dummy)); - } - } - - // -47509 - Divine Aegis - [Script] - class spell_pri_divine_aegis : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.DivineAegis); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - return eventInfo.GetProcTarget(); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - - HealInfo healInfo = eventInfo.GetHealInfo(); - if (healInfo == null || healInfo.GetHeal() == 0) - return; - - int absorb = (int)MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount()); - - // Multiple effects stack, so let's try to find this aura. - AuraEffect aegis = eventInfo.GetProcTarget().GetAuraEffect(SpellIds.DivineAegis, 0); - if (aegis != null) - absorb += aegis.GetAmount(); - - absorb = (int)Math.Min(absorb, eventInfo.GetProcTarget().GetLevel() * 125); - - GetTarget().CastCustomSpell(SpellIds.DivineAegis, SpellValueMod.BasePoint0, absorb, eventInfo.GetProcTarget(), true, null, aurEff); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - // 64844 - Divine Hymn [Script] class spell_pri_divine_hymn : SpellScript @@ -392,57 +222,6 @@ namespace Scripts.Spells.Priest } } - // 55680 - Glyph of Prayer of Healing - [Script] - class spell_pri_glyph_of_prayer_of_healing : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.GlyphOfPrayerOfHealingHeal); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - - HealInfo healInfo = eventInfo.GetHealInfo(); - if (healInfo == null || healInfo.GetHeal() == 0) - return; - - SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.GlyphOfPrayerOfHealingHeal, GetCastDifficulty()); - int heal = (int)(MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount()) / triggeredSpellInfo.GetMaxTicks()); - GetTarget().CastCustomSpell(SpellIds.GlyphOfPrayerOfHealingHeal, SpellValueMod.BasePoint0, heal, eventInfo.GetProcTarget(), true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - - [Script] // 24191 - Improved Power Word Shield - class spell_pri_improved_power_word_shield : AuraScript - { - void HandleEffectCalcSpellMod(AuraEffect aurEff, ref SpellModifier spellMod) - { - if (spellMod == null) - { - spellMod = new SpellModifier(GetAura()); - spellMod.op = (SpellModOp)aurEff.GetMiscValue(); - spellMod.type = SpellModType.Pct; - spellMod.spellId = GetId(); - spellMod.mask = GetSpellInfo().GetEffect(aurEff.GetEffIndex()).SpellClassMask; - } - - spellMod.value = aurEff.GetAmount(); - } - - public override void Register() - { - DoEffectCalcSpellMod.Add(new EffectCalcSpellModHandler(HandleEffectCalcSpellMod, 0, AuraType.Dummy)); - } - } - // 47788 - Guardian Spirit [Script] class spell_pri_guardian_spirit : AuraScript @@ -486,45 +265,6 @@ namespace Scripts.Spells.Priest } } - // 64904 - Hymn of Hope - [Script] - class spell_pri_hymn_of_hope : SpellScript - { - void FilterTargets(List targets) - { - targets.RemoveAll(obj => - { - Unit target = obj.ToUnit(); - if (target) - return target.GetPowerType() != PowerType.Mana; - - return true; - }); - - targets.RemoveAll(obj => - { - Unit target = obj.ToUnit(); - if (target) - return !GetCaster().IsInRaidWith(target); - - return true; - }); - - uint maxTargets = 3; - - if (targets.Count > maxTargets) - { - targets.Sort(new PowerPctOrderPred(PowerType.Mana)); - targets.Resize(maxTargets); - } - } - - public override void Register() - { - OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, SpellConst.EffectAll, Targets.UnitSrcAreaAlly)); - } - } - [Script] // 40438 - Priest Tier 6 Trinket class spell_pri_item_t6_trinket : AuraScript { @@ -594,103 +334,6 @@ namespace Scripts.Spells.Priest } } - // 7001 - Lightwell Renew - [Script] - class spell_pri_lightwell_renew : AuraScript - { - void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) - { - Unit caster = GetCaster(); - if (caster) - { - // Bonus from Glyph of Lightwell - AuraEffect modHealing = caster.GetAuraEffect(SpellIds.GlyphOfLightwell, 0); - if (modHealing != null) - MathFunctions.AddPct(ref amount, modHealing.GetAmount()); - } - } - - public override void Register() - { - DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.PeriodicHeal)); - } - } - - // 8129 - Mana Burn - [Script] - class spell_pri_mana_burn : SpellScript - { - void HandleAfterHit() - { - Unit unitTarget = GetHitUnit(); - if (unitTarget) - unitTarget.RemoveAurasWithMechanic((1 << (int)Mechanics.Fear) | (1 << (int)Mechanics.Polymorph)); - } - - public override void Register() - { - AfterHit.Add(new HitHandler(HandleAfterHit)); - } - } - - // 28305 - Mana Leech (Passive) (Priest Pet Aura) - [Script] - class spell_pri_mana_leech : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.ManaLeechProc); - } - - public override bool Load() - { - _procTarget = null; - return true; - } - - bool CheckProc(ProcEventInfo eventInfo) - { - _procTarget = GetTarget().GetOwner(); - return _procTarget; - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - GetTarget().CastSpell(_procTarget, SpellIds.ManaLeechProc, true, null, aurEff); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - - Unit _procTarget; - } - - // 47948 - Pain and Suffering (Proc) - [Script] - class spell_pri_pain_and_suffering_proc : SpellScript - { - void HandleEffectScriptEffect(uint effIndex) - { - // Refresh Shadow Word: Pain on target - Unit unitTarget = GetHitUnit(); - if (unitTarget) - { - AuraEffect aur = unitTarget.GetAuraEffect(AuraType.PeriodicDamage, SpellFamilyNames.Priest, new FlagArray128(0x8000, 0, 0), GetCaster().GetGUID()); - if (aur != null) - aur.GetBase().RefreshDuration(); - } - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleEffectScriptEffect, 0, SpellEffectName.ScriptEffect)); - } - } - // 47540 - Penance [Script] class spell_pri_penance : SpellScript @@ -771,28 +414,6 @@ namespace Scripts.Spells.Priest } } - // -47569 - Phantasm - [Script] - class spell_pri_phantasm : AuraScript - { - bool CheckProc(ProcEventInfo eventInfo) - { - return RandomHelper.randChance(GetEffect(0).GetAmount()); - } - - void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - GetTarget().RemoveMovementImpairingAuras(true); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy)); - } - } - [Script] // 17 - Power Word: Shield class spell_pri_power_word_shield : AuraScript { @@ -848,53 +469,124 @@ namespace Scripts.Spells.Priest } } - [Script] // 33110 - Prayer of Mending Heal - class spell_pri_prayer_of_mending_heal : SpellScript + // Base class used by various prayer of mending spells + class spell_pri_prayer_of_mending_SpellScriptBase : SpellScript { - void HandleHeal(uint effIndex) + SpellInfo _spellInfoHeal; + SpellEffectInfo _healEffectDummy; + + public override bool Validate(SpellInfo spellInfo) { - Unit caster = GetOriginalCaster(); - if (caster) + return ValidateSpellInfo(SpellIds.PrayerOfMendingHeal, SpellIds.PrayerOfMendingAura) + && Global.SpellMgr.GetSpellInfo(SpellIds.PrayerOfMendingHeal, Difficulty.None).GetEffect(0) != null; + } + + public override bool Load() + { + _spellInfoHeal = Global.SpellMgr.GetSpellInfo(SpellIds.PrayerOfMendingHeal, Difficulty.None); + _healEffectDummy = _spellInfoHeal.GetEffect(0); + return true; + } + + public void CastPrayerOfMendingAura(Unit caster, Unit target, byte stack) + { + uint basePoints = caster.SpellHealingBonusDone(target, _spellInfoHeal, (uint)_healEffectDummy.CalcValue(caster), DamageEffectType.Heal, _healEffectDummy); + Dictionary values = new Dictionary(); + values.Add(SpellValueMod.AuraStack, stack); + values.Add(SpellValueMod.BasePoint0, (int)basePoints); + caster.CastCustomSpell(SpellIds.PrayerOfMendingAura, values, target, TriggerCastFlags.FullMask); + } + } + + [Script] // 33076 - Prayer of Mending + class spell_pri_prayer_of_mending : spell_pri_prayer_of_mending_SpellScriptBase + { + void HandleEffectDummy(uint effIndex) + { + CastPrayerOfMendingAura(GetCaster(), GetHitUnit(), (byte)GetEffectValue()); + } + + public override void Register() + { + OnEffectHit .Add(new EffectHandler(HandleEffectDummy, 0, SpellEffectName.Dummy)); + } + } + + [Script] // 41635 - Prayer of Mending (Aura) - SPELL_PRIEST_PRAYER_OF_MENDING_AURA + class spell_pri_prayer_of_mending_AuraScript : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.PrayerOfMendingHeal, SpellIds.PrayerOfMendingJump); + } + + void HandleHeal(AuraEffect aurEff, ProcEventInfo eventInfo) + { + // Caster: player (priest) that cast the Prayer of Mending + // Target: player that currently has Prayer of Mending aura on him + Unit target = GetTarget(); + Unit caster = GetCaster(); + if (caster != null) { - AuraEffect aurEff = caster.GetAuraEffect(SpellIds.T9Healing2p, 0); - if (aurEff != null) - { - int heal = GetHitHeal(); - MathFunctions.AddPct(ref heal, aurEff.GetAmount()); - SetHitHeal(heal); - } + // Cast the spell to heal the owner + caster.CastSpell(target, SpellIds.PrayerOfMendingHeal, true, null, aurEff); + + // Only cast jump if stack is higher than 0 + int stackAmount = GetStackAmount(); + if (stackAmount > 1) + target.CastCustomSpell(SpellIds.PrayerOfMendingJump, SpellValueMod.BasePoint0, stackAmount - 1, target, true, null, aurEff, caster.GetGUID()); + + Remove(); } } public override void Register() { - OnEffectHitTarget.Add(new EffectHandler(HandleHeal, 0, SpellEffectName.Heal)); + OnEffectProc.Add(new EffectProcHandler(HandleHeal, 0, AuraType.Dummy)); } } - // 15473 - Shadowform - [Script] - class spell_pri_shadowform : AuraScript + [Script] // 155793 - prayer of mending (Jump) - SPELL_PRIEST_PRAYER_OF_MENDING_JUMP + class spell_pri_prayer_of_mending_jump : spell_pri_prayer_of_mending_SpellScriptBase { - public override bool Validate(SpellInfo spellInfo) + void OnTargetSelect(List targets) { - return ValidateSpellInfo(SpellIds.ShadowformVisualWithoutGlyph, SpellIds.ShadowformVisualWithGlyph); + // Find the best target - prefer players over pets + bool foundPlayer = false; + foreach (WorldObject worldObject in targets) + { + if (worldObject.IsPlayer()) + { + foundPlayer = true; + break; + } + } + + if (foundPlayer) + targets.RemoveAll(new ObjectTypeIdCheck(TypeId.Player, false)); + + // choose one random target from targets + if (targets.Count > 1) + { + WorldObject selected = targets.SelectRandom(); + targets.Clear(); + targets.Add(selected); + } } - void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode) + void HandleJump(uint effIndex) { - GetTarget().CastSpell(GetTarget(), GetTarget().HasAura(SpellIds.GlyphOfShadow) ? SpellIds.ShadowformVisualWithGlyph : SpellIds.ShadowformVisualWithoutGlyph, true); - } + Unit origCaster = GetOriginalCaster(); // the one that started the prayer of mending chain + Unit target = GetHitUnit(); // the target we decided the aura should jump to - void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - GetTarget().RemoveAurasDueToSpell(GetTarget().HasAura(SpellIds.GlyphOfShadow) ? SpellIds.ShadowformVisualWithGlyph : SpellIds.ShadowformVisualWithoutGlyph); + if (origCaster) + CastPrayerOfMendingAura(origCaster, target, (byte)GetEffectValue()); } public override void Register() { - AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.ModShapeshift, AuraEffectHandleModes.RealOrReapplyMask)); - AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.ModShapeshift, AuraEffectHandleModes.RealOrReapplyMask)); + OnObjectAreaTargetSelect .Add(new ObjectAreaTargetSelectHandler(OnTargetSelect, 0, Targets.UnitSrcAreaAlly)); + OnEffectHitTarget.Add(new EffectHandler(HandleJump, 0, SpellEffectName.Dummy)); } } diff --git a/Source/Scripts/Spells/Quest.cs b/Source/Scripts/Spells/Quest.cs index c4ed707b4..18a02b493 100644 --- a/Source/Scripts/Spells/Quest.cs +++ b/Source/Scripts/Spells/Quest.cs @@ -461,7 +461,7 @@ namespace Scripts.Spells.Quest void HandleDummy(uint effIndex) { - Unit target = GetExplTargetUnit(); + Unit target = GetHitUnit(); if (target) if (target.IsTypeId(TypeId.Unit) && target.HasAura(SpellIds.ForceShieldArcanePurpleX3)) // Make sure nobody else is channeling the same target @@ -553,7 +553,7 @@ namespace Scripts.Spells.Quest Creature target = GetHitCreature(); if (target) { - uint spellId = 0; + uint spellId; switch (target.GetEntry()) { case CreatureIds.Scavengebot004a8: @@ -841,11 +841,10 @@ namespace Scripts.Spells.Quest void HandleDummy(uint effIndex) { Player caster = GetCaster().ToPlayer(); - Creature target = GetHitCreature(); - if (target) + if (target != null) { - if (target && !target.HasAura(SpellIds.Flames)) + if (!target.HasAura(SpellIds.Flames)) { caster.KilledMonsterCredit(CreatureIds.VillagerKillCredit); target.CastSpell(target, SpellIds.Flames, true); @@ -1559,7 +1558,7 @@ namespace Scripts.Spells.Quest void HandleDummy(uint effIndex) { - uint spellId = 0; + uint spellId; switch (GetHitCreature().GetEntry()) { diff --git a/Source/Scripts/Spells/Rogue.cs b/Source/Scripts/Spells/Rogue.cs index 632587e76..0e84d3648 100644 --- a/Source/Scripts/Spells/Rogue.cs +++ b/Source/Scripts/Spells/Rogue.cs @@ -26,18 +26,11 @@ namespace Scripts.Spells.Rogue public struct SpellIds { public const uint BladeFlurryExtraAttack = 22482; - public const uint CheatDeathCooldown = 31231; - public const uint GlyphOfPreparation = 56819; public const uint KillingSpree = 51690; public const uint KillingSpreeTeleport = 57840; public const uint KillingSpreeWeaponDmg = 57841; public const uint KillingSpreeDmgBuff = 61851; - public const uint PreyOnTheWeak = 58670; - public const uint ShivTriggered = 5940; - public const uint TricksOfTheTradeDmgBoost = 57933; public const uint TricksOfTheTradeProc = 59628; - public const uint SerratedBladesR1 = 14171; - public const uint Rupture = 1943; public const uint HonorAmongThievesEnergize = 51699; public const uint T52pSetBonus = 37169; } diff --git a/Source/Scripts/Spells/Shaman.cs b/Source/Scripts/Spells/Shaman.cs index 42a11a0a0..b78059d4f 100644 --- a/Source/Scripts/Spells/Shaman.cs +++ b/Source/Scripts/Spells/Shaman.cs @@ -43,19 +43,16 @@ namespace Scripts.Spells.Shaman public const uint ElementalMastery = 16166; public const uint EnergySurge = 40465; public const uint Exhaustion = 57723; - public const uint FireNovaTriggered = 8349; public const uint FlameShock = 8050; public const uint FlameShockMaelstrom = 188389; public const uint FlametongueAttack = 10444; public const uint GatheringStorms = 198299; public const uint GatheringStormsBuff = 198300; - public const uint HighTide = 157154; public const uint ItemLightningShield = 23552; public const uint ItemLightningShieldDamage = 27635; public const uint ItemManaSurge = 23571; public const uint LavaBurst = 51505; public const uint LavaBurstBonusDamage = 71824; - public const uint LavaLashSpreadFlameShock = 105792; public const uint LavaSurge = 77762; public const uint PathOfFlamesSpread = 210621; public const uint PathOfFlamesTalent = 201909; @@ -300,23 +297,6 @@ namespace Scripts.Spells.Shaman } } - [Script] // 1535 Fire Nova - class spell_sha_fire_nova : SpellScript - { - void HandleDummy(uint effIndex) - { - Unit target = GetHitUnit(); - if (target) - if (target.HasAura(SpellIds.FlameShock)) - GetCaster().CastSpell(target, SpellIds.FireNovaTriggered, true); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); - } - } - [Script] // 194084 - Flametongue class spell_sha_flametongue : AuraScript { diff --git a/Source/Scripts/Spells/Warlock.cs b/Source/Scripts/Spells/Warlock.cs index a7b456f27..c3861e714 100644 --- a/Source/Scripts/Spells/Warlock.cs +++ b/Source/Scripts/Spells/Warlock.cs @@ -27,43 +27,22 @@ namespace Scripts.Spells.Warlock { struct SpellIds { - public const uint BaneOfDoomEffect = 18662; public const uint CreateHealthstone = 23517; public const uint DemonicCircleAllowCast = 62388; public const uint DemonicCircleSummon = 48018; public const uint DemonicCircleTeleport = 48020; - public const uint DemonicEmpowermentFelguard = 54508; - public const uint DemonicEmpowermentFelhunter = 54509; - public const uint DemonicEmpowermentImp = 54444; - public const uint DemonicEmpowermentSuccubus = 54435; - public const uint DemonicEmpowermentVoidwalker = 54443; - public const uint DemonSoulImp = 79459; - public const uint DemonSoulFelhunter = 79460; - public const uint DemonSoulFelguard = 79452; - public const uint DemonSoulSuccubus = 79453; - public const uint DemonSoulVoidwalker = 79454; public const uint DevourMagicHeal = 19658; - public const uint FelSynergyHeal = 54181; public const uint GlyphOfDemonTraining = 56249; - public const uint GlyphOfShadowflame = 63311; public const uint GlyphOfSoulSwap = 56226; public const uint GlyphOfSuccubus = 56250; - public const uint HauntHeal = 48210; - public const uint Immolate = 348; public const uint ImprovedHealthFunnelBuffR1 = 60955; public const uint ImprovedHealthFunnelBuffR2 = 60956; public const uint ImprovedHealthFunnelR1 = 18703; public const uint ImprovedHealthFunnelR2 = 18704; - public const uint ImprovedSoulFirePct = 85383; - public const uint ImprovedSoulFireState = 85385; - public const uint NetherWard = 91711; - public const uint NetherTalent = 91713; public const uint RainOfFire = 5740; public const uint RainOfFireDamage = 42223; public const uint SeedOfCorruptionDamage = 27285; public const uint SeedOfCorruptionGeneric = 32865; - public const uint ShadowTrance = 17941; - public const uint ShadowWard = 6229; public const uint Soulshatter = 32835; public const uint SoulSwapCdMarker = 94229; public const uint SoulSwapOverride = 86211; @@ -102,27 +81,6 @@ namespace Scripts.Spells.Warlock } } - [Script] // 17962 - Conflagrate - Updated to 4.3.4 - class spell_warl_conflagrate : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.Immolate); - } - - // 6.x dmg formula in tooltip - // void HandleHit(uint effIndex) - // { - // if (AuraEffect aurEff = GetHitUnit().GetAuraEffect(SPELL_WARLOCK_IMMOLATE, 2, GetCaster().GetGUID())) - // SetHitDamage(CalculatePct(aurEff.GetAmount(), HasSpellInfo().Effects[1].CalcValue(GetCaster()))); - // } - - public override void Register() - { - //OnEffectHitTarget.Add(new EffectHandler(spell_warl_conflagrate_SpellScript::HandleHit, 0, SpellIds._EFFECT_SCHOOL_DAMAGE); - } - } - [Script] // 77220 - Mastery: Chaotic Energies class spell_warl_chaotic_energies : AuraScript { @@ -173,38 +131,6 @@ namespace Scripts.Spells.Warlock } } - [Script] // 603 - Bane of Doom - class spell_warl_bane_of_doom : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.BaneOfDoomEffect); - } - - public override bool Load() - { - return GetCaster() && GetCaster().IsTypeId(TypeId.Player); - } - - void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - if (!GetCaster()) - return; - - AuraRemoveMode removeMode = GetTargetApplication().GetRemoveMode(); - if (removeMode != AuraRemoveMode.Death || !IsExpired()) - return; - - if (GetCaster().ToPlayer().IsHonorOrXPTarget(GetTarget())) - GetCaster().CastSpell(GetTarget(), SpellIds.BaneOfDoomEffect, true, null, aurEff); - } - - public override void Register() - { - AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.PeriodicDamage, AuraEffectHandleModes.Real)); - } - } - [Script] // 48018 - Demonic Circle: Summon class spell_warl_demonic_circle_summon : AuraScript { @@ -268,103 +194,6 @@ namespace Scripts.Spells.Warlock } } - [Script] // 77801 - Demon Soul - Updated to 4.3.4 - class spell_warl_demon_soul : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.DemonSoulImp, SpellIds.DemonSoulFelhunter, SpellIds.DemonSoulFelguard, SpellIds.DemonSoulSuccubus, SpellIds.DemonSoulVoidwalker); - } - - void OnHitTarget(uint effIndex) - { - Unit caster = GetCaster(); - Creature targetCreature = GetHitCreature(); - if (targetCreature) - { - if (targetCreature.IsPet()) - { - CreatureTemplate ci = targetCreature.GetCreatureTemplate(); - switch (ci.Family) - { - case CreatureFamily.Succubus: - caster.CastSpell(caster, SpellIds.DemonSoulSuccubus); - break; - case CreatureFamily.Voidwalker: - caster.CastSpell(caster, SpellIds.DemonSoulVoidwalker); - break; - case CreatureFamily.Felguard: - caster.CastSpell(caster, SpellIds.DemonSoulFelguard); - break; - case CreatureFamily.Felhunter: - caster.CastSpell(caster, SpellIds.DemonSoulFelhunter); - break; - case CreatureFamily.Imp: - caster.CastSpell(caster, SpellIds.DemonSoulImp); - break; - default: - break; - } - } - } - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(OnHitTarget, 0, SpellEffectName.ScriptEffect)); - } - } - - [Script] // 47193 - Demonic Empowerment - class spell_warl_demonic_empowerment : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.DemonicEmpowermentSuccubus, SpellIds.DemonicEmpowermentVoidwalker, SpellIds.DemonicEmpowermentFelguard, SpellIds.DemonicEmpowermentFelhunter, SpellIds.DemonicEmpowermentImp); - } - - void HandleScriptEffect(uint effIndex) - { - Creature targetCreature = GetHitCreature(); - if (targetCreature) - { - if (targetCreature.IsPet()) - { - CreatureTemplate ci = targetCreature.GetCreatureTemplate(); - switch (ci.Family) - { - case CreatureFamily.Succubus: - targetCreature.CastSpell(targetCreature, SpellIds.DemonicEmpowermentSuccubus, true); - break; - case CreatureFamily.Voidwalker: - { - SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DemonicEmpowermentVoidwalker, GetCastDifficulty()); - int hp = (int)targetCreature.CountPctFromMaxHealth(GetCaster().CalculateSpellDamage(targetCreature, spellInfo, 0)); - targetCreature.CastCustomSpell(targetCreature, SpellIds.DemonicEmpowermentVoidwalker, hp, 0, 0, true); - break; - } - case CreatureFamily.Felguard: - targetCreature.CastSpell(targetCreature, SpellIds.DemonicEmpowermentFelguard, true); - break; - case CreatureFamily.Felhunter: - targetCreature.CastSpell(targetCreature, SpellIds.DemonicEmpowermentFelhunter, true); - break; - case CreatureFamily.Imp: - targetCreature.CastSpell(targetCreature, SpellIds.DemonicEmpowermentImp, true); - break; - default: - break; - } - } - } - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect)); - } - } - [Script] // 67518, 19505 - Devour Magic class spell_warl_devour_magic : SpellScript { @@ -397,86 +226,6 @@ namespace Scripts.Spells.Warlock } } - [Script] // 47422 - Everlasting Affliction - class spell_warl_everlasting_affliction : SpellScript - { - void HandleScriptEffect(uint effIndex) - { - Unit caster = GetCaster(); - Unit target = GetHitUnit(); - if (target) - { - // Refresh corruption on target - AuraEffect aurEff = target.GetAuraEffect(AuraType.PeriodicDamage, SpellFamilyNames.Warlock, new FlagArray128(0x2, 0, 0), caster.GetGUID()); - if (aurEff != null) - { - uint damage = (uint)Math.Max(aurEff.GetAmount(), 0); - Global.ScriptMgr.ModifyPeriodicDamageAurasTick(target, caster, ref damage); - aurEff.SetDamage((int)(caster.SpellDamageBonusDone(target, aurEff.GetSpellInfo(), damage, DamageEffectType.DOT, GetEffectInfo(effIndex)) * aurEff.GetDonePct())); - aurEff.CalculatePeriodic(caster, false, false); - aurEff.GetBase().RefreshDuration(true); - } - } - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect)); - } - } - - [Script] // -47230 - Fel Synergy - class spell_warl_fel_synergy : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.FelSynergyHeal); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - DamageInfo damageInfo = eventInfo.GetDamageInfo(); - if (damageInfo == null || damageInfo.GetDamage() == 0) - return false; - - return GetTarget().GetGuardianPet(); - } - - void onProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - - int heal = (int)MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), aurEff.GetAmount()); - GetTarget().CastCustomSpell(SpellIds.FelSynergyHeal, SpellValueMod.BasePoint0, heal, (Unit)null, true, null, aurEff); // TARGET_UNIT_PET - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(onProc, 0, AuraType.Dummy)); - } - } - - [Script] // 63310 - Glyph of Shadowflame - class spell_warl_glyph_of_shadowflame : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.GlyphOfShadowflame); - } - - void onProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - GetTarget().CastSpell(eventInfo.GetProcTarget(), SpellIds.GlyphOfShadowflame, true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(onProc, 0, AuraType.Dummy)); - } - } - [Script] // 48181 - Haunt class spell_warl_haunt : SpellScript { @@ -497,30 +246,6 @@ namespace Scripts.Spells.Warlock } } - [Script] - class spell_warl_haunt_AuraScript : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.HauntHeal); - } - - void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - Unit caster = GetCaster(); - if (caster) - { - int amount = aurEff.GetAmount(); - GetTarget().CastCustomSpell(caster, SpellIds.HauntHeal, amount, 0, 0, true, null, aurEff, GetCasterGUID()); - } - } - - public override void Register() - { - OnEffectRemove.Add(new EffectApplyHandler(HandleRemove, 1, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask)); - } - } - [Script] // 755 - Health Funnel class spell_warl_health_funnel : AuraScript { @@ -554,7 +279,7 @@ namespace Scripts.Spells.Warlock Player modOwner = caster.GetSpellModOwner(); if (modOwner) - modOwner.ApplySpellMod(GetId(), SpellModOp.Cost, ref damage); + modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.Cost, ref damage); SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, caster, GetSpellInfo(), GetAura().GetSpellVisual(), GetSpellInfo().SchoolMask, GetAura().GetCastGUID()); damageInfo.periodicLog = true; @@ -586,50 +311,6 @@ namespace Scripts.Spells.Warlock } } - [Script] // -18119 - Improved Soul Fire - class spell_warl_improved_soul_fire : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.ImprovedSoulFirePct, SpellIds.ImprovedSoulFireState); - } - - void onProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - GetTarget().CastCustomSpell(SpellIds.ImprovedSoulFirePct, SpellValueMod.BasePoint0, aurEff.GetAmount(), GetTarget(), true, null, aurEff); - GetTarget().CastSpell(GetTarget(), SpellIds.ImprovedSoulFireState, true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(onProc, 0, AuraType.Dummy)); - } - } - - // 687 - Demon Armor - [Script] // 28176 - Fel Armor - class spell_warl_nether_ward_overrride : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.NetherTalent, SpellIds.NetherWard, SpellIds.ShadowWard); - } - - void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) - { - if (GetUnitOwner().HasAura(SpellIds.NetherTalent)) - amount = (int)SpellIds.NetherWard; - else - amount = (int)SpellIds.ShadowWard; - } - - public override void Register() - { - DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 2, AuraType.OverrideActionbarSpells)); - } - } - [Script] // 6358 - Seduction (Special Ability) class spell_warl_seduction : SpellScript { @@ -755,49 +436,6 @@ namespace Scripts.Spells.Warlock } } - [Script] // -7235 - Shadow Ward - class spell_warl_shadow_ward : AuraScript - { - void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) - { - canBeRecalculated = false; - Unit caster = GetCaster(); - if (caster) - { - // +80.68% from sp bonus - float bonus = 0.8068f; - - bonus *= caster.SpellBaseHealingBonusDone(GetSpellInfo().GetSchoolMask()); - - amount += (int)bonus; - } - } - - public override void Register() - { - DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.SchoolAbsorb)); - } - } - - [Script] // -30293 - Soul Leech - class spell_warl_soul_leech : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.GenReplenishment); - } - - void onProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - GetTarget().CastSpell((Unit)null, SpellIds.GenReplenishment, true, null, aurEff); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(onProc, 0, AuraType.ProcTriggerSpellWithValue)); - } - } - [Script] // 86121 - Soul Swap class spell_warl_soul_swap : SpellScript { diff --git a/Source/Scripts/Spells/Warrior.cs b/Source/Scripts/Spells/Warrior.cs index 4ff95d3d2..592ad5511 100644 --- a/Source/Scripts/Spells/Warrior.cs +++ b/Source/Scripts/Spells/Warrior.cs @@ -46,33 +46,17 @@ namespace Scripts.Spells.Warrior public const uint ImpendingVictory = 202168; public const uint ImpendingVictoryHeal = 202166; public const uint ImprovedHeroicLeap = 157449; - public const uint JuggernautCritBonusBuff = 65156; - public const uint JuggernautCritBonusTalent = 64976; - public const uint LastStandTriggered = 12976; public const uint MortalStrike = 12294; public const uint MortalWounds = 213667; public const uint RallyingCry = 97463; - public const uint Rend = 94009; - public const uint RetaliationDamage = 22858; - public const uint SecoundWindProcRank1 = 29834; - public const uint SecoundWindProcRank2 = 29838; - public const uint SecoundWindTriggerRank1 = 29841; - public const uint SecoundWindTriggerRank2 = 29842; - public const uint ShieldSlam = 23922; public const uint Shockwave = 46968; public const uint ShockwaveStun = 132168; - public const uint Slam = 50782; public const uint Stoicism = 70845; public const uint StormBoltStun = 132169; public const uint SweepingStrikesExtraAttack1 = 12723; public const uint SweepingStrikesExtraAttack2 = 26654; public const uint Taunt = 355; public const uint TraumaEffect = 215537; - public const uint UnrelentingAssaultRank1 = 46859; - public const uint UnrelentingAssaultRank2 = 46860; - public const uint UnrelentingAssaultTrigger1 = 64849; - public const uint UnrelentingAssaultTrigger2 = 64850; - public const uint Vengeance = 76691; public const uint Victorious = 32216; public const uint VictoriousRushHeal = 118779; } @@ -192,61 +176,7 @@ namespace Scripts.Spells.Warrior } } - // Updated 4.3.4 - [Script] - class spell_warr_concussion_blow : SpellScript - { - void HandleDummy(uint effIndex) - { - SetHitDamage((int)MathFunctions.CalculatePct(GetCaster().GetTotalAttackPowerValue(WeaponAttackType.BaseAttack), GetEffectValue())); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 2, SpellEffectName.Dummy)); - } - } - - // Updated 4.3.4 - [Script] // 5308 - Execute - class spell_warr_execute : SpellScript - { - void HandleEffect(uint effIndex) - { - /* - Unit caster = GetCaster(); - if (GetHitUnit()) - { - SpellInfo spellInfo = GetSpellInfo(); - int rageUsed = Math.Min(200 - spellInfo.CalcPowerCost(caster, spellInfo.SchoolMask), caster.GetPower(PowerType.Rage)); - int newRage = Math.Max(0, caster.GetPower(PowerType.Rage) - rageUsed); - - // Sudden Death rage save - AuraEffect aurEff = caster.GetAuraEffect(AuraType.ProcTriggerSpell, SpellFamilyNames.Generic, 1989, 0); // Icon SuddenDeath - if (aurEff != null) - { - int ragesave = aurEff.GetSpellInfo().GetEffect(0).CalcValue() * 10; - newRage = Math.Max(newRage, ragesave); - } - - caster.SetPower(PowerType.Rage, newRage); - - // Formula taken from the DBC: "${10+$AP*0.437*$m1/100}" - int baseDamage = (int)(10 + caster.GetTotalAttackPowerValue(WeaponAttackType.BaseAttack) * 0.437f * GetEffectValue() / 100.0f); - // Formula taken from the DBC: "${$ap*0.874*$m1/100-1} = 20 rage" - int moreDamage = (int)(rageUsed * (caster.GetTotalAttackPowerValue(WeaponAttackType.BaseAttack) * 0.874f * GetEffectValue() / 100.0f - 1) / 200); - SetHitDamage(baseDamage + moreDamage); - } - */ - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleEffect, 0, SpellEffectName.SchoolDamage)); - } - } - - [Script] // Heroic leap - 6544 + [Script] // 6544 Heroic leap class spell_warr_heroic_leap : SpellScript { public override bool Validate(SpellInfo spellInfo) @@ -390,55 +320,8 @@ namespace Scripts.Spells.Warrior } } - // -84583 Lambs to the Slaughter - [Script] - class spell_warr_lambs_to_the_slaughter : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.MortalStrike, SpellIds.Rend); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - Aura aur = eventInfo.GetProcTarget().GetAura(SpellIds.Rend, GetTarget().GetGUID()); - if (aur != null) - aur.SetDuration(aur.GetSpellInfo().GetMaxDuration(), true); - - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell)); - } - } - - // Updated 4.3.4 - // 12975 - Last Stand - [Script] - class spell_warr_last_stand : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.LastStandTriggered); - } - - void HandleDummy(uint effIndex) - { - Unit caster = GetCaster(); - int healthModSpellBasePoints0 = (int)(caster.CountPctFromMaxHealth(GetEffectValue())); - caster.CastCustomSpell(caster, SpellIds.LastStandTriggered, healthModSpellBasePoints0, 0, 0, true, null); - } - - public override void Register() - { - // add dummy effect spell handler to Last Stand - OnEffectHit.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); - } - } - [Script] // 12294 - Mortal Strike 7.1.5 - class spell_warr_mortal_strike_SpellScript : SpellScript + class spell_warr_mortal_strike : SpellScript { public override bool Validate(SpellInfo spellInfo) { @@ -458,31 +341,6 @@ namespace Scripts.Spells.Warrior } } - [Script] // 7384 - Overpower - class spell_warr_overpower : SpellScript - { - void HandleEffect(uint effIndex) - { - uint spellId = 0; - if (GetCaster().HasAura(SpellIds.UnrelentingAssaultRank1)) - spellId = SpellIds.UnrelentingAssaultTrigger1; - else if (GetCaster().HasAura(SpellIds.UnrelentingAssaultRank2)) - spellId = SpellIds.UnrelentingAssaultTrigger2; - - if (spellId == 0) - return; - - Player target = GetHitPlayer(); - if (target) - if (target.IsNonMeleeSpellCast(false, false, true)) // UNIT_STATE_CASTING should not be used here, it's present during a tick for instant casts - target.CastSpell(target, spellId, true); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleEffect, 0, SpellEffectName.Any)); - } - } [Script] // 97462 - Rallying Cry class spell_warr_rallying_cry : SpellScript { @@ -509,157 +367,6 @@ namespace Scripts.Spells.Warrior } } - // 94009 - Rend - [Script] - class spell_warr_rend : AuraScript - { - void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) - { - Unit caster = GetCaster(); - if (caster) - { - canBeRecalculated = false; - - // $0.25 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick - float ap = caster.GetTotalAttackPowerValue(WeaponAttackType.BaseAttack); - int mws = (int)caster.GetBaseAttackTime(WeaponAttackType.BaseAttack); - float mwbMin = caster.GetWeaponDamageRange(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage); - float mwbMax = caster.GetWeaponDamageRange(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage); - float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.25f; - amount += (int)(caster.ApplyEffectModifiers(GetSpellInfo(), aurEff.GetEffIndex(), mwb)); - } - } - - public override void Register() - { - DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 0, AuraType.PeriodicDamage)); - } - } - - // 20230 - Retaliation - [Script] - class spell_warr_retaliation : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.RetaliationDamage); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - // check attack comes not from behind and warrior is not stunned - return GetTarget().IsInFront(eventInfo.GetProcTarget(), MathFunctions.PI) && !GetTarget().HasUnitState(UnitState.Stunned); - } - - void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - GetTarget().CastSpell(eventInfo.GetProcTarget(), SpellIds.RetaliationDamage, true, null, aurEff); - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleEffectProc, 0, AuraType.Dummy)); - } - } - - // 64380, 65941 - Shattering Throw - [Script] - class spell_warr_shattering_throw : SpellScript - { - void HandleScript(uint effIndex) - { - PreventHitDefaultEffect(effIndex); - - // Remove shields, will still display immune to damage part - Unit target = GetHitUnit(); - if (target) - target.RemoveAurasWithMechanic(1 << (int)Mechanics.ImmuneShield, AuraRemoveMode.EnemySpell); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect)); - } - } - - // Updated 4.3.4 - [Script] - class spell_warr_slam : SpellScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.Slam); - } - - void HandleDummy(uint effIndex) - { - if (GetHitUnit()) - GetCaster().CastCustomSpell(SpellIds.Slam, SpellValueMod.BasePoint0, GetEffectValue(), GetHitUnit(), TriggerCastFlags.FullMask); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy)); - } - } - - [Script] - class spell_warr_second_wind_proc : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.SecoundWindProcRank1, SpellIds.SecoundWindProcRank2, SpellIds.SecoundWindTriggerRank1, SpellIds.SecoundWindTriggerRank2); - } - - bool CheckProc(ProcEventInfo eventInfo) - { - if (eventInfo.GetProcTarget() == GetTarget()) - return false; - if (eventInfo.GetDamageInfo().GetSpellInfo() == null || - (eventInfo.GetDamageInfo().GetSpellInfo().GetAllEffectsMechanicMask() & ((1 << (int)Mechanics.Root) | (1 << (int)Mechanics.Stun))) == 0) - return false; - return true; - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - uint spellId = 0; - - if (GetSpellInfo().Id == SpellIds.SecoundWindProcRank1) - spellId = SpellIds.SecoundWindTriggerRank1; - else if (GetSpellInfo().Id == SpellIds.SecoundWindProcRank2) - spellId = SpellIds.SecoundWindTriggerRank2; - if (spellId == 0) - return; - - GetTarget().CastSpell(GetTarget(), spellId, true, null, aurEff); - - } - - public override void Register() - { - DoCheckProc.Add(new CheckProcHandler(CheckProc)); - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); - } - } - - [Script] - class spell_warr_second_wind_trigger : AuraScript - { - void CalculateAmount(AuraEffect aurEff, ref int amount, ref bool canBeRecalculated) - { - amount = (int)(GetUnitOwner().CountPctFromMaxHealth(amount)); - } - - public override void Register() - { - DoEffectCalcAmount.Add(new EffectCalcAmountHandler(CalculateAmount, 1, AuraType.PeriodicHeal)); - } - } - [Script] // 46968 - Shockwave class spell_warr_shockwave : SpellScript { @@ -784,29 +491,6 @@ namespace Scripts.Spells.Warrior Unit _procTarget; } - // -46951 - Sword and Board - [Script] - class spell_warr_sword_and_board : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.ShieldSlam); - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - // Remove cooldown on Shield Slam - Player player = GetTarget().ToPlayer(); - if (player) - player.GetSpellHistory().ResetCooldown(SpellIds.ShieldSlam, true); - } - - public override void Register() - { - OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell)); - } - } - [Script] // 215538 - Trauma class spell_warr_trauma : AuraScript { @@ -896,74 +580,4 @@ namespace Scripts.Spells.Warrior AfterCast.Add(new CastHandler(HandleHeal)); } } - - // 50720 - Vigilance - [Script] - class spell_warr_vigilance : AuraScript - { - public override bool Validate(SpellInfo spellInfo) - { - return ValidateSpellInfo(SpellIds.Vengeance); - } - - public override bool Load() - { - //_procTarget = null; - return true; - } - - /*bool CheckProc(ProcEventInfo eventInfo) - { - _procTarget = GetCaster(); - return _procTarget && eventInfo.GetDamageInfo() != null; - } - - void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) - { - PreventDefaultAction(); - int damage = (int)(MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), aurEff.GetSpellInfo().GetEffect(1).CalcValue())); - - GetTarget().CastSpell(_procTarget, SpellIds.VigilanceProc, true, null, aurEff); - _procTarget.CastCustomSpell(_procTarget, SpellIds.Vengeance, damage, damage, damage, true, null, aurEff); - }*/ - - void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode) - { - Unit caster = GetCaster(); - if (caster) - { - if (caster.HasAura(SpellIds.Vengeance)) - caster.RemoveAurasDueToSpell(SpellIds.Vengeance); - } - } - - public override void Register() - { - //DoCheckProc.Add(new CheckProcHandler(CheckProc)); - //OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell)); - OnEffectRemove.Add(new EffectApplyHandler(HandleRemove, 0, AuraType.ProcTriggerSpell, AuraEffectHandleModes.Real)); - } - - //Unit _procTarget; - } - - // 50725 Vigilance - [Script] - class spell_warr_vigilance_trigger : SpellScript - { - void HandleScript(uint effIndex) - { - PreventHitDefaultEffect(effIndex); - - // Remove Taunt cooldown - Player target = GetHitPlayer(); - if (target) - target.GetSpellHistory().ResetCooldown(SpellIds.Taunt, true); - } - - public override void Register() - { - OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect)); - } - } } diff --git a/Source/Scripts/World/NpcSpecial.cs b/Source/Scripts/World/NpcSpecial.cs new file mode 100644 index 000000000..b3bef88ce --- /dev/null +++ b/Source/Scripts/World/NpcSpecial.cs @@ -0,0 +1,2349 @@ +/* + * Copyright (C) 2012-2020 CypherCore + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Framework.Constants; +using Framework.GameMath; +using Game; +using Game.AI; +using Game.Entities; +using Game.Maps; +using Game.Scripting; +using Game.Spells; +using System; +using System.Collections.Generic; +using System.Linq; +using Framework.Dynamic; +using Game.Movement; + +namespace Scripts.World.NpcSpecial +{ + enum SpawnType + { + TripwireRooftop, // no warning, summon Creature at smaller range + AlarmBot, // cast guards mark and summon npc - if player shows up with that buff duration < 5 seconds attack + } + + class SpawnAssociation + { + public SpawnAssociation(uint _thisCreatureEntry, uint _spawnedCreatureEntry, SpawnType _spawnType) + { + thisCreatureEntry = _thisCreatureEntry; + spawnedCreatureEntry = _spawnedCreatureEntry; + spawnType = _spawnType; + } + + public uint thisCreatureEntry; + public uint spawnedCreatureEntry; + public SpawnType spawnType; + } + + struct CreatureIds + { + //Torchtossingtarget + public const uint TorchTossingTargetBunny = 25535; + + //Garments + public const uint Shaya = 12429; + public const uint Roberts = 12423; + public const uint Dolf = 12427; + public const uint Korja = 12430; + public const uint DgKel = 12428; + + //Doctor + public const uint DoctorAlliance = 12939; + public const uint DoctorHorde = 12920; + + //Fireworks + public const uint Omen = 15467; + public const uint MinionOfOmen = 15466; + public const uint FireworkBlue = 15879; + public const uint FireworkGreen = 15880; + public const uint FireworkPurple = 15881; + public const uint FireworkRed = 15882; + public const uint FireworkYellow = 15883; + public const uint FireworkWhite = 15884; + public const uint FireworkBigBlue = 15885; + public const uint FireworkBigGreen = 15886; + public const uint FireworkBigPurple = 15887; + public const uint FireworkBigRed = 15888; + public const uint FireworkBigYellow = 15889; + public const uint FireworkBigWhite = 15890; + + public const uint ClusterBlue = 15872; + public const uint ClusterRed = 15873; + public const uint ClusterGreen = 15874; + public const uint ClusterPurple = 15875; + public const uint ClusterWhite = 15876; + public const uint ClusterYellow = 15877; + public const uint ClusterBigBlue = 15911; + public const uint ClusterBigGreen = 15912; + public const uint ClusterBigPurple = 15913; + public const uint ClusterBigRed = 15914; + public const uint ClusterBigWhite = 15915; + public const uint ClusterBigYellow = 15916; + public const uint ClusterElune = 15918; + + // Rabbitspells + public const uint SpringRabbit = 32791; + + // TrainWrecker + public const uint ExultingWindUpTrainWrecker = 81071; + + // Argent squire/gruntling + public const uint ArgentSquire = 33238; + + // BountifulTable + public const uint TheTurkeyChair = 34812; + public const uint TheCranberryChair = 34823; + public const uint TheStuffingChair = 34819; + public const uint TheSweetPotatoChair = 34824; + public const uint ThePieChair = 34822; + } + + struct GameobjectIds + { + //Fireworks + public const uint FireworkLauncher1 = 180771; + public const uint FireworkLauncher2 = 180868; + public const uint FireworkLauncher3 = 180850; + public const uint ClusterLauncher1 = 180772; + public const uint ClusterLauncher2 = 180859; + public const uint ClusterLauncher3 = 180869; + public const uint ClusterLauncher4 = 180874; + + //TrainWrecker + public const uint ToyTrain = 193963; + + //RibbonPole + public const uint RibbonPole = 181605; + } + + struct SpellIds + { + public const uint GuardsMark = 38067; + + //Dancingflames + public const uint Brazier = 45423; + public const uint Seduction = 47057; + public const uint FieryAura = 45427; + + //RibbonPole + public const uint RibbonDanceCosmetic = 29726; + public const uint RedFireRing = 46836; + public const uint BlueFireRing = 46842; + + //Torchtossingtarget + public const uint TargetIndicator = 45723; + + //Garments + public const uint LesserHealR2 = 2052; + public const uint FortitudeR1 = 1243; + + //Guardianspells + public const uint Deathtouch = 5; + + //Sayge + public const uint Strength = 23735; // +10% Strength + public const uint Agility = 23736; // +10% Agility + public const uint Stamina = 23737; // +10% Stamina + public const uint Spirit = 23738; // +10% Spirit + public const uint Intellect = 23766; // +10% Intellect + public const uint Armor = 23767; // +10% Armor + public const uint Damage = 23768; // +10% Damage + public const uint Resistance = 23769; // +25 Magic Resistance (All) + public const uint Fortune = 23765; // Darkmoon Faire Fortune + + //Tonkmine + public const uint TonkMineDetonate = 25099; + + //Brewfestreveler + public const uint BrewfestToast = 41586; + + //Wormholespells + public const uint BoreanTundra = 67834; + public const uint SholazarBasin = 67835; + public const uint Icecrown = 67836; + public const uint StormPeaks = 67837; + public const uint HowlingFjord = 67838; + public const uint Underground = 68081; + + //Fireworks + public const uint RocketBlue = 26344; + public const uint RocketGreen = 26345; + public const uint RocketPurple = 26346; + public const uint RocketRed = 26347; + public const uint RocketWhite = 26348; + public const uint RocketYellow = 26349; + public const uint RocketBigBlue = 26351; + public const uint RocketBigGreen = 26352; + public const uint RocketBigPurple = 26353; + public const uint RocketBigRed = 26354; + public const uint RocketBigWhite = 26355; + public const uint RocketBigYellow = 26356; + public const uint LunarFortune = 26522; + + //Rabbitspells + public const uint SpringFling = 61875; + public const uint SpringRabbitJump = 61724; + public const uint SpringRabbitWander = 61726; + public const uint SummonBabyBunny = 61727; + public const uint SpringRabbitInLove = 61728; + + //TrainWrecker + public const uint ToyTrainPulse = 61551; + public const uint WreckTrain = 62943; + + //Argent squire/gruntling + public const uint DarnassusPennant = 63443; + public const uint ExodarPennant = 63439; + public const uint GnomereganPennant = 63442; + public const uint IronforgePennant = 63440; + public const uint StormwindPennant = 62727; + public const uint SenjinPennant = 63446; + public const uint UndercityPennant = 63441; + public const uint OrgrimmarPennant = 63444; + public const uint SilvermoonPennant = 63438; + public const uint ThunderbluffPennant = 63445; + public const uint AuraPostmanS = 67376; + public const uint AuraShopS = 67377; + public const uint AuraBankS = 67368; + public const uint AuraTiredS = 67401; + public const uint AuraBankG = 68849; + public const uint AuraPostmanG = 68850; + public const uint AuraShopG = 68851; + public const uint AuraTiredG = 68852; + public const uint TiredPlayer = 67334; + + //BountifulTable + public const uint CranberryServer = 61793; + public const uint PieServer = 61794; + public const uint StuffingServer = 61795; + public const uint TurkeyServer = 61796; + public const uint SweetPotatoesServer = 61797; + public static Dictionary ChairSpells = new Dictionary() + { + { CreatureIds.TheCranberryChair, CranberryServer }, + { CreatureIds.ThePieChair, PieServer }, + { CreatureIds.TheStuffingChair, StuffingServer }, + { CreatureIds.TheTurkeyChair, TurkeyServer }, + { CreatureIds.TheSweetPotatoChair, SweetPotatoesServer }, + }; + } + + struct QuestConst + { + //Lunaclawspirit + public const uint BodyHeartA = 6001; + public const uint BodyHeartH = 6002; + + //ChickenCluck + public const uint Cluck = 3861; + + //Garments + public const uint Moon = 5621; + public const uint Light1 = 5624; + public const uint Light2 = 5625; + public const uint Spirit = 5648; + public const uint Darkness = 5650; + } + + struct TextIds + { + //Lunaclawspirit + public const uint TextIdDefault = 4714; + public const uint TextIdProgress = 4715; + + //Chickencluck + public const uint EmoteHelloA = 0; + public const uint EmoteHelloH = 1; + public const uint EmoteCluck = 2; + + //Doctor + public const uint SayDoc = 0; + + // Garments + // Used By 12429; 12423; 12427; 12430; 12428; But Signed For 12429 + public const uint SayThanks = 0; + public const uint SayGoodbye = 1; + public const uint SayHealed = 2; + + //Wormholespells + public const uint Wormhole = 14785; + + //NpcExperience + public const uint XpOnOff = 14736; + } + + struct GossipMenus + { + //Sayge + public const int OptionIdAnswer1 = 0; + public const int OptionIdAnswer2 = 1; + public const int OptionIdAnswer3 = 2; + public const int OptionIdAnswer4 = 3; + public const int IAmReadyToDiscover = 6186; + public const int OptionSayge = 6185; + public const int OptionSayge2 = 6187; + public const int OptionSayge3 = 6208; + public const int OptionSayge4 = 6209; + public const int OptionSayge5 = 6210; + public const int OptionSayge6 = 6211; + public const int IHaveLongKnown = 7339; + public const int YouHaveBeenTasked = 7340; + public const int SwornExecutioner = 7341; + public const int DiplomaticMission = 7361; + public const int YourBrotherSeeks = 7362; + public const int ATerribleBeast = 7363; + public const int YourFortuneIsCast = 7364; + public const int HereIsYourFortune = 7365; + public const int CantGiveYouYour = 7393; + + //Wormhole + public const int MenuIdWormhole = 10668; // "This tear in the fabric of time and space looks ominous." + public const int OptionIdWormhole1 = 0; // "Borean Tundra" + public const int OptionIdWormhole2 = 1; // "Howling Fjord" + public const int OptionIdWormhole3 = 2; // "Sholazar Basin" + public const int OptionIdWormhole4 = 3; // "Icecrown" + public const int OptionIdWormhole5 = 4; // "Storm Peaks" + public const int OptionIdWormhole6 = 5; // "Underground..." + + //Lunaclawspirit + public const string ItemGrant = "You Have Thought Well; Spirit. I Ask You To Grant Me The Strength Of Your Body And The Strength Of Your Heart."; + + //Pettrainer + public const uint MenuIdPetUnlearn = 6520; + public const uint OptionIdPleaseDo = 0; + + //NpcExperience + public const uint MenuIdXpOnOff = 10638; + public const uint OptionIdXpOff = 0; + public const uint OptionIdXpOn = 1; + + //Argent squire/gruntling + public const uint OptionIdBank = 0; + public const uint OptionIdShop = 1; + public const uint OptionIdMail = 2; + public const uint OptionIdDarnassusSenjinPennant = 3; + public const uint OptionIdExodarUndercityPennant = 4; + public const uint OptionIdGnomereganOrgrimmarPennant = 5; + public const uint OptionIdIronforgeSilvermoonPennant = 6; + public const uint OptionIdStormwindThunderbluffPennant = 7; + } + + enum SeatIds + { + //BountifulTable + TurkeyChair = 0, + CranberryChair = 1, + StuffingChair = 2, + SweetPotatoChair = 3, + PieChair = 4, + FoodHolder = 5, + PlateHolder = 6 + } + + struct Misc + { + public static SpawnAssociation[] spawnAssociations = + { + new SpawnAssociation(2614, 15241, SpawnType.AlarmBot), //Air Force Alarm Bot (Alliance) + new SpawnAssociation(2615, 15242, SpawnType.AlarmBot), //Air Force Alarm Bot (Horde) + new SpawnAssociation(21974, 21976, SpawnType.AlarmBot), //Air Force Alarm Bot (Area 52) + new SpawnAssociation(21993, 15242, SpawnType.AlarmBot), //Air Force Guard Post (Horde - Bat Rider) + new SpawnAssociation(21996, 15241, SpawnType.AlarmBot), //Air Force Guard Post (Alliance - Gryphon) + new SpawnAssociation(21997, 21976, SpawnType.AlarmBot), //Air Force Guard Post (Goblin - Area 52 - Zeppelin) + new SpawnAssociation(21999, 15241, SpawnType.TripwireRooftop), //Air Force Trip Wire - Rooftop (Alliance) + new SpawnAssociation(22001, 15242, SpawnType.TripwireRooftop), //Air Force Trip Wire - Rooftop (Horde) + new SpawnAssociation(22002, 15242, SpawnType.TripwireRooftop), //Air Force Trip Wire - Ground (Horde) + new SpawnAssociation(22003, 15241, SpawnType.TripwireRooftop), //Air Force Trip Wire - Ground (Alliance) + new SpawnAssociation(22063, 21976, SpawnType.TripwireRooftop), //Air Force Trip Wire - Rooftop (Goblin - Area 52) + new SpawnAssociation(22065, 22064, SpawnType.AlarmBot), //Air Force Guard Post (Ethereal - Stormspire) + new SpawnAssociation(22066, 22067, SpawnType.AlarmBot), //Air Force Guard Post (Scryer - Dragonhawk) + new SpawnAssociation(22068, 22064, SpawnType.TripwireRooftop), //Air Force Trip Wire - Rooftop (Ethereal - Stormspire) + new SpawnAssociation(22069, 22064, SpawnType.AlarmBot), //Air Force Alarm Bot (Stormspire) + new SpawnAssociation(22070, 22067, SpawnType.TripwireRooftop), //Air Force Trip Wire - Rooftop (Scryer) + new SpawnAssociation(22071, 22067, SpawnType.AlarmBot), //Air Force Alarm Bot (Scryer) + new SpawnAssociation(22078, 22077, SpawnType.AlarmBot), //Air Force Alarm Bot (Aldor) + new SpawnAssociation(22079, 22077, SpawnType.AlarmBot), //Air Force Guard Post (Aldor - Gryphon) + new SpawnAssociation(22080, 22077, SpawnType.TripwireRooftop), //Air Force Trip Wire - Rooftop (Aldor) + new SpawnAssociation(22086, 22085, SpawnType.AlarmBot), //Air Force Alarm Bot (Sporeggar) + new SpawnAssociation(22087, 22085, SpawnType.AlarmBot), //Air Force Guard Post (Sporeggar - Spore Bat) + new SpawnAssociation(22088, 22085, SpawnType.TripwireRooftop), //Air Force Trip Wire - Rooftop (Sporeggar) + new SpawnAssociation(22090, 22089, SpawnType.AlarmBot), //Air Force Guard Post (Toshley's Station - Flying Machine) + new SpawnAssociation(22124, 22122, SpawnType.AlarmBot), //Air Force Alarm Bot (Cenarion) + new SpawnAssociation(22125, 22122, SpawnType.AlarmBot), //Air Force Guard Post (Cenarion - Stormcrow) + new SpawnAssociation(22126, 22122, SpawnType.AlarmBot) //Air Force Trip Wire - Rooftop (Cenarion Expedition) + }; + + public const float RangeTripwire = 15.0f; + public const float RangeGuardsMark = 50.0f; + + //ChickenCluck + public const uint FactionFriendly = 35; + public const uint FactionChicken = 31; + + //Doctor + public static Position[] DoctorAllianceCoords = + { + new Position(-3757.38f, -4533.05f, 14.16f, 3.62f), // Top-far-right bunk as seen from entrance + new Position(-3754.36f, -4539.13f, 14.16f, 5.13f), // Top-far-left bunk + new Position(-3749.54f, -4540.25f, 14.28f, 3.34f), // Far-right bunk + new Position(-3742.10f, -4536.85f, 14.28f, 3.64f), // Right bunk near entrance + new Position(-3755.89f, -4529.07f, 14.05f, 0.57f), // Far-left bunk + new Position(-3749.51f, -4527.08f, 14.07f, 5.26f), // Mid-left bunk + new Position(-3746.37f, -4525.35f, 14.16f, 5.22f), // Left bunk near entrance + }; + + //alliance run to where + public static Position DoctorAllianceRunTo = new Position(-3742.96f, -4531.52f, 11.91f); + + public static Position[] DoctorHordeCoords = + { + new Position(-1013.75f, -3492.59f, 62.62f, 4.34f), // Left, Behind + new Position(-1017.72f, -3490.92f, 62.62f, 4.34f), // Right, Behind + new Position(-1015.77f, -3497.15f, 62.82f, 4.34f), // Left, Mid + new Position(-1019.51f, -3495.49f, 62.82f, 4.34f), // Right, Mid + new Position(-1017.25f, -3500.85f, 62.98f, 4.34f), // Left, front + new Position(-1020.95f, -3499.21f, 62.98f, 4.34f) // Right, Front + }; + + //horde run to where + public static Position DoctorHordeRunTo = new Position(-1016.44f, -3508.48f, 62.96f); + + public static uint[] AllianceSoldierId = + { + 12938, // 12938 Injured Alliance Soldier + 12936, // 12936 Badly injured Alliance Soldier + 12937 // 12937 Critically injured Alliance Soldier + }; + + public static uint[] HordeSoldierId = + { + 12923, //12923 Injured Soldier + 12924, //12924 Badly injured Soldier + 12925 //12925 Critically injured Soldier + }; + + // WormholeSpells + public const uint DataShowUnderground = 1; + + //Fireworks + public const uint AnimGoLaunchFirework = 3; + public const uint ZoneMoonglade = 493; + + public static Position omenSummonPos = new Position(7558.993f, -2839.999f, 450.0214f, 4.46f); + + public const uint AuraDurationTimeLeft = 5000; + + //Argent squire/gruntling + public static Tuple[] bannerSpells = + { + Tuple.Create(SpellIds.DarnassusPennant, SpellIds.SenjinPennant), + Tuple.Create(SpellIds.ExodarPennant, SpellIds.UndercityPennant), + Tuple.Create(SpellIds.GnomereganPennant, SpellIds.OrgrimmarPennant), + Tuple.Create(SpellIds.IronforgePennant, SpellIds.SilvermoonPennant), + Tuple.Create(SpellIds.StormwindPennant, SpellIds.ThunderbluffPennant) + }; + } + + [Script] + class npc_air_force_bots : ScriptedAI + { + public npc_air_force_bots(Creature creature) : base(creature) + { + SpawnAssoc = null; + SpawnedGUID.Clear(); + + // find the correct spawnhandling + foreach (var association in Misc.spawnAssociations) + { + if (association.thisCreatureEntry == creature.GetEntry()) + { + SpawnAssoc = association; + break; + } + } + + if (SpawnAssoc == null) + Log.outError(LogFilter.Sql, "TCSR: Creature template entry {0} has ScriptName npc_air_force_bots, but it's not handled by that script", creature.GetEntry()); + else + { + CreatureTemplate spawnedTemplate = Global.ObjectMgr.GetCreatureTemplate(SpawnAssoc.spawnedCreatureEntry); + if (spawnedTemplate == null) + { + Log.outError(LogFilter.Sql, "TCSR: Creature template entry {0} does not exist in DB, which is required by npc_air_force_bots", SpawnAssoc.spawnedCreatureEntry); + SpawnAssoc = null; + return; + } + } + } + + SpawnAssociation SpawnAssoc; + ObjectGuid SpawnedGUID; + + public override void Reset() { } + + Creature SummonGuard() + { + Creature summoned = me.SummonCreature(SpawnAssoc.spawnedCreatureEntry, 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOutOfCombat, 300000); + + if (summoned) + SpawnedGUID = summoned.GetGUID(); + else + { + Log.outError(LogFilter.Sql, "npc_air_force_bots: wasn't able to spawn Creature {0}", SpawnAssoc.spawnedCreatureEntry); + SpawnAssoc = null; + } + + return summoned; + } + + Creature GetSummonedGuard() + { + Creature creature = ObjectAccessor.GetCreature(me, SpawnedGUID); + if (creature && creature.IsAlive()) + return creature; + + return null; + } + + public override void MoveInLineOfSight(Unit who) + { + if (SpawnAssoc == null) + return; + + if (me.IsValidAttackTarget(who)) + { + Player playerTarget = who.ToPlayer(); + + // airforce guards only spawn for players + if (!playerTarget) + return; + + Creature lastSpawnedGuard = SpawnedGUID.IsEmpty() ? null : GetSummonedGuard(); + + // prevent calling Unit::GetUnit at next MoveInLineOfSight call - speedup + if (!lastSpawnedGuard) + SpawnedGUID.Clear(); + + switch (SpawnAssoc.spawnType) + { + case SpawnType.AlarmBot: + { + if (!who.IsWithinDistInMap(me, Misc.RangeGuardsMark)) + return; + + Aura markAura = who.GetAura(SpellIds.GuardsMark); + if (markAura != null) + { + // the target wasn't able to move out of our range within 25 seconds + if (!lastSpawnedGuard) + { + lastSpawnedGuard = SummonGuard(); + + if (!lastSpawnedGuard) + return; + } + + if (markAura.GetDuration() < Misc.AuraDurationTimeLeft) + if (!lastSpawnedGuard.GetVictim()) + lastSpawnedGuard.GetAI().AttackStart(who); + } + else + { + if (!lastSpawnedGuard) + lastSpawnedGuard = SummonGuard(); + + if (!lastSpawnedGuard) + return; + + lastSpawnedGuard.CastSpell(who, SpellIds.GuardsMark, true); + } + break; + } + case SpawnType.TripwireRooftop: + { + if (!who.IsWithinDistInMap(me, Misc.RangeTripwire)) + return; + + if (!lastSpawnedGuard) + lastSpawnedGuard = SummonGuard(); + + if (!lastSpawnedGuard) + return; + + // ROOFTOP only triggers if the player is on the ground + if (!playerTarget.IsFlying() && !lastSpawnedGuard.GetVictim()) + lastSpawnedGuard.GetAI().AttackStart(who); + + break; + } + } + } + } + } + + [Script] + class npc_chicken_cluck : ScriptedAI + { + public npc_chicken_cluck(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + ResetFlagTimer = 120000; + } + + uint ResetFlagTimer; + + public override void Reset() + { + Initialize(); + me.SetFaction(Misc.FactionChicken); + me.RemoveNpcFlag(NPCFlags.QuestGiver); + } + + public override void EnterCombat(Unit who) { } + + public override void UpdateAI(uint diff) + { + // Reset flags after a certain time has passed so that the next player has to start the 'event' again + if (me.HasNpcFlag(NPCFlags.QuestGiver)) + { + if (ResetFlagTimer <= diff) + { + EnterEvadeMode(); + return; + } + else + ResetFlagTimer -= diff; + } + + if (UpdateVictim()) + DoMeleeAttackIfReady(); + } + + public override void ReceiveEmote(Player player, TextEmotes emote) + { + switch (emote) + { + case TextEmotes.Chicken: + if (player.GetQuestStatus(QuestConst.Cluck) == QuestStatus.None && RandomHelper.Rand32() % 30 == 1) + { + me.AddNpcFlag(NPCFlags.QuestGiver); + me.SetFaction(Misc.FactionFriendly); + Talk(player.GetTeam() == Team.Horde ? TextIds.EmoteHelloH : TextIds.EmoteHelloA); + } + break; + case TextEmotes.Cheer: + if (player.GetQuestStatus(QuestConst.Cluck) == QuestStatus.Complete) + { + me.AddNpcFlag(NPCFlags.QuestGiver); + me.SetFaction(Misc.FactionFriendly); + Talk(TextIds.EmoteCluck); + } + break; + } + } + + public override void QuestAccept(Player player, Quest quest) + { + if (quest.Id == QuestConst.Cluck) + Reset(); + } + + public override void QuestReward(Player player, Quest quest, uint opt) + { + if (quest.Id == QuestConst.Cluck) + Reset(); + } + } + + [Script] + class npc_dancing_flames : ScriptedAI + { + public npc_dancing_flames(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + Active = true; + CanIteract = 3500; + } + + bool Active; + uint CanIteract; + + public override void Reset() + { + Initialize(); + DoCast(me, SpellIds.Brazier, true); + DoCast(me, SpellIds.FieryAura, false); + float x, y, z; + me.GetPosition(out x, out y, out z); + me.Relocate(x, y, z + 0.94f); + me.SetDisableGravity(true); + me.HandleEmoteCommand(Emote.OneshotDance); + } + + public override void UpdateAI(uint diff) + { + if (!Active) + { + if (CanIteract <= diff) + { + Active = true; + CanIteract = 3500; + me.HandleEmoteCommand(Emote.OneshotDance); + } + else + CanIteract -= diff; + } + } + + public override void EnterCombat(Unit who) { } + + public override void ReceiveEmote(Player player, TextEmotes emote) + { + if (me.IsWithinLOS(player.GetPositionX(), player.GetPositionY(), player.GetPositionZ()) && me.IsWithinDistInMap(player, 30.0f)) + { + me.SetFacingToObject(player); + Active = false; + + switch (emote) + { + case TextEmotes.Kiss: + me.HandleEmoteCommand(Emote.OneshotShy); + break; + case TextEmotes.Wave: + me.HandleEmoteCommand(Emote.OneshotWave); + break; + case TextEmotes.Bow: + me.HandleEmoteCommand(Emote.OneshotBow); + break; + case TextEmotes.Joke: + me.HandleEmoteCommand(Emote.OneshotLaugh); + break; + case TextEmotes.Dance: + if (!player.HasAura(SpellIds.Seduction)) + DoCast(player, SpellIds.Seduction, true); + break; + } + } + } + } + + [Script] + class npc_torch_tossing_target_bunny_controller : ScriptedAI + { + public npc_torch_tossing_target_bunny_controller(Creature creature) : base(creature) + { + _targetTimer = 3000; + } + + ObjectGuid DoSearchForTargets(ObjectGuid lastTargetGUID) + { + List targets = new List(); + me.GetCreatureListWithEntryInGrid(targets, CreatureIds.TorchTossingTargetBunny, 60.0f); + targets.RemoveAll(creature => creature.GetGUID() == lastTargetGUID); + + if (!targets.Empty()) + { + _lastTargetGUID = targets.SelectRandom().GetGUID(); + + return _lastTargetGUID; + } + return ObjectGuid.Empty; + } + + public override void UpdateAI(uint diff) + { + if (_targetTimer < diff) + { + Unit target = Global.ObjAccessor.GetUnit(me, DoSearchForTargets(_lastTargetGUID)); + if (target) + target.CastSpell(target, SpellIds.TargetIndicator, true); + + _targetTimer = 3000; + } + else + _targetTimer -= diff; + } + + uint _targetTimer; + ObjectGuid _lastTargetGUID; + } + + [Script] + class npc_midsummer_bunny_pole : ScriptedAI + { + public npc_midsummer_bunny_pole(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + _scheduler.CancelAll(); + running = false; + } + + public override void Reset() + { + Initialize(); + + _scheduler.SetValidator(() => running); + + _scheduler.Schedule(TimeSpan.FromMilliseconds(1), task => + { + if (checkNearbyPlayers()) + { + Reset(); + return; + } + + GameObject go = me.FindNearestGameObject(GameobjectIds.RibbonPole, 10.0f); + if (go) + me.CastSpell(go, SpellIds.RedFireRing, true); + + task.Schedule(TimeSpan.FromSeconds(5), task1 => + { + if (checkNearbyPlayers()) + { + Reset(); + return; + } + + go = me.FindNearestGameObject(GameobjectIds.RibbonPole, 10.0f); + if (go) + me.CastSpell(go, SpellIds.BlueFireRing, true); + + task.Repeat(TimeSpan.FromSeconds(5)); + }); + }); + } + + public override void DoAction(int action) + { + // Don't start event if it's already running. + if (running) + return; + + running = true; + //events.ScheduleEvent(EVENT_CAST_RED_FIRE_RING, 1); + } + + bool checkNearbyPlayers() + { + // Returns true if no nearby player has aura "Test Ribbon Pole Channel". + List players = new List(); + var check = new UnitAuraCheck(true, SpellIds.RibbonDanceCosmetic); + var searcher = new PlayerListSearcher(me, players, check); + Cell.VisitWorldObjects(me, searcher, 10.0f); + + return players.Empty(); + } + + public override void UpdateAI(uint diff) + { + if (!running) + return; + + _scheduler.Update(diff); + } + + bool running; + } + + [Script] + class npc_doctor : ScriptedAI + { + public npc_doctor(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + PlayerGUID.Clear(); + + SummonPatientTimer = 10000; + SummonPatientCount = 0; + PatientDiedCount = 0; + PatientSavedCount = 0; + + Patients.Clear(); + Coordinates.Clear(); + + Event = false; + } + + public override void Reset() + { + Initialize(); + me.RemoveUnitFlag(UnitFlags.NotSelectable); + } + + public void BeginEvent(Player player) + { + PlayerGUID = player.GetGUID(); + + SummonPatientTimer = 10000; + SummonPatientCount = 0; + PatientDiedCount = 0; + PatientSavedCount = 0; + + switch (me.GetEntry()) + { + case CreatureIds.DoctorAlliance: + foreach (var coord in Misc.DoctorAllianceCoords) + Coordinates.Add(coord); + break; + case CreatureIds.DoctorHorde: + foreach (var coord in Misc.DoctorHordeCoords) + Coordinates.Add(coord); + break; + } + + Event = true; + me.AddUnitFlag(UnitFlags.NotSelectable); + } + + public void PatientDied(Position point) + { + Player player = Global.ObjAccessor.GetPlayer(me, PlayerGUID); + if (player && ((player.GetQuestStatus(6624) == QuestStatus.Incomplete) || (player.GetQuestStatus(6622) == QuestStatus.Incomplete))) + { + ++PatientDiedCount; + + if (PatientDiedCount > 5 && Event) + { + if (player.GetQuestStatus(6624) == QuestStatus.Incomplete) + player.FailQuest(6624); + else if (player.GetQuestStatus(6622) == QuestStatus.Incomplete) + player.FailQuest(6622); + + Reset(); + return; + } + + Coordinates.Add(point); + } + else + // If no player or player abandon quest in progress + Reset(); + } + + public void PatientSaved(Creature soldier, Player player, Position point) + { + if (player && PlayerGUID == player.GetGUID()) + { + if ((player.GetQuestStatus(6624) == QuestStatus.Incomplete) || (player.GetQuestStatus(6622) == QuestStatus.Incomplete)) + { + ++PatientSavedCount; + + if (PatientSavedCount == 15) + { + if (!Patients.Empty()) + { + foreach (var guid in Patients) + { + Creature patient = ObjectAccessor.GetCreature(me, guid); + if (patient) + patient.SetDeathState(DeathState.JustDied); + } + } + + if (player.GetQuestStatus(6624) == QuestStatus.Incomplete) + player.AreaExploredOrEventHappens(6624); + else if (player.GetQuestStatus(6622) == QuestStatus.Incomplete) + player.AreaExploredOrEventHappens(6622); + + Reset(); + return; + } + + Coordinates.Add(point); + } + } + } + + public override void UpdateAI(uint diff) + { + if (Event && SummonPatientCount >= 20) + { + Reset(); + return; + } + + if (Event) + { + if (SummonPatientTimer <= diff) + { + if (Coordinates.Empty()) + return; + + uint patientEntry; + switch (me.GetEntry()) + { + case CreatureIds.DoctorAlliance: + patientEntry = Misc.AllianceSoldierId[RandomHelper.Rand32() % 3]; + break; + case CreatureIds.DoctorHorde: + patientEntry = Misc.HordeSoldierId[RandomHelper.Rand32() % 3]; + break; + default: + Log.outError(LogFilter.Scripts, "Invalid entry for Triage doctor. Please check your database"); + return; + } + + var index = RandomHelper.IRand(0, Coordinates.Count - 1); + + Creature Patient = me.SummonCreature(patientEntry, Coordinates[index], TempSummonType.TimedDespawnOutOfCombat, 5000); + if (Patient) + { + //303, this flag appear to be required for client side item.spell to work (TARGET_SINGLE_FRIEND) + Patient.AddUnitFlag(UnitFlags.PvpAttackable); + + Patients.Add(Patient.GetGUID()); + ((npc_injured_patient)Patient.GetAI()).DoctorGUID = me.GetGUID(); + ((npc_injured_patient)Patient.GetAI()).Coord = Coordinates[index]; + + Coordinates.RemoveAt(index); + } + + SummonPatientTimer = 10000; + ++SummonPatientCount; + } + else + SummonPatientTimer -= diff; + } + } + + public override void EnterCombat(Unit who) { } + + public override void QuestAccept(Player player, Quest quest) + { + if ((quest.Id == 6624) || (quest.Id == 6622)) + BeginEvent(player); + } + + ObjectGuid PlayerGUID; + + uint SummonPatientTimer; + uint SummonPatientCount; + uint PatientDiedCount; + uint PatientSavedCount; + + bool Event; + + List Patients = new List(); + List Coordinates = new List(); + } + + [Script] + public class npc_injured_patient : ScriptedAI + { + public npc_injured_patient(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + DoctorGUID.Clear(); + Coord = null; + } + + public ObjectGuid DoctorGUID; + public Position Coord; + + public override void Reset() + { + Initialize(); + + //no select + me.RemoveUnitFlag(UnitFlags.NotSelectable); + + //no regen health + me.AddUnitFlag(UnitFlags.InCombat); + + //to make them lay with face down + me.SetStandState(UnitStandStateType.Dead); + + uint mobId = me.GetEntry(); + + switch (mobId) + { //lower max health + case 12923: + case 12938: //Injured Soldier + me.SetHealth(me.CountPctFromMaxHealth(75)); + break; + case 12924: + case 12936: //Badly injured Soldier + me.SetHealth(me.CountPctFromMaxHealth(50)); + break; + case 12925: + case 12937: //Critically injured Soldier + me.SetHealth(me.CountPctFromMaxHealth(25)); + break; + } + } + + public override void EnterCombat(Unit who) { } + + public override void SpellHit(Unit caster, SpellInfo spell) + { + Player player = caster.ToPlayer(); + if (!player || !me.IsAlive() || spell.Id != 20804) + return; + + if (player.GetQuestStatus(6624) == QuestStatus.Incomplete || player.GetQuestStatus(6622) == QuestStatus.Incomplete) + { + if (!DoctorGUID.IsEmpty()) + { + Creature doctor = ObjectAccessor.GetCreature(me, DoctorGUID); + if (doctor) + ((npc_doctor)doctor.GetAI()).PatientSaved(me, player, Coord); + } + } + + //make not selectable + me.AddUnitFlag(UnitFlags.NotSelectable); + + //regen health + me.RemoveUnitFlag(UnitFlags.InCombat); + + //stand up + me.SetStandState(UnitStandStateType.Stand); + + Talk(TextIds.SayDoc); + + uint mobId = me.GetEntry(); + me.SetWalk(false); + + switch (mobId) + { + case 12923: + case 12924: + case 12925: + me.GetMotionMaster().MovePoint(0, Misc.DoctorHordeRunTo); + break; + case 12936: + case 12937: + case 12938: + me.GetMotionMaster().MovePoint(0, Misc.DoctorAllianceRunTo); + break; + } + } + + public override void UpdateAI(uint diff) + { + //lower HP on every world tick makes it a useful counter, not officlone though + if (me.IsAlive() && me.GetHealth() > 6) + me.ModifyHealth(-5); + + if (me.IsAlive() && me.GetHealth() <= 6) + { + me.RemoveUnitFlag(UnitFlags.InCombat); + me.AddUnitFlag(UnitFlags.NotSelectable); + me.SetDeathState(DeathState.JustDied); + me.AddDynamicFlag(UnitDynFlags.Dead); + + if (!DoctorGUID.IsEmpty()) + { + Creature doctor = ObjectAccessor.GetCreature((me), DoctorGUID); + if (doctor) + ((npc_doctor)doctor.GetAI()).PatientDied(Coord); + } + } + } + } + + [Script] + class npc_garments_of_quests : EscortAI + { + public npc_garments_of_quests(Creature creature) : base(creature) + { + switch (me.GetEntry()) + { + case CreatureIds.Shaya: + quest = QuestConst.Moon; + break; + case CreatureIds.Roberts: + quest = QuestConst.Light1; + break; + case CreatureIds.Dolf: + quest = QuestConst.Light2; + break; + case CreatureIds.Korja: + quest = QuestConst.Spirit; + break; + case CreatureIds.DgKel: + quest = QuestConst.Darkness; + break; + default: + quest = 0; + break; + } + + Reset(); + } + + ObjectGuid CasterGUID; + + bool IsHealed; + bool CanRun; + + uint RunAwayTimer; + uint quest; + + public override void Reset() + { + CasterGUID.Clear(); + + IsHealed = false; + CanRun = false; + + RunAwayTimer = 5000; + + me.SetStandState(UnitStandStateType.Kneel); + // expect database to have RegenHealth=0 + me.SetHealth(me.CountPctFromMaxHealth(70)); + } + + public override void EnterCombat(Unit who) { } + + public override void SpellHit(Unit caster, SpellInfo spell) + { + if (spell.Id == SpellIds.LesserHealR2 || spell.Id == SpellIds.FortitudeR1) + { + //not while in combat + if (me.IsInCombat()) + return; + + //nothing to be done now + if (IsHealed && CanRun) + return; + + Player player = caster.ToPlayer(); + if (player) + { + if (quest != 0 && player.GetQuestStatus(quest) == QuestStatus.Incomplete) + { + if (IsHealed && !CanRun && spell.Id == SpellIds.FortitudeR1) + { + Talk(TextIds.SayThanks, caster); + CanRun = true; + } + else if (!IsHealed && spell.Id == SpellIds.LesserHealR2) + { + CasterGUID = caster.GetGUID(); + me.SetStandState(UnitStandStateType.Stand); + Talk(TextIds.SayHealed, caster); + IsHealed = true; + } + } + + // give quest credit, not expect any special quest objectives + if (CanRun) + player.TalkedToCreature(me.GetEntry(), me.GetGUID()); + } + } + } + + public override void WaypointReached(uint waypointId, uint pathId) + { + } + + public override void UpdateAI(uint diff) + { + if (CanRun && !me.IsInCombat()) + { + if (RunAwayTimer <= diff) + { + Unit unit = Global.ObjAccessor.GetUnit(me, CasterGUID); + if (unit) + { + switch (me.GetEntry()) + { + case CreatureIds.Shaya: + case CreatureIds.Roberts: + case CreatureIds.Dolf: + case CreatureIds.Korja: + case CreatureIds.DgKel: + Talk(TextIds.SayGoodbye, unit); + break; + } + + Start(false, true); + } + else + EnterEvadeMode(); //something went wrong + + RunAwayTimer = 30000; + } + else + RunAwayTimer -= diff; + } + + base.UpdateAI(diff); + } + } + + [Script] + class npc_guardian : ScriptedAI + { + public npc_guardian(Creature creature) : base(creature) { } + + public override void Reset() + { + me.AddUnitFlag(UnitFlags.NonAttackable); + } + + public override void EnterCombat(Unit who) + { + } + + public override void UpdateAI(uint diff) + { + if (!UpdateVictim()) + return; + + if (me.IsAttackReady()) + { + DoCastVictim(SpellIds.Deathtouch, true); + me.ResetAttackTimer(); + } + } + } + + [Script] + class npc_sayge : ScriptedAI + { + public npc_sayge(Creature creature) : base(creature) { } + + public override bool GossipHello(Player player) + { + if (me.IsQuestGiver()) + player.PrepareQuestMenu(me.GetGUID()); + + if (player.GetSpellHistory().HasCooldown(SpellIds.Strength) || + player.GetSpellHistory().HasCooldown(SpellIds.Agility) || + player.GetSpellHistory().HasCooldown(SpellIds.Stamina) || + player.GetSpellHistory().HasCooldown(SpellIds.Spirit) || + player.GetSpellHistory().HasCooldown(SpellIds.Intellect) || + player.GetSpellHistory().HasCooldown(SpellIds.Armor) || + player.GetSpellHistory().HasCooldown(SpellIds.Damage) || + player.GetSpellHistory().HasCooldown(SpellIds.Resistance)) + player.SendGossipMenu(GossipMenus.CantGiveYouYour, me.GetGUID()); + else + { + player.ADD_GOSSIP_ITEM_DB(GossipMenus.IAmReadyToDiscover, GossipMenus.OptionIdAnswer1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1); + player.SendGossipMenu(GossipMenus.IHaveLongKnown, me.GetGUID()); + } + + return true; + } + + void SendAction(Player player, uint action) + { + switch (action) + { + case eTradeskill.GossipActionInfoDef + 1: + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge, GossipMenus.OptionIdAnswer1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge, GossipMenus.OptionIdAnswer2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 3); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge, GossipMenus.OptionIdAnswer3, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 4); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge, GossipMenus.OptionIdAnswer4, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 5); + player.SendGossipMenu(GossipMenus.YouHaveBeenTasked, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 2: + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge2, GossipMenus.OptionIdAnswer1, eTradeskill.GossipSenderMain + 1, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge2, GossipMenus.OptionIdAnswer2, eTradeskill.GossipSenderMain + 2, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge2, GossipMenus.OptionIdAnswer3, eTradeskill.GossipSenderMain + 3, eTradeskill.GossipActionInfoDef); + player.SendGossipMenu(GossipMenus.SwornExecutioner, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 3: + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge3, GossipMenus.OptionIdAnswer1, eTradeskill.GossipSenderMain + 4, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge3, GossipMenus.OptionIdAnswer2, eTradeskill.GossipSenderMain + 5, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge3, GossipMenus.OptionIdAnswer3, eTradeskill.GossipSenderMain + 2, eTradeskill.GossipActionInfoDef); + player.SendGossipMenu(GossipMenus.DiplomaticMission, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 4: + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge4, GossipMenus.OptionIdAnswer1, eTradeskill.GossipSenderMain + 6, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge4, GossipMenus.OptionIdAnswer2, eTradeskill.GossipSenderMain + 7, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge4, GossipMenus.OptionIdAnswer3, eTradeskill.GossipSenderMain + 8, eTradeskill.GossipActionInfoDef); + player.SendGossipMenu(GossipMenus.YourBrotherSeeks, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 5: + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge5, GossipMenus.OptionIdAnswer1, eTradeskill.GossipSenderMain + 5, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge5, GossipMenus.OptionIdAnswer2, eTradeskill.GossipSenderMain + 4, eTradeskill.GossipActionInfoDef); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge5, GossipMenus.OptionIdAnswer3, eTradeskill.GossipSenderMain + 3, eTradeskill.GossipActionInfoDef); + player.SendGossipMenu(GossipMenus.ATerribleBeast, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef: + player.ADD_GOSSIP_ITEM_DB(GossipMenus.OptionSayge6, GossipMenus.OptionIdAnswer1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 6); + player.SendGossipMenu(GossipMenus.YourFortuneIsCast, me.GetGUID()); + break; + case eTradeskill.GossipActionInfoDef + 6: + DoCast(player, SpellIds.Fortune, false); + player.SendGossipMenu(GossipMenus.HereIsYourFortune, me.GetGUID()); + break; + } + } + + public override bool GossipSelect(Player player, uint menuId, uint gossipListId) + { + uint sender = player.PlayerTalkClass.GetGossipOptionSender(gossipListId); + uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId); + player.PlayerTalkClass.ClearMenus(); + uint spellId = 0; + switch (sender) + { + case eTradeskill.GossipSenderMain: + SendAction(player, action); + break; + case eTradeskill.GossipSenderMain + 1: + spellId = SpellIds.Damage; + break; + case eTradeskill.GossipSenderMain + 2: + spellId = SpellIds.Resistance; + break; + case eTradeskill.GossipSenderMain + 3: + spellId = SpellIds.Armor; + break; + case eTradeskill.GossipSenderMain + 4: + spellId = SpellIds.Spirit; + break; + case eTradeskill.GossipSenderMain + 5: + spellId = SpellIds.Intellect; + break; + case eTradeskill.GossipSenderMain + 6: + spellId = SpellIds.Stamina; + break; + case eTradeskill.GossipSenderMain + 7: + spellId = SpellIds.Strength; + break; + case eTradeskill.GossipSenderMain + 8: + spellId = SpellIds.Agility; + break; + } + + if (spellId != 0) + { + DoCast(player, spellId, false); + player.GetSpellHistory().AddCooldown(spellId, 0, TimeSpan.FromHours(2)); + SendAction(player, action); + } + return true; + } + } + + [Script] + class npc_steam_tonk : ScriptedAI + { + public npc_steam_tonk(Creature creature) : base(creature) { } + + public override void Reset() { } + public override void EnterCombat(Unit who) { } + + public override void OnPossess(bool apply) + { + if (apply) + { + // Initialize the action bar without the melee attack command + me.InitCharmInfo(); + me.GetCharmInfo().InitEmptyActionBar(false); + + me.SetReactState(ReactStates.Passive); + } + else + me.SetReactState(ReactStates.Aggressive); + } + } + + [Script] + class npc_tonk_mine : ScriptedAI + { + public npc_tonk_mine(Creature creature) : base(creature) + { + Initialize(); + me.SetReactState(ReactStates.Passive); + } + + void Initialize() + { + ExplosionTimer = 3000; + } + + uint ExplosionTimer; + + public override void Reset() + { + Initialize(); + } + + public override void EnterCombat(Unit who) { } + public override void AttackStart(Unit who) { } + public override void MoveInLineOfSight(Unit who) { } + + public override void UpdateAI(uint diff) + { + if (ExplosionTimer <= diff) + { + DoCast(me, SpellIds.TonkMineDetonate, true); + me.SetDeathState(DeathState.Dead); // unsummon it + } + else + ExplosionTimer -= diff; + } + } + + [Script] + class npc_brewfest_reveler : ScriptedAI + { + public npc_brewfest_reveler(Creature creature) : base(creature) { } + + public override void ReceiveEmote(Player player, TextEmotes emote) + { + if (!Global.GameEventMgr.IsHolidayActive(HolidayIds.Brewfest)) + return; + + if (emote == TextEmotes.Dance) + me.CastSpell(player, SpellIds.BrewfestToast, false); + } + } + + [Script] + class npc_training_dummy : ScriptedAI + { + public npc_training_dummy(Creature creature) : base(creature) + { + SetCombatMovement(false); + } + + public override void Reset() + { + // TODO: solve this in a different way! setting them as stunned prevents dummies from parrying + me.SetControlled(true, UnitState.Stunned);//disable rotate + + _scheduler.CancelAll(); + _damageTimes.Clear(); + if (me.GetEntry() != AdvancedTargetDummy && me.GetEntry() != TargetDummy) + { + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + long now = Time.UnixTime; + foreach (var pair in _damageTimes.ToList()) + { + // If unit has not dealt damage to training dummy for 5 seconds, Remove him from combat + if (pair.Value < now - 5) + { + Unit unit = Global.ObjAccessor.GetUnit(me, pair.Key); + if (unit) + unit.GetHostileRefManager().DeleteReference(me); + + _damageTimes.Remove(pair.Key); + } + } + task.Repeat(); + }); + } + else + _scheduler.Schedule(TimeSpan.FromSeconds(15), task => me.DespawnOrUnsummon()); + } + + public override void EnterEvadeMode(EvadeReason why) + { + if (!_EnterEvadeMode(why)) + return; + + Reset(); + } + + public override void DamageTaken(Unit doneBy, ref uint damage) + { + AddThreat(doneBy, damage); // just to create threat reference + _damageTimes[doneBy.GetGUID()] = Time.UnixTime; + damage = 0; + } + + public override void UpdateAI(uint diff) + { + if (!me.IsInCombat()) + return; + + if (!me.HasUnitState(UnitState.Stunned)) + me.SetControlled(true, UnitState.Stunned);//disable rotate + + _scheduler.Update(diff); + } + + public override void MoveInLineOfSight(Unit who) { } + + Dictionary _damageTimes = new Dictionary(); + + const uint AdvancedTargetDummy = 2674; + const uint TargetDummy = 2673; + } + + [Script] + class npc_wormhole : PassiveAI + { + public npc_wormhole(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + _showUnderground = RandomHelper.URand(0, 100) == 0; // Guessed value, it is really rare though + } + + public override void InitializeAI() + { + Initialize(); + } + + public override bool GossipHello(Player player) + { + if (me.IsSummon()) + { + if (player == me.ToTempSummon().GetSummoner()) + { + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdWormhole, GossipMenus.OptionIdWormhole1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdWormhole, GossipMenus.OptionIdWormhole2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdWormhole, GossipMenus.OptionIdWormhole3, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 3); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdWormhole, GossipMenus.OptionIdWormhole4, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 4); + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdWormhole, GossipMenus.OptionIdWormhole5, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 5); + + if (_showUnderground) + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdWormhole, GossipMenus.OptionIdWormhole6, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 6); + + player.SendGossipMenu(TextIds.Wormhole, me.GetGUID()); + } + } + + return true; + } + + public override bool GossipSelect(Player player, uint menuId, uint gossipListId) + { + uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId); + player.PlayerTalkClass.ClearMenus(); + + switch (action) + { + case eTradeskill.GossipActionInfoDef + 1: // Borean Tundra + player.CloseGossipMenu(); + DoCast(player, SpellIds.BoreanTundra, false); + break; + case eTradeskill.GossipActionInfoDef + 2: // Howling Fjord + player.CloseGossipMenu(); + DoCast(player, SpellIds.HowlingFjord, false); + break; + case eTradeskill.GossipActionInfoDef + 3: // Sholazar Basin + player.CloseGossipMenu(); + DoCast(player, SpellIds.SholazarBasin, false); + break; + case eTradeskill.GossipActionInfoDef + 4: // Icecrown + player.CloseGossipMenu(); + DoCast(player, SpellIds.Icecrown, false); + break; + case eTradeskill.GossipActionInfoDef + 5: // Storm peaks + player.CloseGossipMenu(); + DoCast(player, SpellIds.StormPeaks, false); + break; + case eTradeskill.GossipActionInfoDef + 6: // Underground + player.CloseGossipMenu(); + DoCast(player, SpellIds.Underground, false); + break; + } + + return true; + } + + bool _showUnderground; + } + + [Script] + class npc_experience : ScriptedAI + { + public npc_experience(Creature creature) : base(creature) { } + + public override bool GossipHello(Player player) + { + if (player.HasPlayerFlag(PlayerFlags.NoXPGain)) // not gaining XP + { + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdXpOnOff, GossipMenus.OptionIdXpOn, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1); + player.SendGossipMenu(TextIds.XpOnOff, me.GetGUID()); + } + else // currently gaining XP + { + player.ADD_GOSSIP_ITEM_DB(GossipMenus.MenuIdXpOnOff, GossipMenus.OptionIdXpOff, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2); + player.SendGossipMenu(TextIds.XpOnOff, me.GetGUID()); + } + return true; + } + + public override bool GossipSelect(Player player, uint menuId, uint gossipListId) + { + uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId); + player.PlayerTalkClass.ClearMenus(); + + switch (action) + { + case eTradeskill.GossipActionInfoDef + 1:// XP ON selected + player.RemovePlayerFlag(PlayerFlags.NoXPGain); // turn on XP gain + break; + case eTradeskill.GossipActionInfoDef + 2:// XP OFF selected + player.AddPlayerFlag(PlayerFlags.NoXPGain); // turn off XP gain + break; + } + + player.PlayerTalkClass.SendCloseGossip(); + return true; + } + } + + [Script] + class npc_firework : ScriptedAI + { + public npc_firework(Creature creature) : base(creature) { } + + bool isCluster() + { + switch (me.GetEntry()) + { + case CreatureIds.FireworkBlue: + case CreatureIds.FireworkGreen: + case CreatureIds.FireworkPurple: + case CreatureIds.FireworkRed: + case CreatureIds.FireworkYellow: + case CreatureIds.FireworkWhite: + case CreatureIds.FireworkBigBlue: + case CreatureIds.FireworkBigGreen: + case CreatureIds.FireworkBigPurple: + case CreatureIds.FireworkBigRed: + case CreatureIds.FireworkBigYellow: + case CreatureIds.FireworkBigWhite: + return false; + case CreatureIds.ClusterBlue: + case CreatureIds.ClusterGreen: + case CreatureIds.ClusterPurple: + case CreatureIds.ClusterRed: + case CreatureIds.ClusterYellow: + case CreatureIds.ClusterWhite: + case CreatureIds.ClusterBigBlue: + case CreatureIds.ClusterBigGreen: + case CreatureIds.ClusterBigPurple: + case CreatureIds.ClusterBigRed: + case CreatureIds.ClusterBigYellow: + case CreatureIds.ClusterBigWhite: + case CreatureIds.ClusterElune: + default: + return true; + } + } + + GameObject FindNearestLauncher() + { + GameObject launcher = null; + + if (isCluster()) + { + GameObject launcher1 = GetClosestGameObjectWithEntry(me, GameobjectIds.ClusterLauncher1, 0.5f); + GameObject launcher2 = GetClosestGameObjectWithEntry(me, GameobjectIds.ClusterLauncher2, 0.5f); + GameObject launcher3 = GetClosestGameObjectWithEntry(me, GameobjectIds.ClusterLauncher3, 0.5f); + GameObject launcher4 = GetClosestGameObjectWithEntry(me, GameobjectIds.ClusterLauncher4, 0.5f); + + if (launcher1) + launcher = launcher1; + else if (launcher2) + launcher = launcher2; + else if (launcher3) + launcher = launcher3; + else if (launcher4) + launcher = launcher4; + } + else + { + GameObject launcher1 = GetClosestGameObjectWithEntry(me, GameobjectIds.FireworkLauncher1, 0.5f); + GameObject launcher2 = GetClosestGameObjectWithEntry(me, GameobjectIds.FireworkLauncher2, 0.5f); + GameObject launcher3 = GetClosestGameObjectWithEntry(me, GameobjectIds.FireworkLauncher3, 0.5f); + + if (launcher1) + launcher = launcher1; + else if (launcher2) + launcher = launcher2; + else if (launcher3) + launcher = launcher3; + } + + return launcher; + } + + uint GetFireworkSpell(uint entry) + { + switch (entry) + { + case CreatureIds.FireworkBlue: + return SpellIds.RocketBlue; + case CreatureIds.FireworkGreen: + return SpellIds.RocketGreen; + case CreatureIds.FireworkPurple: + return SpellIds.RocketPurple; + case CreatureIds.FireworkRed: + return SpellIds.RocketRed; + case CreatureIds.FireworkYellow: + return SpellIds.RocketYellow; + case CreatureIds.FireworkWhite: + return SpellIds.RocketWhite; + case CreatureIds.FireworkBigBlue: + return SpellIds.RocketBigBlue; + case CreatureIds.FireworkBigGreen: + return SpellIds.RocketBigGreen; + case CreatureIds.FireworkBigPurple: + return SpellIds.RocketBigPurple; + case CreatureIds.FireworkBigRed: + return SpellIds.RocketBigRed; + case CreatureIds.FireworkBigYellow: + return SpellIds.RocketBigYellow; + case CreatureIds.FireworkBigWhite: + return SpellIds.RocketBigWhite; + default: + return 0; + } + } + + uint GetFireworkGameObjectId() + { + uint spellId = 0; + + switch (me.GetEntry()) + { + case CreatureIds.ClusterBlue: + spellId = GetFireworkSpell(CreatureIds.FireworkBlue); + break; + case CreatureIds.ClusterGreen: + spellId = GetFireworkSpell(CreatureIds.FireworkGreen); + break; + case CreatureIds.ClusterPurple: + spellId = GetFireworkSpell(CreatureIds.FireworkPurple); + break; + case CreatureIds.ClusterRed: + spellId = GetFireworkSpell(CreatureIds.FireworkRed); + break; + case CreatureIds.ClusterYellow: + spellId = GetFireworkSpell(CreatureIds.FireworkYellow); + break; + case CreatureIds.ClusterWhite: + spellId = GetFireworkSpell(CreatureIds.FireworkWhite); + break; + case CreatureIds.ClusterBigBlue: + spellId = GetFireworkSpell(CreatureIds.FireworkBigBlue); + break; + case CreatureIds.ClusterBigGreen: + spellId = GetFireworkSpell(CreatureIds.FireworkBigGreen); + break; + case CreatureIds.ClusterBigPurple: + spellId = GetFireworkSpell(CreatureIds.FireworkBigPurple); + break; + case CreatureIds.ClusterBigRed: + spellId = GetFireworkSpell(CreatureIds.FireworkBigRed); + break; + case CreatureIds.ClusterBigYellow: + spellId = GetFireworkSpell(CreatureIds.FireworkBigYellow); + break; + case CreatureIds.ClusterBigWhite: + spellId = GetFireworkSpell(CreatureIds.FireworkBigWhite); + break; + case CreatureIds.ClusterElune: + spellId = GetFireworkSpell(RandomHelper.URand(CreatureIds.FireworkBlue, CreatureIds.FireworkWhite)); + break; + } + + SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None); + if (spellInfo != null && spellInfo.GetEffect(0).Effect == SpellEffectName.SummonObjectWild) + return (uint)spellInfo.GetEffect(0).MiscValue; + + return 0; + } + + public override void Reset() + { + GameObject launcher = FindNearestLauncher(); + if (launcher) + { + launcher.SendCustomAnim(Misc.AnimGoLaunchFirework); + me.SetOrientation(launcher.GetOrientation() + MathFunctions.PI / 2); + } + else + return; + + if (isCluster()) + { + // Check if we are near Elune'ara lake south, if so try to summon Omen or a minion + if (me.GetZoneId() == Misc.ZoneMoonglade) + { + if (!me.FindNearestCreature(CreatureIds.Omen, 100.0f) && me.GetDistance2d(Misc.omenSummonPos.GetPositionX(), Misc.omenSummonPos.GetPositionY()) <= 100.0f) + { + switch (RandomHelper.URand(0, 9)) + { + case 0: + case 1: + case 2: + case 3: + Creature minion = me.SummonCreature(CreatureIds.MinionOfOmen, me.GetPositionX() + RandomHelper.FRand(-5.0f, 5.0f), me.GetPositionY() + RandomHelper.FRand(-5.0f, 5.0f), me.GetPositionZ(), 0.0f, TempSummonType.CorpseTimedDespawn, 20000); + if (minion) + minion.GetAI().AttackStart(me.SelectNearestPlayer(20.0f)); + break; + case 9: + me.SummonCreature(CreatureIds.Omen, Misc.omenSummonPos); + break; + } + } + } + if (me.GetEntry() == CreatureIds.ClusterElune) + DoCast(SpellIds.LunarFortune); + + float displacement = 0.7f; + for (byte i = 0; i < 4; i++) + me.SummonGameObject(GetFireworkGameObjectId(), me.GetPositionX() + (i % 2 == 0 ? displacement : -displacement), me.GetPositionY() + (i > 1 ? displacement : -displacement), me.GetPositionZ() + 4.0f, me.GetOrientation(), Quaternion.fromEulerAnglesZYX(me.GetOrientation(), 0.0f, 0.0f), 1); + } + else + //me.CastSpell(me, GetFireworkSpell(me.GetEntry()), true); + me.CastSpell(me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), GetFireworkSpell(me.GetEntry()), true); + } + } + + [Script] + class npc_spring_rabbit : ScriptedAI + { + public npc_spring_rabbit(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + inLove = false; + rabbitGUID.Clear(); + jumpTimer = RandomHelper.URand(5000, 10000); + bunnyTimer = RandomHelper.URand(10000, 20000); + searchTimer = RandomHelper.URand(5000, 10000); + } + + bool inLove; + uint jumpTimer; + uint bunnyTimer; + uint searchTimer; + ObjectGuid rabbitGUID; + + public override void Reset() + { + Initialize(); + Unit owner = me.GetOwner(); + if (owner) + me.GetMotionMaster().MoveFollow(owner, SharedConst.PetFollowDist, SharedConst.PetFollowAngle); + } + + public override void EnterCombat(Unit who) { } + + public override void DoAction(int param) + { + inLove = true; + Unit owner = me.GetOwner(); + if (owner) + owner.CastSpell(owner, SpellIds.SpringFling, true); + } + + public override void UpdateAI(uint diff) + { + if (inLove) + { + if (jumpTimer <= diff) + { + Unit rabbit = Global.ObjAccessor.GetUnit(me, rabbitGUID); + if (rabbit) + DoCast(rabbit, SpellIds.SpringRabbitJump); + jumpTimer = RandomHelper.URand(5000, 10000); + } + else jumpTimer -= diff; + + if (bunnyTimer <= diff) + { + DoCast(SpellIds.SummonBabyBunny); + bunnyTimer = RandomHelper.URand(20000, 40000); + } + else bunnyTimer -= diff; + } + else + { + if (searchTimer <= diff) + { + Creature rabbit = me.FindNearestCreature(CreatureIds.SpringRabbit, 10.0f); + if (rabbit) + { + if (rabbit == me || rabbit.HasAura(SpellIds.SpringRabbitInLove)) + return; + + me.AddAura(SpellIds.SpringRabbitInLove, me); + DoAction(1); + rabbit.AddAura(SpellIds.SpringRabbitInLove, rabbit); + rabbit.GetAI().DoAction(1); + rabbit.CastSpell(rabbit, SpellIds.SpringRabbitJump, true); + rabbitGUID = rabbit.GetGUID(); + } + searchTimer = RandomHelper.URand(5000, 10000); + } + else searchTimer -= diff; + } + } + } + + [Script] + class npc_imp_in_a_ball : ScriptedAI + { + public npc_imp_in_a_ball(Creature creature) : base(creature) + { + summonerGUID.Clear(); + } + + public override void IsSummonedBy(Unit summoner) + { + if (summoner.IsTypeId(TypeId.Player)) + { + summonerGUID = summoner.GetGUID(); + + _scheduler.Schedule(TimeSpan.FromSeconds(3), task => + { + Player owner = Global.ObjAccessor.GetPlayer(me, summonerGUID); + if (owner) + Global.CreatureTextMgr.SendChat(me, 0, owner, owner.GetGroup() ? ChatMsg.MonsterParty : ChatMsg.MonsterWhisper, Language.Addon, CreatureTextRange.Normal); + }); + } + } + + public override void UpdateAI(uint diff) + { + _scheduler.Update(diff); + } + + ObjectGuid summonerGUID; + } + + struct TrainWrecker + { + public const int ActionWrecked = 1; + public const int EventDoJump = 1; + public const int EventDoFacing = 2; + public const int EventDoWreck = 3; + public const int EventDoDance = 4; + public const uint MoveidChase = 1; + public const uint MoveidJump = 2; + } + + [Script] + class npc_train_wrecker : NullCreatureAI + { + public npc_train_wrecker(Creature creature) : base(creature) + { + _isSearching = true; + _nextAction = 0; + _timer = 1 * Time.InMilliseconds; + } + + GameObject VerifyTarget() + { + GameObject target = ObjectAccessor.GetGameObject(me, _target); + if (target) + return target; + + me.HandleEmoteCommand(Emote.OneshotRude); + me.DespawnOrUnsummon(3 * Time.InMilliseconds); + return null; + } + + public override void UpdateAI(uint diff) + { + if (_isSearching) + { + if (diff < _timer) + _timer -= diff; + else + { + GameObject target = me.FindNearestGameObject(GameobjectIds.ToyTrain, 15.0f); + if (target) + { + _isSearching = false; + _target = target.GetGUID(); + me.SetWalk(true); + me.GetMotionMaster().MovePoint(TrainWrecker.MoveidChase, target.GetNearPosition(3.0f, target.GetAngle(me))); + } + else + _timer = 3 * Time.InMilliseconds; + } + } + else + { + switch (_nextAction) + { + case TrainWrecker.EventDoJump: + { + GameObject target = VerifyTarget(); + if (target) + me.GetMotionMaster().MoveJump(target, 5.0f, 10.0f, TrainWrecker.MoveidJump); + _nextAction = 0; + } + break; + case TrainWrecker.EventDoFacing: + { + GameObject target = VerifyTarget(); + if (target) + { + me.SetFacingTo(target.GetOrientation()); + me.HandleEmoteCommand(Emote.OneshotAttack1h); + _timer = (uint)(1.5 * Time.InMilliseconds); + _nextAction = TrainWrecker.EventDoWreck; + } + else + _nextAction = 0; + } + break; + case TrainWrecker.EventDoWreck: + { + if (diff < _timer) + { + _timer -= diff; + break; + } + + GameObject target = VerifyTarget(); + if (target) + { + me.CastSpell(target, SpellIds.WreckTrain, false); + target.GetAI().DoAction(TrainWrecker.ActionWrecked); + _timer = 2 * Time.InMilliseconds; + _nextAction = TrainWrecker.EventDoDance; + } + else + _nextAction = 0; + } + break; + case TrainWrecker.EventDoDance: + if (diff < _timer) + { + _timer -= diff; + break; + } + me.UpdateEntry(CreatureIds.ExultingWindUpTrainWrecker); + me.SetEmoteState(Emote.OneshotDance); + me.DespawnOrUnsummon(5 * Time.InMilliseconds); + _nextAction = 0; + break; + default: + break; + } + } + } + + public override void MovementInform(MovementGeneratorType type, uint id) + { + if (id == TrainWrecker.MoveidChase) + _nextAction = TrainWrecker.EventDoJump; + else if (id == TrainWrecker.MoveidJump) + _nextAction = TrainWrecker.EventDoFacing; + } + + bool _isSearching; + byte _nextAction; + uint _timer; + ObjectGuid _target; + } + + [Script] + class npc_argent_squire_gruntling : ScriptedAI + { + public npc_argent_squire_gruntling(Creature creature) : base(creature) + { + ScheduleTasks(); + } + + public void ScheduleTasks() + { + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + Aura ownerTired = me.GetOwner().GetAura(SpellIds.TiredPlayer); + if (ownerTired != null) + { + Aura squireTired = me.AddAura(IsArgentSquire() ? SpellIds.AuraTiredS : SpellIds.AuraTiredG, me); + if (squireTired != null) + squireTired.SetDuration(ownerTired.GetDuration()); + } + }); + _scheduler.Schedule(TimeSpan.FromSeconds(1), task => + { + if ((me.HasAura(SpellIds.AuraTiredS) || me.HasAura(SpellIds.AuraTiredG)) && me.HasNpcFlag(NPCFlags.Banker | NPCFlags.Mailbox | NPCFlags.Vendor)) + me.RemoveNpcFlag(NPCFlags.Banker | NPCFlags.Mailbox | NPCFlags.Vendor); + task.Repeat(); + }); + } + + public override bool GossipSelect(Player player, uint menuId, uint gossipListId) + { + switch (gossipListId) + { + case GossipMenus.OptionIdBank: + { + me.AddNpcFlag(NPCFlags.Banker); + uint _bankAura = IsArgentSquire() ? SpellIds.AuraBankS : SpellIds.AuraBankG; + if (!me.HasAura(_bankAura)) + DoCastSelf(_bankAura); + + if (!player.HasAura(SpellIds.TiredPlayer)) + player.CastSpell(player, SpellIds.TiredPlayer, true); + break; + } + case GossipMenus.OptionIdShop: + { + me.AddNpcFlag(NPCFlags.Vendor); + uint _shopAura = IsArgentSquire() ? SpellIds.AuraShopS : SpellIds.AuraShopG; + if (!me.HasAura(_shopAura)) + DoCastSelf(_shopAura); + + if (!player.HasAura(SpellIds.TiredPlayer)) + player.CastSpell(player, SpellIds.TiredPlayer, true); + break; + } + case GossipMenus.OptionIdMail: + { + me.AddNpcFlag(NPCFlags.Mailbox); + player.GetSession().SendShowMailBox(me.GetGUID()); + + uint _mailAura = IsArgentSquire() ? SpellIds.AuraPostmanS : SpellIds.AuraPostmanG; + if (!me.HasAura(_mailAura)) + DoCastSelf(_mailAura); + + if (!player.HasAura(SpellIds.TiredPlayer)) + player.CastSpell(player, SpellIds.TiredPlayer, true); + break; + } + case GossipMenus.OptionIdDarnassusSenjinPennant: + case GossipMenus.OptionIdExodarUndercityPennant: + case GossipMenus.OptionIdGnomereganOrgrimmarPennant: + case GossipMenus.OptionIdIronforgeSilvermoonPennant: + case GossipMenus.OptionIdStormwindThunderbluffPennant: + if (IsArgentSquire()) + DoCastSelf(Misc.bannerSpells[gossipListId - 3].Item1, true); + else + DoCastSelf(Misc.bannerSpells[gossipListId - 3].Item2, true); + break; + } + player.PlayerTalkClass.SendCloseGossip(); + return false; + } + + public override void UpdateAI(uint diff) + { + _scheduler.Update(diff); + } + + bool IsArgentSquire() { return me.GetEntry() == CreatureIds.ArgentSquire; } + } + + [Script] + class npc_bountiful_tableAI : PassiveAI + { + public npc_bountiful_tableAI(Creature creature) : base(creature) { } + + public override void PassengerBoarded(Unit who, sbyte seatId, bool apply) + { + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + float o = 0.0f; + + switch ((SeatIds)seatId) + { + case SeatIds.TurkeyChair: + x = 3.87f; + y = 2.07f; + o = 3.700098f; + break; + case SeatIds.CranberryChair: + x = 3.87f; + y = -2.07f; + o = 2.460914f; + break; + case SeatIds.StuffingChair: + x = -2.52f; + break; + case SeatIds.SweetPotatoChair: + x = -0.09f; + y = -3.24f; + o = 1.186824f; + break; + case SeatIds.PieChair: + x = -0.18f; + y = 3.24f; + o = 5.009095f; + break; + case SeatIds.FoodHolder: + case SeatIds.PlateHolder: + Vehicle holders = who.GetVehicleKit(); + if (holders) + holders.InstallAllAccessories(true); + return; + default: + break; + } + + MoveSplineInit init = new MoveSplineInit(who); + init.DisableTransportPathTransformations(); + init.MoveTo(x, y, z, false); + init.SetFacing(o); + init.Launch(); + who.m_Events.AddEvent(new CastFoodSpell(who, SpellIds.ChairSpells[who.GetEntry()]), who.m_Events.CalculateTime(1000)); + Creature creature = who.ToCreature(); + if (creature) + creature.SetDisplayFromModel(0); + } + } + + class CastFoodSpell : BasicEvent + { + Unit _owner; + uint _spellId; + + public CastFoodSpell(Unit owner, uint spellId) + { + _owner = owner; + _spellId = spellId; + } + + public override bool Execute(ulong execTime, uint diff) + { + _owner.CastSpell(_owner, _spellId, true); + return true; + } + } +}