50UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(
STATUS_NONE)
59 if (veSeat->CanEnterOrExit())
77 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
78 ASSERT(itr->second.IsEmpty());
106 for (VehicleAccessoryList::const_iterator itr = accessories->begin(); itr != accessories->end(); ++itr)
107 if (!evading || itr->IsMinion)
108 InstallAccessory(itr->AccessoryEntry, itr->SeatId, itr->IsMinion, itr->SummonedType, itr->SummonTime, itr->RideSpellID);
126 TC_LOG_ERROR(
"entities.vehicle",
"Vehicle {} Entry: {} attempts to uninstall, but already has STATUS_UNINSTALLING! "
264 for (
auto const& [_, seat] :
Seats)
266 passenger->_ExitVehicle();
284 SeatMap::const_iterator seat =
Seats.find(seatId);
285 if (seat ==
Seats.end())
287 return seat->second.IsEmpty();
305 SeatMap::const_iterator seat =
Seats.find(seatId);
306 if (seat ==
Seats.end())
328 SeatMap::const_iterator seat =
Seats.find(seatId);
329 if (seat ==
Seats.end())
332 while (!seat->second.IsEmpty() ||
HasPendingEventForSeat(seat->first) || (!seat->second.SeatInfo->CanEnterOrExit() && !seat->second.SeatInfo->IsUsableByOverride()))
336 if (++seat ==
Seats.end())
337 seat =
Seats.begin();
341 if (seat ==
Seats.begin())
347 if (seat->first == seatId)
372 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); itr++)
373 if (!itr->second.IsEmpty() && itr->second.Passenger.Guid == passenger->
GetGUID())
374 return itr->second.SeatAddon;
401 TC_LOG_ERROR(
"entities.vehicle",
"Vehicle ({}, Entry: {}) attempts to install accessory (Entry: {}) on seat {} with STATUS_UNINSTALLING! "
402 "Check Uninstall/PassengerBoarded script hooks for errors.",
_me->
GetGUID().
ToString(),
407 TC_LOG_DEBUG(
"entities.vehicle",
"Vehicle ({}, Entry {}): installing accessory (Entry: {}) on seat: {}",
447 TC_LOG_ERROR(
"entities.vehicle",
"Passenger {}, attempting to board vehicle {} during uninstall! SeatId: {}",
452 TC_LOG_DEBUG(
"entities.vehicle",
"Unit {} scheduling enter vehicle (entry: {}, vehicleId: {}, guid: {} on seat {}",
459 SeatMap::iterator seat;
465 for (seat =
Seats.begin(); seat !=
Seats.end(); ++seat)
466 if (seat->second.IsEmpty() && !
HasPendingEventForSeat(seat->first) && (seat->second.SeatInfo->CanEnterOrExit() || seat->second.SeatInfo->IsUsableByOverride()))
469 if (seat ==
Seats.end())
480 seat =
Seats.find(seatId);
481 if (seat ==
Seats.end())
489 if (!seat->second.IsEmpty())
496 ASSERT(seat->second.IsEmpty());
525 TC_LOG_DEBUG(
"entities.vehicle",
"Unit {} exit vehicle entry {} id {} guid {} seat {}",
528 if (seat->second.SeatInfo->CanEnterOrExit() && ++
UsableSeatNum)
539 seat->second.Passenger.Reset();
583 std::vector<std::pair<Unit*, Position>> seatRelocation;
584 seatRelocation.reserve(
Seats.size());
587 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
591 ASSERT(passenger->IsInWorld());
597 for (
auto const& [passenger, position] : seatRelocation)
614 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
615 if (!itr->second.IsEmpty())
623 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
672 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
673 if (itr->second.Passenger.Guid == passenger->
GetGUID())
674 return itr->second.SeatInfo;
694 for (SeatMap::iterator itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
695 if (itr->second.Passenger.Guid == passenger->
GetGUID())
715 SeatMap::const_iterator itr;
716 for (itr =
Seats.begin(); itr !=
Seats.end(); ++itr)
717 if (itr->second.IsEmpty() && !
HasPendingEventForSeat(itr->first) && (itr->second.SeatInfo->CanEnterOrExit() || itr->second.SeatInfo->IsUsableByOverride()))
763 if ((*itr)->Seat->first == seatId)
765 (*itr)->ScheduleAbort();
788 if ((*itr)->Passenger == passenger)
790 (*itr)->ScheduleAbort();
819 auto itr = std::find_if(vehicleAuras.begin(), vehicleAuras.end(), [
this](
AuraEffect const* aurEff) ->
bool
821 return aurEff->GetCasterGUID() == Passenger->GetGUID();
823 ASSERT(itr != vehicleAuras.end());
847 if (
Seat->second.SeatInfo->CanEnterOrExit())
910 init.DisableTransportPathTransformations();
911 init.MoveTo(x, y, z,
false,
true);
913 init.SetTransportEnter();
918 threatRef->GetOwner()->GetThreatManager().AddThreat(
Target->
GetBase(), 0.0f,
nullptr,
true,
true);
951 TC_LOG_DEBUG(
"entities.vehicle",
"Passenger {}, board on vehicle {} SeatId: {} cancelled",
963 TC_LOG_DEBUG(
"entities.vehicle",
"Passenger {}, board on uninstalled vehicle SeatId: {} cancelled",
974 if ((*itr)->Seat->first == seatId)
983 return vehicleTemplate->DespawnDelay;
991 if (vehicleTemplate->Pitch)
992 return *vehicleTemplate->Pitch;
999 std::stringstream sstr;
1000 sstr <<
"Vehicle seats:\n";
1001 for (SeatMap::const_iterator itr =
Seats.begin(); itr !=
Seats.end(); itr++)
1003 sstr <<
"seat " << std::to_string(itr->first) <<
": " << (itr->second.IsEmpty() ?
"empty" : itr->second.Passenger.Guid.ToString()) <<
"\n";
1006 sstr <<
"Vehicle pending events:";
1017 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__, message__,...)
#define TC_LOG_ERROR(filterType__, message__,...)
@ MOTION_PRIORITY_HIGHEST
std::optional< T > Optional
Optional helper class to wrap optional values within.
@ 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
@ DontForceParachuteOnExit
std::vector< VehicleAccessory > VehicleAccessoryList
AuraRemoveMode GetRemoveMode() const
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
ObjectGuid const & GetGUID() const
virtual void PassengerBoarded(Unit *, int8, bool)
== Fields =======================================
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
ObjectGuid::LowType GetSpawnId() const
CreatureTemplate const * GetCreatureTemplate() const
constexpr bool HasFlag(T flag) 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, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
std::string ToString() const
void StopCastingBindSight() const
void UnsummonPetTemporaryIfAny()
void SendOnCancelExpectedVehicleRideAura() const
auto const & GetThreatenedByMeList() const
void UpdatePassengerPosition(Map *map, WorldObject *passenger, Position const &position, 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)
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
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.
VehicleJoinEvent(Vehicle *v, Unit *u)
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.
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
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)
void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime, Optional< uint32 > rideSpellId={})
Installs an accessory.
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
Position GetPositionWithOffset(Position const &offset) const
constexpr void Relocate(float x, float y)
std::array< uint16, 8 > SeatID
float SeatOrientationOffset
bool HasFlag(VehicleSeatFlags flag) const
DBCPosition3D AttachmentOffset
EnumFlag< VehicleCustomFlags > CustomFlags