mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spells: Fixed Charge
* Implemented Glyph of Blazing Charge * Implemented a way to compute spline position at any given point in time * Removed incorrect ProgressCurveId handling, it needs to apply to entire spline duration not to each segment separately Closes #19217
This commit is contained in:
5
sql/updates/world/master/2017_03_18_08_world.sql
Normal file
5
sql/updates/world/master/2017_03_18_08_world.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_warr_charge_effect','spell_warr_charge_drop_fire_periodic');
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(198337, 'spell_warr_charge_effect'),
|
||||
(218104, 'spell_warr_charge_effect'),
|
||||
(126661, 'spell_warr_charge_drop_fire_periodic');
|
||||
@@ -25,30 +25,25 @@
|
||||
|
||||
namespace Movement{
|
||||
|
||||
Location MoveSpline::ComputePosition() const
|
||||
Location MoveSpline::computePosition(int32 time_point, int32 point_index) const
|
||||
{
|
||||
ASSERT(Initialized());
|
||||
|
||||
float u = 1.0f;
|
||||
float u2 = 1.0f;
|
||||
int32 seg_time = spline.length(point_Idx, point_Idx+1);
|
||||
int32 seg_time = spline.length(point_index, point_index + 1);
|
||||
if (seg_time > 0)
|
||||
{
|
||||
u = (time_passed - spline.length(point_Idx)) / (float)seg_time;
|
||||
u2 = u;
|
||||
if (spell_effect_extra && spell_effect_extra->ProgressCurveId)
|
||||
u = sDB2Manager.GetCurveValueAt(spell_effect_extra->ProgressCurveId, u);
|
||||
}
|
||||
u = (time_point - spline.length(point_index)) / (float)seg_time;
|
||||
|
||||
Location c;
|
||||
c.orientation = initialOrientation;
|
||||
spline.evaluate_percent(point_Idx, u, c);
|
||||
spline.evaluate_percent(point_index, u, c);
|
||||
|
||||
if (splineflags.animation)
|
||||
;// MoveSplineFlag::Animation disables falling or parabolic movement
|
||||
else if (splineflags.parabolic)
|
||||
computeParabolicElevation(c.z, u2 /*progress without curve modifer is expected here*/);
|
||||
computeParabolicElevation(time_point, c.z);
|
||||
else if (splineflags.falling)
|
||||
computeFallElevation(c.z);
|
||||
computeFallElevation(time_point, c.z);
|
||||
|
||||
if (splineflags.done && facing.type != MONSTER_MOVE_NORMAL)
|
||||
{
|
||||
@@ -73,14 +68,38 @@ Location MoveSpline::ComputePosition() const
|
||||
return c;
|
||||
}
|
||||
|
||||
void MoveSpline::computeParabolicElevation(float& el, float u) const
|
||||
Location MoveSpline::ComputePosition() const
|
||||
{
|
||||
if (time_passed > effect_start_time)
|
||||
return computePosition(time_passed, point_Idx);
|
||||
}
|
||||
|
||||
Location MoveSpline::ComputePosition(int32 time_offset) const
|
||||
{
|
||||
int32 time_point = time_passed + time_offset;
|
||||
if (time_point >= Duration())
|
||||
return computePosition(Duration(), spline.last() - 1);
|
||||
if (time_point <= 0)
|
||||
return computePosition(0, spline.first());
|
||||
|
||||
// find point_index where spline.length(point_index) < time_point < spline.length(point_index + 1)
|
||||
int32 point_index = point_Idx;
|
||||
while (time_point >= spline.length(point_index + 1))
|
||||
++point_index;
|
||||
|
||||
while (time_point < spline.length(point_index))
|
||||
--point_index;
|
||||
|
||||
return computePosition(time_point, point_index);
|
||||
}
|
||||
|
||||
void MoveSpline::computeParabolicElevation(int32 time_point, float& el) const
|
||||
{
|
||||
if (time_point > effect_start_time)
|
||||
{
|
||||
float t_passedf = MSToSec(time_passed - effect_start_time);
|
||||
float t_passedf = MSToSec(time_point - effect_start_time);
|
||||
float t_durationf = MSToSec(Duration() - effect_start_time); //client use not modified duration here
|
||||
if (spell_effect_extra && spell_effect_extra->ParabolicCurveId)
|
||||
t_passedf *= sDB2Manager.GetCurveValueAt(spell_effect_extra->ParabolicCurveId, u);
|
||||
t_passedf *= sDB2Manager.GetCurveValueAt(spell_effect_extra->ParabolicCurveId, float(time_point) / Duration());
|
||||
|
||||
// -a*x*x + bx + c:
|
||||
//(dur * v3->z_acceleration * dt)/2 - (v3->z_acceleration * dt * dt)/2 + Z;
|
||||
@@ -88,9 +107,9 @@ void MoveSpline::computeParabolicElevation(float& el, float u) const
|
||||
}
|
||||
}
|
||||
|
||||
void MoveSpline::computeFallElevation(float& el) const
|
||||
void MoveSpline::computeFallElevation(int32 time_point, float& el) const
|
||||
{
|
||||
float z_now = spline.getPoint(spline.first()).z - Movement::computeFallElevation(MSToSec(time_passed), false);
|
||||
float z_now = spline.getPoint(spline.first()).z - Movement::computeFallElevation(MSToSec(time_point), false);
|
||||
float final_z = FinalDestination().z;
|
||||
el = std::max(z_now, final_z);
|
||||
}
|
||||
|
||||
@@ -86,8 +86,9 @@ namespace Movement
|
||||
|
||||
protected:
|
||||
MySpline::ControlArray const& getPath() const { return spline.getPoints(); }
|
||||
void computeParabolicElevation(float& el, float u) const;
|
||||
void computeFallElevation(float& el) const;
|
||||
Location computePosition(int32 time_point, int32 point_index) const;
|
||||
void computeParabolicElevation(int32 time_point, float& el) const;
|
||||
void computeFallElevation(int32 time_point, float& el) const;
|
||||
|
||||
UpdateResult _updateState(int32& ms_time_diff);
|
||||
int32 next_timestamp() const { return spline.length(point_Idx + 1); }
|
||||
@@ -125,6 +126,7 @@ namespace Movement
|
||||
}
|
||||
|
||||
Location ComputePosition() const;
|
||||
Location ComputePosition(int32 time_offset) const;
|
||||
|
||||
uint32 GetId() const { return m_Id; }
|
||||
bool Finalized() const { return splineflags.done; }
|
||||
|
||||
@@ -23,17 +23,25 @@
|
||||
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "SpellHistory.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellPackets.h"
|
||||
|
||||
enum WarriorSpells
|
||||
{
|
||||
SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND = 50622,
|
||||
SPELL_WARRIOR_BLOODTHIRST_HEAL = 117313,
|
||||
SPELL_WARRIOR_CHARGE = 34846,
|
||||
SPELL_WARRIOR_CHARGE_EFFECT = 218104,
|
||||
SPELL_WARRIOR_CHARGE_EFFECT_BLAZING_TRAIL = 198337,
|
||||
SPELL_WARRIOR_CHARGE_PAUSE_RAGE_DECAY = 109128,
|
||||
SPELL_WARRIOR_CHARGE_ROOT_EFFECT = 105771,
|
||||
SPELL_WARRIOR_CHARGE_SLOW_EFFECT = 236027,
|
||||
SPELL_WARRIOR_COLOSSUS_SMASH = 86346,
|
||||
SPELL_WARRIOR_EXECUTE = 20647,
|
||||
SPELL_WARRIOR_GLYPH_OF_THE_BLAZING_TRAIL = 123779,
|
||||
SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP = 159708,
|
||||
SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP_BUFF = 133278,
|
||||
SPELL_WARRIOR_HEROIC_LEAP_JUMP = 178368,
|
||||
@@ -66,6 +74,11 @@ enum WarriorSpells
|
||||
SPELL_WARRIOR_VICTORY_RUSH_HEAL = 118779,
|
||||
};
|
||||
|
||||
enum WarriorMisc
|
||||
{
|
||||
SPELL_VISUAL_BLAZING_CHARGE = 26423
|
||||
};
|
||||
|
||||
// 23881 - Bloodthirst
|
||||
class spell_warr_bloodthirst : public SpellScriptLoader
|
||||
{
|
||||
@@ -101,7 +114,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Updated 4.3.4
|
||||
// 100 - Charge
|
||||
class spell_warr_charge : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
@@ -113,27 +126,25 @@ class spell_warr_charge : public SpellScriptLoader
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT) ||
|
||||
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF) ||
|
||||
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_CHARGE))
|
||||
return false;
|
||||
return true;
|
||||
return ValidateSpellInfo
|
||||
({
|
||||
SPELL_WARRIOR_CHARGE_EFFECT,
|
||||
SPELL_WARRIOR_CHARGE_EFFECT_BLAZING_TRAIL
|
||||
});
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
int32 chargeBasePoints0 = GetEffectValue();
|
||||
Unit* caster = GetCaster();
|
||||
caster->CastCustomSpell(caster, SPELL_WARRIOR_CHARGE, &chargeBasePoints0, NULL, NULL, true);
|
||||
uint32 spellId = SPELL_WARRIOR_CHARGE_EFFECT;
|
||||
if (GetCaster()->HasAura(SPELL_WARRIOR_GLYPH_OF_THE_BLAZING_TRAIL))
|
||||
spellId = SPELL_WARRIOR_CHARGE_EFFECT_BLAZING_TRAIL;
|
||||
|
||||
// Juggernaut crit bonus
|
||||
if (caster->HasAura(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT))
|
||||
caster->CastSpell(caster, SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF, true);
|
||||
GetCaster()->CastSpell(GetHitUnit(), spellId, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_warr_charge_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_warr_charge_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -143,6 +154,92 @@ class spell_warr_charge : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
// 126661 - Warrior Charge Drop Fire Periodic
|
||||
class spell_warr_charge_drop_fire_periodic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_warr_charge_drop_fire_periodic() : SpellScriptLoader("spell_warr_charge_drop_fire_periodic") { }
|
||||
|
||||
class spell_warr_charge_drop_fire_periodic_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_warr_charge_drop_fire_periodic_AuraScript);
|
||||
|
||||
void DropFireVisual(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (GetTarget()->IsSplineEnabled())
|
||||
{
|
||||
for (uint32 i = 0; i < 5; ++i)
|
||||
{
|
||||
int32 timeOffset = 6 * i * aurEff->GetPeriod() / 25;
|
||||
WorldPackets::Spells::PlaySpellVisual playSpellVisual;
|
||||
playSpellVisual.Source = GetTarget()->GetGUID();
|
||||
playSpellVisual.TargetPostion = static_cast<G3D::Vector3>(GetTarget()->movespline->ComputePosition(timeOffset)); // slices
|
||||
playSpellVisual.SpellVisualID = SPELL_VISUAL_BLAZING_CHARGE;
|
||||
playSpellVisual.TravelSpeed = 1.0f;
|
||||
playSpellVisual.MissReason = 0;
|
||||
playSpellVisual.ReflectStatus = 0;
|
||||
playSpellVisual.Orientation = 0.0f;
|
||||
playSpellVisual.SpeedAsTime = true;
|
||||
GetTarget()->SendMessageToSet(playSpellVisual.Write(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_warr_charge_drop_fire_periodic_AuraScript::DropFireVisual, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_warr_charge_drop_fire_periodic_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 198337 - Charge Effect (dropping Blazing Trail)
|
||||
// 218104 - Charge Effect
|
||||
class spell_warr_charge_effect : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_warr_charge_effect() : SpellScriptLoader("spell_warr_charge_effect") { }
|
||||
|
||||
class spell_warr_charge_effect_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_warr_charge_effect_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo
|
||||
({
|
||||
SPELL_WARRIOR_CHARGE_PAUSE_RAGE_DECAY,
|
||||
SPELL_WARRIOR_CHARGE_ROOT_EFFECT,
|
||||
SPELL_WARRIOR_CHARGE_SLOW_EFFECT
|
||||
});
|
||||
}
|
||||
|
||||
void HandleCharge(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetHitUnit();
|
||||
caster->CastCustomSpell(SPELL_WARRIOR_CHARGE_PAUSE_RAGE_DECAY, SPELLVALUE_BASE_POINT0, 0, caster, true);
|
||||
caster->CastSpell(target, SPELL_WARRIOR_CHARGE_ROOT_EFFECT, true);
|
||||
caster->CastSpell(target, SPELL_WARRIOR_CHARGE_SLOW_EFFECT, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectLaunchTarget += SpellEffectFn(spell_warr_charge_effect_SpellScript::HandleCharge, EFFECT_0, SPELL_EFFECT_CHARGE);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_warr_charge_effect_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
/// Updated 4.3.4
|
||||
class spell_warr_concussion_blow : public SpellScriptLoader
|
||||
{
|
||||
@@ -444,7 +541,7 @@ class spell_warr_last_stand : public SpellScriptLoader
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
int32 healthModSpellBasePoints0 = int32(caster->CountPctFromMaxHealth(GetEffectValue()));
|
||||
caster->CastCustomSpell(caster, SPELL_WARRIOR_LAST_STAND_TRIGGERED, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
|
||||
caster->CastCustomSpell(caster, SPELL_WARRIOR_LAST_STAND_TRIGGERED, &healthModSpellBasePoints0, nullptr, nullptr, true, nullptr);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -524,7 +621,7 @@ class spell_warr_rallying_cry : public SpellScriptLoader
|
||||
{
|
||||
int32 basePoints0 = int32(GetHitUnit()->CountPctFromMaxHealth(GetEffectValue()));
|
||||
|
||||
GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_WARRIOR_RALLYING_CRY, &basePoints0, NULL, NULL, true);
|
||||
GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_WARRIOR_RALLYING_CRY, &basePoints0, nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -603,7 +700,7 @@ class spell_warr_retaliation : public SpellScriptLoader
|
||||
void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARRIOR_RETALIATION_DAMAGE, true, NULL, aurEff);
|
||||
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARRIOR_RETALIATION_DAMAGE, true, nullptr, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -725,7 +822,7 @@ class spell_warr_second_wind_proc : public SpellScriptLoader
|
||||
if (!spellId)
|
||||
return;
|
||||
|
||||
GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff);
|
||||
GetTarget()->CastSpell(GetTarget(), spellId, true, nullptr, aurEff);
|
||||
|
||||
}
|
||||
|
||||
@@ -930,12 +1027,12 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader
|
||||
if (spellInfo && (spellInfo->Id == SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND || (spellInfo->Id == SPELL_WARRIOR_EXECUTE && !_procTarget->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))))
|
||||
{
|
||||
// If triggered by Execute (while target is not under 20% hp) or Bladestorm deals normalized weapon damage
|
||||
GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2, true, NULL, aurEff);
|
||||
GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2, true, nullptr, aurEff);
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 damage = eventInfo.GetDamageInfo()->GetDamage();
|
||||
GetTarget()->CastCustomSpell(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1, SPELLVALUE_BASE_POINT0, damage, _procTarget, true, NULL, aurEff);
|
||||
GetTarget()->CastCustomSpell(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1, SPELLVALUE_BASE_POINT0, damage, _procTarget, true, nullptr, aurEff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1057,7 +1154,7 @@ class spell_warr_vigilance : public SpellScriptLoader
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
_procTarget = NULL;
|
||||
_procTarget = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1139,6 +1236,8 @@ void AddSC_warrior_spell_scripts()
|
||||
{
|
||||
new spell_warr_bloodthirst();
|
||||
new spell_warr_charge();
|
||||
new spell_warr_charge_drop_fire_periodic();
|
||||
new spell_warr_charge_effect();
|
||||
new spell_warr_concussion_blow();
|
||||
new spell_warr_execute();
|
||||
new spell_warr_heroic_leap();
|
||||
|
||||
Reference in New Issue
Block a user