diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 116 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 3 | ||||
-rwxr-xr-x | src/server/game/Entities/Vehicle/Vehicle.cpp | 26 | ||||
-rwxr-xr-x | src/server/game/Entities/Vehicle/Vehicle.h | 1 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/MovementHandler.cpp | 201 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Handlers/VehicleHandler.cpp | 222 |
6 files changed, 313 insertions, 256 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2c697245ca1..9cc92c7e7d4 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -435,6 +435,27 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 M SendMessageToSet(&data, true); } +void Unit::SendMonsterMoveExitVehicle(Position const* newPos) +{ + WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size()); + data.append(GetPackGUID()); + + data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // new in 3.1, bool + data << GetPositionX() << GetPositionY() << GetPositionZ(); + data << getMSTime(); + + data << uint8(SPLINETYPE_FACING_ANGLE); + data << float(GetOrientation()); // guess + data << uint32(SPLINEFLAG_EXIT_VEHICLE); + data << uint32(0); // Time in between points + data << uint32(1); // 1 single waypoint + data << newPos->GetPositionX(); + data << newPos->GetPositionY(); + data << newPos->GetPositionZ(); + + SendMessageToSet(&data, true); +} + void Unit::SendMonsterMoveTransport(Unit *vehicleOwner) { // TODO: Turn into BuildMonsterMoveTransport packet and allow certain variables (for npc movement aboard vehicles) @@ -442,7 +463,7 @@ void Unit::SendMonsterMoveTransport(Unit *vehicleOwner) data.append(GetPackGUID()); data.append(vehicleOwner->GetPackGUID()); data << int8(GetTransSeat()); - data << uint8(0); // unk boolean + data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // boolean data << GetPositionX() - vehicleOwner->GetPositionX(); data << GetPositionY() - vehicleOwner->GetPositionY(); data << GetPositionZ() - vehicleOwner->GetPositionZ(); @@ -451,7 +472,7 @@ void Unit::SendMonsterMoveTransport(Unit *vehicleOwner) data << GetTransOffsetO(); // facing angle? data << uint32(SPLINEFLAG_TRANSPORT); data << uint32(GetTransTime()); // move time - data << uint32(0); // amount of waypoints + data << uint32(1); // amount of waypoints data << uint32(0); // waypoint X data << uint32(0); // waypoint Y data << uint32(0); // waypoint Z @@ -15301,28 +15322,42 @@ void Unit::SetRooted(bool apply) if (m_rootTimes > 0) //blizzard internal check? m_rootTimes++; -// AddUnitMovementFlag(MOVEMENTFLAG_ROOT); - - WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); - data.append(GetPackGUID()); - data << m_rootTimes; - SendMessageToSet(&data,true); + AddUnitMovementFlag(MOVEMENTFLAG_ROOT); - if (GetTypeId() != TYPEID_PLAYER) + if (Player* thisPlr = this->ToPlayer()) + { + WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); + data.append(GetPackGUID()); + data << m_rootTimes; + SendMessageToSet(&data,true); + } + else + { + WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8); + data.append(GetPackGUID()); + SendMessageToSet(&data,true); ToCreature()->StopMoving(); + } } else { if (!HasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect { - m_rootTimes++; //blizzard internal check? - - WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10); - data.append(GetPackGUID()); - data << m_rootTimes; - SendMessageToSet(&data,true); + if (Player* thisPlr = this->ToPlayer()) + { + WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10); + data.append(GetPackGUID()); + data << ++m_rootTimes; + SendMessageToSet(&data,true); + } + else + { + WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); + data.append(GetPackGUID()); + SendMessageToSet(&data,true); + } -// RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT); + RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT); } } } @@ -16465,6 +16500,12 @@ void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId, AuraApplication const * a if (aurApp && aurApp->GetRemoveMode()) return; + if (Player* thisPlr = this->ToPlayer()) + { + WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); + thisPlr->GetSession()->SendPacket(&data); + } + ASSERT(!m_vehicle); m_vehicle = vehicle; if (!m_vehicle->AddPassenger(this, seatId)) @@ -16472,19 +16513,6 @@ void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId, AuraApplication const * a m_vehicle = NULL; return; } - - if (Player* thisPlr = this->ToPlayer()) - { - WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); - thisPlr->GetSession()->SendPacket(&data); - } - - SendClearTarget(); - - SetControlled(true, UNIT_STAT_ROOT); - //movementInfo is set in AddPassenger - //packets are sent in AddPassenger - } void Unit::ChangeSeat(int8 seatId, bool next) @@ -16531,23 +16559,31 @@ void Unit::ExitVehicle(Position const* exitPosition) Vehicle *vehicle = m_vehicle; m_vehicle = NULL; - SetControlled(false, UNIT_STAT_ROOT); // SMSG_MOVE_FORCE_UNROOT + SetControlled(false, UNIT_STAT_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT - if (exitPosition) // Exit position specified - Relocate(exitPosition); + Position pos; + if (!exitPosition) // Exit position not specified + vehicle->GetBase()->GetPosition(&pos); else - Relocate(vehicle->GetBase()); // Relocate to vehicle base + pos = *exitPosition; + + AddUnitState(UNIT_STAT_MOVE); - //Send leave vehicle, not correct if (GetTypeId() == TYPEID_PLAYER) - { - //this->ToPlayer()->SetClientControl(this, 1); this->ToPlayer()->SetFallInformation(0, GetPositionZ()); + else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT)) + { + WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); + data.append(GetPackGUID()); + SendMessageToSet(&data, false); } - WorldPacket data; - BuildHeartBeatMsg(&data); - SendMessageToSet(&data, false); + SendMonsterMoveExitVehicle(&pos); + Relocate(&pos); + + WorldPacket data2; + BuildHeartBeatMsg(&data2); + SendMessageToSet(&data2, false); if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION)) if (((Minion*)vehicle->GetBase())->GetOwner() == this) @@ -16561,8 +16597,6 @@ void Unit::BuildMovementPacket(ByteBuffer *data) const case TYPEID_UNIT: if (canFly()) const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - if (IsVehicle()) - const_cast<Unit*>(this)->AddExtraUnitMovementFlag(GetVehicleKit()->GetExtraMovementFlagsForBase()); break; case TYPEID_PLAYER: // remove unknown, unused etc flags for now diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 25509e2230f..cb35ee7bafd 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -721,7 +721,7 @@ enum SplineFlags SPLINEFLAG_UNKNOWN22 = 0x00200000, SPLINEFLAG_UNKNOWN23 = 0x00400000, SPLINEFLAG_TRANSPORT = 0x00800000, - SPLINEFLAG_UNKNOWN25 = 0x01000000, + SPLINEFLAG_EXIT_VEHICLE = 0x01000000, SPLINEFLAG_UNKNOWN26 = 0x02000000, SPLINEFLAG_UNKNOWN27 = 0x04000000, SPLINEFLAG_UNKNOWN28 = 0x08000000, @@ -1521,6 +1521,7 @@ class Unit : public WorldObject void SendMonsterStop(bool on_death = false); void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL); void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player = NULL); + void SendMonsterMoveExitVehicle(Position const* newPos); //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); void SendMonsterMoveTransport(Unit *vehicleOwner); void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index bb8c443d09a..e22fe9668e4 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -61,6 +61,8 @@ Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleI default: break; } + + InitMovementInfoForBase(); } Vehicle::~Vehicle() @@ -373,8 +375,10 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) if (me->IsInWorld()) { - // In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) - unit->SendMonsterMoveTransport(me); + unit->SendClearTarget(); // SMSG_BREAK_TARGET + unit->SetControlled(true, UNIT_STAT_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) + // also adds MOVEMENTFLAG_ROOT + unit->SendMonsterMoveTransport(me); // SMSG_MONSTER_MOVE_TRANSPORT if (me->GetTypeId() == TYPEID_UNIT) { @@ -476,29 +480,25 @@ void Vehicle::Dismiss() { sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Dismiss %u", me->GetEntry()); Uninstall(); - me->SendObjectDeSpawnAnim(me->GetGUID()); + me->DestroyForNearbyPlayers(); me->CombatStop(); me->AddObjectToRemoveList(); } -uint16 Vehicle::GetExtraMovementFlagsForBase() const +void Vehicle::InitMovementInfoForBase() { - uint16 movementMask = MOVEMENTFLAG2_NONE; uint32 vehicleFlags = GetVehicleInfo()->m_flags; if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE) - movementMask |= MOVEMENTFLAG2_NO_STRAFE; + me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_STRAFE); if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING) - movementMask |= MOVEMENTFLAG2_NO_JUMPING; + me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_JUMPING); if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING) - movementMask |= MOVEMENTFLAG2_FULL_SPEED_TURNING; + me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_TURNING); if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING) - movementMask |= MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING; + me->AddExtraUnitMovementFlag( MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING); if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING) - movementMask |= MOVEMENTFLAG2_FULL_SPEED_PITCHING; - - sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::GetExtraMovementFlagsForBase() returned %u", movementMask); - return movementMask; + me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING); } VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit* passenger) diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 03e283548d4..8ec342e21e5 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -145,6 +145,7 @@ class Vehicle private: SeatMap::iterator GetSeatIteratorForPassenger(Unit* passenger); + void InitMovementInfoForBase(); protected: Unit *me; diff --git a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp index 3624773a9b4..671f7541cf7 100755 --- a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp @@ -23,7 +23,6 @@ #include "Log.h" #include "Corpse.h" #include "Player.h" -#include "Vehicle.h" #include "SpellAuras.h" #include "MapManager.h" #include "Transport.h" @@ -513,206 +512,6 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) _player->m_movementInfo = mi; } -void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) -{ - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE"); - recv_data.hexlike(); - - uint64 vehicleGUID = _player->GetCharmGUID(); - - if (!vehicleGUID) // something wrong here... - { - recv_data.rpos(recv_data.wpos()); // prevent warnings spam - return; - } - - uint64 guid; - - recv_data.readPackGUID(guid); - - MovementInfo mi; - mi.guid = guid; - ReadMovementInfo(recv_data, &mi); - - _player->m_movementInfo = mi; - - _player->ExitVehicle(); -} - -void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) -{ - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE"); - recv_data.hexlike(); - - Unit* vehicle_base = GetPlayer()->GetVehicleBase(); - if (!vehicle_base) - return; - - VehicleSeatEntry const* seat = GetPlayer()->GetVehicle()->GetSeatForPassenger(GetPlayer()); - if (!seat->CanSwitchFromSeat()) - { - sLog->outError("HandleChangeSeatsOnControlledVehicle, Opcode: %u, Player %u tried to switch seats but current seatflags %u don't permit that.", - recv_data.GetOpcode(), GetPlayer()->GetGUIDLow(), seat->m_flags); - return; - } - - switch (recv_data.GetOpcode()) - { - case CMSG_REQUEST_VEHICLE_PREV_SEAT: - GetPlayer()->ChangeSeat(-1, false); - break; - case CMSG_REQUEST_VEHICLE_NEXT_SEAT: - GetPlayer()->ChangeSeat(-1, true); - break; - case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE: - { - uint64 guid; // current vehicle guid - recv_data.readPackGUID(guid); - - ReadMovementInfo(recv_data, &vehicle_base->m_movementInfo); - - uint64 accessory; // accessory guid - recv_data.readPackGUID(accessory); - - int8 seatId; - recv_data >> seatId; - - if (vehicle_base->GetGUID() != guid) - return; - - if (!accessory) - GetPlayer()->ChangeSeat(-1, seatId > 0); // prev/next - else if (Unit *vehUnit = Unit::GetUnit(*GetPlayer(), accessory)) - { - if (Vehicle *vehicle = vehUnit->GetVehicleKit()) - if (vehicle->HasEmptySeat(seatId)) - GetPlayer()->EnterVehicle(vehicle, seatId); - } - } - break; - case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: - { - uint64 guid; // current vehicle guid - recv_data.readPackGUID(guid); - - int8 seatId; - recv_data >> seatId; - - if (vehicle_base->GetGUID() == guid) - GetPlayer()->ChangeSeat(seatId); - else if (Unit *vehUnit = Unit::GetUnit(*GetPlayer(), guid)) - if (Vehicle *vehicle = vehUnit->GetVehicleKit()) - if (vehicle->HasEmptySeat(seatId)) - GetPlayer()->EnterVehicle(vehicle, seatId); - } - break; - default: - break; - } -} - -void WorldSession::HandleEnterPlayerVehicle(WorldPacket &data) -{ - // Read guid - uint64 guid; - data >> guid; - - if (Player* pl=ObjectAccessor::FindPlayer(guid)) - { - if (!pl->GetVehicleKit()) - return; - if (!pl->IsInRaidWith(_player)) - return; - if (!pl->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) - return; - _player->EnterVehicle(pl); - } -} - -void WorldSession::HandleEjectPassenger(WorldPacket &data) -{ - Vehicle* vehicle = _player->GetVehicleKit(); - if (!vehicle) - { - sLog->outError("HandleEjectPassenger: Player %u is not in a vehicle!", GetPlayer()->GetGUIDLow()); - return; - } - - uint64 guid; - data >> guid; - - if (IS_PLAYER_GUID(guid)) - { - Player *plr = ObjectAccessor::FindPlayer(guid); - if (!plr) - { - sLog->outError("Player %u tried to eject player %u from vehicle, but the latter was not found in world!", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); - return; - } - - if (!plr->IsOnVehicle(vehicle->GetBase())) - { - sLog->outError("Player %u tried to eject player %u, but they are not in the same vehicle", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); - return; - } - - VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(plr); - ASSERT(seat); - if (seat->IsEjectable()) - plr->ExitVehicle(); - else - sLog->outError("Player %u attempted to eject player %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); - } - - else if (IS_CREATURE_GUID(guid)) - { - Unit *unit = ObjectAccessor::GetUnit(*_player, guid); - if (!unit) // creatures can be ejected too from player mounts - { - sLog->outError("Player %u tried to eject creature guid %u from vehicle, but the latter was not found in world!", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); - return; - } - - if (!unit->IsOnVehicle(vehicle->GetBase())) - { - sLog->outError("Player %u tried to eject unit %u, but they are not in the same vehicle", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); - return; - } - - VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(unit); - ASSERT(seat); - if (seat->IsEjectable()) - { - ASSERT(GetPlayer() == vehicle->GetBase()); - unit->ExitVehicle(); - unit->ToCreature()->DespawnOrUnsummon(1000); - ASSERT(!unit->IsOnVehicle(vehicle->GetBase())); - } - else - sLog->outError("Player %u attempted to eject creature GUID %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); - } - else - sLog->outError("HandleEjectPassenger: Player %u tried to eject invalid GUID "UI64FMTD, GetPlayer()->GetGUIDLow(), guid); -} - -void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data) -{ - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT"); - recv_data.hexlike(); - - if (Vehicle* vehicle = GetPlayer()->GetVehicle()) - { - if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(GetPlayer())) - { - if (seat->CanEnterOrExit()) - GetPlayer()->ExitVehicle(); - else - sLog->outError("Player %u tried to exit vehicle, but seatflags %u (ID: %u) don't permit that.", - GetPlayer()->GetGUIDLow(), seat->m_ID, seat->m_flags); - } - } -} - void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recv_data*/) { WorldPacket data(SMSG_MOUNTSPECIAL_ANIM, 8); diff --git a/src/server/game/Server/Protocol/Handlers/VehicleHandler.cpp b/src/server/game/Server/Protocol/Handlers/VehicleHandler.cpp new file mode 100644 index 00000000000..296ae23899c --- /dev/null +++ b/src/server/game/Server/Protocol/Handlers/VehicleHandler.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2008-2011 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 "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Vehicle.h" +#include "Player.h" +#include "Log.h" + +void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE"); + recv_data.hexlike(); + + uint64 vehicleGUID = _player->GetCharmGUID(); + + if (!vehicleGUID) // something wrong here... + { + recv_data.rpos(recv_data.wpos()); // prevent warnings spam + return; + } + + uint64 guid; + + recv_data.readPackGUID(guid); + + MovementInfo mi; + mi.guid = guid; + ReadMovementInfo(recv_data, &mi); + + _player->m_movementInfo = mi; + + _player->ExitVehicle(); +} + +void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE"); + recv_data.hexlike(); + + Unit* vehicle_base = GetPlayer()->GetVehicleBase(); + if (!vehicle_base) + return; + + VehicleSeatEntry const* seat = GetPlayer()->GetVehicle()->GetSeatForPassenger(GetPlayer()); + if (!seat->CanSwitchFromSeat()) + { + sLog->outError("HandleChangeSeatsOnControlledVehicle, Opcode: %u, Player %u tried to switch seats but current seatflags %u don't permit that.", + recv_data.GetOpcode(), GetPlayer()->GetGUIDLow(), seat->m_flags); + return; + } + + switch (recv_data.GetOpcode()) + { + case CMSG_REQUEST_VEHICLE_PREV_SEAT: + GetPlayer()->ChangeSeat(-1, false); + break; + case CMSG_REQUEST_VEHICLE_NEXT_SEAT: + GetPlayer()->ChangeSeat(-1, true); + break; + case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE: + { + uint64 guid; // current vehicle guid + recv_data.readPackGUID(guid); + + ReadMovementInfo(recv_data, &vehicle_base->m_movementInfo); + + uint64 accessory; // accessory guid + recv_data.readPackGUID(accessory); + + int8 seatId; + recv_data >> seatId; + + if (vehicle_base->GetGUID() != guid) + return; + + if (!accessory) + GetPlayer()->ChangeSeat(-1, seatId > 0); // prev/next + else if (Unit *vehUnit = Unit::GetUnit(*GetPlayer(), accessory)) + { + if (Vehicle *vehicle = vehUnit->GetVehicleKit()) + if (vehicle->HasEmptySeat(seatId)) + GetPlayer()->EnterVehicle(vehicle, seatId); + } + } + break; + case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: + { + uint64 guid; // current vehicle guid + recv_data.readPackGUID(guid); + + int8 seatId; + recv_data >> seatId; + + if (vehicle_base->GetGUID() == guid) + GetPlayer()->ChangeSeat(seatId); + else if (Unit *vehUnit = Unit::GetUnit(*GetPlayer(), guid)) + if (Vehicle *vehicle = vehUnit->GetVehicleKit()) + if (vehicle->HasEmptySeat(seatId)) + GetPlayer()->EnterVehicle(vehicle, seatId); + } + break; + default: + break; + } +} + +void WorldSession::HandleEnterPlayerVehicle(WorldPacket &data) +{ + // Read guid + uint64 guid; + data >> guid; + + if (Player* pl=ObjectAccessor::FindPlayer(guid)) + { + if (!pl->GetVehicleKit()) + return; + if (!pl->IsInRaidWith(_player)) + return; + if (!pl->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) + return; + _player->EnterVehicle(pl); + } +} + +void WorldSession::HandleEjectPassenger(WorldPacket &data) +{ + Vehicle* vehicle = _player->GetVehicleKit(); + if (!vehicle) + { + sLog->outError("HandleEjectPassenger: Player %u is not in a vehicle!", GetPlayer()->GetGUIDLow()); + return; + } + + uint64 guid; + data >> guid; + + if (IS_PLAYER_GUID(guid)) + { + Player *plr = ObjectAccessor::FindPlayer(guid); + if (!plr) + { + sLog->outError("Player %u tried to eject player %u from vehicle, but the latter was not found in world!", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); + return; + } + + if (!plr->IsOnVehicle(vehicle->GetBase())) + { + sLog->outError("Player %u tried to eject player %u, but they are not in the same vehicle", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); + return; + } + + VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(plr); + ASSERT(seat); + if (seat->IsEjectable()) + plr->ExitVehicle(); + else + sLog->outError("Player %u attempted to eject player %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); + } + + else if (IS_CREATURE_GUID(guid)) + { + Unit *unit = ObjectAccessor::GetUnit(*_player, guid); + if (!unit) // creatures can be ejected too from player mounts + { + sLog->outError("Player %u tried to eject creature guid %u from vehicle, but the latter was not found in world!", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); + return; + } + + if (!unit->IsOnVehicle(vehicle->GetBase())) + { + sLog->outError("Player %u tried to eject unit %u, but they are not in the same vehicle", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); + return; + } + + VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(unit); + ASSERT(seat); + if (seat->IsEjectable()) + { + ASSERT(GetPlayer() == vehicle->GetBase()); + unit->ExitVehicle(); + unit->AddObjectToRemoveList(); + } + else + sLog->outError("Player %u attempted to eject creature GUID %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); + } + else + sLog->outError("HandleEjectPassenger: Player %u tried to eject invalid GUID "UI64FMTD, GetPlayer()->GetGUIDLow(), guid); +} + +void WorldSession::HandleRequestVehicleExit(WorldPacket &recv_data) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT"); + recv_data.hexlike(); + + if (Vehicle* vehicle = GetPlayer()->GetVehicle()) + { + if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(GetPlayer())) + { + if (seat->CanEnterOrExit()) + GetPlayer()->ExitVehicle(); + else + sLog->outError("Player %u tried to exit vehicle, but seatflags %u (ID: %u) don't permit that.", + GetPlayer()->GetGUIDLow(), seat->m_ID, seat->m_flags); + } + } +}
\ No newline at end of file |