diff --git a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs index 5b39664df..d4ae2eb07 100644 --- a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs +++ b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs @@ -754,17 +754,17 @@ namespace Game.Entities rotatedPoints.Add(new Vector3(x, y, z)); } - InitSplines(rotatedPoints, timeToTarget); + InitSplines(rotatedPoints.ToArray(), timeToTarget); } - public void InitSplines(List splinePoints, uint timeToTarget) + public void InitSplines(Vector3[] splinePoints, uint timeToTarget) { - if (splinePoints.Count < 2) + if (splinePoints.Length < 2) return; _movementTime = 0; - _spline.InitSpline(splinePoints.ToArray(), splinePoints.Count, EvaluationMode.Linear); + _spline.InitSpline(splinePoints, splinePoints.Length, EvaluationMode.Linear); _spline.InitLengths(); // should be sent in object create packets only diff --git a/Source/Game/Networking/Packets/AreaTriggerPackets.cs b/Source/Game/Networking/Packets/AreaTriggerPackets.cs index 9d2c41fc5..7611e6f69 100644 --- a/Source/Game/Networking/Packets/AreaTriggerPackets.cs +++ b/Source/Game/Networking/Packets/AreaTriggerPackets.cs @@ -84,7 +84,7 @@ namespace Game.Networking.Packets data.WriteUInt32(TimeToTarget); data.WriteUInt32(ElapsedTimeForMovement); - data.WriteBits(Points.Count, 16); + data.WriteBits(Points.Length, 16); data.FlushBits(); foreach (Vector3 point in Points) @@ -93,6 +93,6 @@ namespace Game.Networking.Packets public uint TimeToTarget; public uint ElapsedTimeForMovement; - public List Points = new(); + public Vector3[] Points = new Vector3[0]; } } diff --git a/Source/Scripts/Spells/Priest.cs b/Source/Scripts/Spells/Priest.cs index 456a81a07..bde751b56 100644 --- a/Source/Scripts/Spells/Priest.cs +++ b/Source/Scripts/Spells/Priest.cs @@ -29,8 +29,12 @@ namespace Scripts.Spells.Priest public const uint BodyAndSoul = 64129; public const uint BodyAndSoulSpeed = 65081; public const uint DivineBlessing = 40440; - public const uint DivineStarDamage = 122128; - public const uint DivineStarHeal = 110745; + public const uint DivineStarHoly = 110744; + public const uint DivineStarShadow = 122121; + public const uint DivineStarHolyDamage = 122128; + public const uint DivineStarHolyHeal = 110745; + public const uint DivineStarShadowDamage = 390845; + public const uint DivineStarShadowHeal = 390981; public const uint DivineWrath = 40441; public const uint FlashHeal = 2061; public const uint GuardianSpiritHeal = 48153; @@ -324,36 +328,63 @@ namespace Scripts.Spells.Priest } } - [Script] // 110744 - Divine Star + [Script] // 122121 - Divine Star (Shadow) + class spell_pri_divine_star_shadow : SpellScript + { + void HandleHitTarget(uint effIndex) + { + Unit caster = GetCaster(); + + if ((int)caster.GetPowerType() != GetEffectInfo().MiscValue) + PreventHitDefaultEffect(effIndex); + } + + public override void Register() + { + OnEffectHitTarget.Add(new EffectHandler(HandleHitTarget, 2, SpellEffectName.Energize)); + } + } + + // 110744 - Divine Star (Holy) + [Script] // 122121 - Divine Star (Shadow) class areatrigger_pri_divine_star : AreaTriggerAI { TaskScheduler _scheduler = new(); Position _casterCurrentPosition = new(); List _affectedUnits = new(); + float _maxTravelDistance; public areatrigger_pri_divine_star(AreaTrigger areatrigger) : base(areatrigger) { } public override void OnInitialize() { + SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(at.GetSpellId(), Difficulty.None); + if (spellInfo == null) + return; + + if (spellInfo.GetEffects().Count <= 1) + return; + Unit caster = at.GetCaster(); - if (caster != null) - { - _casterCurrentPosition = caster.GetPosition(); + if (caster == null) + return; - // Note: max. distance at which the Divine Star can travel to is 24 yards. - float divineStarXOffSet = 24.0f; + _casterCurrentPosition = caster.GetPosition(); - Position destPos = _casterCurrentPosition; - at.MovePositionToFirstCollision(destPos, divineStarXOffSet, 0.0f); + // Note: max. distance at which the Divine Star can travel to is EFFECT_1's BasePoints yards. + _maxTravelDistance = (float)spellInfo.GetEffect(1).CalcValue(caster); - PathGenerator firstPath = new(at); - firstPath.CalculatePath(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ(), false); + Position destPos = _casterCurrentPosition; + at.MovePositionToFirstCollision(destPos, _maxTravelDistance, 0.0f); - Vector3 endPoint = firstPath.GetPath().Last(); + PathGenerator firstPath = new(at); + firstPath.CalculatePath(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ(), false); + + Vector3 endPoint = firstPath.GetPath().Last(); + + // Note: it takes 1000ms to reach EFFECT_1's BasePoints yards, so it takes (1000 / EFFECT_1's BasePoints)ms to run 1 yard. + at.InitSplines(firstPath.GetPath(), (uint)(at.GetDistance(endPoint.X, endPoint.Y, endPoint.Z) * (float)(1000 / _maxTravelDistance))); - // Note: it takes 1000ms to reach 24 yards, so it takes 41.67ms to run 1 yard. - at.InitSplines(firstPath.GetPath().ToList(), (uint)(at.GetDistance(endPoint.X, endPoint.Y, endPoint.Z) * 41.67f)); - } } public override void OnUpdate(uint diff) @@ -363,37 +394,31 @@ namespace Scripts.Spells.Priest public override void OnUnitEnter(Unit unit) { - Unit caster = at.GetCaster(); - if (caster != null) - { - if (!_affectedUnits.Contains(unit.GetGUID())) - { - if (caster.IsValidAttackTarget(unit)) - caster.CastSpell(unit, SpellIds.DivineStarDamage, new CastSpellExtraArgs(TriggerCastFlags.IgnoreGCD | TriggerCastFlags.IgnoreCastInProgress)); - else if (caster.IsValidAssistTarget(unit)) - caster.CastSpell(unit, SpellIds.DivineStarHeal, new CastSpellExtraArgs(TriggerCastFlags.IgnoreGCD | TriggerCastFlags.IgnoreCastInProgress)); - - _affectedUnits.Add(unit.GetGUID()); - } - } + HandleUnitEnterExit(unit); } public override void OnUnitExit(Unit unit) { - // Note: this ensures any unit receives a second hit if they happen to be inside the AT when Divine Star starts its return path. - Unit caster = at.GetCaster(); - if (caster != null) - { - if (!_affectedUnits.Contains(unit.GetGUID())) - { - if (caster.IsValidAttackTarget(unit)) - caster.CastSpell(unit, SpellIds.DivineStarDamage, new CastSpellExtraArgs(TriggerCastFlags.IgnoreGCD | TriggerCastFlags.IgnoreCastInProgress)); - else if (caster.IsValidAssistTarget(unit)) - caster.CastSpell(unit, SpellIds.DivineStarHeal, new CastSpellExtraArgs(TriggerCastFlags.IgnoreGCD | TriggerCastFlags.IgnoreCastInProgress)); + HandleUnitEnterExit(unit); + } - _affectedUnits.Add(unit.GetGUID()); - } - } + void HandleUnitEnterExit(Unit unit) + { + Unit caster = at.GetCaster(); + if (caster == null) + return; + + if (_affectedUnits.Contains(unit.GetGUID())) + return; + + CastSpellExtraArgs castSpellExtraArgs = new(TriggerCastFlags.IgnoreGCD | TriggerCastFlags.IgnoreCastInProgress); + + if (caster.IsValidAttackTarget(unit)) + caster.CastSpell(unit, at.GetSpellId() == SpellIds.DivineStarShadow ? SpellIds.DivineStarShadowDamage : SpellIds.DivineStarHolyDamage, castSpellExtraArgs); + else if (caster.IsValidAssistTarget(unit)) + caster.CastSpell(unit, at.GetSpellId() == SpellIds.DivineStarShadow ? SpellIds.DivineStarShadowHeal : SpellIds.DivineStarHolyHeal, castSpellExtraArgs); + + _affectedUnits.Add(unit.GetGUID()); } public override void OnDestinationReached() @@ -417,21 +442,22 @@ namespace Scripts.Spells.Priest _scheduler.Schedule(TimeSpan.FromMilliseconds(0), task => { Unit caster = at.GetCaster(); - if (caster != null) - { - _casterCurrentPosition = caster.GetPosition(); + if (caster == null) + return; - List returnSplinePoints = new(); + _casterCurrentPosition = caster.GetPosition(); - returnSplinePoints.Add(at.GetPosition()); - returnSplinePoints.Add(at.GetPosition()); - returnSplinePoints.Add(caster.GetPosition()); - returnSplinePoints.Add(caster.GetPosition()); + Vector3[] returnSplinePoints = new Vector3[4]; - at.InitSplines(returnSplinePoints, (uint)at.GetDistance(caster) / 24 * 1000); + returnSplinePoints[0] = at.GetPosition(); + returnSplinePoints[1] = at.GetPosition(); + returnSplinePoints[2] = caster.GetPosition(); + returnSplinePoints[3] = caster.GetPosition(); + + at.InitSplines(returnSplinePoints, (uint)(at.GetDistance(caster) / _maxTravelDistance * 1000)); + + task.Repeat(TimeSpan.FromMilliseconds(250)); - task.Repeat(TimeSpan.FromMilliseconds(250)); - } }); } }