aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Movement/MovementPacketSender.cpp
diff options
context:
space:
mode:
authorChaouki Dhib <chaodhib@gmail.com>2021-06-15 23:09:48 +0200
committerGitHub <noreply@github.com>2021-06-15 23:09:48 +0200
commitd337fb99ed81dc3522bdea17e762febd989a6956 (patch)
tree308c4402d114163a783d340c90bbe7ec42085169 /src/server/game/Movement/MovementPacketSender.cpp
parent4b9465e1f91adbc139afe5f86ac84eb5f14b62b4 (diff)
Core/Movement: Implement proper player speed change (#26561)
Diffstat (limited to 'src/server/game/Movement/MovementPacketSender.cpp')
-rw-r--r--src/server/game/Movement/MovementPacketSender.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/server/game/Movement/MovementPacketSender.cpp b/src/server/game/Movement/MovementPacketSender.cpp
new file mode 100644
index 00000000000..df0ff5e7bbf
--- /dev/null
+++ b/src/server/game/Movement/MovementPacketSender.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "GameClient.h"
+#include "MovementPacketSender.h"
+#include "Player.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+
+// SMSG_SPLINE_SET_* messages are for units controlled by the server.
+// SMSG_FORCE_*_SPEED_CHANGE messages are for units controlled by a player and require the client to respond with an ACK message.
+// MSG_MOVE_SET_*_SPEED is used to broadcast changes to observers of units controlled by a player
+Opcodes const MovementPacketSender::moveTypeToOpcode[MAX_MOVE_TYPE][3] =
+{
+ { SMSG_SPLINE_SET_WALK_SPEED, SMSG_FORCE_WALK_SPEED_CHANGE, MSG_MOVE_SET_WALK_SPEED },
+ { SMSG_SPLINE_SET_RUN_SPEED, SMSG_FORCE_RUN_SPEED_CHANGE, MSG_MOVE_SET_RUN_SPEED },
+ { SMSG_SPLINE_SET_RUN_BACK_SPEED, SMSG_FORCE_RUN_BACK_SPEED_CHANGE, MSG_MOVE_SET_RUN_BACK_SPEED },
+ { SMSG_SPLINE_SET_SWIM_SPEED, SMSG_FORCE_SWIM_SPEED_CHANGE, MSG_MOVE_SET_SWIM_SPEED },
+ { SMSG_SPLINE_SET_SWIM_BACK_SPEED, SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, MSG_MOVE_SET_SWIM_BACK_SPEED },
+ { SMSG_SPLINE_SET_TURN_RATE, SMSG_FORCE_TURN_RATE_CHANGE, MSG_MOVE_SET_TURN_RATE },
+ { SMSG_SPLINE_SET_FLIGHT_SPEED, SMSG_FORCE_FLIGHT_SPEED_CHANGE, MSG_MOVE_SET_FLIGHT_SPEED },
+ { SMSG_SPLINE_SET_FLIGHT_BACK_SPEED, SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, MSG_MOVE_SET_FLIGHT_BACK_SPEED },
+ { SMSG_SPLINE_SET_PITCH_RATE, SMSG_FORCE_PITCH_RATE_CHANGE, MSG_MOVE_SET_PITCH_RATE },
+};
+
+MovementChangeType MovementPacketSender::GetChangeTypeByMoveType(UnitMoveType moveType)
+{
+ switch (moveType)
+ {
+ case MOVE_WALK: return MovementChangeType::SPEED_CHANGE_WALK;
+ case MOVE_RUN: return MovementChangeType::SPEED_CHANGE_RUN;
+ case MOVE_RUN_BACK: return MovementChangeType::SPEED_CHANGE_RUN_BACK;
+ case MOVE_SWIM: return MovementChangeType::SPEED_CHANGE_SWIM;
+ case MOVE_SWIM_BACK: return MovementChangeType::SPEED_CHANGE_SWIM_BACK;
+ case MOVE_TURN_RATE: return MovementChangeType::RATE_CHANGE_TURN;
+ case MOVE_FLIGHT: return MovementChangeType::SPEED_CHANGE_FLIGHT_SPEED;
+ case MOVE_FLIGHT_BACK: return MovementChangeType::SPEED_CHANGE_FLIGHT_BACK_SPEED;
+ case MOVE_PITCH_RATE: return MovementChangeType::RATE_CHANGE_PITCH;
+ default:
+ ASSERT(false, "MovementPacketSender::SendSpeedChangeToMover Unsupported UnitMoveType");
+ }
+}
+
+void MovementPacketSender::SendSpeedChangeToMover(Unit* unit, UnitMoveType mtype, float newSpeedFlat)
+{
+ GameClient* controller = unit->GetGameClientMovingMe();
+
+ ASSERT(controller);
+
+ uint32 mCounter = unit->GetMovementCounterAndInc();
+ PlayerMovementPendingChange pendingChange;
+ pendingChange.movementCounter = mCounter;
+ pendingChange.newValue = newSpeedFlat;
+ pendingChange.movementChangeType = MovementPacketSender::GetChangeTypeByMoveType(mtype);
+ unit->PushPendingMovementChange(pendingChange);
+
+ WorldPacket data;
+ data.Initialize(moveTypeToOpcode[mtype][1], mtype != MOVE_RUN ? 8 + 4 + 4 : 8 + 4 + 1 + 4);
+ data << unit->GetPackGUID();
+ data << mCounter;
+ if (mtype == MOVE_RUN)
+ data << uint8(1); // unknown byte added in 2.1.0
+ data << newSpeedFlat;
+ controller->SendDirectMessage(&data);
+}
+
+void MovementPacketSender::SendSpeedChangeToObservers(Unit* unit, UnitMoveType mtype, float newSpeedFlat)
+{
+ GameClient* controller = unit->GetGameClientMovingMe();
+
+ ASSERT(controller);
+
+ WorldPacket data;
+ data.Initialize(moveTypeToOpcode[mtype][2], 8 + 30 + 4);
+ WorldSession::WriteMovementInfo(&data, &unit->m_movementInfo);
+ data << newSpeedFlat;
+ unit->SendMessageToSet(&data, controller->GetBasePlayer());
+}
+
+void MovementPacketSender::SendSpeedChangeToAll(Unit* unit, UnitMoveType mtype, float newSpeedFlat)
+{
+ GameClient* controller = unit->GetGameClientMovingMe();
+
+ ASSERT(!controller);
+
+ WorldPacket data;
+ data.Initialize(moveTypeToOpcode[mtype][0], 8 + 4);
+ data << unit->GetPackGUID();
+ data << newSpeedFlat;
+ unit->SendMessageToSet(&data, true);
+}
+