aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Movement/MotionMaster.cpp14
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp7
-rw-r--r--src/server/game/Movement/MovementGenerators/PointMovementGenerator.h2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp7
-rw-r--r--src/server/game/Movement/PathGenerator.h13
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp20
-rwxr-xr-xsrc/server/game/Spells/Spell.h2
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp26
9 files changed, 69 insertions, 24 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 2ad8028ca4f..d7bf433677c 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -340,7 +340,7 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa
_owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + M_PI);
Movement::MoveSplineInit init(_owner);
- init.MoveTo(x,y,z);
+ init.MoveTo(x, y, z);
init.SetParabolic(max_height,0);
init.SetOrientationFixed(true);
init.SetVelocity(speedXY);
@@ -423,6 +423,18 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id,
}
}
+void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id)
+{
+ Vector3 dest = path.getActualEndPosition();
+
+ MoveCharge(dest.x, dest.y, dest.z);
+
+ Movement::MoveSplineInit init(_owner);
+ init.MovebyPath(path.getPath());
+ init.SetVelocity(speed);
+ init.Launch();
+}
+
void MotionMaster::MoveSeekAssistance(float x, float y, float z)
{
if (_owner->GetTypeId() == TYPEID_PLAYER)
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 16accff2ab4..d59ec83e615 100755
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -26,6 +26,7 @@
class MovementGenerator;
class Unit;
+class PathGenerator;
// Creature Entry ID used for waypoints show, visible only for GMs
#define VISUAL_WAYPOINT 1
@@ -161,6 +162,7 @@ class MotionMaster //: private std::stack<MovementGenerator *>
void MoveTakeoff(uint32 id, Position const& pos);
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false);
+ void MoveCharge(PathGenerator path, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE);
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
void MoveJumpTo(float angle, float speedXY, float speedZ);
void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = 0);
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index 20f1c3a29e9..c022de31869 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -33,7 +33,10 @@ void PointMovementGenerator<T>::Initialize(T* unit)
unit->StopMoving();
unit->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
- i_recalculateSpeed = false;
+
+ if (id == EVENT_CHARGE)
+ return;
+
Movement::MoveSplineInit init(unit);
init.MoveTo(i_x, i_y, i_z, m_generatePath);
if (speed > 0.0f)
@@ -55,7 +58,7 @@ bool PointMovementGenerator<T>::Update(T* unit, const uint32& /*diff*/)
unit->AddUnitState(UNIT_STATE_ROAMING_MOVE);
- if (i_recalculateSpeed && !unit->movespline->Finalized())
+ if (id != EVENT_CHARGE && i_recalculateSpeed && !unit->movespline->Finalized())
{
i_recalculateSpeed = false;
Movement::MoveSplineInit init(unit);
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
index 4111690627e..e01ced758a3 100644
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
@@ -27,7 +27,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG
{
public:
PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id),
- i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed) {}
+ i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed), i_recalculateSpeed(false) {}
void Initialize(T*);
void Finalize(T*);
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 4d7707020e1..a02eb0a9a84 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -456,6 +456,13 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
m_type = PATHFIND_NOPATH;
return;
}
+ else if (pointCount == m_pointPathLimit)
+ {
+ sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d\n", pointCount, m_pointPathLimit);
+ BuildShortcut();
+ m_type = PATHFIND_SHORT;
+ return;
+ }
m_pathPoints.resize(pointCount);
for (uint32 i = 0; i < pointCount; ++i)
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index a0d925cb11f..ac163f43be5 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -43,12 +43,13 @@ class Unit;
enum PathType
{
- PATHFIND_BLANK = 0x0000, // path not built yet
- PATHFIND_NORMAL = 0x0001, // normal path
- PATHFIND_SHORTCUT = 0x0002, // travel through obstacles, terrain, air, etc (old behavior)
- PATHFIND_INCOMPLETE = 0x0004, // we have partial path to follow - getting closer to target
- PATHFIND_NOPATH = 0x0008, // no valid path at all or error in generating one
- PATHFIND_NOT_USING_PATH = 0x0010 // used when we are either flying/swiming or on map w/o mmaps
+ PATHFIND_BLANK = 0x00, // path not built yet
+ PATHFIND_NORMAL = 0x01, // normal path
+ PATHFIND_SHORTCUT = 0x02, // travel through obstacles, terrain, air, etc (old behavior)
+ PATHFIND_INCOMPLETE = 0x04, // we have partial path to follow - getting closer to target
+ PATHFIND_NOPATH = 0x08, // no valid path at all or error in generating one
+ PATHFIND_NOT_USING_PATH = 0x10, // used when we are either flying/swiming or on map w/o mmaps
+ PATHFIND_SHORT = 0x20, // path is longer or equal to its limited path length
};
class PathGenerator
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 79e6404f73e..6e056bf59f8 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -490,7 +490,7 @@ SpellValue::SpellValue(SpellInfo const* proto)
Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID, bool skipCheck) :
m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
-, m_spellValue(new SpellValue(m_spellInfo))
+, m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster))
{
m_customError = SPELL_CUSTOM_ERROR_NONE;
m_skipCheck = skipCheck;
@@ -610,6 +610,7 @@ Spell::~Spell()
if (m_caster && m_caster->GetTypeId() == TYPEID_PLAYER)
ASSERT(m_caster->ToPlayer()->m_spellModTakingSpell != this);
+
delete m_spellValue;
CheckEffectExecuteData();
@@ -5143,8 +5144,25 @@ SpellCastResult Spell::CheckCast(bool strict)
if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
m_caster->RemoveMovementImpairingAuras();
}
+
if (m_caster->HasUnitState(UNIT_STATE_ROOT))
return SPELL_FAILED_ROOTED;
+
+ Unit* target = m_targets.GetUnitTarget();
+
+ if (!target)
+ return SPELL_FAILED_DONT_REPORT;
+
+ Position pos;
+ target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
+ target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster));
+
+ m_preGeneratedPath.setPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f);
+ m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize());
+
+ if (m_preGeneratedPath.getPathType() & PATHFIND_SHORT)
+ return SPELL_FAILED_OUT_OF_RANGE;
+
break;
}
case SPELL_EFFECT_SKINNING:
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 1376b0fbd40..22495b3f1f0 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -23,6 +23,7 @@
#include "SharedDefines.h"
#include "ObjectMgr.h"
#include "SpellInfo.h"
+#include "PathGenerator.h"
class Unit;
class Player;
@@ -666,6 +667,7 @@ class Spell
bool m_skipCheck;
uint8 m_auraScaleMask;
+ PathGenerator m_preGeneratedPath;
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS];
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 3637bb18049..1aa2ca0176b 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -63,6 +63,7 @@
#include "GameObjectAI.h"
#include "AccountMgr.h"
#include "InstanceScript.h"
+#include "PathGenerator.h"
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
{
@@ -5133,25 +5134,24 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/)
void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
{
+ if (!unitTarget)
+ return;
+
if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
{
- if (!unitTarget)
- return;
-
- float angle = unitTarget->GetRelativeAngle(m_caster);
- Position pos;
-
- unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
- unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetObjectSize(), angle);
-
- m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + unitTarget->GetObjectSize());
+ if (m_preGeneratedPath.getPathType() & PATHFIND_NOPATH)
+ {
+ Position pos;
+ unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
+ unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetObjectSize(), unitTarget->GetRelativeAngle(m_caster));
+ m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
+ }
+ else
+ m_caster->GetMotionMaster()->MoveCharge(m_preGeneratedPath);
}
if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET)
{
- if (!unitTarget)
- return;
-
// not all charge effects used in negative spells
if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->Attack(unitTarget, true);