aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2017-02-18 21:55:28 +0100
committerShauren <shauren.trinity@gmail.com>2017-02-18 21:55:28 +0100
commit5e437f5d3d500b735eb623914a6cfc6bcb35247b (patch)
tree19544b0c8685de73eaf6772b70b7721ec2b52623 /src
parent255dd29562ae42a73c5947c2a8907faac888af31 (diff)
Core/Movement: Implement SpellEffectExtraData curve modifiers
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp19
-rw-r--r--src/server/game/Movement/MotionMaster.h18
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp21
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.h3
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h7
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInitArgs.h9
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp25
-rw-r--r--src/server/game/Spells/SpellEffects.cpp9
10 files changed, 93 insertions, 22 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3d61e5683e2..e39962e6da3 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -14077,7 +14077,7 @@ void Unit::SendMoveKnockBack(Player* player, float speedXY, float speedZ, float
player->GetSession()->SendPacket(moveKnockBack.Write());
}
-void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
+void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/)
{
Player* player = ToPlayer();
if (!player)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 68042afd6c2..0e17db6b544 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1683,7 +1683,7 @@ class TC_GAME_API Unit : public WorldObject
void UpdateHeight(float newZ);
void SendMoveKnockBack(Player* player, float speedXY, float speedZ, float vcos, float vsin);
- void KnockbackFrom(float x, float y, float speedXY, float speedZ);
+ void KnockbackFrom(float x, float y, float speedXY, float speedZ, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
void JumpTo(float speedXY, float speedZ, bool forward = true);
void JumpTo(WorldObject* obj, float speedZ, bool withOrientation = false);
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 6756463283f..22f06801640 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -345,7 +345,7 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos)
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
}
-void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
+void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/)
{
//this function may make players fall below map
if (_owner->GetTypeId() == TYPEID_PLAYER)
@@ -366,6 +366,9 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa
init.SetParabolic(max_height, 0);
init.SetOrientationFixed(true);
init.SetVelocity(speedXY);
+ if (spellEffectExtraData)
+ init.SetSpellEffectExtraData(*spellEffectExtraData);
+
init.Launch();
Mutate(new EffectMovementGenerator(0), MOTION_SLOT_CONTROLLED);
}
@@ -384,7 +387,8 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
MoveJump(x, y, z, 0.0f, speedXY, speedZ);
}
-void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id /*= EVENT_JUMP*/, bool hasOrientation /* = false*/, uint32 arrivalSpellId /*= 0*/, ObjectGuid const& arrivalSpellTargetGuid /*= ObjectGuid::Empty*/)
+void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id /*= EVENT_JUMP*/, bool hasOrientation /* = false*/,
+ JumpArrivalCastArgs const* arrivalCast /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/)
{
TC_LOG_DEBUG("misc", "Unit (%s) jumps to point (X: %f Y: %f Z: %f).", _owner->GetGUID().ToString().c_str(), x, y, z);
if (speedXY <= 0.1f)
@@ -399,7 +403,18 @@ void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, f
init.SetVelocity(speedXY);
if (hasOrientation)
init.SetFacing(o);
+ if (spellEffectExtraData)
+ init.SetSpellEffectExtraData(*spellEffectExtraData);
init.Launch();
+
+ uint32 arrivalSpellId = 0;
+ ObjectGuid arrivalSpellTargetGuid;
+ if (arrivalCast)
+ {
+ arrivalSpellId = arrivalCast->SpellId;
+ arrivalSpellTargetGuid = arrivalCast->Target;
+ }
+
Mutate(new EffectMovementGenerator(id, arrivalSpellId, arrivalSpellTargetGuid), MOTION_SLOT_CONTROLLED);
}
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 905dcde580e..7e2d6a47e56 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -28,6 +28,10 @@
class MovementGenerator;
class Unit;
class PathGenerator;
+namespace Movement
+{
+ struct SpellEffectExtraData;
+}
// Creature Entry ID used for waypoints show, visible only for GMs
#define VISUAL_WAYPOINT 1
@@ -77,6 +81,12 @@ enum RotateDirection
ROTATE_DIRECTION_RIGHT
};
+struct JumpArrivalCastArgs
+{
+ uint32 SpellId;
+ ObjectGuid Target;
+};
+
// assume it is 25 yard per 0.6 second
#define SPEED_CHARGE 42.0f
@@ -186,13 +196,13 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false);
void MoveCharge(PathGenerator const& path, float speed = SPEED_CHARGE);
- void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
+ void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
void MoveJumpTo(float angle, float speedXY, float speedZ);
- void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, uint32 arrivalSpellId = 0, ObjectGuid const& arrivalSpellTargetGuid = ObjectGuid::Empty)
+ void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr)
{
- MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), speedXY, speedZ, id, hasOrientation, arrivalSpellId, arrivalSpellTargetGuid);
+ MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), speedXY, speedZ, id, hasOrientation, arrivalCast, spellEffectExtraData);
}
- void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, uint32 arrivalSpellId = 0, ObjectGuid const& arrivalSpellTargetGuid = ObjectGuid::Empty);
+ void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount);
void MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk);
void MoveSmoothPath(uint32 pointId, Movement::PointsArray const& points, bool walk);
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
index d4e3cbff60d..a9912745435 100644
--- a/src/server/game/Movement/Spline/MoveSpline.cpp
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -19,6 +19,7 @@
#include "MoveSpline.h"
#include "Log.h"
#include "Creature.h"
+#include "DB2Stores.h"
#include <sstream>
@@ -28,10 +29,16 @@ Location MoveSpline::ComputePosition() const
{
ASSERT(Initialized());
- float u = 1.f;
+ float u = 1.0f;
+ float u2 = 1.0f;
int32 seg_time = spline.length(point_Idx, point_Idx+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);
+ }
Location c;
c.orientation = initialOrientation;
spline.evaluate_percent(point_Idx, u, c);
@@ -39,7 +46,7 @@ Location MoveSpline::ComputePosition() const
if (splineflags.animation)
;// MoveSplineFlag::Animation disables falling or parabolic movement
else if (splineflags.parabolic)
- computeParabolicElevation(c.z);
+ computeParabolicElevation(c.z, u2 /*progress without curve modifer is expected here*/);
else if (splineflags.falling)
computeFallElevation(c.z);
@@ -66,12 +73,14 @@ Location MoveSpline::ComputePosition() const
return c;
}
-void MoveSpline::computeParabolicElevation(float& el) const
+void MoveSpline::computeParabolicElevation(float& el, float u) const
{
if (time_passed > effect_start_time)
{
float t_passedf = MSToSec(time_passed - 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);
// -a*x*x + bx + c:
//(dur * v3->z_acceleration * dt)/2 - (v3->z_acceleration * dt * dt)/2 + Z;
@@ -165,6 +174,7 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)
time_passed = 0;
vertical_acceleration = 0.f;
effect_start_time = 0;
+ spell_effect_extra = args.spellEffectExtra;
splineIsFacingOnly = args.path.size() == 2 && args.facing.type != MONSTER_MOVE_NORMAL && ((args.path[1] - args.path[0]).length() < 0.1f);
// Check if its a stop spline
@@ -210,6 +220,11 @@ bool MoveSplineInitArgs::Validate(Unit* unit) const
CHECK(velocity > 0.01f);
CHECK(time_perc >= 0.f && time_perc <= 1.f);
CHECK(_checkPathLengths());
+ if (spellEffectExtra)
+ {
+ CHECK(!spellEffectExtra->ProgressCurveId || sCurveStore.LookupEntry(spellEffectExtra->ProgressCurveId));
+ CHECK(!spellEffectExtra->ParabolicCurveId || sCurveStore.LookupEntry(spellEffectExtra->ParabolicCurveId));
+ }
return true;
#undef CHECK
}
diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h
index f4f1e07cbe0..672c42ac3ab 100644
--- a/src/server/game/Movement/Spline/MoveSpline.h
+++ b/src/server/game/Movement/Spline/MoveSpline.h
@@ -80,12 +80,13 @@ namespace Movement
int32 effect_start_time;
int32 point_Idx;
int32 point_Idx_offset;
+ Optional<SpellEffectExtraData> spell_effect_extra;
void init_spline(const MoveSplineInitArgs& args);
protected:
MySpline::ControlArray const& getPath() const { return spline.getPoints(); }
- void computeParabolicElevation(float& el) const;
+ void computeParabolicElevation(float& el, float u) const;
void computeFallElevation(float& el) const;
UpdateResult _updateState(int32& ms_time_diff);
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index f0b5e9aaac0..c873013405a 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -146,6 +146,8 @@ namespace Movement
*/
void SetVelocity(float velocity);
+ void SetSpellEffectExtraData(SpellEffectExtraData const& spellEffectExtraData);
+
PointsArray& Path() { return args.path; }
/* Disables transport coordinate transformations for cases where raw offsets are available
@@ -204,5 +206,10 @@ namespace Movement
}
inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; }
+
+ inline void MoveSplineInit::SetSpellEffectExtraData(SpellEffectExtraData const& spellEffectExtraData)
+ {
+ args.spellEffectExtra = spellEffectExtraData;
+ }
}
#endif // TRINITYSERVER_MOVESPLINEINIT_H
diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
index 60cb4db8b55..fc5b82102cd 100644
--- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h
+++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
@@ -40,6 +40,14 @@ namespace Movement
FacingInfo() : angle(0.0f), type(MONSTER_MOVE_NORMAL) { }
};
+ struct SpellEffectExtraData
+ {
+ ObjectGuid Target;
+ uint32 SpellVisualId = 0;
+ uint32 ProgressCurveId = 0;
+ uint32 ParabolicCurveId = 0;
+ };
+
struct MoveSplineInitArgs
{
MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0), velocity(0.f),
@@ -58,6 +66,7 @@ namespace Movement
float time_perc;
uint32 splineId;
float initialOrientation;
+ Optional<SpellEffectExtraData> spellEffectExtra;
bool HasVelocity;
bool TransformForTransport;
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 3156a8516b3..20405fbd097 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -302,7 +302,7 @@ void WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(::
data.WriteBits(moveSpline.getPath().size(), 16);
data.WriteBits(uint8(moveSpline.spline.mode()), 2); // Mode
data.WriteBit(0); // HasSplineFilter
- data.WriteBit(0); // HasSpellEffectExtraData
+ data.WriteBit(moveSpline.spell_effect_extra.is_initialized()); // HasSpellEffectExtraData
data.FlushBits();
//if (HasSplineFilterKey)
@@ -341,13 +341,13 @@ void WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(::
data.append<G3D::Vector3>(&moveSpline.getPath()[0], moveSpline.getPath().size());
- //if (HasSpellEffectExtraData)
- //{
- // data << ObjectGuid(TargetGUID);
- // data << uint32(SpellVisualID);
- // data << uint32(ProgressCurveID);
- // data << uint32(ParabolicCurveID);
- //}
+ if (moveSpline.spell_effect_extra)
+ {
+ data << moveSpline.spell_effect_extra->Target;
+ data << uint32(moveSpline.spell_effect_extra->SpellVisualId);
+ data << uint32(moveSpline.spell_effect_extra->ProgressCurveId);
+ data << uint32(moveSpline.spell_effect_extra->ParabolicCurveId);
+ }
}
}
@@ -381,6 +381,15 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS
if (splineFlags.fadeObject)
movementSpline.SpecialTime = moveSpline.effect_start_time;
+ if (moveSpline.spell_effect_extra)
+ {
+ movementSpline.SpellEffectExtraData = boost::in_place();
+ movementSpline.SpellEffectExtraData->TargetGUID = moveSpline.spell_effect_extra->Target;
+ movementSpline.SpellEffectExtraData->SpellVisualID = moveSpline.spell_effect_extra->SpellVisualId;
+ movementSpline.SpellEffectExtraData->ProgressCurveID = moveSpline.spell_effect_extra->ProgressCurveId;
+ movementSpline.SpellEffectExtraData->ParabolicCurveID = moveSpline.spell_effect_extra->ParabolicCurveId;
+ }
+
::Movement::Spline<int32> const& spline = moveSpline.spline;
std::vector<G3D::Vector3> const& array = spline.getPoints();
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index f7d0f9adb38..378721b83ff 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -868,7 +868,10 @@ void Spell::EffectJump(SpellEffIndex /*effIndex*/)
float speedXY, speedZ;
CalculateJumpSpeeds(effectInfo, m_caster->GetExactDist2d(x, y), speedXY, speedZ);
- m_caster->GetMotionMaster()->MoveJump(x, y, z, 0.0f, speedXY, speedZ, EVENT_JUMP, false, effectInfo->TriggerSpell, unitTarget->GetGUID());
+ JumpArrivalCastArgs arrivalCast;
+ arrivalCast.SpellId = effectInfo->TriggerSpell;
+ arrivalCast.Target = unitTarget->GetGUID();
+ m_caster->GetMotionMaster()->MoveJump(x, y, z, 0.0f, speedXY, speedZ, EVENT_JUMP, false, &arrivalCast);
}
void Spell::EffectJumpDest(SpellEffIndex /*effIndex*/)
@@ -884,7 +887,9 @@ void Spell::EffectJumpDest(SpellEffIndex /*effIndex*/)
float speedXY, speedZ;
CalculateJumpSpeeds(effectInfo, m_caster->GetExactDist2d(destTarget), speedXY, speedZ);
- m_caster->GetMotionMaster()->MoveJump(*destTarget, speedXY, speedZ, EVENT_JUMP, !m_targets.GetObjectTargetGUID().IsEmpty(), effectInfo->TriggerSpell);
+ JumpArrivalCastArgs arrivalCast;
+ arrivalCast.SpellId = effectInfo->TriggerSpell;
+ m_caster->GetMotionMaster()->MoveJump(*destTarget, speedXY, speedZ, EVENT_JUMP, !m_targets.GetObjectTargetGUID().IsEmpty(), &arrivalCast);
}
void Spell::CalculateJumpSpeeds(SpellEffectInfo const* effInfo, float dist, float& speedXY, float& speedZ)