*Integrate Script system to Core

-added ScriptMgr for loading scripts
-removed bindings
-moved script system to src/game
-moved scripts to src/scripts
-VC project files updated
-cmakes updated (not 100% done yet)

NOTE to Devs:
-file locations changed
-precompiled renamed to ScriptedPch
-ecsort_ai renamed to ScriptedEscortAI
-follower_ai renamed to ScriptedFollowerAI
-guard_ai renamed to ScriptedGuardAI
-simple_ai renamed to ScriptedSimpleAI
-sc_creature renamed to ScriptedCreature
-sc_gossip renamed to ScriptedGossip
-sc_instance  renamed to ScriptedInstance

*use the new headers in scripts, thank you

NOTE to ALL:
cmake not fully tested, please report any errors with it
could make creashes, incompability
USE AT YOUR OWN RISK before further tests!!

--HG--
branch : trunk
This commit is contained in:
Rat
2010-01-19 11:36:05 +01:00
parent f5dea61b66
commit 0cc053ea4d
601 changed files with 3908 additions and 7245 deletions
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DEF_AHNKAHET_H
#define DEF_AHNKAHET_H
#define DATA_ELDER_NADOX 1
#define DATA_PRINCE_TALDARAM 2
#define DATA_JEDOGA_SHADOWSEEKER 3
#define DATA_HERALD_VOLAZJ 4
#define DATA_AMANITAR 5
#define DATA_ELDER_NADOX_EVENT 6
#define DATA_PRINCE_TALDARAM_EVENT 7
#define DATA_JEDOGA_SHADOWSEEKER_EVENT 8
#define DATA_HERALD_VOLAZJ_EVENT 9
#define DATA_AMANITAR_EVENT 10
#define DATA_SPHERE1 11
#define DATA_SPHERE2 12
#define DATA_SPHERE1_EVENT 13
#define DATA_SPHERE2_EVENT 14
#define DATA_PRINCE_TALDARAM_PLATFORM 15
#define DATA_PL_JEDOGA_TARGET 16
#define DATA_ADD_JEDOGA_OPFER 17
#define DATA_JEDOGA_RESET_INITIANDS 18
#define DATA_JEDOGA_TRIGGER_SWITCH 19
#define DATA_ADD_JEDOGA_INITIAND 20
#define DATA_ALL_INITIAND_DEAD 21
#define DATA_INITIAND_KILLED 22
#endif
@@ -0,0 +1,238 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: boss_amanitar
SDAuthor: WarHead
SD%Complete: 80%
SDComment: Find correct mushrooms spell to make them visible - buffs of the mushrooms not ever applied to the users...
SDCategory: Ahn'kahet
Script Data End */
#include "ScriptedPch.h"
#include "ahnkahet.h"
enum Spells
{
SPELL_BASH = 57094, // Victim
SPELL_ENTANGLING_ROOTS = 57095, // Random Victim 100Y
SPELL_MINI = 57055, // Self
SPELL_VENOM_BOLT_VOLLEY = 57088, // Random Victim 100Y
HEALTHY_MUSHROOM_SPELL_POTENT_FUNGUS = 56648, // Killer 3Y
POISONOUS_MUSHROOM_SPELL_POISON_CLOUD = 57061, // Self - Duration 8 Sec
POISONOUS_MUSHROOM_SPELL_VISUAL_AREA = 61566, // Self
POISONOUS_MUSHROOM_SPELL_VISUAL_AURA = 56741, // Self
SPELL_PUTRID_MUSHROOM = 31690, // To make the mushrooms visible
};
enum Creatures
{
#define NPC_HEALTHY_MUSHROOM 30391
#define NPC_POISONOUS_MUSHROOM 30435
};
struct TRINITY_DLL_DECL boss_amanitarAI : public ScriptedAI
{
boss_amanitarAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
FirstTime = true;
}
ScriptedInstance* pInstance;
uint32 roottimer,
bashtimer,
bolttimer,
spawntimer;
bool FirstTime;
void Reset()
{
roottimer = urand(5000,9000);
bashtimer = urand(10000,14000);
bolttimer = urand(15000,30000);
spawntimer = 0;
m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
if (pInstance)
{
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI);
if (!FirstTime)
{
pInstance->SetData(DATA_AMANITAR_EVENT, FAIL);
}
else FirstTime = false;
}
}
void JustDied(Unit *Killer)
{
if (pInstance)
{
pInstance->SetData(DATA_AMANITAR_EVENT, DONE);
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI);
}
}
void EnterCombat(Unit *who)
{
if (pInstance)
pInstance->SetData(DATA_AMANITAR_EVENT, IN_PROGRESS);
DoCast(m_creature, SPELL_MINI, false);
}
void SpawnAdds()
{
for (uint8 i = 0; i < 30; ++i)
{
Unit* victim = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (victim)
{
Position pos;
victim->GetPosition(&pos);
m_creature->GetRandomNearPosition(pos, float(urand(5,80)));
m_creature->SummonCreature(NPC_POISONOUS_MUSHROOM, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
m_creature->GetRandomNearPosition(pos, float(urand(5,80)));
m_creature->SummonCreature(NPC_HEALTHY_MUSHROOM, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
}
}
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (spawntimer <= diff)
{
SpawnAdds();
spawntimer = urand(35000,40000);
} else spawntimer -= diff;
if (roottimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_ENTANGLING_ROOTS);
roottimer = urand(15000,30000);
}
if (bashtimer <= diff)
{
DoCastVictim(SPELL_BASH);
bashtimer = urand(15000,30000);
} else bashtimer -= diff;
if (bolttimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_VENOM_BOLT_VOLLEY);
bolttimer = urand(15000,30000);
} else bolttimer -= diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL mob_amanitar_mushroomsAI : public Scripted_NoMovementAI
{
mob_amanitar_mushroomsAI(Creature* c) : Scripted_NoMovementAI(c)
{
c->SetUInt32Value(UNIT_FIELD_DISPLAYID, 26981); // Unsichtbar...
}
uint32 auratimer,
deathtimer; // Without not all will despawn after 30000! :-(
void Reset()
{
DoCast(m_creature, SPELL_PUTRID_MUSHROOM, true); // Hack, to make the mushrooms visible, can't find orig. spell...
if (m_creature->GetEntry() == NPC_POISONOUS_MUSHROOM)
DoCast(m_creature, POISONOUS_MUSHROOM_SPELL_VISUAL_AURA, true);
auratimer = 0;
deathtimer = 30000;
}
void JustDied(Unit *killer)
{
if (!killer)
return;
if (m_creature->GetEntry() == NPC_HEALTHY_MUSHROOM && killer->GetTypeId() == TYPEID_PLAYER)
{
m_creature->InterruptNonMeleeSpells(false);
DoCast(killer, HEALTHY_MUSHROOM_SPELL_POTENT_FUNGUS, false);
}
}
void EnterCombat(Unit *who) {}
void AttackStart(Unit *victim) {}
void UpdateAI(const uint32 diff)
{
if (m_creature->GetEntry() == NPC_POISONOUS_MUSHROOM)
{
if (auratimer <= diff)
{
DoCast(m_creature, POISONOUS_MUSHROOM_SPELL_VISUAL_AREA, true);
DoCast(m_creature, POISONOUS_MUSHROOM_SPELL_POISON_CLOUD, false);
auratimer = 7000;
} else auratimer -= diff;
}
if (deathtimer <= diff)
{
m_creature->DisappearAndDie();
} else deathtimer -= diff;
}
};
CreatureAI* GetAI_boss_amanitar(Creature* pCreature)
{
return new boss_amanitarAI (pCreature);
}
CreatureAI* GetAI_mob_amanitar_mushrooms(Creature *pCreature)
{
return new mob_amanitar_mushroomsAI (pCreature);
}
void AddSC_boss_amanitar()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_amanitar";
newscript->GetAI = &GetAI_boss_amanitar;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_amanitar_mushrooms";
newscript->GetAI = &GetAI_mob_amanitar_mushrooms;
newscript->RegisterSelf();
}
@@ -0,0 +1,285 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_elder_nadox
SD%Complete: 100
SDComment:
SDCategory: Ahn'kahet
EndScriptData */
#include "ScriptedPch.h"
#include "ahnkahet.h"
bool DeadAhnkaharGuardian; // needed for achievement: Respect Your Elders(2038)
#define ACHIEVEMENT_RESPECT_YOUR_ELDERS 2038
//not in db
#define SAY_AGGRO -1619014
#define SAY_SLAY_1 -1619015
#define SAY_SLAY_2 -1619016
#define SAY_SLAY_3 -1619017
#define SAY_DEATH -1619018
#define SAY_EGG_SAC_1 -1619019
#define SAY_EGG_SAC_2 -1619020
#define SPELL_BROOD_PLAGUE 56130
#define H_SPELL_BROOD_PLAGUE 59467
#define H_SPELL_BROOD_RAGE 59465
#define SPELL_ENRAGE 26662// Enraged if too far away from home
#define MOB_AHNKAHAR_SWARMER 30178
#define SPELL_SUMMON_SWARMERS 56119//2x 30178 -- 2x every 10secs
#define MOB_AHNKAHAR_GUARDIAN_ENTRY 30176
#define SPELL_SUMMON_SWARM_GUARD 56120//1x 30176 -- every 25secs
#define SPELL_GUARDIAN_AURA 56151
#define EMOTE_HATCHES "An Ahn'kahar Guardian hatches!"
struct TRINITY_DLL_DECL boss_elder_nadoxAI : public ScriptedAI
{
boss_elder_nadoxAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 plague_Timer;
uint32 rage_Timer;
uint32 swarmer_spawn_Timer;
uint32 guard_spawn_Timer;
uint32 enrage_Timer;
ScriptedInstance *pInstance;
void Reset()
{
plague_Timer = 13000;
rage_Timer = 20000;
swarmer_spawn_Timer = 10000;
guard_spawn_Timer = 25000;
enrage_Timer = 5000;
DeadAhnkaharGuardian = false;
if (pInstance)
pInstance->SetData(DATA_ELDER_NADOX_EVENT, NOT_STARTED);
}
void EnterCombat(Unit *who)
{
DoScriptText(SAY_DEATH,m_creature);
if (pInstance)
pInstance->SetData(DATA_ELDER_NADOX_EVENT, IN_PROGRESS);
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_SLAY_3,m_creature); //SAY_SLAY_3 on death?
if (IsHeroic() && !DeadAhnkaharGuardian)
{
AchievementEntry const *AchievRespectYourElders = GetAchievementStore()->LookupEntry(ACHIEVEMENT_RESPECT_YOUR_ELDERS);
if (AchievRespectYourElders)
{
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievRespectYourElders);
}
}
}
if (pInstance)
pInstance->SetData(DATA_ELDER_NADOX_EVENT, DONE);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (plague_Timer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_BROOD_PLAGUE, H_SPELL_BROOD_PLAGUE));
plague_Timer = 15000;
} else plague_Timer -= diff;
if (IsHeroic())
if (rage_Timer <= diff)
{
Unit* Swarmer = m_creature->FindNearestCreature(MOB_AHNKAHAR_SWARMER, 35);
if (Swarmer)
{
DoCast(Swarmer, H_SPELL_BROOD_RAGE, true);
rage_Timer = 15000;
}
} else rage_Timer -= diff;
if (swarmer_spawn_Timer <= diff)
{
DoCast(m_creature, SPELL_SUMMON_SWARMERS, true);
DoCast(m_creature, SPELL_SUMMON_SWARMERS);
if (urand(1,3) == 3) // 33% chance of dialog
DoScriptText(RAND(SAY_EGG_SAC_1,SAY_EGG_SAC_2), m_creature);
swarmer_spawn_Timer = 10000;
} else swarmer_spawn_Timer -= diff;
if (guard_spawn_Timer <= diff)
{
m_creature->MonsterTextEmote(EMOTE_HATCHES,m_creature->GetGUID(),true);
DoCast(m_creature, SPELL_SUMMON_SWARM_GUARD);
guard_spawn_Timer = 25000;
} else guard_spawn_Timer -= diff;
if (enrage_Timer <= diff)
{
if (m_creature->HasAura(SPELL_ENRAGE,0))
return;
float x, y, z, o;
m_creature->GetHomePosition(x, y, z, o);
if (z < 24)
if (!m_creature->IsNonMeleeSpellCasted(false))
DoCast(m_creature, SPELL_ENRAGE, true);
enrage_Timer = 5000;
} else enrage_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_elder_nadox(Creature* pCreature)
{
return new boss_elder_nadoxAI(pCreature);
}
#define SPELL_SPRINT 56354
struct TRINITY_DLL_DECL mob_ahnkahar_nerubianAI : public ScriptedAI
{
mob_ahnkahar_nerubianAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance *pInstance;
uint32 sprint_Timer;
void Reset()
{
if (m_creature->GetEntry() == 30176) //magic numbers are bad!
DoCast(m_creature, SPELL_GUARDIAN_AURA, true);
sprint_Timer = 10000;
}
void JustDied(Unit *killer)
{
if (m_creature->GetEntry() == MOB_AHNKAHAR_GUARDIAN_ENTRY)
DeadAhnkaharGuardian = true;
}
void EnterCombat(Unit *who){}
void UpdateAI(const uint32 diff)
{
if (m_creature->GetEntry() == 30176) //magic numbers are bad!
m_creature->RemoveAurasDueToSpell(SPELL_GUARDIAN_AURA);
if (pInstance)
{
if (pInstance->GetData(DATA_ELDER_NADOX_EVENT) != IN_PROGRESS)
{
m_creature->DealDamage(m_creature,m_creature->GetHealth());
m_creature->RemoveCorpse();
}
}
if (!UpdateVictim())
return;
if (sprint_Timer <= diff)
{
DoCast(m_creature, SPELL_SPRINT);
sprint_Timer = 25000;
} else sprint_Timer -= diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL mob_nadox_eggsAI : public Scripted_NoMovementAI
{
mob_nadox_eggsAI(Creature* c) : Scripted_NoMovementAI(c)
{
c->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
c->UpdateAllStats();
}
void Reset() {}
void EnterCombat(Unit* who) {}
void AttackStart(Unit* victim) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
};
CreatureAI* GetAI_mob_ahnkahar_nerubian(Creature* pCreature)
{
return new mob_ahnkahar_nerubianAI(pCreature);
}
CreatureAI* GetAI_mob_nadox_eggs(Creature* _Creature)
{
return new mob_nadox_eggsAI(_Creature);
}
void AddSC_boss_elder_nadox()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_elder_nadox";
newscript->GetAI = &GetAI_boss_elder_nadox;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_ahnkahar_nerubian";
newscript->GetAI = &GetAI_mob_ahnkahar_nerubian;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_nadox_eggs";
newscript->GetAI = &GetAI_mob_nadox_eggs;
newscript->RegisterSelf();
}
@@ -0,0 +1,161 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_herald_volazj
SDAuthor: Tartalo
SD%Complete: 20
SDComment: Coded all but Insanity
SDCategory: Ahn'kahet
EndScriptData */
#include "ScriptedPch.h"
#include "ahnkahet.h"
enum Spells
{
SPELL_INSANITY = 57496, //Dummy
INSANITY_VISUAL = 57561,
SPELL_MIND_FLAY = 57941,
H_SPELL_MIND_FLAY = 59974,
SPELL_SHADOW_BOLT_VOLLEY = 57942,
H_SPELL_SHADOW_BOLT_VOLLEY = 59975,
SPELL_SHIVER = 57949,
H_SPELL_SHIVER = 59978
};
//not in db
enum Yells
{
SAY_AGGRO = -1619030,
SAY_SLAY_1 = -1619031,
SAY_SLAY_2 = -1619032,
SAY_SLAY_3 = -1619033,
SAY_DEATH_1 = -1619034,
SAY_DEATH_2 = -1619035,
SAY_PHASE = -1619036
};
enum Achievements
{
ACHIEVEMENT_QUICK_DEMISE = 1862
};
struct TRINITY_DLL_DECL boss_volazjAI : public ScriptedAI
{
boss_volazjAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
ScriptedInstance *pInstance;
uint32 uiMindFlayTimer;
uint32 uiShadowBoltVolleyTimer;
uint32 uiShiverTimer;
uint32 uiEncounterTimer;
void Reset()
{
uiEncounterTimer = 0;
uiMindFlayTimer = 8000;
uiShadowBoltVolleyTimer = 5000;
uiShiverTimer = 15000;
if (pInstance)
pInstance->SetData(DATA_HERALD_VOLAZJ, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_HERALD_VOLAZJ, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiMindFlayTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_MIND_FLAY, H_SPELL_MIND_FLAY));
uiMindFlayTimer = 20000;
} else uiMindFlayTimer -= diff;
if (uiShadowBoltVolleyTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_SHADOW_BOLT_VOLLEY, H_SPELL_SHADOW_BOLT_VOLLEY));
uiShadowBoltVolleyTimer = 5000;
} else uiShadowBoltVolleyTimer -= diff;
if (uiShiverTimer <= diff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_SHIVER, H_SPELL_SHIVER));
uiShiverTimer = 15000;
} else uiShiverTimer -= diff;
uiEncounterTimer += diff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH_1, m_creature);
if (pInstance)
pInstance->SetData(DATA_HERALD_VOLAZJ, DONE);
AchievementEntry const *AchievQuickDemise = GetAchievementStore()->LookupEntry(ACHIEVEMENT_QUICK_DEMISE);
Map* pMap = m_creature->GetMap();
if (IsHeroic() && uiEncounterTimer < 120000 && pMap && pMap->IsDungeon() && AchievQuickDemise)
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievQuickDemise);
}
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
};
CreatureAI* GetAI_boss_volazj(Creature* pCreature)
{
return new boss_volazjAI (pCreature);
}
void AddSC_boss_volazj()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_volazj";
newscript->GetAI = &GetAI_boss_volazj;
newscript->RegisterSelf();
}
@@ -0,0 +1,594 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_jedoga_shadowseeker
SDAuthor: WarHead
SD%Complete: 100%
SDComment: Complete - BUT THE TRIGGER NEEDS DATA WHETHER THE PRISON OF TALDARAM IS OFFLINE !
SDCategory: Ahn'kahet
EndScriptData */
#include "ScriptedPch.h"
#include "ahnkahet.h"
enum Yells
{
TEXT_AGGRO = -1619000,
TEXT_SACRIFICE_1_1 = -1619001,
TEXT_SACRIFICE_1_2 = -1619002,
TEXT_SACRIFICE_2_1 = -1619003,
TEXT_SACRIFICE_2_2 = -1619004,
TEXT_SLAY_1 = -1619005,
TEXT_SLAY_2 = -1619006,
TEXT_SLAY_3 = -1619007,
TEXT_DEATH = -1619008,
TEXT_PREACHING_1 = -1619009,
TEXT_PREACHING_2 = -1619010,
TEXT_PREACHING_3 = -1619011,
TEXT_PREACHING_4 = -1619012,
TEXT_PREACHING_5 = -1619013
};
enum Spells
{
SPELL_SPHERE_VISUAL = 56075,
SPELL_GIFT_OF_THE_HERALD = 56219,
SPELL_CYCLONE_STRIKE = 56855, // Self
SPELL_CYCLONE_STRIKE_H = 60030,
SPELL_LIGHTNING_BOLT = 56891, // 40Y
SPELL_LIGHTNING_BOLT_H = 60032, // 40Y
SPELL_THUNDERSHOCK = 56926, // 30Y
SPELL_THUNDERSHOCK_H = 60029 // 30Y
};
float JEDOGA_POS[2][4] =
{
{372.330994f, -705.278015f, -0.624178f, 5.427970f},
{372.330994f, -705.278015f, -16.179716f, 5.427970f}
};
struct TRINITY_DLL_DECL boss_jedoga_shadowseekerAI : public ScriptedAI
{
boss_jedoga_shadowseekerAI(Creature* c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
FirstTime = true;
predone = false;
}
ScriptedInstance* pInstance;
uint32 uiOpFerTimer,
uiCycloneTimer,
uiBoltTimer,
uiThunderTimer;
bool predone,
bOpFerok,
bOnGround,
bOpFerokFail,
bCanDown;
bool FirstTime;
void Reset()
{
uiOpFerTimer = urand(15000,20000);
uiCycloneTimer = 3000;
uiBoltTimer = 7000;
uiThunderTimer = 12000;
bOpFerok = false;
bOpFerokFail = false;
bOnGround = false;
bCanDown = false;
if (pInstance)
{
if (!FirstTime)
pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, FAIL);
pInstance->SetData64(DATA_PL_JEDOGA_TARGET, 0);
pInstance->SetData64(DATA_ADD_JEDOGA_OPFER, 0);
pInstance->SetData(DATA_JEDOGA_RESET_INITIANDS, 0);
}
MoveUp();
FirstTime = false;
}
void EnterCombat(Unit* who)
{
if (!pInstance || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == 30181))
return;
DoScriptText(TEXT_AGGRO, m_creature);
m_creature->SetInCombatWithZone();
pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, IN_PROGRESS);
}
void AttackStart(Unit* who)
{
if (!who || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == 30181))
return;
ScriptedAI::AttackStart(who);
}
void KilledUnit(Unit* Victim)
{
if (!Victim || Victim->GetTypeId() != TYPEID_PLAYER)
return;
DoScriptText(RAND(TEXT_SLAY_1, TEXT_SLAY_2, TEXT_SLAY_3), m_creature);
}
void JustDied(Unit* Killer)
{
DoScriptText(TEXT_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, DONE);
}
void MoveInLineOfSight(Unit* who)
{
if (!pInstance || !who || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == 30181))
return;
if (!predone && who->GetTypeId() == TYPEID_PLAYER && m_creature->GetDistance(who) < 100.0f)
{
DoScriptText(RAND(TEXT_PREACHING_1, TEXT_PREACHING_2, TEXT_PREACHING_3, TEXT_PREACHING_4, TEXT_PREACHING_5), m_creature);
predone = true;
}
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS || !bOnGround)
return;
if (!m_creature->getVictim() && who->isTargetableForAttack() && m_creature->IsHostileTo(who) && who->isInAccessiblePlaceFor(m_creature))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
{
if (!m_creature->getVictim())
{
who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
AttackStart(who);
}
else if (m_creature->GetMap()->IsDungeon())
{
who->SetInCombatWith(m_creature);
m_creature->AddThreat(who, 0.0f);
}
}
}
}
void MoveDown()
{
if (!pInstance)
return;
bOpFerokFail = false;
pInstance->SetData(DATA_JEDOGA_TRIGGER_SWITCH, 0);
m_creature->GetMotionMaster()->MovePoint(1, JEDOGA_POS[1][0], JEDOGA_POS[1][1], JEDOGA_POS[1][2]);
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
m_creature->SendMonsterMove(JEDOGA_POS[1][0], JEDOGA_POS[1][1], JEDOGA_POS[1][2], 0, MOVEFLAG_JUMP, 0);
m_creature->Relocate(JEDOGA_POS[1][0], JEDOGA_POS[1][1], JEDOGA_POS[1][2], JEDOGA_POS[1][3]);
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
m_creature->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
bOnGround = true;
if (UpdateVictim())
{
AttackStart(m_creature->getVictim());
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
}
else
{
if (Unit* pTarget = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_PL_JEDOGA_TARGET)))
{
AttackStart(pTarget);
pInstance->SetData(DATA_JEDOGA_RESET_INITIANDS, 0);
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS)
EnterCombat(pTarget);
}
else if (!m_creature->isInCombat())
EnterEvadeMode();
}
}
void MoveUp()
{
if (!pInstance)
return;
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
m_creature->AttackStop();
m_creature->RemoveAllAuras();
m_creature->LoadCreaturesAddon();
m_creature->GetMotionMaster()->MovePoint(0, JEDOGA_POS[0][0], JEDOGA_POS[0][1], JEDOGA_POS[0][2]);
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
m_creature->SendMonsterMove(JEDOGA_POS[0][0], JEDOGA_POS[0][1], JEDOGA_POS[0][2], 0, MOVEFLAG_JUMP, 0);
m_creature->Relocate(JEDOGA_POS[0][0], JEDOGA_POS[0][1], JEDOGA_POS[0][2], JEDOGA_POS[0][3]);
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveIdle();
m_creature->StopMoving();
pInstance->SetData(DATA_JEDOGA_TRIGGER_SWITCH, 1);
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) OpferRufen();
bOnGround = false;
uiOpFerTimer = urand(15000,30000);
}
void OpferRufen()
{
if (!pInstance)
return;
uint64 opfer = pInstance->GetData64(DATA_ADD_JEDOGA_INITIAND);
if (opfer)
{
DoScriptText(RAND(TEXT_SACRIFICE_1_1, TEXT_SACRIFICE_1_2), m_creature);
pInstance->SetData64(DATA_ADD_JEDOGA_OPFER, opfer);
} else
bCanDown = true;
}
void Opfern()
{
DoScriptText(RAND(TEXT_SACRIFICE_2_1, TEXT_SACRIFICE_2_2), m_creature);
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature, SPELL_GIFT_OF_THE_HERALD, false);
bOpFerok = false;
bCanDown = true;
}
void UpdateAI(const uint32 diff)
{
if (!pInstance)
return;
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS && pInstance->GetData(DATA_ALL_INITIAND_DEAD))
MoveDown();
if (bOpFerok && !bOnGround && !bCanDown) Opfern();
if (bOpFerokFail && !bOnGround && !bCanDown)
bCanDown = true;
if (bCanDown)
{
MoveDown();
bCanDown = false;
}
if (bOnGround)
{
if (!UpdateVictim())
return;
if (uiCycloneTimer <= diff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_CYCLONE_STRIKE, SPELL_CYCLONE_STRIKE_H), false);
uiCycloneTimer = urand(15000,30000);
} else uiCycloneTimer -= diff;
if (uiBoltTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
m_creature->CastSpell(pTarget, DUNGEON_MODE(SPELL_LIGHTNING_BOLT, SPELL_LIGHTNING_BOLT_H), false);
uiBoltTimer = urand(15000,30000);
} else uiBoltTimer -= diff;
if (uiThunderTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
m_creature->CastSpell(pTarget, DUNGEON_MODE(SPELL_THUNDERSHOCK, SPELL_THUNDERSHOCK_H), false);
uiThunderTimer = urand(15000,30000);
} else uiThunderTimer -= diff;
if (uiOpFerTimer <= diff)
MoveUp();
else
uiOpFerTimer -= diff;
DoMeleeAttackIfReady();
}
}
};
struct TRINITY_DLL_DECL mob_jedoga_initiandAI : public ScriptedAI
{
mob_jedoga_initiandAI(Creature* c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 checktimer;
bool walking;
void Reset()
{
if (!pInstance)
return;
walking = false;
checktimer = 2000;
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS)
{
m_creature->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
}
else
{
DoCast(m_creature, SPELL_SPHERE_VISUAL, false);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
}
}
void JustDied(Unit* Killer)
{
if (!Killer || !pInstance) return;
if (walking)
{
Creature* boss = m_creature->GetMap()->GetCreature(pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER));
if (boss && !CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok) CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = true;
if (Killer->GetTypeId() == TYPEID_PLAYER) pInstance->SetData(DATA_INITIAND_KILLED, 1);
pInstance->SetData64(DATA_ADD_JEDOGA_OPFER, 0);
walking = false;
}
if (Killer->GetTypeId() == TYPEID_PLAYER) pInstance->SetData64(DATA_PL_JEDOGA_TARGET, Killer->GetGUID());
}
void EnterCombat(Unit* who)
{
if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) return;
}
void AttackStart(Unit* victim)
{
if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !victim) return;
ScriptedAI::AttackStart(victim);
}
void MoveInLineOfSight(Unit* who)
{
if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) return;
ScriptedAI::MoveInLineOfSight(who);
}
void MovementInform(uint32 uiType, uint32 uiPointId)
{
if (uiType != POINT_MOTION_TYPE || !pInstance) return;
switch(uiPointId)
{
case 1:
{
Creature* boss = m_creature->GetMap()->GetCreature(pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER));
if (boss)
{
CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok = true;
CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = false;
m_creature->Kill(m_creature);
}
}
break;
}
}
void UpdateAI(const uint32 diff)
{
if (pInstance && checktimer <= diff)
{
if (m_creature->GetGUID() == pInstance->GetData64(DATA_ADD_JEDOGA_OPFER) && !walking)
{
m_creature->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
float distance = m_creature->GetDistance(JEDOGA_POS[1][0], JEDOGA_POS[1][1], JEDOGA_POS[1][2]);
if (distance < 9.0f)
m_creature->SetSpeed(MOVE_WALK, 0.5f, true);
else if (distance < 15.0f)
m_creature->SetSpeed(MOVE_WALK, 0.75f, true);
else if (distance < 20.0f)
m_creature->SetSpeed(MOVE_WALK, 1.0f, true);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MovePoint(1, JEDOGA_POS[1][0], JEDOGA_POS[1][1], JEDOGA_POS[1][2]);
walking = true;
}
if (!walking)
{
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS && m_creature->HasAura(SPELL_SPHERE_VISUAL))
{
m_creature->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
}
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS && !m_creature->HasAura(SPELL_SPHERE_VISUAL))
{
DoCast(m_creature, SPELL_SPHERE_VISUAL, false);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
}
}
checktimer = 2000;
} else checktimer -= diff;
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
// ------------------------------------------------------------------------------------------------------------
// Jedogas Aufseher - Entry: 30181
// ------------------------------------------------------------------------------------------------------------
enum AufseherSpell
{
SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_1 = 60342,
SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_2 = 56312
};
struct TRINITY_DLL_DECL npc_jedogas_aufseher_triggerAI : public Scripted_NoMovementAI
{
npc_jedogas_aufseher_triggerAI(Creature* c) : Scripted_NoMovementAI(c)
{
pInstance = c->GetInstanceData();
c->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
c->setFaction(35);
removed = false;
removed2 = false;
casted = false;
casted2 = false;
}
ScriptedInstance* pInstance;
bool removed,
removed2,
casted,
casted2;
void Reset() {}
void EnterCombat(Unit* who) {}
void AttackStart(Unit* victim) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
if (!pInstance)
return;
if (!removed && m_creature->GetPositionX() > 440.0f)
{ /* NEEDS DATA WHETHER THE PRISON OF TALDARAM IS OFFLINE !
if (pInstance->GetData(EVENT_VORRICHTUNGEN))
{
m_creature->InterruptNonMeleeSpells(true);
removed = true;
return;
}*/
if (pInstance->GetData(DATA_PRINCE_TALDARAM_EVENT) == DONE)
{
m_creature->InterruptNonMeleeSpells(true);
removed = true;
return;
}
if (!casted)
{
DoCast(m_creature, SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_1, false);
casted = true;
}
}
if (!removed2 && m_creature->GetPositionX() < 440.0f)
{
if (!casted2 && pInstance->GetData(DATA_JEDOGA_TRIGGER_SWITCH))
{
DoCast(m_creature, SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_2, false);
casted2 = true;
}
if (casted2 && !pInstance->GetData(DATA_JEDOGA_TRIGGER_SWITCH))
{
m_creature->InterruptNonMeleeSpells(true);
casted2 = false;
}
if (!removed2 && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == DONE)
{
m_creature->InterruptNonMeleeSpells(true);
removed2 = true;
}
}
}
};
CreatureAI* GetAI_boss_jedoga_shadowseeker(Creature* pCreature)
{
return new boss_jedoga_shadowseekerAI (pCreature);
}
CreatureAI* GetAI_mob_jedoga_initiand(Creature* pCreature)
{
return new mob_jedoga_initiandAI (pCreature);
}
CreatureAI* GetAI_npc_jedogas_aufseher_trigger(Creature* pCreature)
{
return new npc_jedogas_aufseher_triggerAI (pCreature);
}
void AddSC_boss_jedoga_shadowseeker()
{
Script* newscript;
newscript = new Script;
newscript->Name = "boss_jedoga_shadowseeker";
newscript->GetAI = &GetAI_boss_jedoga_shadowseeker;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_jedoga_initiand";
newscript->GetAI = &GetAI_mob_jedoga_initiand;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_jedogas_aufseher_trigger";
newscript->GetAI = &GetAI_npc_jedogas_aufseher_trigger;
newscript->RegisterSelf();
}
@@ -0,0 +1,417 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_prince_taldaram
SDAuthor: Tartalo & tlexii
SD%Complete: 0
SDComment:
SDCategory: Ahn'kahet
EndScriptData */
#include "ScriptedPch.h"
#include "ahnkahet.h"
enum Spells
{
SPELL_BLOODTHIRST = 55968, //Trigger Spell + add aura
SPELL_CONJURE_FLAME_SPHERE = 55931,
SPELL_FLAME_SPHERE_SUMMON_1 = 55895,// 1x 30106
H_SPELL_FLAME_SPHERE_SUMMON_1 = 59511,// 1x 31686
H_SPELL_FLAME_SPHERE_SUMMON_2 = 59512,// 1x 31687
SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891,
SPELL_FLAME_SPHERE_VISUAL = 55928,
SPELL_FLAME_SPHERE_PERIODIC = 55926,
H_SPELL_FLAME_SPHERE_PERIODIC = 59508,
SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947,
SPELL_BEAM_VISUAL = 60342,
SPELL_EMBRACE_OF_THE_VAMPYR = 55959,
H_SPELL_EMBRACE_OF_THE_VAMPYR = 59513,
SPELL_VANISH = 55964,
CREATURE_FLAME_SPHERE = 30106,
H_CREATURE_FLAME_SPHERE_1 = 31686,
H_CREATURE_FLAME_SPHERE_2 = 31687
};
enum Misc
{
DATA_EMBRACE_DMG = 20000,
H_DATA_EMBRACE_DMG = 40000,
DATA_SPHERE_DISTANCE = 15
};
#define DATA_SPHERE_ANGLE_OFFSET 0.7
#define DATA_GROUND_POSITION_Z 11.4
enum Achievements
{
ACHIEVEMENT_THE_PARTY_IS_OVER = 1861
};
enum Yells
{
SAY_AGGRO = -1619021,
SAY_SLAY_1 = -1619022,
SAY_SLAY_2 = -1619023,
SAY_DEATH = -1619024,
SAY_FEED_1 = -1619025,
SAY_FEED_2 = -1619026,
SAY_VANISH_1 = -1619027,
SAY_VANISH_2 = -1619028
};
enum CombatPhase
{
NORMAL,
CASTING_FLAME_SPHERES,
JUST_VANISHED,
VANISHED,
FEEDING
};
struct TRINITY_DLL_DECL boss_taldaramAI : public ScriptedAI
{
boss_taldaramAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
uint32 uiBloodthirstTimer;
uint32 uiVanishTimer;
uint32 uiWaitTimer;
uint32 uiEmbraceTimer;
uint32 uiEmbraceTakenDamage;
uint32 uiFlamesphereTimer;
uint32 uiPhaseTimer;
uint64 uiSphereGuids[2];
Unit *pEmbraceTarget;
Unit *pSphereTarget;
Creature* pSpheres[3];
CombatPhase Phase;
ScriptedInstance* pInstance;
void Reset()
{
uiBloodthirstTimer = 10000;
uiVanishTimer = (25 + rand()%10)*1000;
uiEmbraceTimer = 20000;
uiFlamesphereTimer = 5000;
uiEmbraceTakenDamage = 0;
Phase = NORMAL;
uiPhaseTimer = 0;
pEmbraceTarget = NULL;
if (pInstance)
pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
if (pInstance)
pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, IN_PROGRESS);
DoScriptText(SAY_AGGRO, m_creature);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (uiPhaseTimer <= diff)
{
switch (Phase)
{
case CASTING_FLAME_SPHERES:
//DoCast(m_creature, SPELL_FLAME_SPHERE_SUMMON_1);
pSpheres[0] = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
pSphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
if (pSphereTarget && pSpheres[0])
{
float angle,x,y;
angle = pSpheres[0]->GetAngle(pSphereTarget);
x = pSpheres[0]->GetPositionX() + DATA_SPHERE_DISTANCE * cos(angle);
y = pSpheres[0]->GetPositionY() + DATA_SPHERE_DISTANCE * sin(angle);
pSpheres[0]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[0]->GetPositionZ());
}
if (IsHeroic())
{
//DoCast(m_creature, H_SPELL_FLAME_SPHERE_SUMMON_1);
pSpheres[1] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
//DoCast(m_creature, H_SPELL_FLAME_SPHERE_SUMMON_2);
pSpheres[2] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
if (pSphereTarget && pSpheres[1] && pSpheres[2])
{
float angle,x,y;
angle = pSpheres[1]->GetAngle(pSphereTarget) + DATA_SPHERE_ANGLE_OFFSET;
x = pSpheres[1]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * cos(angle);
y = pSpheres[1]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * sin(angle);
pSpheres[1]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[1]->GetPositionZ());
angle = pSpheres[2]->GetAngle(pSphereTarget) - DATA_SPHERE_ANGLE_OFFSET;
x = pSpheres[2]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * cos(angle);
y = pSpheres[2]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * sin(angle);
pSpheres[2]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[2]->GetPositionZ());
}
}
Phase = NORMAL;
uiPhaseTimer = 0;
break;
case JUST_VANISHED:
if(pEmbraceTarget)
{
m_creature->GetMotionMaster()->Clear();
m_creature->SetSpeed(MOVE_WALK, 2.0f, true);
m_creature->GetMotionMaster()->MoveChase(pEmbraceTarget);
}
Phase = VANISHED;
uiPhaseTimer = 1300;
break;
case VANISHED:
if(pEmbraceTarget)
DoCast(pEmbraceTarget, DUNGEON_MODE(SPELL_EMBRACE_OF_THE_VAMPYR, H_SPELL_EMBRACE_OF_THE_VAMPYR));
m_creature->GetMotionMaster()->Clear();
m_creature->SetSpeed(MOVE_WALK, 1.0f, true);
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
Phase = FEEDING;
uiPhaseTimer = 20000;
break;
case FEEDING:
Phase = NORMAL;
uiPhaseTimer = 0;
pEmbraceTarget = NULL;
break;
case NORMAL:
if (uiBloodthirstTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_BLOODTHIRST);
uiBloodthirstTimer = 10000;
} else uiBloodthirstTimer -= diff;
if (uiFlamesphereTimer <= diff)
{
DoCast(m_creature, SPELL_CONJURE_FLAME_SPHERE);
Phase = CASTING_FLAME_SPHERES;
uiPhaseTimer = 3000 + diff;
uiFlamesphereTimer = 15000;
} else uiFlamesphereTimer -= diff;
if (uiVanishTimer <= diff)
{
//Count alive players
Unit *pTarget = NULL;
std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
std::vector<Unit *> target_list;
for (std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
pTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
// exclude pets & totems
if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive())
target_list.push_back(pTarget);
pTarget = NULL;
}
//He only vanishes if there are 3 or more alive players
if (target_list.size() > 2)
{
DoScriptText(RAND(SAY_VANISH_1,SAY_VANISH_2), m_creature);
DoCast(m_creature, SPELL_VANISH);
Phase = JUST_VANISHED;
uiPhaseTimer = 500;
pEmbraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
}
uiVanishTimer = urand(25000,35000);
} else uiVanishTimer -= diff;
DoMeleeAttackIfReady();
break;
}
} else uiPhaseTimer -= diff;
}
void DamageTaken(Unit* done_by, uint32 &damage)
{
if (Phase == FEEDING && pEmbraceTarget && pEmbraceTarget->isAlive())
{
uiEmbraceTakenDamage += damage;
if (uiEmbraceTakenDamage > DUNGEON_MODE(DATA_EMBRACE_DMG, H_DATA_EMBRACE_DMG))
{
Phase = NORMAL;
uiPhaseTimer = 0;
pEmbraceTarget = NULL;
m_creature->CastStop();
}
}
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
{
pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, DONE);
//The Party's Over achievement:
AchievementEntry const *AchievThePartyIsOver = GetAchievementStore()->LookupEntry(ACHIEVEMENT_THE_PARTY_IS_OVER);
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon() && IsHeroic() && AchievThePartyIsOver)
{
Map::PlayerList const &players = pMap->GetPlayers();
if (players.getSize() < 5)
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievThePartyIsOver);
}
}
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
if (Phase == FEEDING && pEmbraceTarget && victim == pEmbraceTarget)
{
Phase = NORMAL;
uiPhaseTimer = 0;
pEmbraceTarget = NULL;
}
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
}
bool CheckSpheres()
{
if(!pInstance)
return false;
uiSphereGuids[0] = pInstance->GetData64(DATA_SPHERE1);
uiSphereGuids[1] = pInstance->GetData64(DATA_SPHERE2);
GameObject *pSpheres[2];
for (uint8 i=0; i < 2; ++i)
{
pSpheres[i] = pInstance->instance->GetGameObject(uiSphereGuids[i]);
if (!pSpheres[i])
return false;
if (pSpheres[i]->GetGoState() != GO_STATE_ACTIVE)
return false;
}
RemovePrison();
return true;
}
void RemovePrison()
{
if(!pInstance)
return;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->RemoveAurasDueToSpell(SPELL_BEAM_VISUAL);
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
m_creature->SetHomePosition(m_creature->GetPositionX(), m_creature->GetPositionY(), DATA_GROUND_POSITION_Z, m_creature->GetOrientation());
uint64 prison_GUID = pInstance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM);
pInstance->HandleGameObject(prison_GUID,true);
}
};
struct TRINITY_DLL_DECL mob_taldaram_flamesphereAI : public ScriptedAI
{
mob_taldaram_flamesphereAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 uiDespawnTimer;
ScriptedInstance* pInstance;
void Reset()
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
m_creature->setFaction(16);
m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
DoCast(m_creature, SPELL_FLAME_SPHERE_VISUAL);
DoCast(m_creature, SPELL_FLAME_SPHERE_SPAWN_EFFECT);
DoCast(m_creature, DUNGEON_MODE(SPELL_FLAME_SPHERE_PERIODIC, H_SPELL_FLAME_SPHERE_PERIODIC));
uiDespawnTimer = 10000;
}
void EnterCombat(Unit *who) {}
void MoveInLineOfSight(Unit *who) {}
void JustDied(Unit* slayer)
{
DoCast(m_creature, SPELL_FLAME_SPHERE_DEATH_EFFECT);
}
void UpdateAI(const uint32 diff)
{
if (uiDespawnTimer <= diff)
m_creature->DisappearAndDie();
else
uiDespawnTimer -= diff;
}
};
CreatureAI* GetAI_boss_taldaram(Creature* pCreature)
{
return new boss_taldaramAI (pCreature);
}
CreatureAI* GetAI_mob_taldaram_flamesphere(Creature* pCreature)
{
return new mob_taldaram_flamesphereAI (pCreature);
}
bool GOHello_prince_taldaram_sphere(Player *pPlayer, GameObject *pGO)
{
ScriptedInstance *pInstance = pGO->GetInstanceData();
Creature *pPrinceTaldaram = Unit::GetCreature(*pGO, pInstance ? pInstance->GetData64(DATA_PRINCE_TALDARAM) : 0);
if (pPrinceTaldaram && pPrinceTaldaram->isAlive())
{
// maybe these are hacks :(
pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
pGO->SetGoState(GO_STATE_ACTIVE);
switch(pGO->GetEntry())
{
case 193093: pInstance->SetData(DATA_SPHERE1_EVENT,IN_PROGRESS); break;
case 193094: pInstance->SetData(DATA_SPHERE2_EVENT,IN_PROGRESS); break;
}
CAST_AI(boss_taldaramAI, pPrinceTaldaram->AI())->CheckSpheres();
}
return true;
}
void AddSC_boss_taldaram()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_taldaram";
newscript->GetAI = &GetAI_boss_taldaram;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_taldaram_flamesphere";
newscript->GetAI = &GetAI_mob_taldaram_flamesphere;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "prince_taldaram_sphere";
newscript->pGOHello = &GOHello_prince_taldaram_sphere;
newscript->RegisterSelf();
}
@@ -0,0 +1,318 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance_Azjol_Nerub
SD%Complete: 0
SDComment:
SDCategory: Azjol Nerub
EndScriptData */
#include "ScriptedPch.h"
#include "ahnkahet.h"
#define MAX_ENCOUNTER 5
#define MAX_JEDOGA_INITIANDS 15
#define AchievementVolunteerWork 2056
/* Ahn'kahet encounters:
0 - Elder Nadox
1 - Prince Taldaram
2 - Jedoga Shadowseeker
3 - Herald Volazj
4 - Amanitar (Heroic only)
*/
struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance
{
instance_ahnkahet(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
uint64 Elder_Nadox;
uint64 Prince_Taldaram;
uint64 Jedoga_Shadowseeker;
uint64 Herald_Volazj;
uint64 Amanitar;
uint64 Prince_TaldaramSpheres[2];
uint64 Prince_TaldaramPlatform;
uint64 Prince_TaldaramGate;
std::set<uint64> InitiandGUIDs;
uint64 JedogaSacrifices;
uint64 JedogaTarget;
uint32 m_auiEncounter[MAX_ENCOUNTER];
uint32 spheres[2];
uint8 InitiandCnt,
switchtrigger,
initiandkilled;
std::string str_data;
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
InitiandGUIDs.clear();
Elder_Nadox =0;
Prince_Taldaram =0;
Jedoga_Shadowseeker =0;
Herald_Volazj =0;
Amanitar =0;
spheres[0] = NOT_STARTED;
spheres[1] = NOT_STARTED;
InitiandCnt = 0;
switchtrigger = 0;
initiandkilled = 0;
JedogaSacrifices = 0;
JedogaTarget = 0;
}
bool IsEncounterInProgress() const
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
return false;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case 29309: Elder_Nadox = pCreature->GetGUID(); break;
case 29308: Prince_Taldaram = pCreature->GetGUID(); break;
case 29310: Jedoga_Shadowseeker = pCreature->GetGUID(); break;
case 29311: Herald_Volazj = pCreature->GetGUID(); break;
case 30258: Amanitar = pCreature->GetGUID(); break;
case 30114: InitiandGUIDs.insert(pCreature->GetGUID()); break;
}
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch(pGo->GetEntry())
{
case 193564: Prince_TaldaramPlatform = pGo->GetGUID();
if (m_auiEncounter[1] == DONE) HandleGameObject(NULL,true,pGo); break;
case 193093: Prince_TaldaramSpheres[0] = pGo->GetGUID();
if (spheres[0] == IN_PROGRESS)
{
pGo->SetGoState(GO_STATE_ACTIVE);
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
}
else pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
break;
case 193094: Prince_TaldaramSpheres[1] = pGo->GetGUID();
if (spheres[1] == IN_PROGRESS)
{
pGo->SetGoState(GO_STATE_ACTIVE);
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
}
else pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
break;
case 192236: Prince_TaldaramGate = pGo->GetGUID(); // Web gate past Prince Taldaram
if (m_auiEncounter[1] == DONE)HandleGameObject(NULL,true,pGo);break;
}
}
void SetData64(uint32 idx, uint64 guid)
{
switch(idx)
{
case DATA_ADD_JEDOGA_OPFER: JedogaSacrifices = guid; break;
case DATA_PL_JEDOGA_TARGET: JedogaTarget = guid; break;
}
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_ELDER_NADOX: return Elder_Nadox;
case DATA_PRINCE_TALDARAM: return Prince_Taldaram;
case DATA_JEDOGA_SHADOWSEEKER: return Jedoga_Shadowseeker;
case DATA_HERALD_VOLAZJ: return Herald_Volazj;
case DATA_AMANITAR: return Amanitar;
case DATA_SPHERE1: return Prince_TaldaramSpheres[0];
case DATA_SPHERE2: return Prince_TaldaramSpheres[1];
case DATA_PRINCE_TALDARAM_PLATFORM: return Prince_TaldaramPlatform;
case DATA_ADD_JEDOGA_INITIAND:
{
std::vector<uint64> vInitiands;
vInitiands.clear();
for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
{
Creature* cr = instance->GetCreature(*itr);
if (cr && cr->isAlive())
vInitiands.push_back(*itr);
}
if (vInitiands.empty())
return 0;
uint8 j = urand(0,vInitiands.size() -1);
return vInitiands[j];
}
case DATA_ADD_JEDOGA_OPFER: return JedogaSacrifices;
case DATA_PL_JEDOGA_TARGET: return JedogaTarget;
}
return 0;
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_ELDER_NADOX_EVENT: m_auiEncounter[0] = data; break;
case DATA_PRINCE_TALDARAM_EVENT:
if (data == DONE)
HandleGameObject(Prince_TaldaramGate,true);
m_auiEncounter[1] = data;
break;
case DATA_JEDOGA_SHADOWSEEKER_EVENT:
m_auiEncounter[2] = data;
if (data == DONE)
{
for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
{
Creature* cr = instance->GetCreature(*itr);
if (cr && cr->isAlive())
{
cr->SetVisibility(VISIBILITY_OFF);
cr->setDeathState(JUST_DIED);
cr->RemoveCorpse();
}
}
if (!initiandkilled && instance->IsHeroic())
DoCompleteAchievement(AchievementVolunteerWork);
}
break;
case DATA_HERALD_VOLAZJ: m_auiEncounter[3] = data; break;
case DATA_AMANITAR: m_auiEncounter[4] = data; break;
case DATA_SPHERE1_EVENT: spheres[0] = data; break;
case DATA_SPHERE2_EVENT: spheres[1] = data; break;
case DATA_JEDOGA_TRIGGER_SWITCH: switchtrigger = data; break;
case DATA_INITIAND_KILLED: initiandkilled = data; break;
case DATA_JEDOGA_RESET_INITIANDS:
for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
{
Creature* cr = instance->GetCreature(*itr);
if (cr)
{
cr->Respawn();
if (!cr->IsInEvadeMode()) cr->AI()->EnterEvadeMode();
}
}
break;
}
if (data == DONE)
SaveToDB();
}
uint32 GetData(uint32 type)
{
switch(type)
{
case DATA_ELDER_NADOX_EVENT: return m_auiEncounter[0];
case DATA_PRINCE_TALDARAM_EVENT: return m_auiEncounter[1];
case DATA_JEDOGA_SHADOWSEEKER_EVENT: return m_auiEncounter[2];
case DATA_HERALD_VOLAZJ: return m_auiEncounter[3];
case DATA_AMANITAR: return m_auiEncounter[4];
case DATA_SPHERE1_EVENT: return spheres[0];
case DATA_SPHERE2_EVENT: return spheres[1];
case DATA_ALL_INITIAND_DEAD:
for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
{
Creature* cr = instance->GetCreature(*itr);
if (!cr || (cr && cr->isAlive())) return 0;
}
return 1;
case DATA_JEDOGA_TRIGGER_SWITCH: return switchtrigger;
case DATA_INITIAND_KILLED: return initiandkilled;
}
return 0;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "A K " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
<< m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " "
<< spheres[0] << " " << spheres[1];
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in)
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3, data4, data5, data6;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5 >> data6;
if (dataHead1 == 'A' && dataHead2 == 'K')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
m_auiEncounter[3] = data3;
m_auiEncounter[4] = data4;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
spheres[0] = data5;
spheres[1] = data6;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_ahnkahet(Map* pMap)
{
return new instance_ahnkahet(pMap);
}
void AddSC_instance_ahnkahet()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_ahnkahet";
newscript->GetInstanceData = &GetInstanceData_instance_ahnkahet;
newscript->RegisterSelf();
}
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DEF_AZJOL_NERUB_H
#define DEF_AZJOL_NERUB_H
enum Data64
{
DATA_KRIKTHIR_THE_GATEWATCHER,
DATA_HADRONOX,
DATA_ANUBARAK,
DATA_WATCHER_GASHRA,
DATA_WATCHER_SILTHIK,
DATA_WATCHER_NARJIL
};
enum Data
{
DATA_KRIKTHIR_THE_GATEWATCHER_EVENT,
DATA_HADRONOX_EVENT,
DATA_ANUBARAK_EVENT
};
#endif
@@ -0,0 +1,289 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_anubarak
SD%Complete: 90 %
SDComment: Says are not implemented.
SDCategory: Azjol Nerub
EndScriptData */
#include "ScriptedPch.h"
#include "azjol_nerub.h"
enum Spells
{
SPELL_CARRION_BEETLES = 53520,
SPELL_SUMMON_CARRION_BEETLES = 53521,
SPELL_LEECHING_SWARM = 53467,
SPELL_IMPALE = 53454,
H_SPELL_IMPALE = 59446,
SPELL_POUND = 53472,
H_SPELL_POUND = 59433,
SPELL_SUBMERGE = 53421,
};
enum Creatures
{
CREATURE_GUARDIAN = 29216,
CREATURE_VENOMANCER = 29217,
CREATURE_DATTER = 29213
};
// not in db
enum Yells
{
SAY_INTRO = -1601010,
SAY_AGGRO = -1601000,
SAY_SLAY_1 = -1601001,
SAY_SLAY_2 = -1601002,
SAY_SLAY_3 = -1601003,
SAY_LOCUST_1 = -1601005,
SAY_LOCUST_2 = -1601006,
SAY_LOCUST_3 = -1601007,
SAY_SUBMERGE_1 = -1601008,
SAY_SUBMERGE_2 = -1601009,
SAY_DEATH = -1601004
};
#define SPAWNPOINT_Z 224.3
float SpawnPoint[2][2] =
{
{550.7, 282.8},
{551.1, 229.4},
};
struct TRINITY_DLL_DECL boss_anub_arakAI : public ScriptedAI
{
boss_anub_arakAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance *pInstance;
bool Channeling;
bool HeroicMode;
bool Summoned_Guardian;
bool Summoned_Venomancer;
bool Summoned_Datter;
uint32 Phase;
uint32 Phase_Time;
uint32 SPELL_CARRION_BEETLES_Timer;
uint32 SPELL_LEECHING_SWARM_Timer;
uint32 SPELL_IMPALE_Timer;
uint32 SPELL_POUND_Timer;
uint32 SPELL_SUBMERGE_Timer;
uint32 UNDERGROUND_Timer;
uint32 VENOMANCER_Timer;
uint32 DATTER_Timer;
void Reset()
{
SPELL_CARRION_BEETLES_Timer = 8000;
SPELL_LEECHING_SWARM_Timer = 20000;
SPELL_IMPALE_Timer = 9000;
SPELL_POUND_Timer = 15000;
Phase = 0;
Phase_Time = 0;
Channeling = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
m_creature->RemoveAura(SPELL_SUBMERGE);
if (pInstance)
pInstance->SetData(DATA_ANUBARAK_EVENT, NOT_STARTED);
}
void EnterCombat(Unit *pWho)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_ANUBARAK_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (Channeling == true)
{
for (uint8 i = 0; i < 4; ++i)
DoCast(m_creature->getVictim(), SPELL_SUMMON_CARRION_BEETLES, true);
Channeling = false;
}
if (Phase == 1)
{
if (SPELL_IMPALE_Timer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
m_creature->CastSpell(pTarget, DUNGEON_MODE(SPELL_IMPALE,H_SPELL_IMPALE), true);
SPELL_IMPALE_Timer = 9000;
} else SPELL_IMPALE_Timer -= diff;
if (!Summoned_Guardian)
{
for (uint8 i = 0; i < 2; ++i)
{
if (Creature *Guardian = m_creature->SummonCreature(CREATURE_GUARDIAN,SpawnPoint[i][0],SpawnPoint[i][1],SPAWNPOINT_Z,0,TEMPSUMMON_CORPSE_DESPAWN,0))
{
Guardian->AddThreat(m_creature->getVictim(), 0.0f);
DoZoneInCombat(Guardian);
}
}
Summoned_Guardian = true;
}
if(!Summoned_Venomancer)
{
if (VENOMANCER_Timer <= diff)
{
if (Phase_Time > 1)
{
for (uint8 i = 0; i < 2; ++i)
{
if (Creature *Venomancer = m_creature->SummonCreature(CREATURE_VENOMANCER,SpawnPoint[i][0],SpawnPoint[i][1],SPAWNPOINT_Z,0,TEMPSUMMON_CORPSE_DESPAWN,0))
{
Venomancer->AddThreat(m_creature->getVictim(), 0.0f);
DoZoneInCombat(Venomancer);
}
}
Summoned_Venomancer = true;
}
} else VENOMANCER_Timer -= diff;
}
if(!Summoned_Datter)
{
if (DATTER_Timer <= diff)
{
if (Phase_Time > 2)
{
for (uint8 i = 0; i < 2; ++i)
{
if (Creature *Datter = m_creature->SummonCreature(CREATURE_DATTER,SpawnPoint[i][0],SpawnPoint[i][1],SPAWNPOINT_Z,0,TEMPSUMMON_CORPSE_DESPAWN,0))
{
Datter->AddThreat(m_creature->getVictim(), 0.0f);
DoZoneInCombat(Datter);
}
}
Summoned_Datter = true;
}
} else DATTER_Timer -= diff;
}
if (UNDERGROUND_Timer <= diff)
{
m_creature->RemoveAura(SPELL_SUBMERGE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
Phase = 0;
} else UNDERGROUND_Timer -= diff;
}
if (Phase == 0)
{
if (SPELL_LEECHING_SWARM_Timer <= diff)
{
DoCast(m_creature, SPELL_LEECHING_SWARM, true);
SPELL_LEECHING_SWARM_Timer = 19000;
} else SPELL_LEECHING_SWARM_Timer -= diff;
if (SPELL_CARRION_BEETLES_Timer <= diff)
{
Channeling = true;
DoCastVictim(SPELL_CARRION_BEETLES);
SPELL_CARRION_BEETLES_Timer = 25000;
} else SPELL_CARRION_BEETLES_Timer -= diff;
if (SPELL_POUND_Timer <= diff)
{
DoCastVictim(DUNGEON_MODE(SPELL_POUND, H_SPELL_POUND));
SPELL_POUND_Timer = 16500;
} else SPELL_POUND_Timer -= diff;
}
if ((Phase_Time == 0 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 75)
|| (Phase_Time == 1 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50)
|| (Phase_Time == 2 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 25))
{
++Phase_Time;
Summoned_Guardian = false;
Summoned_Venomancer = false;
Summoned_Datter = false;
UNDERGROUND_Timer = 40000;
VENOMANCER_Timer = 25000;
DATTER_Timer = 32000;
DoCast(m_creature, SPELL_SUBMERGE, false);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
Phase = 1;
}
if (Phase != 1)
DoMeleeAttackIfReady();
}
void JustDied(Unit *pKiller)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_ANUBARAK_EVENT, DONE);
}
void KilledUnit(Unit *pVictim)
{
if (pVictim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
};
CreatureAI* GetAI_boss_anub_arak(Creature *pCreature)
{
return new boss_anub_arakAI (pCreature);
}
void AddSC_boss_anub_arak()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_anub_arak";
newscript->GetAI = &GetAI_boss_anub_arak;
newscript->RegisterSelf();
}
@@ -0,0 +1,213 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: Boss hadronox
SDAuthor: WarHead
SD%Complete: 50
SDComment: No Waves atm and the doors spells are crazy...
SDCategory:
Script Data End */
//Phase 0 => Gauntlet Event described below
//Phase 1 => Boss Encounter
/*When your group enters the main room (the one after the bridge), you will notice a group of 3 Nerubians.
When you engage them, 2 more groups like this one spawn behind the first one - it is important to pull the first group back,
so you don't aggro all 3. Hadronox will be under you, fighting Nerubians.
This is the timed gauntlet - waves of non-elite spiders
will spawn from the 3 doors located a little above the main room, and will then head down to fight Hadronox. After clearing the
main room, it is recommended to just stay in it, kill the occasional non-elites that will attack you instead of the boss, and wait for
Hadronox to make his way to you. When Hadronox enters the main room, she will web the doors, and no more non-elites will spawn.*/
#include "ScriptedPch.h"
#include "azjol_nerub.h"
#define SPELL_ACID_CLOUD 53400 // Victim
#define SPELL_LEECH_POISON 53030 // Victim
#define SPELL_PIERCE_ARMOR 53418 // Victim
#define SPELL_WEB_GRAB 57731 // Victim
#define SPELL_WEB_FRONT_DOORS 53177 // Self
#define SPELL_WEB_SIDE_DOORS 53185 // Self
#define SPELL_ACID_CLOUD_H 59419
#define SPELL_LEECH_POISON_H 59417
#define SPELL_WEB_GRAB_H 59421
struct TRINITY_DLL_DECL boss_hadronoxAI : public ScriptedAI
{
boss_hadronoxAI(Creature* c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
MaxDistance = 50.0f;
FirstTime = true;
}
ScriptedInstance* pInstance;
uint32 acidtimer,
leechtimer,
piercetimer,
grabtimer,
doorstimer,
CheckDistanceTimer;
bool FirstTime;
float MaxDistance;
void Reset()
{
m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 9.0f);
m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 9.0f);
acidtimer = urand(10000,14000);
leechtimer = urand(3000,9000);
piercetimer = urand(1000,3000);
grabtimer = urand(15000,19000);
doorstimer = urand(20000,30000);
CheckDistanceTimer = 2000;
if (pInstance && (pInstance->GetData(DATA_HADRONOX_EVENT) != DONE && !FirstTime))
pInstance->SetData(DATA_HADRONOX_EVENT, FAIL);
FirstTime = false;
}
//when Hadronox kills any enemy (that includes a party member) she will regain 10% of her HP if the target had Leech Poison on
void KilledUnit(Unit* Victim)
{
// not sure if this aura check is correct, I think it is though
if (!Victim || !Victim->HasAura(DUNGEON_MODE(SPELL_LEECH_POISON, SPELL_LEECH_POISON_H)) || !m_creature->isAlive())
return;
uint32 health = (m_creature->GetMaxHealth()/100)*10;
if ((m_creature->GetHealth()+health) >= m_creature->GetMaxHealth())
m_creature->SetHealth(m_creature->GetMaxHealth());
else
m_creature->SetHealth(m_creature->GetHealth()+health);
}
void JustDied(Unit* Killer)
{
if (pInstance)
pInstance->SetData(DATA_HADRONOX_EVENT, DONE);
}
void EnterCombat(Unit* who)
{
if (pInstance)
pInstance->SetData(DATA_HADRONOX_EVENT, IN_PROGRESS);
m_creature->SetInCombatWithZone();
}
void CheckDistance(float dist, const uint32 uiDiff)
{
if (!m_creature->isInCombat())
return;
float x=0.0f, y=0.0f, z=0.0f;
m_creature->GetRespawnCoord(x,y,z);
if (CheckDistanceTimer <= uiDiff)
CheckDistanceTimer = 5000;
else
{
CheckDistanceTimer -= uiDiff;
return;
}
if (m_creature->IsInEvadeMode() || !m_creature->getVictim())
return;
if (m_creature->GetDistance(x,y,z) > dist)
EnterEvadeMode();
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim()) return;
// Without he comes up through the air to players on the bridge after krikthir if players crossing this bridge!
CheckDistance(MaxDistance, diff);
if (m_creature->HasAura(SPELL_WEB_FRONT_DOORS) || m_creature->HasAura(SPELL_WEB_SIDE_DOORS))
{
if (IsCombatMovement())
SetCombatMovement(false);
}
else if (!IsCombatMovement())
SetCombatMovement(true);
if (piercetimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_PIERCE_ARMOR);
piercetimer = 8000;
} else piercetimer -= diff;
if (acidtimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_ACID_CLOUD, SPELL_ACID_CLOUD_H));
acidtimer = urand(20000,30000);
} else acidtimer -= diff;
if (leechtimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_LEECH_POISON, SPELL_LEECH_POISON_H));
leechtimer = urand(11000,14000);
} else leechtimer -= diff;
if (grabtimer <= diff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) // Draws all players (and attacking Mobs) to itself.
DoCast(pTarget, DUNGEON_MODE(SPELL_WEB_GRAB, SPELL_WEB_GRAB_H));
grabtimer = urand(15000,30000);
} else grabtimer -= diff;
if (doorstimer <= diff)
{/* Debuff bleibt auf den Spielern bis zum Tod...
DoCast(m_creature, RAND(SPELL_WEB_FRONT_DOORS, SPELL_WEB_SIDE_DOORS));
*/
doorstimer = urand(30000,60000);
} else doorstimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_hadronox(Creature* pCreature)
{
return new boss_hadronoxAI (pCreature);
}
void AddSC_boss_hadronox()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_hadronox";
newscript->GetAI = &GetAI_boss_hadronox;
newscript->RegisterSelf();
}
@@ -0,0 +1,556 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_krikthir_the_gatewatcher
SD%Complete: 80 %
SDComment: Find in the future best timers and the event is not implemented.
SDCategory: Azjol Nerub
EndScriptData */
/*** SQL START ***
update creature_template set scriptname = 'boss_krik_thir' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "azjol_nerub.h"
enum Spells
{
SPELL_MIND_FLAY = 52586,
H_SPELL_MIND_FLAY = 59367,
SPELL_CURSE_OF_FATIGUE = 52592,
H_SPELL_CURSE_OF_FATIGUE = 59368,
SPELL_FRENZY = 28747, //maybe 53361
SPELL_SUMMON_SKITTERING_SWARMER = 52438, //AOE Effect 140, maybe 52439
SPELL_SUMMON_SKITTERING_SWARMER_1 = 52439, //Summon 3x 28735
H_SPELL_ACID_SPLASH = 59363,
SPELL_ACID_SPLASH = 52446,
SPELL_CHARGE = 16979,//maybe is another spell
SPELL_BACKSTAB = 52540,
SPELL_SHADOW_BOLT = 52534,
H_SPELL_SHADOW_BOLT = 59357,
SPELL_SHADOW_NOVA = 52535,
H_SPELL_SHADOW_NOVA = 59358,
SPELL_STRIKE = 52532,
SPELL_CLEAVE = 49806,
SPELL_ENRAGE = 52470,
SPELL_INFECTED_BITE = 52469,
H_SPELL_INFECTED_BITE = 59364,
SPELL_WEB_WRAP = 52086,//the spell is not working propperly
SPELL_BLINDING_WEBS = 52524,
H_SPELL_BLINDING_WEBS = 59365,
SPELL_POSION_SPRAY = 52493,
H_SPELL_POSION_SPRAY = 59366,
};
enum Mobs
{
MOB_SKITTERING_SWARMER = 28735,
MOB_SKITTERING_SWARMER_CONTROLLER = 32593,
MOB_SKITTERING_INFECTIOR = 28736,
};
enum Yells
{
SAY_AGGRO = -1601000,
SAY_SLAY_1 = -1601001,
SAY_SLAY_2 = -1601002,
SAY_DEATH = -1601003,
//Not in db
SAY_SEND_GROUP_1 = -1601004,
SAY_SEND_GROUP_2 = -1601005,
SAY_SEND_GROUP_3 = -1601006,
SAY_SWARM_1 = -1601007,
SAY_SWARM_2 = -1601008,
SAY_PREFIGHT_1 = -1601009,
SAY_PREFIGHT_2 = -1601010,
SAY_PREFIGHT_3 = -1601011,
};
enum Misc
{
ACHIEVEMENT_WATCH_HIM_DIE = 1296
};
struct TRINITY_DLL_DECL boss_krik_thirAI : public ScriptedAI
{
boss_krik_thirAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 MindFlayTimer;
uint32 CurseFatigueTimer;
uint32 SummonTimer;
void Reset()
{
MindFlayTimer = 15000;
CurseFatigueTimer = 12000;
if (pInstance)
pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
Summon();
SummonTimer = 15000;
if (pInstance)
pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, IN_PROGRESS);
}
void Summon()
{
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,566.164,682.087,769.079,2.21657,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,566.164,682.087,769.079,2.21657,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,529.042,706.941,777.298,1.0821,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,529.042,706.941,777.298,1.0821,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,489.975,671.239,772.131,0.261799,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,489.975,671.239,772.131,0.261799,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,488.556,692.95,771.764,4.88692,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,488.556,692.95,771.764,4.88692,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_INFECTIOR,553.34,640.387,777.419,1.20428,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,553.34,640.387,777.419,1.20428,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_INFECTIOR,517.486,706.398,777.335,5.35816,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,517.486,706.398,777.335,5.35816,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_INFECTIOR,504.01,637.693,777.479,0.506145,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,504.01,637.693,777.479,0.506145,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,552.625,706.408,777.177,3.4383,TEMPSUMMON_TIMED_DESPAWN,25000);
m_creature->SummonCreature(MOB_SKITTERING_SWARMER,552.625,706.408,777.177,3.4383,TEMPSUMMON_TIMED_DESPAWN,25000);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (SummonTimer <= diff)
{
Summon();
SummonTimer = 15000;
} else SummonTimer -= diff;
if (MindFlayTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_MIND_FLAY, H_SPELL_MIND_FLAY));
MindFlayTimer = 15000;
} else MindFlayTimer -= diff;
if (CurseFatigueTimer <= diff)
{
//WowWiki say "Curse of Fatigue-Kirk'thir will cast Curse of Fatigue on 2-3 targets periodically."
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
Unit *pTarget_1 = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
DoCast(pTarget, DUNGEON_MODE(SPELL_CURSE_OF_FATIGUE, H_SPELL_CURSE_OF_FATIGUE));
DoCast(pTarget_1, DUNGEON_MODE(SPELL_CURSE_OF_FATIGUE, H_SPELL_CURSE_OF_FATIGUE));
CurseFatigueTimer = 10000;
} else CurseFatigueTimer -= diff;
if (!m_creature->HasAura(SPELL_FRENZY) && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 10)
DoCast(m_creature, SPELL_FRENZY, true);
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
{
pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, DONE);
//Achievement: Watch him die
AchievementEntry const *AchievWatchHimDie = GetAchievementStore()->LookupEntry(ACHIEVEMENT_WATCH_HIM_DIE);
Map* pMap = m_creature->GetMap();
Creature *pAdd1, *pAdd2, *pAdd3;
if ((pAdd1 = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_WATCHER_GASHRA))) && pAdd1->isAlive() &&
(pAdd2 = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_WATCHER_SILTHIK))) && pAdd2->isAlive() &&
(pAdd3 = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_WATCHER_NARJIL))) && pAdd3->isAlive() &&
IsHeroic() && pMap && pMap->IsDungeon() && AchievWatchHimDie)
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (itr->getSource())
itr->getSource()->CompletedAchievement(AchievWatchHimDie);
}
}
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
}
void JustSummoned(Creature* summoned)
{
summoned->GetMotionMaster()->MovePoint(m_creature->GetEntry(),m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ());
}
};
struct TRINITY_DLL_DECL npc_skittering_infectorAI : public ScriptedAI
{
npc_skittering_infectorAI(Creature *c) : ScriptedAI(c) {}
void JustDied(Unit* killer)
{
//The spell is not working propperly
DoCast(m_creature->getVictim(),DUNGEON_MODE(SPELL_ACID_SPLASH, H_SPELL_ACID_SPLASH), true);
}
};
struct TRINITY_DLL_DECL npc_anub_ar_skirmisherAI : public ScriptedAI
{
npc_anub_ar_skirmisherAI(Creature *c) : ScriptedAI(c) {}
uint32 ChargeTimer;
uint32 BackstabTimer;
void Reset()
{
ChargeTimer = 11000;
BackstabTimer = 7000;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (ChargeTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
DoResetThreat();
m_creature->AddThreat(pTarget,1.0f);
DoCast(pTarget, SPELL_CHARGE, true);
}
ChargeTimer = 15000;
} else ChargeTimer -= diff;
if (BackstabTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_BACKSTAB);
BackstabTimer = 12000;
} else BackstabTimer -= diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL npc_anub_ar_shadowcasterAI : public ScriptedAI
{
npc_anub_ar_shadowcasterAI(Creature *c) : ScriptedAI(c) {}
uint32 ShadowBoltTimer;
uint32 ShadowNovaTimer;
void Reset()
{
ShadowBoltTimer = 6000;
ShadowNovaTimer = 15000;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (ShadowBoltTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT), true);
ShadowBoltTimer = 15000;
} else ShadowBoltTimer -= diff;
if (ShadowNovaTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_SHADOW_NOVA, H_SPELL_SHADOW_NOVA), true);
ShadowNovaTimer = 17000;
} else ShadowNovaTimer -= diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL npc_anub_ar_warriorAI : public ScriptedAI
{
npc_anub_ar_warriorAI(Creature *c) : ScriptedAI(c){}
uint32 CleaveTimer;
uint32 StrikeTimer;
void Reset()
{
CleaveTimer = 11000;
StrikeTimer = 6000;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (StrikeTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_STRIKE, true);
StrikeTimer = 15000;
} else StrikeTimer -= diff;
if (CleaveTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_CLEAVE, true);
CleaveTimer = 17000;
} else CleaveTimer -= diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL npc_watcher_gashraAI : public ScriptedAI
{
npc_watcher_gashraAI(Creature *c) : ScriptedAI(c) {}
uint32 WebWrapTimer;
uint32 InfectedBiteTimer;
void Reset()
{
WebWrapTimer = 11000;
InfectedBiteTimer = 4000;
}
void EnterCombat(Unit* who)
{
DoCast(m_creature, SPELL_ENRAGE, true);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (WebWrapTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_WEB_WRAP, true);
WebWrapTimer = 17000;
} else WebWrapTimer -= diff;
if (InfectedBiteTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_INFECTED_BITE, H_SPELL_INFECTED_BITE), true);
InfectedBiteTimer = 15000;
} else InfectedBiteTimer -= diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL npc_watcher_narjilAI : public ScriptedAI
{
npc_watcher_narjilAI(Creature *c) : ScriptedAI(c) {}
uint32 WebWrapTimer;
uint32 InfectedBiteTimer;
uint32 BlindingWebsTimer;
void Reset()
{
WebWrapTimer = 11000;
InfectedBiteTimer = 4000;
BlindingWebsTimer = 17000;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (WebWrapTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_WEB_WRAP, true);
WebWrapTimer = 15000;
} else WebWrapTimer -= diff;
if (InfectedBiteTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_INFECTED_BITE, H_SPELL_INFECTED_BITE), true);
InfectedBiteTimer = 11000;
} else InfectedBiteTimer -= diff;
if (BlindingWebsTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_BLINDING_WEBS, H_SPELL_BLINDING_WEBS), true);
BlindingWebsTimer = 17000;
} else BlindingWebsTimer -= diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL npc_watcher_silthikAI : public ScriptedAI
{
npc_watcher_silthikAI(Creature *c) : ScriptedAI(c) {}
uint32 WebWrapTimer;
uint32 InfectedBiteTimer;
uint32 PosionSprayTimer;
void Reset()
{
WebWrapTimer = 11000;
InfectedBiteTimer = 4000;
PosionSprayTimer = 15000;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (WebWrapTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_WEB_WRAP, true);
WebWrapTimer = 15000;
} else WebWrapTimer -= diff;
if (InfectedBiteTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_INFECTED_BITE, H_SPELL_INFECTED_BITE), true);
InfectedBiteTimer = 15000;
} else InfectedBiteTimer -= diff;
if (PosionSprayTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_POSION_SPRAY, H_SPELL_POSION_SPRAY), true);
PosionSprayTimer = 17000;
} else PosionSprayTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_krik_thir(Creature* pCreature)
{
return new boss_krik_thirAI (pCreature);
}
CreatureAI* GetAI_npc_anub_ar_skirmisher (Creature* pCreature)
{
return new npc_anub_ar_skirmisherAI (pCreature);
}
CreatureAI* GetAI_npc_skittering_infector (Creature* pCreature)
{
return new npc_skittering_infectorAI (pCreature);
}
CreatureAI* GetAI_npc_anub_ar_shadowcaster (Creature* pCreature)
{
return new npc_anub_ar_shadowcasterAI (pCreature);
}
CreatureAI* GetAI_npc_anub_ar_warrior (Creature* pCreature)
{
return new npc_anub_ar_warriorAI (pCreature);
}
CreatureAI* GetAI_npc_watcher_gashra (Creature* pCreature)
{
return new npc_watcher_gashraAI (pCreature);
}
CreatureAI* GetAI_npc_watcher_narjil (Creature* pCreature)
{
return new npc_watcher_narjilAI (pCreature);
}
CreatureAI* GetAI_npc_watcher_silthik (Creature* pCreature)
{
return new npc_watcher_silthikAI (pCreature);
}
void AddSC_boss_krik_thir()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_krik_thir";
newscript->GetAI = &GetAI_boss_krik_thir;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_skittering_infector";
newscript->GetAI = &GetAI_npc_skittering_infector;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_anub_ar_skirmisher";
newscript->GetAI = &GetAI_npc_anub_ar_skirmisher;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_anub_ar_shadowcaster";
newscript->GetAI = &GetAI_npc_anub_ar_shadowcaster;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_watcher_gashra";
newscript->GetAI = &GetAI_npc_watcher_gashra;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_anub_ar_warrior";
newscript->GetAI = &GetAI_npc_anub_ar_warrior;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_watcher_silthik";
newscript->GetAI = &GetAI_npc_watcher_silthik;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_watcher_narjil";
newscript->GetAI = &GetAI_npc_watcher_narjil;
newscript->RegisterSelf();
}
@@ -0,0 +1,206 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance_Azjol_Nerub
SD%Complete: 0
SDComment: Placeholder
SDCategory: Azjol Nerub
EndScriptData */
#include "ScriptedPch.h"
#include "azjol_nerub.h"
#define MAX_ENCOUNTER 3
/* Azjol Nerub encounters:
0 - Krik'thir the Gatewatcher
1 - Hadronox
2 - Anub'arak
*/
struct TRINITY_DLL_DECL instance_azjol_nerub : public ScriptedInstance
{
instance_azjol_nerub(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
uint64 m_uiKrikthir;
uint64 m_uiHadronox;
uint64 m_uiAnubarak;
uint64 m_uiWatcherGashra;
uint64 m_uiWatcherSilthik;
uint64 m_uiWatcherNarjil;
uint64 m_uiKrikthirDoor;
uint32 m_auiEncounter[MAX_ENCOUNTER];
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
m_uiKrikthir = 0;
m_uiHadronox = 0;
m_uiAnubarak = 0;
m_uiWatcherGashra = 0;
m_uiWatcherSilthik = 0;
m_uiWatcherNarjil = 0;
m_uiKrikthirDoor = 0;
}
bool IsEncounterInProgress() const
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
return false;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case 28684: m_uiKrikthir = pCreature->GetGUID(); break;
case 28921: m_uiHadronox = pCreature->GetGUID(); break;
case 29120: m_uiAnubarak = pCreature->GetGUID(); break;
case 28730: m_uiWatcherGashra = pCreature->GetGUID(); break;
case 28731: m_uiWatcherSilthik = pCreature->GetGUID(); break;
case 28729: m_uiWatcherNarjil = pCreature->GetGUID(); break;
}
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch (pGo->GetEntry())
{
case 192395:
m_uiKrikthirDoor = pGo->GetGUID();
if (m_auiEncounter[0] == DONE)
HandleGameObject(NULL,true,pGo);
break;
}
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_KRIKTHIR_THE_GATEWATCHER: return m_uiKrikthir;
case DATA_HADRONOX: return m_uiHadronox;
case DATA_ANUBARAK: return m_uiAnubarak;
case DATA_WATCHER_GASHRA: return m_uiWatcherGashra;
case DATA_WATCHER_SILTHIK: return m_uiWatcherSilthik;
case DATA_WATCHER_NARJIL: return m_uiWatcherNarjil;
}
return 0;
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_KRIKTHIR_THE_GATEWATCHER_EVENT:
m_auiEncounter[0] = data;
if (data == DONE)
HandleGameObject(m_uiKrikthirDoor,true);
break;
case DATA_HADRONOX_EVENT:
m_auiEncounter[1] = data; break;
case DATA_ANUBARAK_EVENT:
m_auiEncounter[2] = data; break;
}
if (data == DONE)
{
SaveToDB();
}
}
uint32 GetData(uint32 type)
{
switch(type)
{
case DATA_KRIKTHIR_THE_GATEWATCHER_EVENT: return m_auiEncounter[0];
case DATA_HADRONOX_EVENT: return m_auiEncounter[1];
case DATA_ANUBARAK_EVENT: return m_auiEncounter[2];
}
return 0;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::string str_data;
std::ostringstream saveStream;
saveStream << "A N " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
<< m_auiEncounter[2];
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in)
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0,data1,data2;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
if (dataHead1 == 'A' && dataHead2 == 'N')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_azjol_nerub(Map* pMap)
{
return new instance_azjol_nerub(pMap);
}
void AddSC_instance_azjol_nerub()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_azjol_nerub";
newscript->GetInstanceData = &GetInstanceData_instance_azjol_nerub;
newscript->RegisterSelf();
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,316 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Argent Challenge Encounter.
SD%Complete: 90 %
SDComment: Texts are not implemented.
SDCategory: Trial of the Champion
EndScriptData */
#include "ScriptedPch.h"
#include "trial_of_the_champion.h"
enum eSpells
{
//Eadric
SPELL_EADRIC_ACHIEVEMENT = 68197,
SPELL_HAMMER_JUSTICE = 66863,
SPELL_HAMMER_RIGHTEOUS = 66867,
SPELL_RADIANCE = 66935,
SPELL_VENGEANCE = 66865,
//Paletress
SPELL_SMITE = 66536,
SPELL_SMITE_H = 67674,
SPELL_HOLY_FIRE = 66538,
SPELL_HOLY_FIRE_H = 67676,
SPELL_RENEW = 66537,
SPELL_RENEW_H = 67675,
SPELL_HOLY_NOVA = 66546,
SPELL_SHIELD = 66515,
SPELL_CONFESS = 66680,
SPELL_SUMMON_MEMORY = 66545,
//Memory
SPELL_OLD_WOUNDS = 66620,
SPELL_OLD_WOUNDS_H = 67679,
SPELL_SHADOWS_PAST = 66619,
SPELL_SHADOWS_PAST_H = 67678,
SPELL_WAKING_NIGHTMARE = 66552,
SPELL_WAKING_NIGHTMARE_H = 67677
};
struct TRINITY_DLL_DECL boss_eadricAI : public ScriptedAI
{
boss_eadricAI(Creature* pCreature) : ScriptedAI(pCreature) {}
uint32 uiVenganceTimer;
uint32 uiRadianceTimer;
uint32 uiHammerJusticeTimer;
void Reset()
{
uiVenganceTimer = 10000;
uiRadianceTimer = 16000;
uiHammerJusticeTimer = 25000;
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (uiHammerJusticeTimer <= uiDiff)
{
m_creature->InterruptNonMeleeSpells(true);
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 250, true))
{
if (pTarget && pTarget->isAlive())
{
DoCast(pTarget, SPELL_HAMMER_JUSTICE);
DoCast(pTarget, SPELL_HAMMER_RIGHTEOUS);
}
}
uiHammerJusticeTimer = 25000;
} else uiHammerJusticeTimer -= uiDiff;
if (uiVenganceTimer <= uiDiff)
{
DoCast(m_creature,SPELL_VENGEANCE);
uiVenganceTimer = 10000;
} else uiVenganceTimer -= uiDiff;
if (uiRadianceTimer <= uiDiff)
{
DoCastAOE(SPELL_RADIANCE);
uiRadianceTimer = 16000;
} else uiRadianceTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_eadric(Creature* pCreature)
{
return new boss_eadricAI(pCreature);
}
struct TRINITY_DLL_DECL boss_paletressAI : public ScriptedAI
{
boss_paletressAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pMemory = NULL;
}
ScriptedInstance* pInstance;
Creature* pMemory;
bool bHealth;
uint32 uiHolyFireTimer;
uint32 uiHolySmiteTimer;
uint32 uiRenewTimer;
uint32 uiRandomSpell;
void Reset()
{
m_creature->RemoveAllAuras();
uiHolyFireTimer = urand(9000,12000);
uiHolySmiteTimer = urand(5000,7000);
uiRenewTimer = urand(2000,5000);
uiRandomSpell = 0;
bHealth = false;
if (pMemory && pMemory->isAlive())
pMemory->RemoveFromWorld();
}
void SetData(uint32 uiId, uint32 uiValue)
{
if (uiId == 1)
m_creature->RemoveAura(SPELL_SHIELD);
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (uiHolyFireTimer <= uiDiff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 250, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,DUNGEON_MODE(SPELL_HOLY_FIRE,SPELL_HOLY_FIRE_H));
}
if (m_creature->HasAura(SPELL_SHIELD))
uiHolyFireTimer = 13000;
else
uiHolyFireTimer = urand(9000,12000);
} else uiHolyFireTimer -= uiDiff;
if (uiHolySmiteTimer <= uiDiff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 250, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,DUNGEON_MODE(SPELL_SMITE,SPELL_SMITE_H));
}
if (m_creature->HasAura(SPELL_SHIELD))
uiHolySmiteTimer = 9000;
else
uiHolySmiteTimer = urand(5000,7000);
} else uiHolySmiteTimer -= uiDiff;
if (m_creature->HasAura(SPELL_SHIELD))
if (uiRenewTimer <= uiDiff)
{
m_creature->InterruptNonMeleeSpells(true);
uint8 uiTarget = urand(0,1);
switch(uiTarget)
{
case 0:
DoCast(m_creature,DUNGEON_MODE(SPELL_RENEW,SPELL_RENEW_H));
break;
case 1:
if (pMemory && pMemory->isAlive())
DoCast(pMemory,DUNGEON_MODE(SPELL_RENEW,SPELL_RENEW_H));
break;
}
uiRenewTimer = urand(15000,17000);
} else uiRenewTimer -= uiDiff;
if (!bHealth && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 25)
{
m_creature->InterruptNonMeleeSpells(true);
uiRandomSpell = urand(1,26);
DoCastAOE(SPELL_HOLY_NOVA,false);
DoCast(m_creature, SPELL_SHIELD);
DoCastAOE(SPELL_SUMMON_MEMORY,false);
DoCastAOE(SPELL_CONFESS,false);
bHealth = true;
}
DoMeleeAttackIfReady();
}
void JustSummoned(Creature* pSummon)
{
pMemory = pSummon;
}
};
CreatureAI* GetAI_boss_paletress(Creature* pCreature)
{
return new boss_paletressAI(pCreature);
}
struct TRINITY_DLL_DECL npc_memoryAI : public ScriptedAI
{
npc_memoryAI(Creature* pCreature) : ScriptedAI(pCreature) {}
uint32 uiOldWoundsTimer;
uint32 uiShadowPastTimer;
uint32 uiWakingNightmare;
void Reset()
{
uiOldWoundsTimer = 12000;
uiShadowPastTimer = 5000;
uiWakingNightmare = 7000;
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (uiOldWoundsTimer <= uiDiff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget, DUNGEON_MODE(SPELL_OLD_WOUNDS,SPELL_OLD_WOUNDS_H));
}
uiOldWoundsTimer = 12000;
}else uiOldWoundsTimer -= uiDiff;
if (uiWakingNightmare <= uiDiff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_WAKING_NIGHTMARE,SPELL_WAKING_NIGHTMARE_H));
uiWakingNightmare = 7000;
}else uiWakingNightmare -= uiDiff;
if (uiShadowPastTimer <= uiDiff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,DUNGEON_MODE(SPELL_SHADOWS_PAST,SPELL_SHADOWS_PAST_H));
}
uiShadowPastTimer = 5000;
}else uiShadowPastTimer -= uiDiff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* pKiller)
{
if (m_creature->isSummon())
if (Unit* pSummoner = CAST_SUM(m_creature)->GetSummoner())
{
if (pSummoner && pSummoner->isAlive())
CAST_CRE(pSummoner)->AI()->SetData(1,0);
}
}
};
CreatureAI* GetAI_npc_memory(Creature* pCreature)
{
return new npc_memoryAI(pCreature);
}
void AddSC_boss_argent_challenge()
{
Script* NewScript;
NewScript = new Script;
NewScript->Name = "boss_eadric";
NewScript->GetAI = &GetAI_boss_eadric;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "boss_paletress";
NewScript->GetAI = &GetAI_boss_paletress;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "npc_memory";
NewScript->GetAI = &GetAI_npc_memory;
NewScript->RegisterSelf();
}
@@ -0,0 +1,334 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss Black Knight
SD%Complete: 80%
SDComment: missing yells. not sure about timers.
SDCategory: Trial of the Champion
EndScriptData */
#include "ScriptedPch.h"
#include "trial_of_the_champion.h"
enum eSpells
{
//phase 1
SPELL_PLAGUE_STRIKE = 67884,
SPELL_PLAGUE_STRIKE_2 = 67724,
SPELL_ICY_TOUCH_H = 67881,
SPELL_ICY_TOUCH = 67718,
SPELL_DEATH_RESPITE = 67745,
SPELL_DEATH_RESPITE_2 = 68306,
SPELL_DEATH_RESPITE_3 = 66798,
SPELL_OBLITERATE_H = 67883,
SPELL_OBLITERATE = 67725,
//in this phase should rise herald (the spell is missing)
//phase 2 - During this phase, the Black Knight will use the same abilities as in phase 1, except for Death's Respite
SPELL_ARMY_DEAD = 67761,
SPELL_DESECRATION = 67778,
SPELL_DESECRATION_2 = 67778,
SPELL_GHOUL_EXPLODE = 67751,
//phase 3
SPELL_DEATH_BITE_H = 67875,
SPELL_DEATH_BITE = 67808,
SPELL_MARKED_DEATH = 67882,
SPELL_MARKED_DEATH_2 = 67823,
SPELL_BLACK_KNIGHT_RES = 67693,
SPELL_LEAP = 67749,
SPELL_LEAP_H = 67880
};
enum eModels
{
MODEL_SKELETON = 29846,
MODEL_GHOST = 21300
};
enum ePhases
{
PHASE_UNDEAD = 1,
PHASE_SKELETON = 2,
PHASE_GHOST = 3
};
struct TRINITY_DLL_DECL boss_black_knightAI : public ScriptedAI
{
boss_black_knightAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* pInstance;
std::list<uint64> SummonList;
bool bEventInProgress;
bool bEvent;
bool bSummonArmy;
bool bDeathArmyDone;
uint8 uiPhase;
uint32 uiPlagueStrikeTimer;
uint32 uiIcyTouchTimer;
uint32 uiDeathRespiteTimer;
uint32 uiObliterateTimer;
uint32 uiDesecration;
uint32 uiResurrectTimer;
uint32 uiDeathArmyCheckTimer;
uint32 uiGhoulExplodeTimer;
uint32 uiDeathBiteTimer;
uint32 uiMarkedDeathTimer;
void Reset()
{
RemoveSummons();
m_creature->SetDisplayId(m_creature->GetNativeDisplayId());
m_creature->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
bEventInProgress = false;
bEvent = false;
bSummonArmy = false;
bDeathArmyDone = false;
uiPhase = PHASE_UNDEAD;
uiIcyTouchTimer = urand(5000,9000);
uiPlagueStrikeTimer = urand(10000,13000);
uiDeathRespiteTimer = urand(15000,16000);
uiObliterateTimer = urand(17000,19000);
uiDesecration = urand(15000,16000);
uiDeathArmyCheckTimer = 7000;
uiResurrectTimer = 4000;
uiGhoulExplodeTimer = 8000;
uiDeathBiteTimer = urand (2000,4000);
uiMarkedDeathTimer = urand (5000,7000);
}
void RemoveSummons()
{
if (SummonList.empty())
return;
for(std::list<uint64>::iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
{
if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
if (pTemp)
pTemp->DisappearAndDie();
}
SummonList.clear();
}
void JustSummoned(Creature* pSummon)
{
SummonList.push_back(pSummon->GetGUID());
pSummon->AI()->AttackStart(m_creature->getVictim());
}
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (bEventInProgress)
if (uiResurrectTimer <= uiDiff)
{
m_creature->SetHealth(m_creature->GetMaxHealth());
DoCast(m_creature,SPELL_BLACK_KNIGHT_RES,true);
uiPhase++;
uiResurrectTimer = 4000;
bEventInProgress = false;
m_creature->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
} else uiResurrectTimer -= uiDiff;
switch(uiPhase)
{
case PHASE_UNDEAD:
case PHASE_SKELETON:
{
if (uiIcyTouchTimer <= uiDiff)
{
DoCastVictim(DUNGEON_MODE(SPELL_ICY_TOUCH,SPELL_ICY_TOUCH_H));
uiIcyTouchTimer = urand(5000,7000);
} else uiIcyTouchTimer -= uiDiff;
if (uiPlagueStrikeTimer <= uiDiff)
{
DoCastVictim(DUNGEON_MODE(SPELL_ICY_TOUCH,SPELL_ICY_TOUCH_H));
uiPlagueStrikeTimer = urand(12000,15000);
} else uiPlagueStrikeTimer -= uiDiff;
if (uiObliterateTimer <= uiDiff)
{
DoCastVictim(DUNGEON_MODE(SPELL_OBLITERATE,SPELL_OBLITERATE_H));
uiObliterateTimer = urand(17000,19000);
} else uiObliterateTimer -= uiDiff;
switch(uiPhase)
{
case PHASE_UNDEAD:
{
if (uiDeathRespiteTimer <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,SPELL_DEATH_RESPITE);
}
uiDeathRespiteTimer = urand(15000,16000);
} else uiDeathRespiteTimer -= uiDiff;
break;
}
case PHASE_SKELETON:
{
if (!bSummonArmy)
{
bSummonArmy = true;
m_creature->addUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
DoCast(m_creature, SPELL_ARMY_DEAD);
}
if (!bDeathArmyDone)
if (uiDeathArmyCheckTimer <= uiDiff)
{
m_creature->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
uiDeathArmyCheckTimer = 0;
bDeathArmyDone = true;
} else uiDeathArmyCheckTimer -= uiDiff;
if (uiDesecration <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,SPELL_DESECRATION);
}
uiDesecration = urand(15000,16000);
} else uiDesecration -= uiDiff;
if (uiGhoulExplodeTimer <= uiDiff)
{
DoCast(m_creature, SPELL_GHOUL_EXPLODE);
uiGhoulExplodeTimer = 8000;
} else uiGhoulExplodeTimer -= uiDiff;
break;
}
break;
}
break;
}
case PHASE_GHOST:
{
if (uiDeathBiteTimer <= uiDiff)
{
DoCastAOE(DUNGEON_MODE(SPELL_DEATH_BITE,SPELL_DEATH_BITE_H));
uiDeathBiteTimer = urand (2000, 4000);
} else uiDeathBiteTimer -= uiDiff;
if (uiMarkedDeathTimer <= uiDiff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,SPELL_MARKED_DEATH);
}
uiMarkedDeathTimer = urand (5000, 7000);
} else uiMarkedDeathTimer -= uiDiff;
break;
}
}
if (!m_creature->hasUnitState(UNIT_STAT_ROOT) && !m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 0)
DoMeleeAttackIfReady();
}
void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
{
if (uiDamage > m_creature->GetHealth() && uiPhase <= PHASE_SKELETON)
{
uiDamage = 0;
m_creature->SetHealth(0);
m_creature->addUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
RemoveSummons();
switch(uiPhase)
{
case PHASE_UNDEAD:
m_creature->SetDisplayId(MODEL_SKELETON);
break;
case PHASE_SKELETON:
m_creature->SetDisplayId(MODEL_GHOST);
break;
}
bEventInProgress = true;
}
}
};
CreatureAI* GetAI_boss_black_knight(Creature *pCreature)
{
return new boss_black_knightAI (pCreature);
}
struct TRINITY_DLL_DECL npc_risen_ghoulAI : public ScriptedAI
{
npc_risen_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature) {}
uint32 uiAttackTimer;
void Reset()
{
uiAttackTimer = 3500;
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (uiAttackTimer <= uiDiff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget, (DUNGEON_MODE(SPELL_LEAP,SPELL_LEAP_H)));
}
uiAttackTimer = 3500;
} else uiAttackTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_npc_risen_ghoul(Creature* pCreature)
{
return new npc_risen_ghoulAI(pCreature);
}
void AddSC_boss_black_knight()
{
Script* NewScript;
NewScript = new Script;
NewScript->Name = "boss_black_knight";
NewScript->GetAI = &GetAI_boss_black_knight;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "npc_risen_ghoul";
NewScript->GetAI = &GetAI_npc_risen_ghoul;
NewScript->RegisterSelf();
}
@@ -0,0 +1,580 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_grand_champions
SD%Complete: 92%
SDComment: missing yells. hunter AI sucks. no pvp diminuishing returns(is it DB related?)
SDCategory: Trial Of the Champion
EndScriptData */
#include "ScriptedPch.h"
#include "trial_of_the_champion.h"
enum Spells
{
//yells
//warrior
SPELL_MORTAL_STRIKE = 68783,
SPELL_MORTAL_STRIKE_H = 68784,
SPELL_BLADESTORM = 63784,
SPELL_INTERCEPT = 67540,
SPELL_ROLLING_THROW = 47115, //need core support for spell 67546, using 47115 instead
//mage
SPELL_FIREBALL = 66042,
SPELL_FIREBALL_H = 68310,
SPELL_BLAST_WAVE = 66044,
SPELL_BLAST_WAVE_H = 68312,
SPELL_HASTE = 66045,
SPELL_POLYMORPH = 66043,
SPELL_POLYMORPH_H = 68311,
//shaman
SPELL_CHAIN_LIGHTNING = 67529,
SPELL_CHAIN_LIGHTNING_H = 68319,
SPELL_EARTH_SHIELD = 67530,
SPELL_HEALING_WAVE = 67528,
SPELL_HEALING_WAVE_H = 68318,
SPELL_HEX_OF_MENDING = 67534,
//hunter
SPELL_DISENGAGE = 68340,
SPELL_LIGHTNING_ARROWS = 66083,
SPELL_MULTI_SHOT = 66081,
SPELL_SHOOT = 66079,
//rogue
SPELL_EVISCERATE = 67709,
SPELL_EVISCERATE_H = 68317,
SPELL_FAN_OF_KNIVES = 67706,
SPELL_POISON_BOTTLE = 67701
};
// Warrior
struct TRINITY_DLL_DECL mob_toc5_warriorAI : public ScriptedAI
{
mob_toc5_warriorAI(Creature* pCreature) : ScriptedAI(pCreature)
{
Reset();
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
uint32 Mortal_Strike_Timer;
uint32 Bladestorm_Timer;
uint32 Rolling_Throw_Timer;
uint32 Intercept_Cooldown;
uint32 intercept_check;
void Reset()
{
m_creature->SetRespawnDelay(999999999);
Mortal_Strike_Timer = 6000;
Bladestorm_Timer = 20000;
Rolling_Throw_Timer = 30000;
Intercept_Cooldown = 0;
intercept_check = 1000;
}
void EnterEvadeMode()
{
}
void Aggro(Unit* pWho)
{
if (!m_pInstance)
return;
if (m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE)
m_creature->ForcedDespawn();
else
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
}
void JustDied(Unit* pKiller)
{
if (!m_pInstance)
return;
if(!m_creature->FindNearestCreature(35572, 200, true) && !m_creature->FindNearestCreature(35569, 200, true) && !m_creature->FindNearestCreature(35571, 200, true) &&
!m_creature->FindNearestCreature(35570, 200, true) && !m_creature->FindNearestCreature(35617, 200, true) && !m_creature->FindNearestCreature(34705, 200, true)
&& !m_creature->FindNearestCreature(34702, 200, true) && !m_creature->FindNearestCreature(34701, 200, true) && !m_creature->FindNearestCreature(34657, 200, true)
&& !m_creature->FindNearestCreature(34703, 200, true))
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectVictim() || !m_creature->getVictim())
return;
if (Mortal_Strike_Timer < diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_MORTAL_STRIKE, SPELL_MORTAL_STRIKE_H));
Mortal_Strike_Timer = 6000;
}else Mortal_Strike_Timer -= diff;
if (Rolling_Throw_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ROLLING_THROW);
Rolling_Throw_Timer = 30000;
}else Rolling_Throw_Timer -= diff;
if (Bladestorm_Timer < diff)
{
DoCast(m_creature, SPELL_BLADESTORM);
Bladestorm_Timer = 90000;
}else Bladestorm_Timer -= diff;
if (intercept_check < diff)
{
if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 25) && Intercept_Cooldown < diff)
{
DoCast(m_creature->getVictim(), SPELL_INTERCEPT);
Intercept_Cooldown = 15000;
}
intercept_check = 1000;
}
else
{
intercept_check -= diff;
Intercept_Cooldown -= diff;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_toc5_warrior(Creature* pCreature)
{
return new mob_toc5_warriorAI(pCreature);
}
// Mage
struct TRINITY_DLL_DECL mob_toc5_mageAI : public ScriptedAI
{
mob_toc5_mageAI(Creature* pCreature) : ScriptedAI(pCreature)
{
Reset();
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
uint32 Fireball_Timer;
uint32 Blast_Wave_Timer;
uint32 Haste_Timer;
uint32 Polymorph_Timer;
void Reset()
{
m_creature->SetRespawnDelay(999999999);
Fireball_Timer = 0;
Blast_Wave_Timer = 20000;
Haste_Timer = 9000;
Polymorph_Timer = 15000;
}
void EnterEvadeMode()
{
}
void Aggro(Unit* pWho)
{
if (!m_pInstance)
return;
if (m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE)
m_creature->ForcedDespawn();
else
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
}
void JustDied(Unit* pKiller)
{
if (!m_pInstance)
return;
if(!m_creature->FindNearestCreature(35572, 200, true) && !m_creature->FindNearestCreature(35569, 200, true) && !m_creature->FindNearestCreature(35571, 200, true) &&
!m_creature->FindNearestCreature(35570, 200, true) && !m_creature->FindNearestCreature(35617, 200, true) && !m_creature->FindNearestCreature(34705, 200, true)
&& !m_creature->FindNearestCreature(34702, 200, true) && !m_creature->FindNearestCreature(34701, 200, true) && !m_creature->FindNearestCreature(34657, 200, true)
&& !m_creature->FindNearestCreature(34703, 200, true))
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectVictim() || !m_creature->getVictim())
return;
if (Fireball_Timer < diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_FIREBALL, SPELL_FIREBALL_H));
Fireball_Timer = 3000;
}else Fireball_Timer -= diff;
if (Blast_Wave_Timer < diff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_BLAST_WAVE, SPELL_BLAST_WAVE_H));
Blast_Wave_Timer = 20000;
}else Blast_Wave_Timer -= diff;
if (Haste_Timer < diff)
{
DoCast(m_creature, SPELL_HASTE);
Haste_Timer = 10000;
}else Haste_Timer -= diff;
if (Polymorph_Timer < diff)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
DoCast(target, DUNGEON_MODE(SPELL_POLYMORPH, SPELL_POLYMORPH_H));
Polymorph_Timer = 15000;
}else Polymorph_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_toc5_mage(Creature* pCreature)
{
return new mob_toc5_mageAI(pCreature);
}
// Shaman
struct TRINITY_DLL_DECL mob_toc5_shamanAI : public ScriptedAI
{
mob_toc5_shamanAI(Creature* pCreature) : ScriptedAI(pCreature)
{
Reset();
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
uint32 Chain_Lightning_Timer;
uint32 Earth_Shield_Timer;
uint32 Healing_Wave_Timer;
uint32 Hex_Timer;
float mob1_health;
float mob2_health;
float mob3_health;
void Reset()
{
m_creature->SetRespawnDelay(999999999);
Chain_Lightning_Timer = 1000;
Earth_Shield_Timer = 5000;
Healing_Wave_Timer = 13000;
Hex_Timer = 10000;
}
void EnterEvadeMode()
{
}
void Aggro(Unit* pWho)
{
if (!m_pInstance)
return;
if (m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE)
m_creature->ForcedDespawn();
else
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
}
void JustDied(Unit* pKiller)
{
if (!m_pInstance)
return;
if(!m_creature->FindNearestCreature(35572, 200, true) && !m_creature->FindNearestCreature(35569, 200, true) && !m_creature->FindNearestCreature(35571, 200, true) &&
!m_creature->FindNearestCreature(35570, 200, true) && !m_creature->FindNearestCreature(35617, 200, true) && !m_creature->FindNearestCreature(34705, 200, true)
&& !m_creature->FindNearestCreature(34702, 200, true) && !m_creature->FindNearestCreature(34701, 200, true) && !m_creature->FindNearestCreature(34657, 200, true)
&& !m_creature->FindNearestCreature(34703, 200, true))
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectVictim() || !m_creature->getVictim())
return;
if (Chain_Lightning_Timer < diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_CHAIN_LIGHTNING, SPELL_CHAIN_LIGHTNING_H));
Chain_Lightning_Timer = 10000;
}else Chain_Lightning_Timer -= diff;
if (Hex_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_HEX_OF_MENDING);
Hex_Timer = 20000;
}else Hex_Timer -= diff;
if (Healing_Wave_Timer < diff)
{
if(Unit* target = m_creature->SelectNearestTarget(40))
if(target->GetHealth() == target->GetHealth() * 100 / target->GetMaxHealth() && target->IsFriendlyTo(m_creature))
{
DoCast(target, DUNGEON_MODE(SPELL_HEALING_WAVE, SPELL_HEALING_WAVE_H));
Healing_Wave_Timer = 8000;
}
}else Healing_Wave_Timer -= diff;
if (Earth_Shield_Timer < diff)
{
if(Unit* target = m_creature->SelectNearestTarget(40))
if(!target->HasAura(SPELL_EARTH_SHIELD,m_creature->GetGUID()) && target->IsFriendlyTo(m_creature))
{
DoCast(target, SPELL_EARTH_SHIELD);
Earth_Shield_Timer = 25000;
}
}else Earth_Shield_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_toc5_shaman(Creature* pCreature)
{
return new mob_toc5_shamanAI(pCreature);
}
// Hunter
struct TRINITY_DLL_DECL mob_toc5_hunterAI : public ScriptedAI
{
mob_toc5_hunterAI(Creature* pCreature) : ScriptedAI(pCreature)
{
Reset();
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
uint32 Shoot_Timer;
uint32 Lightning_Arrows_Timer;
uint32 Multi_Shot_Timer;
uint32 Disengage_Cooldown;
uint32 enemy_check;
uint32 disengage_check;
void Reset()
{
m_creature->SetRespawnDelay(999999999);
Shoot_Timer = 0;
Lightning_Arrows_Timer = 13000;
Multi_Shot_Timer = 10000;
Disengage_Cooldown = 0;
enemy_check = 1000;
disengage_check;
}
void EnterEvadeMode()
{
}
void Aggro(Unit* pWho)
{
if (!m_pInstance)
return;
if (m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE)
m_creature->ForcedDespawn();
else
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
}
void JustDied(Unit* pKiller)
{
if (!m_pInstance)
return;
if(!m_creature->FindNearestCreature(35572, 200, true) && !m_creature->FindNearestCreature(35569, 200, true) && !m_creature->FindNearestCreature(35571, 200, true) &&
!m_creature->FindNearestCreature(35570, 200, true) && !m_creature->FindNearestCreature(35617, 200, true) && !m_creature->FindNearestCreature(34705, 200, true)
&& !m_creature->FindNearestCreature(34702, 200, true) && !m_creature->FindNearestCreature(34701, 200, true) && !m_creature->FindNearestCreature(34657, 200, true)
&& !m_creature->FindNearestCreature(34703, 200, true))
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectVictim() || !m_creature->getVictim())
return;
if (enemy_check < diff)
{
if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8) && m_creature->IsWithinDistInMap(m_creature->getVictim(), 30))
{
m_creature->SetSpeed(MOVE_RUN, 0.0001);
}
else
{
m_creature->SetSpeed(MOVE_RUN, 1);
}
enemy_check = 100;
}else enemy_check -= diff;
if (Disengage_Cooldown>0)
Disengage_Cooldown -= diff;
if (Shoot_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_SHOOT);
Shoot_Timer = 3000;
}else Shoot_Timer -= diff;
if (Multi_Shot_Timer < diff)
{
m_creature->CastStop(SPELL_SHOOT);
DoCast(m_creature->getVictim(), SPELL_MULTI_SHOT);
Multi_Shot_Timer = 10000;
}else Multi_Shot_Timer -= diff;
if (Lightning_Arrows_Timer < diff)
{
m_creature->CastStop(SPELL_SHOOT);
DoCast(m_creature, SPELL_LIGHTNING_ARROWS);
Lightning_Arrows_Timer = 25000;
}else Lightning_Arrows_Timer -= diff;
if (disengage_check < diff)
{
if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 5) && Disengage_Cooldown == 0)
{
DoCast(m_creature, SPELL_DISENGAGE);
Disengage_Cooldown = 15000;
}
disengage_check = 1000;
}else disengage_check -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_toc5_hunter(Creature* pCreature)
{
return new mob_toc5_hunterAI(pCreature);
}
// Rogue
struct TRINITY_DLL_DECL mob_toc5_rogueAI : public ScriptedAI
{
mob_toc5_rogueAI(Creature* pCreature) : ScriptedAI(pCreature)
{
Reset();
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
uint32 Eviscerate_Timer;
uint32 FoK_Timer;
uint32 Poison_Timer;
void Reset()
{
m_creature->SetRespawnDelay(999999999);
Eviscerate_Timer = 15000;
FoK_Timer = 10000;
Poison_Timer = 7000;
}
void EnterEvadeMode()
{
}
void Aggro(Unit* pWho)
{
if (!m_pInstance)
return;
if (m_pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE)
m_creature->ForcedDespawn();
else
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
}
void JustDied(Unit* pKiller)
{
if (!m_pInstance)
return;
if(!m_creature->FindNearestCreature(35572, 200, true) && !m_creature->FindNearestCreature(35569, 200, true) && !m_creature->FindNearestCreature(35571, 200, true) &&
!m_creature->FindNearestCreature(35570, 200, true) && !m_creature->FindNearestCreature(35617, 200, true) && !m_creature->FindNearestCreature(34705, 200, true)
&& !m_creature->FindNearestCreature(34702, 200, true) && !m_creature->FindNearestCreature(34701, 200, true) && !m_creature->FindNearestCreature(34657, 200, true)
&& !m_creature->FindNearestCreature(34703, 200, true))
m_pInstance->SetData(TYPE_GRAND_CHAMPIONS, DONE);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectVictim() || !m_creature->getVictim())
return;
if (Eviscerate_Timer < diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_EVISCERATE, SPELL_EVISCERATE_H));
Eviscerate_Timer = 10000;
}else Eviscerate_Timer -= diff;
if (FoK_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FAN_OF_KNIVES);
FoK_Timer = 7000;
}else FoK_Timer -= diff;
if (Poison_Timer < diff)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(m_creature, SPELL_POISON_BOTTLE);
Poison_Timer = 6000;
}else Poison_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_toc5_rogue(Creature* pCreature)
{
return new mob_toc5_rogueAI(pCreature);
}
void AddSC_boss_grand_champions()
{
Script* NewScript;
NewScript = new Script;
NewScript->Name = "mob_toc5_warrior";
NewScript->GetAI = &GetAI_mob_toc5_warrior;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "mob_toc5_mage";
NewScript->GetAI = &GetAI_mob_toc5_mage;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "mob_toc5_shaman";
NewScript->GetAI = &GetAI_mob_toc5_shaman;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "mob_toc5_hunter";
NewScript->GetAI = &GetAI_mob_toc5_hunter;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "mob_toc5_rogue";
NewScript->GetAI = &GetAI_mob_toc5_rogue;
NewScript->RegisterSelf();
}
@@ -0,0 +1,349 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance_Trial_Of_the_Champion
SD%Complete: 100
SDComment:
SDCategory: Trial Of the Champion
EndScriptData */
#include "ScriptedPch.h"
#include "trial_of_the_champion.h"
struct TRINITY_DLL_DECL instance_trial_of_the_champion : public ScriptedInstance
{
instance_trial_of_the_champion(Map* pMap) : ScriptedInstance(pMap), m_uiChampionsLootGUID(NULL), m_uiPaletressLootGUID(NULL), m_uiEadricLootGUID(NULL) { Initialize(); }
uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string strInstData;
uint64 m_uiEadricGUID;
uint64 m_uiPaletressGUID;
uint64 m_uiBlackKnightGUID;
uint64 m_uiJaerenGUID;
uint64 m_uiArelasGUID;
uint64 m_uiAnnouncerGUID;
uint64 m_uiBlackKnightMinionGUID;
uint64 m_uiArgentChallenger;
uint64 m_uiMemoryGUID;
GameObject* m_uiChampionsLootGUID;
GameObject* m_uiPaletressLootGUID;
GameObject* m_uiEadricLootGUID;
void Initialize()
{
m_uiChampionsLootGUID = 0;
m_uiEadricGUID = 0;
m_uiEadricLootGUID = 0;
m_uiPaletressGUID = 0;
m_uiPaletressLootGUID = 0;
m_uiBlackKnightGUID = 0;
m_uiJaerenGUID = 0;
m_uiArelasGUID = 0;
m_uiAnnouncerGUID = 0;
m_uiBlackKnightMinionGUID = 0;
m_uiArgentChallenger = 0;
m_uiMemoryGUID = 0;
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
}
bool IsEncounterInProgress() const
{
for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
{
if (m_auiEncounter[i] == IN_PROGRESS)
return true;
}
return false;
}
void OnCreatureCreate(Creature* pCreature, bool bAdd)
{
Map::PlayerList const &players = instance->GetPlayers();
uint32 TeamInInstance = 0;
if (!players.isEmpty())
{
if (Player* pPlayer = players.begin()->getSource())
TeamInInstance = pPlayer->GetTeam();
}
switch(pCreature->GetEntry())
{
// Champions
case NPC_MOKRA:
if (TeamInInstance == HORDE)
pCreature->UpdateEntry(NPC_JACOB, ALLIANCE);
break;
case NPC_ERESSEA:
if (TeamInInstance == HORDE)
pCreature->UpdateEntry(NPC_AMBROSE, ALLIANCE);
break;
case NPC_RUNOK:
if (TeamInInstance == HORDE)
pCreature->UpdateEntry(NPC_COLOSOS, ALLIANCE);
break;
case NPC_ZULTORE:
if (TeamInInstance == HORDE)
pCreature->UpdateEntry(NPC_JAELYNE, ALLIANCE);
break;
case NPC_VISCERI:
if (TeamInInstance == HORDE)
pCreature->UpdateEntry(NPC_LANA, ALLIANCE);
break;
// Argent Challenge
case NPC_EADRIC:
m_uiEadricGUID = pCreature->GetGUID();
m_uiArgentChallenger = pCreature->GetGUID();
break;
case NPC_PALETRESS:
m_uiPaletressGUID = pCreature->GetGUID();
m_uiArgentChallenger = pCreature->GetGUID();
break;
// Black Knight
case NPC_BLACK_KNIGHT:
m_uiBlackKnightGUID = pCreature->GetGUID();
break;
case NPC_RISEN_JAEREN:
m_uiBlackKnightMinionGUID = pCreature->GetGUID();
break;
case NPC_RISEN_ARELAS:
m_uiBlackKnightMinionGUID = pCreature->GetGUID();
break;
// Coliseum Announcers
case NPC_JAEREN:
m_uiJaerenGUID = pCreature->GetGUID();
break;
case NPC_ARELAS:
m_uiArelasGUID = pCreature->GetGUID();
break;
// memories
case MEMORY_ALGALON:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_ARCHIMONDE:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_CHROMAGGUS:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_CYANIGOSA:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_DELRISSA:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_ECK:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_ENTROPIUS:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_GRUUL:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_HAKKAR:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_HEIGAN:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_HEROD:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_HOGGER:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_IGNIS:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_ILLIDAN:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_INGVAR:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_KALITHRESH:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_LUCIFRON:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_MALCHEZAAR:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_MUTANUS:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_ONYXIA:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_THUNDERAAN:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_VANCLEEF:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_VASHJ:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_VEKNILASH:
m_uiMemoryGUID = pCreature->GetGUID();
break;
case MEMORY_VEZAX:
m_uiMemoryGUID = pCreature->GetGUID();
break;
}
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch(pGo->GetEntry())
{
case GO_CHAMPIONS_LOOT: m_uiChampionsLootGUID = add ? pGo : NULL; break;
case GO_EADRIC_LOOT: m_uiEadricLootGUID = add ? pGo : NULL; break;
case GO_PALETRESS_LOOT: m_uiPaletressLootGUID = add ? pGo : NULL; break;
case GO_CHAMPIONS_LOOT_H: m_uiChampionsLootGUID = add ? pGo : NULL; break;
case GO_EADRIC_LOOT_H: m_uiEadricLootGUID = add ? pGo : NULL; break;
case GO_PALETRESS_LOOT_H: m_uiPaletressLootGUID = add ? pGo : NULL; break;
}
}
void SetData(uint32 Type, uint32 Data)
{
switch(Type)
{
case DATA_TOC5_ANNOUNCER:
m_uiAnnouncerGUID = Data;
break;
case DATA_BLACK_KNIGHT_MINION:
m_uiBlackKnightMinionGUID = Data;
break;
case TYPE_GRAND_CHAMPIONS:
if (Data == DONE)
m_uiChampionsLootGUID->SetRespawnTime(m_uiChampionsLootGUID->GetRespawnDelay());
m_auiEncounter[0] = Data;
break;
case TYPE_ARGENT_CHALLENGE:
if (Data == DONE)
{
if(m_uiEadricGUID == m_uiArgentChallenger)
m_uiEadricLootGUID->SetRespawnTime(m_uiEadricLootGUID->GetRespawnDelay());
if(m_uiPaletressGUID == m_uiArgentChallenger)
m_uiPaletressLootGUID->SetRespawnTime(m_uiPaletressLootGUID->GetRespawnDelay());
}
m_auiEncounter[1] = Data;
break;
case TYPE_BLACK_KNIGHT:
m_auiEncounter[2] = Data;
break;
}
if (Data == DONE)
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2];
strInstData = saveStream.str();
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE;
}
}
uint64 GetData64(uint32 uiData)
{
switch(uiData)
{
case DATA_MEMORY:
return m_uiMemoryGUID;
case DATA_BLACK_KNIGHT:
return m_uiBlackKnightGUID;
}
return 0;
}
std::string GetSaveData()
{
return strInstData;
}
uint32 GetData(uint32 uiType)
{
switch(uiType)
{
case DATA_BLACK_KNIGHT_MINION:
return m_uiBlackKnightMinionGUID;
case DATA_TOC5_ANNOUNCER:
return m_uiAnnouncerGUID;
case DATA_JAEREN:
return m_uiJaerenGUID;
case DATA_ARELAS:
return m_uiArelasGUID;
case TYPE_GRAND_CHAMPIONS:
case TYPE_ARGENT_CHALLENGE:
case TYPE_BLACK_KNIGHT:
return m_auiEncounter[uiType];
}
return 0;
}
void Load(const char *chrIn)
{
if (!chrIn)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(chrIn);
std::istringstream loadStream(chrIn);
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2];
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_trial_of_the_champion(Map* pMap)
{
return new instance_trial_of_the_champion(pMap);
}
void AddSC_instance_trial_of_the_champion()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_trial_of_the_champion";
newscript->GetInstanceData = &GetInstanceData_instance_trial_of_the_champion;
newscript->RegisterSelf();
}
@@ -0,0 +1,135 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Trial Of the Champion
SD%Complete: 80%
SDComment: event script
SDCategory: trial_of_the_champion
EndScriptData */
/* ContentData
npc_toc5_announcer
EndContentData */
#include "ScriptedPch.h"
#include "trial_of_the_champion.h"
#define GOSSIP_START_EVENT1 "I'm ready to start challenge."
#define GOSSIP_START_EVENT2 "I'm ready for the next challenge."
/*######
## npc_toc5_announcer
######*/
struct TRINITY_DLL_DECL npc_toc5_announcerAI : public ScriptedAI
{
npc_toc5_announcerAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* pInstance;
uint32 chmp1, chmp2, chmp3, argent;
void Reset()
{
}
void StartEvent(Player* pPlayer)
{
if(!pInstance)
return;
if(pInstance->GetData(TYPE_GRAND_CHAMPIONS) == NOT_STARTED && pInstance->GetData(TYPE_ARGENT_CHALLENGE) == NOT_STARTED && pInstance->GetData(TYPE_BLACK_KNIGHT) == NOT_STARTED)
{
chmp1 = RAND(35572,35569,35571,35570,35617);
chmp2 = RAND(35572,35569,35571,35570,35617);
chmp3 = RAND(35572,35569,35571,35570,35617);
if(chmp1 != chmp2 && chmp2 != chmp3 && chmp1 != chmp3)
{
m_creature->SummonCreature(chmp1, 738.665771, 661.031433, 412.394623, 4.698702, TEMPSUMMON_MANUAL_DESPAWN, 0);
m_creature->SummonCreature(chmp2, 746.864441, 660.918762, 411.695465, 4.698700, TEMPSUMMON_MANUAL_DESPAWN, 0);
m_creature->SummonCreature(chmp3, 754.360779, 660.816162, 412.395996, 4.698700, TEMPSUMMON_MANUAL_DESPAWN, 0);
pInstance->SetData(TYPE_GRAND_CHAMPIONS, IN_PROGRESS);
} else return;
}
if(pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE && pInstance->GetData(TYPE_ARGENT_CHALLENGE) == NOT_STARTED && pInstance->GetData(TYPE_BLACK_KNIGHT) == NOT_STARTED)
{
argent = RAND(35119,34928);
m_creature->SummonCreature(argent, 746.864441, 660.918762, 411.695465, 4.698700, TEMPSUMMON_MANUAL_DESPAWN, 0);
pInstance->SetData(TYPE_ARGENT_CHALLENGE, IN_PROGRESS);
}
if(pInstance->GetData(TYPE_GRAND_CHAMPIONS) == DONE && pInstance->GetData(TYPE_ARGENT_CHALLENGE) == DONE && pInstance->GetData(TYPE_BLACK_KNIGHT) == NOT_STARTED)
{
m_creature->SummonCreature(NPC_BLACK_KNIGHT, 746.864441, 660.918762, 411.695465, 4.698700, TEMPSUMMON_MANUAL_DESPAWN, 0);
pInstance->SetData(TYPE_BLACK_KNIGHT, IN_PROGRESS);
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
}
void UpdateAI(const uint32 diff)
{
}
};
CreatureAI* GetAI_npc_toc5_announcer(Creature* pCreature)
{
return new npc_toc5_announcerAI(pCreature);
}
bool GossipHello_npc_toc5_announcer(Player* pPlayer, Creature* pCreature)
{
ScriptedInstance* pInstance = pCreature->GetInstanceData();
if(!pInstance)
return false;
if(pInstance->GetData(TYPE_GRAND_CHAMPIONS) == NOT_STARTED && pInstance->GetData(TYPE_ARGENT_CHALLENGE) == NOT_STARTED && pInstance->GetData(TYPE_BLACK_KNIGHT) == NOT_STARTED)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
else
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(pCreature->GetEntry(), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_toc5_announcer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
pPlayer->CLOSE_GOSSIP_MENU();
CAST_AI(npc_toc5_announcerAI, pCreature->AI())->StartEvent(pPlayer);
}
return true;
}
void AddSC_trial_of_the_champion()
{
Script* NewScript;
NewScript = new Script;
NewScript->Name = "npc_toc5_announcer";
NewScript->GetAI = &GetAI_npc_toc5_announcer;
NewScript->pGossipHello = &GossipHello_npc_toc5_announcer;
NewScript->pGossipSelect = &GossipSelect_npc_toc5_announcer;
NewScript->RegisterSelf();
}
@@ -0,0 +1,78 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_TOC_H
#define DEF_TOC_H
enum
{
MAX_ENCOUNTER = 3,
TYPE_GRAND_CHAMPIONS = 0,
TYPE_ARGENT_CHALLENGE = 1,
TYPE_BLACK_KNIGHT = 2,
DATA_BLACK_KNIGHT = 6,
DATA_BLACK_KNIGHT_MINION = 7,
DATA_TOC5_ANNOUNCER = 8,
DATA_JAEREN = 9,
DATA_ARELAS = 10,
DATA_CHAMPIONID_1 = 11,
DATA_CHAMPIONID_2 = 12,
DATA_CHAMPIONID_3 = 13,
DATA_MEMORY = 14,
DATA_ARGENT_CHALLENGER = 15,
NPC_JACOB = 34705,
NPC_AMBROSE = 34702,
NPC_COLOSOS = 34701,
NPC_JAELYNE = 34657,
NPC_LANA = 34703,
NPC_MOKRA = 35572,
NPC_ERESSEA = 35569,
NPC_RUNOK = 35571,
NPC_ZULTORE = 35570,
NPC_VISCERI = 35617,
NPC_EADRIC = 35119,
NPC_PALETRESS = 34928,
NPC_BLACK_KNIGHT = 35451,
NPC_RISEN_JAEREN = 35545,
NPC_RISEN_ARELAS = 35564,
NPC_JAEREN = 35004,
NPC_ARELAS = 35005,
MEMORY_ALGALON = 35052,
MEMORY_ARCHIMONDE = 35041,
MEMORY_CHROMAGGUS = 35033,
MEMORY_CYANIGOSA = 35046,
MEMORY_DELRISSA = 35043,
MEMORY_ECK = 35047,
MEMORY_ENTROPIUS = 35044,
MEMORY_GRUUL = 35039,
MEMORY_HAKKAR = 35034,
MEMORY_HEIGAN = 35049,
MEMORY_HEROD = 35030,
MEMORY_HOGGER = 34942,
MEMORY_IGNIS = 35050,
MEMORY_ILLIDAN = 35042,
MEMORY_INGVAR = 35045,
MEMORY_KALITHRESH = 35037,
MEMORY_LUCIFRON = 35031,
MEMORY_MALCHEZAAR = 35038,
MEMORY_MUTANUS = 35029,
MEMORY_ONYXIA = 35048,
MEMORY_THUNDERAAN = 35032,
MEMORY_VANCLEEF = 35028,
MEMORY_VASHJ = 35040,
MEMORY_VEKNILASH = 35036,
MEMORY_VEZAX = 35051,
GO_CHAMPIONS_LOOT = 195709,
GO_CHAMPIONS_LOOT_H = 195710,
GO_EADRIC_LOOT = 195374,
GO_EADRIC_LOOT_H = 195375,
GO_PALETRESS_LOOT = 195323,
GO_PALETRESS_LOOT_H = 195324
};
#endif
+116
View File
@@ -0,0 +1,116 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: Dalaran
SDAuthor: WarHead, MaXiMiUS
SD%Complete: 99%
SDComment: For what is 63990+63991? Same function but don't work correct...
SDCategory: Dalaran
Script Data End */
#include "ScriptedPch.h"
/*******************************************************
* npc_mageguard_dalaran
*******************************************************/
enum Spells
{
SPELL_TRESPASSER_A = 54028,
SPELL_TRESPASSER_H = 54029
};
enum NPCs // All outdoor guards are within 35.0f of these NPCs
{
NPC_APPLEBOUGH_A = 29547,
NPC_SWEETBERRY_H = 29715,
};
struct TRINITY_DLL_DECL npc_mageguard_dalaranAI : public Scripted_NoMovementAI
{
npc_mageguard_dalaranAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
{
pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pCreature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, true);
pCreature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
}
void Reset(){}
void Aggro(Unit* pWho){}
void AttackStart(Unit* pWho){}
void MoveInLineOfSight(Unit *pWho)
{
if (!pWho || !pWho->IsInWorld() || pWho->GetZoneId() != 4395)
return;
if (!me->IsWithinDist(pWho, 65.0f, false))
return;
Player *pPlayer = pWho->GetCharmerOrOwnerPlayerOrPlayerItself();
if (!pPlayer || pPlayer->isGameMaster() || pPlayer->IsBeingTeleported())
return;
switch (m_creature->GetEntry())
{
case 29254:
if (pPlayer->GetTeam() == HORDE) // Horde unit found in Alliance area
if (Creature *pOutdoorNPC = GetClosestCreatureWithEntry(me, NPC_APPLEBOUGH_A, 32.0f))
{
if (me->isInBackInMap(pWho, 12.0f)) // In my line of sight, "outdoors", and behind me
DoCast(pWho, SPELL_TRESPASSER_A); // Teleport the Horde unit out
}
else // In my line of sight, and "indoors"
DoCast(pWho, SPELL_TRESPASSER_A); // Teleport the Horde unit out
break;
case 29255:
if (pPlayer->GetTeam() == ALLIANCE) // Alliance unit found in Horde area
if (Creature *pOutdoorNPC = GetClosestCreatureWithEntry(me, NPC_SWEETBERRY_H, 32.0f))
{
if (me->isInBackInMap(pWho, 12.0f)) // In my line of sight, "outdoors", and behind me
DoCast(pWho, SPELL_TRESPASSER_H); // Teleport the Alliance unit out
}
else // In my line of sight, and "indoors"
DoCast(pWho, SPELL_TRESPASSER_H); // Teleport the Alliance unit out
break;
}
me->SetOrientation(me->GetHomePosition().GetOrientation());
return;
}
void UpdateAI(const uint32 diff){}
};
CreatureAI* GetAI_npc_mageguard_dalaran(Creature* pCreature)
{
return new npc_mageguard_dalaranAI(pCreature);
}
void AddSC_dalaran()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_mageguard_dalaran";
newscript->GetAI = &GetAI_npc_mageguard_dalaran;
newscript->RegisterSelf();
}
+71
View File
@@ -0,0 +1,71 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Dragonblight
SD%Complete: 100
SDComment:
SDCategory: Dragonblight
EndScriptData */
/* ContentData
npc_alexstrasza_wr_gate
EndContentData */
#include "ScriptedPch.h"
enum eEnums
{
QUEST_RETURN_TO_AG_A = 12499,
QUEST_RETURN_TO_AG_H = 12500,
MOVIE_ID_GATES = 14
};
#define GOSSIP_ITEM_WHAT_HAPPENED "Alexstrasza, can you show me what happened here?"
bool GossipHello_npc_alexstrasza_wr_gate(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestRewardStatus(QUEST_RETURN_TO_AG_A) || pPlayer->GetQuestRewardStatus(QUEST_RETURN_TO_AG_H))
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_WHAT_HAPPENED, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_alexstrasza_wr_gate(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->SendMovieStart(MOVIE_ID_GATES);
}
return true;
}
void AddSC_dragonblight()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_alexstrasza_wr_gate";
newscript->pGossipHello = &GossipHello_npc_alexstrasza_wr_gate;
newscript->pGossipSelect = &GossipSelect_npc_alexstrasza_wr_gate;
newscript->RegisterSelf();
}
@@ -0,0 +1,274 @@
/*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: Boss dred
SDAuthor: Manuel
SD%Complete: 100 %
SDComment: MAYBE need more improve the "Raptor Call".
SDCategory:
Script Data End */
#include "ScriptedPch.h"
#include "drak_tharon_keep.h"
enum eSpells
{
SPELL_BELLOWING_ROAR = 22686, // fears the group, can be resisted/dispelled
SPELL_GRIEVOUS_BITE = 48920,
SPELL_MANGLING_SLASH = 48873, //casted on the current tank, adds debuf
SPELL_FEARSOME_ROAR = 48849,
H_SPELL_FEARSOME_ROAR = 59422, //Not stacking, debuff
SPELL_PIERCING_SLASH = 48878, //debuff -->Armor reduced by 75%
SPELL_RAPTOR_CALL = 59416, //dummy
SPELL_GUT_RIP = 49710,
SPELL_REND = 13738
};
enum eArchivements
{
ACHIEV_BETTER_OFF_DRED = 2039
};
enum Creatures
{
NPC_RAPTOR_1 = 26641,
NPC_RAPTOR_2 = 26628
};
struct TRINITY_DLL_DECL boss_dredAI : public ScriptedAI
{
boss_dredAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 BellowingRoarTimer;
uint32 GrievousBiteTimer;
uint32 ManglingSlashTimer;
uint32 FearsomeRoarTimer;
uint32 PiercingSlashTimer;
uint32 RaptorCallTimer;
ScriptedInstance* pInstance;
void Reset()
{
if (pInstance)
{
pInstance->SetData(DATA_DRED_EVENT,NOT_STARTED);
pInstance->SetData(DATA_KING_DRED_ACHIEV, 0);
}
BellowingRoarTimer = 33000;
GrievousBiteTimer = 20000;
ManglingSlashTimer = 18500;
FearsomeRoarTimer = urand(10000,20000);
PiercingSlashTimer = 17000;
RaptorCallTimer = urand(20000,25000);
}
void EnterCombat(Unit* who)
{
if (pInstance)
pInstance->SetData(DATA_DRED_EVENT,IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (BellowingRoarTimer < diff)
{
DoCastAOE(SPELL_BELLOWING_ROAR, false);
BellowingRoarTimer = 40000;
} else BellowingRoarTimer -=diff;
if (GrievousBiteTimer < diff)
{
DoCastVictim(SPELL_GRIEVOUS_BITE ,false);
GrievousBiteTimer = 20000;
} else GrievousBiteTimer -=diff;
if (ManglingSlashTimer < diff)
{
DoCastVictim(SPELL_MANGLING_SLASH,false);
ManglingSlashTimer = 20000;
} else ManglingSlashTimer -=diff;
if (FearsomeRoarTimer < diff)
{
DoCastAOE(DUNGEON_MODE(SPELL_FEARSOME_ROAR, H_SPELL_FEARSOME_ROAR),false);
FearsomeRoarTimer = urand(16,18)*1000;
} else FearsomeRoarTimer -=diff;
if (PiercingSlashTimer < diff)
{
DoCastVictim(SPELL_PIERCING_SLASH,false);
PiercingSlashTimer = 20000;
} else PiercingSlashTimer -=diff;
if (RaptorCallTimer < diff)
{
DoCastVictim(SPELL_RAPTOR_CALL,false);
float x,y,z;
m_creature->GetClosePoint(x,y,z,m_creature->GetObjectSize()/3,10.0f);
m_creature->SummonCreature(RAND(NPC_RAPTOR_1,NPC_RAPTOR_2),x,y,z,0,TEMPSUMMON_DEAD_DESPAWN,1000);
RaptorCallTimer = urand(20000,25000);
} else RaptorCallTimer -=diff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
if (pInstance)
{
pInstance->SetData(DATA_DRED_EVENT,DONE);
if (IsHeroic() && pInstance->GetData(DATA_KING_DRED_ACHIEV) == 6)
pInstance->DoCompleteAchievement(ACHIEV_BETTER_OFF_DRED);
}
}
};
CreatureAI* GetAI_boss_dred(Creature* pCreature)
{
return new boss_dredAI (pCreature);
}
struct TRINITY_DLL_DECL npc_drakkari_gutripperAI : public ScriptedAI
{
npc_drakkari_gutripperAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 GutRipTimer;
void Reset()
{
GutRipTimer = urand(10000,15000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (GutRipTimer < diff)
{
DoCastVictim(SPELL_GUT_RIP,false);
GutRipTimer = urand(10000,15000);
}else GutRipTimer -=diff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
if (pInstance)
{
if (IsHeroic() && pInstance->GetData(DATA_DRED_EVENT) == IN_PROGRESS && pInstance->GetData(DATA_KING_DRED_ACHIEV) < 6)
{
pInstance->SetData(DATA_KING_DRED_ACHIEV, pInstance->GetData(DATA_KING_DRED_ACHIEV) + 1);
}
}
}
};
CreatureAI* GetAI_npc_drakkari_gutripper(Creature* pCreature)
{
return new npc_drakkari_gutripperAI (pCreature);
}
struct TRINITY_DLL_DECL npc_drakkari_scytheclawAI : public ScriptedAI
{
npc_drakkari_scytheclawAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 RendTimer;
void Reset()
{
RendTimer = urand(10000,15000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (RendTimer < diff)
{
DoCastVictim(SPELL_REND,false);
RendTimer = urand(10000,15000);
}else RendTimer -=diff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
if (pInstance)
{
if (IsHeroic() && pInstance->GetData(DATA_DRED_EVENT) == IN_PROGRESS && pInstance->GetData(DATA_KING_DRED_ACHIEV) < 6)
{
pInstance->SetData(DATA_KING_DRED_ACHIEV, pInstance->GetData(DATA_KING_DRED_ACHIEV) + 1);
}
}
}
};
CreatureAI* GetAI_npc_drakkari_scytheclaw(Creature* pCreature)
{
return new npc_drakkari_scytheclawAI (pCreature);
}
void AddSC_boss_dred()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_drakkari_gutripper";
newscript->GetAI = &GetAI_npc_drakkari_gutripper;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_drakkari_scytheclaw";
newscript->GetAI = &GetAI_npc_drakkari_scytheclaw;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_dred";
newscript->GetAI = &GetAI_boss_dred;
newscript->RegisterSelf();
}
@@ -0,0 +1,291 @@
/*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: Boss novos
SDAuthor: Tartalo
SD%Complete: 100
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_novos' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "drak_tharon_keep.h"
enum Spells
{
SPELL_ARCANE_BLAST = 49198,
H_SPELL_ARCANE_BLAST = 59909,
SPELL_ARCANE_FIELD = 47346,
SPELL_BLIZZARD = 49034,
H_SPELL_BLIZZARD = 59854,
SPELL_FROSTBOLT = 49037,
H_SPELL_FROSTBOLT = 59855,
SPELL_WRATH_OF_MISERY = 50089,
H_SPELL_WRATH_OF_MISERY = 59856,
SPELL_SUMMON_MINIONS = 59910 //Summons an army of Fetid Troll Corpses to assist the caster.
};
//not in db
enum Yells
{
SAY_AGGRO = -1600000,
SAY_KILL = -1600001,
SAY_DEATH = -1600002,
SAY_NECRO_ADD = -1600003,
SAY_REUBBLE_1 = -1600004,
SAY_REUBBLE_2 = -1600005
};
enum Creatures
{
CREATURE_RISEN_SHADOWCASTER = 27600,
CREATURE_FETID_TROLL_CORPSE = 27598,
CREATURE_HULKING_CORPSE = 27597,
CREATURE_CRYSTAL_HANDLER = 26627
};
enum CombatPhase
{
IDLE,
PHASE_1,
PHASE_2
};
enum Achievements
{
ACHIEV_OH_NOVOS = 2057
};
struct Location
{
float x,y,z;
};
static Location AddSpawnPoint = { -379.20, -816.76, 59.70};
static Location CrystalHandlerSpawnPoint = { -326.626343, -709.956604, 27.813314 };
static Location AddDestinyPoint = { -379.314545, -772.577637, 28.58837 };
struct TRINITY_DLL_DECL boss_novosAI : public Scripted_NoMovementAI
{
boss_novosAI(Creature *c) : Scripted_NoMovementAI(c), lSummons(me)
{
pInstance = c->GetInstanceData();
Reset();
}
uint32 uiTimer;
uint32 uiCrystalHandlerTimer;
bool bAchiev;
SummonList lSummons;
std::list<uint64> luiCrystals;
CombatPhase Phase;
ScriptedInstance* pInstance;
void Reset()
{
Phase = IDLE;
luiCrystals.clear();
bAchiev = true;
m_creature->CastStop();
lSummons.DespawnAll();
if (pInstance)
{
pInstance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_1));
luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_2));
luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_3));
luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_4));
for (std::list<uint64>::iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
{
if (GameObject* pTemp = pInstance->instance->GetGameObject(*itr))
pTemp->SetGoState(GO_STATE_READY);
}
}
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
Phase = PHASE_1;
uiCrystalHandlerTimer = 30000;
uiTimer = 1000;
DoCast(m_creature, SPELL_ARCANE_FIELD);
if (pInstance)
{
for (std::list<uint64>::iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
{
if (GameObject *pTemp = pInstance->instance->GetGameObject(*itr))
pTemp->SetGoState(GO_STATE_ACTIVE);
}
pInstance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
}
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
void UpdateAI(const uint32 diff)
{
switch (Phase)
{
case PHASE_1:
if (uiTimer <= diff)
{
Creature *pSummon = m_creature->SummonCreature(RAND(CREATURE_FETID_TROLL_CORPSE,CREATURE_HULKING_CORPSE,CREATURE_RISEN_SHADOWCASTER), AddSpawnPoint.x, AddSpawnPoint.y , AddSpawnPoint.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
pSummon->GetMotionMaster()->MovePoint(0, AddDestinyPoint.x, AddDestinyPoint.y, AddDestinyPoint.z);
//If spell is casted stops casting arcane field so no spell casting
//DoCast(m_creature, SPELL_SUMMON_MINIONS);
uiTimer = 3000;
} else uiTimer -= diff;
if (uiCrystalHandlerTimer <= diff)
{
//TODO: say
Creature *pCrystalHandler = m_creature->SummonCreature(CREATURE_CRYSTAL_HANDLER, CrystalHandlerSpawnPoint.x, CrystalHandlerSpawnPoint.y , CrystalHandlerSpawnPoint.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
pCrystalHandler->GetMotionMaster()->MovePoint(0, AddDestinyPoint.x, AddDestinyPoint.y, AddDestinyPoint.z);
uiCrystalHandlerTimer = urand(20000,30000);
} else uiCrystalHandlerTimer -= diff;
break;
case PHASE_2:
if (uiTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(RAND(SPELL_ARCANE_BLAST,SPELL_BLIZZARD,SPELL_FROSTBOLT,SPELL_WRATH_OF_MISERY),
RAND(H_SPELL_ARCANE_BLAST,H_SPELL_BLIZZARD,H_SPELL_FROSTBOLT,H_SPELL_WRATH_OF_MISERY)));
uiTimer = urand(1000,3000);
} else uiTimer -= diff;
break;
}
}
void JustDied(Unit* killer)
{
if (pInstance)
{
pInstance->SetData(DATA_NOVOS_EVENT, DONE);
if (IsHeroic() && bAchiev)
pInstance->DoCompleteAchievement(ACHIEV_OH_NOVOS);
}
lSummons.DespawnAll();
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(SAY_KILL, m_creature);
}
void JustSummoned(Creature *summon)
{
lSummons.Summon(summon);
}
void RemoveCrystal()
{
if (!luiCrystals.empty())
{
if (pInstance)
if (GameObject *pTemp = pInstance->instance->GetGameObject(luiCrystals.back()))
pTemp->SetGoState(GO_STATE_READY);
luiCrystals.pop_back();
}
if (luiCrystals.empty())
{
m_creature->CastStop();
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Phase = PHASE_2;
uiTimer = 1000;
}
}
};
struct TRINITY_DLL_DECL mob_crystal_handlerAI : public ScriptedAI
{
mob_crystal_handlerAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance *pInstance;
void JustDied(Unit* killer)
{
if (Creature* pNovos = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_NOVOS) : 0))
CAST_AI(boss_novosAI,pNovos->AI())->RemoveCrystal();
}
};
struct TRINITY_DLL_DECL mob_novos_minionAI : public ScriptedAI
{
mob_novos_minionAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance *pInstance;
void MovementInform(uint32 type, uint32 id)
{
if(type != POINT_MOTION_TYPE)
return;
if (Creature* pNovos = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_NOVOS) : 0))
CAST_AI(boss_novosAI, pNovos->AI())->bAchiev = false;
}
};
CreatureAI* GetAI_boss_novos(Creature* pCreature)
{
return new boss_novosAI (pCreature);
}
CreatureAI* GetAI_mob_crystal_handler(Creature* pCreature)
{
return new mob_crystal_handlerAI (pCreature);
}
CreatureAI* GetAI_mob_novos_minion(Creature* pCreature)
{
return new mob_novos_minionAI (pCreature);
}
void AddSC_boss_novos()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_novos";
newscript->GetAI = &GetAI_boss_novos;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_crystal_handler";
newscript->GetAI = &GetAI_mob_crystal_handler;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_novos_minion";
newscript->GetAI = &GetAI_mob_novos_minion;
newscript->RegisterSelf();
}
@@ -0,0 +1,268 @@
/*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: Boss Tharon'ja
SDAuthor: Tartalo
SD%Complete: 100
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_tharon_ja' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "drak_tharon_keep.h"
enum Spells
{
//skeletal spells (phase 1)
SPELL_CURSE_OF_LIFE = 49527,
H_SPELL_CURSE_OF_LIFE = 59972,
SPELL_RAIN_OF_FIRE = 49518,
H_SPELL_RAIN_OF_FIRE = 59971,
SPELL_SHADOW_VOLLEY = 49528,
H_SPELL_SHADOW_VOLLEY = 59973,
SPELL_DECAY_FLESH = 49356, //casted at end of phase 1, starts phase 2
//flesh spells (phase 2)
SPELL_GIFT_OF_THARON_JA = 52509,
SPELL_EYE_BEAM = 49544,
H_SPELL_EYE_BEAM = 59965,
SPELL_LIGHTNING_BREATH = 49537,
H_SPELL_LIGHTNING_BREATH = 59963,
SPELL_POISON_CLOUD = 49548,
H_SPELL_POISON_CLOUD = 59969,
SPELL_RETURN_FLESH = 53463 //Channeled spell ending phase two and returning to phase 1. This ability will stun the party for 6 seconds.
};
/* not needed
enum PlayerSkills
{
//Players' skills during Phase2
SPELL_PLAYER_PHASE2_SLAYING_STRIKE = 50799,
SPELL_PLAYER_PHASE2_TAUNT = 49613,
SPELL_PLAYER_PHASE2_BONE_ARMOR = 49609,
SPELL_PLAYER_PHASE2_TOUCH_OF_LIFE = 49617
};
*/
//not in db
enum Yells
{
SAY_AGGRO = -1600011,
SAY_KILL_1 = -1600012,
SAY_KILL_2 = -1600013,
SAY_FLESH_1 = -1600014,
SAY_FLESH_2 = -1600015,
SAY_SKELETON_1 = -1600016,
SAY_SKELETON_2 = -1600017,
SAY_DEATH = -1600018
};
enum Models
{
MODEL_FLESH = 27073,
MODEL_SKELETON = 27511
};
enum CombatPhase
{
SKELETAL,
GOING_FLESH,
FLESH,
GOING_SKELETAL
};
struct TRINITY_DLL_DECL boss_tharon_jaAI : public ScriptedAI
{
boss_tharon_jaAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 uiPhaseTimer;
uint32 uiCurseOfLifeTimer;
uint32 uiRainOfFireTimer;
uint32 uiShadowVolleyTimer;
uint32 uiEyeBeamTimer;
uint32 uiLightningBreathTimer;
uint32 uiPoisonCloudTimer;
CombatPhase Phase;
ScriptedInstance* pInstance;
void Reset()
{
uiPhaseTimer = 20000;
uiCurseOfLifeTimer = 1000;
uiRainOfFireTimer = urand(14000,18000);
uiShadowVolleyTimer = urand(8000,10000);
Phase = SKELETAL;
m_creature->SetDisplayId(m_creature->GetNativeDisplayId());
if (pInstance)
pInstance->SetData(DATA_THARON_JA_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_THARON_JA_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
switch (Phase)
{
case SKELETAL:
if (uiCurseOfLifeTimer < diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_CURSE_OF_LIFE, H_SPELL_CURSE_OF_LIFE));
uiCurseOfLifeTimer = urand(10000,15000);
} else uiCurseOfLifeTimer -= diff;
if (uiShadowVolleyTimer < diff)
{
DoCastVictim(DUNGEON_MODE(SPELL_SHADOW_VOLLEY,H_SPELL_SHADOW_VOLLEY));
uiShadowVolleyTimer = urand(8000,10000);
} else uiShadowVolleyTimer -= diff;
if (uiRainOfFireTimer < diff)
{
DoCastAOE(DUNGEON_MODE(SPELL_RAIN_OF_FIRE,H_SPELL_RAIN_OF_FIRE));
uiRainOfFireTimer = urand(14000,18000);
} else uiRainOfFireTimer -= diff;
if (uiPhaseTimer < diff)
{
DoCast(SPELL_DECAY_FLESH);
Phase = GOING_FLESH;
uiPhaseTimer = 6000;
} else uiPhaseTimer -= diff;
DoMeleeAttackIfReady();
break;
case GOING_FLESH:
if (uiPhaseTimer < diff)
{
DoScriptText(RAND(SAY_FLESH_1,SAY_FLESH_2),m_creature);
m_creature->SetDisplayId(MODEL_FLESH);
std::list<HostilReference*>& threatlist = m_creature->getThreatManager().getThreatList();
for (std::list<HostilReference*>::iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
{
Unit *pTemp = Unit::GetUnit((*m_creature),(*itr)->getUnitGuid());
if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER)
{
m_creature->AddAura(SPELL_GIFT_OF_THARON_JA,pTemp);
pTemp->SetDisplayId(MODEL_SKELETON);
}
}
uiPhaseTimer = 20000;
uiLightningBreathTimer = urand(3000,4000);
uiEyeBeamTimer = urand(4000,8000);
uiPoisonCloudTimer = urand(6000,7000);
Phase = FLESH;
} else uiPhaseTimer -= diff;
break;
case FLESH:
if (uiLightningBreathTimer < diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_LIGHTNING_BREATH, H_SPELL_LIGHTNING_BREATH));
uiLightningBreathTimer = urand(6000,7000);
} else uiLightningBreathTimer -= diff;
if (uiEyeBeamTimer < diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_EYE_BEAM, H_SPELL_EYE_BEAM));
uiEyeBeamTimer = urand(4000,6000);
} else uiEyeBeamTimer -= diff;
if (uiPoisonCloudTimer < diff)
{
DoCastAOE(DUNGEON_MODE(SPELL_POISON_CLOUD, H_SPELL_POISON_CLOUD));
uiPoisonCloudTimer = urand(10000,12000);
} else uiPoisonCloudTimer -= diff;
if (uiPhaseTimer < diff)
{
DoCast(SPELL_RETURN_FLESH);
Phase = GOING_SKELETAL;
uiPhaseTimer = 6000;
} else uiPhaseTimer -= diff;
DoMeleeAttackIfReady();
break;
case GOING_SKELETAL:
if (uiPhaseTimer < diff)
{
DoScriptText(RAND(SAY_SKELETON_1,SAY_SKELETON_2), m_creature);
m_creature->DeMorph();
Phase = SKELETAL;
uiPhaseTimer = 20000;
uiCurseOfLifeTimer = 1000;
uiRainOfFireTimer = urand(14000,18000);
uiShadowVolleyTimer = urand(8000,10000);
std::list<HostilReference*>& threatlist = m_creature->getThreatManager().getThreatList();
for (std::list<HostilReference*>::iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
{
Unit *pTemp = Unit::GetUnit((*m_creature),(*itr)->getUnitGuid());
if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER)
{
if (pTemp->HasAura(SPELL_GIFT_OF_THARON_JA))
pTemp->RemoveAura(SPELL_GIFT_OF_THARON_JA);
pTemp->DeMorph();
}
}
} else uiPhaseTimer -= diff;
break;
}
}
void KilledUnit(Unit *victim)
{
DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2),m_creature);
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH,m_creature);
if (pInstance)
pInstance->SetData(DATA_THARON_JA_EVENT, DONE);
}
};
CreatureAI* GetAI_boss_tharon_ja(Creature* pCreature)
{
return new boss_tharon_jaAI (pCreature);
}
void AddSC_boss_tharon_ja()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_tharon_ja";
newscript->GetAI = &GetAI_boss_tharon_ja;
newscript->RegisterSelf();
}
@@ -0,0 +1,208 @@
/*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: Boss trollgore
SDAuthor: Tartalo
SD%Complete:
SDComment: TODO: spawn troll waves
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_trollgore' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "drak_tharon_keep.h"
enum Spells
{
SPELL_INFECTED_WOUND = 49637,
SPELL_CRUSH = 49639,
SPELL_CORPSE_EXPLODE = 49555,
SPELL_CONSUME = 49380,
//Heroic spells
H_SPELL_CORPSE_EXPLODE = 59807,
H_SPELL_CONSUME = 59803
};
//not in db
enum Yells
{
SAY_AGGRO = -1600006,
SAY_KILL = -1600007,
SAY_CONSUME = -1600008,
SAY_EXPLODE = -1600009,
SAY_DEATH = -1600010
};
enum Achievements
{
ACHIEV_CONSUMPTION_JUNCTION = 2151
};
enum Creatures
{
NPC_DRAKKARI_INVADER_1 = 27753,
NPC_DRAKKARI_INVADER_2 = 27709
};
Position AddSpawnPoint = { -260.493011, -622.968018, 26.605301, 3.036870 };
struct TRINITY_DLL_DECL boss_trollgoreAI : public ScriptedAI
{
boss_trollgoreAI(Creature *c) : ScriptedAI(c), lSummons(me)
{
pInstance = c->GetInstanceData();
}
uint32 uiConsumeTimer;
uint32 uiAuraCountTimer;
uint32 uiCrushTimer;
uint32 uiInfectedWoundTimer;
uint32 uiExplodeCorpseTimer;
uint32 uiSpawnTimer;
bool bAchiev;
SummonList lSummons;
ScriptedInstance* pInstance;
void Reset()
{
uiConsumeTimer = 15000;
uiAuraCountTimer = 15500;
uiCrushTimer = urand(1000,5000);
uiInfectedWoundTimer = urand(6000,10000);
uiExplodeCorpseTimer = 3000;
uiSpawnTimer = urand(30000,40000);
bAchiev = IsHeroic();
lSummons.DespawnAll();
if (m_creature->HasAura(DUNGEON_MODE(SPELL_CONSUME,H_SPELL_CONSUME)))
m_creature->RemoveAura(DUNGEON_MODE(SPELL_CONSUME,H_SPELL_CONSUME));
if (pInstance)
pInstance->SetData(DATA_TROLLGORE_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_TROLLGORE_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiSpawnTimer <= diff)
{
uint32 spawnNumber = urand(2,DUNGEON_MODE(3,5));
for (uint8 i = 0; i < spawnNumber; ++i)
DoSpawnCreature(RAND(NPC_DRAKKARI_INVADER_1,NPC_DRAKKARI_INVADER_2), AddSpawnPoint.GetPositionX(), AddSpawnPoint.GetPositionY(), AddSpawnPoint.GetPositionZ(), AddSpawnPoint.GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000);
uiSpawnTimer = urand(30000,40000);
} else uiSpawnTimer -= diff;
if (uiConsumeTimer <= diff)
{
DoScriptText(SAY_CONSUME, m_creature);
DoCast(DUNGEON_MODE(SPELL_CONSUME, H_SPELL_CONSUME));
uiConsumeTimer = 15000;
} else uiConsumeTimer -= diff;
if (bAchiev)
{
if (uiAuraCountTimer <= diff)
{
if (Aura *pConsumeAura = m_creature->GetAura(DUNGEON_MODE(SPELL_CONSUME,H_SPELL_CONSUME)))
{
if (pConsumeAura && pConsumeAura->GetStackAmount() > 9)
bAchiev = false;
}
uiAuraCountTimer = 16000;
} else uiAuraCountTimer -= diff;
}
if (uiCrushTimer <= diff)
{
DoCastVictim(SPELL_CRUSH);
uiCrushTimer = urand(10000,15000);
} else uiCrushTimer -= diff;
if (uiInfectedWoundTimer <= diff)
{
DoCastVictim(SPELL_INFECTED_WOUND);
uiInfectedWoundTimer = urand(25000,35000);
} else uiInfectedWoundTimer -= diff;
if (uiExplodeCorpseTimer <= diff)
{
DoCast(DUNGEON_MODE(SPELL_CORPSE_EXPLODE, H_SPELL_CORPSE_EXPLODE));
DoScriptText(SAY_EXPLODE, m_creature);
uiExplodeCorpseTimer = urand(15000,19000);
} else uiExplodeCorpseTimer -= diff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
lSummons.DespawnAll();
if (pInstance)
{
if (bAchiev)
pInstance->DoCompleteAchievement(ACHIEV_CONSUMPTION_JUNCTION);
pInstance->SetData(DATA_TROLLGORE_EVENT, DONE);
}
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(SAY_KILL, m_creature);
}
void JustSummoned(Creature* summon)
{
summon->AI()->AttackStart(m_creature);
}
};
CreatureAI* GetAI_boss_trollgore(Creature* pCreature)
{
return new boss_trollgoreAI (pCreature);
}
void AddSC_boss_trollgore()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_trollgore";
newscript->GetAI = &GetAI_boss_trollgore;
newscript->RegisterSelf();
}
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DEF_DRAK_THARON_H
#define DEF_DRAK_THARON_H
enum Data
{
DATA_TROLLGORE_EVENT,
DATA_NOVOS_EVENT,
DATA_DRED_EVENT,
DATA_THARON_JA_EVENT,
DATA_KING_DRED_ACHIEV
};
enum Data64
{
DATA_TROLLGORE,
DATA_NOVOS,
DATA_DRED,
DATA_THARON_JA,
DATA_NOVOS_CRYSTAL_1,
DATA_NOVOS_CRYSTAL_2,
DATA_NOVOS_CRYSTAL_3,
DATA_NOVOS_CRYSTAL_4
};
#endif
@@ -0,0 +1,243 @@
/*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "drak_tharon_keep.h"
#define MAX_ENCOUNTER 4
/* Drak'Tharon Keep encounters:
0 - Trollgore
1 - Novos
2 - King Dred
3 - Tharon Ja
*/
enum Creatures
{
NPC_TROLLGORE = 26630,
NPC_NOVOS = 26631,
NPC_KING_DRED = 27483,
NPC_THARON_JA = 26632
};
enum GameObjects
{
GO_NOVOS_CRYSTAL_1 = 189299,
GO_NOVOS_CRYSTAL_2 = 189300,
GO_NOVOS_CRYSTAL_3 = 189301,
GO_NOVOS_CRYSTAL_4 = 189302
};
struct TRINITY_DLL_DECL instance_drak_tharon : public ScriptedInstance
{
instance_drak_tharon(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
uint8 uiDredAchievCounter;
uint64 uiTrollgore;
uint64 uiNovos;
uint64 uiDred;
uint64 uiTharonJa;
uint64 uiNovosCrystal1;
uint64 uiNovosCrystal2;
uint64 uiNovosCrystal3;
uint64 uiNovosCrystal4;
uint8 m_auiEncounter[MAX_ENCOUNTER];
std::string str_data;
void Initialize()
{
uiTrollgore = 0;
uiNovos = 0;
uiDred = 0;
uiTharonJa = 0;
uiNovosCrystal1 = 0;
uiNovosCrystal2 = 0;
uiNovosCrystal3 = 0;
uiNovosCrystal4 = 0;
uiDredAchievCounter = 0;
}
bool IsEncounterInProgress() const
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
return false;
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch(pGo->GetEntry())
{
case GO_NOVOS_CRYSTAL_1:
uiNovosCrystal1 = pGo->GetGUID();
break;
case GO_NOVOS_CRYSTAL_2:
uiNovosCrystal2 = pGo->GetGUID();
break;
case GO_NOVOS_CRYSTAL_3:
uiNovosCrystal3 = pGo->GetGUID();
break;
case GO_NOVOS_CRYSTAL_4:
uiNovosCrystal4 = pGo->GetGUID();
break;
}
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case NPC_TROLLGORE:
uiTrollgore = pCreature->GetGUID();
break;
case NPC_NOVOS:
uiNovos = pCreature->GetGUID();
break;
case NPC_KING_DRED:
uiDred = pCreature->GetGUID();
break;
case NPC_THARON_JA:
uiTharonJa = pCreature->GetGUID();
break;
}
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_TROLLGORE: return uiTrollgore;
case DATA_NOVOS: return uiNovos;
case DATA_DRED: return uiDred;
case DATA_THARON_JA: return uiTharonJa;
case DATA_NOVOS_CRYSTAL_1: return uiNovosCrystal1;
case DATA_NOVOS_CRYSTAL_2: return uiNovosCrystal2;
case DATA_NOVOS_CRYSTAL_3: return uiNovosCrystal3;
case DATA_NOVOS_CRYSTAL_4: return uiNovosCrystal4;
}
return 0;
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_TROLLGORE_EVENT:
m_auiEncounter[0] = data;
break;
case DATA_NOVOS_EVENT:
m_auiEncounter[1] = data;
break;
case DATA_DRED_EVENT:
m_auiEncounter[2] = data;
break;
case DATA_THARON_JA_EVENT:
m_auiEncounter[3] = data;
break;
case DATA_KING_DRED_ACHIEV:
uiDredAchievCounter = data;
break;
}
if (data == DONE)
{
SaveToDB();
}
}
uint32 GetData(uint32 type)
{
switch (type)
{
case DATA_TROLLGORE_EVENT: return m_auiEncounter[0];
case DATA_NOVOS_EVENT: return m_auiEncounter[1];
case DATA_DRED_EVENT: return m_auiEncounter[2];
case DATA_THARON_JA_EVENT: return m_auiEncounter[3];
case DATA_KING_DRED_ACHIEV: return uiDredAchievCounter;
}
return 0;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::string str_data;
std::ostringstream saveStream;
saveStream << "D K " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
<< m_auiEncounter[2] << " " << m_auiEncounter[3];
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in)
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0,data1,data2,data3;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
if (dataHead1 == 'D' && dataHead2 == 'K')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
m_auiEncounter[3] = data3;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_drak_tharon(Map* pMap)
{
return new instance_drak_tharon(pMap);
}
void AddSC_instance_drak_tharon()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_drak_tharon";
newscript->GetInstanceData = &GetInstanceData_instance_drak_tharon;
newscript->RegisterSelf();
}
+127
View File
@@ -0,0 +1,127 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Grizzly_Hills
SD%Complete: 80
SDComment: Quest support: 12231, 12247
SDCategory: Grizzly Hills
EndScriptData */
/* ContentData
npc_orsonn_and_kodian
EndContentData */
#include "ScriptedPch.h"
#define GOSSIP_ITEM1 "You're free to go Orsonn, but first tell me what's wrong with the furbolg."
#define GOSSIP_ITEM2 "What happened then?"
#define GOSSIP_ITEM3 "Thank you, Son of Ursoc. I'll see what can be done."
#define GOSSIP_ITEM4 "Who was this stranger?"
#define GOSSIP_ITEM5 "Thank you, Kodian. I'll do what I can."
enum eEnums
{
GOSSIP_TEXTID_ORSONN1 = 12793,
GOSSIP_TEXTID_ORSONN2 = 12794,
GOSSIP_TEXTID_ORSONN3 = 12796,
GOSSIP_TEXTID_KODIAN1 = 12797,
GOSSIP_TEXTID_KODIAN2 = 12798,
NPC_ORSONN = 27274,
NPC_KODIAN = 27275,
//trigger creatures
NPC_ORSONN_CREDIT = 27322,
NPC_KODIAN_CREDIT = 27321,
QUEST_CHILDREN_OF_URSOC = 12247,
QUEST_THE_BEAR_GODS_OFFSPRING = 12231
};
bool GossipHello_npc_orsonn_and_kodian(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_CHILDREN_OF_URSOC) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(QUEST_THE_BEAR_GODS_OFFSPRING) == QUEST_STATUS_INCOMPLETE)
{
switch(pCreature->GetEntry())
{
case NPC_ORSONN:
if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_CHILDREN_OF_URSOC, NPC_ORSONN_CREDIT) || !pPlayer->GetReqKillOrCastCurrentCount(QUEST_THE_BEAR_GODS_OFFSPRING, NPC_ORSONN_CREDIT))
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN1, pCreature->GetGUID());
return true;
}
break;
case NPC_KODIAN:
if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_CHILDREN_OF_URSOC, NPC_KODIAN_CREDIT) || !pPlayer->GetReqKillOrCastCurrentCount(QUEST_THE_BEAR_GODS_OFFSPRING, NPC_KODIAN_CREDIT))
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_KODIAN1, pCreature->GetGUID());
return true;
}
break;
}
}
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_orsonn_and_kodian(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN2, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN3, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->TalkedToCreature(NPC_ORSONN_CREDIT, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_KODIAN2, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->TalkedToCreature(NPC_KODIAN_CREDIT, pCreature->GetGUID());
break;
}
return true;
}
void AddSC_grizzly_hills()
{
Script* newscript;
newscript = new Script;
newscript->Name = "npc_orsonn_and_kodian";
newscript->pGossipHello = &GossipHello_npc_orsonn_and_kodian;
newscript->pGossipSelect = &GossipSelect_npc_orsonn_and_kodian;
newscript->RegisterSelf();
}
@@ -0,0 +1,324 @@
/*
* Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Script Data Start
SDName: Boss Drakkari Colossus
SDAuthor: Manuel
SD%Complete: 95 %
SDComment: The event with the Living Mojos is not implemented, just is done that when one of the mojos around the boss take damage will make the boss enter in combat!
SDCategory:
Script Data End */
#include "ScriptedPch.h"
#include "gundrak.h"
enum Spells
{
SPELL_EMERGE = 54850,
SPELL_MIGHTY_BLOW = 54719,
SPELL_MERGE = 54878,
SPELL_SURGE = 54801,
SPELL_FREEZE_ANIM = 16245,
SPELL_MOJO_PUDDLE = 55627,
H_SPELL_MOJO_PUDDLE = 58994,
SPELL_MOJO_WAVE = 55626,
H_SPELL_MOJO_WAVE = 58993
};
struct TRINITY_DLL_DECL boss_drakkari_colossusAI : public ScriptedAI
{
boss_drakkari_colossusAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* pInstance;
bool bHealth;
bool bHealth1;
uint32 MightyBlowTimer;
void Reset()
{
if (pInstance)
pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, NOT_STARTED);
if(!m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->clearUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
m_creature->SetReactState(REACT_PASSIVE);
MightyBlowTimer = 10000;
bHealth = false;
bHealth1 = false;
}
void EnterCombat(Unit* who)
{
if (pInstance)
pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, IN_PROGRESS);
}
void CreatureState(Creature* pWho, bool bRestore = false)
{
if (!pWho)
return;
if (bRestore)
{
pWho->clearUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
pWho->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if (pWho == m_creature)
m_creature->RemoveAura(SPELL_FREEZE_ANIM);
}else
{
pWho->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pWho->addUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
if (pWho == m_creature)
DoCast(m_creature,SPELL_FREEZE_ANIM);
}
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (!bHealth && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() >= 6)
{
CreatureState(m_creature, false);
DoCast(m_creature,SPELL_FREEZE_ANIM);
DoCast(m_creature,SPELL_EMERGE);
bHealth = true;
}
if (!bHealth1 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 5)
{
DoCast(m_creature,SPELL_EMERGE);
CreatureState(m_creature, false);
bHealth1 = true;
m_creature->RemoveAllAuras();
}
if (MightyBlowTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_MIGHTY_BLOW, true);
MightyBlowTimer = 10000;
} else MightyBlowTimer -= diff;
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED))
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
if (pInstance)
pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, DONE);
}
void JustSummoned(Creature* pSummon)
{
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 5)
pSummon->DealDamage(pSummon, pSummon->GetHealth() * 0.5 , NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
pSummon->AI()->AttackStart(m_creature->getVictim());
}
};
struct TRINITY_DLL_DECL boss_drakkari_elementalAI : public ScriptedAI
{
boss_drakkari_elementalAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
if(pInstance)
{
if (pCreature->GetMap()->IsDungeon())
pColossus = CAST_CRE(pCreature->GetUnit(*pCreature, pInstance->GetData64(DATA_DRAKKARI_COLOSSUS)));
}
}
Creature* pColossus;
ScriptedInstance* pInstance;
uint32 uiSurgeTimer;
bool bGoToColossus;
void Reset()
{
if (pColossus)
CAST_AI(boss_drakkari_colossusAI, pColossus->AI())->CreatureState(m_creature, true);
uiSurgeTimer = 7000;
bGoToColossus = false;
}
void EnterEvadeMode()
{
m_creature->RemoveFromWorld();
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if (uiType != POINT_MOTION_TYPE)
return;
CAST_AI(boss_drakkari_colossusAI, pColossus->AI())->CreatureState(pColossus, true);
CAST_AI(boss_drakkari_colossusAI, pColossus->AI())->bHealth1 = false;
m_creature->RemoveFromWorld();
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if(!UpdateVictim())
return;
if(!bGoToColossus && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50 && pColossus->GetHealth()*100 / pColossus->GetMaxHealth() >= 6)
{
m_creature->InterruptNonMeleeSpells(true);
if (pColossus)
DoCast(pColossus, SPELL_MERGE);
bGoToColossus = true;
}
if (uiSurgeTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_SURGE);
uiSurgeTimer = 7000;
} else uiSurgeTimer -= diff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
if (!pColossus)
return;
pColossus->Kill(pColossus);
}
};
struct TRINITY_DLL_DECL npc_living_mojoAI : public ScriptedAI
{
npc_living_mojoAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
Creature* pColossus;
ScriptedInstance* pInstance;
uint32 uiMojoWaveTimer;
uint32 uiMojoPuddleTimer;
void Reset()
{
uiMojoWaveTimer = 2000;
uiMojoPuddleTimer = 7000;
}
void EnterCombat(Unit* who)
{
if (pInstance)
pColossus = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_DRAKKARI_COLOSSUS));
//Check if the npc is near of Drakkari Colossus.
if (pColossus && pColossus->isAlive() && m_creature->IsInRange3d(pColossus->GetHomePosition().GetPositionX(),pColossus->GetHomePosition().GetPositionY(),pColossus->GetHomePosition().GetPositionZ(),0.0f,17.0f))
m_creature->SetReactState(REACT_PASSIVE);
else
m_creature->SetReactState(REACT_AGGRESSIVE);
}
void DamageTaken(Unit* pDone_by, uint32& uiDamage)
{
if (m_creature->HasReactState(REACT_PASSIVE))
{
if (pColossus && pColossus->isAlive() && !pColossus->isInCombat())
{
pColossus->RemoveAura(SPELL_FREEZE_ANIM);
pColossus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
pColossus->SetReactState(REACT_AGGRESSIVE);
if (pDone_by && pDone_by->isAlive())
pColossus->AI()->AttackStart(pDone_by);
EnterEvadeMode();
}
}
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiMojoWaveTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_MOJO_WAVE, H_SPELL_MOJO_WAVE));
uiMojoWaveTimer = 15000;
} else uiMojoWaveTimer -= diff;
if (uiMojoPuddleTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_MOJO_PUDDLE, H_SPELL_MOJO_PUDDLE));
uiMojoPuddleTimer = 18000;
} else uiMojoPuddleTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_drakkari_colossus(Creature* pCreature)
{
return new boss_drakkari_colossusAI (pCreature);
}
CreatureAI* GetAI_boss_drakkari_elemental(Creature* pCreature)
{
return new boss_drakkari_elementalAI (pCreature);
}
CreatureAI* GetAI_npc_living_mojo(Creature* pCreature)
{
return new npc_living_mojoAI (pCreature);
}
void AddSC_boss_drakkari_colossus()
{
Script* newscript;
newscript = new Script;
newscript->Name = "boss_drakkari_colossus";
newscript->GetAI = &GetAI_boss_drakkari_colossus;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_drakkari_elemental";
newscript->GetAI = &GetAI_boss_drakkari_elemental;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_living_mojo";
newscript->GetAI = &GetAI_npc_living_mojo;
newscript->RegisterSelf();
}
+128
View File
@@ -0,0 +1,128 @@
/* Script Data Start
SDName: Boss Eck the Ferocious
SDAuthor: LordVanMartin
SD%Complete:
SDComment: Only appears in Heroic mode
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = '' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "gundrak.h"
enum Spells
{
SPELL_ECK_BERSERK = 55816, //Eck goes berserk, increasing his attack speed by 150% and all damage he deals by 500%.
SPELL_ECK_BITE = 55813, //Eck bites down hard, inflicting 150% of his normal damage to an enemy.
SPELL_ECK_SPIT = 55814, //Eck spits toxic bile at enemies in a cone in front of him, inflicting 2970 Nature damage and draining 220 mana every 1 sec for 3 sec.
SPELL_ECK_SPRING_1 = 55815, //Eck leaps at a distant target. --> Drops aggro and charges a random player. Tank can simply taunt him back.
SPELL_ECK_SPRING_2 = 55837 //Eck leaps at a distant target.
};
struct TRINITY_DLL_DECL boss_eckAI : public ScriptedAI
{
boss_eckAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 uiBerserkTimer;
uint32 uiBiteTimer;
uint32 uiSpitTimer;
uint32 uiSpringTimer;
bool bBerserk;
ScriptedInstance* pInstance;
void Reset()
{
uiBerserkTimer = 60000 + rand()%30000; //60-90 secs according to wowwiki
uiBiteTimer = 5000;
uiSpitTimer = 10000;
uiSpringTimer = 8000;
bBerserk = false;
if (pInstance)
pInstance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
if (pInstance)
pInstance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiBiteTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_ECK_BITE);
uiBiteTimer = 8000 + rand()%4000;
} else uiBiteTimer -= diff;
if (uiSpitTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_ECK_SPIT);
uiSpitTimer = 6000 + rand()%8000;
} else uiSpitTimer -= diff;
if (uiSpringTimer <= diff)
{
Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1);
if(pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
{
DoCast(pTarget, RAND(SPELL_ECK_SPRING_1, SPELL_ECK_SPRING_2));
uiSpringTimer = 5000 + rand()%10000;
}
} else uiSpringTimer -= diff;
//Berserk on timer or 20% of health
if (!bBerserk)
{
if (uiBerserkTimer <= diff)
{
DoCast(m_creature, SPELL_ECK_BERSERK);
bBerserk = true;
}
else
{
uiBerserkTimer -= diff;
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 20)
{
DoCast(m_creature, SPELL_ECK_BERSERK);
bBerserk = true;
}
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
if (pInstance)
pInstance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, DONE);
}
};
CreatureAI* GetAI_boss_eck(Creature* pCreature)
{
return new boss_eckAI (pCreature);
}
void AddSC_boss_eck()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_eck";
newscript->GetAI = &GetAI_boss_eck;
newscript->RegisterSelf();
}
@@ -0,0 +1,200 @@
/* Script Data Start
SDName: Boss gal_darah
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = '' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "gundrak.h"
//Spells
enum Spells
{
SPELL_ENRAGE = 55285,
H_SPELL_ENRAGE = 59828,
SPELL_IMPALING_CHARGE = 54956,
H_SPELL_IMPALING_CHARGE = 59827,
SPELL_STOMP = 55292,
H_SPELL_STOMP = 59826,
SPELL_PUNCTURE = 55276,
H_SPELL_PUNCTURE = 59826,
SPELL_STAMPEDE = 55218,
SPELL_WHIRLING_SLASH = 55249,
H_SPELL_WHIRLING_SLASH = 55825
};
//Yells
enum Yells
{
SAY_AGGRO = -1604000,
SAY_SLAY_1 = -1604001,
SAY_SLAY_2 = -1604002,
SAY_SLAY_3 = -1604003,
SAY_DEATH = -1604004,
SAY_SUMMON_RHINO_1 = -1604005,
SAY_SUMMON_RHINO_2 = -1604006,
SAY_SUMMON_RHINO_3 = -1604007,
SAY_TRANSFORM_1 = -1604008, //Phase change
SAY_TRANSFORM_2 = -1604009
};
enum CombatPhase
{
TROLL,
RHINO
};
struct TRINITY_DLL_DECL boss_gal_darahAI : public ScriptedAI
{
boss_gal_darahAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 uiStampedeTimer;
uint32 uiWhirlingSlashTimer;
uint32 uiPunctureTimer;
uint32 uiEnrageTimer;
uint32 uiImpalingChargeTimer;
uint32 uiStompTimer;
CombatPhase Phase;
uint8 uiPhaseCounter;
ScriptedInstance* pInstance;
void Reset()
{
uiStampedeTimer = 10000;
uiWhirlingSlashTimer = 20000;
uiPunctureTimer = 10000;
uiEnrageTimer = 15000;
uiImpalingChargeTimer = 20000;
uiStompTimer = 25000;
Phase = TROLL;
if (pInstance)
pInstance->SetData(DATA_GAL_DARAH_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_GAL_DARAH_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
switch (Phase)
{
case TROLL:
if (uiPhaseCounter == 2)
{
//FIX: implement transformation
Phase = RHINO;
uiPhaseCounter = 0;
DoScriptText(SAY_TRANSFORM_1,m_creature);
}
else
{
if (uiStampedeTimer <= diff)
{
DoCast(m_creature, SPELL_STAMPEDE);
DoScriptText(RAND(SAY_SUMMON_RHINO_1,SAY_SUMMON_RHINO_2,SAY_SUMMON_RHINO_3),m_creature);
uiStampedeTimer = 15000;
} else uiStampedeTimer -= diff;
if (uiWhirlingSlashTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_WHIRLING_SLASH, H_SPELL_WHIRLING_SLASH));
uiWhirlingSlashTimer = 20000;
++uiPhaseCounter;
} else uiWhirlingSlashTimer -= diff;
}
break;
case RHINO:
if (uiPhaseCounter == 2)
{
//FIX: implement transformation
Phase = TROLL;
uiPhaseCounter = 0;
DoScriptText(SAY_TRANSFORM_2,m_creature);
}
else
{
if (uiPunctureTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_PUNCTURE, H_SPELL_PUNCTURE));
uiPunctureTimer = 8000;
} else uiPunctureTimer -= diff;
if (uiEnrageTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_ENRAGE, H_SPELL_ENRAGE));
uiEnrageTimer = 20000;
} else uiEnrageTimer -= diff;
if (uiStompTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_STOMP, H_SPELL_STOMP));
uiStompTimer = 20000;
} else uiStompTimer -= diff;
if (uiImpalingChargeTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_IMPALING_CHARGE, H_SPELL_IMPALING_CHARGE));
uiImpalingChargeTimer = 30000;
++uiPhaseCounter;
} else uiImpalingChargeTimer -= diff;
}
break;
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_GAL_DARAH_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
};
CreatureAI* GetAI_boss_gal_darah(Creature* pCreature)
{
return new boss_gal_darahAI (pCreature);
}
void AddSC_boss_gal_darah()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_gal_darah";
newscript->GetAI = &GetAI_boss_gal_darah;
newscript->RegisterSelf();
}
@@ -0,0 +1,177 @@
/* Script Data Start
SDName: Boss moorabi
SDAuthor: Manuel
SD%Complete: 100%
SDComment: Maybe needs better timers.
SDCategory: Gundrak
Script Data End */
#include "ScriptedPch.h"
#include "gundrak.h"
enum eSpells
{
SPELL_DETERMINED_STAB = 55104,
SPELL_GROUND_TREMOR = 55142,
SPELL_NUMBING_SHOUT = 55106,
SPELL_DETERMINED_GORE = 55102,
SPELL_DETERMINED_GORE_1 = 59444,
SPELL_QUAKE = 55101,
SPELL_NUMBING_ROAR = 55100,
SPELL_MOJO_FRENZY = 55163,
SPELL_TRANSFORMATION = 55098, //Periodic, The caster transforms into a powerful mammoth, increasing Physical damage done by 25% and granting immunity to Stun effects.
};
enum eArchivements
{
ACHIEVEMENT_LESS_RABI = 2040
};
enum eSays
{
SAY_AGGRO = -1604010,
//SAY_SLAY_1 = -1604011, // not in db
SAY_SLAY_2 = -1604012,
SAY_SLAY_3 = -1604013,
SAY_DEATH = -1604014,
SAY_TRANSFORM = -1604015,
SAY_QUAKE = -1604016,
EMOTE_TRANSFORM = -1604017
};
struct TRINITY_DLL_DECL boss_moorabiAI : public ScriptedAI
{
boss_moorabiAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* pInstance;
bool bPhase;
uint32 uiNumblingShoutTimer;
uint32 uiGroundTremorTimer;
uint32 uiDeterminedStabTimer;
uint32 uiTransformationTImer;
void Reset()
{
uiGroundTremorTimer = 18000;
uiNumblingShoutTimer = 10000;
uiDeterminedStabTimer = 20000;
uiTransformationTImer = 12000;
bPhase = false;
if (pInstance)
pInstance->SetData(DATA_MOORABI_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* pWho)
{
DoScriptText(SAY_AGGRO, m_creature);
DoCast(m_creature, SPELL_MOJO_FRENZY, true);
if (pInstance)
pInstance->SetData(DATA_MOORABI_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if(!bPhase && m_creature->HasAura(SPELL_TRANSFORMATION))
{
bPhase = true;
m_creature->RemoveAura(SPELL_MOJO_FRENZY);
}
if (uiGroundTremorTimer <= uiDiff)
{
DoScriptText(SAY_QUAKE, m_creature);
if (bPhase)
DoCast(m_creature->getVictim(), SPELL_QUAKE, true);
else
DoCast(m_creature->getVictim(), SPELL_GROUND_TREMOR, true);
uiGroundTremorTimer = 10000;
} else uiGroundTremorTimer -= uiDiff;
if (uiNumblingShoutTimer <= uiDiff)
{
if (bPhase)
DoCast(m_creature->getVictim(), SPELL_NUMBING_ROAR, true);
else
DoCast(m_creature->getVictim(), SPELL_NUMBING_SHOUT, true);
uiNumblingShoutTimer = 10000;
} else uiNumblingShoutTimer -=uiDiff;
if (uiDeterminedStabTimer <= uiDiff)
{
if (bPhase)
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_DETERMINED_GORE, SPELL_DETERMINED_GORE_1));
else
DoCast(m_creature->getVictim(), SPELL_DETERMINED_STAB, true);
uiDeterminedStabTimer = 8000;
} else uiDeterminedStabTimer -=uiDiff;
if (!bPhase && uiTransformationTImer <= uiDiff)
{
DoScriptText(EMOTE_TRANSFORM, m_creature);
DoScriptText(SAY_TRANSFORM, m_creature);
DoCast(m_creature, SPELL_TRANSFORMATION, false);
uiTransformationTImer = 10000;
} else uiTransformationTImer -= uiDiff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* pKiller)
{
DoScriptText(SAY_DEATH, m_creature);
if (IsHeroic() && !bPhase)
{
AchievementEntry const *AchievLessRabi = GetAchievementStore()->LookupEntry(ACHIEVEMENT_LESS_RABI);
if (AchievLessRabi)
{
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievLessRabi);
}
}
}
if (pInstance)
pInstance->SetData(DATA_MOORABI_EVENT, DONE);
}
void KilledUnit(Unit* pVictim)
{
if (pVictim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
};
CreatureAI* GetAI_boss_moorabi(Creature *pCreature)
{
return new boss_moorabiAI(pCreature);
}
void AddSC_boss_moorabi()
{
Script* newscript;
newscript = new Script;
newscript->Name = "boss_moorabi";
newscript->GetAI = &GetAI_boss_moorabi;
newscript->RegisterSelf();
}
@@ -0,0 +1,260 @@
/* Script Data Start
SDName: Boss slad_ran
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_slad_ran' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "gundrak.h"
//Spells
enum Spells
{
SPELL_POISON_NOVA = 55081,
H_SPELL_POISON_NOVA = 59842,
SPELL_POWERFULL_BITE = 48287,
H_SPELL_POWERFULL_BITE = 59840,
SPELL_VENOM_BOLT = 54970,
H_SPELL_VENOM_BOLT = 59839
};
//Yell
enum Yells
{
SAY_AGGRO = -1604017,
SAY_SLAY_1 = -1604018,
SAY_SLAY_2 = -1604019,
SAY_SLAY_3 = -1604020,
SAY_DEATH = -1604021,
SAY_SUMMON_SNAKES = -1604022,
SAY_SUMMON_CONSTRICTORS = -1604023
};
//Creatures
enum Creatures
{
CREATURE_SNAKE = 29680,
CREATURE_CONSTRICTORS = 29713
};
//Creatures' spells
enum ConstrictorSpells
{
SPELL_GRIP_OF_SLAD_RAN = 55093,
SPELL_VENOMOUS_BITE = 54987,
H_SPELL_VENOMOUS_BITE = 58996
};
// Spawning locations
struct Locations
{
float x, y, z, orientation;
};
static Locations SpawnLoc[]=
{
{1783.81, 646.637, 133.948, 3.71755},
{1775.03, 606.586, 134.165, 1.43117},
{1717.39, 630.041, 129.282, 5.96903},
{1765.66, 646.542, 134.02, 5.11381},
{1716.76, 635.159, 129.282, 0.191986}
};
struct TRINITY_DLL_DECL boss_slad_ranAI : public ScriptedAI
{
boss_slad_ranAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 uiPoisonNovaTimer;
uint32 uiPowerfullBiteTimer;
uint32 uiVenomBoltTimer;
uint32 uiSpawnTimer;
uint8 uiPhase;
ScriptedInstance* pInstance;
void Reset()
{
uiPoisonNovaTimer = 10000;
uiPowerfullBiteTimer = 3000;
uiVenomBoltTimer = 15000;
uiSpawnTimer = 5000;
uiPhase = 0;
if (pInstance)
pInstance->SetData(DATA_SLAD_RAN_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_SLAD_RAN_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiPoisonNovaTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_POISON_NOVA, H_SPELL_POISON_NOVA));
uiPoisonNovaTimer = 15000;
} else uiPoisonNovaTimer -= diff;
if (uiPowerfullBiteTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_POWERFULL_BITE, H_SPELL_POWERFULL_BITE));
uiPowerfullBiteTimer = 10000;
} else uiPowerfullBiteTimer -= diff;
if (uiVenomBoltTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_VENOM_BOLT, H_SPELL_VENOM_BOLT));
uiVenomBoltTimer = 10000;
} else uiVenomBoltTimer -= diff;
if (uiPhase)
{
if (uiSpawnTimer <= diff)
{
if (uiPhase == 1)
for (uint8 i = 0; i < DUNGEON_MODE(3, 5); ++i)
m_creature->SummonCreature(CREATURE_SNAKE, SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z, SpawnLoc[i].orientation, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
if (uiPhase == 2)
for (uint8 i = 0; i < DUNGEON_MODE(3, 5); ++i)
m_creature->SummonCreature(CREATURE_CONSTRICTORS, SpawnLoc[i].x, SpawnLoc[i].y, SpawnLoc[i].z, SpawnLoc[i].orientation, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
uiSpawnTimer = 5000;
} else uiSpawnTimer -= diff;
}
if ((uiPhase == 0) && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30)
{
DoScriptText(SAY_SUMMON_SNAKES,m_creature);
uiPhase = 1;
}
if ((uiPhase == 1) && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25)
{
DoScriptText(SAY_SUMMON_CONSTRICTORS,m_creature);
uiPhase = 2;
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_SLAD_RAN_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
void JustSummoned(Creature* summoned)
{
summoned->GetMotionMaster()->MovePoint(0,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ());
}
};
struct TRINITY_DLL_DECL mob_slad_ran_constrictorAI : public ScriptedAI
{
mob_slad_ran_constrictorAI(Creature *c) : ScriptedAI(c) {}
uint32 uiGripOfSladRanTimer;
void Reset()
{
uiGripOfSladRanTimer = 1000;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (uiGripOfSladRanTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_GRIP_OF_SLAD_RAN);
uiGripOfSladRanTimer = 5000;
} else uiGripOfSladRanTimer -= diff;
}
ScriptedInstance* pInstance;
};
struct TRINITY_DLL_DECL mob_slad_ran_viperAI : public ScriptedAI
{
mob_slad_ran_viperAI(Creature *c) : ScriptedAI(c) {}
uint32 uiVenomousBiteTimer;
ScriptedInstance* pInstance;
void Reset()
{
uiVenomousBiteTimer = 2000;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (uiVenomousBiteTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_VENOMOUS_BITE, H_SPELL_VENOMOUS_BITE));
uiVenomousBiteTimer = 10000;
} else uiVenomousBiteTimer -= diff;
}
};
CreatureAI* GetAI_boss_slad_ran(Creature* pCreature)
{
return new boss_slad_ranAI (pCreature);
}
CreatureAI* GetAI_mob_slad_ran_constrictor(Creature* pCreature)
{
return new mob_slad_ran_constrictorAI (pCreature);
}
CreatureAI* GetAI_mob_slad_ran_viper(Creature* pCreature)
{
return new mob_slad_ran_viperAI (pCreature);
}
void AddSC_boss_slad_ran()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_slad_ran";
newscript->GetAI = &GetAI_boss_slad_ran;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_slad_ran_constrictor";
newscript->GetAI = &GetAI_mob_slad_ran_constrictor;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_slad_ran_viper";
newscript->GetAI = &GetAI_mob_slad_ran_viper;
newscript->RegisterSelf();
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef DEF_GUNDRAK_H
#define DEF_GUNDRAK_H
enum Data
{
DATA_SLAD_RAN_EVENT,
DATA_MOORABI_EVENT,
DATA_DRAKKARI_COLOSSUS_EVENT,
DATA_GAL_DARAH_EVENT,
DATA_ECK_THE_FEROCIOUS_EVENT
};
enum Data64
{
DATA_SLAD_RAN_ALTAR,
DATA_MOORABI_ALTAR,
DATA_DRAKKARI_COLOSSUS_ALTAR,
DATA_SLAD_RAN_STATUE,
DATA_MOORABI_STATUE,
DATA_DRAKKARI_COLOSSUS_STATUE,
DATA_DRAKKARI_COLOSSUS
};
#endif
@@ -0,0 +1,503 @@
#include "ScriptedPch.h"
#include "gundrak.h"
#define MAX_ENCOUNTER 5
/* GunDrak encounters:
0 - Slad'Ran
1 - Moorabi
2 - Drakkari Colossus
3 - Gal'Darah
4 - Eck the Ferocious
*/
struct TRINITY_DLL_DECL instance_gundrak : public ScriptedInstance
{
instance_gundrak(Map* pMap) : ScriptedInstance(pMap)
{
bHeroicMode = pMap->IsHeroic();
Initialize();
};
bool bHeroicMode;
bool spawnSupport;
uint32 timer;
uint32 phase;
uint64 toActivate;
uint64 uiSladRan;
uint64 uiMoorabi;
uint64 uiDrakkariColossus;
uint64 uiGalDarah;
uint64 uiEckTheFerocious;
uint64 uiSladRanAltar;
uint64 uiMoorabiAltar;
uint64 uiDrakkariColossusAltar;
uint64 uiSladRanStatue;
uint64 uiMoorabiStatue;
uint64 uiDrakkariColossusStatue;
uint64 uiGalDarahStatue;
uint64 uiEckTheFerociousDoor;
uint64 uiEckTheFerociousDoorBehind;
uint64 uiGalDarahDoor1;
uint64 uiGalDarahDoor2;
uint64 uiBridge;
uint64 uiCollision;
uint32 m_auiEncounter[MAX_ENCOUNTER];
GOState uiSladRanStatueState;
GOState uiMoorabiStatueState;
GOState uiDrakkariColossusStatueState;
GOState uiGalDarahStatueState;
GOState uiBridgeState;
GOState uiCollisionState;
std::string str_data;
void Initialize()
{
spawnSupport = false;
timer = 0;
phase = 0;
toActivate = 0;
uiSladRan = 0;
uiMoorabi = 0;
uiDrakkariColossus = 0;
uiGalDarah = 0;
uiEckTheFerocious = 0;
uiSladRanAltar = 0;
uiMoorabiAltar = 0;
uiDrakkariColossusAltar = 0;
uiSladRanStatue = 0;
uiMoorabiStatue = 0;
uiDrakkariColossusStatue = 0;
uiGalDarahStatue = 0;
uiEckTheFerociousDoor = 0;
uiEckTheFerociousDoorBehind = 0;
uiGalDarahDoor1 = 0;
uiGalDarahDoor2 = 0;
uiBridge = 0;
uiCollision = 0;
uiSladRanStatueState = GO_STATE_ACTIVE;
uiMoorabiStatueState = GO_STATE_ACTIVE;
uiDrakkariColossusStatueState = GO_STATE_ACTIVE;
uiGalDarahStatueState = GO_STATE_READY;
uiBridgeState = GO_STATE_ACTIVE;
uiCollisionState = GO_STATE_READY;
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
}
bool IsEncounterInProgress() const
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
return false;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case 29304: uiSladRan = pCreature->GetGUID(); break;
case 29305: uiMoorabi = pCreature->GetGUID(); break;
case 29306: uiGalDarah = pCreature->GetGUID(); break;
case 29307: uiDrakkariColossus = pCreature->GetGUID(); break;
case 29932: uiEckTheFerocious = pCreature->GetGUID(); break;
}
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch(pGo->GetEntry())
{
case 192518:
uiSladRanAltar = pGo->GetGUID();
// Make sure that they start out as unusuable
pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
if (m_auiEncounter[0] == DONE)
{
if (uiSladRanStatueState == GO_STATE_ACTIVE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
else
{
++phase;
pGo->SetGoState(GO_STATE_ACTIVE);
}
}
break;
case 192519:
uiMoorabiAltar = pGo->GetGUID();
// Make sure that they start out as unusuable
pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
if (m_auiEncounter[0] == DONE)
{
if (uiMoorabiStatueState == GO_STATE_ACTIVE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
else
{
++phase;
pGo->SetGoState(GO_STATE_ACTIVE);
}
}
break;
case 192520:
uiDrakkariColossusAltar = pGo->GetGUID();
// Make sure that they start out as unusuable
pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
if (m_auiEncounter[0] == DONE)
{
if (uiDrakkariColossusStatueState == GO_STATE_ACTIVE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
else
{
++phase;
pGo->SetGoState(GO_STATE_ACTIVE);
}
}
break;
case 192564:
uiSladRanStatue = pGo->GetGUID();
pGo->SetGoState(uiSladRanStatueState);
break;
case 192565:
uiMoorabiStatue = pGo->GetGUID();
pGo->SetGoState(uiMoorabiStatueState);
break;
case 192566:
uiGalDarahStatue = pGo->GetGUID();
pGo->SetGoState(uiGalDarahStatueState);
break;
case 192567:
uiDrakkariColossusStatue = pGo->GetGUID();
pGo->SetGoState(uiDrakkariColossusStatueState);
break;
case 192632:
uiEckTheFerociousDoor = pGo->GetGUID();
if (bHeroicMode && m_auiEncounter[1] == DONE)
HandleGameObject(NULL,true,pGo);
break;
case 192569:
uiEckTheFerociousDoorBehind = pGo->GetGUID();
if (bHeroicMode && m_auiEncounter[4] == DONE)
HandleGameObject(NULL,true,pGo);
case 193208:
uiGalDarahDoor1 = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)
HandleGameObject(NULL,true,pGo);
break;
case 193209:
uiGalDarahDoor2 = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)
HandleGameObject(NULL,true,pGo);
break;
case 193188:
uiBridge = pGo->GetGUID();
pGo->SetGoState(uiBridgeState);
break;
case 192633:
uiCollision = pGo->GetGUID();
pGo->SetGoState(uiCollisionState);
// Can't spawn here with SpawnGameObject because pGo isn't added to world yet...
if (uiCollisionState == GO_STATE_ACTIVE_ALTERNATIVE)
spawnSupport = true;
break;
}
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_SLAD_RAN_EVENT:
m_auiEncounter[0] = data;
if (data == DONE)
{
GameObject* pGo = instance->GetGameObject(uiSladRanAltar);
if (pGo)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
}
break;
case DATA_MOORABI_EVENT:
m_auiEncounter[1] = data;
if (data == DONE)
{
GameObject* pGo = instance->GetGameObject(uiMoorabiAltar);
if (pGo)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
if (bHeroicMode)
HandleGameObject(uiEckTheFerociousDoor,true);
}
break;
case DATA_DRAKKARI_COLOSSUS_EVENT:
m_auiEncounter[2] = data;
if (data == DONE)
{
GameObject* pGo = instance->GetGameObject(uiDrakkariColossusAltar);
if (pGo)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
}
break;
case DATA_GAL_DARAH_EVENT:
m_auiEncounter[3] = data;
if (data == DONE)
{
HandleGameObject(uiGalDarahDoor1,true);
HandleGameObject(uiGalDarahDoor2,true);
}
break;
case DATA_ECK_THE_FEROCIOUS_EVENT:
m_auiEncounter[4] = data;
if (bHeroicMode && data == DONE)
HandleGameObject(uiEckTheFerociousDoorBehind,true);
break;
}
if (data == DONE)
SaveToDB();
}
uint32 GetData(uint32 type)
{
switch(type)
{
case DATA_SLAD_RAN_EVENT: return m_auiEncounter[0];
case DATA_MOORABI_EVENT: return m_auiEncounter[1];
case DATA_GAL_DARAH_EVENT: return m_auiEncounter[2];
case DATA_DRAKKARI_COLOSSUS_EVENT: return m_auiEncounter[3];
case DATA_ECK_THE_FEROCIOUS_EVENT: return m_auiEncounter[4];
}
return 0;
}
uint64 GetData64(uint32 type)
{
switch(type)
{
case DATA_SLAD_RAN_ALTAR: return uiSladRanAltar;
case DATA_MOORABI_ALTAR: return uiMoorabiAltar;
case DATA_DRAKKARI_COLOSSUS_ALTAR: return uiDrakkariColossusAltar;
case DATA_SLAD_RAN_STATUE: return uiSladRanStatue;
case DATA_MOORABI_STATUE: return uiMoorabiStatue;
case DATA_DRAKKARI_COLOSSUS_STATUE: return uiDrakkariColossusStatue;
case DATA_DRAKKARI_COLOSSUS: return uiDrakkariColossus;
}
return 0;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "G D " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
<< m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " "
<< (uiSladRanStatue ? GetObjState(uiSladRanStatue) : GO_STATE_ACTIVE) << " " << (uiMoorabiStatue ? GetObjState(uiMoorabiStatue) : GO_STATE_ACTIVE) << " "
<< (uiDrakkariColossusStatue ? GetObjState(uiDrakkariColossusStatue) : GO_STATE_ACTIVE) << " " << (uiGalDarahStatue ? GetObjState(uiGalDarahStatue) : GO_STATE_READY) << " "
<< (uiBridge ? GetObjState(uiBridge) : GO_STATE_ACTIVE) << " " << (uiCollision ? GetObjState(uiCollision) : GO_STATE_READY);
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in)
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3
>> data4 >> data5 >> data6 >> data7 >> data8 >> data9 >> data10;
if (dataHead1 == 'G' && dataHead2 == 'D')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
m_auiEncounter[3] = data3;
m_auiEncounter[4] = data4;
uiSladRanStatueState = GOState(data5);
uiMoorabiStatueState = GOState(data6);
uiDrakkariColossusStatueState = GOState(data7);
uiGalDarahStatueState = GOState(data8);
uiBridgeState = GOState(data9);
uiCollisionState = GOState(data10);
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
bool QueueActivation(uint64 guid, uint32 time)
{
if (timer)
return false;
toActivate = guid;
timer = time;
phase++;
return true;
}
void Update(uint32 diff)
{
// Spawn the support for the bridge if necessary
if (spawnSupport)
{
if (GameObject* pCollision = instance->GetGameObject(uiCollision))
pCollision->SummonGameObject(192743, pCollision->GetPositionX(), pCollision->GetPositionY(), pCollision->GetPositionZ(), pCollision->GetOrientation(), 0, 0, 0, 0, 0);
spawnSupport = false;
}
// If there is nothing to activate, then return
if (!toActivate)
return;
if (timer < diff)
{
timer = 0;
if (toActivate == uiBridge)
{
toActivate = 0;
GameObject* pBridge = instance->GetGameObject(uiBridge);
GameObject* pCollision = instance->GetGameObject(uiCollision);
GameObject* pSladRanStatue = instance->GetGameObject(uiSladRanStatue);
GameObject* pMoorabiStatue = instance->GetGameObject(uiMoorabiStatue);
GameObject* pDrakkariColossusStatue = instance->GetGameObject(uiDrakkariColossusStatue);
GameObject* pGalDarahStatue = instance->GetGameObject(uiGalDarahStatue);
if (pBridge && pCollision && pSladRanStatue && pMoorabiStatue && pDrakkariColossusStatue && pGalDarahStatue)
{
pBridge->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
pCollision->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
pSladRanStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
pMoorabiStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
pDrakkariColossusStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
pGalDarahStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
// Add the GO that solidifies the bridge so you can walk on it
spawnSupport = true;
SaveToDB();
}
}
else
{
uint32 spell = 0;
GameObject* pAltar = NULL;
if (toActivate == uiSladRanStatue)
{
spell = 57071;
pAltar = instance->GetGameObject(uiSladRanAltar);
} else if (toActivate == uiMoorabiStatue)
{
spell = 57068;
pAltar = instance->GetGameObject(uiMoorabiAltar);
} else if (toActivate == uiDrakkariColossusStatue)
{
spell = 57072;
pAltar = instance->GetGameObject(uiDrakkariColossusAltar);
}
// This is a workaround to make the beam cast properly. The caster should be ID 30298 but since the spells
// all are with scripted target for that same ID, it will hit itself.
if (pAltar)
if (Creature* trigger = pAltar->SummonCreature(18721, pAltar->GetPositionX(), pAltar->GetPositionY(), pAltar->GetPositionZ() + 3, pAltar->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 5000))
{
// Set the trigger model to invisible
trigger->SetDisplayId(11686);
trigger->CastSpell(trigger, spell, false);
}
if (GameObject* statueGO = instance->GetGameObject(toActivate))
statueGO->SetGoState(GO_STATE_READY);
toActivate = 0;
if (phase == 3)
QueueActivation(uiBridge, 3000);
else
SaveToDB(); // Don't save in between last statue and bridge turning in case of crash leading to stuck instance
}
} else timer -= diff;
}
GOState GetObjState(uint64 guid)
{
if (GameObject* go = instance->GetGameObject(guid))
return go->GetGoState();
return GO_STATE_ACTIVE;
}
};
bool GOHello_altar(Player *pPlayer, GameObject *pGO)
{
ScriptedInstance *pInstance = pGO->GetInstanceData();
uint64 uiStatue;
pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
pGO->SetGoState(GO_STATE_ACTIVE);
if (pInstance)
{
switch(pGO->GetEntry())
{
case 192518: uiStatue = pInstance->GetData64(DATA_SLAD_RAN_STATUE); break;
case 192519: uiStatue = pInstance->GetData64(DATA_MOORABI_STATUE); break;
case 192520: uiStatue = pInstance->GetData64(DATA_DRAKKARI_COLOSSUS_STATUE); break;
}
if (((instance_gundrak*)pInstance)->QueueActivation(uiStatue, 3500))
{
pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
pGO->SetGoState(GO_STATE_ACTIVE);
}
return true;
}
return false;
}
InstanceData* GetInstanceData_instance_gundrak(Map* pMap)
{
return new instance_gundrak(pMap);
}
void AddSC_instance_gundrak()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_gundrak";
newscript->GetInstanceData = &GetInstanceData_instance_gundrak;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "go_gundrak_altar";
newscript->pGOHello = &GOHello_altar;
newscript->RegisterSelf();
}
+338
View File
@@ -0,0 +1,338 @@
/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Sholazar_Basin
SD%Complete: 100
SDComment: Quest support: 11253, 11241.
SDCategory: howling_fjord
EndScriptData */
/* ContentData
npc_plaguehound_tracker
npc_apothecary_hanes
EndContentData */
#include "ScriptedPch.h"
#include "ScriptedEscortAI.h"
/*######
## npc_apothecary_hanes
######*/
enum Entries
{
NPC_APOTHECARY_HANES = 23784,
FACTION_ESCORTEE_A = 774,
FACTION_ESCORTEE_H = 775,
NPC_HANES_FIRE_TRIGGER = 23968,
QUEST_TRAIL_OF_FIRE = 11241,
SPELL_COSMETIC_LOW_POLY_FIRE = 56274
};
bool QuestAccept_npc_apothecary_hanes(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_TRAIL_OF_FIRE)
{
switch (pPlayer->GetTeam())
{
case ALLIANCE:
pCreature->setFaction(FACTION_ESCORTEE_A);
break;
case HORDE:
pCreature->setFaction(FACTION_ESCORTEE_H);
break;
}
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
}
return true;
}
struct TRINITY_DLL_DECL npc_Apothecary_HanesAI : public npc_escortAI
{
npc_Apothecary_HanesAI(Creature* pCreature) : npc_escortAI(pCreature){}
uint32 PotTimer;
void Reset ()
{
SetDespawnAtFar(false);
PotTimer = 10000; //10 sec cooldown on potion
}
void JustDied(Unit* killer)
{
if (Player* pPlayer = GetPlayerForEscort())
pPlayer->FailQuest(QUEST_TRAIL_OF_FIRE);
}
void UpdateEscortAI(const uint32 diff)
{
if(HealthBelowPct(75))
{
if (PotTimer <= diff)
{
DoCast(me, 17534, true);
PotTimer = 10000;
} else PotTimer -= diff;
}
if (GetAttack() && UpdateVictim())
DoMeleeAttackIfReady();
}
void WaypointReached(uint32 i)
{
Player* pPlayer = GetPlayerForEscort();
if (!pPlayer)
return;
switch(i)
{
case 1:
me->SetReactState(REACT_AGGRESSIVE);
SetRun(true);
break;
case 23:
if (pPlayer)
pPlayer->GroupEventHappens(QUEST_TRAIL_OF_FIRE, m_creature);
me->ForcedDespawn();
break;
case 5:
if (Unit* Trigger = m_creature->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
SetRun(false);
break;
case 6:
if (Unit* Trigger = m_creature->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
SetRun(true);
break;
case 8:
if (Unit* Trigger = m_creature->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
SetRun(false);
break;
case 9:
if (Unit* Trigger = m_creature->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
break;
case 10:
SetRun(true);
break;
case 13:
SetRun(false);
break;
case 14:
if (Unit* Trigger = m_creature->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
SetRun(true);
break;
}
}
};
CreatureAI* GetAI_npc_apothecary_hanes(Creature* pCreature)
{
return new npc_Apothecary_HanesAI(pCreature);
}
/*######
## npc_plaguehound_tracker
######*/
enum ePlaguehound
{
QUEST_SNIFF_OUT_ENEMY = 11253
};
struct TRINITY_DLL_DECL npc_plaguehound_trackerAI : public npc_escortAI
{
npc_plaguehound_trackerAI(Creature* pCreature) : npc_escortAI(pCreature) { }
void Reset()
{
InitScriptData();
}
void InitScriptData()
{
Player* pPlayer = NULL;
if(me->isSummon())
if(Unit* summoner = CAST_SUM(me)->GetSummoner())
if(summoner->GetTypeId() == TYPEID_PLAYER)
pPlayer = CAST_PLR(summoner);
if (!pPlayer)
return;
me->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
Start(false, false, pPlayer->GetGUID());
}
void WaypointReached(uint32 i)
{
Player* pPlayer = NULL;
if(me->isSummon())
if(Unit* summoner = CAST_SUM(me)->GetSummoner())
if(summoner->GetTypeId() == TYPEID_PLAYER)
pPlayer = CAST_PLR(summoner);
if (!pPlayer)
return;
switch(i)
{
case 26:
me->ForcedDespawn();
break;
}
}
};
CreatureAI* GetAI_npc_plaguehound_tracker(Creature* pCreature)
{
return new npc_plaguehound_trackerAI(pCreature);
}
/*######
## npc_razael_and_lyana
######*/
#define GOSSIP_RAZAEL_REPORT "High Executor Anselm wants a report on the situation."
#define GOSSIP_LYANA_REPORT "High Executor Anselm requests your report."
enum eRazael
{
QUEST_REPORTS_FROM_THE_FIELD = 11221,
NPC_RAZAEL = 23998,
NPC_LYANA = 23778,
GOSSIP_TEXTID_RAZAEL1 = 11562,
GOSSIP_TEXTID_RAZAEL2 = 11564,
GOSSIP_TEXTID_LYANA1 = 11586,
GOSSIP_TEXTID_LYANA2 = 11588
};
bool GossipHello_npc_razael_and_lyana(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_REPORTS_FROM_THE_FIELD) == QUEST_STATUS_INCOMPLETE)
switch (pCreature->GetEntry())
{
case NPC_RAZAEL:
if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_RAZAEL))
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_RAZAEL_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL1, pCreature->GetGUID());
return true;
}
break;
case NPC_LYANA:
if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_LYANA))
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LYANA_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA1, pCreature->GetGUID());
return true;
}
break;
}
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_razael_and_lyana(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_INFO_DEF + 1:
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL2, pCreature->GetGUID());
pPlayer->TalkedToCreature(NPC_RAZAEL, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2:
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA2, pCreature->GetGUID());
pPlayer->TalkedToCreature(NPC_LYANA, pCreature->GetGUID());
break;
}
return true;
}
/*######
## npc_mcgoyver
######*/
#define GOSSIP_ITEM_MG_I "Walt sent me to pick up some dark iron ingots."
#define GOSSIP_ITEM_MG_II "Yarp."
enum eMcGoyver
{
QUEST_WE_CAN_REBUILD_IT = 11483,
SPELL_CREATURE_DARK_IRON_INGOTS = 44512,
SPELL_TAXI_EXPLORERS_LEAGUE = 44280,
GOSSIP_TEXTID_MCGOYVER = 12193
};
bool GossipHello_npc_mcgoyver(Player* pPlayer, Creature* pCreature)
{
if(pPlayer->GetQuestStatus(QUEST_WE_CAN_REBUILD_IT) == QUEST_STATUS_INCOMPLETE)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_I, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_mcgoyver(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_II, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_MCGOYVER, pCreature->GetGUID());
pPlayer->CastSpell(pPlayer, SPELL_CREATURE_DARK_IRON_INGOTS, true);
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->CastSpell(pPlayer, SPELL_TAXI_EXPLORERS_LEAGUE, true);
pPlayer->CLOSE_GOSSIP_MENU();
break;
}
return true;
}
void AddSC_howling_fjord()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_apothecary_hanes";
newscript->GetAI = &GetAI_npc_apothecary_hanes;
newscript->pQuestAccept = &QuestAccept_npc_apothecary_hanes;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_plaguehound_tracker";
newscript->GetAI = &GetAI_npc_plaguehound_tracker;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_razael_and_lyana";
newscript->pGossipHello = &GossipHello_npc_razael_and_lyana;
newscript->pGossipSelect = &GossipSelect_npc_razael_and_lyana;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_mcgoyver";
newscript->pGossipHello = &GossipHello_npc_mcgoyver;
newscript->pGossipSelect = &GossipSelect_npc_mcgoyver;
newscript->RegisterSelf();
}
+135
View File
@@ -0,0 +1,135 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Icecrown
SD%Complete: 100
SDComment: Quest support: 12807
SDCategory: Icecrown
EndScriptData */
/* ContentData
npc_arete
EndContentData */
#include "ScriptedPch.h"
/*######
## npc_arete
######*/
#define GOSSIP_ARETE_ITEM1 "Lord-Commander, I would hear your tale."
#define GOSSIP_ARETE_ITEM2 "<You nod slightly but do not complete the motion as the Lord-Commander narrows his eyes before he continues.>"
#define GOSSIP_ARETE_ITEM3 "I thought that they now called themselves the Scarlet Onslaught?"
#define GOSSIP_ARETE_ITEM4 "Where did the grand admiral go?"
#define GOSSIP_ARETE_ITEM5 "That's fine. When do I start?"
#define GOSSIP_ARETE_ITEM6 "Let's finish this!"
#define GOSSIP_ARETE_ITEM7 "That's quite a tale, Lord-Commander."
enum eArete
{
GOSSIP_TEXTID_ARETE1 = 13525,
GOSSIP_TEXTID_ARETE2 = 13526,
GOSSIP_TEXTID_ARETE3 = 13527,
GOSSIP_TEXTID_ARETE4 = 13528,
GOSSIP_TEXTID_ARETE5 = 13529,
GOSSIP_TEXTID_ARETE6 = 13530,
GOSSIP_TEXTID_ARETE7 = 13531,
QUEST_THE_STORY_THUS_FAR = 12807
};
bool GossipHello_npc_arete(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_THE_STORY_THUS_FAR) == QUEST_STATUS_INCOMPLETE)
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE1, pCreature->GetGUID());
return true;
}
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_arete(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE2, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE3, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE4, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE5, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE6, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+6:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE7, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+7:
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->AreaExploredOrEventHappens(QUEST_THE_STORY_THUS_FAR);
break;
}
return true;
}
/*######
## The Valiant's Challenge Quest 13699
######*/
bool GossipHello_valiant_challenge(Player* player, Creature* _Creature)
{
if (player->GetQuestStatus(13699) == QUEST_STATUS_INCOMPLETE)
{
player->SummonCreature(30675, player->GetInnPosX(),player->GetInnPosY(),player->GetInnPosZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,1000000);
}
return true;
}
void AddSC_icecrown()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_arete";
newscript->pGossipHello = &GossipHello_npc_arete;
newscript->pGossipSelect = &GossipSelect_npc_arete;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "valiant_challenge";
newscript->pGossipHello = &GossipHello_valiant_challenge;
newscript->RegisterSelf();
}
@@ -0,0 +1,126 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define SAY_GREET RAND(-1533000,-1533004,-1533005,-1533006,-1533007)
#define SAY_AGGRO RAND(-1533001,-1533002,-1533003)
#define SAY_SLAY -1533008
#define SPELL_IMPALE RAID_MODE(28783,56090)
#define SPELL_LOCUSTSWARM RAID_MODE(28785,54021)
#define SPELL_SELF_SPAWN_5 29105 //This spawns 5 corpse scarabs ontop of us (most likely the player casts this on death)
#define EVENT_IMPALE 1
#define EVENT_LOCUST 2
#define MOB_CRYPT_GUARD 16573
struct TRINITY_DLL_DECL boss_anubrekhanAI : public BossAI
{
boss_anubrekhanAI(Creature *c) : BossAI(c, BOSS_ANUBREKHAN) { Prepare(); }
bool HasTaunted;
void Prepare()
{
HasTaunted = false;
if (IsHeroic())
{
DoSpawnCreature(MOB_CRYPT_GUARD, 0, -10, 0, me->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
DoSpawnCreature(MOB_CRYPT_GUARD, 0, 10, 0, me->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
}
}
void InitializeAI() { Prepare(); BossAI::InitializeAI(); }
void JustReachedHome() { Prepare(); _JustReachedHome(); }
void KilledUnit(Unit* victim)
{
//Force the player to spawn corpse scarabs via spell
victim->CastSpell(victim, SPELL_SELF_SPAWN_5, true, NULL, NULL, me->GetGUID());
if (!(rand()%5))
DoScriptText(SAY_SLAY, me);
}
void EnterCombat(Unit *who)
{
_EnterCombat();
DoScriptText(SAY_AGGRO, me);
events.ScheduleEvent(EVENT_IMPALE, 15000, 1);
events.ScheduleEvent(EVENT_LOCUST, 80000 + rand()%40000, 1);
}
void MoveInLineOfSight(Unit *who)
{
if (!HasTaunted && me->IsWithinDistInMap(who, 60.0f))
{
DoScriptText(SAY_GREET, me);
HasTaunted = true;
}
ScriptedAI::MoveInLineOfSight(who);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_IMPALE:
//Cast Impale on a random target
//Do NOT cast it when we are afflicted by locust swarm
if (!me->HasAura(SPELL_LOCUSTSWARM))
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_IMPALE);
events.ScheduleEvent(EVENT_IMPALE, 15000, 1);
events.DelayEvents(1500, 1);
return;
case EVENT_LOCUST:
DoCast(m_creature, SPELL_LOCUSTSWARM);
DoSpawnCreature(MOB_CRYPT_GUARD, 5, 5, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
events.ScheduleEvent(EVENT_LOCUST, 90000, 1);
return;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_anubrekhan(Creature* pCreature)
{
return new boss_anubrekhanAI (pCreature);
}
void AddSC_boss_anubrekhan()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_anubrekhan";
newscript->GetAI = &GetAI_boss_anubrekhan;
newscript->RegisterSelf();
}
@@ -0,0 +1,206 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
enum Yells
{
SAY_GREET = -1533009,
SAY_AGGRO_1 = -1533010,
SAY_AGGRO_2 = -1533011,
SAY_AGGRO_3 = -1533012,
SAY_AGGRO_4 = -1533013,
SAY_SLAY_1 = -1533014,
SAY_SLAY_2 = -1533015,
SAY_DEATH = -1533016
};
//#define SOUND_RANDOM_AGGRO 8955 //soundId containing the 4 aggro sounds, we not using this
enum Spells
{
SPELL_POISON_BOLT_VOLLEY = 28796,
H_SPELL_POISON_BOLT_VOLLEY = 54098,
SPELL_RAIN_OF_FIRE = 28794,
H_SPELL_RAIN_OF_FIRE = 54099,
SPELL_FRENZY = 28798,
H_SPELL_FRENZY = 54100,
SPELL_WIDOWS_EMBRACE = 28732,
H_SPELL_WIDOWS_EMBRACE = 54097
};
enum Events
{
EVENT_NONE,
EVENT_POISON,
EVENT_FIRE,
EVENT_FRENZY,
EVENT_AFTERENRAGE
};
enum Creatures
{
NPC_WORSHIPPER = 16506
};
struct TRINITY_DLL_DECL boss_faerlinaAI : public BossAI
{
boss_faerlinaAI(Creature *c) : BossAI(c, BOSS_FAERLINA), greet(false) {}
bool greet;
bool delayFrenzy;
void Reset()
{
delayFrenzy = false;
_Reset();
}
void EnterCombat(Unit *who)
{
_EnterCombat();
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3,SAY_AGGRO_4), me);
events.ScheduleEvent(EVENT_POISON, urand(12000,15000));
events.ScheduleEvent(EVENT_FIRE, urand(6000,18000));
events.ScheduleEvent(EVENT_FRENZY, urand(60000,80000),1);
}
void MoveInLineOfSight(Unit *who)
{
if (!greet)
{
DoScriptText(SAY_GREET, me);
greet = true;
}
BossAI::MoveInLineOfSight(who);
}
void KilledUnit(Unit* victim)
{
if (!(rand()%3))
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
}
void JustDied(Unit* Killer)
{
_JustDied();
DoScriptText(SAY_DEATH, me);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_POISON:
if (!me->HasAura(SPELL_WIDOWS_EMBRACE))
DoCastAOE(RAID_MODE(SPELL_POISON_BOLT_VOLLEY,H_SPELL_POISON_BOLT_VOLLEY));
events.ScheduleEvent(EVENT_POISON, urand(12000,15000));
return;
case EVENT_FIRE:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, RAID_MODE(SPELL_RAIN_OF_FIRE, H_SPELL_RAIN_OF_FIRE));
events.ScheduleEvent(EVENT_FIRE, urand(6000,18000));
return;
case EVENT_FRENZY:
DoCast(me, RAID_MODE(SPELL_FRENZY, H_SPELL_FRENZY));
delayFrenzy = false;
return;
case EVENT_AFTERENRAGE:
events.ScheduleEvent(EVENT_FRENZY, urand(60000,80000));
}
}
DoMeleeAttackIfReady();
}
void SpellHit(Unit* caster, const SpellEntry *spell)
{
if (spell->Id == SPELL_WIDOWS_EMBRACE || spell->Id == H_SPELL_WIDOWS_EMBRACE)
{
if (m_creature->HasAura(RAID_MODE(SPELL_FRENZY,H_SPELL_FRENZY)))
{
if (!delayFrenzy)
{
events.DelayEvents(30000, 1);
delayFrenzy = true;
}
}
else
events.ScheduleEvent(EVENT_AFTERENRAGE, 60000);
}
}
};
CreatureAI* GetAI_boss_faerlina(Creature* pCreature)
{
return new boss_faerlinaAI (pCreature);
}
struct TRINITY_DLL_DECL mob_faerlina_addAI : public ScriptedAI
{
mob_faerlina_addAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
ScriptedInstance *pInstance;
void Reset()
{
if (getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, SPELL_EFFECT_BIND, true);
}
void JustDied(Unit *killer)
{
if (pInstance)
{
if (Creature *pFaerlina = pInstance->instance->GetCreature(pInstance->GetData64(DATA_FAERLINA)))
DoCast(pFaerlina, RAID_MODE(SPELL_WIDOWS_EMBRACE, H_SPELL_WIDOWS_EMBRACE));
}
}
};
CreatureAI* GetAI_mob_faerlina_add(Creature* pCreature)
{
return new mob_faerlina_addAI (pCreature);
}
void AddSC_boss_faerlina()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_faerlina";
newscript->GetAI = &GetAI_boss_faerlina;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_faerlina_add";
newscript->GetAI = &GetAI_mob_faerlina_add;
newscript->RegisterSelf();
}
@@ -0,0 +1,374 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
enum Horsemen
{
HORSEMEN_THANE,
HORSEMEN_LADY,
HORSEMEN_BARON,
HORSEMEN_SIR,
};
enum Events
{
EVENT_NONE,
EVENT_MARK,
EVENT_CAST,
EVENT_BERSERK,
};
const Position WaypointPositions[12] =
{
// Thane waypoints
{2542.3, -2984.1, 241.49, 5.362},
{2547.6, -2999.4, 241.34, 5.049},
{2542.9, -3015.0, 241.35, 4.654},
// Lady waypoints
{2498.3, -2961.8, 241.28, 3.267},
{2487.7, -2959.2, 241.28, 2.890},
{2469.4, -2947.6, 241.28, 2.576},
// Baron waypoints
{2553.8, -2968.4, 241.33, 5.757},
{2564.3, -2972.5, 241.33, 5.890},
{2583.9, -2971.67, 241.35, 0.008},
// Sir waypoints
{2534.5, -2921.7, 241.53, 1.363},
{2523.5, -2902.8, 241.28, 2.095},
{2517.8, -2896.6, 241.28, 2.315},
};
const uint32 MOB_HORSEMEN[] = {16064, 16065, 30549, 16063};
const uint32 SPELL_MARK[] = {28832, 28833, 28834, 28835};
#define SPELL_PRIMARY(i) RAID_MODE(SPELL_PRIMARY_N[i],SPELL_PRIMARY_H[i])
const uint32 SPELL_PRIMARY_N[] = {28884, 28863, 28882, 28883};
const uint32 SPELL_PRIMARY_H[] = {57467, 57463, 57369, 57466};
#define SPELL_SECONDARY(i) RAID_MODE(SPELL_SECONDARY_N[i],SPELL_SECONDARY_H[i])
const uint32 SPELL_SECONDARY_N[]= {0, 57374, 0, 57376};
const uint32 SPELL_SECONDARY_H[]= {0, 57464, 0, 57465};
const uint32 SPELL_PUNISH[] = {0, 57381, 0, 57377};
#define SPELL_BERSERK 26662
// used by 16063,16064,16065,30549, but signed for 16063
const int32 SAY_AGGRO[] = {-1533051, -1533044, -1533065, -1533058};
const int32 SAY_TAUNT[3][4] ={ {-1533052, -1533045, -1533071, -1533059},
{-1533053, -1533046, -1533072, -1533060},
{-1533054, -1533047, -1533073, -1533061},};
const int32 SAY_SPECIAL[] = {-1533055, -1533048, -1533070, -1533062};
const int32 SAY_SLAY[] = {-1533056, -1533049, -1533068, -1533063};
const int32 SAY_DEATH[] = {-1533057, -1533050, -1533074, -1533064};
#define SAY_BARON_AGGRO RAND(-1533065,-1533066,-1533067)
#define SAY_BARON_SLAY RAND(-1533068,-1533069)
struct TRINITY_DLL_DECL boss_four_horsemenAI : public BossAI
{
boss_four_horsemenAI(Creature *c) : BossAI(c, BOSS_HORSEMEN)
{
id = Horsemen(0);
for (uint8 i = 0; i < 4; ++i)
if (me->GetEntry() == MOB_HORSEMEN[i])
id = Horsemen(i);
caster = (id == HORSEMEN_LADY || id == HORSEMEN_SIR);
}
Horsemen id;
Unit *eventStarter;
uint8 nextWP;
uint32 punishTimer;
bool caster;
bool nextMovementStarted;
bool movementCompleted;
bool movementStarted;
bool encounterActionAttack;
bool encounterActionReset;
bool doDelayPunish;
void Reset()
{
if (!encounterActionReset)
DoEncounterAction(NULL, false, true, false);
me->SetReactState(REACT_AGGRESSIVE);
eventStarter = NULL;
nextWP = 0;
punishTimer = 2000;
nextMovementStarted = false;
movementCompleted = false;
movementStarted = false;
encounterActionAttack = false;
encounterActionReset = false;
doDelayPunish = false;
_Reset();
}
bool DoEncounterAction(Unit *who, bool attack, bool reset, bool checkAllDead)
{
if (!instance)
return false;
Creature *Thane = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_THANE)));
Creature *Lady = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_LADY)));
Creature *Baron = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_BARON)));
Creature *Sir = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_SIR)));
if (Thane && Lady && Baron && Sir)
{
if (attack && who)
{
CAST_AI(boss_four_horsemenAI, Thane->AI())->encounterActionAttack = true;
CAST_AI(boss_four_horsemenAI, Lady->AI())->encounterActionAttack = true;
CAST_AI(boss_four_horsemenAI, Baron->AI())->encounterActionAttack = true;
CAST_AI(boss_four_horsemenAI, Sir->AI())->encounterActionAttack = true;
CAST_AI(boss_four_horsemenAI, Thane->AI())->AttackStart(who);
CAST_AI(boss_four_horsemenAI, Lady->AI())->AttackStart(who);
CAST_AI(boss_four_horsemenAI, Baron->AI())->AttackStart(who);
CAST_AI(boss_four_horsemenAI, Sir->AI())->AttackStart(who);
}
if (reset)
{
if (instance->GetBossState(BOSS_HORSEMEN) != NOT_STARTED)
{
if (!Thane->isAlive())
Thane->Respawn();
if (!Lady->isAlive())
Lady->Respawn();
if (!Baron->isAlive())
Baron->Respawn();
if (!Sir->isAlive())
Sir->Respawn();
CAST_AI(boss_four_horsemenAI, Thane->AI())->encounterActionReset = true;
CAST_AI(boss_four_horsemenAI, Lady->AI())->encounterActionReset = true;
CAST_AI(boss_four_horsemenAI, Baron->AI())->encounterActionReset = true;
CAST_AI(boss_four_horsemenAI, Sir->AI())->encounterActionReset = true;
CAST_AI(boss_four_horsemenAI, Thane->AI())->EnterEvadeMode();
CAST_AI(boss_four_horsemenAI, Lady->AI())->EnterEvadeMode();
CAST_AI(boss_four_horsemenAI, Baron->AI())->EnterEvadeMode();
CAST_AI(boss_four_horsemenAI, Sir->AI())->EnterEvadeMode();
}
}
if (checkAllDead)
return !Thane->isAlive() && !Lady->isAlive() && !Baron->isAlive() && !Sir->isAlive();
}
return false;
}
void BeginFourHorsemenMovement()
{
movementStarted = true;
me->SetReactState(REACT_PASSIVE);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN), true);
switch(id)
{
case HORSEMEN_THANE:
me->GetMotionMaster()->MovePoint(0, WaypointPositions[0]);
break;
case HORSEMEN_LADY:
me->GetMotionMaster()->MovePoint(3, WaypointPositions[3]);
break;
case HORSEMEN_BARON:
me->GetMotionMaster()->MovePoint(6, WaypointPositions[6]);
break;
case HORSEMEN_SIR:
me->GetMotionMaster()->MovePoint(9, WaypointPositions[9]);
break;
}
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
return;
if (id == 2 || id == 5 || id == 8 || id == 11)
{
movementCompleted = true;
me->SetReactState(REACT_AGGRESSIVE);
if (me->canAttack(eventStarter))
AttackStart(eventStarter);
else if (!UpdateVictim())
{
EnterEvadeMode();
return;
}
if (caster)
{
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveIdle();
}
return;
}
nextMovementStarted = false;
nextWP = id + 1;
}
void MoveInLineOfSight(Unit *who)
{
BossAI::MoveInLineOfSight(who);
if (caster)
SelectNearestTarget(who);
}
void AttackStart(Unit *who)
{
if (!movementCompleted && !movementStarted)
{
eventStarter = who;
BeginFourHorsemenMovement();
if (!encounterActionAttack)
DoEncounterAction(who, true, false, false);
}
else if (movementCompleted && movementStarted)
{
if (caster)
me->Attack(who, false);
else
BossAI::AttackStart(who);
}
}
void KilledUnit(Unit* victim)
{
if (!(rand()%5))
{
if (id == HORSEMEN_BARON)
DoScriptText(SAY_BARON_SLAY, me);
else
DoScriptText(SAY_SLAY[id], me);
}
}
void JustDied(Unit* killer)
{
events.Reset();
summons.DespawnAll();
if(instance && DoEncounterAction(NULL, false, false, true))
{
instance->SetBossState(BOSS_HORSEMEN, DONE);
instance->SaveToDB();
}
DoScriptText(SAY_DEATH[id], me);
}
void EnterCombat(Unit *who)
{
_EnterCombat();
if (id == HORSEMEN_BARON)
DoScriptText(SAY_BARON_AGGRO, me);
else
DoScriptText(SAY_AGGRO[id], me);
events.ScheduleEvent(EVENT_MARK, 15000);
events.ScheduleEvent(EVENT_CAST, 20000+rand()%5000);
events.ScheduleEvent(EVENT_BERSERK, 15*100*1000);
}
void UpdateAI(const uint32 diff)
{
if (nextWP && movementStarted && !movementCompleted && !nextMovementStarted)
{
nextMovementStarted = true;
me->GetMotionMaster()->MovePoint(nextWP, WaypointPositions[nextWP]);
}
if (!UpdateVictim() || !CheckInRoom() || !movementCompleted)
return;
events.Update(diff);
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_MARK:
if (!(rand()%5))
DoScriptText(SAY_SPECIAL[id], me);
DoCastAOE(SPELL_MARK[id]);
events.ScheduleEvent(EVENT_MARK, 15000);
break;
case EVENT_CAST:
if (!(rand()%5))
DoScriptText(SAY_TAUNT[rand()%3][id], me);
if (caster)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 45))
DoCast(pTarget, SPELL_PRIMARY(id));
}
else
DoCast(me->getVictim(), SPELL_PRIMARY(id));
events.ScheduleEvent(EVENT_CAST, 15000);
break;
case EVENT_BERSERK:
DoScriptText(SAY_SPECIAL[id], me);
DoCast(me, EVENT_BERSERK);
break;
}
}
if (punishTimer <= diff)
{
if (doDelayPunish)
{
DoCastAOE(SPELL_PUNISH[id], true);
doDelayPunish = false;
}
punishTimer = 2000;
} else punishTimer -= diff;
if (!caster)
DoMeleeAttackIfReady();
else if ((!DoSpellAttackIfReady(SPELL_SECONDARY(id)) || !me->IsWithinLOSInMap(me->getVictim())) && movementCompleted && !doDelayPunish)
doDelayPunish = true;
}
};
CreatureAI* GetAI_four_horsemen(Creature* pCreature)
{
return new boss_four_horsemenAI (pCreature);
}
void AddSC_boss_four_horsemen()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_four_horsemen";
newscript->GetAI = &GetAI_four_horsemen;
newscript->RegisterSelf();
}
@@ -0,0 +1,167 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define SPELL_MORTAL_WOUND 25646
#define SPELL_ENRAGE RAID_MODE(28371,54427)
#define SPELL_DECIMATE RAID_MODE(28374,54426)
#define SPELL_BERSERK 26662
#define SPELL_INFECTED_WOUND 29306
#define MOB_ZOMBIE 16360
const Position PosSummon[3] =
{
{3267.9, -3172.1, 297.42, 0.94},
{3253.2, -3132.3, 297.42, 0},
{3308.3, -3185.8, 297.42, 1.58},
};
enum Events
{
EVENT_NONE,
EVENT_WOUND,
EVENT_ENRAGE,
EVENT_DECIMATE,
EVENT_BERSERK,
EVENT_SUMMON,
};
#define EMOTE_NEARBY " spots a nearby zombie to devour!"
struct TRINITY_DLL_DECL boss_gluthAI : public BossAI
{
boss_gluthAI(Creature *c) : BossAI(c, BOSS_GLUTH)
{
// Do not let Gluth be affected by zombies' debuff
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_INFECTED_WOUND, true);
}
std::vector<Creature*> triggers;
void Reset()
{
triggers.clear();
_Reset();
}
void MoveInLineOfSight(Unit *who)
{
if (who->GetEntry() == MOB_ZOMBIE && me->IsWithinDistInMap(who, 7))
{
SetGazeOn(who);
// TODO: use a script text
me->MonsterTextEmote(EMOTE_NEARBY, 0, true);
}
else
BossAI::MoveInLineOfSight(who);
}
void EnterCombat(Unit *who)
{
for (uint32 i = 0; i < 3; ++i)
if (Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummon[i]))
triggers.push_back(trigger);
if (triggers.size() < 3)
{
error_log("Script Gluth: cannot summon triggers!");
EnterEvadeMode();
return;
}
_EnterCombat();
events.ScheduleEvent(EVENT_WOUND, 10000);
events.ScheduleEvent(EVENT_ENRAGE, 15000);
events.ScheduleEvent(EVENT_DECIMATE, 105000);
events.ScheduleEvent(EVENT_BERSERK, 8*60000);
events.ScheduleEvent(EVENT_SUMMON, 15000);
}
void JustSummoned(Creature *summon)
{
if (summon->GetEntry() == WORLD_TRIGGER)
summon->setActive(true);
else if (summon->GetEntry() == MOB_ZOMBIE)
summon->AI()->AttackStart(me);
summons.Summon(summon);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictimWithGaze() || !CheckInRoom())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_WOUND:
DoCast(me->getVictim(), SPELL_MORTAL_WOUND);
events.ScheduleEvent(EVENT_WOUND, 10000);
break;
case EVENT_ENRAGE:
// TODO : Add missing text
DoCast(me, SPELL_ENRAGE);
events.ScheduleEvent(EVENT_ENRAGE, 15000);
break;
case EVENT_DECIMATE:
// TODO : Add missing text
DoCastAOE(SPELL_DECIMATE);
events.ScheduleEvent(EVENT_DECIMATE, 105000);
break;
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK);
events.ScheduleEvent(EVENT_BERSERK, 5*60000);
break;
case EVENT_SUMMON:
for (uint32 i = 0; i < RAID_MODE(1,2); ++i)
DoSummon(MOB_ZOMBIE, triggers[rand()%3]);
events.ScheduleEvent(EVENT_SUMMON, 10000);
break;
}
}
if (me->getVictim()->GetEntry() == MOB_ZOMBIE)
{
if (me->IsWithinMeleeRange(me->getVictim()))
{
me->Kill(me->getVictim());
me->ModifyHealth(me->GetMaxHealth() * 0.05f);
}
}
else
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_gluth(Creature* pCreature)
{
return new boss_gluthAI (pCreature);
}
void AddSC_boss_gluth()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_gluth";
newscript->GetAI = &GetAI_boss_gluth;
newscript->RegisterSelf();
}
@@ -0,0 +1,534 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#include "SpellId.h"
enum Yells
{
SAY_SPEECH = -1533040,
SAY_KILL = -1533041,
SAY_DEATH = -1533042,
SAY_TELEPORT = -1533043
};
//Gothik
enum Spells
{
SPELL_HARVEST_SOUL = SPELL_HARVEST_SOUL_28679,
SPELL_SHADOW_BOLT = SPELL_SHADOW_BOLT_29317,
H_SPELL_SHADOW_BOLT = SPELL_SHADOW_BOLT_56405,
SPELL_INFORM_LIVE_TRAINEE = SPELL_TO_ANCHOR_1_27892,
SPELL_INFORM_LIVE_KNIGHT = SPELL_TO_ANCHOR_1_27928,
SPELL_INFORM_LIVE_RIDER = SPELL_TO_ANCHOR_1_27935,
SPELL_INFORM_DEAD_TRAINEE = SPELL_ANCHOR_TO_SKULLS_27915,
SPELL_INFORM_DEAD_KNIGHT = SPELL_ANCHOR_TO_SKULLS_27931,
SPELL_INFORM_DEAD_RIDER = SPELL_ANCHOR_TO_SKULLS_27937
};
enum Creatures
{
MOB_LIVE_TRAINEE = 16124,
MOB_LIVE_KNIGHT = 16125,
MOB_LIVE_RIDER = 16126,
MOB_DEAD_TRAINEE = 16127,
MOB_DEAD_KNIGHT = 16148,
MOB_DEAD_RIDER = 16150,
MOB_DEAD_HORSE = 16149
};
struct Waves { uint32 entry, time; };
// wave setups are the same in heroic and normal difficulty, only count of mobs is different,
// but this is handled in DoGothikSummon function
const Waves waves[] =
{
{MOB_LIVE_TRAINEE, 20000},
{MOB_LIVE_TRAINEE, 20000},
{MOB_LIVE_TRAINEE, 10000},
{MOB_LIVE_KNIGHT, 10000},
{MOB_LIVE_TRAINEE, 15000},
{MOB_LIVE_KNIGHT, 5000},
{MOB_LIVE_TRAINEE, 20000},
{MOB_LIVE_TRAINEE, 0},
{MOB_LIVE_KNIGHT, 10000},
{MOB_LIVE_RIDER, 10000},
{MOB_LIVE_TRAINEE, 5000},
{MOB_LIVE_KNIGHT, 15000},
{MOB_LIVE_RIDER, 0},
{MOB_LIVE_TRAINEE, 10000},
{MOB_LIVE_KNIGHT, 10000},
{MOB_LIVE_TRAINEE, 10000},
{MOB_LIVE_RIDER, 5000},
{MOB_LIVE_KNIGHT, 5000},
{MOB_LIVE_TRAINEE, 20000},
{MOB_LIVE_RIDER, 0},
{MOB_LIVE_KNIGHT, 0},
{MOB_LIVE_TRAINEE, 20000},
{MOB_LIVE_TRAINEE, 25000},
{0, 0},
};
#define POS_Y_GATE -3360.78f
#define POS_Y_WEST -3285.0f
#define POS_Y_EAST -3434.0f
#define POS_X_NORTH 2750.49f
#define POS_X_SOUTH 2633.84f
#define IN_LIVE_SIDE(who) (who->GetPositionY() < POS_Y_GATE)
enum Events
{
EVENT_NONE,
EVENT_SUMMON,
EVENT_HARVEST,
EVENT_BOLT,
EVENT_TELEPORT
};
enum Pos
{
POS_LIVE = 6,
POS_DEAD = 5
};
const Position PosSummonLive[POS_LIVE] =
{
{2669.7, -3428.76, 268.56, 1.6},
{2692.1, -3428.76, 268.56, 1.6},
{2714.4, -3428.76, 268.56, 1.6},
{2669.7, -3431.67, 268.56, 1.6},
{2692.1, -3431.67, 268.56, 1.6},
{2714.4, -3431.67, 268.56, 1.6},
};
const Position PosSummonDead[POS_DEAD] =
{
{2725.1, -3310.0, 268.85, 3.4},
{2699.3, -3322.8, 268.60, 3.3},
{2733.1, -3348.5, 268.84, 3.1},
{2682.8, -3304.2, 268.85, 3.9},
{2664.8, -3340.7, 268.23, 3.7},
};
const float PosGroundLiveSide[4] = {2691.2, -3387.0, 267.68, 1.52};
const float PosGroundDeadSide[4] = {2693.5, -3334.6, 267.68, 4.67};
const float PosPlatform[4] = {2640.5, -3360.6, 285.26, 0};
// Predicate function to check that the r efzr unit is NOT on the same side as the source.
struct NotOnSameSide : public std::unary_function<Unit *, bool> {
bool m_inLiveSide;
NotOnSameSide(Unit *pSource) : m_inLiveSide(IN_LIVE_SIDE(pSource)) {}
bool operator() (const Unit *pTarget) {
return (m_inLiveSide != IN_LIVE_SIDE(pTarget));
}
};
struct TRINITY_DLL_DECL boss_gothikAI : public BossAI
{
boss_gothikAI(Creature *c) : BossAI(c, BOSS_GOTHIK) {}
uint32 waveCount;
typedef std::vector<Creature*> TriggerVct;
TriggerVct liveTrigger, deadTrigger;
bool mergedSides;
bool phaseTwo;
bool thirtyPercentReached;
void Reset()
{
liveTrigger.clear();
deadTrigger.clear();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
me->SetReactState(REACT_PASSIVE);
if (instance)
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
_Reset();
mergedSides = false;
phaseTwo = false;
thirtyPercentReached = false;
}
void EnterCombat(Unit *who)
{
for (uint32 i = 0; i < POS_LIVE; ++i)
if (Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonLive[i]))
liveTrigger.push_back(trigger);
for (uint32 i = 0; i < POS_DEAD; ++i)
if (Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonDead[i]))
deadTrigger.push_back(trigger);
if (liveTrigger.size() < POS_LIVE || deadTrigger.size() < POS_DEAD)
{
error_log("Script Gothik: cannot summon triggers!");
EnterEvadeMode();
return;
}
_EnterCombat();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
waveCount = 0;
events.ScheduleEvent(EVENT_SUMMON, 30000);
DoTeleportTo(PosPlatform);
DoScriptText(SAY_SPEECH, me);
if (instance)
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_READY);
}
void JustSummoned(Creature *summon)
{
if (summon->GetEntry() == WORLD_TRIGGER)
summon->setActive(true);
else if (!mergedSides)
{
summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0);
summon->AI()->EnterEvadeMode();
}
else
{
summon->AI()->DoAction(0);
summon->AI()->DoZoneInCombat();
}
summons.Summon(summon);
}
void SummonedCreatureDespawn(Creature *summon)
{
summons.Despawn(summon);
}
void KilledUnit(Unit* victim)
{
if (!(rand()%5))
DoScriptText(SAY_KILL, me);
}
void JustDied(Unit* Killer)
{
liveTrigger.clear();
deadTrigger.clear();
_JustDied();
DoScriptText(SAY_DEATH, me);
if (instance)
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
}
void DoGothikSummon(uint32 entry)
{
if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
{
switch(entry)
{
case MOB_LIVE_TRAINEE:
DoSummon(MOB_LIVE_TRAINEE, liveTrigger[0], 1);
DoSummon(MOB_LIVE_TRAINEE, liveTrigger[1], 1);
DoSummon(MOB_LIVE_TRAINEE, liveTrigger[2], 1);
break;
case MOB_LIVE_KNIGHT:
DoSummon(MOB_LIVE_KNIGHT, liveTrigger[3], 1);
DoSummon(MOB_LIVE_KNIGHT, liveTrigger[5], 1);
break;
case MOB_LIVE_RIDER:
DoSummon(MOB_LIVE_RIDER, liveTrigger[4], 1);
break;
}
}
else
{
switch(entry)
{
case MOB_LIVE_TRAINEE:
DoSummon(MOB_LIVE_TRAINEE, liveTrigger[0], 1);
DoSummon(MOB_LIVE_TRAINEE, liveTrigger[1], 1);
break;
case MOB_LIVE_KNIGHT:
DoSummon(MOB_LIVE_KNIGHT, liveTrigger[5], 1);
break;
case MOB_LIVE_RIDER:
DoSummon(MOB_LIVE_RIDER, liveTrigger[4], 1);
break;
}
}
}
bool CheckGroupSplitted()
{
bool checklife = false;
bool checkdead = false;
Map* pMap = me->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &PlayerList = pMap->GetPlayers();
if (!PlayerList.isEmpty())
{
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (i->getSource() && i->getSource()->isAlive() &&
i->getSource()->GetPositionX() <= POS_X_NORTH &&
i->getSource()->GetPositionX() >= POS_X_SOUTH &&
i->getSource()->GetPositionY() <= POS_Y_GATE &&
i->getSource()->GetPositionY() >= POS_Y_EAST)
{
checklife = true;
}
else if (i->getSource() && i->getSource()->isAlive() &&
i->getSource()->GetPositionX() <= POS_X_NORTH &&
i->getSource()->GetPositionX() >= POS_X_SOUTH &&
i->getSource()->GetPositionY() >= POS_Y_GATE &&
i->getSource()->GetPositionY() <= POS_Y_WEST)
{
checkdead = true;
}
if (checklife && checkdead)
return true;
}
}
}
return false;
}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
uint32 spellId = 0;
switch(spell->Id)
{
case SPELL_INFORM_LIVE_TRAINEE: spellId = SPELL_INFORM_DEAD_TRAINEE; break;
case SPELL_INFORM_LIVE_KNIGHT: spellId = SPELL_INFORM_DEAD_KNIGHT; break;
case SPELL_INFORM_LIVE_RIDER: spellId = SPELL_INFORM_DEAD_RIDER; break;
}
if (spellId && me->isInCombat())
{
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST);
me->CastSpell(deadTrigger[rand()%POS_DEAD], spellId, true);
}
}
void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
{
if (!me->isInCombat())
return;
switch(spell->Id)
{
case SPELL_INFORM_DEAD_TRAINEE:
DoSummon(MOB_DEAD_TRAINEE, pTarget, 0);
break;
case SPELL_INFORM_DEAD_KNIGHT:
DoSummon(MOB_DEAD_KNIGHT, pTarget, 0);
break;
case SPELL_INFORM_DEAD_RIDER:
DoSummon(MOB_DEAD_RIDER, pTarget, 1.0f);
DoSummon(MOB_DEAD_HORSE, pTarget, 1.0f);
break;
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateCombatState() || !CheckInRoom())
return;
events.Update(diff);
if (!thirtyPercentReached && HealthBelowPct(30) && phaseTwo)
{
thirtyPercentReached = true;
if (instance)
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
}
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SUMMON:
if (waves[waveCount].entry)
{
DoGothikSummon(waves[waveCount].entry);
// if group is not splitted, open gate and merge both sides at ~ 2 minutes (wave 11)
if (waveCount == 11)
{
if (!CheckGroupSplitted())
{
if (instance)
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
summons.DoAction(0, 0);
summons.DoZoneInCombat();
mergedSides = true;
}
}
events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time);
++waveCount;
}
else
{
phaseTwo = true;
DoScriptText(SAY_TELEPORT, me);
DoTeleportTo(PosGroundLiveSide);
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
summons.DoAction(0, 0);
summons.DoZoneInCombat();
events.ScheduleEvent(EVENT_BOLT, 1000);
events.ScheduleEvent(EVENT_HARVEST, urand(3000,15000));
events.ScheduleEvent(EVENT_TELEPORT, 20000);
}
break;
case EVENT_BOLT:
DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT));
events.ScheduleEvent(EVENT_BOLT, 1000);
break;
case EVENT_HARVEST:
DoCast(me->getVictim(), SPELL_HARVEST_SOUL, true);
events.ScheduleEvent(EVENT_HARVEST, urand(20000,25000));
break;
case EVENT_TELEPORT:
if (!thirtyPercentReached)
{
m_creature->AttackStop();
if (IN_LIVE_SIDE(m_creature))
{
DoTeleportTo(PosGroundDeadSide);
}
else
{
DoTeleportTo(PosGroundLiveSide);
}
m_creature->getThreatManager().resetAggro(NotOnSameSide(m_creature));
if (Unit *pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0))
{
m_creature->getThreatManager().addThreat(pTarget, 100.0f);
AttackStart(pTarget);
}
events.ScheduleEvent(EVENT_TELEPORT, 20000);
}
break;
}
}
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL mob_gothik_minionAI : public CombatAI
{
mob_gothik_minionAI(Creature *c) : CombatAI(c)
{
liveSide = IN_LIVE_SIDE(me);
}
bool liveSide;
bool gateClose;
bool isOnSameSide(const Unit *pWho)
{
return (liveSide == IN_LIVE_SIDE(pWho));
}
void DoAction(const int32 param)
{
gateClose = param;
}
void DamageTaken(Unit *attacker, uint32 &damage)
{
if (gateClose && !isOnSameSide(attacker))
damage = 0;
}
void JustDied(Unit *killer)
{
if (me->isSummon())
{
if (Unit *owner = CAST_SUM(me)->GetSummoner())
CombatAI::JustDied(owner);
}
}
void EnterEvadeMode()
{
if (!gateClose)
{
CombatAI::EnterEvadeMode();
return;
}
if (!_EnterEvadeMode())
return;
Map* pMap = me->GetMap();
if (pMap->IsDungeon())
{
Map::PlayerList const &PlayerList = pMap->GetPlayers();
if (!PlayerList.isEmpty())
{
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (i->getSource() && i->getSource()->isAlive() && isOnSameSide(i->getSource()))
{
AttackStart(i->getSource());
return;
}
}
}
}
me->GetMotionMaster()->MoveIdle();
Reset();
}
void UpdateAI(const uint32 diff)
{
if (gateClose && (!isOnSameSide(me) || me->getVictim() && !isOnSameSide(me->getVictim())))
{
EnterEvadeMode();
return;
}
CombatAI::UpdateAI(diff);
}
};
CreatureAI* GetAI_boss_gothik(Creature* pCreature)
{
return new boss_gothikAI (pCreature);
}
CreatureAI* GetAI_mob_gothik_minion(Creature* pCreature)
{
return new mob_gothik_minionAI (pCreature);
}
void AddSC_boss_gothik()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_gothik";
newscript->GetAI = &GetAI_boss_gothik;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_gothik_minion";
newscript->GetAI = &GetAI_mob_gothik_minion;
newscript->RegisterSelf();
}
@@ -0,0 +1,142 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define SPELL_BOMBARD_SLIME 28280
#define SPELL_POISON_CLOUD 28240
#define SPELL_MUTATING_INJECTION 28169
#define SPELL_SLIME_SPRAY RAID_MODE(28157,54364)
#define SPELL_BERSERK 26662
#define SPELL_POISON_CLOUD_ADD 59116
#define EVENT_BERSERK 1
#define EVENT_CLOUD 2
#define EVENT_INJECT 3
#define EVENT_SPRAY 4
#define MOB_FALLOUT_SLIME 16290
struct TRINITY_DLL_DECL boss_grobbulusAI : public BossAI
{
boss_grobbulusAI(Creature *c) : BossAI(c, BOSS_GROBBULUS)
{
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_POISON_CLOUD_ADD, true);
}
void EnterCombat(Unit *who)
{
_EnterCombat();
events.ScheduleEvent(EVENT_CLOUD, 15000);
events.ScheduleEvent(EVENT_INJECT, 20000);
events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000); //not sure
events.ScheduleEvent(EVENT_BERSERK, 12*60000);
}
void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
{
if (spell->Id == SPELL_SLIME_SPRAY)
{
if (TempSummon *slime = me->SummonCreature(MOB_FALLOUT_SLIME, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0))
DoZoneInCombat(slime);
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_CLOUD:
DoCastAOE(SPELL_POISON_CLOUD);
events.ScheduleEvent(EVENT_CLOUD, 15000);
return;
case EVENT_BERSERK:
DoCastAOE(SPELL_BERSERK);
return;
case EVENT_SPRAY:
DoCastAOE(SPELL_SLIME_SPRAY);
events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000);
return;
case EVENT_INJECT:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1))
if (!pTarget->HasAura(SPELL_MUTATING_INJECTION))
DoCast(pTarget, SPELL_MUTATING_INJECTION);
events.ScheduleEvent(EVENT_INJECT, 8000 + 12000 * ((float)me->GetHealth() / me->GetMaxHealth()));
return;
}
}
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL npc_grobbulus_poison_cloudAI : public Scripted_NoMovementAI
{
npc_grobbulus_poison_cloudAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
{
Reset();
}
uint32 Cloud_Timer;
void Reset()
{
Cloud_Timer = 1000;
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
void UpdateAI(const uint32 diff)
{
if (Cloud_Timer <= diff)
{
DoCast(m_creature, SPELL_POISON_CLOUD_ADD);
Cloud_Timer = 10000;
} else Cloud_Timer -= diff;
}
};
CreatureAI* GetAI_boss_grobbulus(Creature* pCreature)
{
return new boss_grobbulusAI (pCreature);
}
CreatureAI* GetAI_npc_grobbulus_poison_cloud(Creature* pCreature)
{
return new npc_grobbulus_poison_cloudAI(pCreature);
}
void AddSC_boss_grobbulus()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_grobbulus";
newscript->GetAI = &GetAI_boss_grobbulus;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_grobbulus_poison_cloud";
newscript->GetAI = &GetAI_npc_grobbulus_poison_cloud;
newscript->RegisterSelf();
}
@@ -0,0 +1,151 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define SAY_AGGRO RAND(-1533109,-1533110,-1533111)
#define SAY_SLAY -1533112
#define SAY_TAUNT RAND(-1533113,-1533114,-1533115,-1533116,-1533117)
#define SAY_DEATH -1533118
#define SPELL_SPELL_DISRUPTION 29310
#define SPELL_DECREPIT_FEVER RAID_MODE(29998,55011)
#define SPELL_PLAGUE_CLOUD 29350
enum Events
{
EVENT_NONE,
EVENT_DISRUPT,
EVENT_FEVER,
EVENT_ERUPT,
EVENT_PHASE,
};
enum Phases
{
PHASE_FIGHT = 1,
PHASE_DANCE,
};
//Spell by eye stalks
#define SPELL_MIND_FLAY 26143
struct TRINITY_DLL_DECL boss_heiganAI : public BossAI
{
boss_heiganAI(Creature *c) : BossAI(c, BOSS_HEIGAN) {}
uint32 eruptSection;
bool eruptDirection;
Phases phase;
void KilledUnit(Unit* Victim)
{
if (!(rand()%5))
DoScriptText(SAY_SLAY, me);
}
void JustDied(Unit* Killer)
{
_JustDied();
DoScriptText(SAY_DEATH, me);
}
void EnterCombat(Unit *who)
{
_EnterCombat();
DoScriptText(SAY_AGGRO, me);
EnterPhase(PHASE_FIGHT);
}
void EnterPhase(Phases newPhase)
{
phase = newPhase;
events.Reset();
eruptSection = 3;
if (phase == PHASE_FIGHT)
{
events.ScheduleEvent(EVENT_DISRUPT, 0);
events.ScheduleEvent(EVENT_FEVER, 20000);
events.ScheduleEvent(EVENT_PHASE, 85000);
events.ScheduleEvent(EVENT_ERUPT, 10000);
}
else
{
float x, y, z, o;
me->GetHomePosition(x, y, z, o);
me->NearTeleportTo(x, y, z, o);
DoCastAOE(SPELL_PLAGUE_CLOUD);
events.ScheduleEvent(EVENT_PHASE, 45000);
events.ScheduleEvent(EVENT_ERUPT, 5000);
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_DISRUPT:
DoCastAOE(SPELL_SPELL_DISRUPTION);
events.ScheduleEvent(EVENT_DISRUPT, 5000);
return;
case EVENT_FEVER:
DoCastAOE(SPELL_DECREPIT_FEVER);
events.ScheduleEvent(EVENT_FEVER, 20000);
return;
case EVENT_PHASE:
EnterPhase(phase == PHASE_FIGHT ? PHASE_DANCE : PHASE_FIGHT);
return;
case EVENT_ERUPT:
instance->SetData(DATA_HEIGAN_ERUPT, eruptSection);
TeleportCheaters();
if (eruptSection == 0)
eruptDirection = true;
else if (eruptSection == 3)
eruptDirection = false;
eruptDirection ? ++eruptSection : --eruptSection;
events.ScheduleEvent(EVENT_ERUPT, phase == PHASE_FIGHT ? 10000 : 3000);
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_heigan(Creature* pCreature)
{
return new boss_heiganAI (pCreature);
}
void AddSC_boss_heigan()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_heigan";
newscript->GetAI = &GetAI_boss_heigan;
newscript->RegisterSelf();
}
@@ -0,0 +1,179 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Highlord_Mograine
SD%Complete: 100
SDComment: SCRIPT OBSOLETE
SDCategory: Naxxramas
EndScriptData */
#include "precompiled.h"
//All horsemen
#define SPELL_SHIELDWALL 29061
#define SPELL_BESERK 26662
// highlord mograine
#define SPELL_MARK_OF_MOGRAINE 28834
#define SPELL_RIGHTEOUS_FIRE 28882 // Applied as a 25% chance on melee hit to proc. m_creature->GetVictim()
#define SAY_TAUNT1 "Enough prattling. Let them come! We shall grind their bones to dust."
#define SAY_TAUNT2 "Conserve your anger! Harness your rage! You will all have outlets for your frustration soon enough."
#define SAY_TAUNT3 "Life is meaningless. It is in death that we are truly tested."
#define SAY_AGGRO1 "You seek death?"
#define SAY_AGGRO2 "None shall pass!"
#define SAY_AGGRO3 "Be still!"
#define SAY_SLAY1 "You will find no peace in death."
#define SAY_SLAY2 "The master's will is done."
#define SAY_SPECIAL "Bow to the might of the Highlord!"
#define SAY_DEATH "I... am... released! Perhaps it's not too late to - noo! I need... more time..."
#define SOUND_TAUNT1 8842
#define SOUND_TAUNT2 8843
#define SOUND_TAUNT3 8844
#define SOUND_AGGRO1 8835
#define SOUND_AGGRO2 8836
#define SOUND_AGGRO3 8837
#define SOUND_SLAY1 8839
#define SOUND_SLAY2 8840
#define SOUND_SPECIAL 8841
#define SOUND_DEATH 8838
#define SPIRIT_OF_MOGRAINE 16775
struct TRINITY_DLL_DECL boss_highlord_mograineAI : public ScriptedAI
{
boss_highlord_mograineAI(Creature *c) : ScriptedAI(c) {}
uint32 Mark_Timer;
uint32 RighteousFire_Timer;
bool ShieldWall1;
bool ShieldWall2;
void Reset()
{
Mark_Timer = 20000; // First Horsemen Mark is applied at 20 sec.
RighteousFire_Timer = 2000; // applied approx 1 out of 4 attacks
ShieldWall1 = true;
ShieldWall2 = true;
}
void InitialYell()
{
if (!m_creature->isInCombat())
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO1);
break;
case 1:
DoYell(SAY_AGGRO2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO2);
break;
case 2:
DoYell(SAY_AGGRO3,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO3);
break;
}
}
}
void KilledUnit()
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY2);
break;
}
}
void JustDied(Unit* Killer)
{
DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_DEATH);
}
void Aggro(Unit *who)
{
InitialYell();
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
// Mark of Mograine
if (Mark_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_MARK_OF_MOGRAINE);
Mark_Timer = 12000;
}else Mark_Timer -= diff;
// Shield Wall - All 4 horsemen will shield wall at 50% hp and 20% hp for 20 seconds
if (ShieldWall1 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 50)
{
if (ShieldWall1)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall1 = false;
}
}
if (ShieldWall2 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20)
{
if (ShieldWall2)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall2 = false;
}
}
// Righteous Fire
if (RighteousFire_Timer < diff)
{
if (rand()%4 == 1) // 1/4
{
DoCast(m_creature->getVictim(),SPELL_RIGHTEOUS_FIRE);
}
RighteousFire_Timer = 2000;
}else RighteousFire_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_highlord_mograine(Creature* pCreature)
{
return new boss_highlord_mograineAI (pCreature);
}
void AddSC_boss_highlord_mograine()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_highlord_mograine";
newscript->GetAI = &GetAI_boss_highlord_mograine;
newscript->RegisterSelf();
}
@@ -0,0 +1,305 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_KelThuzud
SD%Complete: 0
SDComment: VERIFY SCRIPT
SDCategory: Naxxramas
EndScriptData */
#include "ScriptedPch.h"
#include "naxxramas.h"
enum Yells
{
//when shappiron dies. dialog between kel and lich king (in this order)
SAY_SAPP_DIALOG1 = -1533084, //not used
SAY_SAPP_DIALOG2_LICH = -1533085, //not used
SAY_SAPP_DIALOG3 = -1533086, //not used
SAY_SAPP_DIALOG4_LICH = -1533087, //not used
SAY_SAPP_DIALOG5 = -1533088, //not used
SAY_CAT_DIED = -1533089, //when cat dies, not used
//when each of the 4 wing bosses dies
SAY_TAUNT1 = -1533090, //not used
SAY_TAUNT2 = -1533091, //not used
SAY_TAUNT3 = -1533092, //not used
SAY_TAUNT4 = -1533093, //not used
SAY_SUMMON_MINIONS = -1533105, //start of phase 1 not used
SAY_AGGRO_1 = -1533094, //start of phase 2
SAY_AGGRO_2 = -1533095,
SAY_AGGRO_3 = -1533096,
SAY_SLAY_1 = -1533097,
SAY_SLAY_2 = -1533098,
SAY_DEATH = -1533099,
SAY_CHAIN_1 = -1533100,
SAY_CHAIN_2 = -1533101,
SAY_FROST_BLAST = -1533102,
SAY_SPECIAL_1 = -1533106,
SAY_SPECIAL_2 = -1533107,
SAY_SPECIAL_3 = -1533108,
SAY_REQUEST_AID = -1533103, //start of phase 3
SAY_ANSWER_REQUEST = -1533104 //lich king answer
};
enum Event
{
EVENT_NONE,
EVENT_BOLT,
EVENT_NOVA,
EVENT_CHAIN,
EVENT_DETONATE,
EVENT_FISSURE,
EVENT_BLAST,
EVENT_WASTE,
EVENT_ABOMIN,
EVENT_WEAVER,
EVENT_ICECROWN,
EVENT_PHASE,
};
enum Spells
{
SPELL_FROST_BOLT = 28478,
H_SPELL_FROST_BOLT = 55802,
SPELL_FROST_BOLT_AOE = 28479,
H_SPELL_FROST_BOLT_AOE = 55807,
SPELL_SHADOW_FISURE = 27810,
SPELL_VOID_BLAST = 27812,
SPELL_MANA_DETONATION = 27819,
SPELL_FROST_BLAST = 27808,
SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
SPELL_BERSERK = 28498
};
enum Creatures
{
NPC_WASTE = 16427, // Soldiers of the Frozen Wastes
NPC_ABOMINATION = 16428, // Unstoppable Abominations
NPC_WEAVER = 16429, // Soul Weavers
NPC_ICECROWN = 16441 // Guardians of Icecrown
};
const Position Pos[12] =
{
{3783.272705, -5062.697266, 143.711203, 3.617599}, //LEFT_FAR
{3730.291260, -5027.239258, 143.956909, 4.461900}, //LEFT_MIDDLE
{3683.868652, -5057.281250, 143.183884, 5.237086}, //LEFT_NEAR
{3759.355225, -5174.128418, 143.802383, 2.170104}, //RIGHT_FAR
{3700.724365, -5185.123047, 143.928024, 1.309310}, //RIGHT_MIDDLE
{3665.121094, -5138.679199, 143.183212, 0.604023}, //RIGHT_NEAR
{3754.431396, -5080.727734, 142.036316, 3.736189}, //LEFT_FAR
{3724.396484, -5061.330566, 142.032700, 4.564785}, //LEFT_MIDDLE
{3687.158424, -5076.834473, 142.017319, 5.237086}, //LEFT_NEAR
{3687.571777, -5126.831055, 142.017807, 0.604023}, //RIGHT_FAR
{3707.990733, -5151.450195, 142.032562, 1.376855}, //RIGHT_MIDDLE
{3739.500000, -5141.883989, 142.014113, 2.121412} //RIGHT_NEAR
};
struct TRINITY_DLL_DECL boss_kelthuzadAI : public BossAI
{
boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD) {}
uint32 GuardiansOfIcecrown_Count;
uint32 Phase;
uint32 GuardiansOfIcecrown_Timer;
void Reset()
{
_Reset();
me->SetReactState(REACT_AGGRESSIVE);
GuardiansOfIcecrown_Count = 0;
GuardiansOfIcecrown_Timer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3
Phase=0;
}
void KilledUnit()
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
}
void JustDied(Unit* Killer)
{
_JustDied();
DoScriptText(SAY_DEATH, m_creature);
}
void EnterCombat(Unit* who)
{
_EnterCombat();
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
Phase=1;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_PASSIVE);
events.ScheduleEvent(EVENT_WASTE, 5000);
events.ScheduleEvent(EVENT_ABOMIN, 25000);
events.ScheduleEvent(EVENT_WEAVER, 20000);
events.ScheduleEvent(EVENT_PHASE, 228000);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateCombatState())
return;
events.Update(diff);
if (Phase == 1)
{
while(uint32 eventId = events.GetEvent())
{
switch(eventId)
{
case EVENT_WASTE:
DoSummon(NPC_WASTE, Pos[RAND(0,3,6,9)]);
events.RepeatEvent(5000);
break;
case EVENT_ABOMIN:
DoSummon(NPC_ABOMINATION, Pos[RAND(1,4,7,10)]);
events.RepeatEvent(25000);
break;
case EVENT_WEAVER:
DoSummon(NPC_WEAVER, Pos[RAND(0,3,6,9)]);
events.RepeatEvent(20000);
break;
case EVENT_PHASE:
events.Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_AGGRESSIVE);
events.ScheduleEvent(EVENT_BOLT, urand(1000,10000));
events.ScheduleEvent(EVENT_NOVA, urand(10000,15000));
events.ScheduleEvent(EVENT_DETONATE, 20000);
events.ScheduleEvent(EVENT_FISSURE, 25000);
events.ScheduleEvent(EVENT_BLAST, urand(30000,60000));
if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
events.ScheduleEvent(EVENT_CHAIN, urand(30000,60000));
Phase = 2;
return;
default:
events.PopEvent();
break;
}
}
}
else
{
//start phase 3 when we are 40% health
if (Phase != 3)
{
if (HealthBelowPct(40))
{
Phase = 3 ;
DoScriptText(SAY_REQUEST_AID, m_creature);
//here Lich King should respond to KelThuzad but I don't know which Creature to make talk
//so for now just make Kelthuzad says it.
DoScriptText(SAY_ANSWER_REQUEST, m_creature);
}
}
else if (GuardiansOfIcecrown_Count < RAID_MODE(2,5))
{
if (GuardiansOfIcecrown_Timer <= diff)
{
DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8)]);
++GuardiansOfIcecrown_Count;
GuardiansOfIcecrown_Timer = 5000;
}
else GuardiansOfIcecrown_Timer -= diff;
}
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
if (uint32 eventId = events.GetEvent())
{
switch(eventId)
{
case EVENT_BOLT:
DoCastVictim(RAID_MODE(SPELL_FROST_BOLT,H_SPELL_FROST_BOLT));
events.RepeatEvent(urand(1000,10000));
return;
case EVENT_NOVA:
DoCastAOE(RAID_MODE(SPELL_FROST_BOLT_AOE,H_SPELL_FROST_BOLT_AOE));
events.RepeatEvent(urand(10000,20000));
return;
case EVENT_CHAIN:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true))
DoCast(pTarget, SPELL_CHAINS_OF_KELTHUZAD);
DoScriptText(RAND(SAY_CHAIN_1,SAY_CHAIN_2), me);
events.RepeatEvent(urand(30000,60000));
return;
case EVENT_DETONATE:
{
std::vector<Unit*> unitList;
std::list<HostilReference*> *threatList = &me->getThreatManager().getThreatList();
for (std::list<HostilReference*>::const_iterator itr = threatList->begin(); itr != threatList->end(); ++itr)
{
if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER
&& (*itr)->getTarget()->getPowerType() == POWER_MANA
&& (*itr)->getTarget()->GetPower(POWER_MANA))
unitList.push_back((*itr)->getTarget());
}
if (!unitList.empty())
{
std::vector<Unit*>::iterator itr = unitList.begin();
advance(itr, rand()%unitList.size());
DoCast(*itr, SPELL_MANA_DETONATION);
DoScriptText(RAND(SAY_SPECIAL_1,SAY_SPECIAL_2,SAY_SPECIAL_3), me);
}
events.RepeatEvent(20000);
return;
}
case EVENT_FISSURE:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget, SPELL_SHADOW_FISURE);
events.RepeatEvent(25000);
return;
case EVENT_BLAST:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
DoCast(pTarget, SPELL_FROST_BLAST);
if (rand()%2)
DoScriptText(SAY_FROST_BLAST, m_creature);
events.RepeatEvent(urand(30000,60000));
return;
default:
events.PopEvent();
return;
}
}
DoMeleeAttackIfReady();
}
}
};
CreatureAI* GetAI_boss_kelthuzadAI(Creature* pCreature)
{
return new boss_kelthuzadAI (pCreature);
}
void AddSC_boss_kelthuzad()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_kelthuzad";
newscript->GetAI = &GetAI_boss_kelthuzadAI;
newscript->RegisterSelf();
}
@@ -0,0 +1,124 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
enum Spells
{
SPELL_NECROTIC_AURA = 55593,
SPELL_SUMMON_SPORE = 29234,
SPELL_DEATHBLOOM = 29865,
H_SPELL_DEATHBLOOM = 55053,
SPELL_INEVITABLE_DOOM = 29204,
H_SPELL_INEVITABLE_DOOM = 55052
};
enum Events
{
EVENT_NONE,
EVENT_AURA,
EVENT_BLOOM,
EVENT_DOOM,
};
struct TRINITY_DLL_DECL boss_loathebAI : public BossAI
{
boss_loathebAI(Creature *c) : BossAI(c, BOSS_LOATHEB) {}
void EnterCombat(Unit *who)
{
_EnterCombat();
events.ScheduleEvent(EVENT_AURA, 0);
events.ScheduleEvent(EVENT_BLOOM, 30000);
events.ScheduleEvent(EVENT_DOOM, 120000);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_AURA:
DoCastAOE(SPELL_NECROTIC_AURA);
events.ScheduleEvent(EVENT_AURA, 20000);
return;
case EVENT_BLOOM:
DoCastAOE(SPELL_SUMMON_SPORE, true);
DoCastAOE(RAID_MODE(SPELL_DEATHBLOOM,H_SPELL_DEATHBLOOM));
events.ScheduleEvent(EVENT_BLOOM, 30000);
return;
case EVENT_DOOM:
DoCastAOE(RAID_MODE(SPELL_INEVITABLE_DOOM,H_SPELL_INEVITABLE_DOOM));
events.ScheduleEvent(EVENT_DOOM, events.GetTimer() < 5*60000 ? 30000 : 15000);
return;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_loatheb(Creature* pCreature)
{
return new boss_loathebAI (pCreature);
}
enum SporeSpells
{
SPELL_FUNGAL_CREEP = 29232
};
struct TRINITY_DLL_DECL mob_loatheb_sporeAI : public ScriptedAI
{
mob_loatheb_sporeAI(Creature *c) : ScriptedAI(c) {}
void JustDied(Unit* killer)
{
DoCast(killer, SPELL_FUNGAL_CREEP);
}
};
CreatureAI* GetAI_mob_loatheb_spore(Creature* pCreature)
{
return new mob_loatheb_sporeAI (pCreature);
}
void AddSC_boss_loatheb()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_loatheb";
newscript->GetAI = &GetAI_boss_loatheb;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_loatheb_spore";
newscript->GetAI = &GetAI_mob_loatheb_spore;
newscript->RegisterSelf();
// Fungal Creep
//GetAISpellInfo(29232)->condition = AICOND_DIE;
}
@@ -0,0 +1,141 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define SPELL_WEB_WRAP 28622
#define SPELL_WEB_SPRAY RAID_MODE(29484,54125)
#define SPELL_POISON_SHOCK RAID_MODE(28741,54122)
#define SPELL_NECROTIC_POISON RAID_MODE(54121,28776)
#define SPELL_FRENZY RAID_MODE(54123,54124)
#define MOB_WEB_WRAP 16486
#define MOB_SPIDERLING 17055
#define MAX_POS_WRAP 3
const float PosWrap[MAX_POS_WRAP][3] =
{
{3546.796, -3869.082, 296.450},
{3531.271, -3847.424, 299.450},
{3497.067, -3843.384, 302.384},
};
enum Events
{
EVENT_NONE,
EVENT_SPRAY,
EVENT_SHOCK,
EVENT_POISON,
EVENT_WRAP,
EVENT_SUMMON,
};
struct TRINITY_DLL_DECL boss_maexxnaAI : public BossAI
{
boss_maexxnaAI(Creature *c) : BossAI(c, BOSS_MAEXXNA) {}
bool enraged;
void EnterCombat(Unit *who)
{
_EnterCombat();
enraged = false;
events.ScheduleEvent(EVENT_WRAP, 20000);
events.ScheduleEvent(EVENT_SPRAY, 40000);
events.ScheduleEvent(EVENT_SHOCK, 10000);
events.ScheduleEvent(EVENT_POISON, 5000);
events.ScheduleEvent(EVENT_SUMMON, 40000);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_WRAP:
for (uint8 i = 0; i < RAID_MODE(1,2); ++i)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP))
{
pTarget->RemoveAura(SPELL_WEB_SPRAY);
uint8 pos = rand()%MAX_POS_WRAP;
pTarget->GetMotionMaster()->MoveJump(PosWrap[pos][0], PosWrap[pos][1], PosWrap[pos][2], 20, 20);
if (Creature *wrap = DoSummon(MOB_WEB_WRAP, pTarget, 0, 60000))
{
wrap->AI()->SetGUID(pTarget->GetGUID());
wrap->GetMotionMaster()->MoveJump(PosWrap[pos][0], PosWrap[pos][1], PosWrap[pos][2], 20, 20);
}
}
}
events.ScheduleEvent(EVENT_WRAP, 40000);
return;
case EVENT_SPRAY:
DoCastAOE(SPELL_WEB_SPRAY);
events.ScheduleEvent(EVENT_SPRAY, 40000);
return;
case EVENT_SHOCK:
DoCastAOE(SPELL_POISON_SHOCK);
events.ScheduleEvent(EVENT_SHOCK, 10000);
return;
case EVENT_POISON:
DoCast(me->getVictim(), SPELL_NECROTIC_POISON);
events.ScheduleEvent(EVENT_POISON, 30000);
return;
case EVENT_SUMMON:
{
uint8 amount = urand(8,10);
for (uint8 i = 0; i < amount; ++i)
DoSummon(MOB_SPIDERLING, me);
events.ScheduleEvent(EVENT_SUMMON, 40000);
break;
}
}
}
if (!enraged && HealthBelowPct(30))
{
DoCast(me, SPELL_FRENZY);
enraged = true;
}
else
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_maexxna(Creature* pCreature)
{
return new boss_maexxnaAI (pCreature);
}
void AddSC_boss_maexxna()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_maexxna";
newscript->GetAI = &GetAI_boss_maexxna;
newscript->RegisterSelf();
}
@@ -0,0 +1,211 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define SAY_AGGRO RAND(-1533075,-1533076,-1533077)
#define SAY_SUMMON -1533078
#define SAY_SLAY RAND(-1533079,-1533080)
#define SAY_DEATH -1533081
#define SOUND_DEATH 8848
#define SPELL_CURSE_PLAGUEBRINGER RAID_MODE(29213,54835)
#define SPELL_BLINK RAND(29208,29209,29210,29211)
#define SPELL_CRIPPLE RAID_MODE(29212,54814)
#define SPELL_TELEPORT 29216
#define MOB_WARRIOR 16984
#define MOB_CHAMPION 16983
#define MOB_GUARDIAN 16981
// Teleport position of Noth on his balcony
#define TELE_X 2631.370
#define TELE_Y -3529.680
#define TELE_Z 274.040
#define TELE_O 6.277
#define MAX_SUMMON_POS 5
const float SummonPos[MAX_SUMMON_POS][4] =
{
{2728.12, -3544.43, 261.91, 6.04},
{2729.05, -3544.47, 261.91, 5.58},
{2728.24, -3465.08, 264.20, 3.56},
{2704.11, -3456.81, 265.53, 4.51},
{2663.56, -3464.43, 262.66, 5.20},
};
enum Events
{
EVENT_NONE,
EVENT_BERSERK,
EVENT_CURSE,
EVENT_BLINK,
EVENT_WARRIOR,
EVENT_BALCONY,
EVENT_WAVE,
EVENT_GROUND,
};
struct TRINITY_DLL_DECL boss_nothAI : public BossAI
{
boss_nothAI(Creature *c) : BossAI(c, BOSS_NOTH) {}
uint32 waveCount, balconyCount;
void Reset()
{
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
_Reset();
}
void EnterCombat(Unit *who)
{
_EnterCombat();
DoScriptText(SAY_AGGRO, me);
balconyCount = 0;
EnterPhaseGround();
}
void EnterPhaseGround()
{
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoZoneInCombat();
if (me->getThreatManager().isThreatListEmpty())
EnterEvadeMode();
else
{
events.ScheduleEvent(EVENT_BALCONY, 110000);
events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000);
events.ScheduleEvent(EVENT_WARRIOR, 30000);
if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000);
}
}
void KilledUnit(Unit* victim)
{
if (!(rand()%5))
DoScriptText(SAY_SLAY, me);
}
void JustSummoned(Creature *summon)
{
summons.Summon(summon);
summon->setActive(true);
summon->AI()->DoZoneInCombat();
}
void JustDied(Unit* Killer)
{
_JustDied();
DoScriptText(SAY_DEATH, me);
}
void SummonUndead(uint32 entry, uint32 num)
{
for (uint32 i = 0; i < num; ++i)
{
uint32 pos = rand()%MAX_SUMMON_POS;
me->SummonCreature(entry, SummonPos[pos][0], SummonPos[pos][1], SummonPos[pos][2],
SummonPos[pos][3], TEMPSUMMON_CORPSE_DESPAWN, 60000);
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateCombatState() || !CheckInRoom())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_CURSE:
DoCastAOE(SPELL_CURSE_PLAGUEBRINGER);
events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000);
return;
case EVENT_WARRIOR:
DoScriptText(SAY_SUMMON, me);
SummonUndead(MOB_WARRIOR, RAID_MODE(2,3));
events.ScheduleEvent(EVENT_WARRIOR, 30000);
return;
case EVENT_BLINK:
DoCastAOE(SPELL_CRIPPLE, true);
DoCastAOE(SPELL_BLINK);
DoResetThreat();
events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000);
return;
case EVENT_BALCONY:
me->SetReactState(REACT_PASSIVE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->AttackStop();
me->RemoveAllAuras();
me->NearTeleportTo(TELE_X, TELE_Y, TELE_Z, TELE_O);
events.Reset();
events.ScheduleEvent(EVENT_WAVE, 2000);
waveCount = 0;
return;
case EVENT_WAVE:
DoScriptText(SAY_SUMMON, me);
switch(balconyCount)
{
case 0: SummonUndead(MOB_CHAMPION, RAID_MODE(2,4)); break;
case 1: SummonUndead(MOB_CHAMPION, RAID_MODE(1,2));
SummonUndead(MOB_GUARDIAN, RAID_MODE(1,2)); break;
case 2: SummonUndead(MOB_GUARDIAN, RAID_MODE(2,4)); break;
default:SummonUndead(MOB_CHAMPION, RAID_MODE(5,10));
SummonUndead(MOB_GUARDIAN, RAID_MODE(5,10));break;
}
++waveCount;
events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, 34000);
return;
case EVENT_GROUND:
{
++balconyCount;
float x, y, z, o;
me->GetHomePosition(x, y, z, o);
me->NearTeleportTo(x, y, z, o);
EnterPhaseGround();
return;
}
}
}
if (me->HasReactState(REACT_AGGRESSIVE))
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_noth(Creature* pCreature)
{
return new boss_nothAI (pCreature);
}
void AddSC_boss_noth()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_noth";
newscript->GetAI = &GetAI_boss_noth;
newscript->RegisterSelf();
}
@@ -0,0 +1,156 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define SAY_AGGRO RAND(-1533017,-1533018)
#define SAY_SLAY -1533019
#define SAY_DEATH -1533020
#define EMOTE_BERSERK -1533021
#define EMOTE_ENRAGE -1533022
#define SPELL_HATEFULSTRIKE RAID_MODE(41926,59192)
#define SPELL_FRENZY 28131
#define SPELL_BERSERK 26662
#define SPELL_SLIMEBOLT 32309
#define EVENT_BERSERK 1
#define EVENT_HATEFUL 2
#define EVENT_SLIME 3
#define ACHIEVEMENT_MAKE_QUICK_WERK_OF_HIM RAID_MODE(1856, 1857)
#define MAX_ENCOUNTER_TIME 3 * 60 * 1000
struct TRINITY_DLL_DECL boss_patchwerkAI : public BossAI
{
boss_patchwerkAI(Creature *c) : BossAI(c, BOSS_PATCHWERK) {}
bool Enraged;
uint32 EncounterTime;
void KilledUnit(Unit* Victim)
{
if (!(rand()%5))
DoScriptText(SAY_SLAY, me);
}
void JustDied(Unit* Killer)
{
_JustDied();
DoScriptText(SAY_DEATH, me);
if(EncounterTime <= MAX_ENCOUNTER_TIME)
{
AchievementEntry const *AchievMakeQuickWerkOfHim = GetAchievementStore()->LookupEntry(ACHIEVEMENT_MAKE_QUICK_WERK_OF_HIM);
if(AchievMakeQuickWerkOfHim)
{
Map *pMap = m_creature->GetMap();
if(pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievMakeQuickWerkOfHim);
}
}
}
}
void EnterCombat(Unit *who)
{
_EnterCombat();
Enraged = false;
EncounterTime = 0;
DoScriptText(SAY_AGGRO, me);
events.ScheduleEvent(EVENT_HATEFUL, 1200);
events.ScheduleEvent(EVENT_BERSERK, 360000);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
EncounterTime += diff;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_HATEFUL:
{
//Cast Hateful strike on the player with the highest
//amount of HP within melee distance
uint32 MostHP = 0;
Unit* pMostHPTarget = NULL;
std::list<HostilReference*>::iterator i = me->getThreatManager().getThreatList().begin();
for (; i != me->getThreatManager().getThreatList().end(); ++i)
{
Unit *pTarget = (*i)->getTarget();
if (pTarget->isAlive() && pTarget->GetHealth() > MostHP && me->IsWithinMeleeRange(pTarget))
{
MostHP = pTarget->GetHealth();
pMostHPTarget = pTarget;
}
}
if (pMostHPTarget)
DoCast(pMostHPTarget, SPELL_HATEFULSTRIKE, true);
events.ScheduleEvent(EVENT_HATEFUL, 1200);
return;
}
case EVENT_BERSERK:
DoCast(m_creature, SPELL_BERSERK);
DoScriptText(EMOTE_BERSERK, m_creature);
events.ScheduleEvent(EVENT_SLIME, 2000);
return;
case EVENT_SLIME:
DoCast(m_creature->getVictim(), SPELL_SLIMEBOLT);
events.ScheduleEvent(EVENT_SLIME, 2000);
return;
}
}
if (!Enraged && HealthBelowPct(5))
{
DoCast(m_creature, SPELL_FRENZY);
DoScriptText(EMOTE_ENRAGE, NULL);
Enraged = true;
return;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_patchwerk(Creature* pCreature)
{
return new boss_patchwerkAI (pCreature);
}
void AddSC_boss_patchwerk()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_patchwerk";
newscript->GetAI = &GetAI_boss_patchwerk;
newscript->RegisterSelf();
}
@@ -0,0 +1,139 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
//Razuvious - NO TEXT sound only
//8852 aggro01 - Hah hah, I'm just getting warmed up!
//8853 aggro02 Stand and fight!
//8854 aggro03 Show me what you've got!
//8861 slay1 - You should've stayed home!
//8863 slay2-
//8858 cmmnd3 - You disappoint me, students!
//8855 cmmnd1 - Do as I taught you!
//8856 cmmnd2 - Show them no mercy!
//8859 cmmnd4 - The time for practice is over! Show me what you've learned!
//8861 Sweep the leg! Do you have a problem with that?
//8860 death - An honorable... death...
//8947 - Aggro Mixed? - ?
#define SOUND_AGGRO RAND(8852,8853,8854)
#define SOUND_SLAY RAND(8861,8863)
#define SOUND_COMMND RAND(8855,8856,8858,8859,8861)
#define SOUND_DEATH 8860
#define SOUND_AGGROMIX 8847
#define SPELL_UNBALANCING_STRIKE 26613
#define SPELL_DISRUPTING_SHOUT RAID_MODE(29107,55543)
#define SPELL_JAGGED_KNIFE 55550
#define SPELL_HOPELESS 29125
enum Events
{
EVENT_NONE,
EVENT_STRIKE,
EVENT_SHOUT,
EVENT_KNIFE,
EVENT_COMMAND,
};
struct TRINITY_DLL_DECL boss_razuviousAI : public BossAI
{
boss_razuviousAI(Creature *c) : BossAI(c, BOSS_RAZUVIOUS) {}
void KilledUnit(Unit* victim)
{
if (!(rand()%3))
DoPlaySoundToSet(me, SOUND_SLAY);
}
void DamageTaken(Unit* pDone_by, uint32& uiDamage)
{
// Damage done by the controlled Death Knight understudies should also count toward damage done by players
if(pDone_by->GetTypeId() == TYPEID_UNIT && (pDone_by->GetEntry() == 16803 || pDone_by->GetEntry() == 29941))
{
me->LowerPlayerDamageReq(uiDamage);
}
}
void JustDied(Unit* killer)
{
_JustDied();
DoPlaySoundToSet(me, SOUND_DEATH);
me->CastSpell(me, SPELL_HOPELESS, true); // TODO: this may affect other creatures
}
void EnterCombat(Unit *who)
{
_EnterCombat();
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
events.ScheduleEvent(EVENT_STRIKE, 30000);
events.ScheduleEvent(EVENT_SHOUT, 25000);
events.ScheduleEvent(EVENT_COMMAND, 40000);
events.ScheduleEvent(EVENT_KNIFE, 10000);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_STRIKE:
DoCast(me->getVictim(), SPELL_UNBALANCING_STRIKE);
events.ScheduleEvent(EVENT_STRIKE, 30000);
return;
case EVENT_SHOUT:
DoCastAOE(SPELL_DISRUPTING_SHOUT);
events.ScheduleEvent(EVENT_SHOUT, 25000);
return;
case EVENT_KNIFE:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 45))
DoCast(pTarget, SPELL_JAGGED_KNIFE);
events.ScheduleEvent(EVENT_KNIFE, 10000);
return;
case EVENT_COMMAND:
DoPlaySoundToSet(me, SOUND_COMMND);
events.ScheduleEvent(EVENT_COMMAND, 40000);
return;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_razuvious(Creature* pCreature)
{
return new boss_razuviousAI (pCreature);
}
void AddSC_boss_razuvious()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_razuvious";
newscript->GetAI = &GetAI_boss_razuvious;
newscript->RegisterSelf();
}
@@ -0,0 +1,403 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
#define EMOTE_BREATH -1533082
#define EMOTE_ENRAGE -1533083
#define SPELL_FROST_AURA RAID_MODE(28531,55799)
#define SPELL_CLEAVE 19983
#define SPELL_TAIL_SWEEP RAID_MODE(55697,55696)
#define SPELL_SUMMON_BLIZZARD 28560
#define SPELL_LIFE_DRAIN RAID_MODE(28542,55665)
#define SPELL_ICEBOLT 28522
#define SPELL_FROST_BREATH 29318
#define SPELL_FROST_EXPLOSION 28524
#define SPELL_FROST_MISSILE 30101
#define SPELL_BERSERK 26662
#define SPELL_DIES 29357
#define SPELL_CHILL RAID_MODE(28547,55699)
#define MOB_BLIZZARD 16474
#define GO_ICEBLOCK 181247
#define ACHIEVEMENT_THE_HUNDRED_CLUB RAID_MODE(2146, 2147)
#define MAX_FROST_RESISTANCE 100
enum Phases
{
PHASE_NULL = 0,
PHASE_BIRTH,
PHASE_GROUND,
PHASE_FLIGHT,
};
enum Events
{
EVENT_NONE,
EVENT_BERSERK,
EVENT_CLEAVE,
EVENT_TAIL,
EVENT_DRAIN,
EVENT_BLIZZARD,
EVENT_FLIGHT,
EVENT_LIFTOFF,
EVENT_ICEBOLT,
EVENT_BREATH,
EVENT_EXPLOSION,
EVENT_LAND,
EVENT_GROUND,
EVENT_BIRTH,
};
typedef std::map<uint64, uint64> IceBlockMap;
struct TRINITY_DLL_DECL boss_sapphironAI : public BossAI
{
boss_sapphironAI(Creature* c) : BossAI(c, BOSS_SAPPHIRON)
, phase(PHASE_NULL)
{
pMap = m_creature->GetMap();
}
Phases phase;
uint32 iceboltCount;
IceBlockMap iceblocks;
bool CanTheHundredClub; // needed for achievement: The Hundred Club(2146, 2147)
uint32 CheckFrostResistTimer;
Map* pMap;
void InitializeAI()
{
float x, y, z;
me->GetPosition(x, y, z);
me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0);
me->SetVisibility(VISIBILITY_OFF);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_PASSIVE);
ScriptedAI::InitializeAI();
}
void Reset()
{
_Reset();
if (phase = PHASE_FLIGHT)
ClearIceBlock();
phase = PHASE_NULL;
CanTheHundredClub = true;
CheckFrostResistTimer = 5000;
}
void EnterCombat(Unit *who)
{
_EnterCombat();
me->CastSpell(me, SPELL_FROST_AURA, true);
events.ScheduleEvent(EVENT_BERSERK, 15*60000);
EnterPhaseGround();
CheckPlayersFrostResist();
}
void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
{
if (spell->Id == SPELL_ICEBOLT)
{
IceBlockMap::iterator itr = iceblocks.find(pTarget->GetGUID());
if (itr != iceblocks.end() && !itr->second)
{
if (GameObject *iceblock = me->SummonGameObject(GO_ICEBLOCK, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, 0, 0, 0, 0, 25000))
itr->second = iceblock->GetGUID();
}
}
}
void JustDied(Unit* who)
{
_JustDied();
me->CastSpell(me, SPELL_DIES, true);
CheckPlayersFrostResist();
if(CanTheHundredClub)
{
AchievementEntry const *AchievTheHundredClub = GetAchievementStore()->LookupEntry(ACHIEVEMENT_THE_HUNDRED_CLUB);
if(AchievTheHundredClub)
{
if(pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievTheHundredClub);
}
}
}
}
void MovementInform(uint32, uint32 id)
{
if (id == 1)
events.ScheduleEvent(EVENT_LIFTOFF, 0);
}
void DoAction(const int32 param)
{
if (param == DATA_SAPPHIRON_BIRTH)
{
phase = PHASE_BIRTH;
events.ScheduleEvent(EVENT_BIRTH, 23000);
}
}
void CheckPlayersFrostResist()
{
if(CanTheHundredClub && pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
if(itr->getSource()->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE)
{
CanTheHundredClub = false;
break;
}
}
}
}
void EnterPhaseGround()
{
phase = PHASE_GROUND;
me->SetReactState(REACT_AGGRESSIVE);
events.SetPhase(PHASE_GROUND);
events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_BLIZZARD, 5000+rand()%5000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_FLIGHT, 45000);
}
void ClearIceBlock()
{
for (IceBlockMap::iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr)
{
if (Player* pPlayer = Unit::GetPlayer(itr->first))
pPlayer->RemoveAura(SPELL_ICEBOLT);
if (GameObject* pGo = GameObject::GetGameObject(*me, itr->second))
pGo->Delete();
}
iceblocks.clear();
}
void UpdateAI(const uint32 diff)
{
if (!phase)
return;
events.Update(diff);
if (phase != PHASE_BIRTH && !UpdateCombatState() || !CheckInRoom())
return;
if(CanTheHundredClub)
{
if (CheckFrostResistTimer <= diff)
{
CheckPlayersFrostResist();
CheckFrostResistTimer = (rand() % 5 + 5) * 1000;
} else CheckFrostResistTimer -= diff;
}
if (phase == PHASE_GROUND)
{
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_BERSERK:
DoScriptText(EMOTE_ENRAGE, m_creature);
DoCast(me, SPELL_BERSERK);
return;
case EVENT_CLEAVE:
DoCast(me->getVictim(), SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND);
return;
case EVENT_TAIL:
DoCastAOE(SPELL_TAIL_SWEEP);
events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND);
return;
case EVENT_DRAIN:
DoCastAOE(SPELL_LIFE_DRAIN);
events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND);
return;
case EVENT_BLIZZARD:
{
//DoCastAOE(SPELL_SUMMON_BLIZZARD);
if (Creature *pSummon = DoSummon(MOB_BLIZZARD, me, 0.0f, urand(25000,30000), TEMPSUMMON_TIMED_DESPAWN))
pSummon->GetMotionMaster()->MoveRandom(40);
events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20000,7000), 0, PHASE_GROUND);
break;
}
case EVENT_FLIGHT:
phase = PHASE_FLIGHT;
events.SetPhase(PHASE_FLIGHT);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
float x, y, z, o;
me->GetHomePosition(x, y, z, o);
me->GetMotionMaster()->MovePoint(1, x, y, z);
return;
}
}
DoMeleeAttackIfReady();
}
else
{
if (uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_LIFTOFF:
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_ICEBOLT, 1500);
iceboltCount = RAID_MODE(2,3);
return;
case EVENT_ICEBOLT:
{
std::vector<Unit*> targets;
std::list<HostilReference*>::iterator i = me->getThreatManager().getThreatList().begin();
for (; i != me->getThreatManager().getThreatList().end(); ++i)
if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT))
targets.push_back((*i)->getTarget());
if (targets.empty())
iceboltCount = 0;
else
{
std::vector<Unit*>::iterator itr = targets.begin();
advance(itr, rand()%targets.size());
iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0));
DoCast(*itr, SPELL_ICEBOLT);
--iceboltCount;
}
if (iceboltCount)
events.ScheduleEvent(EVENT_ICEBOLT, 1000);
else
events.ScheduleEvent(EVENT_BREATH, 1000);
return;
}
case EVENT_BREATH:
{
DoScriptText(EMOTE_BREATH, me);
DoCastAOE(SPELL_FROST_MISSILE);
events.ScheduleEvent(EVENT_EXPLOSION, 8000);
return;
}
case EVENT_EXPLOSION:
CastExplosion();
ClearIceBlock();
events.ScheduleEvent(EVENT_LAND, 3000);
return;
case EVENT_LAND:
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_GROUND, 1500);
return;
case EVENT_GROUND:
EnterPhaseGround();
return;
case EVENT_BIRTH:
me->SetVisibility(VISIBILITY_ON);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_AGGRESSIVE);
return;
}
}//if (uint32 eventId = events.ExecuteEvent())
}//if (phase == PHASE_GROUND)
}
void CastExplosion()
{
DoZoneInCombat(); // make sure everyone is in threatlist
std::vector<Unit*> targets;
std::list<HostilReference*>::iterator i = me->getThreatManager().getThreatList().begin();
for (; i != me->getThreatManager().getThreatList().end(); ++i)
{
Unit *pTarget = (*i)->getTarget();
if (pTarget->GetTypeId() != TYPEID_PLAYER)
continue;
if (pTarget->HasAura(SPELL_ICEBOLT))
{
pTarget->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true);
targets.push_back(pTarget);
continue;
}
for (IceBlockMap::iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr)
{
if (GameObject* pGo = GameObject::GetGameObject(*me, itr->second))
{
if (pGo->IsInBetween(me, pTarget, 2.0f)
&& me->GetExactDist2d(pTarget->GetPositionX(), pTarget->GetPositionY()) - me->GetExactDist2d(pGo->GetPositionX(), pGo->GetPositionY()) < 5.0f)
{
pTarget->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true);
targets.push_back(pTarget);
break;
}
}
}
}
me->CastSpell(me, SPELL_FROST_EXPLOSION, true);
for (std::vector<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
(*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false);
}
};
CreatureAI* GetAI_boss_sapphiron(Creature* pCreature)
{
return new boss_sapphironAI (pCreature);
}
void AddSC_boss_sapphiron()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_sapphiron";
newscript->GetAI = &GetAI_boss_sapphiron;
newscript->RegisterSelf();
// Chill
GetAISpellInfo(28547)->cooldown = 1000;
GetAISpellInfo(55699)->cooldown = 1000;
}
@@ -0,0 +1,245 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
//Stalagg
enum StalaggYells
{
SAY_STAL_AGGRO = -1533023, //not used
SAY_STAL_SLAY = -1533024, //not used
SAY_STAL_DEATH = -1533025 //not used
};
enum StalagSpells
{
SPELL_POWERSURGE = 54529,
H_SPELL_POWERSURGE = 28134
};
//Feugen
enum FeugenYells
{
SAY_FEUG_AGGRO = -1533026, //not used
SAY_FEUG_SLAY = -1533027, //not used
SAY_FEUG_DEATH = -1533028 //not used
};
enum FeugenSpells
{
SPELL_STATICFIELD = 28135,
H_SPELL_STATICFIELD = 54528
};
//generic
#define C_TESLA_COIL 16218 //the coils (emotes "Tesla Coil overloads!")
//Thaddius
enum ThaddiusYells
{
SAY_GREET = -1533029, //not used
SAY_AGGRO_1 = -1533030,
SAY_AGGRO_2 = -1533031,
SAY_AGGRO_3 = -1533032,
SAY_SLAY = -1533033,
SAY_ELECT = -1533034, //not used
SAY_DEATH = -1533035,
SAY_SCREAM1 = -1533036, //not used
SAY_SCREAM2 = -1533037, //not used
SAY_SCREAM3 = -1533038, //not used
SAY_SCREAM4 = -1533039 //not used
};
enum ThaddiusSpells
{
SPELL_POLARITY_SHIFT = 28089,
SPELL_BALL_LIGHTNING = 28299,
SPELL_CHAIN_LIGHTNING = 28167,
H_SPELL_CHAIN_LIGHTNING = 54531,
SPELL_BERSERK = 27680
};
enum Events
{
EVENT_NONE,
EVENT_SHIFT,
EVENT_CHAIN,
EVENT_BERSERK,
};
bool CheckStalaggAlive = true;
bool CheckFeugenAlive = true;
struct TRINITY_DLL_DECL boss_thaddiusAI : public BossAI
{
boss_thaddiusAI(Creature *c) : BossAI(c, BOSS_THADDIUS)
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
me->SetReactState(REACT_PASSIVE);
}
void KilledUnit(Unit* victim)
{
if (!(rand()%5))
DoScriptText(SAY_SLAY, me);
}
void JustDied(Unit* Killer)
{
_JustDied();
DoScriptText(SAY_DEATH, me);
}
void EnterCombat(Unit *who)
{
_EnterCombat();
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
events.ScheduleEvent(EVENT_SHIFT, 30000);
events.ScheduleEvent(EVENT_CHAIN, urand(10000,20000));
events.ScheduleEvent(EVENT_BERSERK, 360000);
}
void UpdateAI(const uint32 diff)
{
if (CheckStalaggAlive == false && CheckFeugenAlive == false) {
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
me->SetReactState(REACT_AGGRESSIVE);
}
if (!UpdateVictim())
return;
events.Update(diff);
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SHIFT:
DoCastAOE(SPELL_POLARITY_SHIFT);
events.ScheduleEvent(EVENT_SHIFT, 30000);
return;
case EVENT_CHAIN:
DoCast(me->getVictim(), RAID_MODE(SPELL_CHAIN_LIGHTNING, H_SPELL_CHAIN_LIGHTNING));
events.ScheduleEvent(EVENT_CHAIN, urand(10000,20000));
return;
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK);
return;
}
}
if (events.GetTimer() > 15000 && !me->IsWithinMeleeRange(me->getVictim()))
DoCast(me->getVictim(), SPELL_BALL_LIGHTNING);
else
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_thaddius(Creature* pCreature)
{
return new boss_thaddiusAI (pCreature);
}
struct TRINITY_DLL_DECL mob_stalaggAI : public ScriptedAI
{
mob_stalaggAI(Creature *c) : ScriptedAI(c) {}
uint32 PowerSurgeTimer;
void reset()
{
PowerSurgeTimer = urand(20000,25000);
}
void JustDied(Unit *killer)
{
CheckStalaggAlive = false;
}
void UpdateAI(const uint32 uiDiff)
{
if (PowerSurgeTimer <= uiDiff)
{
DoCast(m_creature, RAID_MODE(SPELL_POWERSURGE, H_SPELL_POWERSURGE));
PowerSurgeTimer = urand(15000,20000);
} else PowerSurgeTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_stalagg(Creature* pCreature)
{
return new mob_stalaggAI(pCreature);
}
struct TRINITY_DLL_DECL mob_feugenAI : public ScriptedAI
{
mob_feugenAI(Creature *c) : ScriptedAI(c) {}
uint32 StaticFieldTimer;
uint32 Checktimer;
void reset()
{
StaticFieldTimer = 5000;
}
void JustDied(Unit *killer)
{
CheckFeugenAlive = false;
}
void UpdateAI(const uint32 uiDiff)
{
if (StaticFieldTimer <= uiDiff)
{
DoCast(m_creature, RAID_MODE(SPELL_STATICFIELD, H_SPELL_STATICFIELD));
StaticFieldTimer = 5000;
} else StaticFieldTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_feugen(Creature* pCreature)
{
return new mob_feugenAI(pCreature);
}
void AddSC_boss_thaddius()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_thaddius";
newscript->GetAI = &GetAI_boss_thaddius;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_stalagg";
newscript->GetAI = &GetAI_mob_stalagg;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_feugen";
newscript->GetAI = &GetAI_mob_feugen;
newscript->RegisterSelf();
}
@@ -0,0 +1,244 @@
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "naxxramas.h"
const DoorData doorData[] =
{
{181126, BOSS_ANUBREKHAN,DOOR_TYPE_ROOM, BOUNDARY_S},
{181195, BOSS_ANUBREKHAN,DOOR_TYPE_PASSAGE, 0},
{194022, BOSS_FAERLINA, DOOR_TYPE_PASSAGE, 0},
{181209, BOSS_FAERLINA, DOOR_TYPE_PASSAGE, 0},
{181209, BOSS_MAEXXNA, DOOR_TYPE_ROOM, BOUNDARY_SW},
{181200, BOSS_NOTH, DOOR_TYPE_ROOM, BOUNDARY_N},
{181201, BOSS_NOTH, DOOR_TYPE_PASSAGE, BOUNDARY_E},
{181202, BOSS_NOTH, DOOR_TYPE_PASSAGE, 0},
{181202, BOSS_HEIGAN, DOOR_TYPE_ROOM, BOUNDARY_N},
{181203, BOSS_HEIGAN, DOOR_TYPE_PASSAGE, BOUNDARY_E},
{181241, BOSS_HEIGAN, DOOR_TYPE_PASSAGE, 0},
{181241, BOSS_LOATHEB, DOOR_TYPE_ROOM, BOUNDARY_W},
{181123, BOSS_PATCHWERK, DOOR_TYPE_PASSAGE, 0},
{181123, BOSS_GROBBULUS, DOOR_TYPE_ROOM, 0},
{181120, BOSS_GLUTH, DOOR_TYPE_PASSAGE, BOUNDARY_NW},
{181121, BOSS_GLUTH, DOOR_TYPE_PASSAGE, 0},
{181121, BOSS_THADDIUS, DOOR_TYPE_ROOM, 0},
{181124, BOSS_RAZUVIOUS, DOOR_TYPE_PASSAGE, 0},
{181124, BOSS_GOTHIK, DOOR_TYPE_ROOM, BOUNDARY_N},
{181125, BOSS_GOTHIK, DOOR_TYPE_PASSAGE, BOUNDARY_S},
{181119, BOSS_GOTHIK, DOOR_TYPE_PASSAGE, 0},
{181119, BOSS_HORSEMEN, DOOR_TYPE_ROOM, BOUNDARY_NE},
{181225, BOSS_SAPPHIRON, DOOR_TYPE_PASSAGE, BOUNDARY_W},
{0, 0, DOOR_TYPE_ROOM, 0}, // EOF
};
const MinionData minionData[] =
{
//{16573, BOSS_ANUBREKHAN}, there is no spawn point in db, so we do not add them here
{16506, BOSS_FAERLINA},
{16803, BOSS_RAZUVIOUS},
{16063, BOSS_HORSEMEN},
{16064, BOSS_HORSEMEN},
{16065, BOSS_HORSEMEN},
{30549, BOSS_HORSEMEN},
{0, 0,}
};
enum eEnums
{
GO_HORSEMEN_CHEST_HERO = 193426,
GO_HORSEMEN_CHEST = 181366, //four horsemen event, DoRespawnGameObject() when event == DONE
GO_GOTHIK_GATE = 181170,
SPELL_ERUPTION = 29371
};
const float HeiganPos[2] = {2796, -3707};
const float HeiganEruptionSlope[3] =
{
(-3685 - HeiganPos[1]) /(2724 - HeiganPos[0]),
(-3647 - HeiganPos[1]) /(2749 - HeiganPos[0]),
(-3637 - HeiganPos[1]) /(2771 - HeiganPos[0]),
};
// 0 H x
// 1 ^
// 2 |
// 3 y<--o
inline uint32 GetEruptionSection(float x, float y)
{
y -= HeiganPos[1];
if (y < 1.0f)
return 0;
x -= HeiganPos[0];
if (x > -1.0f)
return 3;
float slope = y/x;
for (uint32 i = 0; i < 3; ++i)
if (slope > HeiganEruptionSlope[i])
return i;
return 3;
}
struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
{
instance_naxxramas(Map* pMap) : InstanceData(pMap)
, Sapphiron(NULL), pGothikGate(NULL), HorsemenChest(NULL), HorsemenNum(0)
{
SetBossNumber(MAX_BOSS_NUMBER);
LoadDoorData(doorData);
LoadMinionData(minionData);
}
std::set<GameObject*> HeiganEruption[4];
GameObject* pGothikGate, *HorsemenChest;
Creature* Sapphiron;
uint32 HorsemenNum;
uint64 uiFaerlina;
uint64 uiThane;
uint64 uiLady;
uint64 uiBaron;
uint64 uiSir;
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case 15989: Sapphiron = add ? pCreature : NULL; return;
case 15953: uiFaerlina = pCreature->GetGUID(); return;
case 16064: uiThane = pCreature->GetGUID(); return;
case 16065: uiLady = pCreature->GetGUID(); return;
case 30549: uiBaron = pCreature->GetGUID(); return;
case 16063: uiSir = pCreature->GetGUID(); return;
}
AddMinion(pCreature, add);
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
if (pGo->GetGOInfo()->displayId == 6785 || pGo->GetGOInfo()->displayId == 1287)
{
uint32 section = GetEruptionSection(pGo->GetPositionX(), pGo->GetPositionY());
if (add)
HeiganEruption[section].insert(pGo);
else
HeiganEruption[section].erase(pGo);
return;
}
switch(pGo->GetEntry())
{
case GO_BIRTH: if (!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); return;
case GO_GOTHIK_GATE: pGothikGate = add ? pGo : NULL; break;
case GO_HORSEMEN_CHEST: HorsemenChest = add ? pGo : NULL; break;
case GO_HORSEMEN_CHEST_HERO: HorsemenChest = add ? pGo : NULL; break;
}
AddDoor(pGo, add);
}
void SetData(uint32 id, uint32 value)
{
switch(id)
{
case DATA_HEIGAN_ERUPT:
HeiganErupt(value);
break;
case DATA_GOTHIK_GATE:
if (pGothikGate)
pGothikGate->SetGoState(GOState(value));
break;
}
}
uint64 GetData64(uint32 id)
{
if (id == DATA_FAERLINA)
return uiFaerlina;
if (id == DATA_THANE)
return uiThane;
if (id == DATA_LADY)
return uiLady;
if (id == DATA_BARON)
return uiBaron;
if (id == DATA_SIR)
return uiSir;
return 0;
}
bool SetBossState(uint32 id, EncounterState state)
{
if (!InstanceData::SetBossState(id, state))
return false;
if (id == BOSS_HORSEMEN && state == DONE && HorsemenChest)
HorsemenChest->SetRespawnTime(HorsemenChest->GetRespawnDelay());
return true;
}
void HeiganErupt(uint32 section)
{
for (uint32 i = 0; i < 4; ++i)
{
if (i == section)
continue;
for (std::set<GameObject*>::iterator itr = HeiganEruption[i].begin(); itr != HeiganEruption[i].end(); ++itr)
{
(*itr)->SendCustomAnim();
(*itr)->CastSpell(NULL, SPELL_ERUPTION);
}
}
}
};
bool AreaTrigger_at_naxxramas_frostwyrm_wing(Player* pPlayer, const AreaTriggerEntry *at)
{
if (pPlayer->isGameMaster())
return false;
InstanceData *data = pPlayer->GetInstanceData();
if (data)
for (uint32 i = BOSS_ANUBREKHAN; i < BOSS_SAPPHIRON; ++i)
if (data->GetBossState(i) != DONE)
return true;
return false;
}
InstanceData* GetInstanceData_instance_naxxramas(Map* pMap)
{
return new instance_naxxramas(pMap);
}
void AddSC_instance_naxxramas()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_naxxramas";
newscript->GetInstanceData = &GetInstanceData_instance_naxxramas;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "at_naxxramas_frostwyrm_wing";
newscript->pAreaTrigger = &AreaTrigger_at_naxxramas_frostwyrm_wing;
newscript->RegisterSelf();
}
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DEF_NAXXRAMAS_H
#define DEF_NAXXRAMAS_H
enum Encounter
{
BOSS_ANUBREKHAN,
BOSS_FAERLINA,
BOSS_MAEXXNA,
BOSS_NOTH,
BOSS_HEIGAN,
BOSS_LOATHEB,
BOSS_PATCHWERK,
BOSS_GROBBULUS,
BOSS_GLUTH,
BOSS_THADDIUS,
BOSS_RAZUVIOUS,
BOSS_GOTHIK,
BOSS_HORSEMEN,
BOSS_SAPPHIRON,
BOSS_KELTHUZAD,
MAX_BOSS_NUMBER
};
enum Data
{
DATA_HEIGAN_ERUPT,
DATA_GOTHIK_GATE,
DATA_SAPPHIRON_BIRTH,
DATA_FAERLINA,
DATA_THANE,
DATA_LADY,
DATA_BARON,
DATA_SIR
};
#define GO_BIRTH 181356
#endif
@@ -0,0 +1,156 @@
/* Script Data Start
SDName: Boss malygos
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = '' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
//Spells
#define SPELL_ARCANE_BREATH_N 56272
#define SPELL_ARCANE_BREATH_H 60072
#define SPELL_ARCANE_PULSE 57432
#define SPELL_ARCANE_STORM_1 57459
#define SPELL_ARCANE_STORM_2 61693
#define SPELL_ARCANE_STORM_3 61694
#define SPELL_STATIC_FIELD 57430
#define SPELL_SURGE_OF_POWER_1 56505
#define SPELL_SURGE_OF_POWER_2 57407
#define SPELL_SURGE_OF_POWER_3 60936
#define SPELL_VORTEX 56105
//Dragon "mounts" spells in Phase3
//they use Rugelike energy
#define SPELL_DMOUNT_FLAME_SPIKE 56091 //maybe not accurate
#define SPELL_DMOUNT_ENGULF_IN_FLAMES 61621
#define SPELL_DMOUNT_REVIVIFY 57090
#define SPELL_DMOUNT_LIFE_BURST 57143
#define SPELL_DMOUNT_FLAME_SHIELD 57108
//#define SPELL_DMOUNT_UNKNOWN XYZ //Increases your drake's flight speed by 500%.
//not in db
//Yell
//-->Other
#define SAY_ANTI_MAGIC_SHELL -1616000
#define SAY_BREATH_ATTACK -1616001
#define SAY_HIGH_DAMAGE_MODE -1616002
#define SAY_MAGIC_BLAST -1616003
//--> Generic Spells
#define SAY_GENERIC_SPELL_1 -1616004
#define SAY_GENERIC_SPELL_2 -1616005
#define SAY_GENERIC_SPELL_3 -1616006
#define SAY_DEATH -1616007
//--> Prefight
#define SAY_PREFIGHT_1 -1616008
#define SAY_PREFIGHT_2 -1616009
#define SAY_PREFIGHT_3 -1616010
#define SAY_PREFIGHT_4 -1616011
#define SAY_PREFIGHT_5 -1616012
//--> Phase1
#define SAY_PHASE1_AGGRO -1616013
#define SAY_PHASE1_END -1616014
#define SAY_PHASE1_SLAY_1 -1616015
#define SAY_PHASE1_SLAY_2 -1616016
#define SAY_PHASE1_SLAY_3 -1616017
//--> Phase2 at 50% HP,
/*Malygos himself is not targetable during this phase, it will end when the adds he spawns are all killed. However, he does continue to play a part in the encounter.
During this phase he drops anti-magic zones onto the ground the raid MUST stand inside of, it reduces magical damage taken by 50%. They shrink over time, so it's important that your raid moves to each new one he drops.
Throughout the phase, he will deep breath doing ~4k damage per second, unless you are standing inside of the anti-magic zone.
The way the fight works during this phase is there are NPCs riding around on disks in the room. There are two types of mobs, Lords and Scions.
The Lords will move down onto the group, and need to be tanked (They will one-shot a non-tank). After they die, they drop a disk that a raid member can mount onto, which allows them to fly, to attack the Scions that do not come down to the ground.
It is recommended to let melee take the first disks, then ranged. As those mobs die, they also drop disks, which allows the rest of your dps to get onto them.
The Scions will continually cast Arcane Blast on random targets on the floor, which is mitigated by the anti-magic zones. While mounted on a disk, you will not take damage.
After all of the NPCs riding on the disks die, the players on the disks need to dismount as Phase 3 is about to begin.*/
//not in db
#define SAY_PHASE2_AGGRO -1616018
#define SAY_PHASE2_END -1616019
#define SAY_PHASE2_SLAY_1 -1616020
#define SAY_PHASE2_SLAY_2 -1616021
#define SAY_PHASE2_SLAY_3 -1616022
//--> Phase3 Malygos destroys the floor, encounter continues on dragon "mounts"
#define SAY_PHASE3_INTRO -1616023
#define SAY_PHASE3_AGGRO -1616024
#define SAY_PHASE3_SLAY_1 -1616025
#define SAY_PHASE3_SLAY_2 -1616026
#define SAY_PHASE3_SLAY_3 -1616027
#define SAY_PHASE3_BIG_ATTACK -1616028
struct TRINITY_DLL_DECL boss_malygosAI : public ScriptedAI
{
boss_malygosAI(Creature *c) : ScriptedAI(c) {}
uint32 phase,
enrage;
void Reset()
{
//Source Deadly Boss Mod
enrage = 615000; //10 min
}
void EnterCombat(Unit* who)
{
if (phase == 1)
DoScriptText(SAY_PHASE1_AGGRO, m_creature);
if (phase == 2)
DoScriptText(SAY_PHASE1_AGGRO, m_creature);
if (phase == 3)
DoScriptText(SAY_PHASE1_AGGRO, m_creature);
}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
phase =1;
//Return since we have no target
if (!UpdateVictim())
return;
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 50){
phase = 2;
//spawn adds
//set malygos unatackable untill all adds spawned dead
//start phase3
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
if (phase ==1)
DoScriptText(RAND(SAY_PHASE1_SLAY_1,SAY_PHASE1_SLAY_2,SAY_PHASE1_SLAY_3), m_creature);
if (phase ==2)
DoScriptText(RAND(SAY_PHASE2_SLAY_1,SAY_PHASE2_SLAY_2,SAY_PHASE2_SLAY_3), m_creature);
if (phase ==3)
DoScriptText(RAND(SAY_PHASE3_SLAY_1,SAY_PHASE3_SLAY_2,SAY_PHASE3_SLAY_3), m_creature);
}
};
CreatureAI* GetAI_boss_malygos(Creature* pCreature)
{
return new boss_malygosAI (pCreature);
}
void AddSC_boss_malygos()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_malygos";
newscript->GetAI = &GetAI_boss_malygos;
newscript->RegisterSelf();
}
@@ -0,0 +1,4 @@
#ifndef DEF_EYE_OF_ETERNITY_H
#define DEF_EYE_OF_ETERNITY_H
#endif
@@ -0,0 +1,21 @@
#include "ScriptedPch.h"
#include "eye_of_eternity.h"
struct TRINITY_DLL_DECL instance_eye_of_eternity : public ScriptedInstance
{
instance_eye_of_eternity(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
};
InstanceData* GetInstanceData_instance_eye_of_eternity(Map* pMap)
{
return new instance_eye_of_eternity(pMap);
}
void AddSC_instance_eye_of_eternity()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_eye_of_eternity";
newscript->GetInstanceData = &GetInstanceData_instance_eye_of_eternity;
newscript->RegisterSelf();
}
@@ -0,0 +1,307 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Anomalus
SD%Complete:
SDComment:
SDCategory: The Nexus, The Nexus
EndScriptData */
#include "ScriptedPch.h"
#include "nexus.h"
bool DeadChaoticRift; // needed for achievement: Chaos Theory(2037)
enum eEnums
{
ACHIEVEMENT_CHAOS_THEORY = 2037,
//Spells
SPELL_SPARK_N = 47751,
SPELL_SPARK_H = 57062,
SPELL_RIFT_SHIELD = 47748,
SPELL_CHARGE_RIFT = 47747, //Works wrong (affect players, not rifts)
SPELL_CREATE_RIFT = 47743, //Don't work, using WA
SPELL_ARCANE_ATTRACTION = 57063, //No idea, when it's used
MOB_CRAZED_MANA_WRAITH = 26746,
MOB_CHAOTIC_RIFT = 26918,
SPELL_CHAOTIC_ENERGY_BURST = 47688,
SPELL_CHARGED_CHAOTIC_ENERGY_BURST = 47737,
SPELL_ARCANEFORM = 48019, //Chaotic Rift visual
//Yell
SAY_AGGRO = -1576010,
SAY_DEATH = -1576011,
SAY_RIFT = -1576012,
SAY_SHIELD = -1576013
};
float RiftLocation[6][3]=
{
{652.64, -273.70, -8.75},
{634.45, -265.94, -8.44},
{620.73, -281.17, -9.02},
{626.10, -304.67, -9.44},
{639.87, -314.11, -9.49},
{651.72, -297.44, -9.37}
};
struct TRINITY_DLL_DECL boss_anomalusAI : public ScriptedAI
{
boss_anomalusAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint8 Phase;
uint32 SPELL_SPARK_Timer;
uint32 SPELL_CREATE_RIFT_Timer;
uint64 ChaoticRiftGUID;
void Reset()
{
Phase = 0;
SPELL_SPARK_Timer = 5000;
SPELL_CREATE_RIFT_Timer = 25000;
ChaoticRiftGUID = 0;
DeadChaoticRift = false;
if (pInstance)
pInstance->SetData(DATA_ANOMALUS_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_ANOMALUS_EVENT, IN_PROGRESS);
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (IsHeroic() && !DeadChaoticRift)
{
AchievementEntry const *AchievChaosTheory = GetAchievementStore()->LookupEntry(ACHIEVEMENT_CHAOS_THEORY);
if (AchievChaosTheory)
{
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievChaosTheory);
}
}
}
if (pInstance)
pInstance->SetData(DATA_ANOMALUS_EVENT, DONE);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (m_creature->GetDistance(m_creature->GetHomePosition()) > 60.0f)
{
//Not blizzlike, hack to avoid an exploit
EnterEvadeMode();
return;
}
if (m_creature->HasAura(SPELL_RIFT_SHIELD))
{
if (ChaoticRiftGUID)
{
Unit* Rift = Unit::GetUnit((*m_creature), ChaoticRiftGUID);
if (Rift && Rift->isDead())
{
m_creature->RemoveAurasDueToSpell(SPELL_RIFT_SHIELD);
ChaoticRiftGUID = 0;
}
return;
}
} else
ChaoticRiftGUID = 0;
if ((Phase == 0) && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.75))
{
Phase = 1;
DoScriptText(SAY_SHIELD, m_creature);
DoCast(m_creature, SPELL_RIFT_SHIELD);
int tmp = rand()%(2);
Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (Rift)
{
//DoCast(Rift, SPELL_CHARGE_RIFT);
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
Rift->AI()->AttackStart(pTarget);
ChaoticRiftGUID = Rift->GetGUID();
DoScriptText(SAY_RIFT , m_creature);
}
}
if ((Phase == 1) && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.50))
{
Phase = 2;
DoScriptText(SAY_SHIELD , m_creature);
DoCast(m_creature, SPELL_RIFT_SHIELD);
int tmp = rand()%(2);
Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (Rift)
{
//DoCast(Rift, SPELL_CHARGE_RIFT);
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
Rift->AI()->AttackStart(pTarget);
ChaoticRiftGUID = Rift->GetGUID();
DoScriptText(SAY_RIFT , m_creature);
}
}
if ((Phase == 2) && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.25))
{
Phase = 3;
DoScriptText(SAY_SHIELD , m_creature);
DoCast(m_creature, SPELL_RIFT_SHIELD);
int tmp = rand()%(2);
Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (Rift)
{
//DoCast(Rift, SPELL_CHARGE_RIFT);
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
Rift->AI()->AttackStart(pTarget);
ChaoticRiftGUID = Rift->GetGUID();
DoScriptText(SAY_RIFT , m_creature);
}
}
if (SPELL_SPARK_Timer <= diff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_SPARK_N, SPELL_SPARK_H));
SPELL_SPARK_Timer = 5000;
} else SPELL_SPARK_Timer -=diff;
if (SPELL_CREATE_RIFT_Timer <= diff)
{
DoScriptText(SAY_RIFT , m_creature);
int tmp = rand()%(2);
Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (Rift)
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
Rift->AI()->AttackStart(pTarget);
SPELL_CREATE_RIFT_Timer = 25000;
} else SPELL_CREATE_RIFT_Timer -=diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_anomalus(Creature* pCreature)
{
return new boss_anomalusAI (pCreature);
}
struct TRINITY_DLL_DECL mob_chaotic_riftAI : public Scripted_NoMovementAI
{
mob_chaotic_riftAI(Creature *c) : Scripted_NoMovementAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 SPELL_CHAOTIC_ENERGY_BURST_Timer;
uint32 SUMMON_CRAZED_MANA_WRAITH_Timer;
void Reset()
{
SPELL_CHAOTIC_ENERGY_BURST_Timer = 1000;
SUMMON_CRAZED_MANA_WRAITH_Timer = 5000;
m_creature->SetDisplayId(25206); //For some reason in DB models for ally and horde are different.
//Model for ally (1126) does not show auras. Horde model works perfect.
//Set model to horde number
DoCast(m_creature, SPELL_ARCANEFORM, false);
}
void JustDied(Unit *killer)
{
DeadChaoticRift = true;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (SPELL_CHAOTIC_ENERGY_BURST_Timer <= diff)
{
Unit* Anomalus = Unit::GetUnit(*m_creature, pInstance ? pInstance->GetData64(DATA_ANOMALUS) : 0);
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
if (Anomalus && Anomalus->HasAura(SPELL_RIFT_SHIELD))
DoCast(pTarget, SPELL_CHARGED_CHAOTIC_ENERGY_BURST);
else
DoCast(pTarget, SPELL_CHAOTIC_ENERGY_BURST);
SPELL_CHAOTIC_ENERGY_BURST_Timer = 1000;
} else SPELL_CHAOTIC_ENERGY_BURST_Timer -=diff;
if (SUMMON_CRAZED_MANA_WRAITH_Timer <= diff)
{
Creature* Wraith = m_creature->SummonCreature(MOB_CRAZED_MANA_WRAITH, m_creature->GetPositionX()+1, m_creature->GetPositionY()+1, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (Wraith)
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
Wraith->AI()->AttackStart(pTarget);
Unit* Anomalus = Unit::GetUnit(*m_creature, pInstance ? pInstance->GetData64(DATA_ANOMALUS) : 0);
if (Anomalus && Anomalus->HasAura(SPELL_RIFT_SHIELD))
SUMMON_CRAZED_MANA_WRAITH_Timer = 5000;
else
SUMMON_CRAZED_MANA_WRAITH_Timer = 10000;
} else SUMMON_CRAZED_MANA_WRAITH_Timer -=diff;
}
};
CreatureAI* GetAI_mob_chaotic_rift(Creature* pCreature)
{
return new mob_chaotic_riftAI (pCreature);
}
void AddSC_boss_anomalus()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_anomalus";
newscript->GetAI = &GetAI_boss_anomalus;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_chaotic_rift";
newscript->GetAI = &GetAI_mob_chaotic_rift;
newscript->RegisterSelf();
}
@@ -0,0 +1,258 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Keristrasza
SD%Complete:
SDComment:
SDCategory: The Nexus, The Nexus
EndScriptData */
#include "ScriptedPch.h"
#include "nexus.h"
enum eEnums
{
CONTAINMENT_SPHERES = 3,
ACHIEVEMENT_INTENSE_COLD = 2036,
//Spells
SPELL_FROZEN_PRISON = 47854,
SPELL_TAIL_SWEEP = 50155,
SPELL_CRYSTAL_CHAINS = 50997,
SPELL_ENRAGE = 8599,
SPELL_CRYSTALFIRE_BREATH_N = 48096,
SPELL_CRYSTALFIRE_BREATH_H = 57091,
SPELL_CRYSTALIZE = 48179,
SPELL_INTENSE_COLD = 48094,
SPELL_INTENSE_COLD_TRIGGERED = 48095,
//Yell
SAY_AGGRO = -1576040,
SAY_SLAY = -1576041,
SAY_ENRAGE = -1576042,
SAY_DEATH = -1576043,
SAY_CRYSTAL_NOVA = -1576044
};
struct TRINITY_DLL_DECL boss_keristraszaAI : public ScriptedAI
{
boss_keristraszaAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 CRYSTALFIRE_BREATH_Timer;
uint32 CRYSTAL_CHAINS_CRYSTALIZE_Timer;
uint32 TAIL_SWEEP_Timer;
bool Enrage;
uint64 ContainmentSphereGUIDs[CONTAINMENT_SPHERES];
uint32 CheckIntenseColdTimer;
bool MoreThanTwoIntenseCold; // needed for achievement: Intense Cold(2036)
void Reset()
{
CRYSTALFIRE_BREATH_Timer = 14000;
CRYSTAL_CHAINS_CRYSTALIZE_Timer = DUNGEON_MODE(30000,11000);
TAIL_SWEEP_Timer = 5000;
Enrage = false;
CheckIntenseColdTimer = 2000;
MoreThanTwoIntenseCold = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
RemovePrison(CheckContainmentSpheres());
if (pInstance)
pInstance->SetData(DATA_KERISTRASZA_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
DoCastAOE(SPELL_INTENSE_COLD);
if (pInstance)
pInstance->SetData(DATA_KERISTRASZA_EVENT, IN_PROGRESS);
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (IsHeroic() && !MoreThanTwoIntenseCold)
{
AchievementEntry const *AchievIntenseCold = GetAchievementStore()->LookupEntry(ACHIEVEMENT_INTENSE_COLD);
if (AchievIntenseCold)
{
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievIntenseCold);
}
}
}
if (pInstance)
pInstance->SetData(DATA_KERISTRASZA_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
DoScriptText(SAY_SLAY, m_creature);
}
bool CheckContainmentSpheres(bool remove_prison = false)
{
if(!pInstance)
return false;
ContainmentSphereGUIDs[0] = pInstance->GetData64(ANOMALUS_CONTAINMET_SPHERE);
ContainmentSphereGUIDs[1] = pInstance->GetData64(ORMOROKS_CONTAINMET_SPHERE);
ContainmentSphereGUIDs[2] = pInstance->GetData64(TELESTRAS_CONTAINMET_SPHERE);
GameObject *ContainmentSpheres[CONTAINMENT_SPHERES];
for (uint8 i = 0; i < CONTAINMENT_SPHERES; ++i)
{
ContainmentSpheres[i] = pInstance->instance->GetGameObject(ContainmentSphereGUIDs[i]);
if (!ContainmentSpheres[i])
return false;
if (ContainmentSpheres[i]->GetGoState() != GO_STATE_ACTIVE)
return false;
}
if (remove_prison)
RemovePrison(true);
return true;
}
void RemovePrison(bool remove)
{
if (remove)
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if (m_creature->HasAura(SPELL_FROZEN_PRISON))
m_creature->RemoveAurasDueToSpell(SPELL_FROZEN_PRISON);
}
else
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
DoCast(m_creature, SPELL_FROZEN_PRISON, false);
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (CheckIntenseColdTimer < diff && !MoreThanTwoIntenseCold)
{
std::list<HostilReference*> ThreatList = m_creature->getThreatManager().getThreatList();
for (std::list<HostilReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); itr++)
{
Unit *pTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER)
continue;
Aura *AuraIntenseCold = pTarget->GetAura(SPELL_INTENSE_COLD_TRIGGERED);
if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2)
{
MoreThanTwoIntenseCold = true;
break;
}
}
CheckIntenseColdTimer = 2000;
} else CheckIntenseColdTimer -= diff;
if (!Enrage && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.25))
{
DoScriptText(SAY_ENRAGE, m_creature);
DoCast(m_creature, SPELL_ENRAGE);
Enrage = true;
}
if (CRYSTALFIRE_BREATH_Timer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_CRYSTALFIRE_BREATH_N, SPELL_CRYSTALFIRE_BREATH_H));
CRYSTALFIRE_BREATH_Timer = 14000;
} else CRYSTALFIRE_BREATH_Timer -=diff;
if (TAIL_SWEEP_Timer <= diff)
{
DoCast(m_creature, SPELL_TAIL_SWEEP);
TAIL_SWEEP_Timer = 5000;
} else TAIL_SWEEP_Timer -=diff;
if (CRYSTAL_CHAINS_CRYSTALIZE_Timer <= diff)
{
DoScriptText(SAY_CRYSTAL_NOVA, m_creature);
if (IsHeroic())
DoCast(m_creature, SPELL_CRYSTALIZE);
else if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_CRYSTAL_CHAINS);
CRYSTAL_CHAINS_CRYSTALIZE_Timer = DUNGEON_MODE(30000,11000);
} else CRYSTAL_CHAINS_CRYSTALIZE_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_keristrasza(Creature* pCreature)
{
return new boss_keristraszaAI (pCreature);
}
bool GOHello_containment_sphere(Player *pPlayer, GameObject *pGO)
{
ScriptedInstance *pInstance = pGO->GetInstanceData();
Creature *Keristrasza = Unit::GetCreature(*pGO, pInstance ? pInstance->GetData64(DATA_KERISTRASZA) : 0);
if (Keristrasza && Keristrasza->isAlive())
{
// maybe these are hacks :(
pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
pGO->SetGoState(GO_STATE_ACTIVE);
CAST_AI(boss_keristraszaAI, Keristrasza->AI())->CheckContainmentSpheres(true);
}
return true;
}
void AddSC_boss_keristrasza()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_keristrasza";
newscript->GetAI = &GetAI_boss_keristrasza;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "containment_sphere";
newscript->pGOHello = &GOHello_containment_sphere;
newscript->RegisterSelf();
}
@@ -0,0 +1,353 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Magus_Telestra
SD%Complete:
SDComment:
SDCategory: The Nexus, The Nexus
EndScriptData */
#include "ScriptedPch.h"
#include "nexus.h"
enum eEnums
{
//Spells
SPELL_ICE_NOVA_N = 47772,
SPELL_ICE_NOVA_H = 56935,
SPELL_FIREBOMB_N = 47773,
SPELL_FIREBOMB_H = 56934,
SPELL_GRAVITY_WELL = 47756,
SPELL_TELESTRA_BACK = 47714,
//At 50% HP - 3 clones, Frost, Fire, Arcane (and in 10% HP in Heroic)
MOB_FIRE_MAGUS = 26928,
MOB_FROST_MAGUS = 26930,
MOB_ARCANE_MAGUS = 26929,
SPELL_FIRE_MAGUS_VISUAL = 47705,
SPELL_FROST_MAGUS_VISUAL = 47706,
SPELL_ARCANE_MAGUS_VISUAL = 47704,
//Yell
SAY_AGGRO = -1576000,
SAY_KILL = -1576001,
SAY_DEATH = -1576002,
SAY_MERGE = -1576003,
SAY_SPLIT_1 = -1576004,
SAY_SPLIT_2 = -1576005,
//Achievement
ACHIEV_SPLIT_PERSONALITY = 2150,
ACHIEV_TIMER = 5 * 1000
};
float CenterOfRoom[1][4] =
{
{504.80, 89.07, -16.12, 6.27}
};
struct TRINITY_DLL_DECL boss_magus_telestraAI : public ScriptedAI
{
boss_magus_telestraAI(Creature* c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint64 FireMagusGUID;
uint64 FrostMagusGUID;
uint64 ArcaneMagusGUID;
bool FireMagusDead;
bool FrostMagusDead;
bool ArcaneMagusDead;
uint32 AppearDelay_Timer;
bool AppearDelay;
uint8 Phase;
uint32 SPELL_ICE_NOVA_Timer;
uint32 SPELL_FIREBOMB_Timer;
uint32 SPELL_GRAVITY_WELL_Timer;
uint32 Cooldown;
bool AchievementTimerRunning;
uint8 AchievementProgress;
uint32 AchievementTimer;
void Reset()
{
Phase = 0;
//These times are probably wrong
SPELL_ICE_NOVA_Timer = 7000;
SPELL_FIREBOMB_Timer = 0;
SPELL_GRAVITY_WELL_Timer = 15000;
Cooldown = 0;
FireMagusGUID = 0;
FrostMagusGUID = 0;
ArcaneMagusGUID = 0;
AchievementProgress = 0;
AchievementTimer = 0;
AchievementTimerRunning = false;
AppearDelay = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetVisibility(VISIBILITY_ON);
if (pInstance)
pInstance->SetData(DATA_MAGUS_TELESTRA_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_MAGUS_TELESTRA_EVENT, IN_PROGRESS);
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (IsHeroic() && AchievementProgress == 2)
{
AchievementEntry const *AchievSplitPersonality = GetAchievementStore()->LookupEntry(ACHIEV_SPLIT_PERSONALITY);
if (AchievSplitPersonality)
{
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievSplitPersonality);
}
}
}
if (pInstance)
pInstance->SetData(DATA_MAGUS_TELESTRA_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
DoScriptText(SAY_KILL, m_creature);
}
uint64 SplitPersonality(uint32 entry)
{
Creature* Summoned = m_creature->SummonCreature(entry, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (Summoned)
{
switch (entry)
{
case MOB_FIRE_MAGUS:
{
Summoned->CastSpell(Summoned, SPELL_FIRE_MAGUS_VISUAL, false);
break;
}
case MOB_FROST_MAGUS:
{
Summoned->CastSpell(Summoned, SPELL_FROST_MAGUS_VISUAL, false);
break;
}
case MOB_ARCANE_MAGUS:
{
Summoned->CastSpell(Summoned, SPELL_ARCANE_MAGUS_VISUAL, false);
break;
}
}
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
Summoned->AI()->AttackStart(pTarget);
return Summoned->GetGUID();
}
return 0;
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
{
return;
}
if (AppearDelay)
{
m_creature->StopMoving();
m_creature->AttackStop();
if (AppearDelay_Timer <= diff)
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
AppearDelay = false;
} else AppearDelay_Timer -= diff;
return;
}
if ((Phase == 1)||(Phase == 3))
{
Unit* FireMagus;
Unit* FrostMagus;
Unit* ArcaneMagus;
if (FireMagusGUID)
FireMagus = Unit::GetUnit((*m_creature), FireMagusGUID);
if (FrostMagusGUID)
FrostMagus = Unit::GetUnit((*m_creature), FrostMagusGUID);
if (ArcaneMagusGUID)
ArcaneMagus = Unit::GetUnit((*m_creature), ArcaneMagusGUID);
if (FireMagus && FireMagus->isDead())
{
FireMagusDead = true;
if (!AchievementTimerRunning)
AchievementTimerRunning = true;
}
if (FrostMagus && FrostMagus->isDead())
{
FrostMagusDead = true;
if (!AchievementTimerRunning)
AchievementTimerRunning = true;
}
if (ArcaneMagus && ArcaneMagus->isDead())
{
ArcaneMagusDead = true;
if (!AchievementTimerRunning)
AchievementTimerRunning = true;
}
if (AchievementTimerRunning)
AchievementTimer += diff;
if (FireMagusDead && FrostMagusDead && ArcaneMagusDead)
{
if (AchievementTimer <= ACHIEV_TIMER)
AchievementProgress +=1;
m_creature->GetMotionMaster()->Clear();
m_creature->GetMap()->CreatureRelocation(m_creature, CenterOfRoom[0][0], CenterOfRoom[0][1], CenterOfRoom[0][2], CenterOfRoom[0][3]);
DoCast(m_creature, SPELL_TELESTRA_BACK);
m_creature->SetVisibility(VISIBILITY_ON);
if (Phase == 1)
Phase = 2;
if (Phase == 3)
Phase = 4;
FireMagusGUID = 0;
FrostMagusGUID = 0;
ArcaneMagusGUID = 0;
AppearDelay = true;
AppearDelay_Timer = 4000;
DoScriptText(SAY_MERGE, m_creature);
AchievementTimerRunning = false;
AchievementTimer = 0;
}else
return;
}
if ((Phase == 0) && (m_creature->GetHealth() <= (m_creature->GetMaxHealth() * 0.5)))
{
Phase = 1;
m_creature->CastStop();
m_creature->RemoveAllAuras();
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
FireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS);
FrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS);
ArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS);
FireMagusDead = false;
FrostMagusDead = false;
ArcaneMagusDead = false;
DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), m_creature);
return;
}
if (IsHeroic() && (Phase == 2) && (m_creature->GetHealth() <= (m_creature->GetMaxHealth() * 0.1)))
{
Phase = 3;
m_creature->CastStop();
m_creature->RemoveAllAuras();
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
FireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS);
FrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS);
ArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS);
FireMagusDead = false;
FrostMagusDead = false;
ArcaneMagusDead = false;
DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), m_creature);
return;
}
if (Cooldown)
{
if (Cooldown <= diff)
Cooldown = 0;
else
{
Cooldown -= diff;
return;
}
}
if (SPELL_ICE_NOVA_Timer <= diff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(pTarget, DUNGEON_MODE(SPELL_ICE_NOVA_N, SPELL_ICE_NOVA_H));
Cooldown = 1500;
}
SPELL_ICE_NOVA_Timer = 15000;
} else SPELL_ICE_NOVA_Timer -=diff;
if (SPELL_GRAVITY_WELL_Timer <= diff)
{
if (Unit *pTarget = m_creature->getVictim())
{
DoCast(pTarget, SPELL_GRAVITY_WELL);
Cooldown = 6000;
}
SPELL_GRAVITY_WELL_Timer = 15000;
} else SPELL_GRAVITY_WELL_Timer -=diff;
if (SPELL_FIREBOMB_Timer <= diff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(pTarget, DUNGEON_MODE(SPELL_FIREBOMB_N, SPELL_FIREBOMB_H));
Cooldown = 2000;
}
SPELL_FIREBOMB_Timer = 2000;
} else SPELL_FIREBOMB_Timer -=diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_magus_telestra(Creature* pCreature)
{
return new boss_magus_telestraAI (pCreature);
}
void AddSC_boss_magus_telestra()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_magus_telestra";
newscript->GetAI = &GetAI_boss_magus_telestra;
newscript->RegisterSelf();
}
@@ -0,0 +1,307 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Ormorok
SD%Complete:
SDComment:
SDCategory: The Nexus, The Nexus
EndScriptData */
#include "ScriptedPch.h"
#include "nexus.h"
enum eEnums
{
//Spells
SPELL_CRYSTAL_SPIKES_N = 47958, //Don't work, using walkaround
SPELL_CRYSTAL_SPIKES_H = 57082, //Don't work, using walkaround
//Walkaround for spells Crystal Spikes -----------------
SPELL_CRYSTALL_SPIKE_DAMAGE_N = 47944,
SPELL_CRYSTALL_SPIKE_DAMAGE_H = 57067,
SPELL_CRYSTAL_SPIKE_PREVISUAL = 50442,
MOB_CRYSTAL_SPIKE = 27099,
//------------------------------------------------------
SPELL_SPELL_REFLECTION = 47981,
SPELL_TRAMPLE_N = 48016,
SPELL_TRAMPLE_H = 57066,
SPELL_FRENZY = 48017,
SPELL_SUMMON_CRYSTALLINE_TANGLER = 61564, //summons npc 32665
MOB_CRYSTALLINE_TANGLER = 32665,
SPELL_ROOTS = 28858, //proper spell id is unknown
//Yell
SAY_AGGRO = -1576020,
SAY_DEATH = -1576021,
SAY_REFLECT = -1576022,
SAY_CRYSTAL_SPIKES = -1576023,
SAY_KILL = -1576024
};
#define SPIKE_DISTANCE 5.0f
struct TRINITY_DLL_DECL boss_ormorokAI : public ScriptedAI
{
boss_ormorokAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
bool Frenzy;
bool CrystalSpikes;
uint8 CrystalSpikes_Count;
float BaseX;
float BaseY;
float BaseZ;
float BaseO;
float SpikeXY[4][2];
uint32 SPELL_CRYSTAL_SPIKES_Timer;
uint32 CRYSTAL_SPIKES_Timer;
uint32 SPELL_TRAMPLE_Timer;
uint32 SPELL_FRENZY_Timer;
uint32 SPELL_SPELL_REFLECTION_Timer;
uint32 SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer;
void Reset()
{
SPELL_CRYSTAL_SPIKES_Timer = 12000;
SPELL_TRAMPLE_Timer = 10000;
SPELL_SPELL_REFLECTION_Timer = 30000;
SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer = 17000;
Frenzy = false;
CrystalSpikes = false;
if (pInstance)
pInstance->SetData(DATA_ORMOROK_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_ORMOROK_EVENT, IN_PROGRESS);
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_ORMOROK_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
DoScriptText(SAY_KILL, m_creature);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
{
return;
}
if (CrystalSpikes)
if (CRYSTAL_SPIKES_Timer <= diff)
{
SpikeXY[0][0] = BaseX+(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO));
SpikeXY[0][1] = BaseY+(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO));
SpikeXY[1][0] = BaseX-(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO));
SpikeXY[1][1] = BaseY-(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO));
SpikeXY[2][0] = BaseX+(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO-(M_PI/2)));
SpikeXY[2][1] = BaseY+(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO-(M_PI/2)));
SpikeXY[3][0] = BaseX-(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO-(M_PI/2)));
SpikeXY[3][1] = BaseY-(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO-(M_PI/2)));
for (uint8 i = 0; i < 4; ++i)
Creature* Spike = m_creature->SummonCreature(MOB_CRYSTAL_SPIKE, SpikeXY[i][0], SpikeXY[i][1], BaseZ, 0, TEMPSUMMON_TIMED_DESPAWN, 7000);
if (++CrystalSpikes_Count >= 13)
CrystalSpikes = false;
CRYSTAL_SPIKES_Timer = 200;
} else CRYSTAL_SPIKES_Timer -= diff;
if (!Frenzy && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.25))
{
DoCast(m_creature, SPELL_FRENZY);
Frenzy = true;
}
if (SPELL_TRAMPLE_Timer <= diff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_TRAMPLE_N, SPELL_TRAMPLE_H));
SPELL_TRAMPLE_Timer = 10000;
} else SPELL_TRAMPLE_Timer -= diff;
if (SPELL_SPELL_REFLECTION_Timer <= diff)
{
DoScriptText(SAY_REFLECT, m_creature);
DoCast(m_creature, SPELL_SPELL_REFLECTION);
SPELL_SPELL_REFLECTION_Timer = 30000;
} else SPELL_SPELL_REFLECTION_Timer -= diff;
if (SPELL_CRYSTAL_SPIKES_Timer <= diff)
{
DoScriptText(SAY_CRYSTAL_SPIKES, m_creature);
CrystalSpikes = true;
CrystalSpikes_Count = 1;
CRYSTAL_SPIKES_Timer = 0;
BaseX = m_creature->GetPositionX();
BaseY = m_creature->GetPositionY();
BaseZ = m_creature->GetPositionZ();
BaseO = m_creature->GetOrientation();
SPELL_CRYSTAL_SPIKES_Timer = 20000;
} else SPELL_CRYSTAL_SPIKES_Timer -=diff;
if (IsHeroic() && (SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer <= diff))
{
Creature* Crystalline_Tangler = m_creature->SummonCreature(MOB_CRYSTALLINE_TANGLER, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (Crystalline_Tangler)
{
Unit *pTarget = NULL;
uint8 Healer = 0;
for (uint8 j = 1; j<=4; j++)
{
switch (j)
{
case 1: Healer = CLASS_PRIEST; break;
case 2: Healer = CLASS_PALADIN; break;
case 3: Healer = CLASS_DRUID; break;
case 4: Healer = CLASS_SHAMAN; break;
}
std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
{
Unit* pTemp = Unit::GetUnit((*m_creature),(*i)->getUnitGuid());
if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && pTemp->getClass() == Healer)
{
pTarget = pTemp;
break;
}
}
if (pTarget)
break;
}
if (!pTarget)
pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (pTarget)
{
Crystalline_Tangler->AI()->AttackStart(pTarget);
Crystalline_Tangler->getThreatManager().addThreat(pTarget, 1000000000.0f);
}
}
SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer = 17000;
} else SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer -=diff;
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL mob_crystal_spikeAI : public Scripted_NoMovementAI
{
mob_crystal_spikeAI(Creature *c) : Scripted_NoMovementAI(c)
{
}
uint32 SPELL_CRYSTALL_SPIKE_DAMAGE_Timer;
uint32 SPELL_CRYSTAL_SPIKE_PREVISUAL_Timer;
void Reset()
{
SPELL_CRYSTALL_SPIKE_DAMAGE_Timer = 3700;
SPELL_CRYSTAL_SPIKE_PREVISUAL_Timer = 1000;
m_creature->SetLevel(80); //
m_creature->setFaction(16); //Walkaround to be independent from data in DB
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); //
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //
}
void UpdateAI(const uint32 diff)
{
if (SPELL_CRYSTAL_SPIKE_PREVISUAL_Timer <= diff)
{
DoCast(m_creature, SPELL_CRYSTAL_SPIKE_PREVISUAL);
SPELL_CRYSTAL_SPIKE_PREVISUAL_Timer = 10000;
} else SPELL_CRYSTAL_SPIKE_PREVISUAL_Timer -=diff;
if (SPELL_CRYSTALL_SPIKE_DAMAGE_Timer <= diff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_CRYSTALL_SPIKE_DAMAGE_N, SPELL_CRYSTALL_SPIKE_DAMAGE_H));
SPELL_CRYSTALL_SPIKE_DAMAGE_Timer = 10000;
} else SPELL_CRYSTALL_SPIKE_DAMAGE_Timer -=diff;
}
};
struct TRINITY_DLL_DECL mob_crystalline_tanglerAI : public ScriptedAI
{
mob_crystalline_tanglerAI(Creature *c) : ScriptedAI(c) {}
uint32 SPELL_ROOTS_Timer;
void Reset()
{
SPELL_ROOTS_Timer = 1000;
}
void UpdateAI(const uint32 diff)
{
if (SPELL_ROOTS_Timer <= diff)
{
if (m_creature->IsWithinDist(m_creature->getVictim(), 5.0f, false))
{
DoCast(m_creature->getVictim(), SPELL_ROOTS);
SPELL_ROOTS_Timer = 15000;
}
} else SPELL_ROOTS_Timer -=diff;
}
};
CreatureAI* GetAI_mob_crystal_spike(Creature* pCreature)
{
return new mob_crystal_spikeAI (pCreature);
}
CreatureAI* GetAI_mob_crystalline_tangler(Creature* pCreature)
{
return new mob_crystalline_tanglerAI (pCreature);
}
CreatureAI* GetAI_boss_ormorok(Creature* pCreature)
{
return new boss_ormorokAI (pCreature);
}
void AddSC_boss_ormorok()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_ormorok";
newscript->GetAI = &GetAI_boss_ormorok;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_crystal_spike";
newscript->GetAI = &GetAI_mob_crystal_spike;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_crystalline_tangler";
newscript->GetAI = &GetAI_mob_crystalline_tangler;
newscript->RegisterSelf();
}
@@ -0,0 +1,58 @@
/* Script Data Start
SDName: Boss Commander Kolurg
SDAuthor: LordVanMartin
SD%Complete:
SDComment: Only Alliance Heroic
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_commander_kolurg' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#define SPELL_BATTLE_SHOUT 31403
#define SPELL_CHARGE 60067
#define SPELL_FRIGHTENING_SHOUT 19134
#define SPELL_WHIRLWIND_1 38619
#define SPELL_WHIRLWIND_2 38618
//not used
//Yell
#define SAY_AGGRO -1576024
#define SAY_KILL -1576025
#define SAY_DEATH -1576026
struct TRINITY_DLL_DECL boss_commander_kolurgAI : public ScriptedAI
{
boss_commander_kolurgAI(Creature *c) : ScriptedAI(c) {}
void Reset() {}
void EnterCombat(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer) {}
};
CreatureAI* GetAI_boss_commander_kolurg(Creature* pCreature)
{
return new boss_commander_kolurgAI (pCreature);
}
void AddSC_boss_commander_kolurg()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_commander_kolurg";
newscript->GetAI = &GetAI_boss_commander_kolurg;
newscript->RegisterSelf();
}
@@ -0,0 +1,64 @@
/* Script Data Start
SDName: Boss Commander Stoutbeard
SDAuthor: LordVanMartin
SD%Complete:
SDComment: Only Horde Heroic
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_commander_stoutbeard' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#define SPELL_BATTLE_SHOUT 31403
#define SPELL_CHARGE 60067
#define SPELL_FRIGHTENING_SHOUT 19134
#define SPELL_WHIRLWIND_1 38619
#define SPELL_WHIRLWIND_2 38618
//not used
//Yell
#define SAY_AGGRO -1576021
#define SAY_KILL -1576022
#define SAY_DEATH -1576023
struct TRINITY_DLL_DECL boss_commander_stoutbeardAI : public ScriptedAI
{
boss_commander_stoutbeardAI(Creature *c) : ScriptedAI(c) {}
void Reset() {}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
}
};
CreatureAI* GetAI_boss_commander_stoutbeard(Creature* pCreature)
{
return new boss_commander_stoutbeardAI (pCreature);
}
void AddSC_boss_commander_stoutbeard()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_commander_stoutbeard";
newscript->GetAI = &GetAI_boss_commander_stoutbeard;
newscript->RegisterSelf();
}
@@ -0,0 +1,254 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance_Nexus
SD%Complete:
SDComment:
SDCategory: The Nexus, The Nexus
EndScriptData */
#include "ScriptedPch.h"
#include "nexus.h"
#define NUMBER_OF_ENCOUNTERS 4
struct TRINITY_DLL_DECL instance_nexus : public ScriptedInstance
{
instance_nexus(Map *pMap) : ScriptedInstance(pMap) { Initialize(); }
uint32 m_auiEncounter[NUMBER_OF_ENCOUNTERS];
uint64 Anomalus;
uint64 Keristrasza;
uint64 AnomalusContainmentSphere;
uint64 OrmoroksContainmentSphere;
uint64 TelestrasContainmentSphere;
std::string strInstData;
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
Anomalus = 0;
}
void OnCreatureCreate(Creature *pCreature, bool bAdd)
{
Map::PlayerList const &players = instance->GetPlayers();
uint32 TeamInInstance = 0;
if (!players.isEmpty())
{
if (Player* pPlayer = players.begin()->getSource())
TeamInInstance = pPlayer->GetTeam();
}
switch (pCreature->GetEntry())
{
case 26763:
Anomalus = pCreature->GetGUID();
break;
case 26723:
Keristrasza = pCreature->GetGUID();
break;
// Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs.
case 26800:
{
pCreature->setFaction(16);
if (TeamInInstance == ALLIANCE)
pCreature->UpdateEntry(26799, HORDE);
break;
}
case 26802:
{
pCreature->setFaction(16);
if (TeamInInstance == ALLIANCE)
pCreature->UpdateEntry(26801, HORDE);
break;
}
case 26805:
{
pCreature->setFaction(16);
if (TeamInInstance == ALLIANCE)
pCreature->UpdateEntry(26803, HORDE);
break;
}
case 27949:
{
pCreature->setFaction(16);
if (TeamInInstance == ALLIANCE)
pCreature->UpdateEntry(27947, HORDE);
break;
}
case 26796:
{
pCreature->setFaction(16);
if (TeamInInstance == ALLIANCE)
pCreature->UpdateEntry(26798, HORDE);
break;
}
}
}
void OnGameObjectCreate(GameObject *pGo, bool bAdd)
{
switch (pGo->GetEntry())
{
case 188527:
{
AnomalusContainmentSphere = pGo->GetGUID();
if (m_auiEncounter[1] == DONE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
break;
}
case 188528:
{
OrmoroksContainmentSphere = pGo->GetGUID();
if (m_auiEncounter[2] == DONE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
break;
}
case 188526:
{
TelestrasContainmentSphere = pGo->GetGUID();
if (m_auiEncounter[0] == DONE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
break;
}
}
}
uint32 GetData(uint32 identifier)
{
switch(identifier)
{
case DATA_MAGUS_TELESTRA_EVENT: return m_auiEncounter[0];
case DATA_ANOMALUS_EVENT: return m_auiEncounter[1];
case DATA_ORMOROK_EVENT: return m_auiEncounter[2];
case DATA_KERISTRASZA_EVENT: return m_auiEncounter[3];
}
return 0;
}
void SetData(uint32 identifier, uint32 data)
{
switch (identifier)
{
case DATA_MAGUS_TELESTRA_EVENT:
{
if (data == DONE)
{
GameObject *Sphere = instance->GetGameObject(TelestrasContainmentSphere);
if (Sphere)
Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
}
m_auiEncounter[0] = data;
break;
}
case DATA_ANOMALUS_EVENT:
{
if (data == DONE)
{
if (GameObject *Sphere = instance->GetGameObject(AnomalusContainmentSphere))
Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
}
m_auiEncounter[1] = data;
break;
}
case DATA_ORMOROK_EVENT:
{
if (data == DONE)
{
if (GameObject *Sphere = instance->GetGameObject(OrmoroksContainmentSphere))
Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
}
m_auiEncounter[2] = data;
break;
}
case DATA_KERISTRASZA_EVENT:
m_auiEncounter[3] = data;
break;
}
if (data == DONE)
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
<< m_auiEncounter[3];
strInstData = saveStream.str();
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE;
}
}
uint64 GetData64(uint32 uiIdentifier)
{
switch(uiIdentifier)
{
case DATA_ANOMALUS: return Anomalus;
case DATA_KERISTRASZA: return Keristrasza;
case ANOMALUS_CONTAINMET_SPHERE: return AnomalusContainmentSphere;
case ORMOROKS_CONTAINMET_SPHERE: return OrmoroksContainmentSphere;
case TELESTRAS_CONTAINMET_SPHERE: return TelestrasContainmentSphere;
}
return 0;
}
std::string GetSaveData()
{
return strInstData;
}
void Load(const char *chrIn)
{
if (!chrIn)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(chrIn);
std::istringstream loadStream(chrIn);
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3];
for (uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData *GetInstanceData_instance_nexus(Map *pMap)
{
return new instance_nexus(pMap);
}
void AddSC_instance_nexus()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_nexus";
newscript->GetInstanceData = &GetInstanceData_instance_nexus;
newscript->RegisterSelf();
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef DEF_NEXUS_H
#define DEF_NEXUS_H
enum eTypes
{
DATA_MAGUS_TELESTRA_EVENT,
DATA_ANOMALUS_EVENT,
DATA_ORMOROK_EVENT,
DATA_KERISTRASZA_EVENT,
DATA_ANOMALUS,
DATA_KERISTRASZA,
ANOMALUS_CONTAINMET_SPHERE,
ORMOROKS_CONTAINMET_SPHERE,
TELESTRAS_CONTAINMET_SPHERE
};
#endif
@@ -0,0 +1,98 @@
/* Script Data Start
SDName: Boss drakos
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = '' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "oculus.h"
enum Spells
{
SPELL_MAGIC_PULL = 51336,
SPELL_THUNDERING_STOMP = 50774,
SPELL_THUNDERING_STOMP_2 = 59370
};
//not in db
enum Yells
{
SAY_AGGRO = -1578000,
SAY_KILL_1 = -1578001,
SAY_KILL_2 = -1578002,
SAY_KILL_3 = -1578003,
SAY_DEATH = -1578004,
SAY_PULL_1 = -1578005,
SAY_PULL_2 = -1578006,
SAY_PULL_3 = -1578007,
SAY_PULL_4 = -1578008,
SAY_STOMP_1 = -1578009,
SAY_STOMP_2 = -1578010,
SAY_STOMP_3 = -1578011
};
struct TRINITY_DLL_DECL boss_drakosAI : public ScriptedAI
{
boss_drakosAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
void Reset()
{
if (pInstance)
pInstance->SetData(DATA_DRAKOS_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_DRAKOS_EVENT, IN_PROGRESS);
}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_DRAKOS_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2,SAY_KILL_3), m_creature);
}
};
CreatureAI* GetAI_boss_drakos(Creature* pCreature)
{
return new boss_drakosAI (pCreature);
}
void AddSC_boss_drakos()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_drakos";
newscript->GetAI = &GetAI_boss_drakos;
newscript->RegisterSelf();
}
@@ -0,0 +1,125 @@
/* Script Data Start
SDName: Boss eregos
SDAuthor: LordVanMartin
SD%Complete:
SDComment: Encounter is done entirely on drake vehicles
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = '' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "oculus.h"
//Types of drake mounts: Ruby(Tank), Amber(DPS), Emerald(Healer)
//Two Repeating phases
enum Spells
{
SPELL_ARCANE_BARRAGE = 50804,
SPELL_ARCANE_VOLLEY = 51153,
SPELL_ENRAGED_ASSAULT = 51170,
SPELL_PLANAR_ANOMALIES = 57959,
SPELL_PLANAR_SHIFT = 51162,
//Heroic
H_SPELL_ARCANE_BARRAGE = 59381,
H_SPELL_ARCANE_VOLLEY = 59382
};
/*Ruby Drake ,
(npc 27756) (item 37860)
(summoned by spell Ruby Essence = 37860 ---> Call Amber Drake == 49462 ---> Summon 27756)
*/
enum RubyDrake
{
NPC_RUBY_DRAKE_VEHICLE = 27756,
SPELL_RIDE_RUBY_DRAKE_QUE = 49463, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49464
SPELL_RUBY_DRAKE_SADDLE = 49464, //Allows you to ride on the back of an Amber Drake. ---> Dummy
SPELL_RUBY_SEARING_WRATH = 50232, //(60 yds) - Instant - Breathes a stream of fire at an enemy dragon, dealing 6800 to 9200 Fire damage and then jumping to additional dragons within 30 yards. Each jump increases the damage by 50%. Affects up to 5 total targets
SPELL_RUBY_EVASIVE_AURA = 50248, //Instant - Allows the Ruby Drake to generate Evasive Charges when hit by hostile attacks and spells.
SPELL_RUBY_EVASIVE_MANEUVERS = 50240, //Instant - 5 sec. cooldown - Allows your drake to dodge all incoming attacks and spells. Requires Evasive Charges to use. Each attack or spell dodged while this ability is active burns one Evasive Charge. Lasts 30 sec. or until all charges are exhausted.
//you do not have acces to until you kill Mage-Lord Urom
SPELL_RUBY_MARTYR = 50253 //Instant - 10 sec. cooldown - Redirect all harmful spells cast at friendly drakes to yourself for 10 sec.
};
/*Amber Drake,
(npc 27755) (item 37859)
(summoned by spell Amber Essence = 37859 ---> Call Amber Drake == 49461 ---> Summon 27755)
*/
enum AmberDrake
{
NPC_AMBER_DRAKE_VEHICLE = 27755,
SPELL_RIDE_AMBER_DRAKE_QUE = 49459, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49460
SPELL_AMBER_DRAKE_SADDLE = 49460, //Allows you to ride on the back of an Amber Drake. ---> Dummy
SPELL_AMBER_SHOCK_LANCE = 49840, //(60 yds) - Instant - Deals 4822 to 5602 Arcane damage and detonates all Shock Charges on an enemy dragon. Damage is increased by 6525 for each detonated.
// SPELL_AMBER_STOP_TIME //Instant - 1 min cooldown - Halts the passage of time, freezing all enemy dragons in place for 10 sec. This attack applies 5 Shock Charges to each affected target.
//you do not have access to until you kill the Mage-Lord Urom.
SPELL_AMBER_TEMPORAL_RIFT = 49592 //(60 yds) - Channeled - Channels a temporal rift on an enemy dragon for 10 sec. While trapped in the rift, all damage done to the target is increased by 100%. In addition, for every 15,000 damage done to a target affected by Temporal Rift, 1 Shock Charge is generated.
};
/*Emerald Drake,
(npc 27692) (item 37815),
(summoned by spell Emerald Essence = 37815 ---> Call Emerald Drake == 49345 ---> Summon 27692)
*/
enum EmeraldDrake
{
NPC_EMERALD_DRAKE_VEHICLE = 27692,
SPELL_RIDE_EMERALD_DRAKE_QUE = 49427, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49346
SPELL_EMERALD_DRAKE_SADDLE = 49346, //Allows you to ride on the back of an Amber Drake. ---> Dummy
SPELL_EMERALD_LEECHING_POISON = 50328, //(60 yds) - Instant - Poisons the enemy dragon, leeching 1300 to the caster every 2 sec. for 12 sec. Stacks up to 3 times.
SPELL_EMERALD_TOUCH_THE_NIGHTMARE = 50341, //(60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25,000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
// you do not have access to until you kill the Mage-Lord Urom
SPELL_EMERALD_DREAM_FUNNEL = 50344 //(60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
};
struct TRINITY_DLL_DECL boss_eregosAI : public ScriptedAI
{
boss_eregosAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
void Reset()
{
if (pInstance)
pInstance->SetData(DATA_EREGOS_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
if (pInstance)
pInstance->SetData(DATA_EREGOS_EVENT, IN_PROGRESS);
}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
if (pInstance)
pInstance->SetData(DATA_EREGOS_EVENT, DONE);
}
};
CreatureAI* GetAI_boss_eregos(Creature* pCreature)
{
return new boss_eregosAI (pCreature);
}
void AddSC_boss_eregos()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_eregos";
newscript->GetAI = &GetAI_boss_eregos;
newscript->RegisterSelf();
}
@@ -0,0 +1,103 @@
/* Script Data Start
SDName: Boss urom
SDAuthor: LordVanMartin
SD%Complete: 1%
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = '' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "oculus.h"
enum Spells
{
SPELL_ARCANE_SHIELD = 53813, //Dummy --> Channeled, shields the caster from damage.
SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110,
SPELL_EMPOWERED_ARCANE_EXPLOSION_2 = 59377,
SPELL_FROSTBOMB = 51103, //Urom throws a bomb, hitting its target with the highest aggro which inflict directly 650 frost damage and drops a frost zone on the ground. This zone deals 650 frost damage per second and reduce the movement speed by 35%. Lasts 1 minute.
SPELL_SUMMON_MENAGERIE = 50476, //Summons an assortment of creatures and teleports the caster to safety.
SPELL_SUMMON_MENAGERIE_2 = 50495,
SPELL_SUMMON_MENAGERIE_3 = 50496,
SPELL_TELEPORT = 51112, //Teleports to the center of Oculus
SPELL_TIME_BOMB = 51121, //Deals arcane damage to a random player, and after 6 seconds, deals zone damage to nearby equal to the health missing of the target afflicted by the debuff.
SPELL_TIME_BOMB_2 = 59376
};
//not in db
enum Yells
{
SAY_AGGRO = -1578012,
SAY_KILL_1 = -1578013,
SAY_KILL_2 = -1578014,
SAY_KILL_3 = -1578015,
SAY_DEATH = -1578016,
SAY_EXPLOSION_1 = -1578017,
SAY_EXPLOSION_2 = -1578018,
SAY_SUMMON_1 = -1578019,
SAY_SUMMON_2 = -1578020,
SAY_SUMMON_3 = -1578021
};
struct TRINITY_DLL_DECL boss_uromAI : public ScriptedAI
{
boss_uromAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
void Reset()
{
if (pInstance)
pInstance->SetData(DATA_UROM_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_UROM_EVENT, IN_PROGRESS);
}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_UROM_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2,SAY_KILL_3), m_creature);
}
};
CreatureAI* GetAI_boss_urom(Creature* pCreature)
{
return new boss_uromAI (pCreature);
}
void AddSC_boss_urom()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_urom";
newscript->GetAI = &GetAI_boss_urom;
newscript->RegisterSelf();
}
@@ -0,0 +1,100 @@
/* Script Data Start
SDName: Boss varos
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = '' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "oculus.h"
enum Spells
{
SPELL_ENERGIZE_CORES = 50785, //Damage 5938 to 6562, effec2 Triggers 54069, effect3 Triggers 56251
SPELL_ENERGIZE_CORES_TRIGGER_1 = 54069,
SPELL_ENERGIZE_CORES_TRIGGER_2 = 56251,
SPELL_ENERGIZE_CORES_2 = 59372, //Damage 9025 to 9975, effect2 Triggers 54069, effect 56251
SPELL_CALL_AZURE_RING_CAPTAIN = 51002, //Effect Send Event (12229)
SPELL_CALL_AZURE_RING_CAPTAIN_2 = 51006, //Effect Send Event (10665)
SPELL_CALL_AZURE_RING_CAPTAIN_3 = 51007, //Effect Send Event (18454)
SPELL_CALL_AZURE_RING_CAPTAIN_4 = 51008, //Effect Send Event (18455)
SPELL_CALL_AMPLIFY_MAGIC = 51054,
SPELL_CALL_AMPLIFY_MAGIC_2 = 59371
};
//not in db
enum Yells
{
SAY_AGGRO = -1578022,
SAY_KILL_1 = -1578023,
SAY_KILL_2 = -1578024,
SAY_DEATH = -1578025,
SAY_STRIKE_1 = -1578026,
SAY_STRIKE_2 = -1578027,
SAY_STRIKE_3 = -1578028,
SAY_SPAWN = -1578029
};
struct TRINITY_DLL_DECL boss_varosAI : public ScriptedAI
{
boss_varosAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
void Reset()
{
if (pInstance)
pInstance->SetData(DATA_VAROS_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_VAROS_EVENT, IN_PROGRESS);
}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_VAROS_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2), m_creature);
}
};
CreatureAI* GetAI_boss_varos(Creature* pCreature)
{
return new boss_varosAI (pCreature);
}
void AddSC_boss_varos()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_varos";
newscript->GetAI = &GetAI_boss_varos;
newscript->RegisterSelf();
}
@@ -0,0 +1,150 @@
#include "ScriptedPch.h"
#include "oculus.h"
#define MAX_ENCOUNTER 4
/* The Occulus encounters:
0 - Drakos the Interrogator
1 - Varos Cloudstrider
2 - Mage-Lord Urom
3 - Ley-Guardian Eregos */
struct TRINITY_DLL_DECL instance_oculus : public ScriptedInstance
{
instance_oculus(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
uint64 uiDrakos;
uint64 uiVaros;
uint64 uiUrom;
uint64 uiEregos;
uint8 m_auiEncounter[MAX_ENCOUNTER];
std::string str_data;
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case CREATURE_DRAKOS:
uiDrakos = pCreature->GetGUID();
break;
case CREATURE_VAROS:
uiVaros = pCreature->GetGUID();
break;
case CREATURE_UROM:
uiUrom = pCreature->GetGUID();
break;
case CREATURE_EREGOS:
uiEregos = pCreature->GetGUID();
break;
}
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_DRAKOS_EVENT:
m_auiEncounter[0] = data;
break;
case DATA_VAROS_EVENT:
m_auiEncounter[1] = data;
break;
case DATA_UROM_EVENT:
m_auiEncounter[2] = data;
break;
case DATA_EREGOS_EVENT:
m_auiEncounter[3] = data;
break;
}
if (data == DONE)
SaveToDB();
}
uint32 GetData(uint32 type)
{
switch(type)
{
case DATA_DRAKOS_EVENT: return m_auiEncounter[0];
case DATA_VAROS_EVENT: return m_auiEncounter[1];
case DATA_UROM_EVENT: return m_auiEncounter[2];
case DATA_EREGOS_EVENT: return m_auiEncounter[3];
}
return 0;
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_DRAKOS: return uiDrakos;
case DATA_VAROS: return uiVaros;
case DATA_UROM: return uiUrom;
case DATA_EREGOS: return uiEregos;
}
return 0;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "T O " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in)
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
if (dataHead1 == 'T' && dataHead2 == 'O')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
m_auiEncounter[3] = data3;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_oculus(Map* pMap)
{
return new instance_oculus(pMap);
}
void AddSC_instance_oculus()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_oculus";
newscript->GetInstanceData = &GetInstanceData_instance_oculus;
newscript->RegisterSelf();
}
@@ -0,0 +1,28 @@
#ifndef DEF_OCULUS_H
#define DEF_OCULUS_H
enum Data
{
DATA_DRAKOS_EVENT,
DATA_VAROS_EVENT,
DATA_UROM_EVENT,
DATA_EREGOS_EVENT
};
enum Data64
{
DATA_DRAKOS,
DATA_VAROS,
DATA_UROM,
DATA_EREGOS
};
enum Bosses
{
CREATURE_DRAKOS = 27654,
CREATURE_VAROS = 27447,
CREATURE_UROM = 27655,
CREATURE_EREGOS = 27656
};
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,97 @@
#include "ScriptedPch.h"
#include "obsidian_sanctum.h"
#define MAX_ENCOUNTER 1
/* Obsidian Sanctum encounters:
0 - Sartharion
*/
struct TRINITY_DLL_DECL instance_obsidian_sanctum : public ScriptedInstance
{
instance_obsidian_sanctum(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
uint32 m_auiEncounter[MAX_ENCOUNTER];
uint64 m_uiSartharionGUID;
uint64 m_uiTenebronGUID;
uint64 m_uiShadronGUID;
uint64 m_uiVesperonGUID;
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
m_uiSartharionGUID = 0;
m_uiTenebronGUID = 0;
m_uiShadronGUID = 0;
m_uiVesperonGUID = 0;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case NPC_SARTHARION:
m_uiSartharionGUID = pCreature->GetGUID();
break;
//three dragons below set to active state once created.
//we must expect bigger raid to encounter main boss, and then three dragons must be active due to grid differences
case NPC_TENEBRON:
m_uiTenebronGUID = pCreature->GetGUID();
pCreature->setActive(true);
break;
case NPC_SHADRON:
m_uiShadronGUID = pCreature->GetGUID();
pCreature->setActive(true);
break;
case NPC_VESPERON:
m_uiVesperonGUID = pCreature->GetGUID();
pCreature->setActive(true);
break;
}
}
void SetData(uint32 uiType, uint32 uiData)
{
if (uiType == TYPE_SARTHARION_EVENT)
m_auiEncounter[0] = uiData;
}
uint32 GetData(uint32 uiType)
{
if (uiType == TYPE_SARTHARION_EVENT)
return m_auiEncounter[0];
return 0;
}
uint64 GetData64(uint32 uiData)
{
switch(uiData)
{
case DATA_SARTHARION:
return m_uiSartharionGUID;
case DATA_TENEBRON:
return m_uiTenebronGUID;
case DATA_SHADRON:
return m_uiShadronGUID;
case DATA_VESPERON:
return m_uiVesperonGUID;
}
return 0;
}
};
InstanceData* GetInstanceData_instance_obsidian_sanctum(Map* pMap)
{
return new instance_obsidian_sanctum(pMap);
}
void AddSC_instance_obsidian_sanctum()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_obsidian_sanctum";
newscript->GetInstanceData = &GetInstanceData_instance_obsidian_sanctum;
newscript->RegisterSelf();
}
@@ -0,0 +1,20 @@
#ifndef DEF_OBSIDIAN_SANCTUM_H
#define DEF_OBSIDIAN_SANCTUM_H
enum eTypes
{
TYPE_SARTHARION_EVENT = 1,
DATA_SARTHARION = 10,
DATA_TENEBRON = 11,
DATA_SHADRON = 12,
DATA_VESPERON = 13,
NPC_SARTHARION = 28860,
NPC_TENEBRON = 30452,
NPC_SHADRON = 30451,
NPC_VESPERON = 30449,
GO_TWILIGHT_PORTAL = 193988
};
#endif
+328
View File
@@ -0,0 +1,328 @@
/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Sholazar_Basin
SD%Complete: 100
SDComment: Quest support: 12570, 12573, 12621.
SDCategory: Sholazar_Basin
EndScriptData */
/* ContentData
npc_injured_rainspeaker_oracle
npc_vekjik
avatar_of_freya
EndContentData */
#include "ScriptedPch.h"
#include "ScriptedEscortAI.h"
/*######
## npc_injured_rainspeaker_oracle
######*/
#define GOSSIP_ITEM1 "I am ready to travel to your village now."
enum eRainspeaker
{
SAY_START_IRO = -1571000,
SAY_QUEST_ACCEPT_IRO = -1571001,
SAY_END_IRO = -1571002,
QUEST_FORTUNATE_MISUNDERSTANDINGS = 12570,
FACTION_ESCORTEE_A = 774,
FACTION_ESCORTEE_H = 775
};
struct TRINITY_DLL_DECL npc_injured_rainspeaker_oracleAI : public npc_escortAI
{
npc_injured_rainspeaker_oracleAI(Creature* c) : npc_escortAI(c) { c_guid = c->GetGUID(); }
uint64 c_guid;
void Reset()
{
me->RestoreFaction();
// if we will have other way to assign this to only one npc remove this part
if (GUID_LOPART(me->GetGUID()) != 101030)
{
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
}
void WaypointReached(uint32 i)
{
Player* pPlayer = GetPlayerForEscort();
if (!pPlayer)
return;
switch(i)
{
case 1: SetRun(); break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_JUMPING);
m_creature->SetSpeed(MOVE_SWIM, 0.85f, true);
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_LEVITATING);
break;
case 19:
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
break;
case 28:
if (Player* pPlayer = GetPlayerForEscort())
pPlayer->GroupEventHappens(QUEST_FORTUNATE_MISUNDERSTANDINGS, m_creature);
// me->RestoreFaction();
DoScriptText(SAY_END_IRO,m_creature);
SetRun(false);
break;
}
}
void JustDied(Unit* killer)
{
if (!HasEscortState(STATE_ESCORT_ESCORTING))
return;
if (Player* pPlayer = GetPlayerForEscort())
{
if (pPlayer->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) != QUEST_STATUS_COMPLETE)
pPlayer->FailQuest(QUEST_FORTUNATE_MISUNDERSTANDINGS);
}
}
};
bool GossipHello_npc_injured_rainspeaker_oracle(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) == QUEST_STATUS_INCOMPLETE)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_injured_rainspeaker_oracle(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
CAST_AI(npc_escortAI, (pCreature->AI()))->SetMaxPlayerDistance(35.0f);
pCreature->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
DoScriptText(SAY_START_IRO, pCreature);
switch (pPlayer->GetTeam()){
case ALLIANCE:
pCreature->setFaction(FACTION_ESCORTEE_A);
break;
case HORDE:
pCreature->setFaction(FACTION_ESCORTEE_H);
break;
}
}
return true;
}
bool QuestAccept_npc_injured_rainspeaker_oracle(Player* pPlayer, Creature* pCreature, Quest const *_Quest)
{
DoScriptText(SAY_QUEST_ACCEPT_IRO, pCreature);
return false;
}
CreatureAI* GetAI_npc_injured_rainspeaker_oracle(Creature* pCreature)
{
return new npc_injured_rainspeaker_oracleAI(pCreature);
}
/*######
## npc_vekjik
######*/
#define GOSSIP_VEKJIK_ITEM1 "Shaman Vekjik, I have spoken with the big-tongues and they desire peace. I have brought this offering on their behalf."
#define GOSSIP_VEKJIK_ITEM2 "No no... I had no intentions of betraying your people. I was only defending myself. it was all a misunderstanding."
enum eVekjik
{
GOSSIP_TEXTID_VEKJIK1 = 13137,
GOSSIP_TEXTID_VEKJIK2 = 13138,
SAY_TEXTID_VEKJIK1 = -1000208,
SPELL_FREANZYHEARTS_FURY = 51469,
QUEST_MAKING_PEACE = 12573
};
bool GossipHello_npc_vekjik(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_MAKING_PEACE) == QUEST_STATUS_INCOMPLETE)
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK1, pCreature->GetGUID());
return true;
}
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_vekjik(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK2, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->CLOSE_GOSSIP_MENU();
DoScriptText(SAY_TEXTID_VEKJIK1, pCreature, pPlayer);
pPlayer->AreaExploredOrEventHappens(QUEST_MAKING_PEACE);
pCreature->CastSpell(pPlayer, SPELL_FREANZYHEARTS_FURY, false);
break;
}
return true;
}
/*######
## avatar_of_freya
######*/
#define GOSSIP_ITEM_AOF1 "I want to stop the Scourge as much as you do. How can I help?"
#define GOSSIP_ITEM_AOF2 "You can trust me. I am no friend of the Lich King."
#define GOSSIP_ITEM_AOF3 "I will not fail."
enum eFreya
{
QUEST_FREYA_PACT = 12621,
SPELL_FREYA_CONVERSATION = 52045,
GOSSIP_TEXTID_AVATAR1 = 13303,
GOSSIP_TEXTID_AVATAR2 = 13304,
GOSSIP_TEXTID_AVATAR3 = 13305
};
bool GossipHello_npc_avatar_of_freya(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_FREYA_PACT) == QUEST_STATUS_INCOMPLETE)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR1, pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_avatar_of_freya(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR2, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR3, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->CastSpell(pPlayer, SPELL_FREYA_CONVERSATION, true);
pPlayer->CLOSE_GOSSIP_MENU();
break;
}
return true;
}
/*######
## npc_geezle
######*/
struct TRINITY_DLL_DECL npc_bushwhackerAI : public ScriptedAI
{
npc_bushwhackerAI(Creature* pCreature) : ScriptedAI(pCreature)
{
MoveToSummoner();
}
void MoveToSummoner()
{
if (m_creature->isSummon())
if (Unit* pSummoner = CAST_SUM(m_creature)->GetSummoner())
if (pSummoner)
m_creature->GetMotionMaster()->MovePoint(0,pSummoner->GetPositionX(),pSummoner->GetPositionY(),pSummoner->GetPositionZ());
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_npc_bushwhacker(Creature* pCreature)
{
return new npc_bushwhackerAI(pCreature);
}
void AddSC_sholazar_basin()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_injured_rainspeaker_oracle";
newscript->GetAI = &GetAI_npc_injured_rainspeaker_oracle;
newscript->pGossipHello = &GossipHello_npc_injured_rainspeaker_oracle;
newscript->pGossipSelect = &GossipSelect_npc_injured_rainspeaker_oracle;
newscript->pQuestAccept = &QuestAccept_npc_injured_rainspeaker_oracle;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_vekjik";
newscript->pGossipHello = &GossipHello_npc_vekjik;
newscript->pGossipSelect = &GossipSelect_npc_vekjik;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_avatar_of_freya";
newscript->pGossipHello = &GossipHello_npc_avatar_of_freya;
newscript->pGossipSelect = &GossipSelect_npc_avatar_of_freya;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_bushwhacker";
newscript->GetAI = &GetAI_npc_bushwhacker;
newscript->RegisterSelf();
}
+389
View File
@@ -0,0 +1,389 @@
/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
/*######
## npc_agnetta_tyrsdottar
######*/
#define SAY_AGGRO -1571003
#define GOSSIP_AGNETTA "Skip the warmup, sister... or are you too scared to face soemeone your own size?"
enum eAgnetta
{
QUEST_ITS_THAT_YOUR_GOBLIN = 12969,
FACTION_HOSTILE_AT1 = 45
};
struct TRINITY_DLL_DECL npc_agnetta_tyrsdottarAI : public ScriptedAI
{
npc_agnetta_tyrsdottarAI(Creature* pCreature) : ScriptedAI(pCreature) { }
void Reset()
{
me->RestoreFaction();
}
};
CreatureAI* GetAI_npc_agnetta_tyrsdottar(Creature* pCreature)
{
return new npc_agnetta_tyrsdottarAI(pCreature);
}
bool GossipHello_npc_agnetta_tyrsdottar(Player* pPlayer, Creature* pCreature)
{
if (pPlayer->GetQuestStatus(QUEST_ITS_THAT_YOUR_GOBLIN) == QUEST_STATUS_INCOMPLETE)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_AGNETTA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(13691, pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_agnetta_tyrsdottar(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction )
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
DoScriptText(SAY_AGGRO, pCreature);
pPlayer->CLOSE_GOSSIP_MENU();
pCreature->setFaction(FACTION_HOSTILE_AT1);
pCreature->AI()->AttackStart(pPlayer);
}
return true;
}
/*######
## npc_frostborn_scout
######*/
#define GOSSIP_ITEM1 "Are you okay? I've come to take you back to Frosthold if you can stand."
#define GOSSIP_ITEM2 "I'm sorry that I didn't get here sooner. What happened?"
#define GOSSIP_ITEM3 "I'll go get some help. Hang in there."
enum eFrostbornScout
{
QUEST_MISSING_SCOUTS = 12864
};
bool GossipHello_npc_frostborn_scout(Player* pPlayer, Creature* pCreature)
{
if (pPlayer->GetQuestStatus(QUEST_MISSING_SCOUTS) == QUEST_STATUS_INCOMPLETE)
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->PlayerTalkClass->SendGossipMenu(13611, pCreature->GetGUID());
}
return true;
}
bool GossipSelect_npc_frostborn_scout(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->PlayerTalkClass->SendGossipMenu(13612, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
pPlayer->PlayerTalkClass->SendGossipMenu(13613, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->PlayerTalkClass->SendGossipMenu(13614, pCreature->GetGUID());
pPlayer->AreaExploredOrEventHappens(QUEST_MISSING_SCOUTS);
break;
}
return true;
}
/*######
## npc_thorim
######*/
#define GOSSIP_HN "Thorim?"
#define GOSSIP_SN1 "Can you tell me what became of Sif?"
#define GOSSIP_SN2 "He did more than that, Thorim. He controls Ulduar now."
#define GOSSIP_SN3 "It needn't end this way."
enum eThorim
{
QUEST_SIBLING_RIVALRY = 13064,
NPC_THORIM = 29445,
GOSSIP_TEXTID_THORIM1 = 13799,
GOSSIP_TEXTID_THORIM2 = 13801,
GOSSIP_TEXTID_THORIM3 = 13802,
GOSSIP_TEXTID_THORIM4 = 13803
};
bool GossipHello_npc_thorim(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_SIBLING_RIVALRY) == QUEST_STATUS_INCOMPLETE) {
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_HN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM1, pCreature->GetGUID());
return true;
}
return false;
}
bool GossipSelect_npc_thorim(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM2, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM3, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM4, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->AreaExploredOrEventHappens(QUEST_SIBLING_RIVALRY);
break;
}
return true;
}
/*######
## npc_goblin_prisoner
######*/
enum eGoblinPrisoner
{
GO_RUSTY_CAGE = 191544
};
struct TRINITY_DLL_DECL npc_goblin_prisonerAI : public ScriptedAI
{
npc_goblin_prisonerAI(Creature* pCreature) : ScriptedAI (pCreature){}
void Reset()
{
m_creature->SetReactState(REACT_PASSIVE);
if(GameObject* pGO = m_creature->FindNearestGameObject(GO_RUSTY_CAGE,5.0f))
{
if(pGO->GetGoState() == GO_STATE_ACTIVE)
pGO->SetGoState(GO_STATE_READY);
}
}
};
CreatureAI* GetAI_npc_goblin_prisoner(Creature* pCreature)
{
return new npc_goblin_prisonerAI(pCreature);
}
/*######
## npc_victorious_challenger
######*/
#define GOSSIP_CHALLENGER "Let's do this, sister."
enum eVictoriousChallenger
{
QUEST_TAKING_ALL_CHALLENGERS = 12971,
QUEST_DEFENDING_YOUR_TITLE = 13423,
SPELL_SUNDER_ARMOR = 11971,
SPELL_REND_VC = 11977
};
struct TRINITY_DLL_DECL npc_victorious_challengerAI : public ScriptedAI
{
npc_victorious_challengerAI(Creature* pCreature) : ScriptedAI(pCreature) {}
uint32 SunderArmorTimer;
uint32 RendTimer;
void Reset()
{
m_creature->RestoreFaction();
SunderArmorTimer = 10000;
RendTimer = 15000;
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if(RendTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_REND_VC, true);
RendTimer = 15000;
}else RendTimer -= diff;
if(SunderArmorTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_SUNDER_ARMOR, true);
SunderArmorTimer = 10000;
}else SunderArmorTimer -= diff;
DoMeleeAttackIfReady();
}
void KilledUnit(Unit* victim)
{
m_creature->RestoreFaction();
}
};
bool GossipHello_npc_victorious_challenger(Player* pPlayer, Creature* pCreature)
{
if(pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_TAKING_ALL_CHALLENGERS) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(QUEST_DEFENDING_YOUR_TITLE) == QUEST_STATUS_INCOMPLETE)
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CHALLENGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
return false;
}
bool GossipSelect_npc_victorious_challenger(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction )
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
pPlayer->CLOSE_GOSSIP_MENU();
pCreature->setFaction(14);
pCreature->AI()->AttackStart(pPlayer);
}
return true;
}
CreatureAI* GetAI_npc_victorious_challenger(Creature* pCreature)
{
return new npc_victorious_challengerAI(pCreature);
}
/*######
## npc_loklira_crone
######*/
#define GOSSIP_LOKLIRACRONE "Tell me about this proposal"
#define GOSSIP_LOKLIRACRONE1 "What happened then?"
#define GOSSIP_LOKLIRACRONE2 "You want me to take part in the Hyldsmeet to end the war?"
#define GOSSIP_LOKLIRACRONE3 "Very well. I'll take part in this competition."
enum eLokliraCrone
{
QUEST_HYLDSMEET = 12970,
GOSSIP_TEXTID_LOK1 = 13778,
GOSSIP_TEXTID_LOK2 = 13779,
GOSSIP_TEXTID_LOK3 = 13780
};
bool GossipHello_npc_loklira_crone(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(QUEST_HYLDSMEET) == QUEST_STATUS_INCOMPLETE)
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
return false;
}
bool GossipSelect_npc_loklira_crone(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK1, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK2, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK3, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->CompleteQuest(QUEST_HYLDSMEET);
break;
}
return true;
}
void AddSC_storm_peaks()
{
Script* newscript;
newscript = new Script;
newscript->Name = "npc_agnetta_tyrsdottar";
newscript->GetAI = &GetAI_npc_agnetta_tyrsdottar;
newscript->pGossipHello = &GossipHello_npc_agnetta_tyrsdottar;
newscript->pGossipSelect = &GossipSelect_npc_agnetta_tyrsdottar;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_frostborn_scout";
newscript->pGossipHello = &GossipHello_npc_frostborn_scout;
newscript->pGossipSelect = &GossipSelect_npc_frostborn_scout;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_thorim";
newscript->pGossipHello = &GossipHello_npc_thorim;
newscript->pGossipSelect = &GossipSelect_npc_thorim;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_goblin_prisoner";
newscript->GetAI = &GetAI_npc_goblin_prisoner;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_victorious_challenger";
newscript->GetAI = &GetAI_npc_victorious_challenger;
newscript->pGossipHello = &GossipHello_npc_victorious_challenger;
newscript->pGossipSelect = &GossipSelect_npc_victorious_challenger;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_loklira_crone";
newscript->pGossipHello = &GossipHello_npc_loklira_crone;
newscript->pGossipSelect = &GossipSelect_npc_loklira_crone;
newscript->RegisterSelf();
}
@@ -0,0 +1,432 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss General Bjarngrim
SD%Complete: 70%
SDComment: Waypoint needed, we expect boss to always have 2x Stormforged Lieutenant following
SDCategory: Halls of Lightning
EndScriptData */
#include "ScriptedPch.h"
#include "halls_of_lightning.h"
enum eEnums
{
//Yell
SAY_AGGRO = -1602000,
SAY_SLAY_1 = -1602001,
SAY_SLAY_2 = -1602002,
SAY_SLAY_3 = -1602003,
SAY_DEATH = -1602004,
SAY_BATTLE_STANCE = -1602005,
EMOTE_BATTLE_STANCE = -1602006,
SAY_BERSEKER_STANCE = -1602007,
EMOTE_BERSEKER_STANCE = -1602008,
SAY_DEFENSIVE_STANCE = -1602009,
EMOTE_DEFENSIVE_STANCE = -1602010,
SPELL_DEFENSIVE_STANCE = 53790,
//SPELL_DEFENSIVE_AURA = 41105,
SPELL_SPELL_REFLECTION = 36096,
SPELL_PUMMEL = 12555,
SPELL_KNOCK_AWAY = 52029,
SPELL_IRONFORM = 52022,
SPELL_BERSEKER_STANCE = 53791,
//SPELL_BERSEKER_AURA = 41107,
SPELL_INTERCEPT = 58769,
SPELL_WHIRLWIND = 52027,
SPELL_CLEAVE = 15284,
SPELL_BATTLE_STANCE = 53792,
//SPELL_BATTLE_AURA = 41106,
SPELL_MORTAL_STRIKE = 16856,
SPELL_SLAM = 52026,
//OTHER SPELLS
//SPELL_CHARGE_UP = 52098, // only used when starting walk from one platform to the other
//SPELL_TEMPORARY_ELECTRICAL_CHARGE = 52092, // triggered part of above
NPC_STORMFORGED_LIEUTENANT = 29240,
SPELL_ARC_WELD = 59085,
SPELL_RENEW_STEEL_N = 52774,
SPELL_RENEW_STEEL_H = 59160,
EQUIP_SWORD = 37871,
EQUIP_SHIELD = 35642,
EQUIP_MACE = 43623,
STANCE_DEFENSIVE = 0,
STANCE_BERSERKER = 1,
STANCE_BATTLE = 2
};
/*######
## boss_bjarngrim
######*/
struct TRINITY_DLL_DECL boss_bjarngrimAI : public ScriptedAI
{
boss_bjarngrimAI(Creature *pCreature) : ScriptedAI(pCreature)
{
m_pInstance = pCreature->GetInstanceData();
m_uiStance = STANCE_DEFENSIVE;
memset(&m_auiStormforgedLieutenantGUID, 0, sizeof(m_auiStormforgedLieutenantGUID));
}
ScriptedInstance* m_pInstance;
bool m_bIsChangingStance;
uint8 m_uiChargingStatus;
uint8 m_uiStance;
uint32 m_uiCharge_Timer;
uint32 m_uiChangeStance_Timer;
uint32 m_uiReflection_Timer;
uint32 m_uiKnockAway_Timer;
uint32 m_uiPummel_Timer;
uint32 m_uiIronform_Timer;
uint32 m_uiIntercept_Timer;
uint32 m_uiWhirlwind_Timer;
uint32 m_uiCleave_Timer;
uint32 m_uiMortalStrike_Timer;
uint32 m_uiSlam_Timer;
uint64 m_auiStormforgedLieutenantGUID[2];
void Reset()
{
m_bIsChangingStance = false;
m_uiChargingStatus = 0;
m_uiCharge_Timer = 1000;
m_uiChangeStance_Timer = 20000 + rand()%5000;
m_uiReflection_Timer = 8000;
m_uiKnockAway_Timer = 20000;
m_uiPummel_Timer = 10000;
m_uiIronform_Timer = 25000;
m_uiIntercept_Timer = 5000;
m_uiWhirlwind_Timer = 10000;
m_uiCleave_Timer = 8000;
m_uiMortalStrike_Timer = 8000;
m_uiSlam_Timer = 10000;
for (uint8 i = 0; i < 2; ++i)
{
if (Creature* pStormforgedLieutenant = (Unit::GetCreature((*m_creature), m_auiStormforgedLieutenantGUID[i])))
{
if (!pStormforgedLieutenant->isAlive())
pStormforgedLieutenant->Respawn();
}
}
if (m_uiStance != STANCE_DEFENSIVE)
{
DoRemoveStanceAura(m_uiStance);
DoCast(m_creature, SPELL_DEFENSIVE_STANCE);
m_uiStance = STANCE_DEFENSIVE;
}
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
if (m_pInstance)
m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
}
void EnterCombat(Unit* pWho)
{
DoScriptText(SAY_AGGRO, m_creature);
//must get both lieutenants here and make sure they are with him
m_creature->CallForHelp(30.0f);
if (m_pInstance)
m_pInstance->SetData(TYPE_BJARNGRIM, IN_PROGRESS);
}
void KilledUnit(Unit* pVictim)
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
void JustDied(Unit* pKiller)
{
DoScriptText(SAY_DEATH, m_creature);
if (m_pInstance)
m_pInstance->SetData(TYPE_BJARNGRIM, DONE);
}
//TODO: remove when removal is done by mangos
void DoRemoveStanceAura(uint8 uiStance)
{
switch(uiStance)
{
case STANCE_DEFENSIVE:
m_creature->RemoveAurasDueToSpell(SPELL_DEFENSIVE_STANCE);
break;
case STANCE_BERSERKER:
m_creature->RemoveAurasDueToSpell(SPELL_BERSEKER_STANCE);
break;
case STANCE_BATTLE:
m_creature->RemoveAurasDueToSpell(SPELL_BATTLE_STANCE);
break;
}
}
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
if (!UpdateVictim())
return;
// Change stance
if (m_uiChangeStance_Timer <= uiDiff)
{
//wait for current spell to finish before change stance
if (m_creature->IsNonMeleeSpellCasted(false))
return;
DoRemoveStanceAura(m_uiStance);
int uiTempStance = rand()%(3-1);
if (uiTempStance >= m_uiStance)
++uiTempStance;
m_uiStance = uiTempStance;
switch(m_uiStance)
{
case STANCE_DEFENSIVE:
DoScriptText(SAY_DEFENSIVE_STANCE, m_creature);
DoScriptText(EMOTE_DEFENSIVE_STANCE, m_creature);
DoCast(m_creature, SPELL_DEFENSIVE_STANCE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
break;
case STANCE_BERSERKER:
DoScriptText(SAY_BERSEKER_STANCE, m_creature);
DoScriptText(EMOTE_BERSEKER_STANCE, m_creature);
DoCast(m_creature, SPELL_BERSEKER_STANCE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
break;
case STANCE_BATTLE:
DoScriptText(SAY_BATTLE_STANCE, m_creature);
DoScriptText(EMOTE_BATTLE_STANCE, m_creature);
DoCast(m_creature, SPELL_BATTLE_STANCE);
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
break;
}
m_uiChangeStance_Timer = 20000 + rand()%5000;
return;
}
else
m_uiChangeStance_Timer -= uiDiff;
switch(m_uiStance)
{
case STANCE_DEFENSIVE:
{
if (m_uiReflection_Timer <= uiDiff)
{
DoCast(m_creature, SPELL_SPELL_REFLECTION);
m_uiReflection_Timer = 8000 + rand()%1000;
}
else
m_uiReflection_Timer -= uiDiff;
if (m_uiKnockAway_Timer <= uiDiff)
{
DoCast(m_creature, SPELL_KNOCK_AWAY);
m_uiKnockAway_Timer = 20000 + rand()%1000;
}
else
m_uiKnockAway_Timer -= uiDiff;
if (m_uiPummel_Timer <= uiDiff)
{
DoCast(m_creature->getVictim(), SPELL_PUMMEL);
m_uiPummel_Timer = 10000 + rand()%1000;
}
else
m_uiPummel_Timer -= uiDiff;
if (m_uiIronform_Timer <= uiDiff)
{
DoCast(m_creature, SPELL_IRONFORM);
m_uiIronform_Timer = 25000 + rand()%1000;
}
else
m_uiIronform_Timer -= uiDiff;
break;
}
case STANCE_BERSERKER:
{
if (m_uiIntercept_Timer <= uiDiff)
{
//not much point is this, better random target and more often?
DoCast(m_creature->getVictim(), SPELL_INTERCEPT);
m_uiIntercept_Timer = 45000 + rand()%1000;
}
else
m_uiIntercept_Timer -= uiDiff;
if (m_uiWhirlwind_Timer <= uiDiff)
{
DoCast(m_creature, SPELL_WHIRLWIND);
m_uiWhirlwind_Timer = 10000 + rand()%1000;
}
else
m_uiWhirlwind_Timer -= uiDiff;
if (m_uiCleave_Timer <= uiDiff)
{
DoCast(m_creature->getVictim(), SPELL_CLEAVE);
m_uiCleave_Timer = 8000 + rand()%1000;
}
else
m_uiCleave_Timer -= uiDiff;
break;
}
case STANCE_BATTLE:
{
if (m_uiMortalStrike_Timer <= uiDiff)
{
DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE);
m_uiMortalStrike_Timer = 20000 + rand()%1000;
}
else
m_uiMortalStrike_Timer -= uiDiff;
if (m_uiSlam_Timer <= uiDiff)
{
DoCast(m_creature->getVictim(), SPELL_SLAM);
m_uiSlam_Timer = 15000 + rand()%1000;
}
else
m_uiSlam_Timer -= uiDiff;
break;
}
}
DoMeleeAttackIfReady();
}
};
/*######
## mob_stormforged_lieutenant
######*/
struct TRINITY_DLL_DECL mob_stormforged_lieutenantAI : public ScriptedAI
{
mob_stormforged_lieutenantAI(Creature *pCreature) : ScriptedAI(pCreature)
{
m_pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
uint32 m_uiArcWeld_Timer;
uint32 m_uiRenewSteel_Timer;
void Reset()
{
m_uiArcWeld_Timer = 20000 + rand()%1000;
m_uiRenewSteel_Timer = 10000 + rand()%1000;
}
void EnterCombat(Unit* pWho)
{
if (m_pInstance)
{
if (Creature* pBjarngrim = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_BJARNGRIM)))
{
if (pBjarngrim->isAlive() && !pBjarngrim->getVictim())
pBjarngrim->AI()->AttackStart(pWho);
}
}
}
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (m_uiArcWeld_Timer <= uiDiff)
{
DoCast(m_creature->getVictim(), SPELL_ARC_WELD);
m_uiArcWeld_Timer = 20000 + rand()%1000;
}
else
m_uiArcWeld_Timer -= uiDiff;
if (m_uiRenewSteel_Timer <= uiDiff)
{
if (m_pInstance)
{
if (Creature* pBjarngrim = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_BJARNGRIM)))
{
if (pBjarngrim->isAlive())
DoCast(pBjarngrim, DUNGEON_MODE(SPELL_RENEW_STEEL_N, SPELL_RENEW_STEEL_H));
}
}
m_uiRenewSteel_Timer = 10000 + rand()%4000;
}
else
m_uiRenewSteel_Timer -= uiDiff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_bjarngrim(Creature* pCreature)
{
return new boss_bjarngrimAI(pCreature);
}
CreatureAI* GetAI_mob_stormforged_lieutenant(Creature* pCreature)
{
return new mob_stormforged_lieutenantAI(pCreature);
}
void AddSC_boss_bjarngrim()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_bjarngrim";
newscript->GetAI = &GetAI_boss_bjarngrim;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_stormforged_lieutenant";
newscript->GetAI = &GetAI_mob_stormforged_lieutenant;
newscript->RegisterSelf();
}
@@ -0,0 +1,380 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss Ionar
SD%Complete: 80%
SDComment: Timer check
SDCategory: Halls of Lightning
EndScriptData */
#include "ScriptedPch.h"
#include "halls_of_lightning.h"
enum eEnums
{
SAY_AGGRO = -1602011,
SAY_SLAY_1 = -1602012,
SAY_SLAY_2 = -1602013,
SAY_SLAY_3 = -1602014,
SAY_DEATH = -1602015,
SAY_SPLIT_1 = -1602016,
SAY_SPLIT_2 = -1602017,
SPELL_BALL_LIGHTNING_N = 52780,
SPELL_BALL_LIGHTNING_H = 59800,
SPELL_STATIC_OVERLOAD_N = 52658,
SPELL_STATIC_OVERLOAD_H = 59795,
SPELL_DISPERSE = 52770,
SPELL_SUMMON_SPARK = 52746,
SPELL_SPARK_DESPAWN = 52776,
//Spark of Ionar
SPELL_SPARK_VISUAL_TRIGGER_N = 52667,
SPELL_SPARK_VISUAL_TRIGGER_H = 59833,
NPC_SPARK_OF_IONAR = 28926,
MAX_SPARKS = 5,
POINT_CALLBACK = 0
};
/*######
## Boss Ionar
######*/
struct TRINITY_DLL_DECL boss_ionarAI : public ScriptedAI
{
boss_ionarAI(Creature *pCreature) : ScriptedAI(pCreature)
{
m_pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
std::list<uint64> m_lSparkGUIDList;
bool m_bIsSplitPhase;
uint32 m_uiSplit_Timer;
uint32 m_uiSparkAtHomeCount;
uint32 m_uiStaticOverload_Timer;
uint32 m_uiBallLightning_Timer;
uint32 m_uiHealthAmountModifier;
void Reset()
{
m_lSparkGUIDList.clear();
m_bIsSplitPhase = true;
m_uiSplit_Timer = 25000;
m_uiSparkAtHomeCount = 0;
m_uiStaticOverload_Timer = 5000 + rand()%1000;
m_uiBallLightning_Timer = 10000 + rand()%1000;
m_uiHealthAmountModifier = 1;
if (m_creature->GetVisibility() == VISIBILITY_OFF)
m_creature->SetVisibility(VISIBILITY_ON);
}
void AttackedBy(Unit* pAttacker)
{
if (m_creature->getVictim())
return;
if (m_creature->GetVisibility() == VISIBILITY_OFF)
return;
AttackStart(pAttacker);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, IN_PROGRESS);
}
void JustReachedHome()
{
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
}
void AttackStart(Unit* pWho)
{
if (m_creature->Attack(pWho, true))
{
m_creature->AddThreat(pWho, 0.0f);
m_creature->SetInCombatWith(pWho);
pWho->SetInCombatWith(m_creature);
if (m_creature->GetVisibility() != VISIBILITY_OFF)
m_creature->GetMotionMaster()->MoveChase(pWho);
}
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
DespawnSpark();
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, DONE);
}
void KilledUnit(Unit *victim)
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
void DespawnSpark()
{
if (m_lSparkGUIDList.empty())
return;
for (std::list<uint64>::iterator itr = m_lSparkGUIDList.begin(); itr != m_lSparkGUIDList.end(); ++itr)
{
if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
{
if (pTemp->isAlive())
pTemp->ForcedDespawn();
}
}
m_lSparkGUIDList.clear();
}
//make sparks come back
void CallBackSparks()
{
//should never be empty here, but check
if (m_lSparkGUIDList.empty())
return;
for (std::list<uint64>::iterator itr = m_lSparkGUIDList.begin(); itr != m_lSparkGUIDList.end(); ++itr)
{
if (Creature* pSpark = Unit::GetCreature(*m_creature, *itr))
{
if (pSpark->isAlive())
{
if (pSpark->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
pSpark->GetMotionMaster()->MovementExpired();
pSpark->SetSpeed(MOVE_RUN, pSpark->GetCreatureInfo()->speed * 2);
pSpark->GetMotionMaster()->MovePoint(POINT_CALLBACK, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
}
}
}
}
void RegisterSparkAtHome()
{
++m_uiSparkAtHomeCount;
}
void JustSummoned(Creature* pSummoned)
{
if (pSummoned->GetEntry() == NPC_SPARK_OF_IONAR)
{
pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_SPARK_VISUAL_TRIGGER_N,SPELL_SPARK_VISUAL_TRIGGER_H), true);
Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (m_creature->getVictim())
pSummoned->AI()->AttackStart(pTarget ? pTarget : m_creature->getVictim());
m_lSparkGUIDList.push_back(pSummoned->GetGUID());
}
}
void UpdateAI(const uint32 uiDiff)
{
// Splitted
if (m_creature->GetVisibility() == VISIBILITY_OFF)
{
/*if (!m_creature->getVictim())
{
Reset();
return;
}*/
if (m_uiSplit_Timer <= uiDiff)
{
m_uiSplit_Timer = 2500;
// Return sparks to where Ionar splitted
if (m_bIsSplitPhase)
{
CallBackSparks();
m_bIsSplitPhase = false;
}
// Lightning effect and restore Ionar
else if (m_uiSparkAtHomeCount == MAX_SPARKS)
{
m_creature->SetVisibility(VISIBILITY_ON);
DoCast(m_creature, SPELL_SPARK_DESPAWN, false);
DespawnSpark();
m_uiSparkAtHomeCount = 0;
m_uiSplit_Timer = 25000;
m_bIsSplitPhase = true;
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
{
if (m_creature->getVictim())
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
}
}
}
else
m_uiSplit_Timer -= uiDiff;
return;
}
//Return since we have no target
if (!UpdateVictim())
return;
if (m_uiStaticOverload_Timer <= uiDiff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_STATIC_OVERLOAD_N, SPELL_STATIC_OVERLOAD_H));
m_uiStaticOverload_Timer = 5000 + rand()%1000;
}
else
m_uiStaticOverload_Timer -= uiDiff;
if (m_uiBallLightning_Timer <= uiDiff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_BALL_LIGHTNING_N, SPELL_BALL_LIGHTNING_H));
m_uiBallLightning_Timer = 10000 + rand()%1000;
}
else
m_uiBallLightning_Timer -= uiDiff;
// Health check
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(20*m_uiHealthAmountModifier)))
{
++m_uiHealthAmountModifier;
DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), m_creature);
if (m_creature->IsNonMeleeSpellCasted(false))
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature, SPELL_DISPERSE);
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_ionar(Creature* pCreature)
{
return new boss_ionarAI(pCreature);
}
bool EffectDummyCreature_boss_ionar(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
{
//always check spellid and effectindex
if (uiSpellId == SPELL_DISPERSE && uiEffIndex == 0)
{
if (pCreatureTarget->GetEntry() != NPC_IONAR)
return true;
for (uint8 i = 0; i < MAX_SPARKS; ++i)
pCreatureTarget->CastSpell(pCreatureTarget, SPELL_SUMMON_SPARK, true);
pCreatureTarget->AttackStop();
pCreatureTarget->SetVisibility(VISIBILITY_OFF);
if (pCreatureTarget->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
pCreatureTarget->GetMotionMaster()->MovementExpired();
//always return true when we are handling this spell and effect
return true;
}
return false;
}
/*######
## mob_spark_of_ionar
######*/
struct TRINITY_DLL_DECL mob_spark_of_ionarAI : public ScriptedAI
{
mob_spark_of_ionarAI(Creature *pCreature) : ScriptedAI(pCreature)
{
m_pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
void Reset() { }
void MovementInform(uint32 uiType, uint32 uiPointId)
{
if (uiType != POINT_MOTION_TYPE || !m_pInstance)
return;
if (uiPointId == POINT_CALLBACK)
{
if (Creature* pIonar = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_IONAR)))
{
if (!pIonar->isAlive())
{
m_creature->ForcedDespawn();
return;
}
if (boss_ionarAI* pIonarAI = dynamic_cast<boss_ionarAI*>(pIonar->AI()))
pIonarAI->RegisterSparkAtHome();
}
else
m_creature->ForcedDespawn();
}
}
};
CreatureAI* GetAI_mob_spark_of_ionar(Creature* pCreature)
{
return new mob_spark_of_ionarAI(pCreature);
}
void AddSC_boss_ionar()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_ionar";
newscript->GetAI = &GetAI_boss_ionar;
newscript->pEffectDummyCreature = &EffectDummyCreature_boss_ionar;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_spark_of_ionar";
newscript->GetAI = &GetAI_mob_spark_of_ionar;
newscript->RegisterSelf();
}
@@ -0,0 +1,239 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss Loken
SD%Complete: 60%
SDComment: Missing intro. Remove hack of Pulsing Shockwave when core supports. Aura is not working (59414)
SDCategory: Halls of Lightning
EndScriptData */
#include "ScriptedPch.h"
#include "halls_of_lightning.h"
#define MAX_ENCOUNTER_TIME 2 * 60 * 1000
enum eEnums
{
ACHIEVEMENT_TIMELY_DEATH = 1867,
SAY_AGGRO = -1602018,
SAY_INTRO_1 = -1602019,
SAY_INTRO_2 = -1602020,
SAY_SLAY_1 = -1602021,
SAY_SLAY_2 = -1602022,
SAY_SLAY_3 = -1602023,
SAY_DEATH = -1602024,
SAY_NOVA_1 = -1602025,
SAY_NOVA_2 = -1602026,
SAY_NOVA_3 = -1602027,
SAY_75HEALTH = -1602028,
SAY_50HEALTH = -1602029,
SAY_25HEALTH = -1602030,
EMOTE_NOVA = -1602031,
SPELL_ARC_LIGHTNING = 52921,
SPELL_LIGHTNING_NOVA_N = 52960,
SPELL_LIGHTNING_NOVA_H = 59835,
SPELL_PULSING_SHOCKWAVE_N = 52961,
SPELL_PULSING_SHOCKWAVE_H = 59836,
SPELL_PULSING_SHOCKWAVE_AURA = 59414
};
/*######
## Boss Loken
######*/
struct TRINITY_DLL_DECL boss_lokenAI : public ScriptedAI
{
boss_lokenAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
bool m_bIsAura;
uint32 m_uiArcLightning_Timer;
uint32 m_uiLightningNova_Timer;
uint32 m_uiPulsingShockwave_Timer;
uint32 m_uiResumePulsingShockwave_Timer;
uint32 m_uiHealthAmountModifier;
uint32 EncounterTime;
void Reset()
{
m_bIsAura = false;
m_uiArcLightning_Timer = 15000;
m_uiLightningNova_Timer = 20000;
m_uiPulsingShockwave_Timer = 2000;
m_uiResumePulsingShockwave_Timer = 15000;
m_uiHealthAmountModifier = 1;
if (m_pInstance)
m_pInstance->SetData(TYPE_LOKEN, NOT_STARTED);
}
void EnterCombat(Unit* pWho)
{
DoScriptText(SAY_AGGRO, m_creature);
EncounterTime = 0;
if (m_pInstance)
m_pInstance->SetData(TYPE_LOKEN, IN_PROGRESS);
}
void JustDied(Unit* pKiller)
{
DoScriptText(SAY_DEATH, m_creature);
if (IsHeroic() && EncounterTime <= MAX_ENCOUNTER_TIME)
{
AchievementEntry const *AchievTimelyDeath = GetAchievementStore()->LookupEntry(ACHIEVEMENT_TIMELY_DEATH);
if (AchievTimelyDeath)
{
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievTimelyDeath);
}
}
}
if (m_pInstance)
m_pInstance->SetData(TYPE_LOKEN, DONE);
}
void KilledUnit(Unit* pVictim)
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
if (!UpdateVictim())
return;
EncounterTime += uiDiff;
if (m_bIsAura)
{
// workaround for PULSING_SHOCKWAVE
if (m_uiPulsingShockwave_Timer <= uiDiff)
{
Map* pMap = m_creature->GetMap();
if (pMap->IsDungeon())
{
Map::PlayerList const &PlayerList = pMap->GetPlayers();
if (PlayerList.isEmpty())
return;
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (i->getSource() && i->getSource()->isAlive() && i->getSource()->isTargetableForAttack())
{
int32 dmg;
float m_fDist = m_creature->GetExactDist(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ());
dmg = DUNGEON_MODE(100, 150); // need to correct damage
if (m_fDist > 1.0f) // Further from 1 yard
dmg *= m_fDist;
m_creature->CastCustomSpell(i->getSource(), DUNGEON_MODE(52942, 59837), &dmg, 0, 0, false);
}
}
m_uiPulsingShockwave_Timer = 2000;
} else m_uiPulsingShockwave_Timer -= uiDiff;
}
else
{
if (m_uiResumePulsingShockwave_Timer <= uiDiff)
{
//breaks at movement, can we assume when it's time, this spell is casted and also must stop movement?
DoCast(m_creature, SPELL_PULSING_SHOCKWAVE_AURA, true);
DoCast(m_creature, DUNGEON_MODE(SPELL_PULSING_SHOCKWAVE_N, SPELL_PULSING_SHOCKWAVE_H)); // need core support
m_bIsAura = true;
m_uiResumePulsingShockwave_Timer = 0;
}
else
m_uiResumePulsingShockwave_Timer -= uiDiff;
}
if (m_uiArcLightning_Timer <= uiDiff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_ARC_LIGHTNING);
m_uiArcLightning_Timer = 15000 + rand()%1000;
}
else
m_uiArcLightning_Timer -= uiDiff;
if (m_uiLightningNova_Timer <= uiDiff)
{
DoScriptText(RAND(SAY_NOVA_1,SAY_NOVA_2,SAY_NOVA_3), m_creature);
DoScriptText(EMOTE_NOVA, m_creature);
DoCast(m_creature, DUNGEON_MODE(SPELL_LIGHTNING_NOVA_N, SPELL_LIGHTNING_NOVA_H));
m_bIsAura = false;
m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
m_uiLightningNova_Timer = 20000 + rand()%1000;
}
else
m_uiLightningNova_Timer -= uiDiff;
// Health check
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(25*m_uiHealthAmountModifier)))
{
switch(m_uiHealthAmountModifier)
{
case 1: DoScriptText(SAY_75HEALTH, m_creature); break;
case 2: DoScriptText(SAY_50HEALTH, m_creature); break;
case 3: DoScriptText(SAY_25HEALTH, m_creature); break;
}
++m_uiHealthAmountModifier;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_loken(Creature* pCreature)
{
return new boss_lokenAI(pCreature);
}
void AddSC_boss_loken()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_loken";
newscript->GetAI = &GetAI_boss_loken;
newscript->RegisterSelf();
}
@@ -0,0 +1,478 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss Volkhan
SD%Complete: 60%
SDComment: Not considered complete. Some events may fail and need further development
SDCategory: Halls of Lightning
EndScriptData */
#include "ScriptedPch.h"
#include "halls_of_lightning.h"
enum eEnums
{
SAY_AGGRO = -1602032,
SAY_SLAY_1 = -1602033,
SAY_SLAY_2 = -1602034,
SAY_SLAY_3 = -1602035,
SAY_DEATH = -1602036,
SAY_STOMP_1 = -1602037,
SAY_STOMP_2 = -1602038,
SAY_FORGE_1 = -1602039,
SAY_FORGE_2 = -1602040,
EMOTE_TO_ANVIL = -1602041,
EMOTE_SHATTER = -1602042,
SPELL_HEAT_N = 52387,
SPELL_HEAT_H = 59528,
SPELL_SHATTERING_STOMP_N = 52237,
SPELL_SHATTERING_STOMP_H = 59529,
//unclear how "directions" of spells must be. Last, summoning GO, what is it for? Script depend on:
SPELL_TEMPER = 52238, //TARGET_SCRIPT boss->anvil
SPELL_TEMPER_DUMMY = 52654, //TARGET_SCRIPT anvil->boss
//SPELL_TEMPER_VISUAL = 52661, //summons GO
SPELL_SUMMON_MOLTEN_GOLEM = 52405,
//Molten Golem
SPELL_BLAST_WAVE = 23113,
SPELL_IMMOLATION_STRIKE_N = 52433,
SPELL_IMMOLATION_STRIKE_H = 59530,
SPELL_SHATTER_N = 52429,
SPELL_SHATTER_H = 59527,
NPC_VOLKHAN_ANVIL = 28823,
NPC_MOLTEN_GOLEM = 28695,
NPC_BRITTLE_GOLEM = 28681,
POINT_ID_ANVIL = 0,
MAX_GOLEM = 2,
ACHIEVEMENT_SHATTER_RESISTANT = 2042
};
/*######
## Boss Volkhan
######*/
struct TRINITY_DLL_DECL boss_volkhanAI : public ScriptedAI
{
boss_volkhanAI(Creature *pCreature) : ScriptedAI(pCreature)
{
m_pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
std::list<uint64> m_lGolemGUIDList;
bool m_bHasTemper;
bool m_bIsStriking;
bool m_bCanShatterGolem;
uint8 GolemsShattered;
uint32 m_uiPause_Timer;
uint32 m_uiShatteringStomp_Timer;
uint32 m_uiShatter_Timer;
uint32 m_uiHealthAmountModifier;
void Reset()
{
m_bIsStriking = false;
m_bHasTemper = false;
m_bCanShatterGolem = false;
m_uiPause_Timer = 3500;
m_uiShatteringStomp_Timer = 0;
m_uiShatter_Timer = 5000;
GolemsShattered = 0;
m_uiHealthAmountModifier = 1;
DespawnGolem();
m_lGolemGUIDList.clear();
if (m_pInstance)
m_pInstance->SetData(TYPE_VOLKHAN, NOT_STARTED);
}
void EnterCombat(Unit* pWho)
{
DoScriptText(SAY_AGGRO, m_creature);
if (m_pInstance)
m_pInstance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
}
void AttackStart(Unit* pWho)
{
if (m_creature->Attack(pWho, true))
{
m_creature->AddThreat(pWho, 0.0f);
m_creature->SetInCombatWith(pWho);
pWho->SetInCombatWith(m_creature);
if (!m_bHasTemper)
m_creature->GetMotionMaster()->MoveChase(pWho);
}
}
void JustDied(Unit* pKiller)
{
DoScriptText(SAY_DEATH, m_creature);
DespawnGolem();
if (m_pInstance)
m_pInstance->SetData(TYPE_VOLKHAN, DONE);
if (IsHeroic() && GolemsShattered < 5)
{
AchievementEntry const *AchievShatterResistant = GetAchievementStore()->LookupEntry(ACHIEVEMENT_SHATTER_RESISTANT);
if (AchievShatterResistant)
{
Map* pMap = m_creature->GetMap();
if (pMap && pMap->IsDungeon())
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievShatterResistant);
}
}
}
}
void KilledUnit(Unit* pVictim)
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
void DespawnGolem()
{
if (m_lGolemGUIDList.empty())
return;
for (std::list<uint64>::iterator itr = m_lGolemGUIDList.begin(); itr != m_lGolemGUIDList.end(); ++itr)
{
if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
{
if (pTemp->isAlive())
pTemp->ForcedDespawn();
}
}
m_lGolemGUIDList.clear();
}
void ShatterGolem()
{
if (m_lGolemGUIDList.empty())
return;
for (std::list<uint64>::iterator itr = m_lGolemGUIDList.begin(); itr != m_lGolemGUIDList.end(); ++itr)
{
if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
{
// only shatter brittle golems
if (pTemp->isAlive() && pTemp->GetEntry() == NPC_BRITTLE_GOLEM)
{
pTemp->CastSpell(pTemp, DUNGEON_MODE(SPELL_SHATTER_N, SPELL_SHATTER_H), false);
GolemsShattered += 1;
}
}
}
}
void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
{
if (pSpell->Id == SPELL_TEMPER_DUMMY)
m_bIsStriking = true;
}
void JustSummoned(Creature* pSummoned)
{
if (pSummoned->GetEntry() == NPC_MOLTEN_GOLEM)
{
m_lGolemGUIDList.push_back(pSummoned->GetGUID());
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
pSummoned->AI()->AttackStart(pTarget);
//why healing when just summoned?
pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_HEAT_N, SPELL_HEAT_H), false, NULL, NULL, m_creature->GetGUID());
}
}
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (m_bIsStriking)
{
if (m_uiPause_Timer <= uiDiff)
{
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
{
if (m_creature->getVictim())
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
}
m_bHasTemper = false;
m_bIsStriking = false;
m_uiPause_Timer = 3500;
}
else
m_uiPause_Timer -= uiDiff;
return;
}
// When to start shatter? After 60, 40 or 20% hp?
if (!m_bHasTemper && m_uiHealthAmountModifier >= 3)
{
if (m_uiShatteringStomp_Timer <= uiDiff)
{
//should he stomp even if he has no brittle golem to shatter?
DoScriptText(RAND(SAY_STOMP_1,SAY_STOMP_2), m_creature);
DoCast(m_creature, DUNGEON_MODE(SPELL_SHATTERING_STOMP_N, SPELL_SHATTERING_STOMP_H));
DoScriptText(EMOTE_SHATTER, m_creature);
m_uiShatteringStomp_Timer = 30000;
m_bCanShatterGolem = true;
}
else
m_uiShatteringStomp_Timer -= uiDiff;
}
// Shatter Golems 3 seconds after Shattering Stomp
if (m_bCanShatterGolem)
{
if (m_uiShatter_Timer <= uiDiff)
{
ShatterGolem();
m_uiShatter_Timer = 3000;
m_bCanShatterGolem = false;
}
else
m_uiShatter_Timer -= uiDiff;
}
// Health check
if (!m_bCanShatterGolem && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(20*m_uiHealthAmountModifier)))
{
++m_uiHealthAmountModifier;
if (m_creature->IsNonMeleeSpellCasted(false))
m_creature->InterruptNonMeleeSpells(false);
DoScriptText(RAND(SAY_FORGE_1,SAY_FORGE_2), m_creature);
m_bHasTemper = true;
DoCast(m_creature, SPELL_TEMPER, false);
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_volkhan(Creature* pCreature)
{
return new boss_volkhanAI(pCreature);
}
bool EffectDummyCreature_boss_volkhan(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
{
//always check spellid and effectindex
if (uiSpellId == SPELL_TEMPER_DUMMY && uiEffIndex == 0)
{
if (pCaster->GetEntry() != NPC_VOLKHAN_ANVIL || pCreatureTarget->GetEntry() != NPC_VOLKHAN)
return true;
for (uint8 i = 0; i < MAX_GOLEM; ++i)
{
pCreatureTarget->CastSpell(pCaster, SPELL_SUMMON_MOLTEN_GOLEM, true);
}
//always return true when we are handling this spell and effect
return true;
}
return false;
}
/*######
## npc_volkhan_anvil
######*/
bool EffectDummyCreature_npc_volkhan_anvil(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
{
//always check spellid and effectindex
if (uiSpellId == SPELL_TEMPER && uiEffIndex == 0)
{
if (pCaster->GetEntry() != NPC_VOLKHAN || pCreatureTarget->GetEntry() != NPC_VOLKHAN_ANVIL)
return true;
Creature *cre = CAST_CRE(pCaster);
DoScriptText(EMOTE_TO_ANVIL, pCaster);
float fX, fY, fZ;
pCreatureTarget->GetContactPoint(pCaster, fX, fY, fZ, INTERACTION_DISTANCE);
pCaster->AttackStop();
if (pCaster->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
pCaster->GetMotionMaster()->MovementExpired();
cre->GetMap()->CreatureRelocation(cre, fX, fY, fZ, pCreatureTarget->GetOrientation());
cre->SendMonsterMove(fX, fY, fZ, 0, cre->GetUnitMovementFlags(), 1);
pCreatureTarget->CastSpell(pCaster, SPELL_TEMPER_DUMMY, false);
//always return true when we are handling this spell and effect
return true;
}
return false;
}
/*######
## mob_molten_golem
######*/
struct TRINITY_DLL_DECL mob_molten_golemAI : public ScriptedAI
{
mob_molten_golemAI(Creature *pCreature) : ScriptedAI(pCreature)
{
}
bool m_bIsFrozen;
uint32 m_uiBlast_Timer;
uint32 m_uiDeathDelay_Timer;
uint32 m_uiImmolation_Timer;
void Reset()
{
m_bIsFrozen = false;
m_uiBlast_Timer = 20000;
m_uiDeathDelay_Timer = 0;
m_uiImmolation_Timer = 5000;
}
void AttackStart(Unit* pWho)
{
if (m_creature->Attack(pWho, true))
{
m_creature->AddThreat(pWho, 0.0f);
m_creature->SetInCombatWith(pWho);
pWho->SetInCombatWith(m_creature);
if (!m_bIsFrozen)
m_creature->GetMotionMaster()->MoveChase(pWho);
}
}
void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
{
if (uiDamage > m_creature->GetHealth())
{
m_creature->UpdateEntry(NPC_BRITTLE_GOLEM);
m_creature->SetHealth(1);
uiDamage = 0;
m_creature->RemoveAllAuras();
m_creature->AttackStop();
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
if (m_creature->IsNonMeleeSpellCasted(false))
m_creature->InterruptNonMeleeSpells(false);
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
m_creature->GetMotionMaster()->MovementExpired();
m_bIsFrozen = true;
}
}
void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
{
//this is the dummy effect of the spells
if (pSpell->Id == SPELL_SHATTER_N || pSpell->Id == SPELL_SHATTER_H)
{
if (m_creature->GetEntry() == NPC_BRITTLE_GOLEM)
m_creature->ForcedDespawn();
}
}
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target or if we are frozen
if (!UpdateVictim() || m_bIsFrozen)
return;
if (m_uiBlast_Timer <= uiDiff)
{
DoCast(m_creature, SPELL_BLAST_WAVE);
m_uiBlast_Timer = 20000;
}
else
m_uiBlast_Timer -= uiDiff;
if (m_uiImmolation_Timer <= uiDiff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_IMMOLATION_STRIKE_N, SPELL_IMMOLATION_STRIKE_H));
m_uiImmolation_Timer = 5000;
}
else
m_uiImmolation_Timer -= uiDiff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_molten_golem(Creature* pCreature)
{
return new mob_molten_golemAI(pCreature);
}
void AddSC_boss_volkhan()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_volkhan";
newscript->GetAI = &GetAI_boss_volkhan;
newscript->pEffectDummyCreature = &EffectDummyCreature_boss_volkhan;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_volkhan_anvil";
newscript->pEffectDummyCreature = &EffectDummyCreature_npc_volkhan_anvil;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_molten_golem";
newscript->GetAI = &GetAI_mob_molten_golem;
newscript->RegisterSelf();
}
@@ -0,0 +1,34 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_HALLS_OF_LIGHTNING_H
#define DEF_HALLS_OF_LIGHTNING_H
enum eTypes
{
MAX_ENCOUNTER = 4,
DATA_BJARNGRIM = 1,
DATA_IONAR = 2,
DATA_LOKEN = 3,
DATA_VOLKHAN = 4,
TYPE_BJARNGRIM = 10,
TYPE_IONAR = 11,
TYPE_LOKEN = 12,
TYPE_VOLKHAN = 13,
NPC_BJARNGRIM = 28586,
NPC_VOLKHAN = 28587,
NPC_IONAR = 28546,
NPC_LOKEN = 28923,
GO_BJARNGRIM_DOOR = 191416, //_doors10
GO_VOLKHAN_DOOR = 191325, //_doors07
GO_IONAR_DOOR = 191326, //_doors05
GO_LOKEN_DOOR = 191324, //_doors02
GO_LOKEN_THRONE = 192654
};
#endif
@@ -0,0 +1,237 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance_Halls_of_Lightning
SD%Complete: 90%
SDComment: All ready.
SDCategory: Halls of Lightning
EndScriptData */
#include "ScriptedPch.h"
#include "halls_of_lightning.h"
/* Halls of Lightning encounters:
0 - General Bjarngrim
1 - Volkhan
2 - Ionar
3 - Loken
*/
struct TRINITY_DLL_DECL instance_halls_of_lightning : public ScriptedInstance
{
instance_halls_of_lightning(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
uint32 m_auiEncounter[MAX_ENCOUNTER];
uint64 m_uiGeneralBjarngrimGUID;
uint64 m_uiIonarGUID;
uint64 m_uiLokenGUID;
uint64 m_uiVolkhanGUID;
uint64 m_uiBjarngrimDoorGUID;
uint64 m_uiVolkhanDoorGUID;
uint64 m_uiIonarDoorGUID;
uint64 m_uiLokenDoorGUID;
uint64 m_uiLokenGlobeGUID;
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
m_uiGeneralBjarngrimGUID = 0;
m_uiVolkhanGUID = 0;
m_uiIonarGUID = 0;
m_uiLokenGUID = 0;
m_uiBjarngrimDoorGUID = 0;
m_uiVolkhanDoorGUID = 0;
m_uiIonarDoorGUID = 0;
m_uiLokenDoorGUID = 0;
m_uiLokenGlobeGUID = 0;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case NPC_BJARNGRIM:
m_uiGeneralBjarngrimGUID = pCreature->GetGUID();
break;
case NPC_VOLKHAN:
m_uiVolkhanGUID = pCreature->GetGUID();
break;
case NPC_IONAR:
m_uiIonarGUID = pCreature->GetGUID();
break;
case NPC_LOKEN:
m_uiLokenGUID = pCreature->GetGUID();
break;
}
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch(pGo->GetEntry())
{
case GO_BJARNGRIM_DOOR:
m_uiBjarngrimDoorGUID = pGo->GetGUID();
if (m_auiEncounter[0] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_VOLKHAN_DOOR:
m_uiVolkhanDoorGUID = pGo->GetGUID();
if (m_auiEncounter[1] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_IONAR_DOOR:
m_uiIonarDoorGUID = pGo->GetGUID();
if (m_auiEncounter[2] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_LOKEN_DOOR:
m_uiLokenDoorGUID = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_LOKEN_THRONE:
m_uiLokenGlobeGUID = pGo->GetGUID();
break;
}
}
void SetData(uint32 uiType, uint32 uiData)
{
switch(uiType)
{
case TYPE_BJARNGRIM:
if (uiData == DONE)
DoUseDoorOrButton(m_uiBjarngrimDoorGUID);
m_auiEncounter[0] = uiData;
break;
case TYPE_VOLKHAN:
if (uiData == DONE)
DoUseDoorOrButton(m_uiVolkhanDoorGUID);
m_auiEncounter[1] = uiData;
break;
case TYPE_IONAR:
if (uiData == DONE)
DoUseDoorOrButton(m_uiIonarDoorGUID);
m_auiEncounter[2] = uiData;
break;
case TYPE_LOKEN:
if (uiData == DONE)
{
DoUseDoorOrButton(m_uiLokenDoorGUID);
//Appears to be type 5 GO with animation. Need to figure out how this work, code below only placeholder
if (GameObject* pGlobe = instance->GetGameObject(m_uiLokenGlobeGUID))
pGlobe->SetGoState(GO_STATE_ACTIVE);
}
m_auiEncounter[3] = uiData;
break;
}
}
uint32 GetData(uint32 uiType)
{
switch(uiType)
{
case TYPE_BJARNGRIM:
return m_auiEncounter[0];
case TYPE_VOLKHAN:
return m_auiEncounter[1];
case TYPE_IONAR:
return m_auiEncounter[2];
case TYPE_LOKEN:
return m_auiEncounter[3];
}
return 0;
}
uint64 GetData64(uint32 uiData)
{
switch(uiData)
{
case DATA_BJARNGRIM:
return m_uiGeneralBjarngrimGUID;
case DATA_VOLKHAN:
return m_uiVolkhanGUID;
case DATA_IONAR:
return m_uiIonarGUID;
case DATA_LOKEN:
return m_uiLokenGUID;
}
return 0;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "H L " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
<< m_auiEncounter[2] << " " << m_auiEncounter[3];
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
void Load(const char* in)
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
if (dataHead1 == 'H' && dataHead2 == 'L')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
m_auiEncounter[3] = data3;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_halls_of_lightning(Map* pMap)
{
return new instance_halls_of_lightning(pMap);
}
void AddSC_instance_halls_of_lightning()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_halls_of_lightning";
newscript->GetInstanceData = &GetInstanceData_instance_halls_of_lightning;
newscript->RegisterSelf();
}
@@ -0,0 +1,148 @@
/* Script Data Start
SDName: Boss krystallus
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_krystallus' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "halls_of_stone.h"
enum Spells
{
SPELL_BOULDER_TOSS = 50843,
H_SPELL_BOULDER_TOSS = 59742,
SPELL_GROUND_SPIKE = 59750,
SPELL_GROUND_SLAM = 50827,
SPELL_SHATTER = 50810,
H_SPELL_SHATTER = 61546,
SPELL_STOMP = 48131,
H_SPELL_STOMP = 59744
};
enum Yells
{
SAY_AGGRO = -1603007,
SAY_KILL = -1603008,
SAY_DEATH = -1603009,
SAY_SHATTER = -1603010
};
struct TRINITY_DLL_DECL boss_krystallusAI : public ScriptedAI
{
boss_krystallusAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 uiBoulderTossTimer;
uint32 uiGroundSpikeTimer;
uint32 uiGroundSlamTimer;
uint32 uiShatterTimer;
uint32 uiStompTimer;
bool bIsSlam;
ScriptedInstance* pInstance;
void Reset()
{
bIsSlam = false;
uiBoulderTossTimer = 3000 + rand()%6000;
uiGroundSpikeTimer = 9000 + rand()%5000;
uiGroundSlamTimer = 15000 + rand()%3000;
uiStompTimer = 20000 + rand()%9000;
uiShatterTimer = 0;
if (pInstance)
pInstance->SetData(DATA_KRYSTALLUS_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_KRYSTALLUS_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiBoulderTossTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_BOULDER_TOSS, H_SPELL_BOULDER_TOSS));
uiBoulderTossTimer = 9000 + rand()%6000;
} else uiBoulderTossTimer -= diff;
if (uiGroundSpikeTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_GROUND_SPIKE);
uiGroundSpikeTimer = 12000 + rand()%5000;
} else uiGroundSpikeTimer -= diff;
if (uiStompTimer <= diff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_STOMP, H_SPELL_STOMP));
uiStompTimer = 20000 + rand()%9000;
} else uiStompTimer -= diff;
if (uiGroundSlamTimer <= diff)
{
DoCast(m_creature, SPELL_GROUND_SLAM);
bIsSlam = true;
uiShatterTimer = 10000;
uiGroundSlamTimer = 15000 + rand()%3000;
} else uiGroundSlamTimer -= diff;
if (bIsSlam)
{
if (uiShatterTimer <= diff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_SHATTER, H_SPELL_SHATTER));
bIsSlam = false;
} else uiShatterTimer -= diff;
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_KRYSTALLUS_EVENT, DONE);
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(SAY_KILL, m_creature);
}
};
CreatureAI* GetAI_boss_krystallus(Creature* pCreature)
{
return new boss_krystallusAI (pCreature);
}
void AddSC_boss_krystallus()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_krystallus";
newscript->GetAI = &GetAI_boss_krystallus;
newscript->RegisterSelf();
}
@@ -0,0 +1,177 @@
/* Script Data Start
SDName: Boss maiden_of_grief
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_maiden_of_grief' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "halls_of_stone.h"
enum Spells
{
SPELL_PARTING_SORROW = 59723,
SPELL_STORM_OF_GRIEF_N = 50752,
SPELL_STORM_OF_GRIEF_H = 59772,
SPELL_SHOCK_OF_SORROW_N = 50760,
SPELL_SHOCK_OF_SORROW_H = 59726,
SPELL_PILLAR_OF_WOE_N = 50761,
SPELL_PILLAR_OF_WOE_H = 59727
};
enum Yells
{
SAY_AGGRO = -1603000,
SAY_SLAY_1 = -1603001,
SAY_SLAY_2 = -1603002,
SAY_SLAY_3 = -1603003,
SAY_SLAY_4 = -1603004,
SAY_DEATH = -1603005,
SAY_STUN = -1603006
};
enum Achievements
{
ACHIEVEMENT_GOOD_GRIEF = 1866
};
struct TRINITY_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI
{
boss_maiden_of_griefAI(Creature *c) : ScriptedAI(c)
{
pInstance = m_creature->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 PartingSorrowTimer;
uint32 StormOfGriefTimer;
uint32 ShockOfSorrowTimer;
uint32 PillarOfWoeTimer;
uint32 AchievTimer;
void Reset()
{
PartingSorrowTimer = 25000 + rand()%5000;
StormOfGriefTimer = 10000;
ShockOfSorrowTimer = 20000+rand()%5000;
PillarOfWoeTimer = 5000 + rand()%10000;
AchievTimer = 0;
if (pInstance)
pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
{
if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_MAIDEN_DOOR)))
if (pDoor->GetGoState() == GO_STATE_READY)
{
EnterEvadeMode();
return;
}
pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, IN_PROGRESS);
}
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//Achievement counter
if (pInstance)
if (pInstance->GetData(DATA_MAIDEN_OF_GRIEF_EVENT) == IN_PROGRESS)
AchievTimer += diff;
if (IsHeroic())
{
if (PartingSorrowTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(pTarget)
DoCast(pTarget, SPELL_PARTING_SORROW);
PartingSorrowTimer = 30000 + rand()%10000;
} else PartingSorrowTimer -= diff;
}
if (StormOfGriefTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_STORM_OF_GRIEF_N, SPELL_STORM_OF_GRIEF_H), true);
StormOfGriefTimer = 15000 + rand()%5000;
} else StormOfGriefTimer -= diff;
if (ShockOfSorrowTimer <= diff)
{
DoResetThreat();
DoScriptText(SAY_STUN, m_creature);
DoCast(m_creature, DUNGEON_MODE(SPELL_SHOCK_OF_SORROW_N, SPELL_SHOCK_OF_SORROW_H));
ShockOfSorrowTimer = 20000 + rand()%10000;
} else ShockOfSorrowTimer -= diff;
if (PillarOfWoeTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (pTarget)
DoCast(pTarget, DUNGEON_MODE(SPELL_PILLAR_OF_WOE_N, SPELL_PILLAR_OF_WOE_H));
else
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_PILLAR_OF_WOE_N, SPELL_PILLAR_OF_WOE_H));
PillarOfWoeTimer = 5000 + rand()%20000;
} else PillarOfWoeTimer -= diff;
DoMeleeAttackIfReady();
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, DONE);
AchievementEntry const *AchievGoodGrief = GetAchievementStore()->LookupEntry(ACHIEVEMENT_GOOD_GRIEF);
Map* pMap = m_creature->GetMap();
if (IsHeroic() && AchievTimer < 60000 && pMap && pMap->IsDungeon() && AchievGoodGrief)
{
Map::PlayerList const &players = pMap->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
itr->getSource()->CompletedAchievement(AchievGoodGrief);
}
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3,SAY_SLAY_4), m_creature);
}
};
CreatureAI* GetAI_boss_maiden_of_grief(Creature* pCreature)
{
return new boss_maiden_of_griefAI (pCreature);
}
void AddSC_boss_maiden_of_grief()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_maiden_of_grief";
newscript->GetAI = &GetAI_boss_maiden_of_grief;
newscript->RegisterSelf();
}
@@ -0,0 +1,300 @@
/* Script Data Start
SDName: Boss sjonnir
SDAuthor: LordVanMartin
SD%Complete:
SDComment:
SDCategory:
Script Data End */
/*** SQL START ***
update creature_template set scriptname = 'boss_sjonnir' where entry = '';
*** SQL END ***/
#include "ScriptedPch.h"
#include "halls_of_stone.h"
enum Spells
{
SPELL_LIGHTING_RING = 51849, //Periodic Trigger (interval 2s) spell = 50841
H_SPELL_LIGHTING_RING = 59861, //Periodic Trigger (interval 2s) spell = 59849
SPELL_LIGHTING_RING_1 = 50840, //Periodic Trigger (interval 2s) spell = 50841
H_SPELL_LIGHTING_RING_1 = 59848, //Periodic Trigger (interval 2s) spell = 59849
SPELL_STATIC_CHARGE = 50834, //Periodic Trigger 2s interval, spell =50835
H_SPELL_STATIC_CHARGE = 59846, //Periodic Trigger 2s interval, spell =50847
SPELL_CHAIN_LIGHTING = 50830,
H_SPELL_CHAIN_LIGHTING = 59844,
SPELL_LIGHTING_SHIELD = 50831,
H_SPELL_LIGHTING_SHIELD = 59845,
SPELL_FRENZY = 28747
};
enum Yells
{
SAY_AGGRO = -1603011,
SAY_SLAY_1 = -1603012,
SAY_SLAY_2 = -1603013,
SAY_SLAY_3 = -1603014,
SAY_DEATH = -1603015
};
#define EMOTE_GENERIC_FRENZY -1000002
enum SjonnirCreatures
{
CREATURE_FORGED_IRON_TROGG = 27979,
CREATURE_MALFORMED_OOZE = 27981,
CREATURE_FORGED_IRON_DWARF = 27982,
CREATURE_IRON_SLUDGE = 28165
};
enum Misc
{
DATA_TIME_BEFORE_OOZE = 150000, //2min 30 secs
ACHIEV_ABUSE_THE_OOZE = 2155
};
struct Locations
{
float x, y, z;
};
static Locations PipeLocations[] =
{
{1295.44, 734.07, 200.3}, //left
{1297.7, 595.6, 199.9} //right
};
static Locations CenterPoint = {1295.21, 667.157, 189.691};
struct TRINITY_DLL_DECL boss_sjonnirAI : public ScriptedAI
{
boss_sjonnirAI(Creature *c) : ScriptedAI(c), lSummons(me)
{
pInstance = c->GetInstanceData();
}
bool bIsFrenzy;
uint32 uiChainLightningTimer;
uint32 uiLightningShieldTimer;
uint32 uiStaticChargeTimer;
uint32 uiLightningRingTimer;
uint32 uiSummonTimer;
uint32 uiFrenzyTimer;
uint32 uiEncounterTimer;
uint32 uiKilledIronSludges;
SummonList lSummons;
ScriptedInstance* pInstance;
void Reset()
{
bIsFrenzy = false;
uiEncounterTimer = 0;
uiChainLightningTimer = 3000 + rand()%5000;
uiLightningShieldTimer = 20000 + rand()%5000;
uiStaticChargeTimer = 20000 + rand()%5000;
uiLightningRingTimer = 30000 + rand()%5000;
uiSummonTimer = 5000;
uiFrenzyTimer = 300000; //5 minutes
uiKilledIronSludges = 0;
lSummons.DespawnAll();
if (pInstance)
pInstance->SetData(DATA_SJONNIR_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
uiEncounterTimer = 0;
if (pInstance)
{
if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_SJONNIR_DOOR)))
if (pDoor->GetGoState() == GO_STATE_READY)
{
EnterEvadeMode();
return;
}
pInstance->SetData(DATA_SJONNIR_EVENT, IN_PROGRESS);
}
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiChainLightningTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_CHAIN_LIGHTING, H_SPELL_CHAIN_LIGHTING));
uiChainLightningTimer = 10000 + rand()%5000;
} else uiChainLightningTimer -= diff;
if (uiLightningShieldTimer <= diff)
{
DoCast(m_creature, DUNGEON_MODE(SPELL_LIGHTING_SHIELD, H_SPELL_LIGHTING_SHIELD));
uiLightningShieldTimer -= diff;
}
if (uiStaticChargeTimer <= diff)
{
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_STATIC_CHARGE, H_SPELL_STATIC_CHARGE));
uiStaticChargeTimer = 20000 + rand()%5000;
} uiStaticChargeTimer -= diff;
if (uiLightningRingTimer <= diff)
{
if (m_creature->IsNonMeleeSpellCasted(false))
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature, DUNGEON_MODE(SPELL_LIGHTING_RING, H_SPELL_LIGHTING_RING));
uiLightningRingTimer = 30000 + rand()%5000;
} else uiLightningRingTimer -= diff;
if (uiSummonTimer <= diff)
{
uint32 uiSummonPipe = rand()%2;
m_creature->SummonCreature(uiEncounterTimer > DATA_TIME_BEFORE_OOZE ? CREATURE_MALFORMED_OOZE :
RAND(CREATURE_FORGED_IRON_DWARF,CREATURE_FORGED_IRON_TROGG),
PipeLocations[uiSummonPipe].x, PipeLocations[uiSummonPipe].y, PipeLocations[uiSummonPipe].z, 0.0f,
TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
uiSummonTimer = 20000;
} else uiSummonTimer -= diff;
if (!bIsFrenzy)
{
if (uiFrenzyTimer <= diff)
{
DoCast(m_creature, SPELL_FRENZY);
bIsFrenzy = true;
}
else uiFrenzyTimer -= diff;
}
uiEncounterTimer +=diff;
DoMeleeAttackIfReady();
}
void JustSummoned(Creature* summon)
{
summon->GetMotionMaster()->MovePoint(0, CenterPoint.x, CenterPoint.y, CenterPoint.z);
/*if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
summon->AI()->AttackStart(pTarget);*/
lSummons.Summon(summon);
}
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
lSummons.DespawnAll();
if (pInstance)
{
pInstance->SetData(DATA_SJONNIR_EVENT, DONE);
if (IsHeroic() && uiKilledIronSludges > 4)
pInstance->DoCompleteAchievement(ACHIEV_ABUSE_THE_OOZE);
}
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)
return;
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
void KilledIronSludge()
{
++uiKilledIronSludges;
}
};
CreatureAI* GetAI_boss_sjonnir(Creature* pCreature)
{
return new boss_sjonnirAI (pCreature);
}
struct TRINITY_DLL_DECL mob_malformed_oozeAI : public ScriptedAI
{
mob_malformed_oozeAI(Creature *c) : ScriptedAI(c) {}
uint32 uiMergeTimer;
void Reset()
{
uiMergeTimer = 10000;
}
void UpdateAI(const uint32 diff)
{
if (uiMergeTimer <= diff)
{
if (Creature* pTemp = m_creature->FindNearestCreature(CREATURE_MALFORMED_OOZE, 3.0f, true))
{
DoSpawnCreature(CREATURE_IRON_SLUDGE, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
pTemp->DisappearAndDie();
m_creature->DisappearAndDie();
}
uiMergeTimer = 3000;
} else uiMergeTimer -= diff;
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_malformed_ooze(Creature* pCreature)
{
return new mob_malformed_oozeAI(pCreature);
}
struct TRINITY_DLL_DECL mob_iron_sludgeAI : public ScriptedAI
{
mob_iron_sludgeAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
void JustDied(Unit* pKiller)
{
if (pInstance)
if(Creature* pSjonnir = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_SJONNIR)))
CAST_AI(boss_sjonnirAI, pSjonnir->AI())->KilledIronSludge();
}
};
CreatureAI* GetAI_mob_iron_sludge(Creature* pCreature)
{
return new mob_iron_sludgeAI(pCreature);
}
void AddSC_boss_sjonnir()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_sjonnir";
newscript->GetAI = &GetAI_boss_sjonnir;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_malformed_ooze";
newscript->GetAI = &GetAI_mob_malformed_ooze;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_iron_sludge";
newscript->GetAI = &GetAI_mob_iron_sludge;
newscript->RegisterSelf();
}
@@ -0,0 +1,690 @@
#include "ScriptedPch.h"
#include "ScriptedEscortAI.h"
#include "halls_of_stone.h"
enum Texts
{
SAY_KILL_1 = -1603016,
SAY_KILL_2 = -1603017,
SAY_KILL_3 = -1603018,
SAY_LOW_HEALTH = -1603019,
SAY_DEATH = -1603020,
SAY_PLAYER_DEATH_1 = -1603021,
SAY_PLAYER_DEATH_2 = -1603022,
SAY_PLAYER_DEATH_3 = -1603023,
SAY_ESCORT_START = -1603024,
SAY_SPAWN_DWARF = -1603025,
SAY_SPAWN_TROGG = -1603026,
SAY_SPAWN_OOZE = -1603027,
SAY_SPAWN_EARTHEN = -1603028,
SAY_EVENT_INTRO_1 = -1603029,
SAY_EVENT_INTRO_2 = -1603030,
SAY_EVENT_INTRO_3_ABED = -1603031,
SAY_EVENT_A_1 = -1603032,
SAY_EVENT_A_2_KADD = -1603033,
SAY_EVENT_A_3 = -1603034,
SAY_EVENT_B_1 = -1603035,
SAY_EVENT_B_2_MARN = -1603036,
SAY_EVENT_B_3 = -1603037,
SAY_EVENT_C_1 = -1603038,
SAY_EVENT_C_2_ABED = -1603039,
SAY_EVENT_C_3 = -1603040,
SAY_EVENT_D_1 = -1603041,
SAY_EVENT_D_2_ABED = -1603042,
SAY_EVENT_D_3 = -1603043,
SAY_EVENT_D_4_ABED = -1603044,
SAY_EVENT_END_01 = -1603045,
SAY_EVENT_END_02 = -1603046,
SAY_EVENT_END_03_ABED = -1603047,
SAY_EVENT_END_04 = -1603048,
SAY_EVENT_END_05_ABED = -1603049,
SAY_EVENT_END_06 = -1603050,
SAY_EVENT_END_07_ABED = -1603051,
SAY_EVENT_END_08 = -1603052,
SAY_EVENT_END_09_KADD = -1603053,
SAY_EVENT_END_10 = -1603054,
SAY_EVENT_END_11_KADD = -1603055,
SAY_EVENT_END_12 = -1603056,
SAY_EVENT_END_13_KADD = -1603057,
SAY_EVENT_END_14 = -1603058,
SAY_EVENT_END_15_MARN = -1603059,
SAY_EVENT_END_16 = -1603060,
SAY_EVENT_END_17_MARN = -1603061,
SAY_EVENT_END_18 = -1603062,
SAY_EVENT_END_19_MARN = -1603063,
SAY_EVENT_END_20 = -1603064,
SAY_EVENT_END_21_ABED = -1603065,
SAY_VICTORY_SJONNIR_1 = -1603066,
SAY_VICTORY_SJONNIR_2 = -1603067,
SAY_ENTRANCE_MEET = -1603068,
TEXT_ID_START = 13100,
TEXT_ID_PROGRESS = 13101
};
enum BrannCreatures
{
CREATURE_TRIBUNAL_OF_THE_AGES = 28234,
CREATURE_BRANN_BRONZEBEARD = 28070,
CREATURE_DARK_MATTER_TARGET = 28237,
CREATURE_SEARING_GAZE_TARGET = 28265,
CREATURE_DARK_RUNE_PROTECTOR = 27983,
CREATURE_DARK_RUNE_STORMCALLER = 27984,
CREATURE_IRON_GOLEM_CUSTODIAN = 27985,
};
enum Spells
{
SPELL_STEALTH = 58506,
//Kadrak
SPELL_GLARE_OF_THE_TRIBUNAL = 50988,
H_SPELL_GLARE_OF_THE_TRIBUNAL = 59868,
//Marnak
SPELL_DARK_MATTER = 51012,
H_SPELL_DARK_MATTER = 59868,
//Abedneum
SPELL_SEARING_GAZE = 51136,
H_SPELL_SEARING_GAZE = 59867
};
enum Quests
{
QUEST_HALLS_OF_STONE = 13207
};
#define GOSSIP_ITEM_START "Brann, it would be our honor!"
#define GOSSIP_ITEM_PROGRESS "Let's move Brann, enough of the history lessons!"
struct Locations
{
float x, y, z;
};
static Locations SpawnLocations[]=
{
{946.992, 397.016, 208.374},
{960.748, 382.944, 208.374},
};
struct TRINITY_DLL_DECL mob_tribuna_controllerAI : public ScriptedAI
{
mob_tribuna_controllerAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
SetCombatMovement(false);
}
ScriptedInstance* pInstance;
uint32 uiKaddrakEncounterTimer;
uint32 uiMarnakEncounterTimer;
uint32 uiAbedneumEncounterTimer;
bool bKaddrakActivated;
bool bMarnakActivated;
bool bAbedneumActivated;
std::list<Creature*> lKaddrakGUIDList;
void Reset()
{
uiKaddrakEncounterTimer = 1500;
uiMarnakEncounterTimer = 10000;
uiAbedneumEncounterTimer = 10000;
bKaddrakActivated = false;
bMarnakActivated = false;
bAbedneumActivated = false;
lKaddrakGUIDList.clear();
}
void UpdateFacesList()
{
/*GetCreatureListWithEntryInGrid(lKaddrakGUIDList, m_creature, CREATURE_KADDRAK, 50.0f);
if (!lKaddrakGUIDList.empty())
{
uint32 uiPositionCounter = 0;
for (std::list<Creature*>::iterator itr = lKaddrakGUIDList.begin(); itr != lKaddrakGUIDList.end(); ++itr)
{
if ((*itr)->isAlive())
{
if (uiPositionCounter == 0)
{
(*itr)->GetMap()->CreatureRelocation((*itr), 927.265, 333.200, 218.780, (*itr)->GetOrientation());
(*itr)->SendMonsterMove(927.265, 333.200, 218.780, 0, (*itr)->GetMovementFlags(), 1);
}
else
{
(*itr)->GetMap()->CreatureRelocation((*itr), 921.745, 328.076, 218.780, (*itr)->GetOrientation());
(*itr)->SendMonsterMove(921.745, 328.076, 218.780, 0, (*itr)->GetMovementFlags(), 1);
}
}
++uiPositionCounter;
}
}*/
}
void UpdateAI(const uint32 diff)
{
if(bKaddrakActivated)
{
if (uiKaddrakEncounterTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
if (!lKaddrakGUIDList.empty())
for (std::list<Creature*>::iterator itr = lKaddrakGUIDList.begin(); itr != lKaddrakGUIDList.end(); ++itr)
if ((*itr)->isAlive())
(*itr)->CastSpell(pTarget, DUNGEON_MODE(SPELL_GLARE_OF_THE_TRIBUNAL, H_SPELL_GLARE_OF_THE_TRIBUNAL), true);
uiKaddrakEncounterTimer = 1500;
} else uiKaddrakEncounterTimer -= diff;
}
if (bMarnakActivated)
{
if (uiMarnakEncounterTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (Creature* pSummon = m_creature->SummonCreature(CREATURE_DARK_MATTER_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000))
{
pSummon->SetDisplayId(11686);
pSummon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pSummon->CastSpell(pTarget, DUNGEON_MODE(SPELL_DARK_MATTER, H_SPELL_DARK_MATTER), true);
}
}
uiMarnakEncounterTimer = 30000 + rand()%1000;
} else uiMarnakEncounterTimer -= diff;
}
if (bAbedneumActivated)
{
if (uiAbedneumEncounterTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (Creature* pSummon = m_creature->SummonCreature(CREATURE_SEARING_GAZE_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000))
{
pSummon->SetDisplayId(11686);
pSummon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pSummon->CastSpell(pTarget, DUNGEON_MODE(SPELL_SEARING_GAZE, H_SPELL_SEARING_GAZE), true);
}
}
uiAbedneumEncounterTimer = 30000 + rand()%1000;
} else uiAbedneumEncounterTimer -= diff;
}
}
};
struct TRINITY_DLL_DECL npc_brann_hosAI : public npc_escortAI
{
npc_brann_hosAI(Creature *c) : npc_escortAI(c)
{
pInstance = c->GetInstanceData();
}
uint32 uiStep;
uint32 uiPhaseTimer;
uint64 uiControllerGUID;
std::list<uint64> lDwarfGUIDList;
ScriptedInstance* pInstance;
bool bIsBattle;
bool bIsLowHP;
void Reset()
{
if (!HasEscortState(STATE_ESCORT_ESCORTING))
{
bIsLowHP = false;
bIsBattle = false;
uiStep = 0;
uiPhaseTimer = 0;
uiControllerGUID = 0;
DespawnDwarf();
if (pInstance)
pInstance->SetData(DATA_BRANN_EVENT, NOT_STARTED);
}
}
void DespawnDwarf()
{
if (lDwarfGUIDList.empty())
return;
for (std::list<uint64>::iterator itr = lDwarfGUIDList.begin(); itr != lDwarfGUIDList.end(); ++itr)
{
Creature* pTemp = Unit::GetCreature(*m_creature, pInstance ? (*itr) : 0);
if (pTemp && pTemp->isAlive())
pTemp->ForcedDespawn();
}
lDwarfGUIDList.clear();
}
void WaypointReached(uint32 uiPointId)
{
switch(uiPointId)
{
case 7:
if (Creature* pCreature = GetClosestCreatureWithEntry(m_creature, CREATURE_TRIBUNAL_OF_THE_AGES, 100.0f))
{
if (!pCreature->isAlive())
pCreature->Respawn();
CAST_AI(mob_tribuna_controllerAI, pCreature->AI())->UpdateFacesList();
uiControllerGUID = pCreature->GetGUID();
}
break;
case 13:
DoScriptText(SAY_EVENT_INTRO_1, m_creature);
SetEscortPaused(true);
SetRun(true);
JumpToNextStep(20000);
break;
case 17:
DoScriptText(SAY_EVENT_INTRO_2, m_creature);
if (pInstance)
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_TRIBUNAL_CONSOLE),true);
m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
SetEscortPaused(true);
JumpToNextStep(8500);
break;
case 18:
SetEscortPaused(true);
break;
}
}
void SpawnDwarf(uint32 uiType)
{
switch(uiType)
{
case 1:
{
uint32 uiSpawnNumber = DUNGEON_MODE(2,3);
for (uint8 i = 0; i < uiSpawnNumber; ++i)
m_creature->SummonCreature(CREATURE_DARK_RUNE_PROTECTOR, SpawnLocations[0].x, SpawnLocations[0].y, SpawnLocations[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[0].x, SpawnLocations[0].y, SpawnLocations[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
break;
}
case 2:
for (uint8 i = 0; i < 2; ++i)
m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[1].x, SpawnLocations[1].y, SpawnLocations[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
break;
case 3:
m_creature->SummonCreature(CREATURE_IRON_GOLEM_CUSTODIAN, SpawnLocations[1].x, SpawnLocations[1].y, SpawnLocations[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
break;
}
}
void JustSummoned(Creature* pSummoned)
{
lDwarfGUIDList.push_back(pSummoned->GetGUID());
pSummoned->AddThreat(m_creature, 0.0f);
pSummoned->AI()->AttackStart(m_creature);
}
void JumpToNextStep(uint32 uiTimer)
{
uiPhaseTimer = uiTimer;
++uiStep;
}
void StartWP()
{
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
SetEscortPaused(false);
uiStep = 1;
Start();
}
void UpdateEscortAI(const uint32 uiDiff)
{
if (uiPhaseTimer <= uiDiff)
{
switch(uiStep)
{
case 1:
if (pInstance)
{
if (pInstance->GetData(DATA_BRANN_EVENT) != NOT_STARTED)
return;
pInstance->SetData(DATA_BRANN_EVENT, IN_PROGRESS);
}
bIsBattle = false;
DoScriptText(SAY_ESCORT_START, m_creature);
JumpToNextStep(0);
break;
case 3:
SetEscortPaused(false);
JumpToNextStep(0);
break;
case 5:
if (pInstance)
if (Creature* pTemp = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM))))
DoScriptText(SAY_EVENT_INTRO_3_ABED, pTemp);
JumpToNextStep(8500);
break;
case 6:
DoScriptText(SAY_EVENT_A_1, m_creature);
JumpToNextStep(6500);
break;
case 7:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
DoScriptText(SAY_EVENT_A_2_KADD, pTemp);
JumpToNextStep(12500);
break;
case 8:
DoScriptText(SAY_EVENT_A_3, m_creature);
if (pInstance)
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_KADDRAK),true);
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bKaddrakActivated = true;
JumpToNextStep(5000);
break;
case 9:
SpawnDwarf(1);
JumpToNextStep(20000);
break;
case 10:
DoScriptText(SAY_EVENT_B_1, m_creature);
JumpToNextStep(6000);
break;
case 11:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
DoScriptText(SAY_EVENT_B_2_MARN, pTemp);
SpawnDwarf(1);
JumpToNextStep(20000);
break;
case 12:
DoScriptText(SAY_EVENT_B_3, m_creature);
if (pInstance)
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_MARNAK),true);
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bMarnakActivated = true;
JumpToNextStep(10000);
break;
case 13:
SpawnDwarf(1);
JumpToNextStep(10000);
break;
case 14:
SpawnDwarf(2);
JumpToNextStep(20000);
break;
case 15:
DoScriptText(SAY_EVENT_C_1, m_creature);
SpawnDwarf(1);
JumpToNextStep(10000);
break;
case 16:
SpawnDwarf(2);
JumpToNextStep(20000);
break;
case 17:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
DoScriptText(SAY_EVENT_C_2_ABED, pTemp);
SpawnDwarf(1);
JumpToNextStep(20000);
break;
case 18:
DoScriptText(SAY_EVENT_C_3, m_creature);
if (pInstance)
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_ABEDNEUM),true);
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bAbedneumActivated = true;
JumpToNextStep(5000);
break;
case 19:
SpawnDwarf(2);
JumpToNextStep(10000);
break;
case 20:
SpawnDwarf(1);
JumpToNextStep(15000);
break;
case 21:
DoScriptText(SAY_EVENT_D_1, m_creature);
SpawnDwarf(3);
JumpToNextStep(20000);
break;
case 22:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
DoScriptText(SAY_EVENT_D_2_ABED, pTemp);
SpawnDwarf(1);
JumpToNextStep(5000);
break;
case 23:
SpawnDwarf(2);
JumpToNextStep(15000);
break;
case 24:
DoScriptText(SAY_EVENT_D_3, m_creature);
SpawnDwarf(3);
JumpToNextStep(5000);
break;
case 25:
SpawnDwarf(1);
JumpToNextStep(5000);
break;
case 26:
SpawnDwarf(2);
JumpToNextStep(10000);
break;
case 27:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
DoScriptText(SAY_EVENT_D_4_ABED, pTemp);
SpawnDwarf(1);
JumpToNextStep(10000);
break;
case 28:
DoScriptText(SAY_EVENT_END_01, m_creature);
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
if (pInstance)
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_SKY_FLOOR),true);
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
bIsBattle = true;
SetEscortPaused(false);
JumpToNextStep(6500);
break;
case 29:
DoScriptText(SAY_EVENT_END_02, m_creature);
JumpToNextStep(5500);
break;
case 30:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
DoScriptText(SAY_EVENT_END_03_ABED, pTemp);
JumpToNextStep(8500);
break;
case 31:
DoScriptText(SAY_EVENT_END_04, m_creature);
JumpToNextStep(11500);
break;
case 32:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
DoScriptText(SAY_EVENT_END_05_ABED, pTemp);
JumpToNextStep(11500);
break;
case 33:
DoScriptText(SAY_EVENT_END_06, m_creature);
JumpToNextStep(4500);
break;
case 34:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
DoScriptText(SAY_EVENT_END_07_ABED, pTemp);
JumpToNextStep(22500);
break;
case 35:
DoScriptText(SAY_EVENT_END_08, m_creature);
JumpToNextStep(7500);
break;
case 36:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
DoScriptText(SAY_EVENT_END_09_KADD, pTemp);
JumpToNextStep(18500);
break;
case 37:
DoScriptText(SAY_EVENT_END_10, m_creature);
JumpToNextStep(5500);
break;
case 38:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
DoScriptText(SAY_EVENT_END_11_KADD, pTemp);
JumpToNextStep(20500);
break;
case 39:
DoScriptText(SAY_EVENT_END_12, m_creature);
JumpToNextStep(2500);
break;
case 40:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
DoScriptText(SAY_EVENT_END_13_KADD, pTemp);
JumpToNextStep(19500);
break;
case 41:
DoScriptText(SAY_EVENT_END_14, m_creature);
JumpToNextStep(10500);
break;
case 42:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
DoScriptText(SAY_EVENT_END_15_MARN, pTemp);
JumpToNextStep(6500);
break;
case 43:
DoScriptText(SAY_EVENT_END_16, m_creature);
JumpToNextStep(6500);
break;
case 44:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
DoScriptText(SAY_EVENT_END_17_MARN, pTemp);
JumpToNextStep(25500);
break;
case 45:
DoScriptText(SAY_EVENT_END_18, m_creature);
JumpToNextStep(23500);
break;
case 46:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
DoScriptText(SAY_EVENT_END_19_MARN, pTemp);
JumpToNextStep(3500);
break;
case 47:
DoScriptText(SAY_EVENT_END_20, m_creature);
JumpToNextStep(8500);
break;
case 48:
if (pInstance)
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
DoScriptText(SAY_EVENT_END_21_ABED, pTemp);
JumpToNextStep(5500);
break;
case 49:
{
if (pInstance)
{
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_KADDRAK),true);
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_MARNAK),true);
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_ABEDNEUM),true);
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_SKY_FLOOR),true);
pInstance->SetData(DATA_BRANN_EVENT, DONE);
}
Player* pPlayer = GetPlayerForEscort();
if (pPlayer)
pPlayer->GroupEventHappens(QUEST_HALLS_OF_STONE, m_creature);
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
JumpToNextStep(180000);
break;
}
case 50:
SetEscortPaused(false);
break;
}
} else uiPhaseTimer -= uiDiff;
if (!bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 30)
{
DoScriptText(SAY_LOW_HEALTH, m_creature);
bIsLowHP = true;
} else if (bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 30)
bIsLowHP = false;
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
bool GossipHello_npc_brann_hos(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_brann_hos(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1 || uiAction == GOSSIP_ACTION_INFO_DEF+2)
{
pPlayer->CLOSE_GOSSIP_MENU();
CAST_AI(npc_brann_hosAI, pCreature->AI())->StartWP();
}
return true;
}
CreatureAI* GetAI_mob_tribuna_controller(Creature* pCreature)
{
return new mob_tribuna_controllerAI(pCreature);
}
CreatureAI* GetAI_npc_brann_hos(Creature* pCreature)
{
return new npc_brann_hosAI(pCreature);
}
void AddSC_halls_of_stone()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_brann_hos";
newscript->GetAI = &GetAI_npc_brann_hos;
newscript->pGossipHello = &GossipHello_npc_brann_hos;
newscript->pGossipSelect = &GossipSelect_npc_brann_hos;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_tribuna_controller";
newscript->GetAI = &GetAI_mob_tribuna_controller;
newscript->RegisterSelf();
}
@@ -0,0 +1,48 @@
#ifndef DEF_HALLS_OF_STONE_H
#define DEF_HALLS_OF_STONE_H
enum Data
{
DATA_KRYSTALLUS_EVENT,
DATA_MAIDEN_OF_GRIEF_EVENT,
DATA_SJONNIR_EVENT,
DATA_BRANN_EVENT
};
enum Data64
{
DATA_KRYSTALLUS,
DATA_MAIDEN_OF_GRIEF,
DATA_SJONNIR,
DATA_KADDRAK,
DATA_MARNAK,
DATA_ABEDNEUM,
DATA_GO_TRIBUNAL_CONSOLE,
DATA_GO_KADDRAK,
DATA_GO_MARNAK,
DATA_GO_ABEDNEUM,
DATA_GO_SKY_FLOOR,
DATA_SJONNIR_DOOR,
DATA_MAIDEN_DOOR
};
enum Creatures
{
CREATURE_MAIDEN = 27975,
CREATURE_KRYSTALLUS = 27977,
CREATURE_SJONNIR = 27978,
CREATURE_MARNAK = 30897,
CREATURE_KADDRAK = 30898,
CREATURE_ABEDNEUM = 30899,
CREATURE_BRANN = 28070
};
enum GameObjects
{
GO_ABEDNEUM = 191669,
GO_MARNAK = 192170,
GO_KADDRAK = 192171,
GO_MAIDEN_DOOR = 191292,
GO_BRANN_DOOR = 191295,
GO_SJONNIR_DOOR = 191296,
GO_TRIBUNAL_CONSOLE = 193907,
GO_TRIBUNAL_CHEST = 190586,
GO_TRIBUNAL_CHEST_HERO = 193996
};
#endif
@@ -0,0 +1,254 @@
#include "ScriptedPch.h"
#include "halls_of_stone.h"
#define MAX_ENCOUNTER 4
/* Halls of Stone encounters:
0- Krystallus
1- Maiden of Grief
2- Escort Event
3- Sjonnir The Ironshaper
*/
struct TRINITY_DLL_DECL instance_halls_of_stone : public ScriptedInstance
{
instance_halls_of_stone(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
uint64 uiMaidenOfGrief;
uint64 uiKrystallus;
uint64 uiSjonnir;
uint64 uiKaddrak;
uint64 uiAbedneum;
uint64 uiMarnak;
uint64 uiBrann;
uint64 uiMaidenOfGriefDoor;
uint64 uiSjonnirDoor;
uint64 uiBrannDoor;
uint64 uiTribunalConsole;
uint64 uiTribunalChest;
uint64 uiTribunalSkyFloor;
uint64 uiKaddrakGo;
uint64 uiAbedneumGo;
uint64 uiMarnakGo;
uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string str_data;
void Initialize()
{
uiMaidenOfGrief = 0;
uiKrystallus = 0;
uiSjonnir = 0;
uiKaddrak = 0;
uiMarnak = 0;
uiAbedneum = 0;
uiBrann = 0;
uiMaidenOfGriefDoor = 0;
uiSjonnirDoor = 0;
uiBrannDoor = 0;
uiKaddrakGo = 0;
uiMarnakGo = 0;
uiAbedneumGo = 0;
uiTribunalConsole = 0;
uiTribunalChest = 0;
uiTribunalSkyFloor = 0;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
m_auiEncounter[i] = NOT_STARTED;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
{
case CREATURE_MAIDEN: uiMaidenOfGrief = pCreature->GetGUID(); break;
case CREATURE_KRYSTALLUS: uiKrystallus = pCreature->GetGUID(); break;
case CREATURE_SJONNIR: uiSjonnir = pCreature->GetGUID(); break;
case CREATURE_MARNAK: uiMarnak = pCreature->GetGUID(); break;
case CREATURE_KADDRAK: uiKaddrak = pCreature->GetGUID(); break;
case CREATURE_ABEDNEUM: uiAbedneum = pCreature->GetGUID(); break;
case CREATURE_BRANN: uiBrann = pCreature->GetGUID(); break;
}
}
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch(pGo->GetEntry())
{
case GO_ABEDNEUM:
uiAbedneumGo = pGo->GetGUID();
break;
case GO_MARNAK:
uiMarnakGo = pGo->GetGUID();
break;
case GO_KADDRAK:
uiKaddrakGo = pGo->GetGUID();
break;
case GO_MAIDEN_DOOR:
uiMaidenOfGriefDoor = pGo->GetGUID();
if (m_auiEncounter[0] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
else
pGo->SetGoState(GO_STATE_READY);
break;
case GO_BRANN_DOOR:
uiBrannDoor = pGo->GetGUID();
if (m_auiEncounter[1] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
else
pGo->SetGoState(GO_STATE_READY);
break;
case GO_SJONNIR_DOOR:
uiSjonnirDoor = pGo->GetGUID();
if (m_auiEncounter[2] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
else
pGo->SetGoState(GO_STATE_READY);
break;
case GO_TRIBUNAL_CONSOLE:
uiTribunalConsole = pGo->GetGUID();
break;
case GO_TRIBUNAL_CHEST:
case GO_TRIBUNAL_CHEST_HERO:
uiTribunalChest = pGo->GetGUID();
if (m_auiEncounter[2] == DONE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
break;
case 191527:
uiTribunalSkyFloor = pGo->GetGUID();
break;
}
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_MAIDEN_OF_GRIEF_EVENT:
m_auiEncounter[1] = data;
if (m_auiEncounter[1] == DONE)
HandleGameObject(uiBrannDoor,true);
break;
case DATA_KRYSTALLUS_EVENT:
m_auiEncounter[0] = data;
if (m_auiEncounter[0] == DONE)
HandleGameObject(uiMaidenOfGriefDoor,true);
break;
case DATA_SJONNIR_EVENT:
m_auiEncounter[3] = data;
break;
case DATA_BRANN_EVENT:
m_auiEncounter[2] = data;
if (m_auiEncounter[2] == DONE)
{
HandleGameObject(uiSjonnirDoor,true);
GameObject *pGo = instance->GetGameObject(uiTribunalChest);
if (pGo)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
}
break;
}
if (data == DONE)
SaveToDB();
}
uint32 GetData(uint32 type)
{
switch(type)
{
case DATA_KRYSTALLUS_EVENT: return m_auiEncounter[0];
case DATA_MAIDEN_OF_GRIEF_EVENT: return m_auiEncounter[1];
case DATA_SJONNIR_EVENT: return m_auiEncounter[2];
case DATA_BRANN_EVENT: return m_auiEncounter[3];
}
return 0;
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_MAIDEN_OF_GRIEF: return uiMaidenOfGrief;
case DATA_KRYSTALLUS: return uiKrystallus;
case DATA_SJONNIR: return uiSjonnir;
case DATA_KADDRAK: return uiKaddrak;
case DATA_MARNAK: return uiMarnak;
case DATA_ABEDNEUM: return uiAbedneum;
case DATA_GO_TRIBUNAL_CONSOLE: return uiTribunalConsole;
case DATA_GO_KADDRAK: return uiKaddrakGo;
case DATA_GO_ABEDNEUM: return uiAbedneumGo;
case DATA_GO_MARNAK: return uiMarnakGo;
case DATA_GO_SKY_FLOOR: return uiTribunalSkyFloor;
case DATA_SJONNIR_DOOR: return uiSjonnirDoor;
case DATA_MAIDEN_DOOR: return uiMaidenOfGriefDoor;
}
return 0;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "H S " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in)
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
if (dataHead1 == 'H' && dataHead2 == 'S')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
m_auiEncounter[3] = data3;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_halls_of_stone(Map* pMap)
{
return new instance_halls_of_stone(pMap);
}
void AddSC_instance_halls_of_stone()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_halls_of_stone";
newscript->GetInstanceData = &GetInstanceData_instance_halls_of_stone;
newscript->RegisterSelf();
}
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
@@ -0,0 +1,560 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Assembly of Iron encounter
SD%Complete: 60%
SDComment: Runes need DB support, chain lightning won't cast, supercharge won't cast (pTarget error?) - it worked before during debugging.
SDCategory: Ulduar - Ulduar
EndScriptData */
#include "ScriptedPch.h"
#include "ulduar.h"
// Any boss
#define SPELL_SUPERCHARGE 61920
#define SPELL_BERSERK 47008 // Hard enrage, don't know the correct ID.
// Steelbreaker
#define SPELL_HIGH_VOLTAGE 61890
#define SPELL_HIGH_VOLTAGE_H 63498
#define SPELL_FUSION_PUNCH 61903
#define SPELL_FUSION_PUNCH_H 63493
#define SPELL_STATIC_DISRUPTION 44008
#define SPELL_STATIC_DISRUPTION_H 63494
#define SPELL_OVERWHELMING_POWER_H 61888
#define SPELL_OVERWHELMING_POWER 64637
#define SPELL_ELECTRICAL_CHARGE 61902
// Runemaster Molgeim
#define SPELL_SHIELD_OF_RUNES 62274
#define SPELL_SHIELD_OF_RUNES_H 63489
#define SPELL_RUNE_OF_POWER 64320
#define SPELL_RUNE_OF_DEATH 62269
#define SPELL_RUNE_OF_SUMMONING 62273
#define SPELL_LIGHTNING_BLAST 62054
#define SPELL_LIGHTNING_BLAST_H 63491
#define CREATURE_RUNE_OF_SUMMONING 33051
// Stormcaller Brundir
#define SPELL_CHAIN_LIGHTNING_N 61879
#define SPELL_CHAIN_LIGHTNING_H 63479
#define SPELL_OVERLOAD 61869
#define SPELL_OVERLOAD_H 63481
#define SPELL_LIGHTNING_WHIRL 61915
#define SPELL_LIGHTNING_WHIRL_H 63483
#define SPELL_LIGHTNING_TENDRILS 61887
#define SPELL_LIGHTNING_TENDRILS_H 63486
#define SPELL_STORMSHIELD 64187
enum eEnums
{
EVENT_ENRAGE,
// Steelbreaker
EVENT_FUSION_PUNCH,
EVENT_STATIC_DISRUPTION,
EVENT_OVERWHELMING_POWER,
// Molgeim
EVENT_RUNE_OF_POWER,
EVENT_SHIELD_OF_RUNES,
EVENT_RUNE_OF_DEATH,
EVENT_RUNE_OF_SUMMONING,
EVENT_LIGHTNING_BLAST,
// Brundir
EVENT_CHAIN_LIGHTNING,
EVENT_OVERLOAD,
EVENT_LIGHTNING_WHIRL,
EVENT_LIGHTNING_TENDRILS,
EVENT_STORMSHIELD,
MAX_EVENT
};
bool IsEncounterComplete(ScriptedInstance* pInstance, Creature* m_creature)
{
if (!pInstance || !m_creature)
return false;
for (uint8 i = 0; i < 3; ++i)
{
uint64 guid = pInstance->GetData64(DATA_STEELBREAKER+i);
if(!guid)
return false;
if(Creature *boss = (Unit::GetCreature((*m_creature), guid)))
{
if(boss->isAlive())
return false;
continue;
}
else
return false;
}
return true;
}
struct TRINITY_DLL_DECL boss_steelbreakerAI : public ScriptedAI
{
boss_steelbreakerAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
void Reset()
{
events.Reset();
phase = 0;
m_creature->RemoveAllAuras();
if(pInstance)
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
}
EventMap events;
ScriptedInstance* pInstance;
uint32 phase;
void EnterCombat(Unit *who)
{
DoZoneInCombat();
DoCast(m_creature, RAID_MODE(SPELL_HIGH_VOLTAGE, SPELL_HIGH_VOLTAGE_H));
events.ScheduleEvent(EVENT_ENRAGE, 900000);
UpdatePhase();
}
void UpdatePhase()
{
++phase;
events.SetPhase(phase);
events.RescheduleEvent(EVENT_FUSION_PUNCH, 15000);
if(phase >= 2)
events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 30000);
if(phase >= 3)
events.RescheduleEvent(EVENT_OVERWHELMING_POWER, rand()%5000);
}
void DamageTaken(Unit* pKiller, uint32 &damage)
{
if(damage >= m_creature->GetHealth())
{
if(Creature* Brundir = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_STORMCALLER_BRUNDIR) : 0))
if(Brundir->isAlive())
{
Brundir->SetHealth(Brundir->GetMaxHealth());
}
if(Creature* Molgeim = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_RUNEMASTER_MOLGEIM) : 0))
if(Molgeim->isAlive())
{
Molgeim->SetHealth(Molgeim->GetMaxHealth());
}
DoCast(SPELL_SUPERCHARGE);
}
}
void JustDied(Unit* Killer)
{
if(IsEncounterComplete(pInstance, m_creature) && pInstance)
pInstance->SetData(TYPE_ASSEMBLY, DONE);
}
void KilledUnit(Unit *who)
{
if(phase == 3)
DoCast(m_creature, SPELL_ELECTRICAL_CHARGE);
}
void SpellHit(Unit *from, const SpellEntry *spell)
{
if(spell->Id == SPELL_SUPERCHARGE)
UpdatePhase();
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_ENRAGE:
DoCast(SPELL_BERSERK);
break;
case EVENT_FUSION_PUNCH:
DoCast(me->getVictim(), RAID_MODE(SPELL_FUSION_PUNCH_H, SPELL_FUSION_PUNCH));
events.ScheduleEvent(EVENT_FUSION_PUNCH, 13000 + (rand()%9)*1000);
break;
case EVENT_STATIC_DISRUPTION:
{
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM);
DoCast(pTarget, RAID_MODE(SPELL_STATIC_DISRUPTION_H, SPELL_STATIC_DISRUPTION));
events.ScheduleEvent(EVENT_STATIC_DISRUPTION, 20000 + (rand()%20)*1000);
}
break;
case EVENT_OVERWHELMING_POWER:
DoCast(me->getVictim(), RAID_MODE(SPELL_OVERWHELMING_POWER, SPELL_OVERWHELMING_POWER_H));
events.ScheduleEvent(EVENT_OVERWHELMING_POWER, RAID_MODE(60000, 35000));
break;
}
}
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL boss_runemaster_molgeimAI : public ScriptedAI
{
boss_runemaster_molgeimAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
void Reset()
{
if(pInstance)
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
events.Reset();
m_creature->RemoveAllAuras();
phase = 0;
}
ScriptedInstance* pInstance;
EventMap events;
uint32 phase;
void EnterCombat(Unit* who)
{
DoZoneInCombat();
events.ScheduleEvent(EVENT_ENRAGE, 900000);
UpdatePhase();
}
void UpdatePhase()
{
++phase;
events.SetPhase(phase);
events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000);
events.RescheduleEvent(EVENT_RUNE_OF_POWER, 60000);
if(phase >= 2)
events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000);
if(phase >= 3)
events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, 20000+(rand()%10)*1000);
}
void DamageTaken(Unit* pKiller, uint32 &damage)
{
if(damage >= m_creature->GetHealth())
{
if(Creature* Steelbreaker = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_STEELBREAKER) : 0))
if(Steelbreaker->isAlive())
{
Steelbreaker->SetHealth(Steelbreaker->GetMaxHealth());
}
if(Creature* Brundir = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_STORMCALLER_BRUNDIR) : 0))
if(Brundir->isAlive())
{
Brundir->SetHealth(Brundir->GetMaxHealth());
}
DoCast(m_creature, SPELL_SUPERCHARGE);
}
}
void JustDied(Unit* Killer)
{
if(IsEncounterComplete(pInstance, m_creature) && pInstance)
pInstance->SetData(TYPE_ASSEMBLY, DONE);
}
void SpellHit(Unit *from, const SpellEntry *spell)
{
if(spell->Id == SPELL_SUPERCHARGE)
UpdatePhase();
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_ENRAGE:
DoCast(SPELL_BERSERK);
break;
case EVENT_RUNE_OF_POWER: // Improve target selection; random alive friendly
{
Unit *Target = DoSelectLowestHpFriendly(60);
if(!Target || (Target && !Target->isAlive()))
Target = m_creature;
DoCast(Target, SPELL_RUNE_OF_POWER);
events.ScheduleEvent(EVENT_RUNE_OF_POWER, 60000);
}
break;
case EVENT_SHIELD_OF_RUNES:
DoCast(m_creature, RAID_MODE(SPELL_SHIELD_OF_RUNES, SPELL_SHIELD_OF_RUNES_H));
events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, 27000+ (rand()%7)*1000);
break;
case EVENT_RUNE_OF_DEATH:
{
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM);
DoCast(pTarget, SPELL_RUNE_OF_DEATH);
events.ScheduleEvent(EVENT_RUNE_OF_DEATH, 30000+ (rand()%10)*1000);
}
break;
case EVENT_RUNE_OF_SUMMONING:
{
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM);
DoCast(pTarget, SPELL_RUNE_OF_SUMMONING);
events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, 20000+(rand()%10)*1000);
}
break;
}
}
DoMeleeAttackIfReady();
}
};
struct TRINITY_DLL_DECL mob_lightning_elementalAI : public ScriptedAI
{
mob_lightning_elementalAI(Creature *c) : ScriptedAI(c)
{
Charge();
}
Unit* Target;
void Charge()
{
Target = m_creature->SelectNearestTarget();
m_creature->AddThreat(Target, 5000000.0f);
AttackStart(Target);
}
void UpdateAI(const uint32 diff)
{
if(!m_creature->isInCombat())
return;
if(m_creature->IsWithinMeleeRange(Target))
{
DoCast(Target, RAID_MODE(SPELL_LIGHTNING_BLAST, SPELL_LIGHTNING_BLAST_H));
m_creature->Kill(m_creature); // hack until spell works
}
m_creature->GetMotionMaster()->MoveChase(Target); // needed at every update?
}
};
struct TRINITY_DLL_DECL mob_rune_of_summoningAI : public ScriptedAI
{
mob_rune_of_summoningAI(Creature *c) : ScriptedAI(c)
{
SummonLightningElemental();
}
void SummonLightningElemental()
{
m_creature->SummonCreature(CREATURE_RUNE_OF_SUMMONING, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN );
m_creature->DealDamage(m_creature, m_creature->GetHealth());
}
};
struct TRINITY_DLL_DECL boss_stormcaller_brundirAI : public ScriptedAI
{
boss_stormcaller_brundirAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
void Reset()
{
if(pInstance)
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
m_creature->RemoveAllAuras();
events.Reset();
phase = 0;
}
EventMap events;
ScriptedInstance* pInstance;
uint32 phase;
void EnterCombat(Unit* who)
{
DoZoneInCombat();
events.ScheduleEvent(EVENT_ENRAGE, 900000);
UpdatePhase();
}
void UpdatePhase()
{
++phase;
events.SetPhase(phase);
events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, 9000+ (rand()%8)*1000);
events.RescheduleEvent(EVENT_OVERLOAD, 60000+ (rand()%65)*1000);
if(phase >= 2)
events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, 20000+ (rand()%20)*1000);
if(phase >= 3)
{
DoCast(m_creature, SPELL_STORMSHIELD);
events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, 40000+ (rand()%40)*1000);
}
}
void DamageTaken(Unit* pKiller, uint32 &damage)
{
if(damage >= m_creature->GetHealth())
{
if(Creature* Steelbreaker = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_STEELBREAKER) : 0))
if(Steelbreaker->isAlive())
{
Steelbreaker->SetHealth(Steelbreaker->GetMaxHealth());
}
if(Creature* Molgeim = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_RUNEMASTER_MOLGEIM) : 0))
if(Molgeim->isAlive())
{
Molgeim->SetHealth(Molgeim->GetMaxHealth());
}
DoCast(SPELL_SUPERCHARGE);
}
}
void JustDied(Unit* Killer)
{
if(IsEncounterComplete(pInstance, m_creature) && pInstance)
pInstance->SetData(TYPE_ASSEMBLY, DONE);
}
void SpellHit(Unit *from, const SpellEntry *spell)
{
if(spell->Id == SPELL_SUPERCHARGE)
{
UpdatePhase();
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_ENRAGE:
DoCast(SPELL_BERSERK);
break;
case EVENT_CHAIN_LIGHTNING:
{
Unit* Target = SelectUnit(SELECT_TARGET_RANDOM,0);
DoCast(Target, RAID_MODE(SPELL_CHAIN_LIGHTNING_N , SPELL_CHAIN_LIGHTNING_H));
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 9000+ (rand()%8)*1000);
}
break;
case EVENT_OVERLOAD:
DoCast(RAID_MODE(SPELL_OVERLOAD , SPELL_OVERLOAD_H));
events.ScheduleEvent(EVENT_OVERLOAD, 60000+ (rand()%65)*1000);
break;
case EVENT_LIGHTNING_WHIRL:
DoCast(RAID_MODE(SPELL_LIGHTNING_WHIRL , SPELL_LIGHTNING_WHIRL_H));
events.ScheduleEvent(EVENT_LIGHTNING_WHIRL, 20000+ (rand()%20)*1000);
break;
case EVENT_LIGHTNING_TENDRILS:
DoCast(RAID_MODE(SPELL_LIGHTNING_TENDRILS, SPELL_LIGHTNING_TENDRILS_H));
events.DelayEvents(15000, 5000);
DoResetThreat();
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_steelbreaker(Creature* pCreature)
{
return new boss_steelbreakerAI (pCreature);
}
CreatureAI* GetAI_boss_runemaster_molgeim(Creature* pCreature)
{
return new boss_runemaster_molgeimAI (pCreature);
}
CreatureAI* GetAI_boss_stormcaller_brundir(Creature* pCreature)
{
return new boss_stormcaller_brundirAI (pCreature);
}
CreatureAI* GetAI_mob_lightning_elemental(Creature* pCreature)
{
return new mob_lightning_elementalAI (pCreature);
}
CreatureAI* GetAI_mob_rune_of_summoning(Creature* pCreature)
{
return new mob_rune_of_summoningAI (pCreature);
}
void AddSC_boss_assembly_of_iron()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_steelbreaker";
newscript->GetAI = &GetAI_boss_steelbreaker;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_runemaster_molgeim";
newscript->GetAI = &GetAI_boss_runemaster_molgeim;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_stormcaller_brundir";
newscript->GetAI = &GetAI_boss_stormcaller_brundir;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_lightning_elemental";
newscript->GetAI = &GetAI_mob_lightning_elemental;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_rune_of_summoning";
newscript->GetAI = &GetAI_mob_rune_of_summoning;
newscript->RegisterSelf();
}
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
//boss_auriaya
#define SPELL_TERRIFYING_SCREECH 64386
#define SPELL_SETINEL_BLAST 64679
#define SPELL_SONIC_SCREECH 64422
#define SPELL_SUMMON_SWARMING_GUARDIAN 64397
//wrong text ids. correct are beetwen -1000000 AND -1999999
//beetwen -2000000 and -2999999 are custom texts so wtf?
#define SAY_AGGRO -2615016
#define SAY_SLAY_1 -2615017
struct TRINITY_DLL_DECL boss_auriaya_AI : public BossAI
{
boss_auriaya_AI(Creature *pCreature) : BossAI(pCreature, TYPE_AURIAYA)
{
m_pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
uint32 TERRIFYING_SCREECH_Timer;
uint32 SONIC_SCREECH_Timer;
void Reset()
{
TERRIFYING_SCREECH_Timer = 180000;
SONIC_SCREECH_Timer = 30000;
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO,m_creature);
}
void KilledUnit(Unit* victim)
{
DoScriptText(SAY_SLAY_1, m_creature);
}
void JustDied(Unit *victim)
{
DoScriptText(SAY_SLAY_1, m_creature);
if (m_pInstance)
m_pInstance->SetData(TYPE_AURIAYA, DONE);
}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (TERRIFYING_SCREECH_Timer <= diff)
{
DoCast(SPELL_TERRIFYING_SCREECH);
DoScriptText(SAY_SLAY_1, m_creature);
TERRIFYING_SCREECH_Timer = 180000;
} else TERRIFYING_SCREECH_Timer -= diff;
if (SONIC_SCREECH_Timer <= diff)
{
DoCastVictim(SPELL_SONIC_SCREECH);
SONIC_SCREECH_Timer = 30000;
} else SONIC_SCREECH_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_auriaya(Creature* pCreature)
{
return new boss_auriaya_AI (pCreature);
}
void AddSC_boss_auriaya()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_auriaya";
newscript->GetAI = &GetAI_boss_auriaya;
newscript->RegisterSelf();
}
@@ -0,0 +1,395 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
#include "Vehicle.h"
#define SPELL_PURSUED 62374
#define SPELL_GATHERING_SPEED 62375
#define SPELL_BATTERING_RAM 62376
#define SPELL_FLAME_VENTS 62396
#define SPELL_MISSILE_BARRAGE 62400
#define SPELL_SYSTEMS_SHUTDOWN 62475
#define SPELL_FLAME_CANNON 62395
//#define SPELL_FLAME_CANNON 64692 trigger the same spell
#define SPELL_OVERLOAD_CIRCUIT 62399
#define SPELL_SEARING_FLAME 62402
#define SPELL_BLAZE 62292
#define SPELL_SMOKE_TRAIL 63575
#define SPELL_MIMIRON_INFERNO 62910
#define SPELL_HODIR_FURY 62297
#define SPELL_ELECTROSHOCK 62522
enum Mobs
{
MOB_MECHANOLIFT = 33214,
MOB_LIQUID = 33189,
MOB_CONTAINER = 33218,
};
enum Events
{
EVENT_PURSUE = 1,
EVENT_MISSILE,
EVENT_VENT,
EVENT_SPEED,
EVENT_SUMMON,
EVENT_MIMIRON_INFERNO, // Not Blizzlike
EVENT_HODIR_FURY, // Not Blizzlike
};
enum Seats
{
SEAT_PLAYER = 0,
SEAT_TURRET = 1,
SEAT_DEVICE = 2,
};
struct TRINITY_DLL_DECL boss_flame_leviathanAI : public BossAI
{
boss_flame_leviathanAI(Creature *pCreature) : BossAI(pCreature, TYPE_LEVIATHAN), vehicle(me->GetVehicleKit())
{
m_pInstance = pCreature->GetInstanceData();
assert(vehicle);
}
ScriptedInstance* m_pInstance;
Vehicle *vehicle;
void Reset()
{
_Reset();
me->SetReactState(REACT_AGGRESSIVE);
}
void EnterCombat(Unit *who)
{
_EnterCombat();
me->SetReactState(REACT_DEFENSIVE);
events.ScheduleEvent(EVENT_PURSUE, 0);
events.ScheduleEvent(EVENT_MISSILE, 1500);
events.ScheduleEvent(EVENT_VENT, 20000);
events.ScheduleEvent(EVENT_SPEED, 15000);
events.ScheduleEvent(EVENT_SUMMON, 0);
//events.ScheduleEvent(EVENT_MIMIRON_INFERNO, 60000 + (rand()%60000)); // Not Blizzlike
//events.ScheduleEvent(EVENT_HODIR_FURY, 60000 + (rand()%60000)); // Not Blizzlike
if (Creature *turret = CAST_CRE(vehicle->GetPassenger(7)))
turret->AI()->DoZoneInCombat();
}
// TODO: effect 0 and effect 1 may be on different target
void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
{
if (spell->Id == SPELL_PURSUED)
AttackStart(pTarget);
}
void JustDied(Unit *victim)
{
if (m_pInstance)
m_pInstance->SetData(TYPE_LEVIATHAN, DONE);
}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
if(spell->Id == 62472)
vehicle->InstallAllAccessories();
else if(spell->Id == SPELL_ELECTROSHOCK)
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
}
void UpdateAI(const uint32 diff)
{
if (!me->isInCombat())
return;
if (me->getThreatManager().isThreatListEmpty())
{
EnterEvadeMode();
return;
}
events.Update(diff);
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
uint32 eventId = events.GetEvent();
if (!me->getVictim())
eventId = EVENT_PURSUE;
switch(eventId)
{
case 0: break; // this is a must
case EVENT_PURSUE:
DoCastAOE(SPELL_PURSUED, true);
//events.RepeatEvent(35000); // this should not be used because eventId may be overriden
events.RescheduleEvent(EVENT_PURSUE, 35000);
if(!me->getVictim()) // all siege engines and demolishers are dead
UpdateVictim(); // begin to kill other things
return;
case EVENT_MISSILE:
//TODO: without target no visual effect
//DoCastAOE(SPELL_MISSILE_BARRAGE);
DoCast(me->getVictim(), SPELL_MISSILE_BARRAGE);
events.RepeatEvent(1500);
return;
case EVENT_VENT:
DoCastAOE(SPELL_FLAME_VENTS);
events.RepeatEvent(20000);
return;
case EVENT_SPEED:
DoCastAOE(SPELL_GATHERING_SPEED);
events.RepeatEvent(15000);
return;
case EVENT_SUMMON:
if(summons.size() < 15) // 4seat+1turret+10lift
if(Creature *lift = DoSummonFlyer(MOB_MECHANOLIFT, me, rand()%20 + 20, 50, 0))
lift->GetMotionMaster()->MoveRandom(100);
events.RepeatEvent(2000);
return;
case EVENT_MIMIRON_INFERNO: // Not Blizzlike
DoCast(me->getVictim(), SPELL_MIMIRON_INFERNO);
events.RepeatEvent(60000 + (rand()%60000));
return;
case EVENT_HODIR_FURY: // Not Blizzlike
DoCast(me->getVictim(), SPELL_HODIR_FURY);
events.RepeatEvent(60000 + (rand()%60000));
default:
events.PopEvent();
break;
}
DoSpellAttackIfReady(SPELL_BATTERING_RAM);
}
};
//#define BOSS_DEBUG
struct TRINITY_DLL_DECL boss_flame_leviathan_seatAI : public PassiveAI
{
boss_flame_leviathan_seatAI(Creature *c) : PassiveAI(c), vehicle(c->GetVehicleKit())
{
assert(vehicle);
#ifdef BOSS_DEBUG
me->SetReactState(REACT_AGGRESSIVE);
#endif
}
Vehicle *vehicle;
#ifdef BOSS_DEBUG
void MoveInLineOfSight(Unit *who)
{
if(who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->isGameMaster()
&& !who->GetVehicle() && vehicle->GetPassenger(SEAT_TURRET))
who->EnterVehicle(vehicle, SEAT_PLAYER);
}
#endif
void PassengerBoarded(Unit *who, int8 seatId, bool apply)
{
if(!me->GetVehicle())
return;
if(seatId == SEAT_PLAYER)
{
if(!apply)
return;
if(Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
{
turret->setFaction(me->GetVehicleBase()->getFaction());
turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
turret->AI()->AttackStart(who);
}
if(Unit *device = vehicle->GetPassenger(SEAT_DEVICE))
{
device->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
device->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
}
else if(seatId == SEAT_TURRET)
{
if(apply)
return;
if(Unit *device = vehicle->GetPassenger(SEAT_DEVICE))
{
device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
}
}
}
};
struct TRINITY_DLL_DECL boss_flame_leviathan_defense_turretAI : public TurretAI
{
boss_flame_leviathan_defense_turretAI(Creature *c) : TurretAI(c) {}
void DamageTaken(Unit *who, uint32 &damage)
{
if(!CanAIAttack(who))
damage = 0;
}
bool CanAIAttack(const Unit *who) const
{
if (who->GetTypeId() != TYPEID_PLAYER || !who->GetVehicle() || who->GetVehicleBase()->GetEntry() != 33114)
return false;
return true;
}
};
struct TRINITY_DLL_DECL boss_flame_leviathan_overload_deviceAI : public PassiveAI
{
boss_flame_leviathan_overload_deviceAI(Creature *c) : PassiveAI(c) {}
void DoAction(const int32 param)
{
if(param == EVENT_SPELLCLICK)
{
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
if(me->GetVehicle())
{
if(Unit *player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
{
player->ExitVehicle();
me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true);
if(Unit *leviathan = me->GetVehicleBase()->GetVehicleBase())
player->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30);
}
}
}
}
};
struct TRINITY_DLL_DECL boss_flame_leviathan_safety_containerAI : public PassiveAI
{
boss_flame_leviathan_safety_containerAI(Creature *c) : PassiveAI(c) {}
void MovementInform(uint32 type, uint32 id)
{
if(id == me->GetEntry())
{
if(Creature *liquid = DoSummon(MOB_LIQUID, me, 0))
liquid->CastSpell(liquid, 62494, true);
me->DisappearAndDie(); // this will relocate creature to sky
}
}
void UpdateAI(const uint32 diff)
{
if(!me->GetVehicle() && me->isSummon() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
me->GetMotionMaster()->MoveFall(409.8f, me->GetEntry());
}
};
struct TRINITY_DLL_DECL spell_pool_of_tarAI : public TriggerAI
{
spell_pool_of_tarAI(Creature *c) : TriggerAI(c)
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
void DamageTaken(Unit *who, uint32 &damage)
{
damage = 0;
}
void SpellHit(Unit* caster, const SpellEntry *spell)
{
if(spell->SchoolMask & SPELL_SCHOOL_MASK_FIRE && !me->HasAura(SPELL_BLAZE))
me->CastSpell(me, SPELL_BLAZE, true);
}
};
CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature)
{
return new boss_flame_leviathanAI (pCreature);
}
CreatureAI* GetAI_boss_flame_leviathan_seat(Creature* pCreature)
{
return new boss_flame_leviathan_seatAI (pCreature);
}
CreatureAI* GetAI_boss_flame_leviathan_defense_turret(Creature* pCreature)
{
return new boss_flame_leviathan_defense_turretAI (pCreature);
}
CreatureAI* GetAI_boss_flame_leviathan_overload_device(Creature* pCreature)
{
return new boss_flame_leviathan_overload_deviceAI (pCreature);
}
CreatureAI* GetAI_boss_flame_leviathan_safety_containerAI(Creature* pCreature)
{
return new boss_flame_leviathan_safety_containerAI(pCreature);
}
CreatureAI* GetAI_spell_pool_of_tar(Creature* pCreature)
{
return new spell_pool_of_tarAI (pCreature);
}
void AddSC_boss_flame_leviathan()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_flame_leviathan";
newscript->GetAI = &GetAI_boss_flame_leviathan;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_flame_leviathan_seat";
newscript->GetAI = &GetAI_boss_flame_leviathan_seat;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_flame_leviathan_defense_turret";
newscript->GetAI = &GetAI_boss_flame_leviathan_defense_turret;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_flame_leviathan_overload_device";
newscript->GetAI = &GetAI_boss_flame_leviathan_overload_device;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_flame_leviathan_safety_container";
newscript->GetAI = &GetAI_boss_flame_leviathan_safety_containerAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "spell_pool_of_tar";
newscript->GetAI = &GetAI_spell_pool_of_tar;
newscript->RegisterSelf();
}
@@ -0,0 +1,85 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
/*
#define SAY_AGGRO -1
#define SAY_SLAY -1
*/
struct TRINITY_DLL_DECL boss_freyaAI : public BossAI
{
boss_freyaAI(Creature* pCreature) : BossAI(pCreature, TYPE_FREYA)
{
m_pInstance = pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
void Reset()
{
}
void KilledUnit(Unit *victim)
{
}
void JustDied(Unit *victim)
{
if (m_pInstance)
m_pInstance->SetData(TYPE_FREYA, DONE);
}
void Aggro(Unit* pWho)
{
// DoScriptText(SAY_AGGRO, m_creature);
m_creature->SetInCombatWithZone();
if (m_pInstance)
m_pInstance->SetData(TYPE_FREYA, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
//SPELLS TODO:
//
DoMeleeAttackIfReady();
EnterEvadeIfOutOfCombatArea(diff);
}
};
CreatureAI* GetAI_boss_freya(Creature* pCreature)
{
return new boss_freyaAI(pCreature);
}
void AddSC_boss_freya()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_freya";
newscript->GetAI = &GetAI_boss_freya;
newscript->RegisterSelf();
}
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
@@ -0,0 +1,89 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
/*
#define SAY_AGGRO -1
#define SAY_SLAY -1
*/
struct TRINITY_DLL_DECL boss_hodirAI : public BossAI
{
boss_hodirAI(Creature *pCreature) : BossAI(pCreature, TYPE_HODIR)
{
m_pInstance = pCreature->GetInstanceData();
Reset();
}
ScriptedInstance* m_pInstance;
void Reset()
{
}
void KilledUnit(Unit *victim)
{
}
void JustDied(Unit *victim)
{
if (m_pInstance)
m_pInstance->SetData(TYPE_HODIR, DONE);
}
void Aggro(Unit* pWho)
{
// DoScriptText(SAY_AGGRO, m_creature);
m_creature->SetInCombatWithZone();
if (m_pInstance)
m_pInstance->SetData(TYPE_HODIR, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
//SPELLS TODO:
//
DoMeleeAttackIfReady();
EnterEvadeIfOutOfCombatArea(diff);
}
};
CreatureAI* GetAI_boss_hodir(Creature* pCreature)
{
return new boss_hodirAI(pCreature);
}
void AddSC_boss_hodir()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_hodir";
newscript->GetAI = &GetAI_boss_hodir;
newscript->RegisterSelf();
}
@@ -0,0 +1,111 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
#define SPELL_FLAME_JETS 62680
#define SPELL_SCORCH 62546
#define SPELL_SLAG_POT 62717
//wrong ids. not in db
#define SAY_AGGRO -10000002
#define SAY_SLAY -1000003
struct TRINITY_DLL_DECL boss_ignis_AI : public BossAI
{
boss_ignis_AI(Creature *pCreature) : BossAI(pCreature, TYPE_IGNIS) {}
uint32 FLAME_JETS_Timer;
uint32 SCORCH_Timer;
uint32 SLAG_POT_Timer;
void Reset()
{
FLAME_JETS_Timer = 32000;
SCORCH_Timer = 100;
SLAG_POT_Timer = 100;
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO,m_creature);
}
void KilledUnit(Unit* victim)
{
DoScriptText(SAY_SLAY, m_creature);
}
void JustDied(Unit *victim)
{
DoScriptText(SAY_SLAY, m_creature);
}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if(m_creature->GetPositionY() < 150 || m_creature->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
{
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop(false);
m_creature->GetMotionMaster()->MoveTargetedHome();
}
if (FLAME_JETS_Timer <= diff)
{
DoCast(SPELL_FLAME_JETS);
DoScriptText(SAY_SLAY, m_creature);
FLAME_JETS_Timer = 25000;
} else FLAME_JETS_Timer -= diff;
if (SCORCH_Timer <= diff)
{
DoCast(SPELL_SCORCH);
SCORCH_Timer = 20000;
} else SCORCH_Timer -= diff;
if (SLAG_POT_Timer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_SLAG_POT);
DoScriptText(SAY_SLAY, m_creature);
SLAG_POT_Timer = 30000;
} else SLAG_POT_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_ignis(Creature* pCreature)
{
return new boss_ignis_AI (pCreature);
}
void AddSC_boss_ignis()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_ignis";
newscript->GetAI = &GetAI_boss_ignis;
newscript->RegisterSelf();
}
@@ -0,0 +1,140 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
#include "Vehicle.h"
#define SPELL_ARM_DEAD_DAMAGE RAID_MODE(63629,63979)
#define SPELL_TWO_ARM_SMASH RAID_MODE(63356,64003)
#define SPELL_ONE_ARM_SMASH RAID_MODE(63573,64006)
#define SPELL_STONE_SHOUT RAID_MODE(63716,64005)
#define SPELL_PETRIFY_BREATH RAID_MODE(62030,63980)
#define SPELL_STONE_GRIP RAID_MODE(62166,63981)
#define SPELL_ARM_SWEEP RAID_MODE(63766,63983)
enum Events
{
EVENT_NONE = 0,
EVENT_SMASH,
EVENT_GRIP,
EVENT_SWEEP,
};
struct TRINITY_DLL_DECL boss_kologarnAI : public BossAI
{
boss_kologarnAI(Creature *pCreature) : BossAI(pCreature, TYPE_KOLOGARN), vehicle(me->GetVehicleKit()),
left(false), right(false)
{
m_pInstance = me->GetInstanceData();
assert(vehicle);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); // i think this is a hack, but there is no other way to disable his rotation
}
ScriptedInstance* m_pInstance;
Vehicle *vehicle;
bool left, right;
void AttackStart(Unit *who)
{
me->Attack(who, true);
}
void JustDied(Unit *victim)
{
if (m_pInstance)
m_pInstance->SetData(TYPE_KOLOGARN, DONE);
}
void PassengerBoarded(Unit *who, int8 seatId, bool apply)
{
if(who->GetTypeId() == TYPEID_UNIT)
{
if(who->GetEntry() == 32933)
left = apply;
else if(who->GetEntry() == 32934)
right = apply;
who->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
CAST_CRE(who)->SetReactState(REACT_PASSIVE);
}
}
void EnterCombat(Unit *who)
{
_EnterCombat();
events.ScheduleEvent(EVENT_SMASH, 5000);
events.ScheduleEvent(EVENT_SWEEP, 10000);
events.ScheduleEvent(EVENT_GRIP, 15000);
}
void UpdateAI(const uint32 diff)
{
if(!UpdateVictim())
return;
events.Update(diff);
if(me->hasUnitState(UNIT_STAT_CASTING))
return;
// TODO: because we are using hack, he is stunned and cannot cast, so we use triggered for every spell
switch(events.GetEvent())
{
case EVENT_NONE: break;
case EVENT_SMASH:
if(left && right)
DoCastVictim(SPELL_TWO_ARM_SMASH, true);
else if(left || right)
DoCastVictim(SPELL_ONE_ARM_SMASH, true);
events.RepeatEvent(15000);
break;
case EVENT_SWEEP:
if(left)
DoCastAOE(SPELL_ARM_SWEEP, true);
events.RepeatEvent(15000);
break;
case EVENT_GRIP:
if(right)
DoCastAOE(SPELL_STONE_GRIP, true);
events.RepeatEvent(15000);
break;
default:
events.PopEvent();
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_kologarn(Creature* pCreature)
{
return new boss_kologarnAI (pCreature);
}
void AddSC_boss_kologarn()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_kologarn";
newscript->GetAI = &GetAI_boss_kologarn;
newscript->RegisterSelf();
}
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "ulduar.h"
@@ -0,0 +1,331 @@
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: razorscale
SDAuthor: MaXiMiUS
SD%Complete: 65
EndScriptData */
#include "ScriptedPch.h"
#include "ulduar.h"
//not in db
#define SAY_AGGRO -2000000
#define SAY_KILL -2000001
#define SAY_PHASE_2_TRANS -2000002
#define SAY_PHASE_3_TRANS -2000003
#define EMOTE_BREATH -2000004
enum Spells
{
SPELL_FLAMEBUFFET = 64016,
SPELL_FIREBALL = 62796,
SPELL_WINGBUFFET = 62666,
SPELL_FLAMEBREATH = 63317,
SPELL_FUSEARMOR = 64771,
SPELL_DEVOURINGFLAME = 63014
};
enum Mobs
{
NPC_DARK_RUNE_SENTINEL = 33846
};
struct TRINITY_DLL_DECL boss_razorscaleAI : public BossAI
{
boss_razorscaleAI(Creature *pCreature) : BossAI(pCreature, TYPE_RAZORSCALE) {}
uint8 Phase;
uint32 FlameBreathTimer;
uint32 FuseArmorTimer;
uint32 DevouringFlameTimer;
uint32 FlameBuffetTimer;
uint32 SummonAddsTimer;
uint32 WingBuffetTimer;
uint32 FireballTimer;
//uint32 StunTimer;
//uint32 CastSpellsTimer;
bool InitialSpawn;
bool IsFlying;
void Reset()
{
Phase = 1;
FlyPhase(Phase, 0);
FlameBreathTimer = 20000;
DevouringFlameTimer = 2000;
FuseArmorTimer = 15000;
FlameBuffetTimer = 3000;
SummonAddsTimer = 45000;
WingBuffetTimer = 17000;
FireballTimer = 18000;
//StunTimer = 30000;
//CastSpellsTimer = 0;
InitialSpawn = true;
IsFlying = true;
m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
DoZoneInCombat();
}
void JustDied(Unit* Killer)
{
}
void KilledUnit(Unit *victim)
{
DoScriptText(SAY_KILL, m_creature);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if(m_creature->GetPositionY() > -60 || m_creature->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
{
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop(false);
m_creature->GetMotionMaster()->MoveTargetedHome();
}
// Victim is not controlled by a player (should never happen)
if (m_creature->getVictim() && !m_creature->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
m_creature->Kill(m_creature->getVictim());
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 99 && Phase == 1) // TODO: Only land (exit Phase 1) if brought down with harpoon guns! This is important!
{
Phase = 2;
DoScriptText(SAY_PHASE_2_TRANS, m_creature); // Audio: "Move quickly! She won't remain grounded for long!"
}
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 33 && Phase == 2) // Health under 33%, Razorscale can't fly anymore.
{
Phase = 3;
DoScriptText(SAY_PHASE_3_TRANS, m_creature); // "Razorscale lands permanently!"
// TODO: Cast Devouring Flame on all harpoon guns simultaneously, briefly after Phase 3 starts (lasts until the harpoon guns are destroyed)
}
/*
if (Phase == 2 && CastSpellsTimer > 0) // 5 seconds of spell casting, after stun breaks, during Phase 2
{
if (CastSpellsTimer <= diff) // 5 seconds are up
Phase = 1; // Return to phase 1
else
CastSpellsTimer -= diff;
}*/
FlyPhase(Phase, diff);
if (Phase >= 2) // Ground Phase (Phase 3 = permanent ground phase)
{
if (FuseArmorTimer <= diff)
{
DoCastVictim(SPELL_FUSEARMOR);
FuseArmorTimer = 10000;
} else FuseArmorTimer -= diff;
if (WingBuffetTimer <= diff)
{
DoCast(SPELL_WINGBUFFET);
WingBuffetTimer = urand(7000,14000);
} else WingBuffetTimer -= diff;
if (FireballTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
{
m_creature->SetInFront(pTarget);
DoCast(pTarget, SPELL_FIREBALL);
}
FireballTimer = 18000;
} else FireballTimer -= diff;
if (FlameBreathTimer <= diff)
{
DoScriptText(EMOTE_BREATH, m_creature); // TODO: "Razorscale takes a deep breath..."
DoCastVictim(SPELL_FLAMEBREATH);
FlameBreathTimer = 15000;
WingBuffetTimer = 0;
} else FlameBreathTimer -= diff;
if (Phase == 3)
{
if (FlameBuffetTimer <= diff)
{
DoScriptText(EMOTE_BREATH, m_creature);
std::list<Unit*> pTargets;
SelectTargetList(pTargets, RAID_MODE(3,9), SELECT_TARGET_RANDOM, 100, true);
uint8 i = 0;
for (std::list<Unit*>::iterator itr = pTargets.begin(); itr != pTargets.end();)
{
if (m_creature->HasInArc(M_PI, *itr))
{
DoCast(*itr, SPELL_FLAMEBUFFET, true);
++i;
}
if (++itr == pTargets.end() || i == RAID_MODE(3,9))
{
AttackStart(*--itr); // seems to attack targets randomly during perma-ground phase..
break;
}
}
FlameBuffetTimer = 25000;
} else FlameBuffetTimer -= diff;
}
DoMeleeAttackIfReady();
}
else if (Phase == 1) //Flying Phase
{
if (InitialSpawn)
SummonAdds();
InitialSpawn = false;
if (FireballTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
{
m_creature->SetInFront(pTarget);
DoCast(pTarget, SPELL_FIREBALL);
}
FireballTimer = 18000;
} else FireballTimer -= diff;
if (DevouringFlameTimer <= diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
{
m_creature->SetInFront(pTarget);
DoCast(pTarget, SPELL_DEVOURINGFLAME);
}
DevouringFlameTimer = 10000;
} else DevouringFlameTimer -= diff;
if (SummonAddsTimer <= diff)
SummonAdds();
else SummonAddsTimer -= diff;
}
}
void SummonAdds()
{
// TODO: Adds will come in waves from mole machines. One mole can spawn a Dark Rune Watcher
// with 1-2 Guardians, or a lone Sentinel. Up to 4 mole machines can spawn adds at any given time.
uint8 random = urand(1,4);
for (uint8 i = 0; i < random; ++i)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
{
float x = std::max(500.0f, std::min(650.0f, pTarget->GetPositionX() + irand(-20,20))); // Safe range is between 500 and 650
float y = std::max(-235.0f, std::min(-145.0f, pTarget->GetPositionY() + irand(-20,20))); // Safe range is between -235 and -145
float z = m_creature->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT); // Ground level
// TODO: Spawn drillers, then spawn adds 5 seconds later
if (Creature *pAdd = m_creature->SummonCreature(NPC_DARK_RUNE_SENTINEL, x, y, z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000))
pAdd->AI()->AttackStart(pTarget);
}
}
SummonAddsTimer = 45000;
}
void FlyPhase(uint8 Phase, const uint32 diff)
{
const float x = 587.54;
const float y = -174.92;
const float GroundLevel = m_creature->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT);
const float FlightHeight = GroundLevel + 4.0f; // TODO: Fly out of range of attacks (442 is sufficient height for this), minus ~(10*number of harpoon gun chains attached to Razorscale)
if (Phase == 1) // Always flying during Phase 1
IsFlying = true;
m_creature->SetFlying(IsFlying);
m_creature->SendMovementFlagUpdate();
m_creature->SetSpeed(MOVE_WALK, IsFlying ? 7.0f : 2.5f, IsFlying);
if (Phase == 1) // Flying Phase
{
if (m_creature->GetPositionZ() > FlightHeight) // Correct height, stop moving
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
else // Incorrect height
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
m_creature->GetMotionMaster()->MovePoint(0, x, y, FlightHeight + 0.5f); // Fly to slightly above (x, y, FlightHeight)
}
}
else // Ground Phases
{
const float CurrentGroundLevel = m_creature->GetBaseMap()->GetHeight(m_creature->GetPositionX(), m_creature->GetPositionY(), MAX_HEIGHT);
//if (StunTimer == 30000) // Only fly around if not stunned.
//{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
if (IsFlying && m_creature->GetPositionZ() > CurrentGroundLevel) // Fly towards the ground
m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), CurrentGroundLevel);
// TODO: Swoop up just before landing
else
IsFlying = false; // Landed, no longer flying
//}
//if (!IsFlying &&Phase == 2 && CastSpellsTimer == 0 && StunTimer >= diff) // No longer flying, non-permanent ground phase, and not casting spells
//{
// TODO: Add stun here. 30 second stun after Razorscale is grounded by harpoon guns
//StunTimer -= diff;
//}
//else if (StunTimer != 30000 && (StunTimer < 0 || Phase == 3)) // Stun is active, and needs to end. Note: Stun breaks instantly if Phase 3 starts
//{
// TODO: Remove stun here.
//DoCast(SPELL_WINGBUFFET); // "Used in the beginning of the phase."
//WingBuffetTimer = urand(7000,14000);
//StunTimer = 30000; // Reinitialize the stun timer
//if (Phase == 2) // Non-permanent ground phase
// CastSpellsTimer = 5000; // Five seconds of casting before returning to Phase 1
//}
}
}
};
CreatureAI* GetAI_boss_razorscale(Creature* pCreature)
{
return new boss_razorscaleAI (pCreature);
}
void AddSC_boss_razorscale()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_razorscale";
newscript->GetAI = &GetAI_boss_razorscale;
newscript->RegisterSelf();
}

Some files were not shown because too many files have changed in this diff Show More