Skip to content

Commit

Permalink
Core/Movement: MotionMaster reimplementation (#21888)
Browse files Browse the repository at this point in the history
Internal structure and handling changes, nothing behavioural (or thats the intention at least).
  • Loading branch information
ccrs committed Jun 3, 2018
1 parent b84348f commit 982643c
Show file tree
Hide file tree
Showing 96 changed files with 2,351 additions and 1,420 deletions.
8 changes: 3 additions & 5 deletions src/server/game/AI/CreatureAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,7 @@ void CreatureAI::TriggerAlert(Unit const* who) const
me->SendAIReaction(AI_REACTION_ALERT);

// Face the unit (stealthed player) and set distracted state for 5 seconds
me->GetMotionMaster()->MoveDistract(5 * IN_MILLISECONDS);
me->StopMoving();
me->SetFacingTo(me->GetAbsoluteAngle(who));
me->GetMotionMaster()->MoveDistract(5 * IN_MILLISECONDS, me->GetAbsoluteAngle(who));
}

void CreatureAI::EnterEvadeMode(EvadeReason why)
Expand All @@ -173,8 +171,8 @@ void CreatureAI::EnterEvadeMode(EvadeReason why)
{
if (Unit* owner = me->GetCharmerOrOwner())
{
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle());
}
else
{
Expand Down
6 changes: 3 additions & 3 deletions src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ void EscortAI::UpdateAI(uint32 diff)
else if (_resume)
{
_resume = false;
if (MovementGenerator* movementGenerator = me->GetMotionMaster()->GetMotionSlot(MOTION_SLOT_IDLE))
if (MovementGenerator* movementGenerator = me->GetMotionMaster()->GetCurrentMovementGenerator(MOTION_SLOT_DEFAULT))
movementGenerator->Resume(0);
}
}
Expand Down Expand Up @@ -331,7 +331,7 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */,
TC_LOG_DEBUG("scripts", "EscortAI::Start: (script: %s, creature entry: %u) is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn.", me->GetScriptName().c_str(), me->GetEntry());

me->GetMotionMaster()->MoveIdle();
me->GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
me->GetMotionMaster()->Clear(MOTION_PRIORITY_NORMAL);

