1 | | /* Copyright ? 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> |
2 | | * This program is free software; you can redistribute it and/or modify |
3 | | * it under the terms of the GNU General Public License as published by |
4 | | * the Free Software Foundation; either version 2 of the License, or |
5 | | * (at your option) any later version. |
6 | | * |
7 | | * This program is distributed in the hope that it will be useful, |
8 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | | * GNU General Public License for more details. |
11 | | * |
12 | | * You should have received a copy of the GNU General Public License |
13 | | * along with this program; if not, write to the Free Software |
14 | | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
15 | | */ |
| 1 | /* Copyright ?2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> |
| 2 | * This program is free software; you can redistribute it and/or modify |
| 3 | * it under the terms of the GNU General Public License as published by |
| 4 | * the Free Software Foundation; either version 2 of the License, or |
| 5 | * (at your option) any later version. |
| 6 | * |
| 7 | * This program is distributed in the hope that it will be useful, |
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 | * GNU General Public License for more details. |
| 11 | * |
| 12 | * You should have received a copy of the GNU General Public License |
| 13 | * along with this program; if not, write to the Free Software |
| 14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 15 | */ |
28 | | #define SAY_KALECGOS_AGGRO "Aggh! No longer will I be a slave to Malygos! Challenge me and you will be destroyed!" |
29 | | #define SOUND_KALECGOS_AGGRO 12422 |
30 | | #define SAY_KALECGOS_SPELL1 "I will purge you!" |
31 | | #define SOUND_KALECGOS_SPELL1 12423 |
32 | | #define SAY_KALECGOS_SPELL2 "Your pain has only begun!" |
33 | | #define SOUND_KALECGOS_SPELL2 12424 |
34 | | #define SAY_KALECGOS_SLAY1 "In the name of Kil'jaeden!" |
35 | | #define SOUND_KALECGOS_SLAY1 12425 |
36 | | #define SAY_KALECGOS_SLAY2 "You were warned!" |
37 | | #define SOUND_KALECGOS_SLAY2 12426 |
38 | | #define SAY_KALECGOS_ENRAGE "My awakening is complete! You shall all perish!" |
39 | | #define SOUND_KALECGOS_ENRAGE 12427 |
40 | | |
41 | | #define SAY_SATH_AGGRO "There will be no reprieve. My work here is nearly finished." |
42 | | #define SOUND_SATH_AGGRO 12451 |
43 | | #define SAY_SATH_DEATH "I'm... never on... the losing... side..." |
44 | | #define SOUND_SATH_DEATH 12452 |
45 | | #define SAY_SATH_SPELL1 "Your misery is my delight!" |
46 | | #define SOUND_SATH_SPELL1 12453 |
47 | | #define SAY_SATH_SPELL2 "I will watch you bleed!" |
48 | | #define SOUND_SATH_SPELL2 12454 |
49 | | #define SAY_SATH_SLAY1 "Pitious mortal!" |
50 | | #define SOUND_SATH_SLAY1 12455 |
51 | | #define SAY_SATH_SLAY2 "Haven't you heard? I always win!" |
52 | | #define SOUND_SATH_SLAY2 12456 |
53 | | #define SAY_SATH_ENRAGE "I have toyed with you long enough!" |
54 | | #define SOUND_SATH_ENRAGE 12457 |
55 | | |
56 | | #define SAY_KALEC_AGGRO "I need... your help... Cannot... resist him... much longer..." |
57 | | #define SOUND_KALEC_AGGRO 12428 |
58 | | #define SAY_KALEC_NEAR_DEATH "Aaahhh! Help me, before I lose my mind!" |
59 | | #define SOUND_KALEC_NEAR_DEATH 12429 |
60 | | //??? |
61 | | #define SAY_KALEC_NEAR_DEATH2 "Hurry! There is not much of me left!" |
62 | | #define SOUND_KALEC_NEAR_DEATH2 12430 |
63 | | #define SAY_KALEC_PLRWIN "I am forever in your debt. Once we have triumphed over Kil'jaeden, this entire world will be in your debt as well." |
64 | | #define SOUND_KALEC_PLRWIN 12431 |
65 | | |
66 | | #define SPELL_SPECTRAL_EXHAUSTION 44867 |
67 | | #define SPELL_TELEPORT_SPECTRAL_REALM 46019 |
68 | | #define SPELL_SPECTRAL_REALM 46021 |
69 | | |
70 | | #define NOTIFY_SPECTRALLY_EXHAUSTED "Your body is too exhausted to travel to the Spectral Realm." |
71 | | #define ERROR_INST_DATA "SD2: Instance Data not set properly for Sunwell Plateau. Kalecgos Encounter will be buggy." |
72 | | #define ERROR_INST_DATA_PLR "SD2 ERROR: Instance Data not set properly for Sunwell Plateau. Please report this to your administrator." |
73 | | #define ERROR_UNABLE_TO_TELEPORT "SD2: Unable to select target for Spectral Blast. Threatlist has too few players." |
74 | | #define ERROR_MISSING_TELEPORT_GUID "SD2: [Kalecgos] Invalid TeleportTargetGUID. Unable to teleport player." |
75 | | #define ERROR_KALECGOS_NOT_FOUND "SD2: Unable to create pointer to Kalecgos from Sathrovarr." |
76 | | |
77 | | #define KALECGOS_ARENA_X 1704.34 |
78 | | #define KALECGOS_ARENA_Y 928.17 |
79 | | #define KALECGOS_ARENA_Z 53.08 |
80 | | |
81 | | /*** Kalecgos ****/ |
82 | | #define SPELL_SPECTRAL_BLAST 44866 |
| 26 | #define KALECGOS_SAY_AGGRO "No longer will I be a slave to Malygos! Challenge me and you will be destroyed!" |
| 27 | #define KALECGOS_SOUND_AGGRO 12422 |
| 28 | #define KALECGOS_SAY_SPELL_1 "I will purge you!" |
| 29 | #define KALECGOS_SOUND_SPELL_1 12423 |
| 30 | #define KALECGOS_SAY_SPELL_2 "Your pain has only begun!" |
| 31 | #define KALECGOS_SOUND_SPELL_2 12424 |
| 32 | #define KALECGOS_SAY_KILL_1 "In the name of Kil'jaeden!" |
| 33 | #define KALECGOS_SOUND_KILL_1 12425 |
| 34 | #define KALECGOS_SAY_KILL_2 "You were warned!" |
| 35 | #define KALECGOS_SOUND_KILL_2 12426 |
| 36 | #define KALECGOS_SAY_FLY_AWAY "My awakening is complete! You shall all perish!" |
| 37 | #define KALECGOS_SOUND_FLY_AWAY 12427 |
| 38 | #define KALECGOS_SAY_WIN "I am forever in your debt. Once we have triumphed over Kil'jaeden, this entire world will be in your debt as well." |
| 39 | #define KALECGOS_SOUND_WIN 12431 |
| 40 | |
| 41 | #define SATH_SAY_AGGRO "Gyahaha... There will be no reprieve. My work here is nearly finished." |
| 42 | #define SATH_SOUND_AGGRO 12451 |
| 43 | #define SATH_SAY_DIE "I'm... never on... the losing... side..." |
| 44 | #define SATH_SOUND_DIE 12452 |
| 45 | #define SATH_SAY_SPELL_1 "Your misery is my delight!" |
| 46 | #define SATH_SOUND_SPELL_1 12453 |
| 47 | #define SATH_SAY_SPELL_2 "I will watch you bleed!" |
| 48 | #define SATH_SOUND_SPELL_2 12454 |
| 49 | #define SATH_SAY_KILL_1 "Pitious mortal!" |
| 50 | #define SATH_SOUND_KILL_1 12455 |
| 51 | #define SATH_SAY_KILL_2 "Haven't you heard? I always win!" |
| 52 | #define SATH_SOUND_KILL_2 12456 |
| 53 | #define SATH_SAY_ENRAGE "I have toyed with you long enough!" |
| 54 | #define SATH_SOUND_ENRAGE 12457 |
| 55 | |
| 56 | #define KALEC_SAY_AGGRO "I need... your help... Cannot... resist him... much longer..." |
| 57 | #define KALEC_SOUND_AGGRO 12428 |
| 58 | #define KALEC_SAY_LOSING1 "Aaahhh! Help me, before I lose my mind!" |
| 59 | #define KALEC_SOUND_LOSING1 12429 |
| 60 | #define KALEC_SAY_LOSING2 "Hurry! There is not much of me left!" //??? |
| 61 | #define KALEC_SOUND_LOSING2 12430 |
| 62 | |
| 63 | #define GO_FAILED "You are unable to use this currently." |
| 64 | |
| 65 | #define FLY_X 1679 |
| 66 | #define FLY_Y 900 |
| 67 | #define FLY_Z 82 |
| 68 | |
| 69 | #define CENTER_X 1705 |
| 70 | #define CENTER_Y 930 |
| 71 | #define RADIUS 30 |
| 72 | |
| 73 | #define AURA_SUNWELL_RADIANCE 45769 |
| 74 | #define AURA_SPECTRAL_EXHAUSTION 44867 |
| 75 | #define AURA_SPECTRAL_REALM 46021 |
| 76 | #define AURA_SPECTRAL_INVISIBILITY 44801 |
| 77 | #define AURA_DEMONIC_VISUAL 44800 |
| 78 | |
| 79 | #define SPELL_SPECTRAL_BLAST 44869 |
| 80 | #define SPELL_TELEPORT_SPECTRAL 46019 |
92 | | /*** Sathrovarr ***/ |
93 | | #define SPELL_CORRUPTING_STRIKE 45029 |
94 | | #define SPELL_CURSE_OF_BOUNDLESS_AGONY 45032 |
95 | | #define SPELL_SHADOW_BOLT_VOLLEY 45031 |
96 | | |
97 | | /*** Misc ***/ |
98 | | #define SPELL_BANISH 44836 |
99 | | |
100 | | void TeleportToInnerVeil(Player* plr) |
101 | | { |
102 | | if(plr->HasAura(SPELL_SPECTRAL_EXHAUSTION, 0)) |
103 | | { |
104 | | plr->GetSession()->SendNotification(NOTIFY_SPECTRALLY_EXHAUSTED); |
105 | | return; |
106 | | } |
107 | | |
108 | | ScriptedInstance* pInstance = ((ScriptedInstance*)plr->GetInstanceData()); |
109 | | if(!pInstance) |
110 | | { |
111 | | error_log(ERROR_INST_DATA); |
112 | | plr->GetSession()->SendNotification(ERROR_INST_DATA_PLR); |
113 | | return; |
114 | | } |
115 | | |
116 | | pInstance->SetData64(DATA_PLAYER_SPECTRAL_REALM, plr->GetGUID()); |
117 | | // Remove the player from Kalecgos' Threat List |
118 | | Creature* Kalecgos = ((Creature*)Unit::GetUnit(*plr, pInstance->GetData64(DATA_KALECGOS_DRAGON))); |
119 | | if(Kalecgos) |
120 | | { |
121 | | HostilReference* ref = Kalecgos->getThreatManager().getOnlineContainer().getReferenceByTarget(plr); |
122 | | if(ref) |
123 | | ref->removeReference(); |
124 | | } |
125 | | |
126 | | // Add the player to Sathrovarr's Threat List |
127 | | Creature* Sathrovarr = ((Creature*)Unit::GetUnit(*plr, pInstance->GetData64(DATA_SATHROVARR))); |
128 | | if(Sathrovarr) |
129 | | Sathrovarr->AddThreat(plr, 1.0f); |
130 | | |
131 | | // Make them able to see Sathrovarr (he's invisible for some reason). Also, when this buff wears off, they get teleported back to Normal Realm (this is handled by Instance Script) |
132 | | plr->CastSpell(plr, SPELL_SPECTRAL_REALM, true); |
133 | | plr->CastSpell(plr, SPELL_TELEPORT_SPECTRAL_REALM, true); |
134 | | } |
135 | | |
136 | | bool GOHello_GO_Spectral_Portal(Player* plr, GameObject* go) |
137 | | { |
138 | | TeleportToInnerVeil(plr); |
139 | | |
140 | | return true; |
141 | | } |
191 | | if(Creature* Sath = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_SATHROVARR)))) |
192 | | Sath->AI()->EnterEvadeMode(); |
| 137 | { |
| 138 | uint64 SathGUID = pInstance->GetData64(DATA_SATHROVARR); |
| 139 | uint64 DoorGUID = pInstance->GetData64(DATA_GO_FORCEFIELD); |
| 140 | } |
| 141 | |
| 142 | Unit *Sath = Unit::GetUnit(*m_creature,SathGUID); |
| 143 | if(Sath) ((Creature*)Sath)->AI()->EnterEvadeMode(); |
| 144 | |
| 145 | GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID); |
| 146 | if(Door) Door->SetLootState(GO_JUST_DEACTIVATED); |
| 147 | |
| 148 | m_creature->setFaction(14); |
| 149 | m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); |
| 150 | m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); |
| 151 | m_creature->SetVisibility(VISIBILITY_ON); |
| 152 | m_creature->SetStandState(PLAYER_STATE_SLEEP); |
| 153 | |
| 154 | ArcaneBuffetTimer = 8000; |
| 155 | FrostBreathTimer = 15000; |
| 156 | WildMagicTimer = 10000; |
| 157 | TailLashTimer = 25000; |
| 158 | SpectralBlastTimer = 20000+(rand()%5000); |
| 159 | CheckTimer = SpectralBlastTimer+20000; //after spectral blast |
| 160 | |
| 161 | TalkTimer = 0; |
| 162 | TalkSequence = 0; |
| 163 | isFriendly = false; |
| 164 | isEnraged = false; |
| 165 | isBanished = false; |
| 166 | //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true); |
| 167 | } |
| 168 | |
| 169 | void DamageTaken(Unit *done_by, uint32 &damage) |
| 170 | { |
| 171 | if(damage >= m_creature->GetHealth() && done_by != m_creature) |
| 172 | damage = 0; |
197 | | DoYell(SAY_KALECGOS_AGGRO, LANG_UNIVERSAL, NULL); |
198 | | DoPlaySoundToSet(m_creature, SOUND_KALECGOS_AGGRO); |
199 | | |
| 177 | m_creature->SetStandState(PLAYER_STATE_NONE); |
| 178 | DoYell(KALECGOS_SAY_AGGRO, LANG_UNIVERSAL,NULL); |
| 179 | DoPlaySoundToSet(m_creature, KALECGOS_SOUND_AGGRO); |
| 180 | GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID); |
| 181 | if(Door) Door->SetLootState(GO_ACTIVATED); |
| 182 | DoZoneInCombat(); |
| 183 | } |
| 184 | |
| 185 | void KilledUnit(Unit *victim) |
| 186 | { |
| 187 | switch(rand()%2) |
| 188 | { |
| 189 | case 0: |
| 190 | DoYell(KALECGOS_SAY_KILL_1,LANG_UNIVERSAL,NULL); |
| 191 | DoPlaySoundToSet(m_creature,KALECGOS_SOUND_KILL_1); |
| 192 | break; |
| 193 | case 1: |
| 194 | DoYell(KALECGOS_SAY_KILL_2,LANG_UNIVERSAL,NULL); |
| 195 | DoPlaySoundToSet(m_creature,KALECGOS_SOUND_KILL_2); |
| 196 | break; |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | void MovementInform(uint32 type,uint32 id) |
| 201 | { |
| 202 | m_creature->SetVisibility(VISIBILITY_OFF); |
| 203 | if(isFriendly) |
| 204 | m_creature->setDeathState(JUST_DIED); |
| 205 | else |
| 206 | { |
| 207 | m_creature->GetMotionMaster()->MoveTargetedHome(); |
| 208 | TalkTimer = 30000; |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | void GoodEnding() |
| 213 | { |
| 214 | switch(TalkSequence) |
| 215 | { |
| 216 | case 1: |
| 217 | m_creature->setFaction(35); |
| 218 | DoCast(m_creature, SPELL_TRANSFORM_KALEC); |
| 219 | TalkTimer = 1000; |
| 220 | break; |
| 221 | case 2: |
| 222 | DoSay(KALECGOS_SAY_WIN, LANG_UNIVERSAL,NULL); |
| 223 | DoPlaySoundToSet(m_creature, KALECGOS_SOUND_WIN); |
| 224 | TalkTimer = 10000; |
| 225 | break; |
| 226 | case 3: |
| 227 | m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); |
| 228 | m_creature->GetMotionMaster()->Clear(); |
| 229 | m_creature->GetMotionMaster()->MovePoint(0,FLY_X,FLY_Y,FLY_Z); |
| 230 | TalkTimer = 600000; |
| 231 | break; |
| 232 | default: |
| 233 | break; |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | void BadEnding() |
| 238 | { |
| 239 | switch(TalkSequence) |
| 240 | { |
| 241 | case 1: |
| 242 | DoYell(KALECGOS_SAY_FLY_AWAY,LANG_UNIVERSAL,NULL); |
| 243 | DoPlaySoundToSet(m_creature,KALECGOS_SOUND_FLY_AWAY); |
| 244 | TalkTimer = 3000; |
| 245 | break; |
| 246 | case 2: |
| 247 | m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); |
| 248 | m_creature->GetMotionMaster()->Clear(); |
| 249 | m_creature->GetMotionMaster()->MovePoint(0,FLY_X,FLY_Y,FLY_Z); |
| 250 | TalkTimer = 600000; |
| 251 | break; |
| 252 | case 3: |
| 253 | EnterEvadeMode(); |
| 254 | break; |
| 255 | default: |
| 256 | break; |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | void UpdateAI(const uint32 diff); |
| 261 | }; |
| 262 | |
| 263 | struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI |
| 264 | { |
| 265 | boss_sathrovarrAI(Creature *c) : ScriptedAI(c) |
| 266 | { |
| 267 | pInstance = ((ScriptedInstance*)c->GetInstanceData()); |
| 268 | KalecGUID = 0; |
| 269 | KalecgosGUID = 0; |
| 270 | Reset(); |
| 271 | } |
| 272 | |
| 273 | ScriptedInstance *pInstance; |
| 274 | |
| 275 | uint32 CorruptionStrikeTimer; |
| 276 | uint32 AgonyCurseTimer; |
| 277 | uint32 ShadowBoltTimer; |
| 278 | uint32 CheckTimer; |
| 279 | |
| 280 | uint64 KalecGUID; |
| 281 | uint64 KalecgosGUID; |
| 282 | |
| 283 | bool isEnraged; |
| 284 | bool isBanished; |
| 285 | |
| 286 | void Reset() |
| 287 | { |
201 | | pInstance->SetData(DATA_KALECGOS_EVENT, IN_PROGRESS); |
202 | | } |
203 | | |
204 | | void DamageTaken(Unit* done_by, uint32 &damage) |
205 | | { |
206 | | if(damage > m_creature->GetHealth() && done_by != m_creature) |
207 | | { |
208 | | if(!Uncorrupted) |
| 289 | KalecgosGUID = pInstance->GetData64(DATA_KALECGOS_DRAGON); |
| 290 | |
| 291 | if(KalecGUID) |
| 292 | { |
| 293 | if(Unit* Kalec = Unit::GetUnit(*m_creature, KalecGUID)) |
| 294 | Kalec->setDeathState(JUST_DIED); |
| 295 | KalecGUID = 0; |
| 296 | } |
| 297 | |
| 298 | ShadowBoltTimer = 7000 + rand()%3 * 1000; |
| 299 | AgonyCurseTimer = 20000; |
| 300 | CorruptionStrikeTimer = 13000; |
| 301 | CheckTimer = 1000; |
| 302 | isEnraged = false; |
| 303 | isBanished = false; |
| 304 | //m_creature->CastSpell(m_creature, AURA_SPECTRAL_INVISIBILITY, true); |
| 305 | //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true); |
| 306 | //m_creature->CastSpell(m_creature, AURA_DEMONIC_VISUAL, true); |
| 307 | } |
| 308 | |
| 309 | void Aggro(Unit* who) |
| 310 | { |
| 311 | Creature *Kalec = m_creature->SummonCreature(MOB_KALEC, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); |
| 312 | if(Kalec) |
| 313 | { |
| 314 | KalecGUID = Kalec->GetGUID(); |
| 315 | m_creature->CombatStart(Kalec); |
| 316 | m_creature->AddThreat(Kalec, 100.0f); |
| 317 | } |
| 318 | DoYell(SATH_SAY_AGGRO, LANG_UNIVERSAL, NULL); |
| 319 | DoPlaySoundToSet(m_creature, SATH_SOUND_AGGRO); |
| 320 | } |
| 321 | |
| 322 | void DamageTaken(Unit *done_by, uint32 &damage) |
| 323 | { |
| 324 | if(damage >= m_creature->GetHealth() && done_by != m_creature) |
| 325 | damage = 0; |
| 326 | } |
| 327 | |
| 328 | void KilledUnit(Unit *target) |
| 329 | { |
| 330 | if(target->GetGUID() == KalecGUID) |
| 331 | { |
| 332 | TeleportAllPlayersBack(); |
| 333 | if(Unit *Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID)) |
215 | | else |
| 338 | EnterEvadeMode(); |
| 339 | return; |
| 340 | } |
| 341 | switch(rand()%2) |
| 342 | { |
| 343 | case 0: |
| 344 | DoYell(SATH_SAY_KILL_1,LANG_UNIVERSAL,NULL); |
| 345 | DoPlaySoundToSet(m_creature,SATH_SOUND_KILL_1); |
| 346 | break; |
| 347 | case 1: |
| 348 | DoYell(SATH_SAY_KILL_2,LANG_UNIVERSAL,NULL); |
| 349 | DoPlaySoundToSet(m_creature,SATH_SOUND_KILL_2); |
| 350 | break; |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | void JustDied(Unit *victim) |
| 355 | { |
| 356 | DoYell(SATH_SAY_DIE, LANG_UNIVERSAL, NULL); |
| 357 | DoPlaySoundToSet(m_creature, SATH_SOUND_DIE); |
| 358 | m_creature->Relocate(m_creature->GetPositionX(), m_creature->GetPositionY(), DRAGON_REALM_Z, m_creature->GetOrientation()); |
| 359 | TeleportAllPlayersBack(); |
| 360 | if(Unit *Kalecgos = Unit::GetUnit(*m_creature, KalecgosGUID)) |
| 361 | { |
| 362 | ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->TalkTimer = 1; |
| 363 | ((boss_kalecgosAI*)((Creature*)Kalecgos)->AI())->isFriendly = true; |
| 364 | } |
| 365 | } |
| 366 | |
| 367 | void TeleportAllPlayersBack() |
| 368 | { |
| 369 | Map *map = m_creature->GetMap(); |
| 370 | if(!map->IsDungeon()) return; |
| 371 | InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers(); |
| 372 | InstanceMap::PlayerList::const_iterator i; |
| 373 | for (i = PlayerList.begin(); i != PlayerList.end(); ++i) |
| 374 | { |
| 375 | if((*i)->HasAura(AURA_SPECTRAL_REALM,0)) |
| 376 | (*i)->RemoveAurasDueToSpell(AURA_SPECTRAL_REALM); |
| 377 | } |
| 378 | } |
| 379 | |
| 380 | void Enrage(); // demon and dragon should enrage at the same time |
| 381 | |
| 382 | void UpdateAI(const uint32 diff) |
| 383 | { |
| 384 | if (!m_creature->SelectHostilTarget() && !m_creature->getVictim()) |
| 385 | return; |
| 386 | |
| 387 | if(CheckTimer < diff) |
| 388 | { |
| 389 | if(!isEnraged && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10) |
| 390 | Enrage(); |
| 391 | |
| 392 | if(!isBanished && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1) |
220 | | } |
221 | | } |
222 | | |
223 | | void KilledUnit(Unit* victim) |
224 | | { |
225 | | switch(rand()%2) |
226 | | { |
| 413 | CheckTimer = 1000; |
| 414 | }else CheckTimer -= diff; |
| 415 | |
| 416 | if(ShadowBoltTimer < diff) |
| 417 | { |
| 418 | DoCast(m_creature, SPELL_SHADOW_BOLT); |
| 419 | ShadowBoltTimer = 7000+(rand()%3000); |
| 420 | }else ShadowBoltTimer -= diff; |
| 421 | |
| 422 | if(AgonyCurseTimer < diff) |
| 423 | { |
| 424 | Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); |
| 425 | if(!target) target = m_creature->getVictim(); |
| 426 | DoCast(target, SPELL_AGONY_CURSE); |
| 427 | AgonyCurseTimer = 20000; |
| 428 | }else AgonyCurseTimer -= diff; |
| 429 | |
| 430 | if(CorruptionStrikeTimer < diff) |
| 431 | { |
| 432 | DoCast(m_creature->getVictim(), SPELL_CORRUPTION_STRIKE); |
| 433 | CorruptionStrikeTimer = 13000; |
| 434 | }else CorruptionStrikeTimer -= diff; |
| 435 | |
| 436 | DoMeleeAttackIfReady(); |
| 437 | } |
| 438 | }; |
| 439 | |
| 440 | struct TRINITY_DLL_DECL boss_kalecAI : public ScriptedAI |
| 441 | { |
| 442 | ScriptedInstance *pInstance; |
| 443 | |
| 444 | uint32 RevitalizeTimer; |
| 445 | uint32 HeroicStrikeTimer; |
| 446 | uint32 YellTimer; |
| 447 | uint32 YellSequence; |
| 448 | |
| 449 | uint64 SathGUID; |
| 450 | |
| 451 | bool isEnraged; // if demon is enraged |
| 452 | |
| 453 | boss_kalecAI(Creature *c) : ScriptedAI(c) |
| 454 | { |
| 455 | pInstance = ((ScriptedInstance*)c->GetInstanceData()); |
| 456 | Reset(); |
| 457 | } |
| 458 | |
| 459 | void Reset() |
| 460 | { |
| 461 | if(pInstance) |
| 462 | SathGUID = pInstance->GetData64(DATA_SATHROVARR); |
| 463 | |
| 464 | RevitalizeTimer = 5000; |
| 465 | HeroicStrikeTimer = 3000; |
| 466 | YellTimer = 5000; |
| 467 | YellSequence = 0; |
| 468 | |
| 469 | isEnraged = false; |
| 470 | |
| 471 | //m_creature->CastSpell(m_creature, AURA_SPECTRAL_INVISIBILITY, true); |
| 472 | //m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true); |
| 473 | } |
| 474 | |
| 475 | void Aggro(Unit* who) {} |
| 476 | |
| 477 | void DamageTaken(Unit *done_by, uint32 &damage) |
| 478 | { |
| 479 | if(done_by->GetGUID() != SathGUID) |
| 480 | damage = 0; |
| 481 | else if(isEnraged) |
| 482 | damage *= 3; |
| 483 | } |
| 484 | |
| 485 | void UpdateAI(const uint32 diff) |
| 486 | { |
| 487 | if(!m_creature->getVictim()) // only victim is Sath |
| 488 | { |
| 489 | EnterEvadeMode(); |
| 490 | return; |
| 491 | } |
| 492 | |
| 493 | if(YellTimer < diff) |
| 494 | { |
| 495 | switch(YellSequence) |
| 496 | { |
235 | | } |
236 | | } |
237 | | |
238 | | void BeginOutro() |
239 | | { |
240 | | debug_log("SD2: KALEC: Beginning Outro"); |
241 | | |
242 | | if(!pInstance) |
243 | | { |
244 | | error_log(ERROR_INST_DATA); |
| 510 | case 2: |
| 511 | if((m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10) |
| 512 | { |
| 513 | DoYell(KALEC_SAY_LOSING2, LANG_UNIVERSAL, NULL); |
| 514 | DoPlaySoundToSet(m_creature, KALEC_SOUND_LOSING2); |
| 515 | YellSequence++; |
| 516 | } |
| 517 | break; |
| 518 | default: |
| 519 | break; |
| 520 | } |
| 521 | YellTimer = 5000; |
| 522 | } |
| 523 | |
| 524 | if(RevitalizeTimer < diff) |
| 525 | { |
| 526 | DoCast(m_creature, SPELL_REVITALIZE); |
| 527 | RevitalizeTimer = 5000; |
| 528 | }else RevitalizeTimer -= diff; |
| 529 | |
| 530 | if(HeroicStrikeTimer < diff) |
| 531 | { |
| 532 | DoCast(m_creature->getVictim(), SPELL_HEROIC_STRIKE); |
| 533 | HeroicStrikeTimer = 2000; |
| 534 | }else HeroicStrikeTimer -= diff; |
| 535 | |
| 536 | DoMeleeAttackIfReady(); |
| 537 | } |
| 538 | }; |
| 539 | |
| 540 | void boss_kalecgosAI::UpdateAI(const uint32 diff) |
| 541 | { |
| 542 | if(TalkTimer) |
| 543 | { |
| 544 | if(!TalkSequence) |
| 545 | { |
| 546 | m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); |
| 547 | m_creature->InterruptNonMeleeSpells(true); |
| 548 | m_creature->RemoveAllAuras(); |
| 549 | m_creature->DeleteThreatList(); |
| 550 | m_creature->CombatStop(); |
| 551 | GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID); |
| 552 | if(Door) Door->SetLootState(GO_JUST_DEACTIVATED); |
| 553 | TalkSequence++; |
| 554 | } |
| 555 | if(TalkTimer <= diff) |
| 556 | { |
| 557 | if(isFriendly) |
| 558 | GoodEnding(); |
| 559 | else |
| 560 | BadEnding(); |
| 561 | TalkSequence++; |
| 562 | }else TalkTimer -= diff; |
| 563 | } |
| 564 | else |
| 565 | { |
| 566 | if (!m_creature->SelectHostilTarget() && !m_creature->getVictim()) |
246 | | } |
247 | | |
248 | | Unit* Sathrovarr = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_SATHROVARR)); |
249 | | if(Sathrovarr) |
250 | | { |
251 | | Sathrovarr->DealDamage(Sathrovarr, Sathrovarr->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); |
252 | | |
253 | | Sathrovarr->Relocate(KALECGOS_ARENA_X, KALECGOS_ARENA_Y, KALECGOS_ARENA_Z); |
254 | | Sathrovarr->SendMonsterMove(KALECGOS_ARENA_X, KALECGOS_ARENA_Y, KALECGOS_ARENA_Z, 0, 0, 0); |
255 | | } |
256 | | |
257 | | Creature* Kalec = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KALECGOS_HUMAN))); |
258 | | if(Kalec) |
259 | | { |
260 | | Kalec->DeleteThreatList(); |
261 | | Kalec->SetVisibility(VISIBILITY_OFF); |
262 | | } |
263 | | |
264 | | m_creature->GetMotionMaster()->MoveIdle(); |
265 | | m_creature->setFaction(35); |
266 | | } |
267 | | |
268 | | void MovementInform(uint32 type, uint32 id) |
269 | | { |
270 | | if(type != POINT_MOTION_TYPE) |
271 | | return; |
272 | | |
273 | | if(id) |
274 | | { |
275 | | if(pInstance) |
| 568 | |
| 569 | if(CheckTimer < diff) |
| 570 | { |
| 571 | if(!isEnraged && (m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 10) |
314 | | else |
315 | | BeginOutro(); |
316 | | } |
317 | | |
318 | | if(ExitTimer) |
319 | | if(ExitTimer <= diff) |
320 | | { |
321 | | debug_log("SD2: KALEC: Exiting the arena"); |
322 | | DoYell(SAY_KALEC_PLRWIN, LANG_UNIVERSAL, NULL); |
323 | | DoPlaySoundToSet(m_creature, SOUND_KALEC_PLRWIN); |
324 | | m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); |
325 | | float x, y, z; |
326 | | float iniX, iniY, iniZ; |
327 | | m_creature->GetPosition(iniX, iniY, iniZ); |
328 | | m_creature->GetRandomPoint(iniX, iniY, iniZ, 30, x, y, z); |
329 | | z = 70; |
330 | | m_creature->GetMotionMaster()->MovePoint(1, x, y, z); |
331 | | }else ExitTimer -= diff; |
332 | | |
333 | | if(!LockedArena) |
334 | | if(ForceFieldTimer < diff) |
335 | | { |
336 | | if(pInstance) |
337 | | { |
338 | | GameObject* ForceField = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GO_FORCEFIELD)); |
339 | | if(ForceField) |
340 | | ForceField->SetUInt32Value(GAMEOBJECT_STATE, 0); |
341 | | |
342 | | LockedArena = true; |
343 | | }else error_log(ERROR_INST_DATA); |
344 | | }else ForceFieldTimer -= diff; |
| 595 | CheckTimer = 1000; //every 1 sec we check this |
| 596 | }else CheckTimer -= diff; |
385 | | if(SpectralTeleportTimer < diff) |
386 | | { |
387 | | if(TeleportTargetGUID) |
388 | | { |
389 | | Unit* pUnit = Unit::GetUnit((*m_creature), TeleportTargetGUID); |
390 | | if(pUnit) |
391 | | { |
392 | | pUnit->CastSpell(pUnit, SPELL_SPECTRAL_BLAST, true); |
393 | | TeleportToInnerVeil((Player*)pUnit); |
394 | | } |
395 | | else error_log(ERROR_MISSING_TELEPORT_GUID); |
396 | | } |
397 | | else error_log(ERROR_MISSING_TELEPORT_GUID); |
398 | | |
399 | | m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->getVictim()->GetGUID()); |
400 | | TeleportTargetGUID = 0; |
401 | | SpectralTeleportTimer = SpectralBlastTimer + 2000; |
402 | | |
403 | | }else SpectralTeleportTimer -= diff; |
404 | | |
405 | | if(!Banished) DoMeleeAttackIfReady(); |
406 | | } |
407 | | }; |
408 | | |
409 | | struct TRINITY_DLL_DECL boss_sathrovarrAI : public ScriptedAI |
410 | | { |
411 | | boss_sathrovarrAI(Creature* c) : ScriptedAI(c) |
412 | | { |
413 | | pInstance = ((ScriptedInstance*)c->GetInstanceData()); |
414 | | Reset(); |
415 | | } |
416 | | |
417 | | ScriptedInstance* pInstance; |
418 | | |
419 | | uint32 CorruptingStrikeTimer; |
420 | | uint32 CurseOfBoundlessAgonyTimer; |
421 | | uint32 ShadowBoltVolleyTimer; |
422 | | bool Banished; |
423 | | bool Enraged; |
424 | | |
425 | | void Reset() |
426 | | { |
427 | | // FIXME: Timers |
428 | | CorruptingStrikeTimer = 5000; |
429 | | CurseOfBoundlessAgonyTimer = 15000; |
430 | | ShadowBoltVolleyTimer = 10000; |
431 | | |
432 | | Banished = false; |
433 | | Enraged = false; |
434 | | |
435 | | DoCast(m_creature, SPELL_SPECTRAL_REALM, true); |
436 | | } |
437 | | |
438 | | void Aggro(Unit* who) |
439 | | { |
440 | | DoYell(SAY_SATH_AGGRO, LANG_UNIVERSAL, NULL); |
441 | | DoPlaySoundToSet(m_creature, SOUND_SATH_AGGRO); |
442 | | |
443 | | Creature* Kalec = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KALECGOS_HUMAN))); |
444 | | if(Kalec) |
445 | | { |
446 | | m_creature->AddThreat(Kalec, 10000000.0f); |
447 | | Kalec->AddThreat(m_creature, 10000000.0f); |
448 | | } |
449 | | } |
450 | | |
451 | | void DamageTaken(Unit* done_by, uint32 &damage) |
452 | | { |
453 | | if(damage > m_creature->GetHealth()) |
454 | | { |
455 | | damage = 0; |
456 | | DoCast(m_creature, SPELL_BANISH, true); |
457 | | Banished = true; |
458 | | |
459 | | DoYell(SAY_SATH_DEATH, LANG_UNIVERSAL, NULL); |
460 | | DoPlaySoundToSet(m_creature, SOUND_SATH_DEATH); |
461 | | |
462 | | if(!pInstance) |
463 | | { |
464 | | error_log(ERROR_INST_DATA); |
465 | | return; |
466 | | } |
467 | | |
468 | | pInstance->SetData(DATA_SET_SPECTRAL_CHECK, 5000); |
469 | | |
470 | | Creature* Kalecgos = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KALECGOS_DRAGON))); |
471 | | if(Kalecgos) |
472 | | { |
473 | | ((boss_kalecgosAI*)Kalecgos->AI())->Checked = false; |
474 | | ((boss_kalecgosAI*)Kalecgos->AI())->Uncorrupted = true; |
475 | | } |
476 | | else error_log(ERROR_KALECGOS_NOT_FOUND); |
477 | | } |
478 | | } |
479 | | |
480 | | void KilledUnit(Unit* victim) |
481 | | { |
482 | | switch(rand()%2) |
483 | | { |
484 | | case 0: |
485 | | DoYell(SAY_SATH_SLAY1,LANG_UNIVERSAL,NULL); |
486 | | DoPlaySoundToSet(m_creature,SOUND_SATH_SLAY1); |
487 | | break; |
488 | | case 1: |
489 | | DoYell(SAY_SATH_SLAY2,LANG_UNIVERSAL,NULL); |
490 | | DoPlaySoundToSet(m_creature,SOUND_SATH_SLAY2); |
491 | | break; |
492 | | } |
493 | | } |
494 | | |
495 | | void UpdateAI(const uint32 diff) |
496 | | { |
497 | | if(!m_creature->getVictim() || !m_creature->SelectHostilTarget() || Banished) |
498 | | return; |
499 | | |
500 | | if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !Enraged) |
501 | | { |
502 | | Unit* Kalecgos = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KALECGOS_DRAGON)); |
503 | | if(Kalecgos) |
504 | | Kalecgos->CastSpell(Kalecgos, SPELL_CRAZED_RAGE, true); |
505 | | DoCast(m_creature, SPELL_CRAZED_RAGE, true); |
506 | | Enraged = true; |
507 | | } |
508 | | |
509 | | if(CorruptingStrikeTimer < diff) |
510 | | { |
511 | | if(rand()%2 == 0) |
512 | | { |
513 | | DoYell(SAY_SATH_SPELL2, LANG_UNIVERSAL, NULL); |
514 | | DoPlaySoundToSet(m_creature, SOUND_SATH_SPELL2); |
515 | | } |
516 | | DoCast(m_creature->getVictim(), SPELL_CORRUPTING_STRIKE); |
517 | | CorruptingStrikeTimer = 13000; |
518 | | }else CorruptingStrikeTimer -= diff; |
519 | | |
520 | | if(CurseOfBoundlessAgonyTimer < diff) |
521 | | { |
522 | | DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_CURSE_OF_BOUNDLESS_AGONY); |
523 | | CurseOfBoundlessAgonyTimer = 35000; |
524 | | DoCast(m_creature, SPELL_SPECTRAL_REALM, true); |
525 | | }else CurseOfBoundlessAgonyTimer -= diff; |
526 | | |
527 | | if(ShadowBoltVolleyTimer < diff) |
528 | | { |
529 | | if(rand()%2 == 0) |
530 | | { |
531 | | DoYell(SAY_SATH_SPELL1, LANG_UNIVERSAL, NULL); |
532 | | DoPlaySoundToSet(m_creature, SOUND_SATH_SPELL1); |
533 | | } |
534 | | DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT_VOLLEY); |
535 | | ShadowBoltVolleyTimer = 15000; |
536 | | }else ShadowBoltVolleyTimer -= diff; |
537 | | |
540 | | }; |
541 | | |
542 | | struct TRINITY_DLL_DECL boss_kalecAI : public ScriptedAI |
543 | | { |
544 | | boss_kalecAI(Creature* c) : ScriptedAI(c) |
545 | | { |
546 | | pInstance = ((ScriptedInstance*)c->GetInstanceData()); |
547 | | Reset(); |
548 | | } |
549 | | |
550 | | ScriptedInstance *pInstance; |
551 | | |
552 | | uint32 RevitalizeTimer; |
553 | | uint32 HeroicStrikeTimer; |
554 | | |
555 | | bool HasYelled10Percent; |
556 | | bool HasYelled20Percent; |
557 | | |
558 | | void Reset() |
559 | | { |
560 | | //TODO: Times! |
561 | | RevitalizeTimer = 30000; |
562 | | HeroicStrikeTimer = 8000; |
563 | | |
564 | | HasYelled10Percent = false; |
565 | | HasYelled20Percent = false; |
566 | | |
567 | | DoCast(m_creature, SPELL_SPECTRAL_REALM, true); |
568 | | } |
569 | | |
570 | | void Aggro(Unit* who) |
571 | | { |
572 | | DoYell(SAY_KALEC_AGGRO, LANG_UNIVERSAL, NULL); |
573 | | DoPlaySoundToSet(m_creature, SOUND_KALEC_AGGRO); |
574 | | } |
575 | | |
576 | | void JustDied(Unit* killer) |
577 | | { |
578 | | // Whatever happens when Kalec (Half-elf) dies |
579 | | } |
580 | | |
581 | | void UpdateAI(const uint32 diff) |
582 | | { |
583 | | if(!m_creature->getVictim() || !m_creature->SelectHostilTarget()) |
584 | | return; |
585 | | |
586 | | if(RevitalizeTimer < diff) |
587 | | { |
588 | | if(pInstance) |
589 | | { |
590 | | Unit* pUnit = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_RANDOM_SPECTRAL_PLAYER)); |
591 | | if(pUnit) |
592 | | DoCast(pUnit, SPELL_REVITALIZE); |
593 | | RevitalizeTimer = 30000; |
594 | | } |
595 | | }else RevitalizeTimer -= diff; |
596 | | |
597 | | if(HeroicStrikeTimer < diff) |
598 | | { |
599 | | DoCast(m_creature->getVictim(), SPELL_HEROIC_STRIKE); |
600 | | HeroicStrikeTimer = 30000; |
601 | | }else HeroicStrikeTimer -= diff; |
602 | | |
603 | | if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20) && !HasYelled20Percent) |
604 | | { |
605 | | DoYell(SAY_KALEC_NEAR_DEATH, LANG_UNIVERSAL, NULL); |
606 | | DoPlaySoundToSet(m_creature, SOUND_KALEC_NEAR_DEATH); |
607 | | HasYelled20Percent = true; |
608 | | } |
609 | | |
610 | | if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !HasYelled10Percent) |
611 | | { |
612 | | DoYell(SAY_KALEC_NEAR_DEATH2, LANG_UNIVERSAL, NULL); |
613 | | DoPlaySoundToSet(m_creature, SOUND_KALEC_NEAR_DEATH2); |
614 | | HasYelled10Percent = true; |
615 | | } |
616 | | } |
617 | | }; |
618 | | |
619 | | CreatureAI* GetAI_boss_kalecgos(Creature* c) |
620 | | { |
621 | | return new boss_kalecgosAI(c); |