Fix Script Violet Hold/Ichoron.
Fixes issue #33. - implement Dehydration achievement - go frenzy at 25% health and no longer cast bubble - loose health when water elements are killed (3%. may still need to be adjusted). - use spawn loc for adds --HG-- branch : trunk
This commit is contained in:
@@ -17,25 +17,26 @@
|
|||||||
/* Script Data Start
|
/* Script Data Start
|
||||||
SDName: Boss ichoron
|
SDName: Boss ichoron
|
||||||
SDAuthor: ckegg
|
SDAuthor: ckegg
|
||||||
SD%Complete:
|
SD%Complete: 80%
|
||||||
SDComment:
|
SDComment: TODO: better spawn location for adds
|
||||||
SDCategory:
|
SDCategory:
|
||||||
Script Data End */
|
Script Data End */
|
||||||
|
|
||||||
#include "ScriptedPch.h"
|
#include "ScriptedPch.h"
|
||||||
#include "violet_hold.h"
|
#include "violet_hold.h"
|
||||||
|
#include "SpellId.h"
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
{
|
{
|
||||||
SPELL_DRAINED = 59820,
|
SPELL_DRAINED = SPELL_DRAINED_59820,
|
||||||
SPELL_FRENZY = 54312,
|
SPELL_FRENZY = SPELL_FRENZY_54312,
|
||||||
SPELL_FRENZY_H = 59522,
|
SPELL_FRENZY_H = SPELL_FRENZY_59522,
|
||||||
SPELL_PROTECTIVE_BUBBLE = 54306,
|
SPELL_PROTECTIVE_BUBBLE = SPELL_PROTECTIVE_BUBBLE_54306,
|
||||||
SPELL_WATER_BLAST = 54237,
|
SPELL_WATER_BLAST = SPELL_WATER_BLAST_54237,
|
||||||
SPELL_WATER_BLAST_H = 59520,
|
SPELL_WATER_BLAST_H = SPELL_WATER_BLAST_59520,
|
||||||
SPELL_WATER_BOLT_VOLLEY = 54241,
|
SPELL_WATER_BOLT_VOLLEY = SPELL_WATER_BOLT_VOLLEY_54241,
|
||||||
SPELL_WATER_BOLT_VOLLEY_H = 59521,
|
SPELL_WATER_BOLT_VOLLEY_H = SPELL_WATER_BOLT_VOLLEY_59521,
|
||||||
SPELL_SPLASH = 59516,
|
SPELL_SPLASH = SPELL_SPLASH_59516,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum IchoronCreatures
|
enum IchoronCreatures
|
||||||
@@ -57,47 +58,53 @@ enum Yells
|
|||||||
SAY_BUBBLE = -1608026
|
SAY_BUBBLE = -1608026
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Locations
|
enum Achievements
|
||||||
{
|
{
|
||||||
float x, y, z;
|
ACHIEVEMENT_DEHYDRATION = 2041,
|
||||||
uint32 id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Locations PortalLoc[]=
|
enum Actions
|
||||||
{
|
{
|
||||||
{1857.125, 763.295, 38.654},
|
ACTION_WATER_ELEMENT_HIT = 1,
|
||||||
{1925.480, 849.981, 47.174},
|
ACTION_WATER_ELEMENT_KILLED = 2,
|
||||||
{1892.737, 744.589, 47.666},
|
};
|
||||||
{1878.198, 850.005, 43.333},
|
|
||||||
{1909.381, 806.796, 38.645},
|
// TODO get those positions from spawn of creature 29326
|
||||||
{1936.101, 802.950, 52.417},
|
#define MAX_SPAWN_LOC 5
|
||||||
|
static Position SpawnLoc[MAX_SPAWN_LOC]=
|
||||||
|
{
|
||||||
|
{1840.64, 795.407, 44.079, 1.676},
|
||||||
|
{1886.24, 757.733, 47.750, 5.201},
|
||||||
|
{1877.91, 845.915, 43.417, 3.560},
|
||||||
|
{1918.97, 850.645, 47.225, 4.136},
|
||||||
|
{1935.50, 796.224, 52.492, 4.224},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
|
struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
|
||||||
{
|
{
|
||||||
boss_ichoronAI(Creature* pCreature) : ScriptedAI(pCreature)
|
boss_ichoronAI(Creature* pCreature) : ScriptedAI(pCreature), m_waterElements(pCreature)
|
||||||
{
|
{
|
||||||
pInstance = pCreature->GetInstanceData();
|
pInstance = pCreature->GetInstanceData();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bIsExploded;
|
bool bIsExploded;
|
||||||
bool bIsFrenzy;
|
bool bIsFrenzy;
|
||||||
|
bool bAchievement;
|
||||||
|
|
||||||
uint32 uiBuubleChecker_Timer;
|
uint32 uiBubbleCheckerTimer;
|
||||||
uint32 uiWaterBoltVolley_Timer;
|
uint32 uiWaterBoltVolleyTimer;
|
||||||
uint32 uiShowup_Counter;
|
|
||||||
|
|
||||||
ScriptedInstance* pInstance;
|
ScriptedInstance* pInstance;
|
||||||
|
|
||||||
std::list<uint64> m_lWaterElementsGUIDList;
|
SummonList m_waterElements;
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
bIsExploded = false;
|
bIsExploded = false;
|
||||||
bIsFrenzy = false;
|
bIsFrenzy = false;
|
||||||
uiBuubleChecker_Timer = 1000;
|
bAchievement = true;
|
||||||
uiWaterBoltVolley_Timer = urand(10000, 15000);
|
uiBubbleCheckerTimer = 1000;
|
||||||
uiShowup_Counter = 0;
|
uiWaterBoltVolleyTimer = urand(10000, 15000);
|
||||||
|
|
||||||
m_creature->SetVisibility(VISIBILITY_ON);
|
m_creature->SetVisibility(VISIBILITY_ON);
|
||||||
DespawnWaterElements();
|
DespawnWaterElements();
|
||||||
@@ -140,32 +147,45 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterElementHit()
|
void DoAction(const int32 param)
|
||||||
{
|
{
|
||||||
|
if (!m_creature->isAlive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case ACTION_WATER_ELEMENT_HIT:
|
||||||
m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.01);
|
m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.01);
|
||||||
|
|
||||||
if (bIsExploded)
|
if (bIsExploded)
|
||||||
{
|
DoExplodeCompleted();
|
||||||
DoCast(m_creature, SPELL_PROTECTIVE_BUBBLE);
|
|
||||||
bIsExploded = false;
|
bAchievement = false;
|
||||||
m_creature->SetVisibility(VISIBILITY_ON);
|
break;
|
||||||
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
|
case ACTION_WATER_ELEMENT_KILLED:
|
||||||
|
uint32 damage = (m_creature->GetMaxHealth()*3)/100;
|
||||||
|
m_creature->SetHealth(m_creature->GetHealth() - damage);
|
||||||
|
m_creature->LowerPlayerDamageReq(damage);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DespawnWaterElements()
|
void DespawnWaterElements()
|
||||||
{
|
{
|
||||||
if (m_lWaterElementsGUIDList.empty())
|
m_waterElements.DespawnAll();
|
||||||
return;
|
}
|
||||||
|
|
||||||
for(std::list<uint64>::iterator itr = m_lWaterElementsGUIDList.begin(); itr != m_lWaterElementsGUIDList.end(); ++itr)
|
// call when explode shall stop.
|
||||||
|
// either when "hit" by a bubble, or when there is no bubble left.
|
||||||
|
void DoExplodeCompleted()
|
||||||
{
|
{
|
||||||
if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
|
bIsExploded = false;
|
||||||
{
|
|
||||||
if (pTemp->isAlive())
|
if (!HealthBelowPct(25))
|
||||||
pTemp->Kill(pTemp, false);
|
DoCast(m_creature, SPELL_PROTECTIVE_BUBBLE, true);
|
||||||
}
|
|
||||||
}
|
m_creature->SetVisibility(VISIBILITY_ON);
|
||||||
m_lWaterElementsGUIDList.clear();
|
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* pWho) {}
|
void MoveInLineOfSight(Unit* pWho) {}
|
||||||
@@ -176,68 +196,62 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
|
||||||
|
{
|
||||||
|
DoCast(m_creature, DUNGEON_MODE(SPELL_FRENZY, SPELL_FRENZY_H), true);
|
||||||
|
bIsFrenzy = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!bIsFrenzy)
|
if (!bIsFrenzy)
|
||||||
{
|
{
|
||||||
if (uiBuubleChecker_Timer < uiDiff)
|
if (uiBubbleCheckerTimer <= uiDiff)
|
||||||
{
|
{
|
||||||
if (!bIsExploded)
|
if (!bIsExploded)
|
||||||
{
|
{
|
||||||
if (!m_creature->HasAura(SPELL_PROTECTIVE_BUBBLE, 0))
|
if (!m_creature->HasAura(SPELL_PROTECTIVE_BUBBLE, 0))
|
||||||
{
|
{
|
||||||
DoCast(m_creature, DUNGEON_MODE(SPELL_WATER_BLAST, SPELL_WATER_BLAST_H));
|
DoCast(m_creature, DUNGEON_MODE(SPELL_WATER_BLAST, SPELL_WATER_BLAST_H));
|
||||||
//DoCast(m_creature, SPELL_DRAINED);
|
DoCast(m_creature, SPELL_DRAINED);
|
||||||
bIsExploded = true;
|
bIsExploded = true;
|
||||||
uiShowup_Counter = 0;
|
|
||||||
m_creature->AttackStop();
|
m_creature->AttackStop();
|
||||||
m_creature->SetVisibility(VISIBILITY_OFF);
|
m_creature->SetVisibility(VISIBILITY_OFF);
|
||||||
for(uint8 i = 0; i < 10; i++)
|
for(uint8 i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
//int tmp = urand(0, 5);
|
int tmp = urand(0, MAX_SPAWN_LOC-1);
|
||||||
//m_creature->SummonCreature(NPC_ICHOR_GLOBULE, PortalLoc[tmp].x, PortalLoc[tmp].y, PortalLoc[tmp].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
m_creature->SummonCreature(NPC_ICHOR_GLOBULE, SpawnLoc[tmp], TEMPSUMMON_CORPSE_DESPAWN);
|
||||||
m_creature->SummonCreature(NPC_ICHOR_GLOBULE, m_creature->GetPositionX()-10+rand()%20, m_creature->GetPositionY()-10+rand()%20, m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uiBuubleChecker_Timer = 3000;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool bIsWaterElementsAlive = false;
|
bool bIsWaterElementsAlive = false;
|
||||||
++uiShowup_Counter;
|
if (!m_waterElements.empty())
|
||||||
if (!m_lWaterElementsGUIDList.empty())
|
|
||||||
{
|
{
|
||||||
for(std::list<uint64>::iterator itr = m_lWaterElementsGUIDList.begin(); itr != m_lWaterElementsGUIDList.end(); ++itr)
|
for (std::list<uint64>::iterator itr = m_waterElements.begin(); itr != m_waterElements.end(); ++itr)
|
||||||
if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
|
if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
|
||||||
if (pTemp->isAlive())
|
if (pTemp->isAlive())
|
||||||
bIsWaterElementsAlive = true;
|
|
||||||
}
|
|
||||||
if (!bIsWaterElementsAlive || uiShowup_Counter > 20)
|
|
||||||
{
|
{
|
||||||
DoCast(m_creature, SPELL_PROTECTIVE_BUBBLE);
|
bIsWaterElementsAlive = true;
|
||||||
bIsExploded = false;
|
break;
|
||||||
uiShowup_Counter = 0;
|
|
||||||
m_creature->SetVisibility(VISIBILITY_ON);
|
|
||||||
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
|
|
||||||
}
|
|
||||||
uiBuubleChecker_Timer = 1000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else uiBuubleChecker_Timer -= uiDiff;
|
|
||||||
|
if (!bIsWaterElementsAlive)
|
||||||
|
DoExplodeCompleted();
|
||||||
|
}
|
||||||
|
uiBubbleCheckerTimer = 1000;
|
||||||
|
}
|
||||||
|
else uiBubbleCheckerTimer -= uiDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bIsExploded)
|
if (!bIsExploded)
|
||||||
{
|
{
|
||||||
if (uiWaterBoltVolley_Timer < uiDiff)
|
if (uiWaterBoltVolleyTimer <= uiDiff)
|
||||||
{
|
{
|
||||||
DoCast(m_creature, DUNGEON_MODE(SPELL_WATER_BOLT_VOLLEY, SPELL_WATER_BOLT_VOLLEY_H));
|
DoCast(m_creature, DUNGEON_MODE(SPELL_WATER_BOLT_VOLLEY, SPELL_WATER_BOLT_VOLLEY_H));
|
||||||
uiWaterBoltVolley_Timer = urand(10000, 15000);
|
uiWaterBoltVolleyTimer = urand(10000, 15000);
|
||||||
}
|
|
||||||
else uiWaterBoltVolley_Timer -= uiDiff;
|
|
||||||
|
|
||||||
if (!bIsFrenzy && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25)
|
|
||||||
{
|
|
||||||
DoCast(m_creature, DUNGEON_MODE(SPELL_FRENZY, SPELL_FRENZY_H));
|
|
||||||
bIsFrenzy = true;
|
|
||||||
}
|
}
|
||||||
|
else uiWaterBoltVolleyTimer -= uiDiff;
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
@@ -247,10 +261,19 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
|
|||||||
{
|
{
|
||||||
DoScriptText(SAY_DEATH, m_creature);
|
DoScriptText(SAY_DEATH, m_creature);
|
||||||
|
|
||||||
|
if (bIsExploded)
|
||||||
|
{
|
||||||
|
bIsExploded = false;
|
||||||
|
m_creature->SetVisibility(VISIBILITY_ON);
|
||||||
|
}
|
||||||
|
|
||||||
DespawnWaterElements();
|
DespawnWaterElements();
|
||||||
|
|
||||||
if (pInstance)
|
if (pInstance)
|
||||||
{
|
{
|
||||||
|
if (IsHeroic() && bAchievement)
|
||||||
|
pInstance->DoCompleteAchievement(ACHIEVEMENT_DEHYDRATION);
|
||||||
|
|
||||||
if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
|
if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
|
||||||
{
|
{
|
||||||
pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
|
||||||
@@ -266,9 +289,15 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
|
|||||||
|
|
||||||
void JustSummoned(Creature* pSummoned)
|
void JustSummoned(Creature* pSummoned)
|
||||||
{
|
{
|
||||||
pSummoned->SetSpeed(MOVE_RUN, 0.2f);
|
pSummoned->SetSpeed(MOVE_RUN, 0.3f);
|
||||||
pSummoned->GetMotionMaster()->MoveFollow(m_creature, 0, 0);
|
pSummoned->GetMotionMaster()->MoveFollow(m_creature, 0, 0);
|
||||||
m_lWaterElementsGUIDList.push_back(pSummoned->GetGUID());
|
m_waterElements.push_back(pSummoned->GetGUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SummonedCreatureDespawn(Creature *pSummoned)
|
||||||
|
{
|
||||||
|
m_waterElements.remove(pSummoned->GetGUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
void KilledUnit(Unit *victim)
|
void KilledUnit(Unit *victim)
|
||||||
@@ -313,12 +342,11 @@ struct TRINITY_DLL_DECL mob_ichor_globuleAI : public ScriptedAI
|
|||||||
{
|
{
|
||||||
if (Creature* pIchoron = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ICHORON))))
|
if (Creature* pIchoron = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ICHORON))))
|
||||||
{
|
{
|
||||||
//maybe 12.0f is not offlike, maybe 2.00f ?
|
if (m_creature->IsWithinDist(pIchoron, 2.0f , false))
|
||||||
float fDistance = m_creature->GetDistance(pIchoron);
|
|
||||||
if (m_creature->IsWithinDist(pIchoron, fDistance <= 12.0f , false))
|
|
||||||
{
|
{
|
||||||
((boss_ichoronAI*)pIchoron->AI())->WaterElementHit();
|
if (pIchoron->AI())
|
||||||
m_creature->Kill(m_creature, false);
|
pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_HIT);
|
||||||
|
m_creature->ForcedDespawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,6 +358,9 @@ struct TRINITY_DLL_DECL mob_ichor_globuleAI : public ScriptedAI
|
|||||||
void JustDied(Unit* pKiller)
|
void JustDied(Unit* pKiller)
|
||||||
{
|
{
|
||||||
DoCast(m_creature, SPELL_SPLASH);
|
DoCast(m_creature, SPELL_SPLASH);
|
||||||
|
if (Creature* pIchoron = ((Creature*)Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ICHORON))))
|
||||||
|
if (pIchoron->AI())
|
||||||
|
pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_KILLED);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user