mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-27 12:22:39 +01:00
Core/Vehicles: Fixed crash in RemovePendingEventsForSeat - changed _pendingJoinEvents container from deque to list as deque invalidates all iterators pointing to the container (including .end()) when performing erase
This commit is contained in:
@@ -436,10 +436,6 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
|
||||
// exits the vehicle will dismiss. That's why the actual adding the passenger to the vehicle is scheduled
|
||||
// asynchronously, so it can be cancelled easily in case the vehicle is uninstalled meanwhile.
|
||||
SeatMap::iterator seat;
|
||||
VehicleJoinEvent* e = new VehicleJoinEvent(this, unit);
|
||||
unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0));
|
||||
_pendingJoinEvents.push_back(e);
|
||||
|
||||
if (seatId < 0) // no specific seat requirement
|
||||
{
|
||||
for (seat = Seats.begin(); seat != Seats.end(); ++seat)
|
||||
@@ -447,23 +443,22 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
|
||||
break;
|
||||
|
||||
if (seat == Seats.end()) // no available seat
|
||||
{
|
||||
CancelJoinEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
e->Seat = seat;
|
||||
VehicleJoinEvent* e = new VehicleJoinEvent(this, unit, seat);
|
||||
_pendingJoinEvents.push_back(e);
|
||||
unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
seat = Seats.find(seatId);
|
||||
if (seat == Seats.end())
|
||||
{
|
||||
CancelJoinEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
e->Seat = seat;
|
||||
VehicleJoinEvent* e = new VehicleJoinEvent(this, unit, seat);
|
||||
_pendingJoinEvents.push_back(e);
|
||||
unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0));
|
||||
|
||||
if (seat->second.Passenger)
|
||||
{
|
||||
Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger);
|
||||
@@ -687,25 +682,6 @@ void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o)
|
||||
x = (inx + iny * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void Vehicle::CancelJoinEvent(VehicleJoinEvent* e)
|
||||
*
|
||||
* @brief Aborts delayed @VehicleJoinEvent objects.
|
||||
* Implies that the related unit will not be boarding the vehicle after all.
|
||||
*
|
||||
* @author Machiavelli
|
||||
* @date 17-2-2013
|
||||
*
|
||||
* @param [in,out] e The VehicleJoinEvent* to process.
|
||||
*/
|
||||
|
||||
void Vehicle::CancelJoinEvent(VehicleJoinEvent* e)
|
||||
{
|
||||
ASSERT(_pendingJoinEvents.back() == e);
|
||||
e->to_Abort = true;
|
||||
_pendingJoinEvents.pop_back();
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void Vehicle::RemovePendingEvent(VehicleJoinEvent* e)
|
||||
*
|
||||
@@ -721,7 +697,7 @@ void Vehicle::CancelJoinEvent(VehicleJoinEvent* e)
|
||||
|
||||
void Vehicle::RemovePendingEvent(VehicleJoinEvent* e)
|
||||
{
|
||||
for (std::deque<VehicleJoinEvent*>::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
|
||||
for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
|
||||
{
|
||||
if (*itr == e)
|
||||
{
|
||||
@@ -744,7 +720,7 @@ void Vehicle::RemovePendingEvent(VehicleJoinEvent* e)
|
||||
|
||||
void Vehicle::RemovePendingEventsForSeat(int8 seatId)
|
||||
{
|
||||
for (std::deque<VehicleJoinEvent*>::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();)
|
||||
for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();)
|
||||
{
|
||||
if ((*itr)->Seat->first == seatId)
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "Object.h"
|
||||
#include "VehicleDefines.h"
|
||||
#include "Unit.h"
|
||||
#include <deque>
|
||||
#include <list>
|
||||
|
||||
struct VehicleEntry;
|
||||
class Unit;
|
||||
@@ -63,12 +63,8 @@ class Vehicle : public TransportBase
|
||||
void RelocatePassengers();
|
||||
void RemoveAllPassengers();
|
||||
void Dismiss();
|
||||
void TeleportVehicle(float x, float y, float z, float ang);
|
||||
bool IsVehicleInUse() { return Seats.begin() != Seats.end(); }
|
||||
|
||||
void SetLastShootPos(Position const& pos) { m_lastShootPos.Relocate(pos); }
|
||||
Position GetLastShootPos() { return m_lastShootPos; }
|
||||
|
||||
SeatMap Seats; ///< The collection of all seats on the vehicle. Including vacant ones.
|
||||
|
||||
VehicleSeatEntry const* GetSeatForPassenger(Unit* passenger);
|
||||
@@ -94,7 +90,6 @@ 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(int8 seatId);
|
||||
|
||||
@@ -105,15 +100,16 @@ class Vehicle : public TransportBase
|
||||
|
||||
uint32 _creatureEntry; ///< Can be different than the entry of _me in case of players
|
||||
Status _status; ///< Internal variable for sanity checks
|
||||
Position m_lastShootPos;
|
||||
std::deque<VehicleJoinEvent*> _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers
|
||||
|
||||
typedef std::list<VehicleJoinEvent*> PendingJoinEventContainer;
|
||||
PendingJoinEventContainer _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers
|
||||
};
|
||||
|
||||
class VehicleJoinEvent : public BasicEvent
|
||||
{
|
||||
friend class Vehicle;
|
||||
protected:
|
||||
VehicleJoinEvent(Vehicle* v, Unit* u) : Target(v), Passenger(u), Seat(Target->Seats.end()) {}
|
||||
VehicleJoinEvent(Vehicle* v, Unit* u, SeatMap::iterator seat) : Target(v), Passenger(u), Seat(seat) {}
|
||||
~VehicleJoinEvent() { Target->RemovePendingEvent(this); }
|
||||
bool Execute(uint64, uint32);
|
||||
void Abort(uint64);
|
||||
|
||||
Reference in New Issue
Block a user