public void RemovePendingEvent(VehicleJoinEvent e) { foreach (var Event in _pendingJoinEvents) { if (Event == e) { _pendingJoinEvents.Remove(Event); break; } } }
public void RemoveAllPassengers() { Log.outDebug(LogFilter.Vehicle, "Vehicle.RemoveAllPassengers. Entry: {0}, GuidLow: {1}", _creatureEntry, _me.GetGUID().ToString()); // Setting to_Abort to true will cause @VehicleJoinEvent.Abort to be executed on next @Unit.UpdateEvents call // This will properly "reset" the pending join process for the passenger. { // Update vehicle in every pending join event - Abort may be called after vehicle is deleted Vehicle eventVehicle = _status != Status.UnInstalling ? this : null; while (!_pendingJoinEvents.Empty()) { VehicleJoinEvent e = _pendingJoinEvents.First(); e.ScheduleAbort(); e.Target = eventVehicle; _pendingJoinEvents.Remove(_pendingJoinEvents.First()); } } // Passengers always cast an aura with SPELL_AURA_CONTROL_VEHICLE on the vehicle // We just remove the aura and the unapply handler will make the target leave the vehicle. // We don't need to iterate over Seats _me.RemoveAurasByType(AuraType.ControlVehicle); }
public bool AddPassenger(Unit unit, sbyte seatId) { // @Prevent adding passengers when vehicle is uninstalling. (Bad script in OnUninstall/OnRemovePassenger/PassengerBoarded hook.) if (_status == Status.UnInstalling) { Log.outError(LogFilter.Vehicle, "Passenger GuidLow: {0}, Entry: {1}, attempting to board vehicle GuidLow: {2}, Entry: {3} during uninstall! SeatId: {4}", unit.GetGUID().ToString(), unit.GetEntry(), _me.GetGUID().ToString(), _me.GetEntry(), seatId); return(false); } Log.outDebug(LogFilter.Vehicle, "Unit {0} scheduling enter vehicle (entry: {1}, vehicleId: {2}, guid: {3} (dbguid: {4}) on seat {5}", unit.GetName(), _me.GetEntry(), _vehicleInfo.Id, _me.GetGUID().ToString(), (_me.IsTypeId(TypeId.Unit) ? _me.ToCreature().GetSpawnId() : 0), seatId); // The seat selection code may kick other passengers off the vehicle. // While the validity of the following may be arguable, it is possible that when such a passenger // 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. VehicleJoinEvent e = new VehicleJoinEvent(this, unit); unit.m_Events.AddEvent(e, unit.m_Events.CalculateTime(0)); KeyValuePair <sbyte, VehicleSeat> seat = new KeyValuePair <sbyte, VehicleSeat>(); if (seatId < 0) // no specific seat requirement { foreach (var _seat in Seats) { seat = _seat; if (seat.Value.IsEmpty() && (_seat.Value.SeatInfo.CanEnterOrExit() || _seat.Value.SeatInfo.IsUsableByOverride())) { break; } } if (seat.Value == null) // no available seat { e.ScheduleAbort(); return(false); } e.Seat = seat; _pendingJoinEvents.Add(e); } else { seat = new KeyValuePair <sbyte, VehicleSeat>(seatId, Seats.LookupByKey(seatId)); if (seat.Value == null) { e.ScheduleAbort(); return(false); } e.Seat = seat; _pendingJoinEvents.Add(e); if (!seat.Value.IsEmpty()) { Unit passenger = Global.ObjAccessor.GetUnit(GetBase(), seat.Value.Passenger.Guid); Contract.Assert(passenger != null); passenger.ExitVehicle(); } Contract.Assert(seat.Value.IsEmpty()); } return(true); }