Core/Vehicles: Fix a crash in VehicleJoinEvent::Execute

Crash would happen if multiple events were scheduled for the same seat.
Fixes #9255
This commit is contained in:
Machiavelli
2013-02-23 15:12:39 +01:00
parent 729a37363b
commit b91c33dca5
2 changed files with 31 additions and 2 deletions

View File

@@ -701,6 +701,7 @@ void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o)
void Vehicle::CancelJoinEvent(VehicleJoinEvent* e)
{
ASSERT(_pendingJoinEvents.back() == e);
e->to_Abort = true;
_pendingJoinEvents.pop_back();
}
@@ -730,6 +731,29 @@ void Vehicle::RemovePendingEvent(VehicleJoinEvent* e)
}
}
/**
* @fn void Vehicle::RemovePendingEventsForSeat(uint8 seatId)
*
* @brief Removes any pending events for given seatId. Executed when a @VehicleJoinEvent::Execute is called
*
* @author Machiavelli
* @date 23-2-2013
*
* @param seatId Identifier for the seat.
*/
void Vehicle::RemovePendingEventsForSeat(uint8 seatId)
{
for (std::deque<VehicleJoinEvent*>::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
{
if (uint8((*itr)->Seat->first) == seatId)
{
(*itr)->to_Abort = true;
_pendingJoinEvents.erase(itr);
}
}
}
/**
* @fn bool VehicleJoinEvent::Execute(uint64, uint32)
*
@@ -750,6 +774,8 @@ bool VehicleJoinEvent::Execute(uint64, uint32)
ASSERT(Passenger->IsInWorld());
ASSERT(Target->GetBase()->IsInWorld());
Target->RemovePendingEventsForSeat(uint8(Seat->first));
Passenger->m_vehicle = Target;
Seat->second.Passenger = Passenger->GetGUID();
if (Seat->second.SeatInfo->CanEnterOrExit())

View File

@@ -94,6 +94,11 @@ class Vehicle : public TransportBase
/// This method transforms supplied global coordinates into local offsets
void CalculatePassengerOffset(float& x, float& y, float& z, float& o);
void CancelJoinEvent(VehicleJoinEvent* e);
void RemovePendingEvent(VehicleJoinEvent* e);
void RemovePendingEventsForSeat(uint8 seatId);
private:
Unit* _me; ///< The underlying unit with the vehicle kit. Can be player or creature.
VehicleEntry const* _vehicleInfo; ///< DBC data for vehicle
GuidSet vehiclePlayers;
@@ -102,8 +107,6 @@ class Vehicle : public TransportBase
Status _status; ///< Internal variable for sanity checks
Position m_lastShootPos;
std::deque<VehicleJoinEvent*> _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers
void CancelJoinEvent(VehicleJoinEvent* e);
void RemovePendingEvent(VehicleJoinEvent* e);
};
class VehicleJoinEvent : public BasicEvent