Core/Vehicles&Movement:

- Send correct SMSG_MONSTER_MOVE with newly discovered SPLINEFLAG_EXIT_VEHICLE on vehicle exit. Fixes the "stuck on exit" bug as a result of removing the previous hack in 04b656a44f.
- Use SMSG_SPLINE_MOVE_ROOT and SMSG_SPLINE_MOVE_UNROOT as root packets for creatures.
- Reimplement toggling of MOVEMENTFLAG_ROOT on root event (including enter vehicle)
- Speedup in fetching movementflags for vehicles depending on vehicleflags on object updates.
- Code cleanup and refactoring
This commit is contained in:
Machiavelli
2011-02-26 03:47:23 +01:00
parent 98f6c2fe80
commit 30738e645f
6 changed files with 313 additions and 256 deletions
@@ -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);
@@ -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);
}
}
}