diff options
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 14 | ||||
-rwxr-xr-x | src/server/game/Movement/MotionMaster.h | 2 | ||||
-rwxr-xr-x | src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Movement/MovementGenerators/PointMovementGenerator.h | 2 | ||||
-rw-r--r-- | src/server/game/Movement/PathGenerator.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Movement/PathGenerator.h | 13 | ||||
-rwxr-xr-x | src/server/game/Spells/Spell.cpp | 20 | ||||
-rwxr-xr-x | src/server/game/Spells/Spell.h | 2 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellEffects.cpp | 26 |
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); |