Update Waypoint System and Commands

Update Waypoint System and Commands
This commit is contained in:
Charles A Edwards 2016-08-30 11:15:20 +01:00 committed by Antz
parent 870b4dd0a4
commit 6ac38a0d65
48 changed files with 455 additions and 323 deletions

View file

@ -59,8 +59,10 @@ void MotionMaster::Initialize()
if (m_owner->GetTypeId() == TYPEID_UNIT && !m_owner->hasUnitState(UNIT_STAT_CONTROLLED))
{
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)m_owner);
push(movement == NULL ? &si_idleMovement : movement);
push(movement == nullptr ? &si_idleMovement : movement);
top()->Initialize(*m_owner);
if (top()->GetMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
(static_cast<WaypointMovementGenerator<Creature>*>(top()))->InitializeWaypointPath(*((Creature*)(m_owner)), 0, PATH_NO_PATH, 0, 0);
}
else
push(&si_idleMovement);
@ -376,20 +378,22 @@ void MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
}
}
void MotionMaster::MoveWaypoint()
void MotionMaster::MoveWaypoint(int32 id /*=0*/, uint32 source /*=0==PATH_NO_PATH*/, uint32 initialDelay /*=0*/, uint32 overwriteEntry /*=0*/)
{
if (m_owner->GetTypeId() == TYPEID_UNIT)
{
if (GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
{
sLog.outError("Creature %s (Entry %u) attempt to MoveWaypoint() but creature is already using waypoint", m_owner->GetGuidStr().c_str(), m_owner->GetEntry());
sLog.outError("%s attempt to MoveWaypoint() but is already using waypoint", m_owner->GetGuidStr().c_str());
return;
}
Creature* creature = (Creature*)m_owner;
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature %s (Entry %u) start MoveWaypoint()", m_owner->GetGuidStr().c_str(), m_owner->GetEntry());
Mutate(new WaypointMovementGenerator<Creature>(*creature));
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "%s start MoveWaypoint()", m_owner->GetGuidStr().c_str());
WaypointMovementGenerator<Creature>* newWPMMgen = new WaypointMovementGenerator<Creature>(*creature);
Mutate(newWPMMgen);
newWPMMgen->InitializeWaypointPath(*creature, id, (WaypointPathOrigin)source, initialDelay, overwriteEntry);
}
else
{
@ -469,6 +473,16 @@ void MotionMaster::propagateSpeedChange()
}
}
bool MotionMaster::SetNextWaypoint(uint32 pointId)
{
for (Impl::container_type::reverse_iterator rItr = Impl::c.rbegin(); rItr != Impl::c.rend(); ++rItr)
{
if ((*rItr)->GetMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
return (static_cast<WaypointMovementGenerator<Creature>*>(*rItr))->SetNextWaypoint(pointId);
}
return false;
}
uint32 MotionMaster::getLastReachedWaypoint() const
{
for (Impl::container_type::const_reverse_iterator rItr = Impl::c.rbegin(); rItr != Impl::c.rend(); ++rItr)
@ -487,6 +501,18 @@ MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
return top()->GetMovementGeneratorType();
}
void MotionMaster::GetWaypointPathInformation(std::ostringstream& oss) const
{
for (Impl::container_type::const_reverse_iterator rItr = Impl::c.rbegin(); rItr != Impl::c.rend(); ++rItr)
{
if ((*rItr)->GetMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
{
static_cast<WaypointMovementGenerator<Creature>*>(*rItr)->GetPathInformation(oss);
return;
}
}
}
bool MotionMaster::GetDestination(float& x, float& y, float& z)
{
if (m_owner->movespline->Finalized())

View file

@ -55,6 +55,10 @@ enum MovementGeneratorType
TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
FOLLOW_MOTION_TYPE = 14, // TargetedMovementGenerator.h
EFFECT_MOTION_TYPE = 15,
EXTERNAL_WAYPOINT_MOVE = 256, // Only used in CreatureAI::MovementInform when a waypoint is reached. The pathId >= 0 is added as additonal value
EXTERNAL_WAYPOINT_MOVE_START = 512, // Only used in CreatureAI::MovementInform when a waypoint is started. The pathId >= 0 is added as additional value
EXTERNAL_WAYPOINT_FINISHED_LAST = 1024, // Only used in CreatureAI::MovementInform when the waittime of the last wp is finished The pathId >= 0 is added as additional value
};
enum MMCleanFlag
@ -113,7 +117,7 @@ class MotionMaster : private std::stack<MovementGenerator*>
void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true);
void MoveSeekAssistance(float x, float y, float z);
void MoveSeekAssistanceDistract(uint32 timer);
void MoveWaypoint();
void MoveWaypoint(int32 id = 0, uint32 source = 0, uint32 initialDelay = 0, uint32 overwriteEntry = 0);
void MoveTaxiFlight(uint32 path, uint32 pathnode);
void MoveDistract(uint32 timeLimit);
void MoveJump(float x, float y, float z, float horizontalSpeed, float max_height, uint32 id = 0);
@ -124,7 +128,9 @@ class MotionMaster : private std::stack<MovementGenerator*>
MovementGeneratorType GetCurrentMovementGeneratorType() const;
void propagateSpeedChange();
bool SetNextWaypoint(uint32 pointId);
uint32 getLastReachedWaypoint() const;
void GetWaypointPathInformation(std::ostringstream& oss) const;
bool GetDestination(float& x, float& y, float& z);

View file

@ -77,6 +77,14 @@ void WaypointMovementGenerator<Creature>::Initialize(Creature& creature)
creature.clearUnitState(UNIT_STAT_WAYPOINT_PAUSED);
}
void WaypointMovementGenerator<Creature>::InitializeWaypointPath(Creature& u, int32 id, WaypointPathOrigin wpSource, uint32 initialDelay, uint32 overwriteEntry)
{
LoadPath(u, id, wpSource, overwriteEntry);
i_nextMoveTime.Reset(initialDelay);
// Start moving if possible
StartMove(u);
}
void WaypointMovementGenerator<Creature>::Finalize(Creature& creature)
{
creature.clearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_ROAMING_MOVE);
@ -156,6 +164,15 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature)
}
// Inform script
if (creature.AI())
{
uint32 type = WAYPOINT_MOTION_TYPE;
if (m_PathOrigin == PATH_FROM_EXTERNAL && m_pathId > 0)
type = EXTERNAL_WAYPOINT_MOVE + m_pathId;
creature.AI()->MovementInform(type, i_currentNode);
}
// Wait delay ms
Stop(node.delay);
}
@ -182,9 +199,25 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature& creature)
if (m_isArrivalDone)
{
bool reachedLast = false;
++currPoint;
if (currPoint == i_path->end())
{
reachedLast = true;
currPoint = i_path->begin();
}
// Inform AI
if (creature.AI() && m_PathOrigin == PATH_FROM_EXTERNAL && m_pathId > 0)
{
if (!reachedLast)
creature.AI()->MovementInform(EXTERNAL_WAYPOINT_MOVE_START + m_pathId, currPoint->first);
else
creature.AI()->MovementInform(EXTERNAL_WAYPOINT_FINISHED_LAST + m_pathId, currPoint->first);
if (creature.IsDead() || !creature.IsInWorld()) // Might have happened with above calls
return;
}
i_currentNode = currPoint->first;
}
@ -238,6 +271,20 @@ bool WaypointMovementGenerator<Creature>::Update(Creature& creature, const uint3
return true;
}
bool WaypointMovementGenerator<Creature>::Stopped(Creature& u)
{
return !i_nextMoveTime.Passed() || u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED);
}
bool WaypointMovementGenerator<Creature>::CanMove(int32 diff, Creature& u)
{
i_nextMoveTime.Update(diff);
if (i_nextMoveTime.Passed() && u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED))
i_nextMoveTime.Reset(1);
return i_nextMoveTime.Passed() && !u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED);
}
bool WaypointMovementGenerator<Creature>::GetResetPosition(Creature&, float& x, float& y, float& z, float& o) const
{
// prevent a crash at empty waypoint path.
@ -280,18 +327,10 @@ bool WaypointMovementGenerator<Creature>::GetResetPosition(Creature&, float& x,
return true;
}
bool WaypointMovementGenerator<Creature>::Stopped(Creature& u)
void WaypointMovementGenerator<Creature>::GetPathInformation(std::ostringstream& oss) const
{
return !i_nextMoveTime.Passed() || u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED);
}
bool WaypointMovementGenerator<Creature>::CanMove(int32 diff, Creature& u)
{
i_nextMoveTime.Update(diff);
if (i_nextMoveTime.Passed() && u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED))
i_nextMoveTime.Reset(1);
return i_nextMoveTime.Passed() && !u.hasUnitState(UNIT_STAT_WAYPOINT_PAUSED);
oss << "WaypointMovement: Last Reached WP: " << m_lastReachedWaypoint << " ";
oss << "(Loaded path " << m_pathId << " from " << WaypointManager::GetOriginString(m_PathOrigin) << ")\n";
}
void WaypointMovementGenerator<Creature>::AddToWaypointPauseTime(int32 waitTimeDiff)
@ -304,6 +343,26 @@ void WaypointMovementGenerator<Creature>::AddToWaypointPauseTime(int32 waitTimeD
}
}
bool WaypointMovementGenerator<Creature>::SetNextWaypoint(uint32 pointId)
{
if (!i_path || i_path->empty())
return false;
WaypointPath::const_iterator currPoint = i_path->find(pointId);
if (currPoint == i_path->end())
return false;
// Allow Moving with next tick
// Handle allow movement this way to not interact with PAUSED state.
// If this function is called while PAUSED, it will move properly when unpaused.
i_nextMoveTime.Reset(1);
m_isArrivalDone = false;
// Set the point
i_currentNode = pointId;
return true;
}
//----------------------------------------------------//
uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
{