TrinityCore
Vehicle.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Vehicle.h"
19#include "Battleground.h"
20#include "CharmInfo.h"
21#include "Common.h"
22#include "CreatureAI.h"
23#include "DB2Stores.h"
24#include "EventProcessor.h"
25#include "Log.h"
26#include "MotionMaster.h"
27#include "MoveSplineInit.h"
28#include "ObjectAccessor.h"
29#include "ObjectMgr.h"
30#include "Player.h"
31#include "ScriptMgr.h"
32#include "SpellAuraEffects.h"
33#include "TemporarySummon.h"
34#include "Unit.h"
35#include <sstream>
36
37Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) :
38UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(STATUS_NONE)
39{
40 for (int8 i = 0; i < MAX_VEHICLE_SEATS; ++i)
41 {
42 if (uint32 seatId = _vehicleInfo->SeatID[i])
43 if (VehicleSeatEntry const* veSeat = sVehicleSeatStore.LookupEntry(seatId))
44 {
45 VehicleSeatAddon const* addon = sObjectMgr->GetVehicleSeatAddon(seatId);
46 Seats.insert(std::make_pair(i, VehicleSeat(veSeat, addon)));
47 if (veSeat->CanEnterOrExit())
49 }
50 }
51
52 // Set or remove correct flags based on available seats. Will overwrite db data (if wrong).
53 if (UsableSeatNum)
55 else
57
59}
60
62{
65 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
66 ASSERT(itr->second.IsEmpty());
67}
68
79{
81 if (GetBase()->GetTypeId() == TYPEID_UNIT)
82 sScriptMgr->OnInstall(this);
83}
84
86{
87 if (GetBase()->GetTypeId() == TYPEID_PLAYER || !evading)
88 RemoveAllPassengers(); // We might have aura's saved in the DB with now invalid casters - remove
89
90 VehicleAccessoryList const* accessories = sObjectMgr->GetVehicleAccessoryList(this);
91 if (!accessories)
92 return;
93
94 for (VehicleAccessoryList::const_iterator itr = accessories->begin(); itr != accessories->end(); ++itr)
95 if (!evading || itr->IsMinion) // only install minions on evade mode
96 InstallAccessory(itr->AccessoryEntry, itr->SeatId, itr->IsMinion, itr->SummonedType, itr->SummonTime);
97}
98
110{
112 if (_status == STATUS_UNINSTALLING && !GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
113 {
114 TC_LOG_ERROR("entities.vehicle", "Vehicle {} Entry: {} attempts to uninstall, but already has STATUS_UNINSTALLING! "
115 "Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUID().ToString(), _creatureEntry);
116 return;
117 }
118
120 TC_LOG_DEBUG("entities.vehicle", "Vehicle::Uninstall Entry: {}, {}", _creatureEntry, _me->GetGUID().ToString());
122
123 if (GetBase()->GetTypeId() == TYPEID_UNIT)
124 sScriptMgr->OnUninstall(this);
125}
126
138void Vehicle::Reset(bool evading /*= false*/)
139{
140 if (GetBase()->GetTypeId() != TYPEID_UNIT)
141 return;
142
143 TC_LOG_DEBUG("entities.vehicle", "Vehicle::Reset (Entry: {}, {}, DBGuid: {})", GetCreatureEntry(), _me->GetGUID().ToString(), _me->ToCreature()->GetSpawnId());
144
146 if (GetBase()->IsAlive())
147 InstallAllAccessories(evading);
148
149 sScriptMgr->OnReset(this);
150}
151
162{
163 // This couldn't be done in DB, because some spells have MECHANIC_NONE
164
165 // Vehicles should be immune on Knockback ...
168
169 // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
171 {
172 // Heal & dispel ...
177
178 // ... Shield & Immunity grant spells ...
185
186 // ... Resistance, Split damage, Change stats ...
192 }
193
194 // Different immunities for vehicles goes below
195 switch (GetVehicleInfo()->ID)
196 {
197 // code below prevents a bug with movable cannons
198 case 160: // Strand of the Ancients
199 case 244: // Wintergrasp
200 case 510: // Isle of Conquest
201 case 452: // Isle of Conquest
202 case 543: // Isle of Conquest
204 // why we need to apply this? we can simple add immunities to slow mechanic in DB
206 break;
207 case 335: // Salvaged Chopper
208 case 336: // Salvaged Siege Engine
209 case 338: // Salvaged Demolisher
211 break;
212 default:
213 break;
214 }
215}
216
227{
228 TC_LOG_DEBUG("entities.vehicle", "Vehicle::RemoveAllPassengers. Entry: {}, {}", _creatureEntry, _me->GetGUID().ToString());
229
232 {
234 Vehicle* eventVehicle = _status != STATUS_UNINSTALLING ? this : nullptr;
235
236 while (!_pendingJoinEvents.empty())
237 {
239 e->ScheduleAbort();
240 e->Target = eventVehicle;
241 _pendingJoinEvents.pop_front();
242 }
243 }
244
245 // Passengers always cast an aura with SPELL_AURA_CONTROL_VEHICLE on the vehicle
246 // We just remove the aura and the unapply handler will make the target leave the vehicle.
247 // We don't need to iterate over Seats
249
250 // Aura script might cause the vehicle to be despawned in the middle of handling SPELL_AURA_CONTROL_VEHICLE removal
251 // In that case, aura effect has already been unregistered but passenger may still be found in Seats
252 for (auto const& [_, seat] : Seats)
253 if (Unit* passenger = ObjectAccessor::GetUnit(*_me, seat.Passenger.Guid))
254 passenger->_ExitVehicle();
255}
256
270bool Vehicle::HasEmptySeat(int8 seatId) const
271{
272 SeatMap::const_iterator seat = Seats.find(seatId);
273 if (seat == Seats.end())
274 return false;
275 return seat->second.IsEmpty();
276}
277
292{
293 SeatMap::const_iterator seat = Seats.find(seatId);
294 if (seat == Seats.end())
295 return nullptr;
296
297 return ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger.Guid);
298}
299
314SeatMap::const_iterator Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
315{
316 SeatMap::const_iterator seat = Seats.find(seatId);
317 if (seat == Seats.end())
318 return seat;
319
320 while (!seat->second.IsEmpty() || HasPendingEventForSeat(seat->first) || (!seat->second.SeatInfo->CanEnterOrExit() && !seat->second.SeatInfo->IsUsableByOverride()))
321 {
322 if (next)
323 {
324 if (++seat == Seats.end())
325 seat = Seats.begin();
326 }
327 else
328 {
329 if (seat == Seats.begin())
330 seat = Seats.end();
331 --seat;
332 }
333
334 // Make sure we don't loop indefinetly
335 if (seat->first == seatId)
336 return Seats.end();
337 }
338
339 return seat;
340}
341
356{
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;
360
361 return nullptr;
362}
363
381void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime)
382{
385 {
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(),
388 GetCreatureEntry(), entry, (int32)seatId);
389 return;
390 }
391
392 TC_LOG_DEBUG("entities.vehicle", "Vehicle ({}, Entry {}): installing accessory (Entry: {}) on seat: {}",
393 _me->GetGUID().ToString(), GetCreatureEntry(), entry, (int32)seatId);
394
395 TempSummon* accessory = _me->SummonCreature(entry, *_me, TempSummonType(type), Milliseconds(summonTime));
396 ASSERT(accessory);
397
398 if (minion)
400
401 _me->HandleSpellClick(accessory, seatId);
402
405}
406
422{
425 {
426 TC_LOG_ERROR("entities.vehicle", "Passenger {}, attempting to board vehicle {} during uninstall! SeatId: {}",
427 unit->GetGUID().ToString(), _me->GetGUID().ToString(), (int32)seatId);
428 return false;
429 }
430
431 TC_LOG_DEBUG("entities.vehicle", "Unit {} scheduling enter vehicle (entry: {}, vehicleId: {}, guid: {} on seat {}",
432 unit->GetName(), _me->GetEntry(), _vehicleInfo->ID, _me->GetGUID().ToString(), (int32)seatId);
433
434 // The seat selection code may kick other passengers off the vehicle.
435 // While the validity of the following may be arguable, it is possible that when such a passenger
436 // exits the vehicle will dismiss. That's why the actual adding the passenger to the vehicle is scheduled
437 // asynchronously, so it can be cancelled easily in case the vehicle is uninstalled meanwhile.
438 SeatMap::iterator seat;
439 VehicleJoinEvent* e = new VehicleJoinEvent(this, unit);
440 unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0s));
441
442 if (seatId < 0) // no specific seat requirement
443 {
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()))
446 break;
447
448 if (seat == Seats.end()) // no available seat
449 {
450 e->ScheduleAbort();
451 return false;
452 }
453
454 e->Seat = seat;
455 _pendingJoinEvents.push_back(e);
456 }
457 else
458 {
459 seat = Seats.find(seatId);
460 if (seat == Seats.end())
461 {
462 e->ScheduleAbort();
463 return false;
464 }
465
466 e->Seat = seat;
467 _pendingJoinEvents.push_back(e);
468 if (!seat->second.IsEmpty())
469 {
470 Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger.Guid);
471 ASSERT(passenger);
472 passenger->ExitVehicle();
473 }
474
475 ASSERT(seat->second.IsEmpty());
476 }
477
478 return true;
479}
480
493{
494 Unit* unit = passenger->ToUnit();
495 if (!unit)
496 return nullptr;
497
498 if (unit->GetVehicle() != this)
499 return nullptr;
500
501 SeatMap::iterator seat = GetSeatIteratorForPassenger(unit);
502 ASSERT(seat != Seats.end());
503
504 TC_LOG_DEBUG("entities.vehicle", "Unit {} exit vehicle entry {} id {} guid {} seat {}",
505 unit->GetName(), _me->GetEntry(), _vehicleInfo->ID, _me->GetGUID().ToString(), (int32)seat->first);
506
507 if (seat->second.SeatInfo->CanEnterOrExit() && ++UsableSeatNum)
509
510 // Enable gravity for passenger when he did not have it active before entering the vehicle
511 if (seat->second.SeatInfo->Flags & VEHICLE_SEAT_FLAG_DISABLE_GRAVITY && !seat->second.Passenger.IsGravityDisabled)
512 unit->SetDisableGravity(false);
513
514 // Remove UNIT_FLAG_UNINTERACTIBLE if passenger did not have it before entering vehicle
515 if (seat->second.SeatInfo->Flags & VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE && !seat->second.Passenger.IsUninteractible)
516 unit->SetUninteractible(false);
517
518 seat->second.Passenger.Reset();
519
520 if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->second.SeatInfo->Flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
521 _me->RemoveCharmedBy(unit);
522
523 if (_me->IsInWorld())
524 {
525 if (!_me->GetTransport())
527 else
529 }
530
531 // only for flyable vehicles
532 if (unit->IsFlying())
534
536 _me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, false);
537
538 if (GetBase()->GetTypeId() == TYPEID_UNIT)
539 sScriptMgr->OnRemovePassenger(this, unit);
540
541 unit->SetVehicle(nullptr);
542 return this;
543}
544
555{
556 ASSERT(_me->GetMap());
557
558 std::vector<std::pair<Unit*, Position>> seatRelocation;
559 seatRelocation.reserve(Seats.size());
560
561 // not sure that absolute position calculation is correct, it must depend on vehicle pitch angle
562 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
563 {
564 if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger.Guid))
565 {
566 ASSERT(passenger->IsInWorld());
567
568 float px, py, pz, po;
569 passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po);
570 CalculatePassengerPosition(px, py, pz, &po);
571
572 seatRelocation.emplace_back(passenger, Position(px, py, pz, po));
573 }
574 }
575
576 for (auto const& [passenger, position] : seatRelocation)
577 UpdatePassengerPosition(_me->GetMap(), passenger, position.GetPositionX(), position.GetPositionY(), position.GetPositionZ(), position.GetOrientation(), false);
578}
579
592{
593 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
594 if (!itr->second.IsEmpty())
595 return true;
596
597 return false;
598}
599
601{
602 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
603 if (itr->second.SeatInfo->HasFlag(VEHICLE_SEAT_FLAG_CAN_CONTROL))
604 return true;
605
606 return false;
607}
608
619{
620 uint32 vehicleFlags = GetVehicleInfo()->Flags;
621
622 if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE)
624 if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING)
626 if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING)
628 if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING)
630 if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING)
632}
633
648{
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;
652
653 return nullptr;
654}
655
669SeatMap::iterator Vehicle::GetSeatIteratorForPassenger(Unit* passenger)
670{
671 SeatMap::iterator itr;
672 for (itr = Seats.begin(); itr != Seats.end(); ++itr)
673 if (itr->second.Passenger.Guid == passenger->GetGUID())
674 return itr;
675
676 return Seats.end();
677}
678
691{
692 uint8 ret = 0;
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()))
696 ++ret;
697
698 return ret;
699}
700
715{
716 for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
717 {
718 if (*itr == e)
719 {
720 _pendingJoinEvents.erase(itr);
721 break;
722 }
723 }
724}
725
738{
739 for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();)
740 {
741 if ((*itr)->Seat->first == seatId)
742 {
743 (*itr)->ScheduleAbort();
744 _pendingJoinEvents.erase(itr++);
745 }
746 else
747 ++itr;
748 }
749}
750
763{
764 for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();)
765 {
766 if ((*itr)->Passenger == passenger)
767 {
768 (*itr)->ScheduleAbort();
769 _pendingJoinEvents.erase(itr++);
770 }
771 else
772 ++itr;
773 }
774}
775
792{
795
797 auto itr = std::find_if(vehicleAuras.begin(), vehicleAuras.end(), [this](AuraEffect const* aurEff) -> bool
798 {
799 return aurEff->GetCasterGUID() == Passenger->GetGUID();
800 });
801 ASSERT(itr != vehicleAuras.end());
802
803 AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(Target->GetBase()->GetGUID());
804 ASSERT(aurApp && !aurApp->GetRemoveMode());
805
808
809 // Passenger might've died in the meantime - abort if this is the case
810 if (!Passenger->IsAlive())
811 {
812 Abort(0);
813 return true;
814 }
815
816 //It's possible that multiple vehicle join
817 //events are executed in the same update
818 if (Passenger->GetVehicle())
820
822 Seat->second.Passenger.Guid = Passenger->GetGUID();
823 Seat->second.Passenger.IsUninteractible = Passenger->IsUninteractible();
824 Seat->second.Passenger.IsGravityDisabled = Passenger->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
825 if (Seat->second.SeatInfo->CanEnterOrExit())
826 {
829 if (!Target->UsableSeatNum)
830 {
833 else
835 }
836 }
837
842
843 VehicleSeatEntry const* veSeat = Seat->second.SeatInfo;
844 VehicleSeatAddon const* veSeatAddon = Seat->second.SeatAddon;
845
846 Player* player = Passenger->ToPlayer();
847 if (player)
848 {
849 // drop flag
850 if (Battleground* bg = player->GetBattleground())
851 bg->EventPlayerDroppedFlag(player);
852
853 player->StopCastingCharm();
854 player->StopCastingBindSight();
858 }
859
862
863 float o = veSeatAddon ? veSeatAddon->SeatOrientationOffset : 0.f;
864 float x = veSeat->AttachmentOffset.X;
865 float y = veSeat->AttachmentOffset.Y;
866 float z = veSeat->AttachmentOffset.Z;
867
873
875 Seat->second.SeatInfo->HasFlag(VEHICLE_SEAT_FLAG_CAN_CONTROL))
876 {
877 // handles SMSG_CLIENT_CONTROL
879 {
880 // charming failed, probably aura was removed by relocation/scripts/whatever
881 Abort(0);
882 return true;
883 }
884 }
885
886 Passenger->SendClearTarget(); // SMSG_BREAK_TARGET
887 Passenger->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
888 // also adds MOVEMENTFLAG_ROOT
889
890 std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
891 {
892 init.DisableTransportPathTransformations();
893 init.MoveTo(x, y, z, false, true);
894 init.SetFacing(o);
895 init.SetTransportEnter();
896 };
898
899 for (auto const& [guid, threatRef] : Passenger->GetThreatManager().GetThreatenedByMeList())
900 threatRef->GetOwner()->GetThreatManager().AddThreat(Target->GetBase(), threatRef->GetThreat(), nullptr, true, true);
901
902 if (Creature* creature = Target->GetBase()->ToCreature())
903 {
904 if (CreatureAI* ai = creature->AI())
905 ai->PassengerBoarded(Passenger, Seat->first, true);
906
907 sScriptMgr->OnAddPassenger(Target, Passenger, Seat->first);
908
909 // Actually quite a redundant hook. Could just use OnAddPassenger and check for unit typemask inside script.
911 sScriptMgr->OnInstallAccessory(Target, Passenger->ToCreature());
912 }
913
914 return true;
915}
916
929{
931 if (Target)
932 {
933 TC_LOG_DEBUG("entities.vehicle", "Passenger {}, board on vehicle {} SeatId: {} cancelled",
935
938
943 }
944 else
945 TC_LOG_DEBUG("entities.vehicle", "Passenger {}, board on uninstalled vehicle SeatId: {} cancelled",
946 Passenger->GetGUID().ToString(), (int32)Seat->first);
947
950}
951
953{
954 for (PendingJoinEventContainer::const_iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
955 {
956 if ((*itr)->Seat->first == seatId)
957 return true;
958 }
959 return false;
960}
961
963{
964 if (VehicleTemplate const* vehicleTemplate = sObjectMgr->GetVehicleTemplate(this))
965 return vehicleTemplate->DespawnDelay;
966
967 return 1ms;
968}
969
970std::string Vehicle::GetDebugInfo() const
971{
972 std::stringstream sstr;
973 sstr << "Vehicle seats:\n";
974 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); itr++)
975 {
976 sstr << "seat " << std::to_string(itr->first) << ": " << (itr->second.IsEmpty() ? "empty" : itr->second.Passenger.Guid.ToString()) << "\n";
977 }
978
979 sstr << "Vehicle pending events:";
980
981 if (_pendingJoinEvents.empty())
982 {
983 sstr << " none";
984 }
985 else
986 {
987 sstr << "\n";
988 for (PendingJoinEventContainer::const_iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
989 {
990 sstr << "seat " << std::to_string((*itr)->Seat->first) << ": " << (*itr)->Passenger->GetGUID().ToString() << "\n";
991 }
992 }
993
994 return sstr.str();
995}
996
998{
999 return _me->GetVehicleKitWeakPtr();
1000}
@ STATUS_NONE
Definition: Battleground.h:164
@ CHARM_TYPE_VEHICLE
Definition: CharmInfo.h:72
DB2Storage< VehicleSeatEntry > sVehicleSeatStore("VehicleSeat.db2", &VehicleSeatLoadInfo::Instance)
#define MAX_VEHICLE_SEATS
@ VEHICLE_SEAT_FLAG_DISABLE_GRAVITY
Definition: DBCEnums.h:2419
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
Definition: DBCEnums.h:2428
@ VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE
Definition: DBCEnums.h:2437
@ VEHICLE_SEAT_FLAG_B_KEEP_PET
Definition: DBCEnums.h:2460
uint8_t uint8
Definition: Define.h:144
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
uint32_t uint32
Definition: Define.h:142
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
#define ASSERT
Definition: Errors.h:68
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
@ MOTION_PRIORITY_HIGHEST
TempSummonType
Definition: ObjectDefines.h:62
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
#define sObjectMgr
Definition: ObjectMgr.h:1946
#define sScriptMgr
Definition: ScriptMgr.h:1418
@ EVENT_VEHICLE_BOARD
@ CREATURE_TYPE_MECHANICAL
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_DISPEL
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_KNOCK_BACK
@ SPELL_EFFECT_HEAL_PCT
@ MECHANIC_BANISH
@ MECHANIC_IMMUNE_SHIELD
@ MECHANIC_SHIELD
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_MECHANIC
@ 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_MOD_STAT
@ SPELL_AURA_SCHOOL_IMMUNITY
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_SCHOOL_ABSORB
@ SPELL_AURA_MOD_UNATTACKABLE
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition: UnitDefines.h:367
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition: UnitDefines.h:421
@ MOVEMENTFLAG2_NO_STRAFE
Definition: UnitDefines.h:417
@ MOVEMENTFLAG2_FULL_SPEED_PITCHING
Definition: UnitDefines.h:420
@ MOVEMENTFLAG2_FULL_SPEED_TURNING
Definition: UnitDefines.h:419
@ MOVEMENTFLAG2_NO_JUMPING
Definition: UnitDefines.h:418
@ UNIT_NPC_FLAG_SPELLCLICK
Definition: UnitDefines.h:321
@ UNIT_NPC_FLAG_PLAYER_VEHICLE
Definition: UnitDefines.h:322
@ UNIT_MASK_ACCESSORY
Definition: Unit.h:359
@ UNIT_MASK_MINION
Definition: Unit.h:351
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:590
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:592
@ UNIT_STATE_ROOT
Definition: Unit.h:265
@ VEHICLE_SPELL_PARACHUTE
@ VEHICLE_FLAG_NO_JUMPING
@ VEHICLE_FLAG_NO_STRAFE
@ VEHICLE_FLAG_FULLSPEEDTURNING
@ VEHICLE_FLAG_ALLOW_PITCHING
@ VEHICLE_FLAG_FULLSPEEDPITCHING
std::vector< VehicleAccessory > VehicleAccessoryList
Aura * GetBase() const
Definition: SpellAuras.h:78
AuraRemoveMode GetRemoveMode() const
Definition: SpellAuras.h:91
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
void ScheduleAbort()
virtual void PassengerBoarded(Unit *, int8, bool)
== Fields =======================================
Definition: CreatureAI.h:220
bool isWorldBoss() const
Definition: Creature.cpp:2484
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:98
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:250
CreatureAI * AI() const
Definition: Creature.h:214
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
Definition: ObjectGuid.cpp:554
static Creature * ToCreature(Object *o)
Definition: Object.h:219
static Unit * ToUnit(Object *o)
Definition: Object.h:225
bool IsInWorld() const
Definition: Object.h:154
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
void StopCastingBindSight() const
Definition: Player.cpp:26129
void UnsummonPetTemporaryIfAny()
Definition: Player.cpp:27165
void StopCastingCharm()
Definition: Player.cpp:21677
Battleground * GetBattleground() const
Definition: Player.cpp:24976
void SendOnCancelExpectedVehicleRideAura() const
Definition: Player.cpp:21874
auto const & GetThreatenedByMeList() const
void UpdatePassengerPosition(Map *map, WorldObject *passenger, float x, float y, float z, float o, bool setHomePosition)
Definition: Transport.cpp:39
Trinity::unique_trackable_ptr companion class, replicating what std::weak_ptr is to std::shared_ptr.
Definition: Unit.h:627
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition: Unit.cpp:7845
Vehicle * GetVehicle() const
Definition: Unit.h:1713
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3812
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1321
void AddExtraUnitMovementFlag(uint32 f)
Definition: Unit.h:1667
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:10911
void HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition: Unit.cpp:12027
void SendClearTarget()
Definition: Unit.cpp:12556
std::forward_list< AuraEffect * > AuraEffectList
Definition: Unit.h:644
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsAlive() const
Definition: Unit.h:1164
void RemoveNpcFlag(NPCFlags flags)
Definition: Unit.h:983
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition: Unit.cpp:12725
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
Trinity::unique_weak_ptr< Vehicle > GetVehicleKitWeakPtr() const
Definition: Unit.h:1712
bool IsAIEnabled() const
Definition: Unit.h:658
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1663
void SetNpcFlag(NPCFlags flags)
Definition: Unit.h:982
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition: Unit.cpp:4101
void RemoveCharmedBy(Unit *charmer)
Definition: Unit.cpp:11315
void SetVehicle(Vehicle *vehicle)
Definition: Unit.h:1714
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:736
bool SetCharmedBy(Unit *charmer, CharmType type, AuraApplication const *aurApp=nullptr)
Definition: Unit.cpp:11142
bool IsFlying() const
Definition: Unit.h:1735
bool IsUninteractible() const
Definition: Unit.h:1037
void AddUnitTypeMask(uint32 mask)
Definition: Unit.h:737
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
Definition: Unit.cpp:3017
virtual void ExitVehicle(Position const *exitPosition=nullptr)
Definition: Unit.cpp:12204
bool Execute(uint64, uint32) override
Actually adds the passenger @Passenger to vehicle @Target.
Definition: Vehicle.cpp:791
SeatMap::iterator Seat
Definition: Vehicle.h:144
Unit * Passenger
Definition: Vehicle.h:143
Vehicle * Target
Definition: Vehicle.h:142
void Abort(uint64) override
Aborts the event. Implies that unit @Passenger will not be boarding vehicle @Target after all.
Definition: Vehicle.cpp:928
Vehicle(Unit *unit, VehicleEntry const *vehInfo, uint32 creatureEntry)
Definition: Vehicle.cpp:37
uint8 GetAvailableSeatCount() const
Gets the available seat count.
Definition: Vehicle.cpp:690
Unit * GetBase() const
Definition: Vehicle.h:49
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
Definition: Vehicle.cpp:291
void ApplyAllImmunities()
Applies specific immunities that cannot be set in DB.
Definition: Vehicle.cpp:161
Vehicle * RemovePassenger(WorldObject *passenger) override
Removes the passenger from the vehicle.
Definition: Vehicle.cpp:492
void RemovePendingEvent(VehicleJoinEvent *e)
Removes @VehicleJoinEvent objects from pending join event store. This method only removes it after it...
Definition: Vehicle.cpp:714
SeatMap::iterator GetSeatIteratorForPassenger(Unit *passenger)
Gets seat iterator for specified passenger.
Definition: Vehicle.cpp:669
VehicleEntry const * GetVehicleInfo() const
Definition: Vehicle.h:50
void Reset(bool evading=false)
Reapplies immunities and reinstalls accessories. Only has effect for creatures.
Definition: Vehicle.cpp:138
void InitMovementInfoForBase()
Sets correct MovementFlags2 based on VehicleFlags from DBC.
Definition: Vehicle.cpp:618
@ STATUS_INSTALLED
Definition: Vehicle.h:87
@ STATUS_UNINSTALLING
Definition: Vehicle.h:88
uint32 GetCreatureEntry() const
Definition: Vehicle.h:51
void RemoveAllPassengers()
Removes all current and pending passengers from the vehicle.
Definition: Vehicle.cpp:226
~Vehicle()
Definition: Vehicle.cpp:61
bool IsVehicleInUse() const
Returns information whether the vehicle is currently used by any unit.
Definition: Vehicle.cpp:591
uint32 UsableSeatNum
Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags.
Definition: Vehicle.h:81
void CalculatePassengerPosition(float &x, float &y, float &z, float *o) const override
This method transforms supplied transport offsets into global coordinates.
Definition: Vehicle.h:100
uint32 _creatureEntry
Can be different than the entry of _me in case of players.
Definition: Vehicle.h:127
Status _status
Internal variable for sanity checks.
Definition: Vehicle.h:128
void Uninstall()
Removes all passengers and sets status to STATUS_UNINSTALLING. No new passengers can be added to the ...
Definition: Vehicle.cpp:109
void RemovePendingEventsForSeat(int8 seatId)
Removes any pending events for given seatId. Executed when a @VehicleJoinEvent::Execute is called.
Definition: Vehicle.cpp:737
Unit * _me
The underlying unit with the vehicle kit. Can be player or creature.
Definition: Vehicle.h:123
bool HasEmptySeat(int8 seatId) const
Checks if vehicle's seat specified by 'seatId' is empty.
Definition: Vehicle.cpp:270
PendingJoinEventContainer _pendingJoinEvents
Collection of delayed join events for prospective passengers.
Definition: Vehicle.h:131
Trinity::unique_weak_ptr< Vehicle > GetWeakPtr() const
Definition: Vehicle.cpp:997
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
Definition: Vehicle.cpp:647
void Install()
Initializes power type for vehicle. Nothing more.
Definition: Vehicle.cpp:78
bool IsControllableVehicle() const
Definition: Vehicle.cpp:600
void RelocatePassengers()
Relocate passengers. Must be called after m_base::Relocate.
Definition: Vehicle.cpp:554
bool HasPendingEventForSeat(int8 seatId) const
Definition: Vehicle.cpp:952
void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime)
Installs an accessory.
Definition: Vehicle.cpp:381
std::string GetDebugInfo() const
Definition: Vehicle.cpp:970
SeatMap::const_iterator GetNextEmptySeat(int8 seatId, bool next) const
Gets the next empty seat based on current seat.
Definition: Vehicle.cpp:314
VehicleSeatAddon const * GetSeatAddonForSeatOfPassenger(Unit const *passenger) const
Gets the vehicle seat addon data for the seat of a passenger.
Definition: Vehicle.cpp:355
friend class VehicleJoinEvent
Definition: Vehicle.h:80
Milliseconds GetDespawnDelay()
Definition: Vehicle.cpp:962
void RemovePendingEventsForPassenger(Unit *passenger)
Definition: Vehicle.cpp:762
VehicleEntry const * _vehicleInfo
DBC data for vehicle.
Definition: Vehicle.h:124
void InstallAllAccessories(bool evading)
Definition: Vehicle.cpp:85
bool AddVehiclePassenger(Unit *unit, int8 seatId=-1)
Definition: Vehicle.cpp:421
Map * GetMap() const
Definition: Object.h:624
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
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)
Definition: Object.cpp:2025
TransportBase * GetTransport() const
Definition: Object.h:750
std::string const & GetName() const
Definition: Object.h:555
EventProcessor m_Events
Definition: Object.h:777
MovementInfo m_movementInfo
Definition: Object.h:761
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
void ResetTransport()
Definition: MovementInfo.h:129
struct MovementInfo::TransportInfo transport
constexpr void Relocate(float x, float y)
Definition: Position.h:63
std::array< uint16, 8 > SeatID
bool HasFlag(VehicleSeatFlags flag) const
DBCPosition3D AttachmentOffset