*rewrite The Lurker Below boss script (again)
--HG-- branch : trunk
This commit is contained in:
+181
-249
@@ -37,7 +37,7 @@ EndScriptData */
|
|||||||
#define SPELL_EMERGE 20568
|
#define SPELL_EMERGE 20568
|
||||||
#define SPELL_SCALDINGWATER 37284
|
#define SPELL_SCALDINGWATER 37284
|
||||||
|
|
||||||
#define EMOTE_SPOUT "takes a deep breath."
|
#define EMOTE_SPOUT "The Lurker Below takes a deep breath."
|
||||||
|
|
||||||
#define SPOUT_DIST 100
|
#define SPOUT_DIST 100
|
||||||
|
|
||||||
@@ -65,13 +65,6 @@ float AddPos[9][3] =
|
|||||||
{42.471519, -445.115295, -19.769423} //MOVE_GUARDIAN_3 X, Y, Z
|
{42.471519, -445.115295, -19.769423} //MOVE_GUARDIAN_3 X, Y, Z
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RotationType
|
|
||||||
{
|
|
||||||
NOROTATE = 0,
|
|
||||||
CLOCKWISE = 1,
|
|
||||||
COUNTERCLOCKWISE = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
||||||
{
|
{
|
||||||
boss_the_lurker_belowAI(Creature *c) : Scripted_NoMovementAI(c), Summons(m_creature)
|
boss_the_lurker_belowAI(Creature *c) : Scripted_NoMovementAI(c), Summons(m_creature)
|
||||||
@@ -91,38 +84,35 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
|||||||
|
|
||||||
bool Spawned;
|
bool Spawned;
|
||||||
bool Submerged;
|
bool Submerged;
|
||||||
|
bool InRange;
|
||||||
double SpoutAngle;
|
|
||||||
|
|
||||||
uint8 RotType;
|
|
||||||
|
|
||||||
uint32 RotTimer;
|
uint32 RotTimer;
|
||||||
uint32 SpoutAnimTimer;
|
uint32 SpoutAnimTimer;
|
||||||
uint32 WaterboltTimer;
|
uint32 WaterboltTimer;
|
||||||
uint32 SpoutTimer;
|
uint32 SpoutTimer;
|
||||||
uint32 WhirlTimer;//after avery spout
|
uint32 WhirlTimer;
|
||||||
uint32 PhaseTimer;
|
uint32 PhaseTimer;
|
||||||
uint32 GeyserTimer;
|
uint32 GeyserTimer;
|
||||||
|
uint32 CheckTimer;
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING + MOVEMENTFLAG_LEVITATING);
|
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING + MOVEMENTFLAG_LEVITATING);
|
||||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||||
m_creature->SetCorpseDelay(1000*60*60);
|
m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
|
||||||
|
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
|
||||||
|
|
||||||
RotType = NOROTATE;
|
|
||||||
|
|
||||||
SpoutAngle = 0;
|
|
||||||
SpoutAnimTimer = 1000;
|
SpoutAnimTimer = 1000;
|
||||||
RotTimer = 20000;
|
RotTimer = 0;
|
||||||
WaterboltTimer = 3000;
|
WaterboltTimer = 15000;//give time to get in range when fight starts
|
||||||
SpoutTimer = 15000;
|
SpoutTimer = 45000;
|
||||||
WhirlTimer = 18000;//after avery spout
|
WhirlTimer = 18000;//after avery spout
|
||||||
PhaseTimer = 120000;
|
PhaseTimer = 120000;
|
||||||
GeyserTimer = rand()%5000 + 15000;
|
GeyserTimer = rand()%5000 + 15000;
|
||||||
|
CheckTimer = 15000;//give time to get in range when fight starts
|
||||||
|
|
||||||
Submerged = false;
|
Submerged = false;
|
||||||
Spawned = false;
|
Spawned = false;
|
||||||
|
InRange = false;
|
||||||
|
|
||||||
Summons.DespawnAll();
|
Summons.DespawnAll();
|
||||||
|
|
||||||
@@ -139,245 +129,187 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit *who)
|
void JustDied(Unit* Killer)
|
||||||
{
|
{
|
||||||
if (!who || m_creature->getVictim())
|
if (pInstance)
|
||||||
return;
|
|
||||||
|
|
||||||
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who))
|
|
||||||
{
|
|
||||||
float attackRadius = m_creature->GetAttackDistance(who);
|
|
||||||
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
|
|
||||||
AttackStart(who);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnterCombat(Unit *who)
|
|
||||||
{
|
|
||||||
if (pInstance)
|
|
||||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS);
|
|
||||||
|
|
||||||
if (!who || m_creature->getVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who))
|
|
||||||
{
|
|
||||||
float attackRadius = m_creature->GetAttackDistance(who);
|
|
||||||
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
|
|
||||||
AttackStart(who);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* Killer)
|
|
||||||
{
|
|
||||||
if (pInstance)
|
|
||||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, DONE);
|
pInstance->SetData(DATA_THELURKERBELOWEVENT, DONE);
|
||||||
|
|
||||||
Summons.DespawnAll();
|
Summons.DespawnAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rotate(const uint32 diff)
|
void UpdateAI(const uint32 diff)
|
||||||
{
|
{
|
||||||
bool Spout = false;
|
//MAP 548
|
||||||
switch (RotType)
|
//Check if players in water and if in water cast spell
|
||||||
{
|
/*Map* pMap = m_creature->GetMap();
|
||||||
case NOROTATE:
|
if (pMap->IsDungeon() && pInstance && pInstance->GetData(DATA_THELURKERBELOWEVENT) == IN_PROGRESS)
|
||||||
return;
|
{
|
||||||
case CLOCKWISE://20secs for 360turn
|
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||||
//no target if rotating!
|
|
||||||
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
|
||||||
SpoutAngle += (double)diff/20000*(double)M_PI*2;
|
|
||||||
if (SpoutAngle >= M_PI*2)SpoutAngle = 0;
|
|
||||||
m_creature->SetOrientation(SpoutAngle);
|
|
||||||
m_creature->StopMoving();
|
|
||||||
Spout = true;
|
|
||||||
break;
|
|
||||||
case COUNTERCLOCKWISE://20secs for 360turn
|
|
||||||
//no target if rotating!
|
|
||||||
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
|
||||||
SpoutAngle -= (double)diff/20000*(double)M_PI*2;
|
|
||||||
if (SpoutAngle <= 0)SpoutAngle = M_PI*2;
|
|
||||||
m_creature->SetOrientation(SpoutAngle);
|
|
||||||
m_creature->StopMoving();
|
|
||||||
Spout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Spout)
|
if (PlayerList.isEmpty())
|
||||||
return;
|
|
||||||
|
|
||||||
if (RotTimer<diff)//end rotate
|
|
||||||
{
|
|
||||||
RotType = NOROTATE;//set norotate state
|
|
||||||
RotTimer=20000;
|
|
||||||
m_creature->InterruptNonMeleeSpells(false);
|
|
||||||
WhirlTimer = 4000; //whirl directly after spout ends
|
|
||||||
return;
|
|
||||||
}else RotTimer-=diff;
|
|
||||||
|
|
||||||
if (SpoutAnimTimer<diff)
|
|
||||||
{
|
|
||||||
DoCast(m_creature,SPELL_SPOUT_ANIM,true);
|
|
||||||
SpoutAnimTimer = 1000;
|
|
||||||
}else SpoutAnimTimer-=diff;
|
|
||||||
|
|
||||||
Map* pMap = m_creature->GetMap();
|
|
||||||
if (pMap->IsDungeon() && pInstance && pInstance->GetData(DATA_THELURKERBELOWEVENT) == IN_PROGRESS)
|
|
||||||
{
|
|
||||||
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
|
||||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
|
||||||
{
|
|
||||||
Player *target = i->getSource();
|
|
||||||
if (target && target->isAlive() && m_creature->HasInArc((double)diff/20000*(double)M_PI*2,target) && m_creature->IsWithinDist(target, SPOUT_DIST) && !target->IsInWater())
|
|
||||||
DoCast(target,SPELL_SPOUT,true);//only knock back palyers in arc, in 100yards, not in water
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartRotate(Unit* victim)
|
|
||||||
{
|
|
||||||
switch (rand()%2)
|
|
||||||
{
|
|
||||||
case 0: RotType = CLOCKWISE; break;
|
|
||||||
case 1: RotType = COUNTERCLOCKWISE; break;
|
|
||||||
}
|
|
||||||
RotTimer=20000;
|
|
||||||
|
|
||||||
if (victim)
|
|
||||||
SpoutAngle = m_creature->GetAngle(victim);
|
|
||||||
|
|
||||||
m_creature->MonsterTextEmote(EMOTE_SPOUT,0,true);
|
|
||||||
//DoCast(m_creature,SPELL_SPOUT_BREATH);//take breath anim
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(const uint32 diff)
|
|
||||||
{
|
|
||||||
//Return since we have no target
|
|
||||||
if (!UpdateVictim() /*|| !m_creature->getVictim()*/)//rotate resets target
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Check if players in water and if in water cast spell
|
|
||||||
Map* pMap = m_creature->GetMap();
|
|
||||||
if (pMap->IsDungeon() && pInstance && pInstance->GetData(DATA_THELURKERBELOWEVENT) == IN_PROGRESS)
|
|
||||||
{
|
|
||||||
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()->isAlive() && i->getSource()->IsInWater() && !i->getSource()->HasAura(SPELL_SCALDINGWATER))
|
|
||||||
i->getSource()->CastSpell(i->getSource(), SPELL_SCALDINGWATER, true);
|
|
||||||
else if (!i->getSource()->IsInWater())
|
|
||||||
i->getSource()->RemoveAurasDueToSpell(SPELL_SCALDINGWATER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rotate(diff);//always check rotate things
|
|
||||||
if (!Submerged)
|
|
||||||
{
|
|
||||||
if (PhaseTimer < diff)
|
|
||||||
{
|
|
||||||
m_creature->InterruptNonMeleeSpells(false);
|
|
||||||
DoCast(m_creature,SPELL_SUBMERGE);
|
|
||||||
PhaseTimer = 60000;//60secs submerged
|
|
||||||
Submerged = true;
|
|
||||||
}else PhaseTimer-=diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Submerged && RotType == NOROTATE)//is not spouting and not submerged
|
|
||||||
{
|
|
||||||
if (SpoutTimer < diff)
|
|
||||||
{
|
|
||||||
if (m_creature->getVictim() && RotType == NOROTATE)
|
|
||||||
StartRotate(m_creature->getVictim());//start spout and random rotate
|
|
||||||
|
|
||||||
SpoutTimer= 35000;
|
|
||||||
return;
|
|
||||||
}else SpoutTimer -= diff;
|
|
||||||
|
|
||||||
//Whirl directly after a Spout and at random times
|
|
||||||
if (WhirlTimer < diff)
|
|
||||||
{
|
|
||||||
WhirlTimer = rand()%5000 + 15000;
|
|
||||||
DoCast(m_creature,SPELL_WHIRL);
|
|
||||||
WaterboltTimer += 5000;//add 5secs to waterbolt timer, to add some time to run back to boss
|
|
||||||
}else WhirlTimer -= diff;
|
|
||||||
|
|
||||||
if (GeyserTimer < diff)
|
|
||||||
{
|
|
||||||
Unit* target = NULL;
|
|
||||||
target = SelectUnit(SELECT_TARGET_RANDOM,1);
|
|
||||||
|
|
||||||
if (target)
|
|
||||||
DoCast(target,SPELL_GEYSER,true);
|
|
||||||
else
|
|
||||||
target = SelectUnit(SELECT_TARGET_RANDOM,0);
|
|
||||||
if (target)
|
|
||||||
DoCast(target,SPELL_GEYSER,true);
|
|
||||||
|
|
||||||
GeyserTimer = rand()%5000 + 15000;
|
|
||||||
}else GeyserTimer -= diff;
|
|
||||||
|
|
||||||
if (WaterboltTimer < diff)
|
|
||||||
{
|
|
||||||
Unit* target = SelectTarget(SELECT_TARGET_NEAREST,0,14,true);
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
target = SelectUnit(SELECT_TARGET_RANDOM,0);
|
|
||||||
if (target)
|
|
||||||
DoCast(target,SPELL_WATERBOLT);
|
|
||||||
}
|
|
||||||
WaterboltTimer = 3000;
|
|
||||||
}else WaterboltTimer -= diff;
|
|
||||||
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||||
|
{
|
||||||
|
if (i->getSource()->isAlive() && i->getSource()->IsInWater() && !i->getSource()->HasAura(SPELL_SCALDINGWATER))
|
||||||
|
i->getSource()->CastSpell(i->getSource(), SPELL_SCALDINGWATER, true);
|
||||||
|
else if (!i->getSource()->IsInWater())
|
||||||
|
i->getSource()->RemoveAurasDueToSpell(SPELL_SCALDINGWATER);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
}else if (!Submerged)
|
//Rotate(diff);//always check rotate things
|
||||||
return;
|
|
||||||
else if (Submerged)//phase 2, submerged
|
|
||||||
{
|
|
||||||
if (PhaseTimer < diff)
|
|
||||||
{
|
|
||||||
Submerged = false;
|
|
||||||
m_creature->InterruptNonMeleeSpells(false);//shouldn't be any
|
|
||||||
m_creature->RemoveAllAuras();
|
|
||||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
|
||||||
m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
|
|
||||||
m_creature->RemoveFlag(UNIT_FIELD_BYTES_1,9);
|
|
||||||
DoCast(m_creature,SPELL_EMERGE);
|
|
||||||
Spawned = false;
|
|
||||||
SpoutTimer = 4000; // directly cast Spout after emerging!
|
|
||||||
WhirlTimer = 26000;
|
|
||||||
PhaseTimer = 120000;
|
|
||||||
return;
|
|
||||||
}else PhaseTimer-=diff;
|
|
||||||
|
|
||||||
if (!m_creature->isInCombat())
|
//Return since we have no target
|
||||||
DoZoneInCombat();
|
|
||||||
|
|
||||||
if (!Spawned)
|
if(m_creature->getThreatManager().getThreatList().empty())//check if should evade
|
||||||
{
|
{
|
||||||
m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
if(m_creature->isInCombat())
|
||||||
//spawn adds
|
EnterEvadeMode();
|
||||||
for (uint8 i = 0; i < 9; ++i)
|
return;
|
||||||
{
|
}
|
||||||
Creature* Summoned;
|
if (!Submerged)
|
||||||
if (i < 7)
|
{
|
||||||
Summoned = m_creature->SummonCreature(MOB_COILFANG_AMBUSHER,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
if (PhaseTimer < diff)
|
||||||
else Summoned = m_creature->SummonCreature(MOB_COILFANG_GUARDIAN,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
{
|
||||||
|
m_creature->InterruptNonMeleeSpells(false);
|
||||||
|
DoCast(m_creature,SPELL_SUBMERGE);
|
||||||
|
PhaseTimer = 60000;//60secs submerged
|
||||||
|
Submerged = true;
|
||||||
|
}else PhaseTimer-=diff;
|
||||||
|
|
||||||
if (Summoned)
|
if (SpoutTimer < diff)
|
||||||
|
{
|
||||||
|
m_creature->MonsterTextEmote(EMOTE_SPOUT,0,true);
|
||||||
|
if(rand()%2)
|
||||||
|
m_creature->StartAutoRotate(CREATURE_ROTATE_LEFT,20000);
|
||||||
|
else
|
||||||
|
m_creature->StartAutoRotate(CREATURE_ROTATE_RIGHT,20000);
|
||||||
|
SpoutTimer = 45000;
|
||||||
|
WhirlTimer = 20000;//whirl directly after spout
|
||||||
|
RotTimer = 20000;
|
||||||
|
return;
|
||||||
|
}else SpoutTimer -= diff;
|
||||||
|
|
||||||
|
//Whirl directly after a Spout and at random times
|
||||||
|
if (WhirlTimer < diff)
|
||||||
|
{
|
||||||
|
WhirlTimer = 18000;
|
||||||
|
DoCast(m_creature,SPELL_WHIRL);
|
||||||
|
}else WhirlTimer -= diff;
|
||||||
|
|
||||||
|
if(CheckTimer < diff)//check if there are players in melee range
|
||||||
|
{
|
||||||
|
InRange = false;
|
||||||
|
Map* pMap = m_creature->GetMap();
|
||||||
|
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||||
|
if (!PlayerList.isEmpty())
|
||||||
|
{
|
||||||
|
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||||
|
{
|
||||||
|
if(m_creature->IsWithinMeleeRange(i->getSource()))
|
||||||
|
InRange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CheckTimer = 2000;
|
||||||
|
}else CheckTimer -= diff;
|
||||||
|
|
||||||
|
if(RotTimer)
|
||||||
|
{
|
||||||
|
Map* pMap = m_creature->GetMap();
|
||||||
|
if (pMap->IsDungeon())
|
||||||
|
{
|
||||||
|
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||||
|
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||||
|
{
|
||||||
|
if (i->getSource() && i->getSource()->isAlive() && m_creature->HasInArc((double)diff/20000*(double)M_PI*2,i->getSource()) && m_creature->IsWithinDist(i->getSource(), SPOUT_DIST) && !i->getSource()->IsInWater())
|
||||||
|
DoCast(i->getSource(),SPELL_SPOUT,true);//only knock back palyers in arc, in 100yards, not in water
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SpoutAnimTimer < diff)
|
||||||
|
{
|
||||||
|
DoCast(m_creature,SPELL_SPOUT_ANIM,true);
|
||||||
|
SpoutAnimTimer = 1000;
|
||||||
|
}else SpoutAnimTimer -= diff;
|
||||||
|
|
||||||
|
if(RotTimer < diff)
|
||||||
|
{
|
||||||
|
RotTimer = 0;
|
||||||
|
}else RotTimer -= diff;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GeyserTimer < diff)
|
||||||
|
{
|
||||||
|
Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1);
|
||||||
|
if (!target && m_creature->getVictim())
|
||||||
|
target = m_creature->getVictim();
|
||||||
|
if (target)
|
||||||
|
DoCast(target,SPELL_GEYSER,true);
|
||||||
|
GeyserTimer = rand()%5000 + 15000;
|
||||||
|
}else GeyserTimer -= diff;
|
||||||
|
|
||||||
|
if(!InRange)//if on players in melee range cast Waterbolt
|
||||||
|
{
|
||||||
|
if (WaterboltTimer < diff)
|
||||||
|
{
|
||||||
|
Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);
|
||||||
|
if (!target && m_creature->getVictim())
|
||||||
|
target = m_creature->getVictim();
|
||||||
|
if (target)
|
||||||
|
DoCast(target,SPELL_WATERBOLT,true);
|
||||||
|
WaterboltTimer = 3000;
|
||||||
|
}else WaterboltTimer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
|
||||||
|
}else//submerged
|
||||||
|
{
|
||||||
|
if (PhaseTimer < diff)
|
||||||
|
{
|
||||||
|
Submerged = false;
|
||||||
|
m_creature->InterruptNonMeleeSpells(false);//shouldn't be any
|
||||||
|
m_creature->RemoveAllAuras();
|
||||||
|
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
|
||||||
|
m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
|
||||||
|
DoCast(m_creature,SPELL_EMERGE,true);
|
||||||
|
Spawned = false;
|
||||||
|
SpoutTimer = 3000; // directly cast Spout after emerging!
|
||||||
|
PhaseTimer = 120000;
|
||||||
|
return;
|
||||||
|
}else PhaseTimer-=diff;
|
||||||
|
|
||||||
|
if(m_creature->getThreatManager().getThreatList().empty())//check if should evade
|
||||||
|
{
|
||||||
|
EnterEvadeMode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!m_creature->isInCombat())
|
||||||
|
DoZoneInCombat();
|
||||||
|
|
||||||
|
if (!Spawned)
|
||||||
|
{
|
||||||
|
m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
|
||||||
|
//spawn adds
|
||||||
|
for (uint8 i = 0; i < 9; ++i)
|
||||||
|
{
|
||||||
|
Creature* Summoned;
|
||||||
|
if (i < 6)
|
||||||
|
Summoned = m_creature->SummonCreature(MOB_COILFANG_AMBUSHER,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||||
|
else Summoned = m_creature->SummonCreature(MOB_COILFANG_GUARDIAN,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||||
|
|
||||||
|
if (Summoned)
|
||||||
Summons.Summon(Summoned);
|
Summons.Summon(Summoned);
|
||||||
Spawned = true;
|
}
|
||||||
}
|
Spawned = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI_mob_coilfang_guardian(Creature* pCreature)
|
CreatureAI* GetAI_mob_coilfang_guardian(Creature* pCreature)
|
||||||
@@ -427,7 +359,7 @@ struct TRINITY_DLL_DECL mob_coilfang_ambusherAI : public Scripted_NoMovementAI
|
|||||||
{
|
{
|
||||||
if (!who || m_creature->getVictim()) return;
|
if (!who || m_creature->getVictim()) return;
|
||||||
|
|
||||||
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who))
|
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who) && m_creature->IsWithinDistInMap(who, 45))
|
||||||
{
|
{
|
||||||
AttackStart(who);
|
AttackStart(who);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user