37UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(
STATUS_NONE)
46 if (veSeat->CanEnterOrExit())
64 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
65 ASSERT(itr->second.IsEmpty());
93 for (VehicleAccessoryList::const_iterator itr = accessories->begin(); itr != accessories->end(); ++itr)
94 if (!evading || itr->IsMinion)
95 InstallAccessory(itr->AccessoryEntry, itr->SeatId, itr->IsMinion, itr->SummonedType, itr->SummonTime);
113 TC_LOG_ERROR(
"entities.vehicle",
"Vehicle {} Entry: {} attempts to uninstall, but already has STATUS_UNINSTALLING! "
257 for (
auto const& [_, seat] :
Seats)
259 passenger->_ExitVehicle();
277 SeatMap::const_iterator seat =
Seats.find(seatId);
278 if (seat ==
Seats.end())
280 return seat->second.IsEmpty();
298 SeatMap::const_iterator seat =
Seats.find(seatId);
299 if (seat ==
Seats.end())
321 SeatMap::const_iterator seat =
Seats.find(seatId);
322 if (seat ==
Seats.end())
325 while (!seat->second.IsEmpty() ||
HasPendingEventForSeat(seat->first) || (!seat->second.SeatInfo->CanEnterOrExit() && !seat->second.SeatInfo->IsUsableByOverride()))
329 if (++seat ==
Seats.end())
330 seat =
Seats.begin();
334 if (seat ==
Seats.begin())
340 if (seat->first == seatId)
362 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); itr++)
363 if (!itr->second.IsEmpty() && itr->second.Passenger.Guid == passenger->
GetGUID())
364 return itr->second.SeatAddon;
391 TC_LOG_ERROR(
"entities.vehicle",
"Vehicle ({}, Entry: {}) attempts to install accessory (Entry: {}) on seat {} with STATUS_UNINSTALLING! "
392 "Check Uninstall/PassengerBoarded script hooks for errors.",
_me->
GetGUID().
ToString(),
397 TC_LOG_DEBUG(
"entities.vehicle",
"Vehicle ({}, Entry {}): installing accessory (Entry: {}) on seat: {}",
431 TC_LOG_ERROR(
"entities.vehicle",
"Passenger {}, attempting to board vehicle {} during uninstall! SeatId: {}",
436 TC_LOG_DEBUG(
"entities.vehicle",
"Unit {} scheduling enter vehicle (entry: {}, vehicleId: {}, guid: {} on seat {}",
443 SeatMap::iterator seat;
449 for (seat =
Seats.begin(); seat !=
Seats.end(); ++seat)
450 if (seat->second.IsEmpty() && !
HasPendingEventForSeat(seat->first) && (seat->second.SeatInfo->CanEnterOrExit() || seat->second.SeatInfo->IsUsableByOverride()))
453 if (seat ==
Seats.end())
464 seat =
Seats.find(seatId);
465 if (seat ==
Seats.end())
473 if (!seat->second.IsEmpty())
480 ASSERT(seat->second.IsEmpty());
505 TC_LOG_DEBUG(
"entities.vehicle",
"Unit {} exit vehicle entry {} id {} guid {} seat {}",
508 if (seat->second.SeatInfo->CanEnterOrExit() && ++
UsableSeatNum)
515 seat->second.Passenger.Reset();
558 std::vector<std::pair<Unit*, Position>> seatRelocation;
559 seatRelocation.reserve(
Seats.size());
562 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
566 ASSERT(passenger->IsInWorld());
568 float px, py, pz, po;
569 passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po);
571 seatRelocation.emplace_back(passenger,
Position(px, py, pz, po));
575 for (
auto const& pair : seatRelocation)
576 pair.first->UpdatePosition(pair.second);
592 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
593 if (!itr->second.IsEmpty())
601 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
648 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
649 if (itr->second.Passenger.Guid == passenger->
GetGUID())
650 return itr->second.SeatInfo;
670 SeatMap::iterator itr;
671 for (itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
672 if (itr->second.Passenger.Guid == passenger->
GetGUID())
692 SeatMap::const_iterator itr;
693 for (itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
694 if (itr->second.IsEmpty() && !
HasPendingEventForSeat(itr->first) && (itr->second.SeatInfo->CanEnterOrExit() || itr->second.SeatInfo->IsUsableByOverride()))
740 if ((*itr)->Seat->first == seatId)
742 (*itr)->ScheduleAbort();
765 if ((*itr)->Passenger == passenger)
767 (*itr)->ScheduleAbort();
796 auto itr = std::find_if(vehicleAuras.begin(), vehicleAuras.end(), [
this](
AuraEffect const* aurEff) ->
bool
798 return aurEff->GetCasterGUID() == Passenger->GetGUID();
800 ASSERT(itr != vehicleAuras.end());
823 if (
Seat->second.SeatInfo->CanEnterOrExit())
847 bg->EventPlayerDroppedFlag(player);
891 init.DisableTransportPathTransformations();
892 init.MoveTo(x, y, z,
false,
true);
894 init.SetTransportEnter();
899 threatRef->GetOwner()->GetThreatManager().AddThreat(
Target->
GetBase(), threatRef->GetThreat(),
nullptr,
true,
true);
932 TC_LOG_DEBUG(
"entities.vehicle",
"Passenger {}, board on vehicle {} SeatId: {} cancelled",
944 TC_LOG_DEBUG(
"entities.vehicle",
"Passenger {}, board on uninstalled vehicle SeatId: {} cancelled",
955 if ((*itr)->Seat->first == seatId)
964 return vehicleTemplate->DespawnDelay;
971 std::stringstream sstr;
972 sstr <<
"Vehicle seats:\n";
973 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); itr++)
975 sstr <<
"seat " << std::to_string(itr->first) <<
": " << (itr->second.IsEmpty() ?
"empty" : itr->second.Passenger.Guid.ToString()) <<
"\n";
978 sstr <<
"Vehicle pending events:";
989 sstr <<
"seat " << std::to_string((*itr)->Seat->first) <<
": " << (*itr)->Passenger->GetGUID().ToString() <<
"\n";
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
@ VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE
@ VEHICLE_SEAT_FLAG_B_KEEP_PET
DBCStorage< VehicleSeatEntry > sVehicleSeatStore(VehicleSeatEntryfmt)
#define MAX_VEHICLE_SEATS
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
@ MOTION_PRIORITY_HIGHEST
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_KNOCK_BACK
@ CREATURE_TYPE_MECHANICAL
@ SPELL_AURA_DAMAGE_SHIELD
@ SPELL_AURA_MOD_RESISTANCE
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
@ SPELL_AURA_SPLIT_DAMAGE_PCT
@ SPELL_AURA_SCHOOL_IMMUNITY
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_SCHOOL_ABSORB
@ SPELL_AURA_MOD_UNATTACKABLE
@ AURA_INTERRUPT_FLAG_NOT_SEATED
@ MOVEMENTFLAG_ONTRANSPORT
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
@ MOVEMENTFLAG2_NO_STRAFE
@ MOVEMENTFLAG2_FULL_SPEED_PITCHING
@ MOVEMENTFLAG2_FULL_SPEED_TURNING
@ MOVEMENTFLAG2_NO_JUMPING
@ UNIT_NPC_FLAG_SPELLCLICK
@ UNIT_NPC_FLAG_PLAYER_VEHICLE
@ UNIT_FLAG_UNINTERACTIBLE
@ VEHICLE_SPELL_PARACHUTE
@ VEHICLE_FLAG_NO_JUMPING
@ VEHICLE_FLAG_FIXED_POSITION
@ VEHICLE_FLAG_FULLSPEEDTURNING
@ VEHICLE_FLAG_ALLOW_PITCHING
@ VEHICLE_FLAG_FULLSPEEDPITCHING
std::vector< VehicleAccessory > VehicleAccessoryList
AuraRemoveMode GetRemoveMode() const
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
virtual void PassengerBoarded(Unit *, int8, bool)
== Fields =======================================
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
ObjectGuid::LowType GetSpawnId() const
CreatureTemplate const * GetCreatureTemplate() const
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
void LaunchMoveSpline(std::function< void(Movement::MoveSplineInit &init)> &&initializer, uint32 id=0, MovementGeneratorPriority priority=MOTION_PRIORITY_NORMAL, MovementGeneratorType type=EFFECT_MOTION_TYPE)
std::string ToString() const
static Creature * ToCreature(Object *o)
static ObjectGuid GetGUID(Object const *o)
static Player * ToPlayer(Object *o)
void StopCastingBindSight() const
void UnsummonPetTemporaryIfAny()
Battleground * GetBattleground() const
void SendOnCancelExpectedVehicleRideAura() const
auto const & GetThreatenedByMeList() const
Trinity::unique_trackable_ptr companion class, replicating what std::weak_ptr is to std::shared_ptr.
Vehicle * GetVehicle() const
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
void AddExtraUnitMovementFlag(uint32 f)
ThreatManager & GetThreatManager()
void SetControlled(bool apply, UnitState state)
void HandleSpellClick(Unit *clicker, int8 seatId=-1)
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0)
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
MotionMaster * GetMotionMaster()
bool HasUnitFlag(UnitFlags flags) const
void RemoveNpcFlag(NPCFlags flags)
Trinity::unique_weak_ptr< Vehicle > GetVehicleKitWeakPtr() const
void AddUnitMovementFlag(uint32 f)
void SetNpcFlag(NPCFlags flags)
void RemoveCharmedBy(Unit *charmer)
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
void RemoveUnitMovementFlag(uint32 f)
void SetVehicle(Vehicle *vehicle)
uint32 HasUnitTypeMask(uint32 mask) const
bool SetCharmedBy(Unit *charmer, CharmType type, AuraApplication const *aurApp=nullptr)
void SetUnitFlag(UnitFlags flags)
std::list< AuraEffect * > AuraEffectList
void AddUnitTypeMask(uint32 mask)
void RemoveUnitFlag(UnitFlags flags)
virtual void ExitVehicle(Position const *exitPosition=nullptr)
bool Execute(uint64, uint32) override
Actually adds the passenger @Passenger to vehicle @Target.
void Abort(uint64) override
Aborts the event. Implies that unit @Passenger will not be boarding vehicle @Target after all.
Vehicle(Unit *unit, VehicleEntry const *vehInfo, uint32 creatureEntry)
uint8 GetAvailableSeatCount() const
Gets the available seat count.
Unit * GetBase() const
May be called from scripts.
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
void ApplyAllImmunities()
Applies specific immunities that cannot be set in DB.
void RemovePendingEvent(VehicleJoinEvent *e)
Removes @VehicleJoinEvent objects from pending join event store. This method only removes it after it...
SeatMap::iterator GetSeatIteratorForPassenger(Unit *passenger)
Gets seat iterator for specified passenger.
VehicleEntry const * GetVehicleInfo() const
void Reset(bool evading=false)
Reapplies immunities and reinstalls accessories. Only has effect for creatures.
Vehicle * RemovePassenger(Unit *passenger)
Removes the passenger from the vehicle.
void InitMovementInfoForBase()
Sets correct MovementFlags2 based on VehicleFlags from DBC.
bool AddPassenger(Unit *passenger, int8 seatId=-1)
Attempts to add a passenger to the vehicle on 'seatId'.
uint32 GetCreatureEntry() const
void RemoveAllPassengers()
Removes all current and pending passengers from the vehicle.
bool IsVehicleInUse() const
Returns information whether the vehicle is currently used by any unit.
uint32 UsableSeatNum
Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags.
void CalculatePassengerPosition(float &x, float &y, float &z, float *o) const override
This method transforms supplied transport offsets into global coordinates.
uint32 _creatureEntry
Can be different than the entry of _me in case of players.
Status _status
Internal variable for sanity checks.
void Uninstall()
Removes all passengers and sets status to STATUS_UNINSTALLING. No new passengers can be added to the ...
void RemovePendingEventsForSeat(int8 seatId)
Removes any pending events for given seatId. Executed when a @VehicleJoinEvent::Execute is called.
Unit * _me
The underlying unit with the vehicle kit. Can be player or creature.
bool HasEmptySeat(int8 seatId) const
Checks if vehicle's seat specified by 'seatId' is empty.
PendingJoinEventContainer _pendingJoinEvents
Collection of delayed join events for prospective passengers.
Trinity::unique_weak_ptr< Vehicle > GetWeakPtr() const
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
void Install()
Initializes power type for vehicle. Nothing more.
bool IsControllableVehicle() const
void RelocatePassengers()
Relocate passengers. Must be called after m_base::Relocate.
bool HasPendingEventForSeat(int8 seatId) const
void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime)
Installs an accessory.
SeatMap Seats
The collection of all seats on the vehicle. Including vacant ones.
std::string GetDebugInfo() const
SeatMap::const_iterator GetNextEmptySeat(int8 seatId, bool next) const
Gets the next empty seat based on current seat.
VehicleSeatAddon const * GetSeatAddonForSeatOfPassenger(Unit const *passenger) const
Gets the vehicle seat addon data for the seat of a passenger.
friend class VehicleJoinEvent
Milliseconds GetDespawnDelay()
void RemovePendingEventsForPassenger(Unit *passenger)
VehicleEntry const * _vehicleInfo
DBC data for vehicle.
void InstallAllAccessories(bool evading)
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
std::string const & GetName() const
Transport * GetTransport() const
MovementInfo m_movementInfo
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
struct MovementInfo::TransportInfo transport
void Relocate(float x, float y)
uint32 SeatID[MAX_VEHICLE_SEATS]
float SeatOrientationOffset
bool HasFlag(VehicleSeatFlags flag) const
DBCPosition3D AttachmentOffset