[11711] Rewrite WaypointMovementGenerator

This commit is contained in:
SilverIce 2011-07-04 05:48:36 +03:00
parent 984f16aedd
commit 26d73759e2
3 changed files with 123 additions and 176 deletions

View file

@ -75,15 +75,7 @@ void WaypointMovementGenerator<Creature>::LoadPath(Creature &creature)
}
}
// 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);
if (creature.CanFly())
creature.AddSplineFlag(SPLINEFLAG_FLYING);
const WaypointNode &node = i_path->at(i_currentNode);
i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
StartMoveNow(creature);
}
void WaypointMovementGenerator<Creature>::Initialize(Creature &creature)
@ -104,85 +96,25 @@ void WaypointMovementGenerator<Creature>::Interrupt(Creature &creature)
void WaypointMovementGenerator<Creature>::Reset(Creature &creature)
{
SetStoppedByPlayer(false);
i_nextMoveTime.Reset(0);
creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
StartMoveNow(creature);
}
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature)
{
if (!&creature)
return true;
// Waypoint movement can be switched on/off
// This is quite handy for escort quests and other stuff
if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
{
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
// prevent a crash at empty waypoint path.
if (!i_path || i_path->empty())
{
return;
if (m_isArrivalDone)
return;
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
m_isArrivalDone = true;
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)
return true; // not expire now, but already lost
}
// creature has been stopped in middle of the waypoint segment
if (!i_destinationHolder.HasArrived() && creature.IsStopped())
{
// Timer has elapsed, meaning this part controlled it
if (i_nextMoveTime.Passed())
{
SetStoppedByPlayer(false);
creature.addUnitState(UNIT_STAT_ROAMING_MOVE);
if (creature.CanFly())
creature.AddSplineFlag(SPLINEFLAG_FLYING);
// Now we re-set destination to same node and start travel
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( !i_nextMoveTime.Passed())
{
// unexpected end of timer && creature stopped && not at end of segment
if (!IsStoppedByPlayer())
{
// Put 30 seconds delay
i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
SetStoppedByPlayer(true); // Mark we did it
}
}
return true; // Abort here this update
}
if (creature.IsStopped())
{
if (!m_isArrivalDone)
{
if (i_path->at(i_currentNode).orientation != 100)
creature.SetOrientation(i_path->at(i_currentNode).orientation);
{
creature.SetFacingTo(i_path->at(i_currentNode).orientation);
}
if (i_path->at(i_currentNode).script_id)
{
@ -197,13 +129,8 @@ bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint3
creature.HandleEmote(behavior->emote);
if (behavior->spell != 0)
{
creature.CastSpell(&creature, behavior->spell, false);
if (!IsActive(creature)) // force stop processing (cast can change movegens list)
return true; // not expire now, but already lost
}
if (behavior->model1 != 0)
creature.SetDisplayId(behavior->model1);
@ -225,74 +152,79 @@ bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint3
else
creature.MonsterSay(behavior->textid[0], LANG_UNIVERSAL);
}
} // wpBehaviour found
// Can only do this once for the node
m_isArrivalDone = true;
}
// Inform script
MovementInform(creature);
Stop(i_path->at(i_currentNode).delay);
}
if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list)
return true; // not expire now, but already lost
void WaypointMovementGenerator<Creature>::StartMove(Creature &creature)
{
if (!i_path || i_path->empty())
return;
// prevent a crash at empty waypoint path.
if (!i_path || i_path->empty() || i_currentNode >= i_path->size())
{
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
}
} // i_creature.IsStopped()
// 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
if (creature.IsStopped())
{
creature.addUnitState(UNIT_STAT_ROAMING_MOVE);
if (creature.CanFly())
creature.AddSplineFlag(SPLINEFLAG_FLYING);
if (Stopped())
return;
if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior)
{
if (behavior->model2 != 0)
creature.SetDisplayId(behavior->model2);
creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
}
// behavior for "departure" of the current node is done
if (m_isArrivalDone)
i_currentNode = (i_currentNode+1) % i_path->size();
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);
if (creature.CanFly())
creature.AddSplineFlag(SPLINEFLAG_FLYING);
creature.addUnitState(UNIT_STAT_ROAMING_MOVE);
const WaypointNode &node = i_path->at(i_currentNode);
CreatureTraveller traveller(creature);
i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
}
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
// Waypoint movement can be switched on/off
// This is quite handy for escort quests and other stuff
if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
{
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
// prevent a crash at empty waypoint path.
if (!i_path || i_path->empty())
{
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
if (Stopped())
{
if (CanMove(diff))
StartMove(creature);
}
else
{
// If not stopped then stop it
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
CreatureTraveller traveller(creature);
if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true) && !IsActive(creature))
return true;
SetStoppedByPlayer(false);
if (creature.IsStopped())
Stop(STOP_TIME_FOR_PLAYER);
// Set TimeTracker to waittime for the current node
i_nextMoveTime.Reset(i_path->at(i_currentNode).delay);
if (i_destinationHolder.HasArrived())
{
OnArrived(creature);
StartMove(creature);
}
}
return true;
}

View file

@ -89,19 +89,34 @@ public PathMovementBase<Creature, WaypointPath const*>
// now path movement implmementation
void LoadPath(Creature &c);
// Player stoping creature
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<Creature, WaypointPath const*>::GetDestination(x,y,z); }
bool GetResetPosition(Creature&, float& x, float& y, float& z);
private:
void Stop(int32 time) { i_nextMoveTime.Reset(time);}
bool Stopped() { return !i_nextMoveTime.Passed();}
bool CanMove(int32 diff)
{
i_nextMoveTime.Update(diff);
return i_nextMoveTime.Passed();
}
void OnArrived(Creature&);
void StartMove(Creature&);
void StartMoveNow(Creature& creature)
{
i_nextMoveTime.Reset(0);
StartMove(creature);
}
ShortTimeTracker i_nextMoveTime;
bool m_isArrivalDone;
bool m_isStoppedByPlayer;
};
/** FlightPathMovementGenerator generates movement of the player for the paths

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11709"
#define REVISION_NR "11711"
#endif // __REVISION_NR_H__