TrinityCore
Loading...
Searching...
No Matches
blackrock_depths.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 "ScriptMgr.h"
19#include "blackrock_depths.h"
20#include "GameObject.h"
21#include "GameObjectAI.h"
22#include "InstanceScript.h"
23#include "Log.h"
24#include "ObjectAccessor.h"
25#include "Player.h"
26#include "ScriptedEscortAI.h"
27#include "ScriptedGossip.h"
28#include "TemporarySummon.h"
29#include "WorldSession.h"
30
31//go_shadowforge_brazier
33{
34 public:
35 go_shadowforge_brazier() : GameObjectScript("go_shadowforge_brazier") { }
36
38 {
39 go_shadowforge_brazierAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
40
42
43 bool OnGossipHello(Player* /*player*/) override
44 {
47 else
49 // If used both braziers, open linked doors (North and South)
51 {
54 }
55
56 return false;
57 }
58 };
59
60 GameObjectAI* GetAI(GameObject* go) const override
61 {
62 return GetBlackrockDepthsAI<go_shadowforge_brazierAI>(go);
63 }
64};
65
66// npc_grimstone
68{
70 NPC_THELDREN = 16059,
71
72 //4 or 6 in total? 1+2+1 / 2+2+2 / 3+3. Depending on this, code should be changed.
74};
75
77{
78 8925, // Dredge Worm
79 8926, // Deep Stinger
80 8927, // Dark Screecher
81 8928, // Burrowing Thundersnout
82 8933, // Cave Creeper
83 8932, // Borer Beetle
84};
85
87{
88 9027, // Gorosh
89 9028, // Grizzle
90 9029, // Eviscerator
91 9030, // Ok'thor
92 9031, // Anub'shiah
93 9032, // Hedrum
94};
95
97{
98public:
99 at_ring_of_law() : AreaTriggerScript("at_ring_of_law") { }
100
101 bool OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override
102 {
103 if (InstanceScript* instance = player->GetInstanceScript())
104 {
105 if (instance->GetData(TYPE_RING_OF_LAW) == IN_PROGRESS || instance->GetData(TYPE_RING_OF_LAW) == DONE)
106 return false;
107
108 instance->SetData(TYPE_RING_OF_LAW, IN_PROGRESS);
109 player->SummonCreature(NPC_GRIMSTONE, 625.559f, -205.618f, -52.735f, 2.609f, TEMPSUMMON_DEAD_DESPAWN);
110
111 return false;
112 }
113 return false;
114 }
115};
116
117// npc_grimstone
127
128static constexpr uint32 PATH_ESCORT_GRIMSTONE = 80770;
129
132{
133public:
134 npc_grimstone() : CreatureScript("npc_grimstone") { }
135
136 CreatureAI* GetAI(Creature* creature) const override
137 {
138 return GetBlackrockDepthsAI<npc_grimstoneAI>(creature);
139 }
140
141 struct npc_grimstoneAI : public EscortAI
142 {
143 npc_grimstoneAI(Creature* creature) : EscortAI(creature)
144 {
145 Initialize();
146 instance = creature->GetInstanceScript();
147 MobSpawnId = rand32() % 6;
148 }
149
151 {
152 EventPhase = 0;
153 Event_Timer = 1000;
154
155 MobCount = 0;
156 MobDeath_Timer = 0;
157
158 for (uint8 i = 0; i < MAX_NPC_AMOUNT; ++i)
159 RingMobGUID[i].Clear();
160
162
163 CanWalk = false;
164 }
165
167
170
174
177
179
180 void Reset() override
181 {
182 Initialize();
183 }
184
187 {
188 if (Creature* tmp = me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN))
189 RingMobGUID[MobCount] = tmp->GetGUID();
190
191 ++MobCount;
192
194 MobDeath_Timer = 2500;
195 }
196
199 {
200 if (Creature* tmp = me->SummonCreature(RingBoss[rand32() % 6], 644.300f, -175.989f, -53.739f, 3.418f, TEMPSUMMON_DEAD_DESPAWN))
201 RingBossGUID = tmp->GetGUID();
202
203 MobDeath_Timer = 2500;
204 }
205
206 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
207 {
208 switch (waypointId)
209 {
210 case 0:
212 CanWalk = false;
213 Event_Timer = 5000;
214 break;
215 case 1:
217 CanWalk = false;
218 Event_Timer = 5000;
219 break;
220 case 2:
221 CanWalk = false;
222 break;
223 case 3:
225 break;
226 case 4:
228 CanWalk = false;
229 Event_Timer = 5000;
230 break;
231 case 5:
234 TC_LOG_DEBUG("scripts", "npc_grimstone: event reached end and set complete.");
235 break;
236 }
237 }
238
239 void HandleGameObject(uint32 id, bool open)
240 {
242 }
243
244 void UpdateAI(uint32 diff) override
245 {
246 if (MobDeath_Timer)
247 {
248 if (MobDeath_Timer <= diff)
249 {
250 MobDeath_Timer = 2500;
251
252 if (!RingBossGUID.IsEmpty())
253 {
255 if (boss && !boss->IsAlive() && boss->isDead())
256 {
258 Event_Timer = 5000;
259 MobDeath_Timer = 0;
260 return;
261 }
262 return;
263 }
264
265 for (uint8 i = 0; i < MAX_NPC_AMOUNT; ++i)
266 {
268 if (mob && !mob->IsAlive() && mob->isDead())
269 {
270 RingMobGUID[i].Clear();
271 --MobCount;
272
273 //seems all are gone, so set timer to continue and discontinue this
274 if (!MobCount)
275 {
276 Event_Timer = 5000;
277 MobDeath_Timer = 0;
278 }
279 }
280 }
281 } else MobDeath_Timer -= diff;
282 }
283
284 if (Event_Timer)
285 {
286 if (Event_Timer <= diff)
287 {
288 switch (EventPhase)
289 {
290 case 0:
294 Start(false);
295 CanWalk = true;
296 Event_Timer = 0;
297 break;
298 case 1:
299 CanWalk = true;
300 Event_Timer = 0;
301 break;
302 case 2:
303 Event_Timer = 2000;
304 break;
305 case 3:
307 Event_Timer = 3000;
308 break;
309 case 4:
310 CanWalk = true;
311 me->SetVisible(false);
313 Event_Timer = 8000;
314 break;
315 case 5:
318 Event_Timer = 8000;
319 break;
320 case 6:
322 Event_Timer = 5000;
323 break;
324 case 7:
325 me->SetVisible(true);
328 CanWalk = true;
329 Event_Timer = 5000;
330 break;
331 case 8:
333 Event_Timer = 5000;
334 break;
335 case 9:
336 me->SetVisible(false);
338 Event_Timer = 0;
339 break;
340 case 10:
341 //if quest, complete
345 CanWalk = true;
346 Event_Timer = 0;
347 break;
348 }
349 ++EventPhase;
350 } else Event_Timer -= diff;
351 }
352
353 if (CanWalk)
354 EscortAI::UpdateAI(diff);
355 }
356 };
357};
358
359// npc_phalanx
366
368{
369public:
370 npc_phalanx() : CreatureScript("npc_phalanx") { }
371
372 CreatureAI* GetAI(Creature* creature) const override
373 {
374 return GetBlackrockDepthsAI<npc_phalanxAI>(creature);
375 }
376
377 struct npc_phalanxAI : public ScriptedAI
378 {
379 npc_phalanxAI(Creature* creature) : ScriptedAI(creature)
380 {
381 Initialize();
382 }
383
385 {
386 ThunderClap_Timer = 12000;
388 MightyBlow_Timer = 15000;
389 }
390
394
395 void Reset() override
396 {
397 Initialize();
398 }
399
400 void UpdateAI(uint32 diff) override
401 {
402 //Return since we have no target
403 if (!UpdateVictim())
404 return;
405
406 //ThunderClap_Timer
407 if (ThunderClap_Timer <= diff)
408 {
410 ThunderClap_Timer = 10000;
411 } else ThunderClap_Timer -= diff;
412
413 //FireballVolley_Timer
414 if (HealthBelowPct(51))
415 {
416 if (FireballVolley_Timer <= diff)
417 {
419 FireballVolley_Timer = 15000;
420 } else FireballVolley_Timer -= diff;
421 }
422
423 //MightyBlow_Timer
424 if (MightyBlow_Timer <= diff)
425 {
427 MightyBlow_Timer = 10000;
428 } else MightyBlow_Timer -= diff;
429
431 }
432 };
433};
434
435// npc_lokhtos_darkbargainer
445
446#define GOSSIP_ITEM_GET_CONTRACT "Get Thorium Brotherhood Contract" // miss in db,maybe wrong
447
449{
450 public:
451 npc_lokhtos_darkbargainer() : CreatureScript("npc_lokhtos_darkbargainer") { }
452
454 {
456
457 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
458 {
459 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
460
461 ClearGossipMenuFor(player);
462 if (action == GOSSIP_ACTION_INFO_DEF + 1)
463 {
464 CloseGossipMenuFor(player);
466 }
467 if (action == GOSSIP_ACTION_TRADE)
468 player->GetSession()->SendListInventory(me->GetGUID());
469
470 return true;
471 }
472
473 bool OnGossipHello(Player* player) override
474 {
476 if (me->IsQuestGiver())
477 player->PrepareQuestMenu(me->GetGUID());
478
479 if (me->IsVendor() && player->GetReputationRank(59) >= REP_FRIENDLY)
481
485 {
487 }
488
489 if (player->GetReputationRank(59) < REP_FRIENDLY)
490 SendGossipMenuFor(player, 3673, me->GetGUID());
491 else
492 SendGossipMenuFor(player, 3677, me->GetGUID());
493
494 return true;
495 }
496 };
497
498 CreatureAI* GetAI(Creature* creature) const override
499 {
500 return GetBlackrockDepthsAI<npc_lokhtos_darkbargainerAI>(creature);
501 }
502};
503
504// npc_rocknot
512
514{
515public:
516 npc_rocknot() : CreatureScript("npc_rocknot") { }
517
518 struct npc_rocknotAI : public EscortAI
519 {
520 npc_rocknotAI(Creature* creature) : EscortAI(creature)
521 {
522 Initialize();
523 instance = creature->GetInstanceScript();
524 }
525
527 {
528 BreakKeg_Timer = 0;
529 BreakDoor_Timer = 0;
530 }
531
533
536
537 void Reset() override
538 {
540 return;
541
542 Initialize();
543 }
544
545 void DoGo(uint32 id, uint32 state)
546 {
548 go->SetGoState((GOState)state);
549 }
550
551 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
552 {
553 switch (waypointId)
554 {
555 case 1:
557 break;
558 case 2:
560 break;
561 case 3:
563 break;
564 case 4:
566 break;
567 case 5:
569 BreakKeg_Timer = 2000;
570 break;
571 }
572 }
573
574 void UpdateAI(uint32 diff) override
575 {
576 if (BreakKeg_Timer)
577 {
578 if (BreakKeg_Timer <= diff)
579 {
581 BreakKeg_Timer = 0;
582 BreakDoor_Timer = 1000;
583 } else BreakKeg_Timer -= diff;
584 }
585
586 if (BreakDoor_Timer)
587 {
588 if (BreakDoor_Timer <= diff)
589 {
591 DoGo(DATA_GO_BAR_KEG_TRAP, 0); //doesn't work very well, leaving code here for future
592 //spell by trap has effect61, this indicate the bar go hostile
593
595 tmp->SetFaction(FACTION_MONSTER);
596
597 //for later, this event(s) has alot more to it.
598 //optionally, DONE can trigger bar to go hostile.
600
601 BreakDoor_Timer = 0;
602 } else BreakDoor_Timer -= diff;
603 }
604
605 EscortAI::UpdateAI(diff);
606 }
607
608 void OnQuestReward(Player* /*player*/, Quest const* quest, uint32 /*item*/) override
609 {
611 return;
612
613 if (quest->GetQuestId() == QUEST_ALE)
614 {
617
619
620 //keep track of amount in instance script, returns SPECIAL if amount ok and event in progress
622 {
625
627 Start(false);
628 }
629 }
630 }
631 };
632
633 CreatureAI* GetAI(Creature* creature) const override
634 {
635 return GetBlackrockDepthsAI<npc_rocknotAI>(creature);
636 }
637};
638
640{
642 new at_ring_of_law();
643 new npc_grimstone();
644 new npc_phalanx();
646 new npc_rocknot();
647}
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:60
@ IN_PROGRESS
@ DONE
@ SPECIAL
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
@ TEMPSUMMON_DEAD_DESPAWN
uint32 rand32()
Definition Random.cpp:70
@ STATE_ESCORT_ESCORTING
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const &guid)
void AddGossipItemFor(Player *player, GossipOptionIcon icon, std::string const &text, uint32 sender, uint32 action)
void ClearGossipMenuFor(Player *player)
void InitGossipMenuFor(Player *player, uint32 menuId)
void CloseGossipMenuFor(Player *player)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_TRADE
@ GOSSIP_ACTION_INFO_DEF
@ EMOTE_ONESHOT_KICK
@ EMOTE_ONESHOT_ATTACK_UNARMED
@ REP_FRIENDLY
@ FACTION_MONSTER
GOState
@ SAY_TEXT4
@ SAY_TEXT3
@ SAY_TEXT6
@ SAY_TEXT2
@ SAY_TEXT5
@ SAY_TEXT1
void AddSC_blackrock_depths()
@ MAX_NPC_AMOUNT
@ NPC_THELDREN
@ NPC_GRIMSTONE
@ SPELL_MIGHTYBLOW
@ SPELL_FIREBALLVOLLEY
@ SPELL_THUNDERCLAP
static constexpr uint32 PATH_ESCORT_GRIMSTONE
@ SPELL_DRUNKEN_RAGE
@ QUEST_ALE
@ PATH_ESCORT_ROCKNOT
@ SAY_GOT_BEER
@ SPELL_CREATE_THORIUM_BROTHERHOOD_CONTRACT_DND
@ QUEST_A_BINDING_CONTRACT
@ ITEM_THRORIUM_BROTHERHOOD_CONTRACT
@ ITEM_SULFURON_INGOT
@ GOSSIP_ITEM_SHOW_ACCESS_MID
@ GOSSIP_ITEM_SHOW_ACCESS_OID
uint32 RingMob[]
uint32 RingBoss[]
#define GOSSIP_ITEM_GET_CONTRACT
@ DATA_PHALANX
@ TYPE_RING_OF_LAW
@ TYPE_BAR
@ DATA_GO_BAR_KEG
@ TYPE_LYCEUM
@ DATA_ARENA3
@ DATA_ARENA2
@ DATA_GOLEM_DOOR_S
@ DATA_GOLEM_DOOR_N
@ DATA_ARENA4
@ DATA_GO_BAR_KEG_TRAP
@ DATA_ARENA1
@ DATA_GO_BAR_DOOR
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void HandleGameObject(ObjectGuid guid, bool open, GameObject *go=nullptr)
virtual ObjectGuid GetGuidData(uint32 type) const override
void UpdateEncounterStateForKilledCreature(uint32 creatureId, Unit *source)
bool IsEmpty() const
Definition ObjectGuid.h:172
void Clear()
Definition ObjectGuid.h:150
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetGossipOptionAction(uint32 selection) const
Definition GossipDef.h:269
bool GetQuestRewardStatus(uint32 quest_id) const
Definition Player.cpp:15626
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition Player.cpp:9763
WorldSession * GetSession() const
Definition Player.h:1719
void PrepareQuestMenu(ObjectGuid guid)
Definition Player.cpp:14270
ReputationRank GetReputationRank(uint32 faction_id) const
Definition Player.cpp:6303
PlayerMenu * PlayerTalkClass
Definition Player.h:1969
uint32 GetQuestId() const
Definition QuestDef.h:229
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Definition Unit.h:769
void SetVisible(bool x)
Definition Unit.cpp:8513
bool IsAlive() const
Definition Unit.h:1234
bool IsQuestGiver() const
Definition Unit.h:1103
void HandleEmoteCommand(Emote emoteId)
Definition Unit.cpp:1568
bool IsVendor() const
Definition Unit.h:1101
bool isDead() const
Definition Unit.h:1236
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
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
void SendListInventory(ObjectGuid guid)
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:55
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:56
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
GameObjectAI * GetAI(GameObject *go) const override
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 Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API GameObject * GetGameObject(WorldObject const &u, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void Start(bool isActiveAttacker=true, ObjectGuid playerGUID=ObjectGuid::Empty, Quest const *quest=nullptr, bool instantRespawn=false, bool canLoopPath=false)
bool HasEscortState(uint32 escortState)
void LoadPath(uint32 pathId)
void UpdateAI(uint32 diff) override
bool HealthBelowPct(uint32 pct) const
void WaypointReached(uint32 waypointId, uint32) override
void HandleGameObject(uint32 id, bool open)
void UpdateAI(uint32 diff) override
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
npc_phalanxAI(Creature *creature)
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
npc_rocknotAI(Creature *creature)
void DoGo(uint32 id, uint32 state)
void WaypointReached(uint32 waypointId, uint32) override
void OnQuestReward(Player *, Quest const *quest, uint32) override