// disable npcflags
me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
Expand Down Expand Up @@ -368,7 +368,7 @@ void EscortAI::SetEscortPaused(bool on)
if (on)
{
AddEscortState(STATE_ESCORT_PAUSED);
if (MovementGenerator* movementGenerator = me->GetMotionMaster()->GetMotionSlot(MOTION_SLOT_IDLE))
if (MovementGenerator* movementGenerator = me->GetMotionMaster()->GetCurrentMovementGenerator(MOTION_SLOT_DEFAULT))
movementGenerator->Pause(0);
}
else
Expand Down
31 changes: 22 additions & 9 deletions src/server/game/AI/SmartScripts/SmartAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void SmartAI::PausePath(uint32 delay, bool forced)
{
if (!HasEscortState(SMART_ESCORT_ESCORTING))
{
me->PauseMovement(delay, MOTION_SLOT_IDLE, forced);
me->PauseMovement(delay, MOTION_SLOT_DEFAULT, forced);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
{
std::pair<uint32, uint32> waypointInfo = me->GetCurrentWaypointInfo();
Expand Down Expand Up @@ -544,8 +544,11 @@ void SmartAI::JustReachedHome()
CreatureGroup* formation = me->GetFormation();
if (!formation || formation->GetLeader() == me || !formation->IsFormed())
{
if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != WAYPOINT_MOTION_TYPE && me->GetWaypointPath())
me->GetMotionMaster()->MovePath(me->GetWaypointPath(), true);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType(MOTION_SLOT_DEFAULT) != WAYPOINT_MOTION_TYPE)
{
if (me->GetWaypointPath())
me->GetMotionMaster()->MovePath(me->GetWaypointPath(), true);
}
else
me->ResumeMovement();
}
Expand Down Expand Up @@ -591,7 +594,8 @@ void SmartAI::AttackStart(Unit* who)

if (who && me->Attack(who, mCanAutoAttack))
{
me->GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
me->GetMotionMaster()->Clear(MOTION_PRIORITY_NORMAL);
me->PauseMovement();

if (mCanCombatMove)
{
Expand Down Expand Up @@ -770,13 +774,22 @@ void SmartAI::SetCombatMove(bool on)

if (me->IsEngaged())
{
if (on && !me->HasReactState(REACT_PASSIVE) && me->GetVictim() && me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_ACTIVE) == MAX_MOTION_TYPE)
if (on)
{
SetRun(mRun);
me->GetMotionMaster()->MoveChase(me->GetVictim());
if (!me->HasReactState(REACT_PASSIVE) && me->GetVictim() && !me->GetMotionMaster()->HasMovementGenerator([](MovementGenerator const* movement) -> bool
{
return movement->Mode == MOTION_MODE_DEFAULT && movement->Priority == MOTION_PRIORITY_NORMAL;
}))
{
SetRun(mRun);
me->GetMotionMaster()->MoveChase(me->GetVictim());
}
}
else if (!on && me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_ACTIVE) == CHASE_MOTION_TYPE)
me->GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
else if (MovementGenerator* movement = me->GetMotionMaster()->GetMovementGenerator([](MovementGenerator const* a) -> bool
{
return a->GetMovementGeneratorType() == CHASE_MOTION_TYPE && a->Mode == MOTION_MODE_DEFAULT && a->Priority == MOTION_PRIORITY_NORMAL;
}))
me->GetMotionMaster()->Remove(movement);
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/server/game/AI/SmartScripts/SmartScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1594,10 +1594,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * float(M_PI);

for (WorldObject* target : targets)
{
if (Creature* creature = target->ToCreature())
if (IsSmart(creature) && creature->GetVictim())
if (ENSURE_AI(SmartAI, creature->AI())->CanCombatMove())
creature->GetMotionMaster()->MoveChase(creature->GetVictim(), attackDistance, attackAngle);
}

break;
}
Expand Down Expand Up @@ -2230,16 +2232,16 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
target->ToUnit()->RemoveAllGameObjects();
break;
}
case SMART_ACTION_STOP_MOTION:
case SMART_ACTION_REMOVE_MOVEMENT:
{
for (WorldObject* const target : targets)
{
if (IsUnit(target))
{
if (e.action.stopMotion.stopMovement)
if (e.action.removeMovement.movementType && e.action.removeMovement.movementType < MAX_MOTION_TYPE)
target->ToUnit()->GetMotionMaster()->Remove(MovementGeneratorType(e.action.removeMovement.movementType));
if (e.action.removeMovement.forced)
target->ToUnit()->StopMoving();
if (e.action.stopMotion.movementExpired)
target->ToUnit()->GetMotionMaster()->MovementExpired();
}
}
break;
Expand Down
4 changes: 2 additions & 2 deletions src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "GameEventMgr.h"
#include "InstanceScript.h"
#include "Log.h"
#include "MotionMaster.h"
#include "MovementDefines.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "SpellInfo.h"
Expand Down Expand Up @@ -1570,7 +1570,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_REMOVE_ALL_GAMEOBJECTS:
case SMART_ACTION_SPAWN_SPAWNGROUP:
case SMART_ACTION_DESPAWN_SPAWNGROUP:
case SMART_ACTION_STOP_MOTION:
case SMART_ACTION_REMOVE_MOVEMENT:
break;
default:
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
Expand Down
8 changes: 4 additions & 4 deletions src/server/game/AI/SmartScripts/SmartScriptMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ enum SMART_ACTION
SMART_ACTION_LOAD_EQUIPMENT = 124, // id
SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT = 125, // id min range, id max range
SMART_ACTION_REMOVE_ALL_GAMEOBJECTS = 126,
SMART_ACTION_STOP_MOTION = 127, // stopMoving, movementExpired
SMART_ACTION_REMOVE_MOVEMENT = 127, // movementType, forced
SMART_ACTION_PLAY_ANIMKIT = 128, // don't use on 3.3.5a
SMART_ACTION_SCENE_PLAY = 129, // don't use on 3.3.5a
SMART_ACTION_SCENE_CANCEL = 130, // don't use on 3.3.5a
Expand Down Expand Up @@ -1122,9 +1122,9 @@ struct SmartAction

struct
{
uint32 stopMovement;
uint32 movementExpired;
} stopMotion;
uint32 movementType;
uint32 forced;
} removeMovement;

