TrinityCore
Loading...
Searching...
No Matches
instance_the_black_morass.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/*
19Name: Instance_The_Black_Morass
20%Complete: 50
21Comment: Quest support: 9836, 10297. Currently in progress.
22Category: Caverns of Time, The Black Morass
23*/
24
25#include "ScriptMgr.h"
26#include "EventMap.h"
27#include "InstanceScript.h"
28#include "Log.h"
29#include "Map.h"
30#include "Player.h"
31#include "SpellInfo.h"
32#include "TemporarySummon.h"
33#include "the_black_morass.h"
34
35enum Misc
36{
38 RIFT_BOSS = 1
39};
40
41inline uint32 RandRiftBoss() { return ((rand32() % 2) ? NPC_RIFT_KEEPER : NPC_RIFT_LORD); }
42
43float PortalLocation[4][4]=
44{
45 {-2041.06f, 7042.08f, 29.99f, 1.30f},
46 {-1968.18f, 7042.11f, 21.93f, 2.12f},
47 {-1885.82f, 7107.36f, 22.32f, 3.07f},
48 {-1928.11f, 7175.95f, 22.11f, 3.44f}
49};
50
51struct Wave
52{
53 uint32 PortalBoss; //protector of current portal
54 Milliseconds NextPortalTime; //time to next portal, or 0 if portal boss need to be killed
55};
56
57static Wave RiftWaves[]=
58{
59 { RIFT_BOSS, 0s },
60 { NPC_CRONO_LORD_DEJA, 0s },
61 { RIFT_BOSS, 120s },
62 { NPC_TEMPORUS, 140s },
63 { RIFT_BOSS, 120s },
64 { NPC_AEONUS, 0s }
65};
66
71
73{
74public:
76
81
83 {
89
91
96
99
100 void Clear()
101 {
102 memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
103
105 mShieldPercent = 100;
106 mRiftWaveCount = 0;
107 mRiftWaveId = 0;
108
109 _currentRiftId = 0;
110 }
111
112 void InitWorldState(bool Enable = true)
113 {
114 DoUpdateWorldState(WORLD_STATE_BM, Enable ? 1 : 0);
117 }
118
119 bool IsEncounterInProgress() const override
120 {
122 return true;
123
124 return false;
125 }
126
127 void OnPlayerEnter(Player* player) override
128 {
130 return;
131
133 }
134
135 void OnCreatureCreate(Creature* creature) override
136 {
137 if (creature->GetEntry() == NPC_MEDIVH)
138 _medivhGUID = creature->GetGUID();
139 }
140
141 //what other conditions to check?
143 {
144 if (instance->GetPlayers().isEmpty())
145 return false;
146
147 return true;
148 }
149
151 {
152 switch (mRiftPortalCount)
153 {
154 case 6:
155 mRiftWaveId = 2;
156 return 1;
157 case 12:
158 mRiftWaveId = 4;
159 return 3;
160 case 18:
161 return 5;
162 default:
163 return mRiftWaveId;
164 }
165 }
166
167 void SetData(uint32 type, uint32 data) override
168 {
169 switch (type)
170 {
171 case TYPE_MEDIVH:
172 if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS)
173 {
175
177
178 if (!mShieldPercent)
179 {
181 {
182 if (medivh->IsAlive())
183 {
184 medivh->KillSelf();
185 m_auiEncounter[0] = FAIL;
187 }
188 }
189 }
190 }
191 else
192 {
193 if (data == IN_PROGRESS)
194 {
195 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Starting event.");
199 }
200
201 if (data == DONE)
202 {
203 //this may be completed further out in the post-event
204 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Event completed.");
205 Map::PlayerList const& players = instance->GetPlayers();
206
207 if (!players.isEmpty())
208 {
209 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
210 {
211 if (Player* player = itr->GetSource())
212 {
213 if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE)
214 player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL);
215
216 if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE)
217 player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH);
218 }
219 }
220 }
221 }
222
223 m_auiEncounter[0] = data;
224 }
225 break;
226 case TYPE_RIFT:
227 if (data == SPECIAL)
228 {
229 if (mRiftPortalCount < 7)
231 }
232 else
233 m_auiEncounter[1] = data;
234 break;
235 }
236 }
237
238 uint32 GetData(uint32 type) const override
239 {
240 switch (type)
241 {
242 case TYPE_MEDIVH:
243 return m_auiEncounter[0];
244 case TYPE_RIFT:
245 return m_auiEncounter[1];
247 return mRiftPortalCount;
248 case DATA_SHIELD:
249 return mShieldPercent;
250 }
251 return 0;
252 }
253
254 ObjectGuid GetGuidData(uint32 data) const override
255 {
256 if (data == DATA_MEDIVH)
257 return _medivhGUID;
258
259 return ObjectGuid::Empty;
260 }
261
263 {
265
266 if (entry == RIFT_BOSS)
267 entry = RandRiftBoss();
268
269 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Summoning rift boss entry {}.", entry);
270
271 Position pos = me->GetRandomNearPosition(10.0f);
272
273 //normalize Z-level if we can, if rift is not at ground level.
274 pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY));
275
276 if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min))
277 return summon;
278
279 TC_LOG_DEBUG("scripts", "Instance The Black Morass: What just happened there? No boss, no loot, no fun...");
280 return nullptr;
281 }
282
284 {
286 {
287 uint8 tmp = urand(0, 2);
288
289 if (tmp >= _currentRiftId)
290 ++tmp;
291
292 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Creating Time Rift at locationId {} (old locationId was {}).", tmp, _currentRiftId);
293
294 _currentRiftId = tmp;
295
296 Creature* temp = medivh->SummonCreature(NPC_TIME_RIFT,
297 PortalLocation[tmp][0], PortalLocation[tmp][1], PortalLocation[tmp][2], PortalLocation[tmp][3],
299 if (temp)
300 {
301 if (Creature* boss = SummonedPortalBoss(temp))
302 {
303 if (boss->GetEntry() == NPC_AEONUS)
304 boss->GetThreatManager().AddThreat(medivh, 0.0f);
305 else
306 {
307 boss->GetThreatManager().AddThreat(temp, 0.0f);
308 temp->CastSpell(boss, SPELL_RIFT_CHANNEL, false);
309 }
310 }
311 }
312 }
313 }
314
315 void Update(uint32 diff) override
316 {
317 if (m_auiEncounter[1] != IN_PROGRESS)
318 return;
319
320 //add delay timer?
321 if (!CanProgressEvent())
322 {
323 Clear();
324 return;
325 }
326
327 Events.Update(diff);
328
329 if (Events.ExecuteEvent() == EVENT_NEXT_PORTAL)
330 {
335 }
336 }
337
339 {
340 if (nextPortalTime > 0s)
341 Events.RescheduleEvent(EVENT_NEXT_PORTAL, nextPortalTime);
342 }
343
344 protected:
346 };
347
348};
349
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
@ IN_PROGRESS
@ FAIL
@ DONE
@ SPECIAL
@ NOT_STARTED
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define MAX_HEIGHT
Definition Map.h:240
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
@ TEMPSUMMON_CORPSE_DESPAWN
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:107
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
uint32 rand32()
Definition Random.cpp:70
#define DataHeader
uint32 const EncounterCount
InstanceMap * instance
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue)
void SetHeaders(std::string const &dataHeaders)
bool isEmpty() const
Definition LinkedList.h:108
iterator end()
iterator begin()
float GetWaterLevel(float x, float y) const
Definition Map.cpp:2862
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:2484
PlayerList const & GetPlayers() const
Definition Map.h:448
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:4397
static ObjectGuid const Empty
Definition ObjectGuid.h:140
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SendUpdateWorldState(uint32 variable, uint32 value) const
Definition Player.cpp:8493
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
ThreatManager & GetThreatManager()
Definition Unit.h:1155
Map * GetMap() const
Definition Object.h:449
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
Position GetRandomNearPosition(float radius)
Definition Object.cpp:3264
InstanceScript * GetInstanceScript(InstanceMap *map) const override
float PortalLocation[4][4]
void AddSC_instance_the_black_morass()
uint32 RandRiftBoss()
static Wave RiftWaves[]
float m_positionZ
Definition Position.h:58
float m_positionX
Definition Position.h:56
float m_positionY
Definition Position.h:57
Definition hyjalAI.h:47
Milliseconds NextPortalTime
@ WORLD_STATE_BM_SHIELD
@ WORLD_STATE_BM_RIFT
@ WORLD_STATE_BM
@ NPC_AEONUS
@ NPC_RIFT_KEEPER
@ NPC_MEDIVH
@ NPC_RIFT_LORD
@ NPC_TEMPORUS
@ NPC_CRONO_LORD_DEJA
@ DATA_MEDIVH
@ DATA_PORTAL_COUNT
@ TYPE_MEDIVH
@ TYPE_RIFT
@ DATA_SHIELD
#define TBMScriptName
@ QUEST_MASTER_TOUCH
@ QUEST_OPENING_PORTAL