TrinityCore
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 "the_black_morass.h"
32#include "TemporarySummon.h"
33
34enum Misc
35{
37 RIFT_BOSS = 1
38};
39
40inline uint32 RandRiftBoss() { return ((rand32() % 2) ? NPC_RIFT_KEEPER : NPC_RIFT_LORD); }
41
42float PortalLocation[4][4]=
43{
44 {-2041.06f, 7042.08f, 29.99f, 1.30f},
45 {-1968.18f, 7042.11f, 21.93f, 2.12f},
46 {-1885.82f, 7107.36f, 22.32f, 3.07f},
47 {-1928.11f, 7175.95f, 22.11f, 3.44f}
48};
49
50struct Wave
51{
52 uint32 PortalBoss; //protector of current portal
53 Milliseconds NextPortalTime; //time to next portal, or 0 if portal boss need to be killed
54};
55
56static Wave RiftWaves[]=
57{
58 { RIFT_BOSS, 0s },
59 { NPC_CRONO_LORD_DEJA, 0s },
60 { RIFT_BOSS, 120s },
61 { NPC_TEMPORUS, 140s },
62 { RIFT_BOSS, 120s },
63 { NPC_AEONUS, 0s }
64};
65
67{
69};
70
72{
73public:
75
77 {
79 }
80
82 {
84 {
86 Clear();
87 }
88
90
95
98
99 void Clear()
100 {
101 memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
102
104 mShieldPercent = 100;
105 mRiftWaveCount = 0;
106 mRiftWaveId = 0;
107
108 _currentRiftId = 0;
109 }
110
111 bool IsEncounterInProgress() const override
112 {
114 return true;
115
116 return false;
117 }
118
119 void OnCreatureCreate(Creature* creature) override
120 {
121 if (creature->GetEntry() == NPC_MEDIVH)
122 _medivhGUID = creature->GetGUID();
123 }
124
125 //what other conditions to check?
127 {
128 if (instance->GetPlayers().isEmpty())
129 return false;
130
131 return true;
132 }
133
135 {
136 switch (mRiftPortalCount)
137 {
138 case 6:
139 mRiftWaveId = 2;
140 return 1;
141 case 12:
142 mRiftWaveId = 4;
143 return 3;
144 case 18:
145 return 5;
146 default:
147 return mRiftWaveId;
148 }
149 }
150
151 void SetData(uint32 type, uint32 data) override
152 {
153 switch (type)
154 {
155 case TYPE_MEDIVH:
156 if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS)
157 {
159
161
162 if (!mShieldPercent)
163 {
165 {
166 if (medivh->IsAlive())
167 {
168 medivh->KillSelf();
169 m_auiEncounter[0] = FAIL;
171 }
172 }
173 }
174 }
175 else
176 {
177 if (data == IN_PROGRESS)
178 {
179 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Starting event.");
183 }
184
185 if (data == DONE)
186 {
187 //this may be completed further out in the post-event
188 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Event completed.");
189 Map::PlayerList const& players = instance->GetPlayers();
190
191 if (!players.isEmpty())
192 {
193 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
194 {
195 if (Player* player = itr->GetSource())
196 {
197 if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE)
198 player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL);
199
200 if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE)
201 player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH);
202 }
203 }
204 }
205 }
206
207 m_auiEncounter[0] = data;
208 }
209 break;
210 case TYPE_RIFT:
211 if (data == SPECIAL)
212 {
213 if (mRiftPortalCount < 7)
215 }
216 else
217 m_auiEncounter[1] = data;
218 break;
219 }
220 }
221
222 uint32 GetData(uint32 type) const override
223 {
224 switch (type)
225 {
226 case TYPE_MEDIVH:
227 return m_auiEncounter[0];
228 case TYPE_RIFT:
229 return m_auiEncounter[1];
231 return mRiftPortalCount;
232 case DATA_SHIELD:
233 return mShieldPercent;
234 }
235 return 0;
236 }
237
238 ObjectGuid GetGuidData(uint32 data) const override
239 {
240 if (data == DATA_MEDIVH)
241 return _medivhGUID;
242
243 return ObjectGuid::Empty;
244 }
245
247 {
249
250 if (entry == RIFT_BOSS)
251 entry = RandRiftBoss();
252
253 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Summoning rift boss entry {}.", entry);
254
255 Position pos = me->GetRandomNearPosition(10.0f);
256
257 //normalize Z-level if we can, if rift is not at ground level.
259
260 if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min))
261 return summon;
262
263 TC_LOG_DEBUG("scripts", "Instance The Black Morass: What just happened there? No boss, no loot, no fun...");
264 return nullptr;
265 }
266
268 {
270 {
271 uint8 tmp = urand(0, 2);
272
273 if (tmp >= _currentRiftId)
274 ++tmp;
275
276 TC_LOG_DEBUG("scripts", "Instance The Black Morass: Creating Time Rift at locationId {} (old locationId was {}).", tmp, _currentRiftId);
277
278 _currentRiftId = tmp;
279
280 Creature* temp = medivh->SummonCreature(NPC_TIME_RIFT,
281 PortalLocation[tmp][0], PortalLocation[tmp][1], PortalLocation[tmp][2], PortalLocation[tmp][3],
283 if (temp)
284 {
285 if (Creature* boss = SummonedPortalBoss(temp))
286 {
287 if (boss->GetEntry() == NPC_AEONUS)
288 boss->GetThreatManager().AddThreat(medivh, 0.0f);
289 else
290 {
291 boss->GetThreatManager().AddThreat(temp, 0.0f);
292 temp->CastSpell(boss, SPELL_RIFT_CHANNEL, false);
293 }
294 }
295 }
296 }
297 }
298
299 void Update(uint32 diff) override
300 {
301 if (m_auiEncounter[1] != IN_PROGRESS)
302 return;
303
304 //add delay timer?
305 if (!CanProgressEvent())
306 {
307 Clear();
308 return;
309 }
310
311 Events.Update(diff);
312
313 if (Events.ExecuteEvent() == EVENT_NEXT_PORTAL)
314 {
319 }
320 }
321
323 {
324 if (nextPortalTime > 0s)
325 Events.RescheduleEvent(EVENT_NEXT_PORTAL, nextPortalTime);
326 }
327
328 protected:
330 };
331
332};
333
335{
337}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
#define MAX_HEIGHT
Definition: GridDefines.h:60
@ IN_PROGRESS
@ FAIL
@ DONE
@ SPECIAL
@ NOT_STARTED
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
Definition: ObjectDefines.h:63
@ TEMPSUMMON_CORPSE_DESPAWN
Definition: ObjectDefines.h:67
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:145
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 rand32()
Definition: Random.cpp:70
#define DataHeader
uint32 const EncounterCount
void DoUpdateWorldState(int32 worldStateId, int32 value)
InstanceMap * instance
void SetHeaders(std::string const &dataHeaders)
bool isEmpty() const
Definition: LinkedList.h:110
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
float GetHeight(PhaseShift const &phaseShift, float x, float y, float z, bool vmap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH)
Definition: Map.h:290
float GetWaterLevel(PhaseShift const &phaseShift, float x, float y)
Definition: Map.cpp:1762
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
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
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:1063
Map * GetMap() const
Definition: Object.h:624
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
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:2025
PhaseShift & GetPhaseShift()
Definition: Object.h:523
Position GetRandomNearPosition(float radius)
Definition: Object.cpp:3423
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:55
float m_positionX
Definition: Position.h:53
float m_positionY
Definition: Position.h:54
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