TrinityCore
Loading...
Searching...
No Matches
zone_stormwind_city.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 "AreaTrigger.h"
19#include "AreaTriggerAI.h"
20#include "Containers.h"
21#include "Conversation.h"
22#include "ConversationAI.h"
23#include "CreatureAIImpl.h"
24#include "MotionMaster.h"
25#include "ObjectAccessor.h"
26#include "PhasingHandler.h"
27#include "Player.h"
28#include "ScriptMgr.h"
29#include "ScriptedCreature.h"
30#include "ScriptedGossip.h"
31#include "SpellAuras.h"
32#include "SpellAuraEffects.h"
33#include "SpellInfo.h"
34#include "Spell.h"
35#include "SpellScript.h"
36#include "TemporarySummon.h"
37
39{
40namespace Spells
41{
42 // The King's Command
43 static constexpr uint32 MOPAllianceIntroMoviePlay = 130805;
44 static constexpr uint32 FadeToBlack = 130411;
45
46 // The Mission
47 static constexpr uint32 TeleportPrep = 130832;
48 static constexpr uint32 TeleportTimer = 132032;
49 static constexpr uint32 TheMissionTeleportPlayer = 130321;
50}
51
72
97
98// 55 - Stormwind Keep - Tides of War
100{
102
103 void OnUnitEnter(Unit* unit) override
104 {
105 Player* player = unit->ToPlayer();
107 return;
108
109 // @TODO: cooldown after generic impl
110
112 }
113};
114
115Position const VisionOfSailorsMemoryPosition = { -8384.131f, 324.383f, 148.443f, 1.559973f };
116
117// 4857 - Conversation
119{
120public:
122
128
136
137 void OnCreate(Unit* creator) override
138 {
139 Creature* jainaObject = GetClosestCreatureWithOptions(creator, 30.0f, { .CreatureId = NPC_JAINA_TIDES_OF_WAR, .IgnorePhases = true });
140 if (!jainaObject)
141 return;
142
143 TempSummon* jainaClone = jainaObject->SummonPersonalClone(jainaObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer());
144 if (!jainaClone)
145 return;
146
149 }
150
151 void OnStart() override
152 {
154
155 if (Milliseconds const* jainaWalkStartTime = conversation->GetLineStartTime(privateOwnerLocale, CONVO_LINE_JAINA_WALK))
156 _events.ScheduleEvent(EVENT_JAINA_WALK, *jainaWalkStartTime);
157
159 }
160
161 void OnUpdate(uint32 diff) override
162 {
163 _events.Update(diff);
164
165 switch (_events.ExecuteEvent())
166 {
167 case EVENT_JAINA_WALK:
168 {
169 Creature* jainaClone = conversation->GetActorCreature(3);
170 if (!jainaClone)
171 break;
172
173 jainaClone->GetMotionMaster()->MovePath(PATH_JAINA_VISION_START, false);
174 break;
175 }
177 {
179 if (!privateObjectOwner)
180 break;
181
182 Player* player = privateObjectOwner->ToPlayer();
183 if (!player)
184 break;
185
188 break;
189 }
190 default:
191 break;
192 }
193 }
194
195private:
197};
198
199// 120590 - Jaina Proudmoore
201{
203
204 bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
205 {
206 if (menuId == GOSSIP_MENU_NATION_OF_KULTIRAS)
207 {
208 if (gossipListId == GOSSIP_OPTION_START_KULTIRAS_INTRO)
209 {
210 CloseGossipMenuFor(player);
211 player->CastSpell(nullptr, SPELL_BORALUS_TRANSITION, false);
212 }
213 else if (gossipListId == GOSSIP_OPTION_SKIP_KULTIRAS_INTRO)
214 {
215 CloseGossipMenuFor(player);
216 player->CastSpell(nullptr, SPELL_SKIP_KULTIRAS_INTRO, false);
217 }
218 }
219 return true;
220 }
221
222 void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
223 {
224 if (pathId == PATH_JAINA_VISION_START)
225 {
226 me->SetFacingTo(5.1164f);
228
229 _scheduler.Schedule(14s, [this](TaskContext const& /*context*/)
230 {
232 me->GetMotionMaster()->MovePath(PATH_JAINA_VISION_FINISH, false);
233 });
234 }
235 else if (pathId == PATH_JAINA_VISION_FINISH)
237 }
238
239 void DoAction(int32 action) override
240 {
241 if (action == ACTION_JAINA_LEAVE_COUNCIL)
242 {
243 _scheduler.Schedule(1s, [this](TaskContext& task)
244 {
246 task.Schedule(4s, [this](TaskContext& task)
247 {
249 task.Schedule(2s, [this](TaskContext const& /*task*/)
250 {
251 Unit* privateObjectOwner = ObjectAccessor::GetUnit(*me, me->GetPrivateObjectOwner());
252 if (!privateObjectOwner)
253 return;
254
255 Conversation::CreateConversation(CONVERSATION_JAINA_LEAVE_COUNCIL, privateObjectOwner, *privateObjectOwner, privateObjectOwner->GetGUID(), nullptr, true);
257 });
258 });
259 });
260 }
261 }
262
263 void UpdateAI(uint32 diff) override
264 {
265 _scheduler.Update(diff);
266 }
267
268private:
270};
271
272// 858 - Movie
274{
275public:
276 player_conv_after_movie_tides_of_war() : PlayerScript("player_conv_after_movie_tides_of_war") { }
277
278 void OnMovieComplete(Player* player, uint32 movieId) override
279 {
280 if (movieId == MOVIE_POST_TIDES_OF_WAR)
281 {
282 Creature* jainaClone = GetClosestCreatureWithOptions(player, 30.0f, { .CreatureId = NPC_JAINA_TIDES_OF_WAR, .IgnorePhases = true, .PrivateObjectOwnerGuid = player->GetGUID() });
283 if (!jainaClone)
284 return;
285
286 jainaClone->DespawnOrUnsummon();
287 player->CastSpell(player, SPELL_CONVO_POST_MOVIE_TIDES_OF_WAR, true);
288 }
289 }
290};
291
292// 284807 - Despawn
294{
296 {
297 if (Creature* creature = GetHitUnit()->ToCreature())
298 creature->DespawnOrUnsummon();
299 }
300
305};
306
307// 120756 - Anduin Wrynn
309{
311
312 void OnQuestAccept(Player* player, Quest const* quest) override
313 {
314 if (quest->GetQuestId() == QUEST_NATION_OF_KULTIRAS)
315 {
317
318 Creature* jainaObject = GetClosestCreatureWithOptions(player, 15.0f, { .CreatureId = NPC_JAINA_TIDES_OF_WAR, .IgnorePhases = true });
319 if (!jainaObject)
320 return;
321
322 TempSummon* jainaClone = jainaObject->SummonPersonalClone(jainaObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player->ToPlayer());
323 if (!jainaClone)
324 return;
325
326 jainaClone->AI()->DoAction(ACTION_JAINA_LEAVE_COUNCIL);
327 }
328 }
329};
330
331// 279998 - Kul Tiras: Skip Intro
333{
335
336 void HandleHitTarget(SpellEffIndex /*effIndex*/) const
337 {
338 if (Player* player = GetCaster()->ToPlayer())
339 {
340 player->CastSpell(nullptr, SPELL_SKIP_TOLDAGOR_TELEPORT, false);
341 player->SkipQuests(QuestsToSkip);
342 }
343 }
344
349};
350
351// 240876 - Stormwind Harbor to Boralus transition
353{
354 bool Validate(SpellInfo const* spellInfo) override
355 {
356 return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_1).CalcValueAsInt()) });
357 }
358
359 void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
360 {
361 if (Unit* caster = GetCaster())
362 caster->CastSpell(caster, aurEff->GetAmountAsInt(), false);
363 }
364
369};
370
389
390Position const LysanderWalkToTheDoor = { -8051.493f, 820.21704f, 68.30904f };
391
392// 207353 - Arko'narin Starshade
394{
396
397 void OnQuestAccept(Player* player, Quest const* quest) override
398 {
399 if (quest->GetQuestId() == QUEST_ANCIENT_CURSES)
400 {
402 Conversation::CreateConversation(CONVERSATION_ANCIENT_CURSES, player, *player, player->GetGUID(), nullptr, false);
403 }
404 }
405
406 void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
407 {
409 {
410 me->SetDisableGravity(true, true);
412 _scheduler.Schedule(2s + 500ms, [this](TaskContext const& /*context*/)
413 {
416 });
417 }
418 }
419
420 void UpdateAI(uint32 diff) override
421 {
422 _scheduler.Update(diff);
423 }
424
425private:
427};
428
429// 202700 - Lysander Starshade
431{
433
434 void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
435 {
436 if (pathId == PATH_LYSANDER_WALK_TO_MOUNT_UP)
437 {
438 me->SetDisableGravity(true, true);
440 _scheduler.Schedule(2s + 500ms, [this](TaskContext const& /*context*/)
441 {
444 });
445 }
446 }
447
448 void UpdateAI(uint32 diff) override
449 {
450 _scheduler.Update(diff);
451 }
452
453private:
455};
456
457// 22025 - Conversation
459{
460public:
462
468
474
475 void OnCreate(Unit* creator) override
476 {
477 Creature* arkonarinObject = GetClosestCreatureWithOptions(creator, 20.0f, { .CreatureId = NPC_ARKONARIN_STARSHADE, .IgnorePhases = true });
478 Creature* lysanderObject = GetClosestCreatureWithOptions(creator, 20.0f, { .CreatureId = NPC_LYSANDER_STARSHADE, .IgnorePhases = true });
479 if (!arkonarinObject || !lysanderObject)
480 return;
481
482 TempSummon* arkonarinClone = arkonarinObject->SummonPersonalClone(arkonarinObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer());
483 TempSummon* lysanderClone = lysanderObject->SummonPersonalClone(lysanderObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer());
484 if (!arkonarinClone || !lysanderClone)
485 return;
486
489 lysanderClone->SetWalk(true);
491
495 }
496
497 void OnStart() override
498 {
500
501 if (Milliseconds const* lysanderPathStartTime = conversation->GetLineStartTime(privateOwnerLocale, CONVO_LINE_ARKONARIN_START_PATH))
502 _events.ScheduleEvent(EVENT_ARKONARIN_START_PATH, *lysanderPathStartTime + 2s);
503
504 if (Milliseconds const* lysanderPathStartTime = conversation->GetLineStartTime(privateOwnerLocale, CONVO_LINE_LYSANDER_START_PATH))
505 _events.ScheduleEvent(EVENT_LYSANDER_START_PATH, *lysanderPathStartTime);
506 }
507
508 void OnUpdate(uint32 diff) override
509 {
510 _events.Update(diff);
511
512 switch (_events.ExecuteEvent())
513 {
515 {
516 Creature* arkonarinClone = conversation->GetActorCreature(1);
517 if (!arkonarinClone)
518 break;
519
521 break;
522 }
524 {
525 Creature* lysanderClone = conversation->GetActorCreature(2);
526 if (!lysanderClone)
527 break;
528
530 break;
531 }
532 default:
533 break;
534 }
535 }
536private:
538};
539
540// 130804 - The King's Command Movie Aura
563
564// 130804 - The King's Command Movie Aura
586
587// 140885 - Admiral Rogers Script Effect
610
611// 130832 - Teleport Prep
613{
614 bool Validate(SpellInfo const* /*spellInfo*/) override
615 {
616 return ValidateSpellInfo({
618 });
619 }
620
621 void HandleHitTarget(SpellEffIndex /*effIndex*/) const
622 {
623 Unit* hitUnit = GetHitUnit();
624
625 hitUnit->CancelMountAura();
628 .TriggeringSpell = GetSpell()
629 });
630 }
631
636};
637
638// 132032 - Teleport Timer
663}
664
LocaleConstant
Definition Common.h:51
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
@ TEMPSUMMON_MANUAL_DESPAWN
Spells
Definition PlayerAI.cpp:32
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:150
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1392
#define RegisterSpellAndAuraScriptPair(script_1, script_2)
Definition ScriptMgr.h:1381
#define RegisterAreaTriggerAI(ai_name)
Definition ScriptMgr.h:1428
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
#define RegisterConversationAI(ai_name)
Definition ScriptMgr.h:1437
Creature * GetClosestCreatureWithOptions(WorldObject *source, float maxSearchRange, FindCreatureOptions const &options)
void CloseGossipMenuFor(Player *player)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_APPLY_AURA
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_DUMMY
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will not check if a current cast is in progress.
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
#define SpellEffectFn(F, I, N)
#define AuraEffectRemoveFn(F, I, N, M)
NPCFlags
Non Player Character flags.
@ UNIT_NPC_FLAG_GOSSIP
@ UNIT_NPC_FLAG_QUESTGIVER
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:599
int32 GetAmountAsInt() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
Unit * GetTarget() const
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
Conversation *const conversation
Milliseconds GetLineEndTime(LocaleConstant locale, int32 lineId) const
void AddActor(int32 actorId, uint32 actorIdx, ObjectGuid const &actorGuid)
LocaleConstant GetPrivateObjectOwnerLocale() const
static Conversation * CreateConversation(uint32 conversationEntry, Unit *creator, Position const &pos, ObjectGuid privateObjectOwner, SpellInfo const *spellInfo=nullptr, bool autoStart=true)
Milliseconds const * GetLineStartTime(LocaleConstant locale, int32 lineId) const
Creature * GetActorCreature(uint32 actorIdx) const
Creature *const me
Definition CreatureAI.h:63
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:228
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={}, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MovePath(uint32 pathId, bool repeatable, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< std::pair< Milliseconds, Milliseconds > > waitTimeRangeAtPathEnd={}, Optional< float > wanderDistanceAtPathEnds={}, Optional< bool > followPathBackwardsFromEndToStart={}, Optional< bool > exactSplinePath={}, bool generatePath=true, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
Player * ToPlayer()
Definition Object.h:126
static bool OnConditionChange(WorldObject *object, bool updateVisibility=true)
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition Player.cpp:16679
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15962
uint32 GetQuestId() const
Definition QuestDef.h:637
void HandleAfterEffectRemove(AuraEffect const *, AuraEffectHandleModes) const
void HandleAfterEffectRemove(AuraEffect const *, AuraEffectHandleModes) const
int32 CalcValueAsInt(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:588
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Spell * GetSpell() const
TaskContext & Schedule(TaskScheduler::duration_t time, TaskScheduler::task_handler_t task)
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
virtual void DoAction(int32 param)
Definition UnitAI.h:73
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:162
Definition Unit.h:635
void CancelTravelShapeshiftForm(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool force=false)
Definition Unit.h:1507
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:998
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13361
void CancelMountAura(bool force=false)
Definition Unit.cpp:8350
bool SetWalk(bool enable)
Definition Unit.cpp:13343
void SetFacingTo(float const ori, bool force=true)
Definition Unit.cpp:13289
void SetMountDisplayId(uint32 mountDisplayId)
Definition Unit.h:914
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
Definition Unit.cpp:3159
TempSummon * SummonPersonalClone(Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, Player *privateObjectOwner=nullptr)
Definition Object.cpp:1421
ObjectGuid GetPrivateObjectOwner() const
Definition Object.h:569
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
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:1398
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TriggerCastFlags TriggerFlags
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
void AddSC_stormwind_city()