From 647f731e3b39f1e8329cc3c15b5528cd10e50bbe Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sat, 14 Aug 2010 23:38:20 +0200 Subject: [PATCH] [10358] A small spoon of changes and cleanup for WaypointMovementGenerator * Initialization to ensure destination is always set (prevent evade problem) * Simplify how behavior for node is processed, incl fix MovementInform script call (based on idea/past code from Quriq14) * Make sure last node is also processed correct (DB script for last node will now work as expected) As usual if any problems occur, you can call our toll free customer support number. Signed-off-by: NoFantasy --- src/game/WaypointMovementGenerator.cpp | 127 +++++++++++++------------ src/game/WaypointMovementGenerator.h | 11 +-- src/shared/revision_nr.h | 2 +- 3 files changed, 71 insertions(+), 69 deletions(-) diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 4e3a13634..4950a3614 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -44,55 +44,51 @@ alter table creature_movement add `wpguid` int(11) default '0'; #include //-----------------------------------------------// -void WaypointMovementGenerator::LoadPath(Creature &c) +void WaypointMovementGenerator::LoadPath(Creature &creature) { - DETAIL_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "LoadPath: loading waypoint path for creature %u, %u", c.GetGUIDLow(), c.GetDBTableGUIDLow()); + DETAIL_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "LoadPath: loading waypoint path for creature %u, %u", creature.GetGUIDLow(), creature.GetDBTableGUIDLow()); - i_path = sWaypointMgr.GetPath(c.GetDBTableGUIDLow()); + i_path = sWaypointMgr.GetPath(creature.GetDBTableGUIDLow()); if (!i_path) { sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u) doesn't have waypoint path", - c.GetName(), c.GetEntry(), c.GetDBTableGUIDLow()); + creature.GetName(), creature.GetEntry(), creature.GetDBTableGUIDLow()); return; } - uint32 node_count = i_path->size(); - i_hasDone.resize(node_count); + // We have to set the destination here (for the first point), right after Initialize. Without, we may not have valid xyz for GetResetPosition + CreatureTraveller traveller(creature); - for(uint32 i = 0; i < node_count-1; ++i) - i_hasDone[i] = false; + if (creature.canFly()) + creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); - // to prevent a misbehavior inside "update" - // update is always called with the next wp - but the wpSys needs the current - // so when the routine is called the first time, wpSys gets the last waypoint - // and this prevents the system from performing text/emote, etc - i_hasDone[node_count - 1] = true; + const WaypointNode &node = i_path->at(i_currentNode); + i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); + i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } -void WaypointMovementGenerator::Initialize( Creature &u ) +void WaypointMovementGenerator::Initialize(Creature &creature) { - i_nextMoveTime.Reset(0); // TODO: check the lower bound (0 is probably too small) - u.StopMoving(); - LoadPath(u); - u.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); + LoadPath(creature); + creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); } -void WaypointMovementGenerator::Finalize( Creature &u ) +void WaypointMovementGenerator::Finalize(Creature &creature) { - u.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); + creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); } -void WaypointMovementGenerator::Interrupt( Creature &u ) +void WaypointMovementGenerator::Interrupt(Creature &creature) { - u.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); + creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); } -void WaypointMovementGenerator::Reset( Creature &u ) +void WaypointMovementGenerator::Reset(Creature &creature) { - b_StoppedByPlayer = false; + SetStoppedByPlayer(false); i_nextMoveTime.Reset(0); - u.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); + creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); } bool WaypointMovementGenerator::Update(Creature &creature, const uint32 &diff) @@ -115,16 +111,16 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 return true; } - // i_path was modified by chat commands for example - if (i_path->size() != i_hasDone.size()) - i_hasDone.resize(i_path->size()); - if (i_currentNode >= i_path->size()) + { + sLog.outError("WaypointMovement currentNode (%u) is equal or bigger than path size (creature entry %u)", i_currentNode, creature.GetEntry()); i_currentNode = 0; + } CreatureTraveller traveller(creature); i_nextMoveTime.Update(diff); + if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true)) { if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) @@ -165,20 +161,19 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 if (creature.IsStopped()) { - uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; - - if (!i_hasDone[idx]) + if (!m_isArrivalDone) { - if (i_path->at(idx).orientation != 100) - creature.SetOrientation(i_path->at(idx).orientation); + if (i_path->at(i_currentNode).orientation != 100) + creature.SetOrientation(i_path->at(i_currentNode).orientation); - if (i_path->at(idx).script_id) + if (i_path->at(i_currentNode).script_id) { - DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for creature %u (entry %u).", i_path->at(idx).script_id, idx, creature.GetDBTableGUIDLow(), creature.GetEntry()); - creature.GetMap()->ScriptsStart(sCreatureMovementScripts, i_path->at(idx).script_id, &creature, &creature); + DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for creature %u (entry %u).", i_path->at(i_currentNode).script_id, i_currentNode, creature.GetDBTableGUIDLow(), creature.GetEntry()); + creature.GetMap()->ScriptsStart(sCreatureMovementScripts, i_path->at(i_currentNode).script_id, &creature, &creature); } - if (WaypointBehavior *behavior = i_path->at(idx).behavior) + // We have reached the destination and can process behavior + if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior) { if (behavior->emote != 0) creature.HandleEmote(behavior->emote); @@ -214,7 +209,10 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 } } // wpBehaviour found - i_hasDone[idx] = true; + // Can only do this once for the node + m_isArrivalDone = true; + + // Inform script MovementInform(creature); if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) @@ -226,10 +224,10 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } - } // HasDone == false + } } // i_creature.IsStopped() - // This is at the end of waypoint segment or has been stopped by player + // This is at the end of waypoint segment (incl. was previously stopped by player, extending the time) if (i_nextMoveTime.Passed()) { // If stopped then begin a new move segment @@ -240,48 +238,53 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 if (creature.canFly()) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); - const WaypointNode &node = i_path->at(i_currentNode); - i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); - i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); - - uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; - - if (i_path->at(idx).orientation != 100) - creature.SetOrientation(i_path->at(idx).orientation); - - if (WaypointBehavior *behavior = i_path->at(idx).behavior) + if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior) { - i_hasDone[idx] = false; - if (behavior->model2 != 0) creature.SetDisplayId(behavior->model2); creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); } + + // behavior for "departure" of the current node is done + m_isArrivalDone = false; + + // Proceed with increment current node and then send to the next destination + ++i_currentNode; + + // Oops, end of the line so need to start from the beginning + if (i_currentNode >= i_path->size()) + i_currentNode = 0; + + if (i_path->at(i_currentNode).orientation != 100) + creature.SetOrientation(i_path->at(i_currentNode).orientation); + + const WaypointNode &node = i_path->at(i_currentNode); + i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); + i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else { - // If not stopped then stop it and set the reset of TimeTracker to waittime + // If not stopped then stop it creature.StopMoving(); + SetStoppedByPlayer(false); + // Set TimeTracker to waittime for the current node i_nextMoveTime.Reset(i_path->at(i_currentNode).delay); - ++i_currentNode; - - if (i_currentNode >= i_path->size()) - i_currentNode = 0; } } + return true; } -void WaypointMovementGenerator::MovementInform(Creature &unit) +void WaypointMovementGenerator::MovementInform(Creature &creature) { - if (unit.AI()) - unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode); + if (creature.AI()) + creature.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode); } -bool WaypointMovementGenerator::GetResetPosition( Creature&, float& x, float& y, float& z ) +bool WaypointMovementGenerator::GetResetPosition(Creature&, float& x, float& y, float& z) { return PathMovementBase::GetPosition(x,y,z); } diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h index ba5e794b3..44872502b 100644 --- a/src/game/WaypointMovementGenerator.h +++ b/src/game/WaypointMovementGenerator.h @@ -74,7 +74,7 @@ class MANGOS_DLL_SPEC WaypointMovementGenerator public PathMovementBase { public: - WaypointMovementGenerator(Creature &) : i_nextMoveTime(0), b_StoppedByPlayer(false) {} + WaypointMovementGenerator(Creature &) : i_nextMoveTime(0), m_isArrivalDone(false), m_isStoppedByPlayer(false) {} ~WaypointMovementGenerator() { i_path = NULL; } void Initialize(Creature &u); void Interrupt(Creature &); @@ -90,8 +90,8 @@ public PathMovementBase void LoadPath(Creature &c); // Player stoping creature - bool IsStoppedByPlayer() { return b_StoppedByPlayer; } - void SetStoppedByPlayer(bool val) { b_StoppedByPlayer = val; } + bool IsStoppedByPlayer() { return m_isStoppedByPlayer; } + void SetStoppedByPlayer(bool val) { m_isStoppedByPlayer = val; } // allow use for overwrite empty implementation bool GetDestination(float& x, float& y, float& z) const { return PathMovementBase::GetDestination(x,y,z); } @@ -99,10 +99,9 @@ public PathMovementBase bool GetResetPosition(Creature&, float& x, float& y, float& z); private: - TimeTrackerSmall i_nextMoveTime; - std::vector i_hasDone; - bool b_StoppedByPlayer; + bool m_isArrivalDone; + bool m_isStoppedByPlayer; }; /** FlightPathMovementGenerator generates movement of the player for the paths diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index adff019e6..9f04a22bc 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10357" + #define REVISION_NR "10358" #endif // __REVISION_NR_H__