TrinityCore
Loading...
Searching...
No Matches
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 "Common.h"
21#include "CreatureAI.h"
22#include "DBCStores.h"
23#include "EventProcessor.h"
24#include "Log.h"
25#include "MotionMaster.h"
26#include "MoveSplineInit.h"
27#include "ObjectAccessor.h"
28#include "ObjectMgr.h"
29#include "Player.h"
30#include "ScriptMgr.h"
31#include "SpellAuraEffects.h"
32#include "TemporarySummon.h"
33#include "Unit.h"
34#include "Util.h"
35
36Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) :
37UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(STATUS_NONE)
38{
39 for (uint32 i = 0; i < MAX_VEHICLE_SEATS; ++i)
40 {
41 if (uint32 seatId = _vehicleInfo->SeatID[i])
42 if (VehicleSeatEntry const* veSeat = sVehicleSeatStore.LookupEntry(seatId))
43 {
44 VehicleSeatAddon const* addon = sObjectMgr->GetVehicleSeatAddon(seatId);
45 Seats.insert(std::make_pair(i, VehicleSeat(veSeat, addon)));
46 if (veSeat->CanEnterOrExit())
48 }
49 }
50
51 // Set or remove correct flags based on available seats. Will overwrite db data (if wrong).
52 if (UsableSeatNum)
54 else
56
58}
59
61{
64 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
65 ASSERT(itr->second.IsEmpty());
66}
67
78{
80 if (GetBase()->GetTypeId() == TYPEID_UNIT)
81 sScriptMgr->OnInstall(this);
82}
83
85{
86 if (GetBase()->GetTypeId() == TYPEID_PLAYER || !evading)
87 RemoveAllPassengers(); // We might have aura's saved in the DB with now invalid casters - remove
88
89 VehicleAccessoryList const* accessories = sObjectMgr->GetVehicleAccessoryList(this);
90 if (!accessories)
91 return;
92
93 for (VehicleAccessoryList::const_iterator itr = accessories->begin(); itr != accessories->end(); ++itr)
94 if (!evading || itr->IsMinion) // only install minions on evade mode
95 InstallAccessory(itr->AccessoryEntry, itr->SeatId, itr->IsMinion, itr->SummonedType, itr->SummonTime);
96}
97
109{
111 if (_status == STATUS_UNINSTALLING && !GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
112 {
113 TC_LOG_ERROR("entities.vehicle", "Vehicle {} Entry: {} attempts to uninstall, but already has STATUS_UNINSTALLING! "
114 "Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUID().ToString(), _creatureEntry);
115 return;
116 }
117
119 TC_LOG_DEBUG("entities.vehicle", "Vehicle::Uninstall Entry: {}, {}", _creatureEntry, _me->GetGUID().ToString());
121
122 if (GetBase()->GetTypeId() == TYPEID_UNIT)
123 sScriptMgr->OnUninstall(this);
124}
125
137void Vehicle::Reset(bool evading /*= false*/)
138{
139 if (GetBase()->GetTypeId() != TYPEID_UNIT)
140 return;
141
142 TC_LOG_DEBUG("entities.vehicle", "Vehicle::Reset (Entry: {}, {}, DBGuid: {})", GetCreatureEntry(), _me->GetGUID().ToString(), _me->ToCreature()->GetSpawnId());
143
145 if (GetBase()->IsAlive())
146 InstallAllAccessories(evading);
147
148 sScriptMgr->OnReset(this);
149}
150
161{
162 // This couldn't be done in DB, because some spells have MECHANIC_NONE
163
164 // Vehicles should be immune on Knockback ...
167
168 // Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
170 {
171 // Heal & dispel ...
176
177 // ... Shield & Immunity grant spells ...
184
185 // ... Resistance, Split damage, Change stats ...
191 }
192
193 // If vehicle flag for fixed position set (cannons), or if the following hardcoded units, then set state rooted
194 // 30236 | Argent Cannon
195 // 39759 | Tankbuster Cannon
196 if ((GetVehicleInfo()->Flags & VEHICLE_FLAG_FIXED_POSITION) || GetBase()->GetEntry() == 30236 || GetBase()->GetEntry() == 39759)
198
199 // Different immunities for vehicles goes below
200 switch (GetVehicleInfo()->ID)
201 {
202 // code below prevents a bug with movable cannons
203 case 160: // Strand of the Ancients
204 case 244: // Wintergrasp
205 case 510: // Isle of Conquest
206 case 452: // Isle of Conquest
207 case 543: // Isle of Conquest
209 // why we need to apply this? we can simple add immunities to slow mechanic in DB
211 break;
212 case 335: // Salvaged Chopper
213 case 336: // Salvaged Siege Engine
214 case 338: // Salvaged Demolisher
216 break;
217 default:
218 break;
219 }
220}
221
232{
233 TC_LOG_DEBUG("entities.vehicle", "Vehicle::RemoveAllPassengers. Entry: {}, {}", _creatureEntry, _me->GetGUID().ToString());
234
237 {
239 Vehicle* eventVehicle = _status != STATUS_UNINSTALLING ? this : nullptr;
240
241 while (!_pendingJoinEvents.empty())
242 {
244 e->ScheduleAbort();
245 e->Target = eventVehicle;
246 _pendingJoinEvents.pop_front();
247 }
248 }
249
250 // Passengers always cast an aura with SPELL_AURA_CONTROL_VEHICLE on the vehicle
251 // We just remove the aura and the unapply handler will make the target leave the vehicle.
252 // We don't need to iterate over Seats
254
255 // Aura script might cause the vehicle to be despawned in the middle of handling SPELL_AURA_CONTROL_VEHICLE removal
256 // In that case, aura effect has already been unregistered but passenger may still be found in Seats
257 for (auto const& [_, seat] : Seats)
258 if (Unit* passenger = ObjectAccessor::GetUnit(*_me, seat.Passenger.Guid))
259 passenger->_ExitVehicle();
260}
261
275bool Vehicle::HasEmptySeat(int8 seatId) const
276{
277 SeatMap::const_iterator seat = Seats.find(seatId);
278 if (seat == Seats.end())
279 return false;
280 return seat->second.IsEmpty();
281}
282
297{
298 SeatMap::const_iterator seat = Seats.find(seatId);
299 if (seat == Seats.end())
300 return nullptr;
301
302 return ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger.Guid);
303}
304
319SeatMap::const_iterator Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
320{
321 SeatMap::const_iterator seat = Seats.find(seatId);
322 if (seat == Seats.end())
323 return seat;
324
325 while (!seat->second.IsEmpty() || HasPendingEventForSeat(seat->first) || (!seat->second.SeatInfo->CanEnterOrExit() && !seat->second.SeatInfo->IsUsableByOverride()))
326 {
327 if (next)
328 {
329 if (++seat == Seats.end())
330 seat = Seats.begin();
331 }
332 else
333 {
334 if (seat == Seats.begin())
335 seat = Seats.end();
336 --seat;
337 }
338
339 // Make sure we don't loop indefinetly
340 if (seat->first == seatId)
341 return Seats.end();
342 }
343
344 return seat;
345}
346
361{
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;
365
366 return nullptr;
367}
368
386void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime)
387{
390 {
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(),
393 GetCreatureEntry(), entry, (int32)seatId);
394 return;
395 }
396
397 TC_LOG_DEBUG("entities.vehicle", "Vehicle ({}, Entry {}): installing accessory (Entry: {}) on seat: {}",
398 _me->GetGUID().ToString(), GetCreatureEntry(), entry, (int32)seatId);
399
400 TempSummon* accessory = _me->SummonCreature(entry, *_me, TempSummonType(type), Milliseconds(summonTime));
401 ASSERT(accessory);
402
403 if (minion)
405
406 _me->HandleSpellClick(accessory, seatId);
407
410}
411
426bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
427{
430 {
431 TC_LOG_ERROR("entities.vehicle", "Passenger {}, attempting to board vehicle {} during uninstall! SeatId: {}",
432 unit->GetGUID().ToString(), _me->GetGUID().ToString(), (int32)seatId);
433 return false;
434 }
435
436 TC_LOG_DEBUG("entities.vehicle", "Unit {} scheduling enter vehicle (entry: {}, vehicleId: {}, guid: {} on seat {}",
437 unit->GetName(), _me->GetEntry(), _vehicleInfo->ID, _me->GetGUID().ToString(), (int32)seatId);
438
439 // The seat selection code may kick other passengers off the vehicle.
440 // While the validity of the following may be arguable, it is possible that when such a passenger
441 // exits the vehicle will dismiss. That's why the actual adding the passenger to the vehicle is scheduled
442 // asynchronously, so it can be cancelled easily in case the vehicle is uninstalled meanwhile.
443 SeatMap::iterator seat;
444 VehicleJoinEvent* e = new VehicleJoinEvent(this, unit);
445 unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0s));
446
447 if (seatId < 0) // no specific seat requirement
448 {
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()))
451 break;
452
453 if (seat == Seats.end()) // no available seat
454 {
455 e->ScheduleAbort();
456 return false;
457 }
458
459 e->Seat = seat;
460 _pendingJoinEvents.push_back(e);
461 }
462 else
463 {
464 seat = Seats.find(seatId);
465 if (seat == Seats.end())
466 {
467 e->ScheduleAbort();
468 return false;
469 }
470
471 e->Seat = seat;
472 _pendingJoinEvents.push_back(e);
473 if (!seat->second.IsEmpty())
474 {
475 Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger.Guid);
476 ASSERT(passenger);
477 passenger->ExitVehicle();
478 }
479
480 ASSERT(seat->second.IsEmpty());
481 }
482
483 return true;
484}
485
498{
499 if (unit->GetVehicle() != this)
500 return nullptr;
501
502 SeatMap::iterator seat = GetSeatIteratorForPassenger(unit);
503 ASSERT(seat != Seats.end());
504
505 TC_LOG_DEBUG("entities.vehicle", "Unit {} exit vehicle entry {} id {} guid {} seat {}",
506 unit->GetName(), _me->GetEntry(), _vehicleInfo->ID, _me->GetGUID().ToString(), (int32)seat->first);
507
508 if (seat->second.SeatInfo->CanEnterOrExit() && ++UsableSeatNum)
510
511 // Remove UNIT_FLAG_UNINTERACTIBLE if passenger did not have it before entering vehicle
512 if (seat->second.SeatInfo->Flags & VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE && !seat->second.Passenger.IsUninteractible)
514
515 seat->second.Passenger.Reset();
516
517 if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->second.SeatInfo->Flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
518 _me->RemoveCharmedBy(unit);
519
520 if (_me->IsInWorld())
521 {
522 if (!_me->GetTransport())
523 {
526 }
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 seatRelocation.emplace_back(passenger, Position(px, py, pz, po));
572 }
573 }
574
575 for (auto const& pair : seatRelocation)
576 pair.first->UpdatePosition(pair.second);
577}
578
591{
592 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
593 if (!itr->second.IsEmpty())
594 return true;
595
596 return false;
597}
598
600{
601 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
602 if (itr->second.SeatInfo->HasFlag(VEHICLE_SEAT_FLAG_CAN_CONTROL))
603 return true;
604
605 return false;
606}
607
632
647{
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;
651
652 return nullptr;
653}
654
668SeatMap::iterator Vehicle::GetSeatIteratorForPassenger(Unit* passenger)
669{
670 SeatMap::iterator itr;
671 for (itr = Seats.begin(); itr != Seats.end(); ++itr)
672 if (itr->second.Passenger.Guid == passenger->GetGUID())
673 return itr;
674
675 return Seats.end();
676}
677
690{
691 uint8 ret = 0;
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()))
695 ++ret;
696
697 return ret;
698}
699
714{
715 for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
716 {
717 if (*itr == e)
718 {
719 _pendingJoinEvents.erase(itr);
720 break;
721 }
722 }
723}
724
737{
738 for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();)
739 {
740 if ((*itr)->Seat->first == seatId)
741 {
742 (*itr)->ScheduleAbort();
743 _pendingJoinEvents.erase(itr++);
744 }
745 else
746 ++itr;
747 }
748}
749
762{
763 for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();)
764 {
765 if ((*itr)->Passenger == passenger)
766 {
767 (*itr)->ScheduleAbort();
768 _pendingJoinEvents.erase(itr++);
769 }
770 else
771 ++itr;
772 }
773}
774
791{
794
796 auto itr = std::find_if(vehicleAuras.begin(), vehicleAuras.end(), [this](AuraEffect const* aurEff) -> bool
797 {
798 return aurEff->GetCasterGUID() == Passenger->GetGUID();
799 });
800 ASSERT(itr != vehicleAuras.end());
801
802 AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(Target->GetBase()->GetGUID());
803 ASSERT(aurApp && !aurApp->GetRemoveMode());
804
807
808 // Passenger might've died in the meantime - abort if this is the case
809 if (!Passenger->IsAlive())
810 {
811 Abort(0);
812 return true;
813 }
814
815 //It's possible that multiple vehicle join
816 //events are executed in the same update
817 if (Passenger->GetVehicle())
819
821 Seat->second.Passenger.Guid = Passenger->GetGUID();
822 Seat->second.Passenger.IsUninteractible = Passenger->HasUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
823 if (Seat->second.SeatInfo->CanEnterOrExit())
824 {
827 if (!Target->UsableSeatNum)
828 {
831 else
833 }
834 }
835
838
839 VehicleSeatEntry const* veSeat = Seat->second.SeatInfo;
840 VehicleSeatAddon const* veSeatAddon = Seat->second.SeatAddon;
841
842 Player* player = Passenger->ToPlayer();
843 if (player)
844 {
845 // drop flag
846 if (Battleground* bg = player->GetBattleground())
847 bg->EventPlayerDroppedFlag(player);
848
849 player->StopCastingCharm();
850 player->StopCastingBindSight();
854
855 // This is not perfectly mirroring official behavior (aura removal is delayed, most likely on heartbeat)
857 }
858
861
862 float o = veSeatAddon ? veSeatAddon->SeatOrientationOffset : 0.f;
863 float x = veSeat->AttachmentOffset.X;
864 float y = veSeat->AttachmentOffset.Y;
865 float z = veSeat->AttachmentOffset.Z;
866
872
875 {
876 // handles SMSG_CLIENT_CONTROL
878 {
879 // charming failed, probably aura was removed by relocation/scripts/whatever
880 Abort(0);
881 return true;
882 }
883 }
884
885 Passenger->SendClearTarget(); // SMSG_BREAK_TARGET
886 Passenger->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
887 // also adds MOVEMENTFLAG_ROOT
888
889 std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
890 {
891 init.DisableTransportPathTransformations();
892 init.MoveTo(x, y, z, false, true);
893 init.SetFacing(o);
894 init.SetTransportEnter();
895 };
897
898 for (auto const& [guid, threatRef] : Passenger->GetThreatManager().GetThreatenedByMeList())
899 threatRef->GetOwner()->GetThreatManager().AddThreat(Target->GetBase(), threatRef->GetThreat(), nullptr, true, true);
900
901 if (Creature* creature = Target->GetBase()->ToCreature())
902 {
903 if (CreatureAI* ai = creature->AI())
904 ai->PassengerBoarded(Passenger, Seat->first, true);
905
906 sScriptMgr->OnAddPassenger(Target, Passenger, Seat->first);
907
908 // Actually quite a redundant hook. Could just use OnAddPassenger and check for unit typemask inside script.
910 sScriptMgr->OnInstallAccessory(Target, Passenger->ToCreature());
911 }
912
913 return true;
914}
915
928{
930 if (Target)
931 {
932 TC_LOG_DEBUG("entities.vehicle", "Passenger {}, board on vehicle {} SeatId: {} cancelled",
934
937
942 }
943 else
944 TC_LOG_DEBUG("entities.vehicle", "Passenger {}, board on uninstalled vehicle SeatId: {} cancelled",
945 Passenger->GetGUID().ToString(), (int32)Seat->first);
946
949}
950
952{
953 for (PendingJoinEventContainer::const_iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
954 {
955 if ((*itr)->Seat->first == seatId)
956 return true;
957 }
958 return false;
959}
960
962{
963 if (VehicleTemplate const* vehicleTemplate = sObjectMgr->GetVehicleTemplate(this))
964 return vehicleTemplate->DespawnDelay;
965
966 return 1ms;
967}
968
969std::string Vehicle::GetDebugInfo() const
970{
971 std::stringstream sstr;
972 sstr << "Vehicle seats:\n";
973 for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); itr++)
974 {
975 sstr << "seat " << std::to_string(itr->first) << ": " << (itr->second.IsEmpty() ? "empty" : itr->second.Passenger.Guid.ToString()) << "\n";
976 }
977
978 sstr << "Vehicle pending events:";
979
980 if (_pendingJoinEvents.empty())
981 {
982 sstr << " none";
983 }
984 else
985 {
986 sstr << "\n";
987 for (PendingJoinEventContainer::const_iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
988 {
989 sstr << "seat " << std::to_string((*itr)->Seat->first) << ": " << (*itr)->Passenger->GetGUID().ToString() << "\n";
990 }
991 }
992
993 return sstr.str();
994}
995
@ STATUS_NONE
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
Definition DBCEnums.h:480
@ VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE
Definition DBCEnums.h:489
@ VEHICLE_SEAT_FLAG_B_KEEP_PET
Definition DBCEnums.h:511
DBCStorage< VehicleSeatEntry > sVehicleSeatStore(VehicleSeatEntryfmt)
#define MAX_VEHICLE_SEATS
uint8_t uint8
Definition Define.h:135
int8_t int8
Definition Define.h:131
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint32_t uint32
Definition Define.h:133
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#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
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define sObjectMgr
Definition ObjectMgr.h:1721
#define sScriptMgr
Definition ScriptMgr.h:1168
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_DISPEL
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_KNOCK_BACK
@ SPELL_EFFECT_HEAL_PCT
@ EVENT_VEHICLE_BOARD
@ CREATURE_TYPE_MECHANICAL
@ 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
@ 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
@ UNIT_MASK_ACCESSORY
Definition Unit.h:373
@ UNIT_MASK_MINION
Definition Unit.h:365
@ UNIT_STATE_ROOT
Definition Unit.h:230
@ CHARM_TYPE_VEHICLE
Definition Unit.h:656
@ VEHICLE_SPELL_PARACHUTE
@ VEHICLE_FLAG_NO_JUMPING
@ VEHICLE_FLAG_NO_STRAFE
@ VEHICLE_FLAG_FIXED_POSITION
@ VEHICLE_FLAG_FULLSPEEDTURNING
@ VEHICLE_FLAG_ALLOW_PITCHING
@ VEHICLE_FLAG_FULLSPEEDPITCHING
std::vector< VehicleAccessory > VehicleAccessoryList
Aura * GetBase() const
Definition SpellAuras.h:67
AuraRemoveMode GetRemoveMode() const
Definition SpellAuras.h:80
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:209
void ScheduleAbort()
virtual void PassengerBoarded(Unit *, int8, bool)
== Fields =======================================
Definition CreatureAI.h:238
bool isWorldBoss() const
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:83
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:186
CreatureAI * AI() const
Definition Creature.h:154
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)
Definition Object.h:186
bool IsInWorld() const
Definition Object.h:73
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
void StopCastingBindSight() const
Definition Player.cpp:24109
void UnsummonPetTemporaryIfAny()
Definition Player.cpp:25197
void StopCastingCharm()
Definition Player.cpp:20414
Battleground * GetBattleground() const
Definition Player.cpp:23049
void SendOnCancelExpectedVehicleRideAura() const
Definition Player.cpp:20590
auto const & GetThreatenedByMeList() const
Trinity::unique_trackable_ptr companion class, replicating what std::weak_ptr is to std::shared_ptr.
Definition Unit.h:769
Vehicle * GetVehicle() const
Definition Unit.h:1737
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3765
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1384
void AddExtraUnitMovementFlag(uint32 f)
Definition Unit.h:1682
ThreatManager & GetThreatManager()
Definition Unit.h:1155
void SetControlled(bool apply, UnitState state)
Definition Unit.cpp:11256
void HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition Unit.cpp:12478
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0)
Definition Unit.cpp:4022
void SendClearTarget()
Definition Unit.cpp:13155
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:953
bool IsAlive() const
Definition Unit.h:1234
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:1098
Trinity::unique_weak_ptr< Vehicle > GetVehicleKitWeakPtr() const
Definition Unit.h:1736
bool IsAIEnabled() const
Definition Unit.h:798
void AddUnitMovementFlag(uint32 f)
Definition Unit.h:1676
void SetNpcFlag(NPCFlags flags)
Definition Unit.h:1097
void RemoveCharmedBy(Unit *charmer)
Definition Unit.cpp:11666
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
Definition Unit.cpp:8142
void RemoveUnitMovementFlag(uint32 f)
Definition Unit.h:1677
void SetVehicle(Vehicle *vehicle)
Definition Unit.h:1738
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:880
bool SetCharmedBy(Unit *charmer, CharmType type, AuraApplication const *aurApp=nullptr)
Definition Unit.cpp:11489
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
bool IsFlying() const
Definition Unit.h:1762
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:787
void AddUnitTypeMask(uint32 mask)
Definition Unit.h:881
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
virtual void ExitVehicle(Position const *exitPosition=nullptr)
Definition Unit.cpp:12661
bool Execute(uint64, uint32) override
Actually adds the passenger @Passenger to vehicle @Target.
Definition Vehicle.cpp:790
SeatMap::iterator Seat
Definition Vehicle.h:133
Unit * Passenger
Definition Vehicle.h:132
Vehicle * Target
Definition Vehicle.h:131
void Abort(uint64) override
Aborts the event. Implies that unit @Passenger will not be boarding vehicle @Target after all.
Definition Vehicle.cpp:927
Vehicle(Unit *unit, VehicleEntry const *vehInfo, uint32 creatureEntry)
Definition Vehicle.cpp:36
uint8 GetAvailableSeatCount() const
Gets the available seat count.
Definition Vehicle.cpp:689
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:45
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
Definition Vehicle.cpp:296
void ApplyAllImmunities()
Applies specific immunities that cannot be set in DB.
Definition Vehicle.cpp:160
void RemovePendingEvent(VehicleJoinEvent *e)
Removes @VehicleJoinEvent objects from pending join event store. This method only removes it after it...
Definition Vehicle.cpp:713
SeatMap::iterator GetSeatIteratorForPassenger(Unit *passenger)
Gets seat iterator for specified passenger.
Definition Vehicle.cpp:668
VehicleEntry const * GetVehicleInfo() const
Definition Vehicle.h:46
void Reset(bool evading=false)
Reapplies immunities and reinstalls accessories. Only has effect for creatures.
Definition Vehicle.cpp:137
Vehicle * RemovePassenger(Unit *passenger)
Removes the passenger from the vehicle.
Definition Vehicle.cpp:497
void InitMovementInfoForBase()
Sets correct MovementFlags2 based on VehicleFlags from DBC.
Definition Vehicle.cpp:617
bool AddPassenger(Unit *passenger, int8 seatId=-1)
Attempts to add a passenger to the vehicle on 'seatId'.
Definition Vehicle.cpp:426
@ STATUS_INSTALLED
Definition Vehicle.h:83
@ STATUS_UNINSTALLING
Definition Vehicle.h:84
uint32 GetCreatureEntry() const
Definition Vehicle.h:47
void RemoveAllPassengers()
Removes all current and pending passengers from the vehicle.
Definition Vehicle.cpp:231
~Vehicle()
Definition Vehicle.cpp:60
bool IsVehicleInUse() const
Returns information whether the vehicle is currently used by any unit.
Definition Vehicle.cpp:590
uint32 UsableSeatNum
Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags.
Definition Vehicle.h:77
void CalculatePassengerPosition(float &x, float &y, float &z, float *o) const override
This method transforms supplied transport offsets into global coordinates.
Definition Vehicle.h:91
uint32 _creatureEntry
Can be different than the entry of _me in case of players.
Definition Vehicle.h:116
Status _status
Internal variable for sanity checks.
Definition Vehicle.h:117
void Uninstall()
Removes all passengers and sets status to STATUS_UNINSTALLING. No new passengers can be added to the ...
Definition Vehicle.cpp:108
void RemovePendingEventsForSeat(int8 seatId)
Removes any pending events for given seatId. Executed when a @VehicleJoinEvent::Execute is called.
Definition Vehicle.cpp:736
Unit * _me
The underlying unit with the vehicle kit. Can be player or creature.
Definition Vehicle.h:112
bool HasEmptySeat(int8 seatId) const
Checks if vehicle's seat specified by 'seatId' is empty.
Definition Vehicle.cpp:275
PendingJoinEventContainer _pendingJoinEvents
Collection of delayed join events for prospective passengers.
Definition Vehicle.h:120
Trinity::unique_weak_ptr< Vehicle > GetWeakPtr() const
Definition Vehicle.cpp:996
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
Definition Vehicle.cpp:646
void Install()
Initializes power type for vehicle. Nothing more.
Definition Vehicle.cpp:77
bool IsControllableVehicle() const
Definition Vehicle.cpp:599
void RelocatePassengers()
Relocate passengers. Must be called after m_base::Relocate.
Definition Vehicle.cpp:554
bool HasPendingEventForSeat(int8 seatId) const
Definition Vehicle.cpp:951
void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime)
Installs an accessory.
Definition Vehicle.cpp:386
SeatMap Seats
The collection of all seats on the vehicle. Including vacant ones.
Definition Vehicle.h:63
std::string GetDebugInfo() const
Definition Vehicle.cpp:969
SeatMap::const_iterator GetNextEmptySeat(int8 seatId, bool next) const
Gets the next empty seat based on current seat.
Definition Vehicle.cpp:319
VehicleSeatAddon const * GetSeatAddonForSeatOfPassenger(Unit const *passenger) const
Gets the vehicle seat addon data for the seat of a passenger.
Definition Vehicle.cpp:360
friend class VehicleJoinEvent
Definition Vehicle.h:76
Milliseconds GetDespawnDelay()
Definition Vehicle.cpp:961
void RemovePendingEventsForPassenger(Unit *passenger)
Definition Vehicle.cpp:761
VehicleEntry const * _vehicleInfo
DBC data for vehicle.
Definition Vehicle.h:113
void InstallAllAccessories(bool evading)
Definition Vehicle.cpp:84
Map * GetMap() const
Definition Object.h:449
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
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:1992
std::string const & GetName() const
Definition Object.h:382
Transport * GetTransport() const
Definition Object.h:564
EventProcessor m_Events
Definition Object.h:591
MovementInfo m_movementInfo
Definition Object.h:575
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
struct MovementInfo::TransportInfo transport
void Relocate(float x, float y)
Definition Position.h:66
uint32 SeatID[MAX_VEHICLE_SEATS]
bool HasFlag(VehicleSeatFlags flag) const
DBCPosition3D AttachmentOffset