[svn] Add new function SelectUnit and SelectUnitList to select target or targets with check "isPlayer" and "isWithinDist". Also add target type SELECT_TARGET_NEAREST and SELECT_TARGET_FARTHEST.

SpellEffect Fix for 40802,29364,43723,41931. Patch provided by WarHead.
Update script of Fathom Lord. Patch provided by Blaymoira.

--HG--
branch : trunk
This commit is contained in:
megamage
2008-10-28 16:28:42 -05:00
parent 8ded7dce04
commit 5e809c2a6b
5 changed files with 580 additions and 90 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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 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
#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!"
//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
#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
//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
SearNova_Timer = 20000+rand()%40000; // 20 - 60 seconds
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();
}
}
BlessingOfTides = false;
if( pInstance )
pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
}
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;
//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;
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;
//Heal_Timer
if(Heal_Timer < diff)
{
// It can be cast on any of the mobs
Unit *pUnit = NULL;
if(pUnit && pUnit->isAlive())
DoCast(pUnit, SPELL_HEAL);
while( pUnit == NULL || !pUnit->isAlive() )
{
pUnit = selectAdvisorUnit();
}
Heal_Timer = 60000;
}else Heal_Timer -= diff;
if(pUnit && pUnit->isAlive())
DoCast(pUnit, SPELL_HEAL);
Heal_Timer = 60000;
}else Heal_Timer -= diff;
DoMeleeAttackIfReady();
}
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)

View File

@@ -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

View File

@@ -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