38UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(
STATUS_NONE)
47 if (veSeat->CanEnterOrExit())
65 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
66 ASSERT(itr->second.IsEmpty());
94 for (VehicleAccessoryList::const_iterator itr = accessories->begin(); itr != accessories->end(); ++itr)
95 if (!evading || itr->IsMinion)
96 InstallAccessory(itr->AccessoryEntry, itr->SeatId, itr->IsMinion, itr->SummonedType, itr->SummonTime);
114 TC_LOG_ERROR(
"entities.vehicle",
"Vehicle {} Entry: {} attempts to uninstall, but already has STATUS_UNINSTALLING! "
252 for (
auto const& [_, seat] :
Seats)
254 passenger->_ExitVehicle();
272 SeatMap::const_iterator seat =
Seats.find(seatId);
273 if (seat ==
Seats.end())
275 return seat->second.IsEmpty();
293 SeatMap::const_iterator seat =
Seats.find(seatId);
294 if (seat ==
Seats.end())
316 SeatMap::const_iterator seat =
Seats.find(seatId);
317 if (seat ==
Seats.end())
320 while (!seat->second.IsEmpty() ||
HasPendingEventForSeat(seat->first) || (!seat->second.SeatInfo->CanEnterOrExit() && !seat->second.SeatInfo->IsUsableByOverride()))
324 if (++seat ==
Seats.end())
325 seat =
Seats.begin();
329 if (seat ==
Seats.begin())
335 if (seat->first == seatId)
357 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); itr++)
358 if (!itr->second.IsEmpty() && itr->second.Passenger.Guid == passenger->
GetGUID())
359 return itr->second.SeatAddon;
386 TC_LOG_ERROR(
"entities.vehicle",
"Vehicle ({}, Entry: {}) attempts to install accessory (Entry: {}) on seat {} with STATUS_UNINSTALLING! "
387 "Check Uninstall/PassengerBoarded script hooks for errors.",
_me->
GetGUID().
ToString(),
392 TC_LOG_DEBUG(
"entities.vehicle",
"Vehicle ({}, Entry {}): installing accessory (Entry: {}) on seat: {}",
426 TC_LOG_ERROR(
"entities.vehicle",
"Passenger {}, attempting to board vehicle {} during uninstall! SeatId: {}",
431 TC_LOG_DEBUG(
"entities.vehicle",
"Unit {} scheduling enter vehicle (entry: {}, vehicleId: {}, guid: {} on seat {}",
438 SeatMap::iterator seat;
444 for (seat =
Seats.begin(); seat !=
Seats.end(); ++seat)
445 if (seat->second.IsEmpty() && !
HasPendingEventForSeat(seat->first) && (seat->second.SeatInfo->CanEnterOrExit() || seat->second.SeatInfo->IsUsableByOverride()))
448 if (seat ==
Seats.end())
459 seat =
Seats.find(seatId);
460 if (seat ==
Seats.end())
468 if (!seat->second.IsEmpty())
475 ASSERT(seat->second.IsEmpty());
504 TC_LOG_DEBUG(
"entities.vehicle",
"Unit {} exit vehicle entry {} id {} guid {} seat {}",
507 if (seat->second.SeatInfo->CanEnterOrExit() && ++
UsableSeatNum)
518 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);
572 seatRelocation.emplace_back(passenger,
Position(px, py, pz, po));
576 for (
auto const& [passenger, position] : seatRelocation)
577 UpdatePassengerPosition(
_me->
GetMap(), passenger, position.GetPositionX(), position.GetPositionY(), position.GetPositionZ(), position.GetOrientation(),
false);
593 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
594 if (!itr->second.IsEmpty())
602 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
649 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
650 if (itr->second.Passenger.Guid == passenger->
GetGUID())
651 return itr->second.SeatInfo;
671 SeatMap::iterator itr;
672 for (itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
673 if (itr->second.Passenger.Guid == passenger->
GetGUID())
693 SeatMap::const_iterator itr;
694 for (itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
695 if (itr->second.IsEmpty() && !
HasPendingEventForSeat(itr->first) && (itr->second.SeatInfo->CanEnterOrExit() || itr->second.SeatInfo->IsUsableByOverride()))
741 if ((*itr)->Seat->first == seatId)
743 (*itr)->ScheduleAbort();
766 if ((*itr)->Passenger == passenger)
768 (*itr)->ScheduleAbort();
797 auto itr = std::find_if(vehicleAuras.begin(), vehicleAuras.end(), [
this](
AuraEffect const* aurEff) ->
bool
799 return aurEff->GetCasterGUID() == Passenger->GetGUID();
801 ASSERT(itr != vehicleAuras.end());
825 if (
Seat->second.SeatInfo->CanEnterOrExit())
851 bg->EventPlayerDroppedFlag(player);
892 init.DisableTransportPathTransformations();
893 init.MoveTo(x, y, z,
false,
true);
895 init.SetTransportEnter();
900 threatRef->GetOwner()->GetThreatManager().AddThreat(
Target->
GetBase(), threatRef->GetThreat(),
nullptr,
true,
true);
933 TC_LOG_DEBUG(
"entities.vehicle",
"Passenger {}, board on vehicle {} SeatId: {} cancelled",
945 TC_LOG_DEBUG(
"entities.vehicle",
"Passenger {}, board on uninstalled vehicle SeatId: {} cancelled",
956 if ((*itr)->Seat->first == seatId)
965 return vehicleTemplate->DespawnDelay;
972 std::stringstream sstr;
973 sstr <<
"Vehicle seats:\n";
974 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); itr++)
976 sstr <<
"seat " << std::to_string(itr->first) <<
": " << (itr->second.IsEmpty() ?
"empty" : itr->second.Passenger.Guid.ToString()) <<
"\n";
979 sstr <<
"Vehicle pending events:";
990 sstr <<
"seat " << std::to_string((*itr)->Seat->first) <<
": " << (*itr)->Passenger->GetGUID().ToString() <<
"\n";
DB2Storage< VehicleSeatEntry > sVehicleSeatStore("VehicleSeat.db2", &VehicleSeatLoadInfo::Instance)
#define MAX_VEHICLE_SEATS
@ VEHICLE_SEAT_FLAG_DISABLE_GRAVITY
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
@ VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE
@ VEHICLE_SEAT_FLAG_B_KEEP_PET
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
@ MOTION_PRIORITY_HIGHEST
@ CREATURE_TYPE_MECHANICAL
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_KNOCK_BACK
@ 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
@ MOVEMENTFLAG_DISABLE_GRAVITY
@ 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
@ CURRENT_AUTOREPEAT_SPELL
@ VEHICLE_SPELL_PARACHUTE
@ VEHICLE_FLAG_NO_JUMPING
@ 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 Unit * ToUnit(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
void UpdatePassengerPosition(Map *map, WorldObject *passenger, float x, float y, float z, float o, bool setHomePosition)
Trinity::unique_trackable_ptr companion class, replicating what std::weak_ptr is to std::shared_ptr.
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
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)
std::forward_list< AuraEffect * > AuraEffectList
MotionMaster * GetMotionMaster()
void RemoveNpcFlag(NPCFlags flags)
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
void SetUninteractible(bool apply)
Trinity::unique_weak_ptr< Vehicle > GetVehicleKitWeakPtr() const
bool HasUnitMovementFlag(uint32 f) const
void SetNpcFlag(NPCFlags flags)
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
void RemoveCharmedBy(Unit *charmer)
void SetVehicle(Vehicle *vehicle)
uint32 HasUnitTypeMask(uint32 mask) const
bool SetCharmedBy(Unit *charmer, CharmType type, AuraApplication const *aurApp=nullptr)
bool IsUninteractible() const
void AddUnitTypeMask(uint32 mask)
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
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 * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
void ApplyAllImmunities()
Applies specific immunities that cannot be set in DB.
Vehicle * RemovePassenger(WorldObject *passenger) override
Removes the passenger from the vehicle.
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.
void InitMovementInfoForBase()
Sets correct MovementFlags2 based on VehicleFlags from DBC.
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.
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)
bool AddVehiclePassenger(Unit *unit, int8 seatId=-1)
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)
TransportBase * GetTransport() const
std::string const & GetName() const
MovementInfo m_movementInfo
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
struct MovementInfo::TransportInfo transport
constexpr void Relocate(float x, float y)
std::array< uint16, 8 > SeatID
float SeatOrientationOffset
bool HasFlag(VehicleSeatFlags flag) const
DBCPosition3D AttachmentOffset