Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
zone_tanaris.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6/* ScriptData
7SDName: Tanaris
8SD%Complete: 80
9SDComment: Quest support: 648, 10277, 10279(Special flight path).
10SDCategory: Tanaris
11EndScriptData */
12
13/* ContentData
14npc_custodian_of_time
15npc_steward_of_time
16npc_OOX17
17EndContentData */
18
19#include "ScriptMgr.h"
20#include "ScriptedCreature.h"
21#include "ScriptedGossip.h"
22#include "ScriptedEscortAI.h"
23#include "ScriptedFollowerAI.h"
24#include "Player.h"
25#include "WorldSession.h"
26
27/*######
28## npc_aquementas
29######*/
30
38
40{
41public:
42 npc_aquementas() : CreatureScript("npc_aquementas") { }
43
45 {
46 return new npc_aquementasAI (creature);
47 }
48
50 {
51 npc_aquementasAI(Creature* creature) : ScriptedAI(creature) { }
52
56
59
61 {
62 SendItemTimer = 0;
63 SwitchFactionTimer = 10000;
64 me->setFaction(35);
65 isFriendly = true;
66
67 AquaJetTimer = 5000;
68 FrostShockTimer = 1000;
69 }
70
71 void SendItem(Unit* receiver)
72 {
73 Player* player = receiver->ToPlayer();
74
75 if (player && player->HasItemCount(11169, 1, false) &&
76 player->HasItemCount(11172, 11, false) &&
77 player->HasItemCount(11173, 1, false) &&
78 !player->HasItemCount(11522, 1, true))
79 {
80 ItemPosCountVec dest;
81 uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 11522, 1, NULL);
82 if (msg == EQUIP_ERR_OK)
83 player->StoreNewItem(dest, 11522, 1, true);
84 }
85 }
86
88 {
90 }
91
93 {
94 if (isFriendly)
95 {
96 if (SwitchFactionTimer <= diff)
97 {
98 me->setFaction(91);
99 isFriendly = false;
100 } else SwitchFactionTimer -= diff;
101 }
102
103 if (!UpdateVictim())
104 return;
105
106 if (!isFriendly)
107 {
108 if (SendItemTimer <= diff)
109 {
110 if (me->GetVictim()->GetTypeId() == TypeID::TYPEID_PLAYER)
111 SendItem(me->GetVictim());
112 SendItemTimer = 5000;
113 } else SendItemTimer -= diff;
114 }
115
116 if (FrostShockTimer <= diff)
117 {
119 FrostShockTimer = 15000;
120 } else FrostShockTimer -= diff;
121
122 if (AquaJetTimer <= diff)
123 {
125 AquaJetTimer = 15000;
126 } else AquaJetTimer -= diff;
127
129 }
130 };
131};
132
133/*######
134## npc_custodian_of_time
135######*/
136
154
156{
157public:
158 npc_custodian_of_time() : CreatureScript("npc_custodian_of_time") { }
159
161 {
162 return new npc_custodian_of_timeAI(creature);
163 }
164
166 {
168
170 {
171 if (Player* player = GetPlayerForEscort())
172 {
173 switch (waypointId)
174 {
175 case 0:
176 Talk(WHISPER_CUSTODIAN_1, player);
177 break;
178 case 1:
179 Talk(WHISPER_CUSTODIAN_2, player);
180 break;
181 case 2:
182 Talk(WHISPER_CUSTODIAN_3, player);
183 break;
184 case 3:
185 Talk(WHISPER_CUSTODIAN_4, player);
186 break;
187 case 5:
188 Talk(WHISPER_CUSTODIAN_5, player);
189 break;
190 case 6:
191 Talk(WHISPER_CUSTODIAN_6, player);
192 break;
193 case 7:
194 Talk(WHISPER_CUSTODIAN_7, player);
195 break;
196 case 8:
197 Talk(WHISPER_CUSTODIAN_8, player);
198 break;
199 case 9:
200 Talk(WHISPER_CUSTODIAN_9, player);
201 break;
202 case 10:
203 Talk(WHISPER_CUSTODIAN_4, player);
204 break;
205 case 13:
206 Talk(WHISPER_CUSTODIAN_10, player);
207 break;
208 case 14:
209 Talk(WHISPER_CUSTODIAN_4, player);
210 break;
211 case 16:
212 Talk(WHISPER_CUSTODIAN_11, player);
213 break;
214 case 17:
215 Talk(WHISPER_CUSTODIAN_12, player);
216 break;
217 case 18:
218 Talk(WHISPER_CUSTODIAN_4, player);
219 break;
220 case 22:
221 Talk(WHISPER_CUSTODIAN_13, player);
222 break;
223 case 23:
224 Talk(WHISPER_CUSTODIAN_4, player);
225 break;
226 case 24:
227 Talk(WHISPER_CUSTODIAN_14, player);
228 DoCast(player, 34883);
229 // below here is temporary workaround, to be removed when spell works properly
230 player->AreaExploredOrEventHappens(10277);
231 break;
232 }
233 }
234 }
235
237 {
239 return;
240
241 if (Player* player = who->ToPlayer())
242 {
243 if (who->HasAura(34877) && player->GetQuestStatus(10277) == QUEST_STATUS_INCOMPLETE)
244 {
245 float Radius = 10.0f;
246 if (me->IsWithinDistInMap(who, Radius))
247 {
248 Start(false, false, who->GetGUID());
249 }
250 }
251 }
252 }
253
254 void EnterCombat(Unit* /*who*/) OVERRIDE { }
255 void Reset() OVERRIDE { }
256
258 {
260 }
261 };
262};
263
264/*######
265## npc_steward_of_time
266######*/
267
268#define GOSSIP_ITEM_FLIGHT "Please take me to the master's lair."
269
271{
272public:
273 npc_steward_of_time() : CreatureScript("npc_steward_of_time") { }
274
275 bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest) OVERRIDE
276 {
277 if (quest->GetQuestId() == 10279) //Quest: To The Master's Lair
278 player->CastSpell(player, 34891, true); //(Flight through Caverns)
279
280 return false;
281 }
282
283 bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) OVERRIDE
284 {
285 player->PlayerTalkClass->ClearMenus();
286 if (action == GOSSIP_ACTION_INFO_DEF + 1)
287 player->CastSpell(player, 34891, true); //(Flight through Caverns)
288
289 return true;
290 }
291
292 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
293 {
294 if (creature->IsQuestGiver())
295 player->PrepareQuestMenu(creature->GetGUID());
296
297 if (player->GetQuestStatus(10279) == QUEST_STATUS_INCOMPLETE || player->GetQuestRewardStatus(10279))
298 {
300 player->SEND_GOSSIP_MENU(9978, creature->GetGUID());
301 }
302 else
303 player->SEND_GOSSIP_MENU(9977, creature->GetGUID());
304
305 return true;
306 }
307};
308
309/*######
310## npc_OOX17
311######*/
312
326
328{
329public:
330 npc_OOX17() : CreatureScript("npc_OOX17") { }
331
332 bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
333 {
334 if (quest->GetQuestId() == Q_OOX17)
335 {
336 creature->setFaction(113);
337 creature->SetFullHealth();
338 creature->SetUInt32Value(UNIT_FIELD_ANIM_TIER, 0);
339 creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
340 creature->AI()->Talk(SAY_OOX_START);
341
342 if (npc_escortAI* pEscortAI = CAST_AI(npc_OOX17::npc_OOX17AI, creature->AI()))
343 pEscortAI->Start(true, false, player->GetGUID());
344 }
345 return true;
346 }
347
349 {
350 return new npc_OOX17AI(creature);
351 }
352
353 struct npc_OOX17AI : public npc_escortAI
354 {
355 npc_OOX17AI(Creature* creature) : npc_escortAI(creature) { }
356
358 {
359 if (Player* player = GetPlayerForEscort())
360 {
361 switch (waypointId)
362 {
363 case 23:
364 me->SummonCreature(SPAWN_FIRST, -8350.96f, -4445.79f, 10.10f, 6.20f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
365 me->SummonCreature(SPAWN_FIRST, -8355.96f, -4447.79f, 10.10f, 6.27f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
366 me->SummonCreature(SPAWN_FIRST, -8353.96f, -4442.79f, 10.10f, 6.08f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
368 break;
369 case 56:
370 me->SummonCreature(SPAWN_SECOND_1, -7510.07f, -4795.50f, 9.35f, 6.06f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
371 me->SummonCreature(SPAWN_SECOND_2, -7515.07f, -4797.50f, 9.35f, 6.22f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
372 me->SummonCreature(SPAWN_SECOND_2, -7518.07f, -4792.50f, 9.35f, 6.22f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
374 if (Creature* scoff = me->FindNearestCreature(SPAWN_SECOND_2, 30))
375 scoff->AI()->Talk(SAY_OOX17_AMBUSH_REPLY);
376 break;
377 case 86:
379 player->GroupEventHappens(Q_OOX17, me);
380 break;
381 }
382 }
383 }
384
385 void Reset()OVERRIDE { }
386
387 void EnterCombat(Unit* /*who*/) OVERRIDE
388 {
390 }
391
393 {
394 summoned->AI()->AttackStart(me);
395 }
396 };
397};
398
399/*####
400# npc_tooga
401####*/
402
419
420Position const ToWaterLoc = {-7032.664551f, -4906.199219f, -1.606446f, 0.0f};
421
423{
424public:
425 npc_tooga() : CreatureScript("npc_tooga") { }
426
427 bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
428 {
429 if (quest->GetQuestId() == QUEST_TOOGA)
430 {
431 if (npc_toogaAI* pToogaAI = CAST_AI(npc_tooga::npc_toogaAI, creature->AI()))
432 pToogaAI->StartFollow(player, FACTION_TOOG_ESCORTEE, quest);
433 }
434
435 return true;
436 }
437
439 {
440 return new npc_toogaAI(creature);
441 }
442
443 struct npc_toogaAI : public FollowerAI
444 {
445 npc_toogaAI(Creature* creature) : FollowerAI(creature) { }
446
450
452
454 {
455 CheckSpeechTimer = 2500;
456 PostEventTimer = 1000;
457 PhasePostEvent = 0;
458
459 TortaGUID = 0;
460 }
461
463 {
465
466 if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE | STATE_FOLLOW_POSTEVENT) && who->GetEntry() == NPC_TORTA)
467 {
468 if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE))
469 {
470 Player* player = GetLeaderForFollower();
471 if (player && player->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE)
473
474 TortaGUID = who->GetGUID();
475 SetFollowComplete(true);
476 }
477 }
478 }
479
480 void MovementInform(uint32 MotionType, uint32 PointId) OVERRIDE
481 {
482 FollowerAI::MovementInform(MotionType, PointId);
483
484 if (MotionType != POINT_MOTION_TYPE)
485 return;
486
487 if (PointId == POINT_ID_TO_WATER)
489 }
490
492 {
493 if (!UpdateVictim())
494 {
495 //we are doing the post-event, or...
497 {
498 if (PostEventTimer <= Diff)
499 {
500 PostEventTimer = 5000;
501
503 if (!torta || !torta->IsAlive())
504 {
505 //something happened, so just complete
507 return;
508 }
509
510 switch (PhasePostEvent)
511 {
512 case 1:
514 break;
515 case 2:
516 torta->AI()->Talk(SAY_TORT_POST_2);
517 break;
518 case 3:
520 break;
521 case 4:
522 torta->AI()->Talk(SAY_TORT_POST_4);
523 break;
524 case 5:
526 break;
527 case 6:
528 torta->AI()->Talk(SAY_TORT_POST_6);
529 me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, ToWaterLoc);
530 break;
531 }
532
534 }
535 else
536 PostEventTimer -= Diff;
537 }
538 //...we are doing regular speech check
540 {
541 if (CheckSpeechTimer <= Diff)
542 {
543 CheckSpeechTimer = 5000;
544
545 if ((std::rand() % 9) > 8)
547 }
548 else
549 CheckSpeechTimer -= Diff;
550 }
551
552 return;
553 }
554
556 }
557 };
558};
559
561{
564 new npc_OOX17();
565}
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ EQUIP_ERR_OK
Definition Item.h:28
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
#define INTERACTION_DISTANCE
Definition Object.h:21
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:777
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
#define CAST_AI(a, b)
@ STATE_ESCORT_ESCORTING
@ STATE_FOLLOW_COMPLETE
@ STATE_FOLLOW_POSTEVENT
@ STATE_FOLLOW_INPROGRESS
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ NULL_BAG
Definition Unit.h:336
@ NULL_SLOT
Definition Unit.h:337
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ UNIT_FIELD_ANIM_TIER
@ UNIT_FIELD_FLAGS
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
void MovementInform(uint32 motionType, uint32 pointId) OVERRIDE
void MoveInLineOfSight(Unit *) OVERRIDE
Player * GetLeaderForFollower()
void SetFollowComplete(bool bWithEndEvent=false)
FollowerAI(Creature *creature)
bool HasFollowState(uint32 uiFollowState) const
Player * ToPlayer()
Definition Object.h:204
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=NULL) const
QuestStatus GetQuestStatus(uint32 quest_id) const
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, AllowedLooterSet const &allowedLooters=AllowedLooterSet())
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
bool IsAlive() const
Definition Unit.h:2032
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
bool OnQuestAccept(Player *player, Creature *creature, Quest const *quest) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnGossipSelect(Player *player, Creature *, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnQuestAccept(Player *player, Creature *, Quest const *quest) OVERRIDE
bool OnQuestAccept(Player *player, Creature *creature, const Quest *quest) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Creature * me
ScriptedAI(Creature *creature)
npc_OOX17AI(Creature *creature)
void EnterCombat(Unit *) OVERRIDE
void WaypointReached(uint32 waypointId) OVERRIDE
void JustSummoned(Creature *summoned) OVERRIDE
npc_aquementasAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void EnterCombat(Unit *who) OVERRIDE
void WaypointReached(uint32 waypointId) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Player * GetPlayerForEscort()
bool HasEscortState(uint32 escortState) const
npc_escortAI(Creature *creature)
void Start(bool isActiveAttacker=true, bool run=false, uint64 playerGUID=0, Quest const *quest=NULL, bool instantRespawn=false, bool canLoopPath=false, bool resetWaypoints=true)
void MovementInform(uint32 MotionType, uint32 PointId) OVERRIDE
npc_toogaAI(Creature *creature)
void UpdateFollowerAI(uint32 Diff) OVERRIDE
void MoveInLineOfSight(Unit *who) OVERRIDE
@ SAY_OOX_AGGRO
@ SAY_OOX_END
@ SAY_OOX_START
@ SAY_OOX_AMBUSH
CustodianOfTime
@ WHISPER_CUSTODIAN_3
@ WHISPER_CUSTODIAN_4
@ WHISPER_CUSTODIAN_5
@ WHISPER_CUSTODIAN_1
@ WHISPER_CUSTODIAN_12
@ WHISPER_CUSTODIAN_10
@ WHISPER_CUSTODIAN_7
@ WHISPER_CUSTODIAN_6
@ WHISPER_CUSTODIAN_11
@ WHISPER_CUSTODIAN_2
@ WHISPER_CUSTODIAN_13
@ WHISPER_CUSTODIAN_8
@ WHISPER_CUSTODIAN_9
@ WHISPER_CUSTODIAN_14
#define GOSSIP_ITEM_FLIGHT
Position const ToWaterLoc
Aquementas
@ SPELL_AQUA_JET
@ AGGRO_YELL_AQUE
@ SPELL_FROST_SHOCK
Npc00X17
@ SAY_OOX_AGGRO
@ SPAWN_SECOND_2
@ SAY_OOX_END
@ SAY_OOX_START
@ SPAWN_FIRST
@ Q_OOX17
@ SAY_OOX17_AMBUSH_REPLY
@ SAY_OOX_AMBUSH
@ SPAWN_SECOND_1
void AddSC_tanaris()
@ NPC_TORTA
@ FACTION_TOOG_ESCORTEE
@ SAY_TOOG_POST_1
@ SAY_TORT_POST_2
@ SAY_TORT_POST_6
@ SAY_TORT_POST_4
@ SAY_TOOG_WORRIED
@ QUEST_TOOGA
@ SAY_TOOG_POST_3
@ SAY_TOOG_POST_5
@ POINT_ID_TO_WATER