From b12f19f066bfd0e968251b3ec77bae2dde40616b Mon Sep 17 00:00:00 2001 From: treeston Date: Wed, 21 Sep 2016 16:22:12 +0200 Subject: Movement/SplineChain: Streamline the script workflow for resume info a bit, provide static method that does all the ugly pointer casts for you. Also prevent a nullptr dereference crash if scripts mishandle motionmaster, and canonize Chain == nullptr to signify "no resume info". (cherry picked from commit d3214a0012cf93a5e66d1dc405ac90c4abc1b8c3) d3214a0 follow-up for code style. (cherry picked from commit 4deeee66bda390d2b35b64aaeb5924dac4170e10) --- src/server/game/Movement/MotionMaster.cpp | 5 +++++ .../MovementGenerators/SplineChainMovementGenerator.cpp | 13 +++++++++++++ .../MovementGenerators/SplineChainMovementGenerator.h | 3 +++ src/server/game/Movement/Spline/SplineChain.h | 2 ++ 4 files changed, 23 insertions(+) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 898e4841559..651efa7f940 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -505,6 +505,11 @@ void MotionMaster::MoveAlongSplineChain(uint32 pointId, SplineChain const& chain void MotionMaster::ResumeSplineChain(SplineChainResumeInfo const& info) { + if (info.Empty()) + { + TC_LOG_ERROR("misc", "MotionMaster::ResumeSplineChain: unit with entry %u tried to resume a spline chain from empty info.", _owner->GetEntry()); + return; + } Mutate(new SplineChainMovementGenerator(info), MOTION_SLOT_ACTIVE); } diff --git a/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.cpp index 551bc3e0283..43b4c6b029e 100644 --- a/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.cpp @@ -138,3 +138,16 @@ SplineChainResumeInfo SplineChainMovementGenerator::GetResumeInfo(Unit const* me return SplineChainResumeInfo(_id, &_chain, _walk, _nextIndex, 0, 1u); return SplineChainResumeInfo(_id, &_chain, _walk, uint8(_nextIndex - 1), uint8(me->movespline->_currentSplineIdx()), _msToNext); } + +/* static */ void SplineChainMovementGenerator::GetResumeInfo(Unit const* me, SplineChainResumeInfo& info) +{ + if (MovementGenerator const* activeGen = me->GetMotionMaster()->GetMotionSlot(MOTION_SLOT_ACTIVE)) + { + if (activeGen->GetMovementGeneratorType() == SPLINE_CHAIN_MOTION_TYPE) + { + info = reinterpret_cast(activeGen)->GetResumeInfo(me); + return; + } + } + info.Chain = nullptr; +} diff --git a/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h b/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h index 8d64bf14562..2892dc3e5c6 100644 --- a/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h @@ -32,6 +32,9 @@ class TC_GAME_API SplineChainMovementGenerator : public MovementGenerator bool Update(Unit* me, uint32 diff) override; MovementGeneratorType GetMovementGeneratorType() const override { return SPLINE_CHAIN_MOTION_TYPE; } // Builds info that can later be used to resume this spline chain movement at the current position + static void GetResumeInfo(Unit const* me, SplineChainResumeInfo& info); + // Leaving the object method public for people that know what they're doing to use + // But really, 99% of the time you should be using the static one instead SplineChainResumeInfo GetResumeInfo(Unit const* me) const; private: diff --git a/src/server/game/Movement/Spline/SplineChain.h b/src/server/game/Movement/Spline/SplineChain.h index bfb66eb7fee..33d816712b7 100644 --- a/src/server/game/Movement/Spline/SplineChain.h +++ b/src/server/game/Movement/Spline/SplineChain.h @@ -36,6 +36,8 @@ struct TC_GAME_API SplineChainResumeInfo SplineChainResumeInfo() : PointID(0), Chain(nullptr), IsWalkMode(false), SplineIndex(0), PointIndex(0), TimeToNext(0) { } SplineChainResumeInfo(uint32 id, SplineChain const* chain, bool walk, uint8 splineIndex, uint8 wpIndex, uint32 msToNext) : PointID(id), Chain(chain), IsWalkMode(walk), SplineIndex(splineIndex), PointIndex(wpIndex), TimeToNext(msToNext) { } + bool Empty() const { return Chain == nullptr; } + void Clear() { Chain = nullptr; } uint32 PointID; SplineChain const* Chain; bool IsWalkMode; -- cgit v1.2.3