diff options
author | Teleqraph <nyrdeveloper@gmail.com> | 2022-08-02 22:25:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-02 22:25:07 +0200 |
commit | 6b944b9e56969fb465449ecda7c8561696c06833 (patch) | |
tree | 11dbd85c310e6e857999bf52e83d78bf46a0cc35 /src | |
parent | 22625e82ba994ccf197592f71b877a14e2c53390 (diff) |
Scripts/Spells: Divine Star (Priest) fixed (#28112)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 118 |
1 files changed, 117 insertions, 1 deletions
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 3f66eacd761..67fc78a1770 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -23,14 +23,18 @@ #include "ScriptMgr.h" #include "AreaTriggerAI.h" +#include "G3DPosition.hpp" #include "GridNotifiers.h" -#include "ObjectAccessor.h" #include "Log.h" +#include "MoveSplineInitArgs.h" +#include "ObjectAccessor.h" +#include "PathGenerator.h" #include "Player.h" #include "SpellAuraEffects.h" #include "SpellHistory.h" #include "SpellMgr.h" #include "SpellScript.h" +#include "TaskScheduler.h" enum PriestSpells { @@ -45,6 +49,8 @@ enum PriestSpells SPELL_PRIEST_BODY_AND_SOUL = 64129, SPELL_PRIEST_BODY_AND_SOUL_SPEED = 65081, SPELL_PRIEST_DIVINE_BLESSING = 40440, + SPELL_PRIEST_DIVINE_STAR_DAMAGE = 122128, + SPELL_PRIEST_DIVINE_STAR_HEAL = 110745, SPELL_PRIEST_DIVINE_WRATH = 40441, SPELL_PRIEST_FLASH_HEAL = 2061, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, @@ -345,6 +351,115 @@ class spell_pri_divine_hymn : public SpellScript } }; +// 110744 - Divine Star +struct areatrigger_pri_divine_star : AreaTriggerAI +{ + areatrigger_pri_divine_star(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) {} + + void OnInitialize() override + { + if (Unit* caster = at->GetCaster()) + { + _casterCurrentPosition = caster->GetPosition(); + + // Note: max. distance at which the Divine Star can travel to is 24 yards. + float divineStarXOffSet = 24.0f; + + Position destPos = _casterCurrentPosition; + at->MovePositionToFirstCollision(destPos, divineStarXOffSet, 0.0f); + + PathGenerator firstPath(at); + firstPath.CalculatePath(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ(), false); + + G3D::Vector3 const& endPoint = firstPath.GetPath().back(); + + // Note: it takes 1000ms to reach 24 yards, so it takes 41.67ms to run 1 yard. + at->InitSplines(firstPath.GetPath(), at->GetDistance(endPoint.x, endPoint.y, endPoint.z) * 41.67f); + } + } + + void OnUpdate(uint32 diff) override + { + _scheduler.Update(diff); + } + + void OnUnitEnter(Unit* unit) override + { + if (Unit* caster = at->GetCaster()) + { + if (std::find(_affectedUnits.begin(), _affectedUnits.end(), unit->GetGUID()) == _affectedUnits.end()) + { + if (caster->IsValidAttackTarget(unit)) + caster->CastSpell(unit, SPELL_PRIEST_DIVINE_STAR_DAMAGE, CastSpellExtraArgs(TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS))); + else if (caster->IsValidAssistTarget(unit)) + caster->CastSpell(unit, SPELL_PRIEST_DIVINE_STAR_HEAL, CastSpellExtraArgs(TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS))); + + _affectedUnits.push_back(unit->GetGUID()); + } + } + } + + void OnUnitExit(Unit* unit) override + { + // Note: this ensures any unit receives a second hit if they happen to be inside the AT when Divine Star starts its return path. + if (Unit* caster = at->GetCaster()) + { + if (std::find(_affectedUnits.begin(), _affectedUnits.end(), unit->GetGUID()) == _affectedUnits.end()) + { + if (caster->IsValidAttackTarget(unit)) + caster->CastSpell(unit, SPELL_PRIEST_DIVINE_STAR_DAMAGE, CastSpellExtraArgs(TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS))); + else if (caster->IsValidAssistTarget(unit)) + caster->CastSpell(unit, SPELL_PRIEST_DIVINE_STAR_HEAL, CastSpellExtraArgs(TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS))); + + _affectedUnits.push_back(unit->GetGUID()); + } + } + } + + void OnDestinationReached() override + { + Unit* caster = at->GetCaster(); + if (!caster) + return; + + if (at->GetDistance(_casterCurrentPosition) > 0.05f) + { + _affectedUnits.clear(); + + ReturnToCaster(); + } + else + at->Remove(); + } + + void ReturnToCaster() + { + _scheduler.Schedule(0ms, [this](TaskContext task) + { + if (Unit* caster = at->GetCaster()) + { + _casterCurrentPosition = caster->GetPosition(); + + Movement::PointsArray returnSplinePoints; + + returnSplinePoints.push_back(PositionToVector3(at)); + returnSplinePoints.push_back(PositionToVector3(at)); + returnSplinePoints.push_back(PositionToVector3(caster)); + returnSplinePoints.push_back(PositionToVector3(caster)); + + at->InitSplines(returnSplinePoints, at->GetDistance(caster) / 24 * 1000); + + task.Repeat(250ms); + } + }); + } + +private: + TaskScheduler _scheduler; + Position _casterCurrentPosition; + std::vector<ObjectGuid> _affectedUnits; +}; + // 47788 - Guardian Spirit class spell_pri_guardian_spirit : public AuraScript { @@ -1494,6 +1609,7 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_atonement); RegisterSpellScript(spell_pri_atonement_triggered); RegisterSpellScript(spell_pri_divine_hymn); + RegisterAreaTriggerAI(areatrigger_pri_divine_star); RegisterSpellScript(spell_pri_guardian_spirit); RegisterAreaTriggerAI(areatrigger_pri_halo); RegisterSpellScript(spell_pri_holy_words); |