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/* ScriptData
19SDName: Stormwind_City
20SD%Complete: 100
21SDComment: Quest support: 1640, 1447, 434.
22SDCategory: Stormwind City
23EndScriptData */
24
25/* ContentData
26npc_tyrion
27npc_tyrion_spybot
28npc_marzon_silent_blade
29npc_lord_gregor_lescovar
30EndContentData */
31
32#include "ScriptMgr.h"
33#include "MotionMaster.h"
34#include "ObjectAccessor.h"
35#include "Player.h"
36#include "ScriptedEscortAI.h"
37#include "ScriptedGossip.h"
38#include "TemporarySummon.h"
39
40/*######
41## npc_lord_gregor_lescovar
42######*/
43
60
62{
63public:
64 npc_lord_gregor_lescovar() : CreatureScript("npc_lord_gregor_lescovar") { }
65
66 CreatureAI* GetAI(Creature* creature) const override
67 {
68 return new npc_lord_gregor_lescovarAI(creature);
69 }
70
72 {
74 {
75 Initialize();
76 }
77
79 {
80 uiTimer = 0;
81 uiPhase = 0;
82
84 }
85
88
90
91 void Reset() override
92 {
93 Initialize();
94 }
95
96 void EnterEvadeMode(EvadeReason /*why*/) override
97 {
99
101 {
102 if (pMarzon->IsAlive())
103 pMarzon->DisappearAndDie();
104 }
105 }
106
107 void JustEngagedWith(Unit* who) override
108 {
110 {
111 if (pMarzon->IsAlive() && !pMarzon->IsInCombat())
112 pMarzon->AI()->AttackStart(who);
113 }
114 }
115
116 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
117 {
118 switch (waypointId)
119 {
120 case 14:
121 SetEscortPaused(true);
123 uiTimer = 3000;
124 uiPhase = 1;
125 break;
126 case 16:
127 SetEscortPaused(true);
128 if (Creature* pMarzon = me->SummonCreature(NPC_MARZON_BLADE, -8411.360352f, 480.069733f, 123.760895f, 4.941504f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1s))
129 {
130 pMarzon->GetMotionMaster()->MovePoint(0, -8408.000977f, 468.611450f, 123.759903f);
131 MarzonGUID = pMarzon->GetGUID();
132 }
133 uiTimer = 2000;
134 uiPhase = 4;
135 break;
136 }
137 }
138 //TO-DO: We don't have movemaps, also we can't make 2 npcs walks to one point propperly (and we can not use escort ai, because they are 2 different spawns and with same entry), because of it we make them, disappear.
140 {
141 std::list<Creature*> GuardList;
143 if (!GuardList.empty())
144 {
145 for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
146 {
147 if (Creature* pGuard = *itr)
148 pGuard->DisappearAndDie();
149 }
150 }
151 }
152
153 void UpdateAI(uint32 uiDiff) override
154 {
155 if (uiPhase)
156 {
157 if (uiTimer <= uiDiff)
158 {
159 switch (uiPhase)
160 {
161 case 1:
162 if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 8.0f, true))
163 pGuard->AI()->Talk(SAY_GUARD_2);
164 uiTimer = 3000;
165 uiPhase = 2;
166 break;
167 case 2:
169 uiTimer = 2000;
170 uiPhase = 3;
171 break;
172 case 3:
173 SetEscortPaused(false);
174 uiTimer = 0;
175 uiPhase = 0;
176 break;
177 case 4:
179 uiTimer = 0;
180 uiPhase = 0;
181 break;
182 case 5:
184 pMarzon->AI()->Talk(SAY_MARZON_1);
185 uiTimer = 3000;
186 uiPhase = 6;
187 break;
188 case 6:
190 if (Player* player = GetPlayerForEscort())
191 player->AreaExploredOrEventHappens(QUEST_THE_ATTACK);
192 uiTimer = 2000;
193 uiPhase = 7;
194 break;
195 case 7:
196 if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 20.0f, true))
197 pTyrion->AI()->Talk(SAY_TYRION_2);
199 pMarzon->SetFaction(FACTION_MONSTER);
201 uiTimer = 0;
202 uiPhase = 0;
203 break;
204 }
205 } else uiTimer -= uiDiff;
206 }
207 EscortAI::UpdateAI(uiDiff);
208
209 if (!UpdateVictim())
210 return;
211
213 }
214 };
215};
216
217/*######
218## npc_marzon_silent_blade
219######*/
220
222{
223public:
224 npc_marzon_silent_blade() : CreatureScript("npc_marzon_silent_blade") { }
225
226 CreatureAI* GetAI(Creature* creature) const override
227 {
228 return new npc_marzon_silent_bladeAI(creature);
229 }
230
232 {
234 {
235 me->SetWalk(true);
236 }
237
238 void Reset() override
239 {
241 }
242
243 void JustEngagedWith(Unit* who) override
244 {
246
247 if (me->IsSummon())
248 {
249 if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
250 {
251 if (summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAlive() && !summoner->IsInCombat())
252 summoner->ToCreature()->AI()->AttackStart(who);
253 }
254 }
255 }
256
257 void EnterEvadeMode(EvadeReason /*why*/) override
258 {
260
261 if (me->IsSummon())
262 {
263 if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
264 {
265 if (summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAlive())
266 summoner->ToCreature()->DisappearAndDie();
267 }
268 }
269 }
270
271 void MovementInform(uint32 uiType, uint32 /*uiId*/) override
272 {
273 if (uiType != POINT_MOTION_TYPE)
274 return;
275
276 if (me->IsSummon())
277 {
278 Unit* summoner = me->ToTempSummon()->GetSummonerUnit();
279 if (summoner && summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAIEnabled())
280 {
283 if (ai)
284 {
285 ai->uiTimer = 2000;
286 ai->uiPhase = 5;
287 }
288 //me->ChangeOrient(0.0f, summoner);
289 }
290 }
291 }
292
293 void UpdateAI(uint32 /*diff*/) override
294 {
295 if (!UpdateVictim())
296 return;
297
299 }
300 };
301};
302
303/*######
304## npc_tyrion_spybot
305######*/
306
321
322static constexpr uint32 PATH_ESCORT_LESCOVAR = 70850;
323
325{
326public:
327 npc_tyrion_spybot() : CreatureScript("npc_tyrion_spybot") { }
328
329 CreatureAI* GetAI(Creature* creature) const override
330 {
331 return new npc_tyrion_spybotAI(creature);
332 }
333
335 {
336 npc_tyrion_spybotAI(Creature* creature) : EscortAI(creature)
337 {
338 Initialize();
339 }
340
342 {
343 uiTimer = 0;
344 uiPhase = 0;
345 }
346
349
350 void Reset() override
351 {
352 Initialize();
353 }
354
355 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
356 {
357 switch (waypointId)
358 {
359 case 1:
360 SetEscortPaused(true);
361 uiTimer = 2000;
362 uiPhase = 1;
363 break;
364 case 5:
365 SetEscortPaused(true);
367 uiTimer = 2000;
368 uiPhase = 5;
369 break;
370 case 17:
371 SetEscortPaused(true);
373 uiTimer = 3000;
374 uiPhase = 8;
375 break;
376 }
377 }
378
379 void UpdateAI(uint32 uiDiff) override
380 {
381 if (uiPhase)
382 {
383 if (uiTimer <= uiDiff)
384 {
385 switch (uiPhase)
386 {
387 case 1:
389 uiTimer = 3000;
390 uiPhase = 2;
391 break;
392 case 2:
393 if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 10.0f))
394 {
395 if (Player* player = GetPlayerForEscort())
396 pTyrion->AI()->Talk(SAY_TYRION_1, player);
397 }
398 uiTimer = 3000;
399 uiPhase = 3;
400 break;
401 case 3:
403 uiTimer = 2000;
404 uiPhase = 4;
405 break;
406 case 4:
407 SetEscortPaused(false);
408 uiPhase = 0;
409 uiTimer = 0;
410 break;
411 case 5:
412 if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 10.0f, true))
413 pGuard->AI()->Talk(SAY_GUARD_1);
414 uiTimer = 3000;
415 uiPhase = 6;
416 break;
417 case 6:
419 uiTimer = 3000;
420 uiPhase = 7;
421 break;
422 case 7:
423 SetEscortPaused(false);
424 uiTimer = 0;
425 uiPhase = 0;
426 break;
427 case 8:
429 pLescovar->AI()->Talk(SAY_LESCOVAR_1);
430 uiTimer = 3000;
431 uiPhase = 9;
432 break;
433 case 9:
435 uiTimer = 3000;
436 uiPhase = 10;
437 break;
438 case 10:
440 {
441 if (Player* player = GetPlayerForEscort())
442 {
443 if (EscortAI* ai = CAST_AI(EscortAI, pLescovar->AI()))
444 {
445 ai->LoadPath(PATH_ESCORT_LESCOVAR);
446 ai->Start(false, player->GetGUID());
447 ai->SetMaxPlayerDistance(200.0f);
448 }
449 }
450 }
452 uiTimer = 0;
453 uiPhase = 0;
454 break;
455 }
456 } else uiTimer -= uiDiff;
457 }
458 EscortAI::UpdateAI(uiDiff);
459
460 if (!UpdateVictim())
461 return;
462
464 }
465 };
466};
467
468/*######
469## npc_tyrion
470######*/
471
473{
474 NPC_TYRION_SPYBOT = 8856
476
477static constexpr uint32 PATH_ESCORT_TYRION_SPYBOT = 14034;
478
480{
481public:
482 npc_tyrion() : CreatureScript("npc_tyrion") { }
483
485 {
486 npc_tyrionAI(Creature* creature) : ScriptedAI(creature) { }
487
488 void OnQuestAccept(Player* player, Quest const* quest) override
489 {
490 if (quest->GetQuestId() == QUEST_THE_ATTACK)
491 {
492 if (Creature* spybot = me->FindNearestCreature(NPC_TYRION_SPYBOT, 5.0f, true))
493 {
494 if (EscortAI* ai = CAST_AI(EscortAI, spybot->AI()))
495 {
496 ai->LoadPath(PATH_ESCORT_TYRION_SPYBOT);
497 ai->Start(false, player->GetGUID());
498 ai->SetMaxPlayerDistance(200.0f);
499 }
500 }
501 }
502 }
503 };
504
505 CreatureAI* GetAI(Creature* creature) const override
506 {
507 return new npc_tyrionAI(creature);
508 }
509};
510
512{
513 new npc_tyrion();
514 new npc_tyrion_spybot();
517}
uint32_t uint32
Definition Define.h:133
@ POINT_MOTION_TYPE
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ FACTION_MONSTER
#define CAST_AI(a, b)
Definition UnitAI.h:27
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:540
void DisappearAndDie()
Definition Creature.h:73
void Clear()
Definition ObjectGuid.h:150
TypeID GetTypeId() const
Definition Object.h:93
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetQuestId() const
Definition QuestDef.h:229
Unit * GetSummonerUnit() const
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
Definition Unit.h:769
void RestoreFaction()
Definition Unit.cpp:11776
void SetFaction(uint32 faction) override
Definition Unit.h:974
TempSummon * ToTempSummon()
Definition Unit.h:1794
UnitAI * GetAI() const
Definition Unit.h:800
bool IsAIEnabled() const
Definition Unit.h:798
bool IsSummon() const
Definition Unit.h:882
bool SetWalk(bool enable)
Definition Unit.cpp:13268
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:3153
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
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
Player * GetPlayerForEscort()
void SetEscortPaused(bool on)
void UpdateAI(uint32 diff) override
void WaypointReached(uint32 waypointId, uint32) override
void MovementInform(uint32 uiType, uint32) override
void OnQuestAccept(Player *player, Quest const *quest) override
void WaypointReached(uint32 waypointId, uint32) override
@ QUEST_THE_ATTACK
@ NPC_MARZON_BLADE
@ SAY_LESCOVAR_4
@ SAY_LESCOVAR_2
@ SAY_LESCOVAR_3
@ NPC_STORMWIND_ROYAL
static constexpr uint32 PATH_ESCORT_LESCOVAR
static constexpr uint32 PATH_ESCORT_TYRION_SPYBOT
@ NPC_PRIESTESS_TYRIONA
@ NPC_LORD_GREGOR_LESCOVAR
@ SAY_QUEST_ACCEPT_ATTACK
void AddSC_stormwind_city()
@ NPC_TYRION_SPYBOT