diff --git a/Source/Framework/Dynamic/EventSystem.cs b/Source/Framework/Dynamic/EventSystem.cs index d67e342b8..077a8087c 100644 --- a/Source/Framework/Dynamic/EventSystem.cs +++ b/Source/Framework/Dynamic/EventSystem.cs @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +using System; using System.Collections.Generic; using System.Linq; @@ -61,7 +62,6 @@ namespace Framework.Dynamic } } - public void KillAllEvents(bool force) { foreach (var pair in m_events.KeyValueList) @@ -96,6 +96,8 @@ namespace Framework.Dynamic m_events.Add(e_time, Event); } + public void AddEventAtOffset(BasicEvent Event, TimeSpan offset) { AddEvent(Event, CalculateTime((ulong)offset.TotalMilliseconds)); } + public void ModifyEventTime(BasicEvent Event, ulong newTime) { foreach (var pair in m_events) diff --git a/Source/Scripts/Spells/Druid.cs b/Source/Scripts/Spells/Druid.cs index e91e3b363..9b879cb00 100644 --- a/Source/Scripts/Spells/Druid.cs +++ b/Source/Scripts/Spells/Druid.cs @@ -22,6 +22,7 @@ using Game.Spells; using System; using System.Collections.Generic; using System.Linq; +using Framework.Dynamic; namespace Scripts.Spells.Druid { @@ -42,6 +43,12 @@ namespace Scripts.Spells.Druid public const uint BristlingFurGainRage = 204031; public const uint CatForm = 768; public const uint EarthwardenAura = 203975; + public const uint EclipseDummy = 79577; + public const uint EclipseLunarAura = 48518; + public const uint EclipseLunarSpellCnt = 326055; + public const uint EclipseOoc = 329910; + public const uint EclipseSolarAura = 48517; + public const uint EclipseSolarSpellCnt = 326053; public const uint Exhilarate = 28742; public const uint FeralChargeBear = 16979; public const uint FeralChargeCat = 49376; @@ -198,6 +205,162 @@ namespace Scripts.Spells.Druid } } + class spell_dru_eclipse_common + { + public static void SetSpellCount(Unit unitOwner, uint spellId, uint amount) + { + Aura aura = unitOwner.GetAura(spellId); + if (aura == null) + unitOwner.CastCustomSpell(spellId, SpellValueMod.AuraStack, (int)amount, null, TriggerCastFlags.FullMask); + else + aura.SetStackAmount((byte)amount); + } + } + + // 48517 Eclipse (Solar) + 48518 Eclipse (Lunar) + class spell_dru_eclipse_aura : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.EclipseLunarSpellCnt, SpellIds.EclipseSolarSpellCnt, SpellIds.EclipseDummy); + } + + void HandleRemoved(AuraEffect aurEff, AuraEffectHandleModes mode) + { + AuraEffect auraEffDummy = GetTarget().GetAuraEffect(SpellIds.EclipseDummy, 0); + if (auraEffDummy == null) + return; + + uint spellId = GetSpellInfo().Id == SpellIds.EclipseSolarAura ? SpellIds.EclipseLunarSpellCnt : SpellIds.EclipseSolarSpellCnt; + spell_dru_eclipse_common.SetSpellCount(GetTarget(), spellId, (uint)auraEffDummy.GetAmount()); + } + + public override void Register() + { + AfterEffectRemove .Add(new EffectApplyHandler(HandleRemoved, 0, AuraType.AddPctModifier, AuraEffectHandleModes.Real)); + } + } + + // 79577 - Eclipse - SPELL_DRUID_ECLIPSE_DUMMY + class spell_dru_eclipse_dummy : AuraScript + { + class InitializeEclipseCountersEvent : BasicEvent + { + Unit _owner; + uint _count; + + public InitializeEclipseCountersEvent(Unit owner, uint count) + { + _owner = owner; + _count = count; + } + + public override bool Execute(ulong e_time, uint p_time) + { + spell_dru_eclipse_common.SetSpellCount(_owner, SpellIds.EclipseSolarSpellCnt, _count); + spell_dru_eclipse_common.SetSpellCount(_owner, SpellIds.EclipseLunarSpellCnt, _count); + return true; + } + } + + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.EclipseSolarSpellCnt, SpellIds.EclipseLunarSpellCnt, SpellIds.EclipseSolarAura, SpellIds.EclipseLunarAura); + } + + void HandleProc(ProcEventInfo eventInfo) + { + SpellInfo spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo != null) + { + if (spellInfo.SpellFamilyFlags & new FlagArray128(0x4, 0x0, 0x0, 0x0)) // Starfire + OnSpellCast(SpellIds.EclipseSolarSpellCnt, SpellIds.EclipseLunarSpellCnt, SpellIds.EclipseSolarAura); + else if (spellInfo.SpellFamilyFlags & new FlagArray128(0x1, 0x0, 0x0, 0x0)) // Wrath + OnSpellCast(SpellIds.EclipseLunarSpellCnt, SpellIds.EclipseSolarSpellCnt, SpellIds.EclipseLunarAura); + } + } + + void HandleApply(AuraEffect aurEff, AuraEffectHandleModes mode) + { + // counters are applied with a delay + GetTarget().m_Events.AddEventAtOffset(new InitializeEclipseCountersEvent(GetTarget(), (uint)aurEff.GetAmount()), TimeSpan.FromSeconds(1)); + } + + void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode) + { + GetTarget().RemoveAura(SpellIds.EclipseSolarSpellCnt); + GetTarget().RemoveAura(SpellIds.EclipseLunarSpellCnt); + } + + void OnOwnerOutOfCombat(bool isNowInCombat) + { + if (!isNowInCombat) + GetTarget().CastSpell(GetTarget(), SpellIds.EclipseOoc, TriggerCastFlags.FullMask); + } + + public override void Register() + { + AfterEffectApply.Add(new EffectApplyHandler(HandleApply, 0, AuraType.Dummy, AuraEffectHandleModes.Real)); + AfterEffectRemove.Add(new EffectApplyHandler(HandleRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real)); + OnProc.Add(new AuraProcHandler(HandleProc)); + OnEnterLeaveCombat.Add(new EnterLeaveCombatHandler(OnOwnerOutOfCombat)); + } + + void OnSpellCast(uint cntSpellId, uint otherCntSpellId, uint eclipseAuraSpellId) + { + Unit target = GetTarget(); + Aura aura = target.GetAura(cntSpellId); + if (aura != null) + { + uint remaining = aura.GetStackAmount(); + if (remaining == 0) + return; + + if (remaining > 1) + aura.SetStackAmount((byte)(remaining - 1)); + else + { + // cast eclipse + target.CastSpell(target, eclipseAuraSpellId, TriggerCastFlags.FullMask); + + // Remove stacks from other one as well + // reset remaining power on other spellId + target.RemoveAura(cntSpellId); + target.RemoveAura(otherCntSpellId); + } + } + } + } + + // 329910 - Eclipse out of combat - SPELL_DRUID_ECLIPSE_OOC + class spell_dru_eclipse_ooc : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.EclipseDummy, SpellIds.EclipseSolarSpellCnt, SpellIds.EclipseLunarSpellCnt); + } + + void Tick(AuraEffect aurEff) + { + Unit owner = GetTarget(); + AuraEffect auraEffDummy = owner.GetAuraEffect(SpellIds.EclipseDummy, 0); + if (auraEffDummy == null) + return; + + if (!owner.IsInCombat() && (!owner.HasAura(SpellIds.EclipseSolarSpellCnt) || !owner.HasAura(SpellIds.EclipseLunarSpellCnt))) + { + // Restore 2 stacks to each spell when out of combat + spell_dru_eclipse_common.SetSpellCount(owner, SpellIds.EclipseSolarSpellCnt, (uint)auraEffDummy.GetAmount()); + spell_dru_eclipse_common.SetSpellCount(owner, SpellIds.EclipseLunarSpellCnt, (uint)auraEffDummy.GetAmount()); + } + } + + public override void Register() + { + OnEffectPeriodic.Add(new EffectPeriodicHandler(Tick, 0, AuraType.PeriodicDummy)); + } + } + [Script] // 203974 - Earthwarden class spell_dru_earthwarden : AuraScript { diff --git a/sql/updates/world/master/2021_03_23_00_world_druid_eclipse.sql b/sql/updates/world/master/2021_03_23_00_world_druid_eclipse.sql new file mode 100644 index 000000000..01b1a47dd --- /dev/null +++ b/sql/updates/world/master/2021_03_23_00_world_druid_eclipse.sql @@ -0,0 +1,11 @@ +DELETE FROM `spell_proc` WHERE `SpellId`=79577; +INSERT INTO `spell_proc` (`SpellId`,`SchoolMask`,`SpellFamilyName`,`SpellFamilyMask0`,`SpellFamilyMask1`,`SpellFamilyMask2`,`SpellFamilyMask3`,`ProcFlags`,`SpellTypeMask`,`SpellPhaseMask`,`HitMask`,`AttributesMask`,`DisableEffectsMask`,`ProcsPerMinute`,`Chance`,`Cooldown`,`Charges`) VALUES +(79577,0,7,0x5,0,0,0,0,0,0x1,0,0,0,0,0,0,0); -- Eclipse, proc on launch of Wrath and Starfire + +-- Add eclipse spell script +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_dru_eclipse_dummy', 'spell_dru_eclipse_aura', 'spell_dru_eclipse_ooc'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(79577, 'spell_dru_eclipse_dummy'), +(48517, 'spell_dru_eclipse_aura'), +(48518, 'spell_dru_eclipse_aura'), +(329910, 'spell_dru_eclipse_ooc');