TrinityCore
vortex_pinnacle.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 "vortex_pinnacle.h"
19#include "Creature.h"
20#include "DB2Structure.h"
21#include "EventMap.h"
22#include "InstanceScript.h"
23#include "ObjectAccessor.h"
24#include "PassiveAI.h"
25#include "Player.h"
26#include "ScriptMgr.h"
27#include "SpellInfo.h"
28#include "SpellScript.h"
29#include "Vehicle.h"
30
32{
41};
42
44{
45 // Spells
58};
59
61{
62 SlipstreamInfo(std::string_view const& stringId, std::string_view const& targetStringId, uint32 vehicleId, bool spellClick, uint32 chainSpellId) :
63 StringId(stringId), TargetStringId(targetStringId), VehicleId(vehicleId), SpellClick(spellClick), ChainSpellId(chainSpellId) { }
64
65 std::string_view StringId;
66 std::string_view TargetStringId;
70};
71
72static std::array<SlipstreamInfo const, 11> const SlipstreamData =
73{
74 // Sequence for Grandvizier Ertan's Slipstreams
75 SlipstreamInfo("vp_slipstream_ertan_1", "vp_slipstream_ertan_2", VEHICLE_ID_SLIPSTREAM_1, true, SPELL_SLIPSTREAM_FIRST),
76 SlipstreamInfo("vp_slipstream_ertan_2", "vp_slipstream_ertan_3", VEHICLE_ID_SLIPSTREAM_2, false, SPELL_SLIPSTREAM_SECOND),
77 SlipstreamInfo("vp_slipstream_ertan_3", "vp_slipstream_landing_zone_1", VEHICLE_ID_SLIPSTREAM_3, false, SPELL_SLIPSTREAM_LAST),
78
79 // Sequence for Altairus' Slipstreams
80 SlipstreamInfo("vp_slipstream_altairus_1", "vp_slipstream_altairus_2", VEHICLE_ID_SLIPSTREAM_1, true, SPELL_SLIPSTREAM_FIRST),
81 SlipstreamInfo("vp_slipstream_altairus_2", "vp_slipstream_altairus_3", VEHICLE_ID_SLIPSTREAM_2, false, SPELL_SLIPSTREAM_SECOND),
82 SlipstreamInfo("vp_slipstream_altairus_3", "vp_slipstream_altairus_4", VEHICLE_ID_SLIPSTREAM_3, false, SPELL_SLIPSTREAM_THIRD),
83 SlipstreamInfo("vp_slipstream_altairus_4", "vp_slipstream_altairus_5", VEHICLE_ID_SLIPSTREAM_4, false, SPELL_SLIPSTREAM_FOURTH),
84 SlipstreamInfo("vp_slipstream_altairus_5", "vp_slipstream_landing_zone_2", VEHICLE_ID_SLIPSTREAM_5, false, SPELL_SLIPSTREAM_LAST),
85
86 // Shortcuts
89 SlipstreamInfo("vp_slipstream_back_to_entrance", "", VEHICLE_ID_SLIPSTREAM_BACK_TO_ENTRANCE, true, SPELL_SLIPSTREAM_ASAAD)
90};
91
93{
94 npc_vp_slipstream(Creature* creature) : NullCreatureAI(creature) { }
95
96 // This is a bit hacky but we have to set the vehicleId before the npc is being sent out via UpdateObject to prevent client visuals from breaking
97 void InitializeAI() override
98 {
99 for (SlipstreamInfo const& slipstreamInfo : SlipstreamData)
100 {
101 if (!me->HasStringId(slipstreamInfo.StringId))
102 continue;
103
104 Vehicle const* vehicle = me->GetVehicleKit();
105 // Uninstall the existing vehicle kit when the vehicleId mismatches
106 if (vehicle && vehicle->GetVehicleInfo()->ID != slipstreamInfo.VehicleId)
107 {
108 me->RemoveVehicleKit(true);
109 vehicle = nullptr;
110 }
111
112 if (!vehicle)
113 me->CreateVehicleKit(slipstreamInfo.VehicleId, me->GetEntry(), true);
114
115 if (slipstreamInfo.SpellClick)
116 {
119 }
120 break;
121 }
122 }
123
124 void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override
125 {
126 if (!apply || !who->IsPlayer())
127 return;
128
129 for (SlipstreamInfo const& slipstreamInfo : SlipstreamData)
130 {
131 if (!me->HasStringId(slipstreamInfo.StringId))
132 continue;
133
134 // The cast of the chain spell is slightly delayed
135 me->m_Events.AddEventAtOffset([caster = me, playerGuid = who->GetGUID(), chainSpellId = slipstreamInfo.ChainSpellId]()
136 {
137 if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
138 if (player->IsOnVehicle(caster))
139 caster->CastSpell(player, chainSpellId);
140 }, 500ms);
141 break;
142 }
143 }
144};
145
146static constexpr uint32 const EVENT_EJECT_ALL_PASSENGERS = 1;
147
149{
151
152 void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply) override
153 {
154 if (!apply)
155 return;
156
157 // Every time a player enters the landing zone vehicle before it can eject passengers, it will delay its cast
159 }
160
161 void UpdateAI(uint32 diff) override
162 {
163 _events.Update(diff);
164
165 if (_events.ExecuteEvent())
167 }
168
169private:
171};
172
173// 84978, 84989, 85395, 85396, 85017 - Slipstream
175{
176 bool Load() override
177 {
178 Creature const* vehicle = GetCaster()->GetVehicleCreatureBase();
179 if (!vehicle)
180 return false;
181
182 for (SlipstreamInfo const& slipstreamInfo : SlipstreamData)
183 {
184 if (!vehicle->HasStringId(slipstreamInfo.StringId))
185 continue;
186
187 _targetStringId = slipstreamInfo.TargetStringId;
188 return true;
189 }
190
191 return false;
192 }
193
195 {
196 target = GetCaster()->FindNearestCreatureWithOptions(200.f, { .StringId = _targetStringId });
197 }
198
199 void Register() override
200 {
202 }
203private:
204 std::string_view _targetStringId;
205};
206
207// 89499, 89501 - Slipstream
209{
210 bool Load() override
211 {
213 return _instance != nullptr;
214 }
215
216 bool Validate(SpellInfo const* /*spellInfo*/) override
217 {
219 }
220
221 // The distance between the shortcut Slipstreams and the Slipstream Landing Platforms is beyond our grid searching limit, we have to manually select the target
223 {
224 switch (GetSpellInfo()->Id)
225 {
228 target.Relocate(landingZone->GetPosition());
229 break;
232 target.Relocate(landingZone->GetPosition());
233 break;
234 default:
235 break;
236 }
237 }
238
239 void Register() override
240 {
242 }
243private:
245};
246
248{
253}
int8_t int8
Definition: Define.h:140
uint32_t uint32
Definition: Define.h:142
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_DEST_NEARBY_ENTRY
@ TARGET_UNIT_NEARBY_ENTRY
#define SpellObjectTargetSelectFn(F, I, N)
Definition: SpellScript.h:869
#define SpellDestinationTargetSelectFn(F, I, N)
Definition: SpellScript.h:874
@ UNIT_NPC_FLAG_SPELLCLICK
Definition: UnitDefines.h:321
@ UNIT_FLAG_UNINTERACTIBLE
Definition: UnitDefines.h:169
Creature *const me
Definition: CreatureAI.h:61
bool HasStringId(std::string_view id) const
Definition: Creature.cpp:3165
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void RescheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:52
void AddEventAtOffset(BasicEvent *event, Milliseconds offset)
Creature * GetCreature(uint32 type)
bool IsPlayer() const
Definition: Object.h:212
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
Definition: SpellScript.h:873
HookList< ObjectTargetSelectHandler > OnObjectTargetSelect
Definition: SpellScript.h:868
SpellInfo const * GetSpellInfo() const
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
Definition: Unit.h:627
Creature * GetVehicleCreatureBase() const
Definition: Unit.cpp:11501
void SetNpcFlag(NPCFlags flags)
Definition: Unit.h:982
bool CreateVehicleKit(uint32 id, uint32 creatureEntry, bool loading=false)
Definition: Unit.cpp:11443
void RemoveVehicleKit(bool onRemoveFromWorld=false)
Definition: Unit.cpp:11459
Vehicle * GetVehicleKit() const
Definition: Unit.h:1711
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
VehicleEntry const * GetVehicleInfo() const
Definition: Vehicle.h:50
Creature * FindNearestCreatureWithOptions(float range, FindCreatureOptions const &options) const
Definition: Object.cpp:2157
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
EventProcessor m_Events
Definition: Object.h:777
void SetDestination(SpellDestination &target)
bool Validate(SpellInfo const *) override
bool Load() override
void SelectNextSlipstream(WorldObject *&target)
std::string_view _targetStringId
void Register() override
void apply(T *val)
Definition: ByteConverter.h:41
SlipstreamInfo(std::string_view const &stringId, std::string_view const &targetStringId, uint32 vehicleId, bool spellClick, uint32 chainSpellId)
std::string_view TargetStringId
std::string_view StringId
void Relocate(Position const &pos)
Definition: Spell.cpp:111
npc_vp_slipstream_landing_zone(Creature *creature)
void UpdateAI(uint32 diff) override
void PassengerBoarded(Unit *, int8, bool apply) override
== Fields =======================================
void InitializeAI() override
npc_vp_slipstream(Creature *creature)
void PassengerBoarded(Unit *who, int8, bool apply) override
== Fields =======================================
VPSlipstreamSpells
@ SPELL_SLIPSTREAM_ENTER
@ SPELL_SLIPSTREAM_FIRST
@ SPELL_SLIPSTREAM_SHORTCUT_ASAAD_TELEPORT
@ SPELL_SLIPSTREAM_ASAAD
@ SPELL_SLIPSTREAM_SHORTCUT_ALTAIRUS
@ SPELL_SLIPSTREAM_LAST
@ SPELL_SLIPSTREAM_THIRD
@ SPELL_SLIPSTREAM_FOURTH
@ SPELL_SLIPSTREAM_SHORTCUT_ASAAD
@ SPELL_SLIPSTREAM_SECOND
@ SPELL_SLIPSTREAM_SHORTCUT_ALTAIRUS_TELEPORT
@ SPELL_GENERIC_EJECT_ALL_PASSENGERS
static constexpr uint32 const EVENT_EJECT_ALL_PASSENGERS
void AddSC_vortex_pinnacle()
VPVehicleIds
@ VEHICLE_ID_SLIPSTREAM_1
@ VEHICLE_ID_SLIPSTREAM_ENTRANCE_1
@ VEHICLE_ID_SLIPSTREAM_2
@ VEHICLE_ID_SLIPSTREAM_4
@ VEHICLE_ID_SLIPSTREAM_BACK_TO_ENTRANCE
@ VEHICLE_ID_SLIPSTREAM_ENTRANCE_2
@ VEHICLE_ID_SLIPSTREAM_5
@ VEHICLE_ID_SLIPSTREAM_3
static std::array< SlipstreamInfo const, 11 > const SlipstreamData
@ DATA_SLIPSTREAM_LANDING_ZONE_1
@ DATA_SLIPSTREAM_LANDING_ZONE_2
#define RegisterVortexPinnacleCreatureAI(ai_name)