Core/Vehicles: Fixed a crash that happened if someone called ExitVehicle during seat changing
This commit is contained in:
1 parent
5f16aad092
commit
16f9a9d1b4
3 files changed
+23
-8
No files matched your search
@@ -16605,7 +16605,12 @@ void Unit::ChangeSeat(int8 seatId, bool next)
|
||||
// Todo: the functions below could be consolidated and refactored to take
|
||||
// SeatMap::const_iterator as parameter, to save redundant map lookups.
|
||||
m_vehicle->RemovePassenger(this);
|
||||
if (!m_vehicle->AddPassenger(this, seatId))
|
||||
|
||||
// Set m_vehicle to NULL before adding passenger as adding new passengers is handled asynchronously
|
||||
// and someone may call ExitVehicle again before passenger is added to new seat
|
||||
Vehicle* veh = m_vehicle;
|
||||
m_vehicle = NULL;
|
||||
if (!veh->AddPassenger(this, seatId))
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -436,6 +436,9 @@ 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));
|
||||
|
||||
if (seatId < 0) // no specific seat requirement
|
||||
{
|
||||
for (seat = Seats.begin(); seat != Seats.end(); ++seat)
|
||||
@@ -443,22 +446,25 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
|
||||
break;
|
||||
|
||||
if (seat == Seats.end()) // no available seat
|
||||
{
|
||||
e->to_Abort = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
VehicleJoinEvent* e = new VehicleJoinEvent(this, unit, seat);
|
||||
e->Seat = seat;
|
||||
_pendingJoinEvents.push_back(e);
|
||||
unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
seat = Seats.find(seatId);
|
||||
if (seat == Seats.end())
|
||||
{
|
||||
e->to_Abort = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
VehicleJoinEvent* e = new VehicleJoinEvent(this, unit, seat);
|
||||
e->Seat = 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);
|
||||
@@ -480,7 +486,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
|
||||
* @author Machiavelli
|
||||
* @date 17-2-2013
|
||||
*
|
||||
* @param [in,out] unit The passenger to remove..
|
||||
* @param [in,out] unit The passenger to remove.
|
||||
*/
|
||||
|
||||
void Vehicle::RemovePassenger(Unit* unit)
|
||||
|
||||
@@ -65,6 +65,9 @@ class Vehicle : public TransportBase
|
||||
void Dismiss();
|
||||
bool IsVehicleInUse() { return Seats.begin() != Seats.end(); }
|
||||
|
||||
void SetLastShootPos(Position const& pos) { _lastShootPos.Relocate(pos); }
|
||||
Position GetLastShootPos() { return _lastShootPos; }
|
||||
|
||||
SeatMap Seats; ///< The collection of all seats on the vehicle. Including vacant ones.
|
||||
|
||||
VehicleSeatEntry const* GetSeatForPassenger(Unit* passenger);
|
||||
@@ -100,6 +103,7 @@ 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 _lastShootPos;
|
||||
|
||||
typedef std::list<VehicleJoinEvent*> PendingJoinEventContainer;
|
||||
PendingJoinEventContainer _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers
|
||||
@@ -109,7 +113,7 @@ class VehicleJoinEvent : public BasicEvent
|
||||
{
|
||||
friend class Vehicle;
|
||||
protected:
|
||||
VehicleJoinEvent(Vehicle* v, Unit* u, SeatMap::iterator seat) : Target(v), Passenger(u), Seat(seat) {}
|
||||
VehicleJoinEvent(Vehicle* v, Unit* u) : Target(v), Passenger(u), Seat(Target->Seats.end()) {}
|
||||
~VehicleJoinEvent() { Target->RemovePendingEvent(this); }
|
||||
bool Execute(uint64, uint32);
|
||||
void Abort(uint64);
|
||||
|
||||
Reference in new issue
Block a user