Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
VehicleHandler.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Log.h"
8#include "ObjectAccessor.h"
9#include "Opcodes.h"
10#include "Player.h"
11#include "Vehicle.h"
12#include "WorldPacket.h"
13#include "WorldSession.h"
14
16{
17 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
18
19 uint64 vehicleGUID = _player->GetCharmGUID();
20
21 if (!vehicleGUID) // something wrong here...
22 {
23 recvData.rfinish(); // prevent warnings spam
24 return;
25 }
26
27 MovementInfo mi;
28 _player->ReadMovementInfo(recvData, &mi);
29
30 _player->m_movementInfo = mi;
31
32 _player->ExitVehicle();
33}
34
36{
37 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
38
39 Unit* vehicle_base = GetPlayer()->GetVehicleBase();
40 if (!vehicle_base)
41 {
42 recvData.rfinish(); // prevent warnings spam
43 return;
44 }
45
47 if (!seat->CanSwitchFromSeat())
48 {
49 recvData.rfinish(); // prevent warnings spam
50 SF_LOG_ERROR("network", "HandleChangeSeatsOnControlledVehicle, Opcode: %u, Player %u tried to switch seats but current seatflags %u don't permit that.",
51 recvData.GetOpcode(), GetPlayer()->GetGUIDLow(), seat->m_flags);
52 return;
53 }
54
55 switch (recvData.GetOpcode())
56 {
58 GetPlayer()->ChangeSeat(-1, false);
59 break;
61 GetPlayer()->ChangeSeat(-1, true);
62 break;
64 {
65 static MovementStatusElements const accessoryGuid[] =
66 {
84 };
85
86 Movement::ExtraMovementStatusElement extra(accessoryGuid);
87 MovementInfo movementInfo;
88 GetPlayer()->ReadMovementInfo(recvData, &movementInfo, &extra);
89 vehicle_base->m_movementInfo = movementInfo;
90
91 uint64 accessory = extra.Data.guid;
92 int8 seatId = extra.Data.byteData;
93
94 if (vehicle_base->GetGUID() != movementInfo.guid)
95 return;
96
97 if (!accessory)
98 GetPlayer()->ChangeSeat(-1, seatId > 0); // prev/next
99 else if (Unit* vehUnit = Unit::GetUnit(*GetPlayer(), accessory))
100 {
101 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
102 if (vehicle->HasEmptySeat(seatId))
103 vehUnit->HandleSpellClick(GetPlayer(), seatId);
104 }
105 break;
106 }
108 {
109 int8 seatId;
110 ObjectGuid VehicleGUID; // current vehicle guid
111 recvData >> seatId;
112 recvData.ReadGuidMask(VehicleGUID, 7, 3, 0, 1, 6, 4, 5, 2);
113 recvData.ReadGuidBytes(VehicleGUID, 5, 0, 2, 3, 7, 4, 6, 1);
114
115 if (vehicle_base->GetGUID() == VehicleGUID)
116 GetPlayer()->ChangeSeat(seatId);
117 else if (Unit* vehUnit = Unit::GetUnit(*GetPlayer(), VehicleGUID))
118 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
119 if (vehicle->HasEmptySeat(seatId))
120 vehUnit->HandleSpellClick(GetPlayer(), seatId);
121 break;
122 }
123 default:
124 break;
125 }
126}
127
129{
130 ObjectGuid VehicleGUID;
131 recvData.ReadGuidMask(VehicleGUID, 5, 7, 3, 0, 2, 4, 6, 1);
132 recvData.ReadGuidBytes(VehicleGUID, 5, 3, 1, 2, 7, 0, 6, 4);
133
134 if (Player* player = ObjectAccessor::FindPlayer(VehicleGUID))
135 {
136 if (!player->GetVehicleKit())
137 return;
138 if (!player->IsInRaidWith(_player))
139 return;
140 if (!player->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
141 return;
142
143 _player->EnterVehicle(player);
144 }
145}
146
148{
149 Vehicle* vehicle = _player->GetVehicleKit();
150 if (!vehicle)
151 {
152 data.rfinish(); // prevent warnings spam
153 SF_LOG_ERROR("network", "HandleEjectPassenger: Player %u is not in a vehicle!", GetPlayer()->GetGUIDLow());
154 return;
155 }
156
157 ObjectGuid PassengerGUID;
158 data.ReadGuidMask(PassengerGUID, 4, 2, 1, 6, 5, 0, 7, 3);
159 data.ReadGuidBytes(PassengerGUID, 2, 7, 0, 6, 4, 3, 5, 1);
160
161 if (IS_PLAYER_GUID(PassengerGUID))
162 {
163 Player* player = ObjectAccessor::FindPlayer(PassengerGUID);
164 if (!player)
165 {
166 SF_LOG_ERROR("network", "Player %u tried to eject player %u from vehicle, but the latter was not found in world!", GetPlayer()->GetGUIDLow(), GUID_LOPART(PassengerGUID));
167 return;
168 }
169
170 if (!player->IsOnVehicle(vehicle->GetBase()))
171 {
172 SF_LOG_ERROR("network", "Player %u tried to eject player %u, but they are not in the same vehicle", GetPlayer()->GetGUIDLow(), GUID_LOPART(PassengerGUID));
173 return;
174 }
175
176 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(player);
177 ASSERT(seat);
178 if (seat->IsEjectable())
179 player->ExitVehicle();
180 else
181 SF_LOG_ERROR("network", "Player %u attempted to eject player %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(PassengerGUID));
182 }
183
184 else if (IS_CREATURE_GUID(PassengerGUID))
185 {
186 Unit* unit = ObjectAccessor::GetUnit(*_player, PassengerGUID);
187 if (!unit) // creatures can be ejected too from player mounts
188 {
189 SF_LOG_ERROR("network", "Player %u tried to eject creature guid %u from vehicle, but the latter was not found in world!", GetPlayer()->GetGUIDLow(), GUID_LOPART(PassengerGUID));
190 return;
191 }
192
193 if (!unit->IsOnVehicle(vehicle->GetBase()))
194 {
195 SF_LOG_ERROR("network", "Player %u tried to eject unit %u, but they are not in the same vehicle", GetPlayer()->GetGUIDLow(), GUID_LOPART(PassengerGUID));
196 return;
197 }
198
199 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(unit);
200 ASSERT(seat);
201 if (seat->IsEjectable())
202 {
203 ASSERT(GetPlayer() == vehicle->GetBase());
204 unit->ExitVehicle();
205 }
206 else
207 SF_LOG_ERROR("network", "Player %u attempted to eject creature GUID %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(PassengerGUID));
208 }
209 else
210 SF_LOG_ERROR("network", "HandleEjectPassenger: Player %u tried to eject invalid GUID %u", GetPlayer()->GetGUIDLow(), GUID_LOPART(PassengerGUID));
211}
212
214{
215 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
216
217 if (Vehicle* vehicle = GetPlayer()->GetVehicle())
218 {
219 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(GetPlayer()))
220 {
221 if (seat->CanEnterOrExit())
223 else
224 SF_LOG_ERROR("network", "Player %u tried to exit vehicle, but seatflags %u (ID: %u) don't permit that.",
225 GetPlayer()->GetGUIDLow(), seat->m_ID, seat->m_flags);
226 }
227 }
228}
229
231{
232 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_VEHICLE_REC_ID_ACK");
233
234 static MovementStatusElements const vehicleIdExtra = MSEExtraInt32;
235 Movement::ExtraMovementStatusElement extras(&vehicleIdExtra);
236 MovementInfo movementInfo;
237 GetPlayer()->ReadMovementInfo(recvData, &movementInfo, &extras);
238
239 uint32 vehicleId = extras.Data.extraInt32Data;
240
241 ObjectGuid vehicleGuid = GetPlayer()->GetGUID();
243 data.WriteGuidMask(vehicleGuid, 5, 7, 2, 1, 4, 0, 3, 6);
244 data.WriteGuidBytes(vehicleGuid, 5, 7, 4, 6, 2, 1, 3, 0);
245 data << uint32(vehicleId);
246 GetPlayer()->SendMessageToSet(&data, true);
247}
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
MovementStatusElements
@ MSEHasGuidByte6
@ MSEExtraInt32
@ MSEGuidByte6
@ MSEHasGuidByte4
@ MSEHasGuidByte5
@ MSEExtraInt8
@ MSEHasGuidByte3
@ MSEGuidByte1
@ MSEHasGuidByte0
@ MSEGuidByte2
@ MSEGuidByte0
@ MSEHasGuidByte7
@ MSEHasGuidByte2
@ MSEGuidByte3
@ MSEGuidByte5
@ MSEGuidByte7
@ MSEGuidByte4
@ MSEHasGuidByte1
#define INTERACTION_DISTANCE
Definition Object.h:21
uint32 GUID_LOPART(uint64 x)
bool IS_CREATURE_GUID(uint64 guid)
bool IS_PLAYER_GUID(uint64 guid)
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void rfinish()
Definition ByteBuffer.h:478
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
struct Movement::ExtraMovementStatusElement::@223034106340337246130275244156275117357303062005 Data
static Unit * GetUnit(WorldObject const &, uint64 guid)
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi, Movement::ExtraMovementStatusElement *extras=NULL)
Definition Player.cpp:22773
void SendMessageToSet(WorldPacket *data, bool self) override
Definition Player.h:2443
Definition Unit.h:1367
Vehicle * GetVehicle() const
Definition Unit.h:2743
Unit * GetVehicleBase() const
Definition Unit.cpp:7203
bool IsOnVehicle(const Unit *vehicle) const
Definition Unit.cpp:7198
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
void ChangeSeat(int8 seatId, bool next=true)
Definition Unit.cpp:8274
void ExitVehicle(Position const *exitPosition=NULL)
Definition Unit.cpp:8306
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:38
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
Definition Vehicle.cpp:614
MovementInfo m_movementInfo
Definition Object.h:807
Opcodes GetOpcode() const
Definition WorldPacket.h:38
void HandleDismissControlledVehicle(WorldPacket &recvData)
void HandleChangeSeatsOnControlledVehicle(WorldPacket &recvData)
void HandleEjectPassenger(WorldPacket &data)
Player * GetPlayer() const
void HandleRequestVehicleExit(WorldPacket &recvData)
void HandleRideVehicleInteract(WorldPacket &recvData)
void HandleMoveSetVehicleRecAck(WorldPacket &recvData)
Player * _player
@ CMSG_REQUEST_VEHICLE_SWITCH_SEAT
Definition Opcodes.h:400
@ SMSG_SET_VEHICLE_REC_ID
Definition Opcodes.h:965
@ CMSG_REQUEST_VEHICLE_NEXT_SEAT
Definition Opcodes.h:398
@ CMSG_REQUEST_VEHICLE_PREV_SEAT
Definition Opcodes.h:399
@ CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE
Definition Opcodes.h:110
uint64 guid
Definition Object.h:449
bool IsEjectable() const
bool CanSwitchFromSeat() const
uint32 m_flags