public VehicleSeat GetNextEmptySeat(sbyte seatId, bool next) { var seat = Seats.LookupByKey(seatId); if (seat == null) { return(null); } foreach (var sea in Seats) { if (!seat.IsEmpty() || (!seat.SeatInfo.CanEnterOrExit() && !seat.SeatInfo.IsUsableByOverride())) { continue; } seat = sea.Value; } return(seat); }
public VehicleSeat GetNextEmptySeat(sbyte seatId, bool next) { var seat = Seats.LookupByKey(seatId); if (seat == null) { return(null); } var newSeatId = seatId; while (!seat.IsEmpty() || HasPendingEventForSeat(newSeatId) || (!seat.SeatInfo.CanEnterOrExit() && !seat.SeatInfo.IsUsableByOverride())) { if (next) { if (!Seats.ContainsKey(++newSeatId)) { newSeatId = 0; } } else { if (!Seats.ContainsKey(newSeatId)) { newSeatId = SharedConst.MaxVehicleSeats; } --newSeatId; } // Make sure we don't loop indefinetly if (newSeatId == seatId) { return(null); } seat = Seats[newSeatId]; } return(seat); }
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(this, unit); unit.m_Events.AddEvent(e, unit.m_Events.CalculateTime(0)); KeyValuePair <sbyte, VehicleSeat> seat = new(); 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); Cypher.Assert(passenger != null); passenger.ExitVehicle(); } Cypher.Assert(seat.Value.IsEmpty()); } return(true); }