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".

This commit is contained in:
treeston
2016-09-21 16:22:12 +02:00
parent 820e843391
commit d3214a0012
4 changed files with 20 additions and 0 deletions

View File

@@ -494,6 +494,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);
}

View File

@@ -138,3 +138,14 @@ 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<SplineChainMovementGenerator const*>(activeGen)->GetResumeInfo(me);
return;
}
info.Chain = nullptr;
}

View File

@@ -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:

View File

@@ -36,6 +36,7 @@ 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; }
uint32 PointID;
SplineChain const* Chain;
bool IsWalkMode;