Scripts/Spells: Divine Star (Priest) fixed (#28112)

This commit is contained in:
Teleqraph
2022-08-02 22:25:07 +02:00
committed by GitHub
parent 22625e82ba
commit 6b944b9e56
2 changed files with 118 additions and 1 deletions

View File

@@ -0,0 +1 @@
UPDATE `areatrigger_create_properties` SET `ScriptName`='areatrigger_pri_divine_star', `VerifiedBuild`=44325 WHERE `Id`=2148;

View File

@@ -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);