struct
{
Expand Down
7 changes: 1 addition & 6 deletions src/server/game/DungeonFinding/LFGMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "LFGQueue.h"
#include "Log.h"
#include "Map.h"
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Player.h"
Expand Down Expand Up @@ -1340,11 +1339,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
if (!player->GetMap()->IsDungeon())
player->SetBattlegroundEntryPoint();

if (player->IsInFlight())
{
player->GetMotionMaster()->MovementExpired();
player->CleanupAfterTaxiFlight();
}
player->FinishTaxiFlight();

if (!player->TeleportTo(mapid, x, y, z, orientation))
error = LFG_TELEPORTERROR_INVALID_LOCATION;
Expand Down
13 changes: 6 additions & 7 deletions src/server/game/Entities/Creature/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ void Creature::DisappearAndDie()

bool Creature::IsReturningHome() const
{
if (GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_ACTIVE) == HOME_MOTION_TYPE)
if (GetMotionMaster()->GetCurrentMovementGeneratorType() == HOME_MOTION_TYPE)
return true;

return false;
Expand Down Expand Up @@ -762,8 +762,7 @@ void Creature::Update(uint32 diff)
IsAIEnabled = true;
if (!IsInEvadeMode() && LastCharmerGUID)
if (Unit* charmer = ObjectAccessor::GetUnit(*this, LastCharmerGUID))
if (CanStartAttack(charmer, true))
i_AI->AttackStart(charmer);
EngageWithTarget(charmer);

LastCharmerGUID.Clear();
}
Expand Down Expand Up @@ -973,7 +972,6 @@ void Creature::DoFleeToGetAssistance()
UpdateSpeed(MOVE_RUN);

if (!creature)
//SetFeared(true, EnsureVictim()->GetGUID(), 0, sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY));
/// @todo use 31365
SetControlled(true, UNIT_STATE_FLEEING);
else
Expand Down Expand Up @@ -1042,7 +1040,7 @@ void Creature::Motion_Initialize()
m_formation->FormationReset(false);
else if (m_formation->IsFormed())
{
GetMotionMaster()->MoveIdle(); //wait the order of leader
GetMotionMaster()->MoveIdle(); // wait the order of leader
return;
}
}
Expand Down Expand Up @@ -2075,8 +2073,9 @@ void Creature::Respawn(bool force)
SetNativeDisplayId(displayID);
}

GetMotionMaster()->InitDefault();
//Re-initialize reactstate that could be altered by movementgenerators
GetMotionMaster()->InitializeDefault();

// Re-initialize reactstate that could be altered by movementgenerators
InitializeReactState();

if (IsAIEnabled) // reset the AI to be sure no dirty or uninitialized values will be used till next tick
Expand Down
8 changes: 4 additions & 4 deletions src/server/game/Entities/Creature/CreatureGroups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ void CreatureGroup::FormationReset(bool dismiss)
pair.first->GetMotionMaster()->Initialize();
else
pair.first->GetMotionMaster()->MoveIdle();
TC_LOG_DEBUG("entities.unit", "Set %s movement for member GUID: %u", dismiss ? "default" : "idle", pair.first->GetGUID().GetCounter());
TC_LOG_DEBUG("entities.unit", "CreatureGroup::FormationReset: Set %s movement for member GUID: %u", dismiss ? "default" : "idle", pair.first->GetGUID().GetCounter());
}
}

