TrinityCore
instance_stratholme.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: instance_stratholme
20SD%Complete: 50
21SDComment: In progress. Undead side 75% implemented. Save/load not implemented.
22SDCategory: Stratholme
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "AreaBoundary.h"
27#include "Creature.h"
28#include "CreatureAI.h"
29#include "EventMap.h"
30#include "GameObject.h"
31#include "InstanceScript.h"
32#include "Log.h"
33#include "Map.h"
34#include "MotionMaster.h"
35#include "Player.h"
36#include "stratholme.h"
37
39{
42};
43
45{
47};
48
49Position const timmyTheCruelSpawnPosition = { 3625.358f, -3188.108f, 130.3985f, 4.834562f };
50EllipseBoundary const beforeScarletGate(Position(3671.158f, -3181.79f), 60.0f, 40.0f);
51
52static constexpr DungeonEncounterData Encounters[] =
53{
54 { BOSS_HEARTHSINGER_FORRESTEN, {{ 473 }} }, // Hearthsinger Forresten
55 { BOSS_TIMMY_THE_CRUEL, {{ 474 }} }, // Timmy the Cruel
56 { BOSS_COMMANDER_MALOR, {{ 476 }} }, // Commander Malor
57 { BOSS_WILLEY_HOPEBREAKER, {{ 475 }} }, // Willey Hopebreaker
58 { BOSS_INSTRUCTOR_GALFORD, {{ 477 }} }, // Instructor Galford
59 { BOSS_BALNAZZAR, {{ 478 }} }, // Balnazzar
60 { BOSS_THE_UNFORGIVEN, {{ 472 }} }, // The Unforgiven
61 { BOSS_BARONESS_ANASTARI, {{ 479 }} }, // Baroness Anastari
62 { BOSS_NERUB_ENKAN, {{ 480 }} }, // Nerub'enkan
63 { BOSS_MALEKI_THE_PALLID, {{ 481 }} }, // Maleki the Pallid
64 { BOSS_MAGISTRATE_BARTHILAS, {{ 482 }} }, // Magistrate Barthilas
65 { BOSS_RAMSTEIN_THE_GORGER, {{ 483 }} }, // Ramstein the Gorger
66 { BOSS_RIVENDARE, {{ 484 }} }, // Lord Aurius Rivendare
67 { BOSS_POSTMASTER_MALOWN, {{ 1885 }} } // Postmaster Malown
68};
69
71{
72 public:
74
76 {
78 {
82
83 for (uint8 i = 0; i < 5; ++i)
84 IsSilverHandDead[i] = false;
85
86 timmySpawned = false;
90 }
91
95
98
110
117
118 void OnUnitDeath(Unit* who) override
119 {
120 switch (who->GetEntry())
121 {
126 {
127 if (!timmySpawned)
128 {
129 Position pos = who->ToCreature()->GetHomePosition();
130 // check if they're in front of the entrance
132 {
134 {
136 timmySpawned = true;
137 }
138 }
139 }
140 break;
141 }
144 break;
147 break;
150 break;
153 break;
154 default:
155 break;
156 }
157 }
158
160 {
161 if (brokenCrystals >= 3)
162 {
165 return true;
166 }
167
168 TC_LOG_DEBUG("scripts", "Instance Stratholme: Cannot open slaugther square yet.");
169 return false;
170 }
171
172 //if withRestoreTime true, then newState will be ignored and GO should be restored to original state after 10 seconds
173 void UpdateGoState(ObjectGuid goGuid, uint32 newState, bool withRestoreTime)
174 {
175 if (!goGuid)
176 return;
177
178 if (GameObject* go = instance->GetGameObject(goGuid))
179 {
180 if (withRestoreTime)
181 go->UseDoorOrButton(10);
182 else
183 go->SetGoState((GOState)newState);
184 }
185 }
186
187 void OnCreatureCreate(Creature* creature) override
188 {
189 switch (creature->GetEntry())
190 {
191 case NPC_BARON:
192 baronGUID = creature->GetGUID();
193 break;
195 ysidaTriggerGUID = creature->GetGUID();
196 break;
197 case NPC_CRYSTAL:
198 crystalsGUID.insert(creature->GetGUID());
199 break;
200 case NPC_ABOM_BILE:
201 case NPC_ABOM_VENOM:
202 abomnationGUID.insert(creature->GetGUID());
203 break;
204 case NPC_YSIDA:
205 ysidaGUID = creature->GetGUID();
207 break;
208 }
209 }
210
211 void OnCreatureRemove(Creature* creature) override
212 {
213 switch (creature->GetEntry())
214 {
215 case NPC_CRYSTAL:
216 crystalsGUID.erase(creature->GetGUID());
217 break;
218 case NPC_ABOM_BILE:
219 case NPC_ABOM_VENOM:
220 abomnationGUID.erase(creature->GetGUID());
221 break;
222 }
223 }
224
226 {
227 switch (go->GetEntry())
228 {
231 break;
233 //weird, but unless flag is set, client will not respond as expected. DB bug?
236 break;
237 case GO_ZIGGURAT1:
238 ziggurat1GUID = go->GetGUID();
241 break;
242 case GO_ZIGGURAT2:
243 ziggurat2GUID = go->GetGUID();
246 break;
247 case GO_ZIGGURAT3:
248 ziggurat3GUID = go->GetGUID();
251 break;
252 case GO_ZIGGURAT4:
253 ziggurat4GUID = go->GetGUID();
256 break;
257 case GO_ZIGGURAT5:
258 ziggurat5GUID = go->GetGUID();
261 break;
262 case GO_PORT_GAUNTLET:
264 if (brokenCrystals >= 3)
266 break;
269 if (brokenCrystals >= 3)
271 break;
272 case GO_PORT_ELDERS:
273 portElderGUID = go->GetGUID();
274 break;
275 case GO_YSIDA_CAGE:
276 ysidaCageGUID = go->GetGUID();
277 break;
278 }
279 }
280
281 bool SetBossState(uint32 id, EncounterState state) override
282 {
283 if (!InstanceScript::SetBossState(id, state))
284 return false;
285
286 switch (id)
287 {
289 if (state == DONE)
290 {
292
293 //remove when crystals implemented
296 }
297 break;
298 case BOSS_NERUB_ENKAN:
299 if (state == DONE)
300 {
302
303 //remove when crystals implemented
306 }
307 break;
309 if (state == DONE)
310 {
312
313 //remove when crystals implemented
316 }
317 break;
319 if (state == IN_PROGRESS)
320 {
322
323 uint32 count = abomnationGUID.size();
324 for (GuidSet::const_iterator i = abomnationGUID.begin(); i != abomnationGUID.end(); ++i)
325 {
326 if (Creature* pAbom = instance->GetCreature(*i))
327 if (!pAbom->IsAlive())
328 --count;
329 }
330
331 if (!count)
332 {
333 //a bit itchy, it should close the door after 10 secs, but it doesn't. skipping it for now.
334 //UpdateGoState(ziggurat4GUID, 0, true);
335 if (Creature* pBaron = instance->GetCreature(baronGUID))
336 pBaron->SummonCreature(NPC_RAMSTEIN, 4032.84f, -3390.24f, 119.73f, 4.71f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30min);
337 TC_LOG_DEBUG("scripts", "Instance Stratholme: Ramstein spawned.");
338 }
339 else
340 TC_LOG_DEBUG("scripts", "Instance Stratholme: {} Abomnation left to kill.", count);
341 }
342
343 if (state == NOT_STARTED)
345
346 if (state == DONE)
347 {
349 TC_LOG_DEBUG("scripts", "Instance Stratholme: Slaugther event will continue in 1 minute.");
350 }
351 break;
352 case BOSS_RIVENDARE:
355 if (state == DONE)
356 {
360
362 }
363 break;
364 default:
365 break;
366 }
367
368 return true;
369 }
370
371 void SetData(uint32 type, uint32 data) override
372 {
373 switch (type)
374 {
375 case TYPE_BARON_RUN:
376 switch (data)
377 {
378 case IN_PROGRESS:
380 break;
383 TC_LOG_DEBUG("scripts", "Instance Stratholme: Baron run in progress.");
384 break;
385 case FAIL:
387 if (Creature* ysida = instance->GetCreature(ysidaGUID))
388 ysida->CastSpell(ysida, SPELL_PERM_FEIGN_DEATH, true);
390 break;
391 case DONE:
393
394 if (Creature* ysida = instance->GetCreature(ysidaGUID))
395 {
397 cage->UseDoorOrButton();
398
399 float x, y, z;
401 ysida->CastSpell(nullptr, SPELL_YSIDA_SAVED, true);
402 ysida->SetWalk(true);
403 ysida->AI()->Talk(SAY_YSIDA_SAVED);
404 ysida->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
405 ysida->GetClosePoint(x, y, z, ysida->GetObjectScale() / 3, 4.0f);
406 ysida->GetMotionMaster()->MovePoint(1, x, y, z);
407
408 Map::PlayerList const& players = instance->GetPlayers();
409
410 for (auto const& i : players)
411 {
412 if (Player* player = i.GetSource())
413 {
414 if (player->IsGameMaster())
415 continue;
416
419 player->CastSpell(ysida, SPELL_YSIDA_CREDIT_EFFECT, true);
420 }
421 }
422 }
424 break;
425 }
426 break;
427 case TYPE_SH_AELMAR:
428 IsSilverHandDead[0] = (data) ? true : false;
429 break;
430 case TYPE_SH_CATHELA:
431 IsSilverHandDead[1] = (data) ? true : false;
432 break;
433 case TYPE_SH_GREGOR:
434 IsSilverHandDead[2] = (data) ? true : false;
435 break;
436 case TYPE_SH_NEMAS:
437 IsSilverHandDead[3] = (data) ? true : false;
438 break;
439 case TYPE_SH_VICAR:
440 IsSilverHandDead[4] = (data) ? true : false;
441 break;
442 default:
443 break;
444 }
445 }
446
447 uint32 GetData(uint32 type) const override
448 {
449 switch (type)
450 {
451 case TYPE_SH_QUEST:
453 return 1;
454 return 0;
455 case TYPE_BARON_RUN:
456 return baronRunState;
457 case TYPE_BARONESS:
459 case TYPE_NERUB:
461 case TYPE_PALLID:
463 case TYPE_RAMSTEIN:
465 case TYPE_BARON:
467 default:
468 break;
469 }
470 return 0;
471 }
472
473 ObjectGuid GetGuidData(uint32 data) const override
474 {
475 switch (data)
476 {
477 case DATA_BARON:
478 return baronGUID;
480 return ysidaTriggerGUID;
481 case NPC_YSIDA:
482 return ysidaGUID;
483 default:
484 break;
485 }
486 return ObjectGuid::Empty;
487 }
488
489 void Update(uint32 diff) override
490 {
491 events.Update(diff);
492
493 while (uint32 eventId = events.ExecuteEvent())
494 {
495 switch (eventId)
496 {
497 case EVENT_BARON_RUN:
500 TC_LOG_DEBUG("scripts", "Instance Stratholme: Baron run event reached end. Event has state {}.", GetData(TYPE_BARON_RUN));
501 break;
503 if (Creature* baron = instance->GetCreature(baronGUID))
504 {
505 for (uint8 i = 0; i < 4; ++i)
506 baron->SummonCreature(NPC_BLACK_GUARD, 4032.84f, -3390.24f, 119.73f, 4.71f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30min);
507
510 TC_LOG_DEBUG("scripts", "Instance Stratholme: Black guard sentries spawned. Opening gates to baron.");
511 }
512 break;
513 default:
514 break;
515 }
516 }
517 }
518
519 void AfterDataLoad() override
520 {
527
529 }
530 };
531
533 {
535 }
536};
537
539{
541}
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
EncounterState
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
Definition: ObjectDefines.h:63
std::set< ObjectGuid > GuidSet
Definition: ObjectGuid.h:393
@ GO_FLAG_LOCKED
GOState
@ UNIT_NPC_FLAG_QUESTGIVER
Definition: UnitDefines.h:298
#define DataHeader
bool IsWithinBoundary(Position const *pos) const
Definition: AreaBoundary.h:26
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition: Creature.h:373
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void CancelEvent(uint32 eventId)
Definition: EventMap.cpp:131
void SetFlag(GameObjectFlags flags)
Definition: GameObject.h:274
void SetBossNumber(uint32 number)
virtual bool SetBossState(uint32 id, EncounterState state)
void DoRemoveAurasDueToSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
void HandleGameObject(ObjectGuid guid, bool open, GameObject *go=nullptr)
void LoadDungeonEncounterData(T const &encounters)
InstanceMap * instance
EncounterState GetBossState(uint32 id) const
void SetHeaders(std::string const &dataHeaders)
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, Milliseconds duration=0ms, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty, SmoothPhasingInfo const *smoothPhasingInfo=nullptr)
Definition: Object.cpp:1836
GameObject * GetGameObject(ObjectGuid const &guid)
Definition: Map.cpp:3489
PlayerList const & GetPlayers() const
Definition: Map.h:367
Creature * GetCreature(ObjectGuid const &guid)
Definition: Map.cpp:3479
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
static Creature * ToCreature(Object *o)
Definition: Object.h:219
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
Definition: Unit.h:627
void RemoveNpcFlag(NPCFlags flags)
Definition: Unit.h:983
InstanceScript * GetInstanceScript(InstanceMap *map) const override
#define MAX_ENCOUNTER
EllipseBoundary const beforeScarletGate(Position(3671.158f, -3181.79f), 60.0f, 40.0f)
static constexpr DungeonEncounterData Encounters[]
@ SAY_YSIDA_SAVED
Position const timmyTheCruelSpawnPosition
void AddSC_instance_stratholme()
@ EVENT_SLAUGHTER_SQUARE
@ EVENT_BARON_RUN
@ BOSS_MALEKI_THE_PALLID
Definition: stratholme.h:37
@ BOSS_TIMMY_THE_CRUEL
Definition: stratholme.h:29
@ BOSS_HEARTHSINGER_FORRESTEN
Definition: stratholme.h:28
@ BOSS_BALNAZZAR
Definition: stratholme.h:33
@ BOSS_NERUB_ENKAN
Definition: stratholme.h:36
@ BOSS_RIVENDARE
Definition: stratholme.h:40
@ BOSS_INSTRUCTOR_GALFORD
Definition: stratholme.h:32
@ BOSS_MAGISTRATE_BARTHILAS
Definition: stratholme.h:38
@ BOSS_BARONESS_ANASTARI
Definition: stratholme.h:35
@ BOSS_RAMSTEIN_THE_GORGER
Definition: stratholme.h:39
@ BOSS_POSTMASTER_MALOWN
Definition: stratholme.h:41
@ BOSS_COMMANDER_MALOR
Definition: stratholme.h:30
@ BOSS_THE_UNFORGIVEN
Definition: stratholme.h:34
@ BOSS_WILLEY_HOPEBREAKER
Definition: stratholme.h:31
@ NPC_THE_UNFORGIVEN
Definition: stratholme.h:71
@ NPC_CRIMSON_CONJUROR
Definition: stratholme.h:85
@ NPC_CRIMSON_GALLANT
Definition: stratholme.h:87
@ NPC_HEARTHSINGER_FORRESTEN
Definition: stratholme.h:68
@ NPC_YSIDA
Definition: stratholme.h:81
@ NPC_BLACK_GUARD
Definition: stratholme.h:80
@ NPC_RAMSTEIN
Definition: stratholme.h:77
@ NPC_TIMMY_THE_CRUEL
Definition: stratholme.h:89
@ NPC_BARON
Definition: stratholme.h:74
@ NPC_CRYSTAL
Definition: stratholme.h:73
@ NPC_ABOM_BILE
Definition: stratholme.h:78
@ NPC_CRIMSON_GUARDSMAN
Definition: stratholme.h:84
@ NPC_ABOM_VENOM
Definition: stratholme.h:79
@ NPC_YSIDA_TRIGGER
Definition: stratholme.h:75
@ NPC_INSTRUCTOR_GALFORD
Definition: stratholme.h:70
@ NPC_COMMANDER_MALOR
Definition: stratholme.h:69
@ NPC_CRIMSON_INITATE
Definition: stratholme.h:86
@ SPELL_PERM_FEIGN_DEATH
Definition: stratholme.h:116
@ SPELL_YSIDA_SAVED
Definition: stratholme.h:117
@ SPELL_YSIDA_CREDIT_EFFECT
Definition: stratholme.h:118
@ SPELL_BARON_ULTIMATUM
Definition: stratholme.h:115
@ GO_GAUNTLET_GATE1
Definition: stratholme.h:96
@ GO_ZIGGURAT1
Definition: stratholme.h:97
@ GO_ZIGGURAT3
Definition: stratholme.h:99
@ GO_ZIGGURAT4
Definition: stratholme.h:100
@ GO_ZIGGURAT2
Definition: stratholme.h:98
@ GO_ZIGGURAT5
Definition: stratholme.h:101
@ GO_PORT_ELDERS
Definition: stratholme.h:104
@ GO_SERVICE_ENTRANCE
Definition: stratholme.h:95
@ GO_PORT_GAUNTLET
Definition: stratholme.h:102
@ GO_PORT_SLAUGTHER
Definition: stratholme.h:103
@ GO_YSIDA_CAGE
Definition: stratholme.h:105
#define StratholmeScriptName
Definition: stratholme.h:23
@ TYPE_SH_CATHELA
Definition: stratholme.h:59
@ DATA_BARON
Definition: stratholme.h:55
@ TYPE_PALLID
Definition: stratholme.h:51
@ TYPE_SH_AELMAR
Definition: stratholme.h:63
@ DATA_YSIDA_TRIGGER
Definition: stratholme.h:56
@ TYPE_BARONESS
Definition: stratholme.h:49
@ TYPE_SH_GREGOR
Definition: stratholme.h:60
@ TYPE_SH_NEMAS
Definition: stratholme.h:61
@ TYPE_NERUB
Definition: stratholme.h:50
@ TYPE_BARON
Definition: stratholme.h:53
@ TYPE_SH_VICAR
Definition: stratholme.h:62
@ TYPE_RAMSTEIN
Definition: stratholme.h:52
@ TYPE_BARON_RUN
Definition: stratholme.h:48
@ TYPE_SH_QUEST
Definition: stratholme.h:58
@ TIMMY_THE_CRUEL_CRUSADERS_REQUIRED
amount of crusade monsters required to be killed in order for timmy the cruel to spawn
Definition: stratholme.h:124
void UpdateGoState(ObjectGuid goGuid, uint32 newState, bool withRestoreTime)
bool SetBossState(uint32 id, EncounterState state) override