aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp139
-rw-r--r--src/bindings/scripts/include/sc_creature.h2
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp420
-rw-r--r--src/game/CreatureAI.h2
-rw-r--r--src/game/SpellEffects.cpp123
5 files changed, 588 insertions, 98 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index b1044ff6319..7bc7c1015cb 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -261,6 +261,145 @@ Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position)
return NULL;
}
+struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
+{
+ const Unit* me;
+ TargetDistanceOrder(const Unit* Target) : me(Target) {};
+ // functor for operator ">"
+ bool operator()(const Unit* _Left, const Unit* _Right) const
+ {
+ return (me->GetDistance(_Left) < me->GetDistance(_Right));
+ }
+};
+
+Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly)
+{
+ if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
+ {
+ std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList();
+ if(m_threatlist.empty()) return NULL;
+ std::list<Unit*> targetList;
+ std::list<HostilReference*>::iterator itr = m_threatlist.begin();
+ for(; itr!= m_threatlist.end(); ++itr)
+ {
+ Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
+ if(!target
+ || playerOnly && target->GetTypeId() != TYPEID_PLAYER
+ || dist && !m_creature->IsWithinDistInMap(target, dist))
+ {
+ continue;
+ }
+ targetList.push_back(target);
+ }
+ if(position >= targetList.size())
+ return NULL;
+ targetList.sort(TargetDistanceOrder(m_creature));
+ if(targetType == SELECT_TARGET_NEAREST)
+ {
+ std::list<Unit*>::iterator i = targetList.begin();
+ advance(i, position);
+ return *i;
+ }
+ else
+ {
+ std::list<Unit*>::reverse_iterator i = targetList.rbegin();
+ advance(i, position);
+ return *i;
+ }
+ }
+ else
+ {
+ std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList();
+ std::list<HostilReference*>::iterator i;
+ Unit *target;
+ while(position < m_threatlist.size())
+ {
+ if(targetType == SELECT_TARGET_BOTTOMAGGRO)
+ {
+ i = m_threatlist.end();
+ advance(i, - (int32)position - 1);
+ }
+ else
+ {
+ i = m_threatlist.begin();
+ if(targetType == SELECT_TARGET_TOPAGGRO)
+ advance(i, position);
+ else // random
+ advance(i, position + rand()%(m_threatlist.size() - position));
+ }
+
+ target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
+ if(!target
+ || playerOnly && target->GetTypeId() != TYPEID_PLAYER
+ || dist && !m_creature->IsWithinDistInMap(target, dist))
+ {
+ m_threatlist.erase(i);
+ }
+ else
+ {
+ return target;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void ScriptedAI::SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly)
+{
+ if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
+ {
+ std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList();
+ if(m_threatlist.empty()) return;
+ std::list<HostilReference*>::iterator itr = m_threatlist.begin();
+ for(; itr!= m_threatlist.end(); ++itr)
+ {
+ Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
+ if(!target
+ || playerOnly && target->GetTypeId() != TYPEID_PLAYER
+ || dist && !m_creature->IsWithinDistInMap(target, dist))
+ {
+ continue;
+ }
+ targetList.push_back(target);
+ }
+ targetList.sort(TargetDistanceOrder(m_creature));
+ targetList.resize(num);
+ if(targetType == SELECT_TARGET_FARTHEST)
+ targetList.reverse();
+ }
+ else
+ {
+ std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList();
+ std::list<HostilReference*>::iterator i;
+ Unit *target;
+ while(m_threatlist.size())
+ {
+ if(targetType == SELECT_TARGET_BOTTOMAGGRO)
+ {
+ i = m_threatlist.end();
+ --i;
+ }
+ else
+ {
+ i = m_threatlist.begin();
+ if(targetType == SELECT_TARGET_RANDOM)
+ advance(i, rand()%m_threatlist.size());
+ }
+
+ target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
+ m_threatlist.erase(i);
+ if(!target
+ || playerOnly && target->GetTypeId() != TYPEID_PLAYER
+ || dist && !m_creature->IsWithinDistInMap(target, dist))
+ {
+ continue;
+ }
+ targetList.push_back(target);
+ }
+ }
+}
+
SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects)
{
//No target so we can't cast
diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h
index 494ab101f08..e85e7d45f8f 100644
--- a/src/bindings/scripts/include/sc_creature.h
+++ b/src/bindings/scripts/include/sc_creature.h
@@ -146,6 +146,8 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
//Selects a unit from the creature's current aggro list
Unit* SelectUnit(SelectAggroTarget target, uint32 position);
+ Unit* SelectUnit(SelectAggroTarget target, uint32 position, float dist, bool playerOnly);
+ void SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget target, float dist, bool playerOnly);
//Returns spells that meet the specified criteria from the creatures spell list
SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect);
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
index a4da476a408..2ba76a57bd5 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
@@ -16,46 +16,78 @@
/* ScriptData
SDName: Boss_Fathomlord_Karathress
-SD%Complete: 50
-SDComment: Missing Multishot, pet, Totems, Windfury, Whirlwind
+SD%Complete: 70%
+SDComment: Cyclone workaround
SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
EndScriptData */
#include "precompiled.h"
#include "def_serpent_shrine.h"
+#include "../../../npc/npc_escortAI.h"
//Karathress spells
-#define SPELL_CATACLYSMIC_BOLT 38441
-#define SPELL_POWER_OF_SHARKKIS 38455
-#define SPELL_POWER_OF_TIDALVESS 38452
-#define SPELL_POWER_OF_CARIBDIS 38451
-#define SPELL_ENRAGE 24318
+#define SPELL_CATACLYSMIC_BOLT 38441
+#define SPELL_POWER_OF_SHARKKIS 38455
+#define SPELL_POWER_OF_TIDALVESS 38452
+#define SPELL_POWER_OF_CARIBDIS 38451
+#define SPELL_ENRAGE 45078
+#define SPELL_SEAR_NOVA 38445
+#define SPELL_BLESSING_OF_THE_TIDES 38449
+
//Sharkkis spells
-#define SPELL_LEECHING_THROW 29436
-#define SPELL_THE_BEAST_WITHIN 38373
+#define SPELL_LEECHING_THROW 29436
+#define SPELL_THE_BEAST_WITHIN 38373
+#define SPELL_LEECHING_THROW 29436
+#define SPELL_MULTISHOT 38366
+#define SPELL_THE_BEAST_WITHIN 38373
+#define SPELL_SUMMON_FATHOM_LURKER 38433
+#define SPELL_SUMMON_FATHOM_SPOREBAT 38431
+#define SPELL_PET_ENRAGE 19574
+
//Tidalvess spells
-#define SPELL_FROST_SHOCK 38234
+#define SPELL_FROST_SHOCK 38234
+#define SPELL_SPITFIRE_TOTEM 38236
+#define SPELL_POISON_CLEANSING_TOTEM 38306
+#define SPELL_POISON_CLEANSING_EFFECT 8167
+#define SPELL_EARTHBIND_TOTEM 38304
+#define SPELL_EARTHBIND_TOTEM_EFFECT 6474
+#define SPELL_WINDFURY_WEAPON 32911
+
//Caribdis Spells
-#define SPELL_WATER_BOLT_VOLLEY 38335
-#define SPELL_TIDAL_SURGE 38353
-#define SPELL_HEAL 41386
-
-#define SAY_AGGRO "Guards, attention! We have visitors..."
-#define SAY_SLAY1 "I am rid of you."
-#define SAY_GAIN_ABILITY1 "I am more powerful than ever!"
-#define SAY_GAIN_ABILITY2 "Go on, kill them! I'll be the better for it!"
-#define SAY_GAIN_ABILITY3 "More knowledge, more power!"
-#define SAY_DEATH "Her ... excellency ... awaits!"
-
-#define SOUND_AGGRO 11277
-#define SOUND_PLYR_ATTACK 11278
-#define SOUND_GAIN_ABILITY1 11279
-#define SOUND_GAIN_ABILITY2 11280
-#define SOUND_GAIN_ABILITY3 11281
-#define SOUND_SLAY1 11282
-#define SOUND_SLAY2 11283
-#define SOUND_SLAY3 11284
-#define SOUND_DEATH 11285
+#define SPELL_WATER_BOLT_VOLLEY 38335
+#define SPELL_TIDAL_SURGE 38358
+#define SPELL_TIDAL_SURGE_FREEZE 38357
+#define SPELL_HEAL 41386
+#define SPELL_SUMMON_CYCLONE 38337
+#define SPELL_CYCLONE_CYCLONE 29538
+
+//Yells and Quotes
+#define SAY_AGGRO "Guards, attention! We have visitors..."
+#define SOUND_AGGRO 11277
+#define SAY_SLAY1 "I am rid of you."
+#define SOUND_SLAY1 11282
+#define SAY_SLAY2 "Land-dwelling scum!"
+#define SOUND_SLAY2 11284
+#define SAY_GAIN_ABILITY1 "I am more powerful than ever!"
+#define SOUND_GAIN_ABILITY1 11279
+#define SAY_GAIN_ABILITY2 "Go on, kill them! I'll be the better for it!"
+#define SOUND_GAIN_ABILITY2 11280
+#define SAY_GAIN_ABILITY3 "More knowledge, more power!"
+#define SOUND_GAIN_ABILITY3 11281
+#define SAY_DEATH "Her ... excellency ... awaits!"
+#define SOUND_DEATH 11285
+#define SAY_GAIN_BLESSING_OF_TIDES "Your overconfidence will be your undoing! Guards, lend me your strength!"
+#define SOUND_GAIN_BLESSING_OF_TIDES 11278
+#define SAY_MISC "Alana be'lendor!" //don't know what use this
+#define SOUND_MISC 11283
+
+//Summoned Unit GUIDs
+#define CREATURE_CYCLONE 22104
+#define CREATURE_FATHOM_SPOREBAT 22120
+#define CREATURE_FATHOM_LURKER 22119
+#define CREATURE_SPITFIRE_TOTEM 22091
+#define CREATURE_EARTHBIND_TOTEM 22486
+#define CREATURE_POISON_CLEANSING_TOTEM 22487
//entry and position for Seer Olum
#define SEER_OLUM 22820
@@ -80,6 +112,9 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
uint32 CataclysmicBolt_Timer;
uint32 Enrage_Timer;
+ uint32 SearNova_Timer;
+
+ bool BlessingOfTides;
uint64 Advisors[3];
@@ -87,27 +122,38 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
{
CataclysmicBolt_Timer = 10000;
Enrage_Timer = 600000; //10 minutes
-
- Creature* Advisor;
- for(uint8 i = 0; i < 3; ++i)
- if(Advisors[i])
- {
- Advisor = ((Creature*)Unit::GetUnit(*m_creature, Advisors[i]));
- if(Advisor)
- {
- if(Advisor->isAlive())
- {
- Advisor->DealDamage(Advisor, Advisor->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- Advisor->RemoveCorpse();
- Advisor->Respawn();
- }
- Advisor->AI()->EnterEvadeMode();
- }
- }
-
- if( pInstance )
- pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
- }
+ SearNova_Timer = 20000+rand()%40000; // 20 - 60 seconds
+
+ BlessingOfTides = false;
+
+
+
+ if(pInstance)
+ {
+ uint64 RAdvisors[3];
+ RAdvisors[0] = pInstance->GetData64(DATA_SHARKKIS);
+ RAdvisors[1] = pInstance->GetData64(DATA_TIDALVESS);
+ RAdvisors[2] = pInstance->GetData64(DATA_CARIBDIS);
+ //Respawn of the 3 Advisors
+ Creature* pAdvisor = NULL;
+ for( int i=0; i<3; i++ )
+
+
+ if(RAdvisors[i])
+ {
+ pAdvisor = ((Creature*)Unit::GetUnit((*m_creature), RAdvisors[i]));
+ if(pAdvisor && !pAdvisor->isAlive())
+ {
+ pAdvisor->Respawn();
+ pAdvisor->AI()->EnterEvadeMode();
+ pAdvisor->GetMotionMaster()->MoveTargetedHome();
+ }
+ }
+ pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
+ }
+
+
+ }
void EventSharkkisDeath()
{
@@ -149,6 +195,7 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
+ DoZoneInCombat();
pInstance->SetData64(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
pInstance->SetData(DATA_KARATHRESSEVENT, IN_PROGRESS);
@@ -164,9 +211,7 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
break;
case 1:
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
- break;
- case 2:
- DoPlaySoundToSet(m_creature, SOUND_SLAY3);
+ DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
break;
}
}
@@ -177,7 +222,7 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
if( pInstance )
- pInstance->SetData(DATA_FATHOMLORDKARATHRESSEVENT, NOT_STARTED);
+ pInstance->SetData(DATA_FATHOMLORDKARATHRESSEVENT, DONE);
//support for quest 10944
m_creature->SummonCreature(SEER_OLUM, OLUM_X, OLUM_Y, OLUM_Z, OLUM_O, TEMPSUMMON_TIMED_DESPAWN, 3600000);
@@ -208,7 +253,10 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
//someone evaded!
if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT))
+ {
EnterEvadeMode();
+ return;
+ }
//CataclysmicBolt_Timer
if(CataclysmicBolt_Timer < diff)
@@ -226,6 +274,13 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
CataclysmicBolt_Timer = 10000;
}else CataclysmicBolt_Timer -= diff;
+ //SearNova_Timer
+ if(SearNova_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_SEAR_NOVA);
+ SearNova_Timer = 20000+rand()%40000;
+ }else SearNova_Timer -= diff;
+
//Enrage_Timer
if(Enrage_Timer < diff)
{
@@ -233,6 +288,33 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
Enrage_Timer = 90000;
}else Enrage_Timer -= diff;
+ //Blessing of Tides Trigger
+ if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 75 && !BlessingOfTides)
+ {
+ BlessingOfTides = true;
+ bool continueTriggering;
+ Creature* Advisor;
+ for(uint8 i = 0; i < 4; ++i)
+ if(Advisors[i])
+ {
+ Advisor = ((Creature*)Unit::GetUnit(*m_creature, Advisors[i]));
+ if(Advisor)
+ {
+ if(Advisor->isAlive())
+ {
+ continueTriggering = true;
+ break;
+ }
+ }
+ }
+ if( continueTriggering )
+ {
+ DoCast(m_creature, SPELL_BLESSING_OF_THE_TIDES);
+ DoYell(SAY_GAIN_BLESSING_OF_TIDES, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_GAIN_BLESSING_OF_TIDES);
+ }
+ }
+
DoMeleeAttackIfReady();
}
};
@@ -250,11 +332,30 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
uint32 LeechingThrow_Timer;
uint32 TheBeastWithin_Timer;
+ uint32 Multishot_Timer;
+ uint32 Pet_Timer;
+
+ bool pet;
+
+ uint64 SummonedPet;
+
void Reset()
{
LeechingThrow_Timer = 20000;
TheBeastWithin_Timer = 30000;
+ Multishot_Timer = 15000;
+ Pet_Timer = 10000;
+
+ pet = false;
+
+ Creature *Pet = (Creature*) Unit::GetUnit(*m_creature, SummonedPet);
+ if( Pet && Pet->isAlive() )
+ {
+ Pet->DealDamage( Pet, Pet->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false );
+ }
+
+ SummonedPet = 0;
if( pInstance )
pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
@@ -268,7 +369,8 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
Karathress = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
if(Karathress)
- ((boss_fathomlord_karathressAI*)Karathress->AI())->EventSharkkisDeath();
+ if(!m_creature->isAlive() && Karathress)
+ ((boss_fathomlord_karathressAI*)Karathress->AI())->EventSharkkisDeath();
}
}
@@ -300,7 +402,10 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
//someone evaded!
if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT))
- EnterEvadeMode();
+ {
+ EnterEvadeMode();
+ return;
+ }
//LeechingThrow_Timer
if(LeechingThrow_Timer < diff)
@@ -309,12 +414,51 @@ struct TRINITY_DLL_DECL boss_fathomguard_sharkkisAI : public ScriptedAI
LeechingThrow_Timer = 20000;
}else LeechingThrow_Timer -= diff;
- //TheBeastWithin_Timer
- if(TheBeastWithin_Timer < diff)
- {
- DoCast(m_creature, SPELL_THE_BEAST_WITHIN);
- TheBeastWithin_Timer = 30000;
- }else TheBeastWithin_Timer -= diff;
+ //Multishot_Timer
+ if(Multishot_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_MULTISHOT);
+ Multishot_Timer = 20000;
+ }else Multishot_Timer -= diff;
+
+ //TheBeastWithin_Timer
+ if(TheBeastWithin_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_THE_BEAST_WITHIN);
+ Creature *Pet = (Creature*) Unit::GetUnit(*m_creature, SummonedPet);
+ if( Pet && Pet->isAlive() )
+ {
+ Pet->CastSpell( Pet, SPELL_PET_ENRAGE, true );
+ }
+ TheBeastWithin_Timer = 30000;
+ }else TheBeastWithin_Timer -= diff;
+
+ //Pet_Timer
+ if(Pet_Timer < diff && pet == false)
+ {
+ pet = true;
+ //uint32 spell_id;
+ uint32 pet_id;
+ switch( rand()%2 )
+ {
+ case 0:
+ //spell_id = SPELL_SUMMON_FATHOM_LURKER;
+ pet_id = CREATURE_FATHOM_LURKER;
+ break;
+ case 1:
+ //spell_id = SPELL_SUMMON_FATHOM_SPOREBAT;
+ pet_id = CREATURE_FATHOM_SPOREBAT;
+ break;
+ }
+ //DoCast( m_creature, spell_id, true );
+ Creature *Pet = DoSpawnCreature(pet_id,0,0,0,0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000 );
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (Pet && target)
+ {
+ Pet->AI()->AttackStart(target);
+ SummonedPet = Pet->GetGUID();
+ }
+ }else Pet_Timer -= diff;
DoMeleeAttackIfReady();
}
@@ -332,10 +476,16 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
ScriptedInstance* pInstance;
uint32 FrostShock_Timer;
+ uint32 Spitfire_Timer;
+ uint32 PoisonCleansing_Timer;
+ uint32 Earthbind_Timer;
void Reset()
{
FrostShock_Timer = 25000;
+ Spitfire_Timer = 60000;
+ PoisonCleansing_Timer = 30000;
+ Earthbind_Timer = 45000;
if( pInstance )
pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
@@ -349,7 +499,8 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
Karathress = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
if(Karathress)
- ((boss_fathomlord_karathressAI*)Karathress->AI())->EventTidalvessDeath();
+ if(!m_creature->isAlive() && Karathress)
+ ((boss_fathomlord_karathressAI*)Karathress->AI())->EventTidalvessDeath();
}
}
@@ -360,6 +511,7 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
pInstance->SetData64(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
pInstance->SetData(DATA_KARATHRESSEVENT, IN_PROGRESS);
}
+ DoCast(m_creature, SPELL_WINDFURY_WEAPON);
}
void UpdateAI(const uint32 diff)
@@ -381,7 +533,15 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
//someone evaded!
if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT))
+ {
EnterEvadeMode();
+ return;
+ }
+
+ if( !m_creature->HasAura(SPELL_WINDFURY_WEAPON, 0) )
+ {
+ DoCast(m_creature, SPELL_WINDFURY_WEAPON);
+ }
//FrostShock_Timer
if(FrostShock_Timer < diff)
@@ -390,6 +550,32 @@ struct TRINITY_DLL_DECL boss_fathomguard_tidalvessAI : public ScriptedAI
FrostShock_Timer = 25000+rand()%5000;
}else FrostShock_Timer -= diff;
+ //Spitfire_Timer
+ if(Spitfire_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_SPITFIRE_TOTEM);
+ Unit *SpitfireTotem = Unit::GetUnit( *m_creature, CREATURE_SPITFIRE_TOTEM );
+ if( SpitfireTotem )
+ {
+ ((Creature*)SpitfireTotem)->AI()->AttackStart( m_creature->getVictim() );
+ }
+ Spitfire_Timer = 60000;
+ }else Spitfire_Timer -= diff;
+
+ //PoisonCleansing_Timer
+ if(PoisonCleansing_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_POISON_CLEANSING_TOTEM);
+ PoisonCleansing_Timer = 30000;
+ }else PoisonCleansing_Timer -= diff;
+
+ //Earthbind_Timer
+ if(Earthbind_Timer < diff)
+ {
+ DoCast(m_creature, SPELL_EARTHBIND_TOTEM);
+ Earthbind_Timer = 45000;
+ }else Earthbind_Timer -= diff;
+
DoMeleeAttackIfReady();
}
};
@@ -408,12 +594,14 @@ struct TRINITY_DLL_DECL boss_fathomguard_caribdisAI : public ScriptedAI
uint32 WaterBoltVolley_Timer;
uint32 TidalSurge_Timer;
uint32 Heal_Timer;
+ uint32 Cyclone_Timer;
void Reset()
{
WaterBoltVolley_Timer = 35000;
TidalSurge_Timer = 15000+rand()%5000;
Heal_Timer = 55000;
+ Cyclone_Timer = 30000+rand()%10000;
if(pInstance)
pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
@@ -427,7 +615,8 @@ struct TRINITY_DLL_DECL boss_fathomguard_caribdisAI : public ScriptedAI
Karathress = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)));
if(Karathress)
- ((boss_fathomlord_karathressAI*)Karathress->AI())->EventCaribdisDeath();
+ if(!m_creature->isAlive() && Karathress)
+ ((boss_fathomlord_karathressAI*)Karathress->AI())->EventCaribdisDeath();
}
}
@@ -459,7 +648,10 @@ struct TRINITY_DLL_DECL boss_fathomguard_caribdisAI : public ScriptedAI
//someone evaded!
if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT))
+ {
EnterEvadeMode();
+ return;
+ }
//WaterBoltVolley_Timer
if(WaterBoltVolley_Timer < diff)
@@ -472,42 +664,74 @@ struct TRINITY_DLL_DECL boss_fathomguard_caribdisAI : public ScriptedAI
if(TidalSurge_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_TIDAL_SURGE);
+ // Hacky way to do it - won't trigger elseways
+ m_creature->getVictim()->CastSpell( m_creature->getVictim(), SPELL_TIDAL_SURGE_FREEZE, true );
TidalSurge_Timer = 15000+rand()%5000;
}else TidalSurge_Timer -= diff;
- //Heal_Timer
- if(Heal_Timer < diff)
- {
- // It can be cast on any of the mobs
- Unit *pUnit = NULL;
-
- if(pInstance)
- {
- switch(rand()%4)
- {
- case 0:
- pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS));
- break;
- case 1:
- pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_SHARKKIS));
- break;
- case 2:
- pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_TIDALVESS));
- break;
- case 3:
- pUnit = m_creature;
- break;
- }
- }else pUnit = m_creature;
-
- if(pUnit && pUnit->isAlive())
- DoCast(pUnit, SPELL_HEAL);
-
- Heal_Timer = 60000;
- }else Heal_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
+ //Cyclone_Timer
+ if(Cyclone_Timer < diff)
+ {
+ //DoCast(m_creature, SPELL_SUMMON_CYCLONE); // Doesn't work
+ Cyclone_Timer = 30000+rand()%10000;
+ Creature *Cyclone = m_creature->SummonCreature(CREATURE_CYCLONE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), (rand()%5), TEMPSUMMON_TIMED_DESPAWN, 15000);
+ if( Cyclone )
+ {
+ ((Creature*)Cyclone)->SetFloatValue(OBJECT_FIELD_SCALE_X, 3.0f);
+ Cyclone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Cyclone->setFaction(m_creature->getFaction());
+ Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
+ Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if( target )
+ {
+ Cyclone->AI()->AttackStart(target);
+ }
+ }
+ }else Cyclone_Timer -= diff;
+
+ //Heal_Timer
+ if(Heal_Timer < diff)
+ {
+ // It can be cast on any of the mobs
+ Unit *pUnit = NULL;
+
+ while( pUnit == NULL || !pUnit->isAlive() )
+ {
+ pUnit = selectAdvisorUnit();
+ }
+
+ if(pUnit && pUnit->isAlive())
+ DoCast(pUnit, SPELL_HEAL);
+ Heal_Timer = 60000;
+ }else Heal_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ Unit* selectAdvisorUnit()
+ {
+ Unit* pUnit;
+ if(pInstance)
+ {
+ switch(rand()%4)
+ {
+ case 0:
+ pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS));
+ break;
+ case 1:
+ pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_SHARKKIS));
+ break;
+ case 2:
+ pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_TIDALVESS));
+ break;
+ case 3:
+ pUnit = m_creature;
+ break;
+ }
+ }else pUnit = m_creature;
+
+ return pUnit;
+ }
};
CreatureAI* GetAI_boss_fathomlord_karathress(Creature *_Creature)
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index 03782cc6764..d44ab81bd3a 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -65,6 +65,8 @@ enum SelectAggroTarget
SELECT_TARGET_RANDOM = 0, //Just selects a random target
SELECT_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
SELECT_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
+ SELECT_TARGET_NEAREST,
+ SELECT_TARGET_FARTHEST,
};
class TRINITY_DLL_SPEC CreatureAI
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 90dc40c89fc..419a9820ba3 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -615,6 +615,103 @@ void Spell::EffectDummy(uint32 i)
// Gnomish Poultryizer trinket
switch(m_spellInfo->Id )
{
+ // Mingo's Fortune Giblets
+ case 40802:
+ {
+ if (m_caster->GetTypeId() != TYPEID_PLAYER) return;
+
+ Player *player = (Player*)m_caster;
+ uint32 newitemid;
+
+ switch(urand(1,20))
+ {
+ case 1: newitemid = 32688; break;
+ case 2: newitemid = 32689; break;
+ case 3: newitemid = 32690; break;
+ case 4: newitemid = 32691; break;
+ case 5: newitemid = 32692; break;
+ case 6: newitemid = 32693; break;
+ case 7: newitemid = 32700; break;
+ case 8: newitemid = 32701; break;
+ case 9: newitemid = 32702; break;
+ case 10: newitemid = 32703; break;
+ case 11: newitemid = 32704; break;
+ case 12: newitemid = 32705; break;
+ case 13: newitemid = 32706; break;
+ case 14: newitemid = 32707; break;
+ case 15: newitemid = 32708; break;
+ case 16: newitemid = 32709; break;
+ case 17: newitemid = 32710; break;
+ case 18: newitemid = 32711; break;
+ case 19: newitemid = 32712; break;
+ case 20: newitemid = 32713; break;
+ }
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, newitemid, 1, false);
+ if (msg != EQUIP_ERR_OK)
+ {
+ player->SendEquipError(msg, NULL, NULL);
+ return;
+ }
+ Item *pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid));
+
+ if (!pItem)
+ {
+ player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
+ return;
+ }
+ player->SendNewItem(pItem, 1, true, true);
+
+ return;
+ }
+ // Encapsulate Voidwalker
+ case 29364:
+ {
+ if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || ((Creature*)unitTarget)->isPet()) return;
+
+ Creature* creatureTarget = (Creature*)unitTarget;
+ GameObject* pGameObj = new GameObject;
+
+ if (!creatureTarget || !pGameObj) return;
+
+ if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(),
+ creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(),
+ creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ {
+ delete pGameObj;
+ return;
+ }
+
+ pGameObj->SetRespawnTime(0);
+ pGameObj->SetOwnerGUID(m_caster->GetGUID());
+ pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
+ pGameObj->SetSpellId(m_spellInfo->Id);
+
+ MapManager::Instance().GetMap(creatureTarget->GetMapId(), pGameObj)->Add(pGameObj);
+
+ WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
+ data << uint64(pGameObj->GetGUID());
+ m_caster->SendMessageToSet(&data,true);
+
+ return;
+ }
+ // Demon Broiled Surprise
+ case 43723:
+ {
+ if (!unitTarget || unitTarget->isAlive() || unitTarget->GetTypeId() != TYPEID_UNIT ||
+ ((Creature*)unitTarget)->isPet()) return;
+
+ Player *player = (Player*)m_caster;
+
+ if (!player) return;
+
+ player->CastSpell(unitTarget, 43753, true);
+
+ if (player->GetQuestStatus(11379) == QUEST_STATUS_INCOMPLETE && unitTarget->GetEntry() == 19973)
+ player->CastedCreatureOrGO(19973, unitTarget->GetGUID(), 43723);
+
+ return;
+ }
case 8063: // Deviate Fish
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -4788,6 +4885,32 @@ void Spell::EffectScriptEffect(uint32 effIndex)
case 40904: unitTarget->CastSpell(m_caster, 40903, true); break;
// Flame Crash
case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break;
+ case 41931:
+ {
+ int bag=19;
+ int slot=0;
+ Item* item = NULL;
+
+ while (bag < 256)
+ {
+ item = ((Player*)m_caster)->GetItemByPos(bag,slot);
+ if (item && item->GetEntry() == 38587) break;
+ slot++;
+ if (slot == 39)
+ {
+ slot = 0;
+ bag++;
+ }
+ }
+ if (bag < 256)
+ {
+ if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true);
+ else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1);
+ // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
+ m_caster->CastSpell(m_caster,42518,true);
+ return;
+ }
+ }
// Force Cast - Portal Effect: Sunwell Isle
case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break;
//5,000 Gold