Expand Down Expand Up @@ -317,16 +317,16 @@ void CreatureGroup::LeaderMoveTo(Position const& destination, uint32 id /*= 0*/,
if (!member->IsFlying())
member->UpdateGroundPositionZ(dx, dy, dz);

Position point(dx, dy, dz, destination.GetOrientation());
member->SetHomePosition(dx, dy, dz, pathangle);

Position point(dx, dy, dz, destination.GetOrientation());
member->GetMotionMaster()->MoveFormation(id, point, moveType, !member->IsWithinDist(_leader, dist + MAX_DESYNC), orientation);
member->SetHomePosition(dx, dy, dz, pathangle);
}
}

bool CreatureGroup::CanLeaderStartMoving() const
{
for (auto const& pair : _members)
for (std::unordered_map<Creature*, FormationInfo*>::value_type const& pair : _members)
{
if (pair.first != _leader && pair.first->IsAlive())
{
Expand Down
21 changes: 11 additions & 10 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21248,9 +21248,18 @@ bool Player::ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid /*= 0*/)
return ActivateTaxiPathTo(nodes, nullptr, spellid);
}

void Player::FinishTaxiFlight()
{
if (!IsInFlight())
return;

GetMotionMaster()->Remove(FLIGHT_MOTION_TYPE);
m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
}

void Player::CleanupAfterTaxiFlight()
{
m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
Dismount();
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_TAXI_FLIGHT);
}
Expand Down Expand Up @@ -23325,11 +23334,7 @@ void Player::SummonIfPossible(bool agree)
return;

// stop taxi flight at summon
if (IsInFlight())
{
GetMotionMaster()->MovementExpired();
CleanupAfterTaxiFlight();
}
FinishTaxiFlight();

// drop flag at summon
// this code can be reached only when GM is summoning player who carries flag, because player should be immune to summoning spells when he carries flag
Expand Down Expand Up @@ -23742,13 +23747,9 @@ void Player::SetClientControl(Unit* target, bool allowMove)
void Player::SetMovedUnit(Unit* target)
{
m_unitMovedByMe->m_playerMovingMe = nullptr;
if (m_unitMovedByMe->GetTypeId() == TYPEID_UNIT)
m_unitMovedByMe->GetMotionMaster()->Initialize();

m_unitMovedByMe = target;
m_unitMovedByMe->m_playerMovingMe = this;
if (m_unitMovedByMe->GetTypeId() == TYPEID_UNIT)
m_unitMovedByMe->GetMotionMaster()->Initialize();
}

void Player::UpdateZoneDependentAuras(uint32 newZone)
Expand Down
3 changes: 2 additions & 1 deletion src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -945,10 +945,11 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0);
bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0);
void FinishTaxiFlight();
void CleanupAfterTaxiFlight();
void ContinueTaxiFlight() const;
void SendTaxiNodeStatusMultiple();
// mount_id can be used in scripting calls

bool isAcceptWhispers() const { return (m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS) != 0; }
void SetAcceptWhispers(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_ACCEPT_WHISPERS; else m_ExtraFlags &= ~PLAYER_EXTRA_ACCEPT_WHISPERS; }
bool IsGameMaster() const { return (m_ExtraFlags & PLAYER_EXTRA_GM_ON) != 0; }
Expand Down

2 comments on commit 982643c

@Killyana
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ccrs Could explain the arguments used for SMART_ACTION_REMOVE_MOVEMENT an how it work?

I Have an npc with waypoints movements from waypoint_data, at some point of a quest he must move to a position an stay there for 10 secs, I'm using the action move to pos.
The problem is upon reaching the point he return doing the waypoint instead of staying there.
Ofc I used SMART_ACTION_REMOVE_MOVEMENT to stop the waypoint movement (127, 2, 1) but it doesn't work.

@ccrs
Copy link
Member Author

@ccrs ccrs commented on 982643c Aug 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, I'll answer in #22346

Please sign in to comment.