/** * This function will switch the seat of a passenger on the same vehicle * * @param passenger MUST be provided. This Unit will change its seat on the vehicle * @param seat Seat to which the passenger will be switched */ void VehicleInfo::SwitchSeat(Unit* passenger, uint8 seat) { MANGOS_ASSERT(passenger); DEBUG_LOG("VehicleInfo::SwitchSeat: passenger: %s try to switch to seat %u", passenger->GetGuidStr().c_str(), seat); // Switching seats is not possible if (m_vehicleEntry->m_flags & VEHICLE_FLAG_DISABLE_SWITCH) return; PassengerMap::const_iterator itr = m_passengers.find(passenger); MANGOS_ASSERT(itr != m_passengers.end()); // We are already boarded to this seat if (itr->second->GetTransportSeat() == seat) return; // Check if it's a valid seat if (!IsSeatAvailableFor(passenger, seat)) return; VehicleSeatEntry const* seatEntry = GetSeatEntry(itr->second->GetTransportSeat()); MANGOS_ASSERT(seatEntry); // Switching seats is only allowed if this flag is set if (~seatEntry->m_flags & SEAT_FLAG_CAN_SWITCH) return; // Remove passenger modifications of the old seat RemoveSeatMods(passenger, seatEntry->m_flags); // Set to new seat itr->second->SetTransportSeat(seat); Movement::MoveSplineInit init(*passenger); init.MoveTo(0.0f, 0.0f, 0.0f); // ToDo: Set correct local coords //if (oldorientation != neworientation) (?) //init.SetFacing(0.0f); // local orientation ? ToDo: Set proper orientation! // It seems that Seat switching is sent without SplineFlag BoardVehicle init.Launch(); // Get seatEntry of new seat seatEntry = GetSeatEntry(seat); MANGOS_ASSERT(seatEntry); // Apply passenger modifications of the new seat ApplySeatMods(passenger, seatEntry->m_flags); }
/** * This function will Unboard a passenger * * @param passenger MUST be provided. This Unit will be unboarded from the vehicle * @param changeVehicle If set, the passenger is expected to be directly boarded to another vehicle, * and hence he will not be unboarded but only removed from this vehicle. */ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle) { MANGOS_ASSERT(passenger); DEBUG_LOG("VehicleInfo::Unboard: passenger: %s", passenger->GetGuidStr().c_str()); PassengerMap::const_iterator itr = m_passengers.find(passenger); MANGOS_ASSERT(itr != m_passengers.end()); VehicleSeatEntry const* seatEntry = GetSeatEntry(itr->second->GetTransportSeat()); MANGOS_ASSERT(seatEntry); UnBoardPassenger(passenger); // Use TransportBase to remove the passenger from storage list if (!changeVehicle) // Send expected unboarding packages { // Update movementInfo passenger->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT); passenger->m_movementInfo.ClearTransportData(); if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* pPlayer = (Player*)passenger; pPlayer->ResummonPetTemporaryUnSummonedIfAny(); // SMSG_PET_DISMISS_SOUND (?) } if (passenger->IsRooted()) passenger->SetRoot(false); Movement::MoveSplineInit init(*passenger); // ToDo: Set proper unboard coordinates init.MoveTo(m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ()); init.SetExitVehicle(); init.Launch(); } // Remove passenger modifications RemoveSeatMods(passenger, seatEntry->m_flags); }
/** * This function will Unboard a passenger * * @param passenger MUST be provided. This Unit will be unboarded from the vehicle * @param changeVehicle If set, the passenger is expected to be directly boarded to another vehicle, * and hence he will not be unboarded but only removed from this vehicle. */ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle) { MANGOS_ASSERT(passenger); DEBUG_LOG("VehicleInfo::Unboard: passenger: %s", passenger->GetGuidStr().c_str()); PassengerMap::const_iterator itr = m_passengers.find(passenger); MANGOS_ASSERT(itr != m_passengers.end()); VehicleSeatEntry const* seatEntry = GetSeatEntry(itr->second->GetTransportSeat()); MANGOS_ASSERT(seatEntry); UnBoardPassenger(passenger); // Use TransportBase to remove the passenger from storage list if (!changeVehicle) // Send expected unboarding packages { // Update movementInfo passenger->m_movementInfo.ClearTransportData(); if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* pPlayer = (Player*)passenger; pPlayer->ResummonPetTemporaryUnSummonedIfAny(); // SMSG_PET_DISMISS_SOUND (?) } if (passenger->IsRooted()) passenger->SetRoot(false); Movement::MoveSplineInit init(*passenger); // ToDo: Set proper unboard coordinates init.MoveTo(m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ()); init.SetExitVehicle(); init.Launch(); // Despawn if passenger was accessory if (passenger->GetTypeId() == TYPEID_UNIT && m_accessoryGuids.find(passenger->GetObjectGuid()) != m_accessoryGuids.end()) { // TODO Same TODO as in VehicleInfo::RemoveAccessoriesFromMap ((Creature*)passenger)->ForcedDespawn(5000); m_accessoryGuids.erase(passenger->GetObjectGuid()); } } // Remove passenger modifications RemoveSeatMods(passenger, seatEntry->m_flags); // Some creature vehicles get despawned after passenger unboarding if (m_owner->GetTypeId() == TYPEID_UNIT) { // TODO: Guesswork, but seems to be fairly near correct // Only if the passenger was on control seat? Also depending on some flags if ((seatEntry->m_flags & SEAT_FLAG_CAN_CONTROL) && !(m_vehicleEntry->m_flags & (VEHICLE_FLAG_UNK4 | VEHICLE_FLAG_UNK20))) { if (((Creature*)m_owner)->IsTemporarySummon()) ((Creature*)m_owner)->ForcedDespawn(1000); } } }
/** * This function will board a passenger onto a vehicle * * @param passenger MUST be provided. This Unit will be boarded onto the vehicles (if it checks out) * @param seat Seat to which the passenger will be boarded (if can, elsewise an alternative will be selected if possible) */ void VehicleInfo::Board(Unit* passenger, uint8 seat) { MANGOS_ASSERT(passenger); DEBUG_LOG("VehicleInfo::Board: Try to board passenger %s to seat %u", passenger->GetGuidStr().c_str(), seat); // This check is also called in Spell::CheckCast() if (!CanBoard(passenger)) return; // Use the planned seat only if the seat is valid, possible to choose and empty if (!IsSeatAvailableFor(passenger, seat)) if (!GetUsableSeatFor(passenger, seat)) return; VehicleSeatEntry const* seatEntry = GetSeatEntry(seat); MANGOS_ASSERT(seatEntry); // ToDo: Unboard passenger from a MOTransport when they are properly implemented /*if (TransportInfo* transportInfo = passenger->GetTransportInfo()) { WorldObject* transporter = transportInfo->GetTransport(); // Must be a MO transporter MANGOS_ASSERT(transporter->GetObjectGuid().IsMOTransport()); ((Transport*)transporter)->UnBoardPassenger(passenger); }*/ DEBUG_LOG("VehicleInfo::Board: Board passenger: %s to seat %u", passenger->GetGuidStr().c_str(), seat); // Calculate passengers local position float lx, ly, lz, lo; CalculateBoardingPositionOf(passenger->GetPositionX(), passenger->GetPositionY(), passenger->GetPositionZ(), passenger->GetOrientation(), lx, ly, lz, lo); BoardPassenger(passenger, lx, ly, lz, lo, seat); // Use TransportBase to store the passenger // Set data for createobject packets passenger->m_movementInfo.SetTransportData(m_owner->GetObjectGuid(), lx, ly, lz, lo, 0, seat); if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* pPlayer = (Player*)passenger; pPlayer->RemovePet(PET_SAVE_AS_CURRENT); WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA); pPlayer->GetSession()->SendPacket(&data); // SMSG_BREAK_TARGET (?) } if (!passenger->IsRooted()) passenger->SetRoot(true); Movement::MoveSplineInit init(*passenger); init.MoveTo(0.0f, 0.0f, 0.0f); // ToDo: Set correct local coords init.SetFacing(0.0f); // local orientation ? ToDo: Set proper orientation! init.SetBoardVehicle(); init.Launch(); // Apply passenger modifications ApplySeatMods(passenger, seatEntry->m_flags); }