aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrazom62 <none@none>2010-01-31 16:23:28 +0100
committerTrazom62 <none@none>2010-01-31 16:23:28 +0100
commitd435366bceaf6f04dfe226e0838c2893519db5be (patch)
treeef35fae53d2f2e141db25e66077e4bd92a8ad0b9
parent4732618c22c7835a79672a1635454d1d61fcf3a7 (diff)
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
-rw-r--r--src/scripts/northrend/violet_hold/boss_ichoron.cpp201
1 files changed, 116 insertions, 85 deletions
diff --git a/src/scripts/northrend/violet_hold/boss_ichoron.cpp b/src/scripts/northrend/violet_hold/boss_ichoron.cpp
index 78cac6b455c..8c51340acc4 100644
--- a/src/scripts/northrend/violet_hold/boss_ichoron.cpp
+++ b/src/scripts/northrend/violet_hold/boss_ichoron.cpp
@@ -17,25 +17,26 @@
/* Script Data Start
SDName: Boss ichoron
SDAuthor: ckegg
-SD%Complete:
-SDComment:
+SD%Complete: 80%
+SDComment: TODO: better spawn location for adds
SDCategory:
Script Data End */
#include "ScriptedPch.h"
#include "violet_hold.h"
+#include "SpellId.h"
enum Spells
{
- SPELL_DRAINED = 59820,
- SPELL_FRENZY = 54312,
- SPELL_FRENZY_H = 59522,
- SPELL_PROTECTIVE_BUBBLE = 54306,
- SPELL_WATER_BLAST = 54237,
- SPELL_WATER_BLAST_H = 59520,
- SPELL_WATER_BOLT_VOLLEY = 54241,
- SPELL_WATER_BOLT_VOLLEY_H = 59521,
- SPELL_SPLASH = 59516,
+ SPELL_DRAINED = SPELL_DRAINED_59820,
+ SPELL_FRENZY = SPELL_FRENZY_54312,
+ SPELL_FRENZY_H = SPELL_FRENZY_59522,
+ SPELL_PROTECTIVE_BUBBLE = SPELL_PROTECTIVE_BUBBLE_54306,
+ SPELL_WATER_BLAST = SPELL_WATER_BLAST_54237,
+ SPELL_WATER_BLAST_H = SPELL_WATER_BLAST_59520,
+ SPELL_WATER_BOLT_VOLLEY = SPELL_WATER_BOLT_VOLLEY_54241,
+ SPELL_WATER_BOLT_VOLLEY_H = SPELL_WATER_BOLT_VOLLEY_59521,
+ SPELL_SPLASH = SPELL_SPLASH_59516,
};
enum IchoronCreatures
@@ -57,47 +58,53 @@ enum Yells
SAY_BUBBLE = -1608026
};
-struct Locations
+enum Achievements
{
- float x, y, z;
- uint32 id;
+ ACHIEVEMENT_DEHYDRATION = 2041,
};
-static Locations PortalLoc[]=
+enum Actions
{
- {1857.125, 763.295, 38.654},
- {1925.480, 849.981, 47.174},
- {1892.737, 744.589, 47.666},
- {1878.198, 850.005, 43.333},
- {1909.381, 806.796, 38.645},
- {1936.101, 802.950, 52.417},
+ ACTION_WATER_ELEMENT_HIT = 1,
+ ACTION_WATER_ELEMENT_KILLED = 2,
+};
+
+// TODO get those positions from spawn of creature 29326
+#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
{
- boss_ichoronAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_ichoronAI(Creature* pCreature) : ScriptedAI(pCreature), m_waterElements(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
bool bIsExploded;
bool bIsFrenzy;
+ bool bAchievement;
- uint32 uiBuubleChecker_Timer;
- uint32 uiWaterBoltVolley_Timer;
- uint32 uiShowup_Counter;
+ uint32 uiBubbleCheckerTimer;
+ uint32 uiWaterBoltVolleyTimer;
ScriptedInstance* pInstance;
- std::list<uint64> m_lWaterElementsGUIDList;
+ SummonList m_waterElements;
void Reset()
{
bIsExploded = false;
bIsFrenzy = false;
- uiBuubleChecker_Timer = 1000;
- uiWaterBoltVolley_Timer = urand(10000, 15000);
- uiShowup_Counter = 0;
+ bAchievement = true;
+ uiBubbleCheckerTimer = 1000;
+ uiWaterBoltVolleyTimer = urand(10000, 15000);
m_creature->SetVisibility(VISIBILITY_ON);
DespawnWaterElements();
@@ -140,32 +147,45 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
}
}
- void WaterElementHit()
+ void DoAction(const int32 param)
{
- m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.01);
- if (bIsExploded)
+ if (!m_creature->isAlive())
+ return;
+
+ switch(param)
{
- DoCast(m_creature, SPELL_PROTECTIVE_BUBBLE);
- bIsExploded = false;
- m_creature->SetVisibility(VISIBILITY_ON);
- m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ case ACTION_WATER_ELEMENT_HIT:
+ m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.01);
+
+ if (bIsExploded)
+ DoExplodeCompleted();
+
+ bAchievement = false;
+ break;
+ 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()
{
- if (m_lWaterElementsGUIDList.empty())
- return;
+ m_waterElements.DespawnAll();
+ }
- for(std::list<uint64>::iterator itr = m_lWaterElementsGUIDList.begin(); itr != m_lWaterElementsGUIDList.end(); ++itr)
- {
- if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
- {
- if (pTemp->isAlive())
- pTemp->Kill(pTemp, false);
- }
- }
- m_lWaterElementsGUIDList.clear();
+ // call when explode shall stop.
+ // either when "hit" by a bubble, or when there is no bubble left.
+ void DoExplodeCompleted()
+ {
+ bIsExploded = false;
+
+ if (!HealthBelowPct(25))
+ DoCast(m_creature, SPELL_PROTECTIVE_BUBBLE, true);
+
+ m_creature->SetVisibility(VISIBILITY_ON);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
}
void MoveInLineOfSight(Unit* pWho) {}
@@ -176,70 +196,64 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
if (!UpdateVictim())
return;
+ if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
+ {
+ DoCast(m_creature, DUNGEON_MODE(SPELL_FRENZY, SPELL_FRENZY_H), true);
+ bIsFrenzy = true;
+ }
+
if (!bIsFrenzy)
{
- if (uiBuubleChecker_Timer < uiDiff)
+ if (uiBubbleCheckerTimer <= uiDiff)
{
if (!bIsExploded)
{
if (!m_creature->HasAura(SPELL_PROTECTIVE_BUBBLE, 0))
{
DoCast(m_creature, DUNGEON_MODE(SPELL_WATER_BLAST, SPELL_WATER_BLAST_H));
- //DoCast(m_creature, SPELL_DRAINED);
+ DoCast(m_creature, SPELL_DRAINED);
bIsExploded = true;
- uiShowup_Counter = 0;
m_creature->AttackStop();
m_creature->SetVisibility(VISIBILITY_OFF);
for(uint8 i = 0; i < 10; i++)
{
- //int tmp = urand(0, 5);
- //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, m_creature->GetPositionX()-10+rand()%20, m_creature->GetPositionY()-10+rand()%20, m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ int tmp = urand(0, MAX_SPAWN_LOC-1);
+ m_creature->SummonCreature(NPC_ICHOR_GLOBULE, SpawnLoc[tmp], TEMPSUMMON_CORPSE_DESPAWN);
}
}
- uiBuubleChecker_Timer = 3000;
}
else
{
bool bIsWaterElementsAlive = false;
- ++uiShowup_Counter;
- if (!m_lWaterElementsGUIDList.empty())
+ if (!m_waterElements.empty())
{
- for(std::list<uint64>::iterator itr = m_lWaterElementsGUIDList.begin(); itr != m_lWaterElementsGUIDList.end(); ++itr)
- if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
+ for (std::list<uint64>::iterator itr = m_waterElements.begin(); itr != m_waterElements.end(); ++itr)
+ if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
if (pTemp->isAlive())
+ {
bIsWaterElementsAlive = true;
+ break;
+ }
}
- if (!bIsWaterElementsAlive || uiShowup_Counter > 20)
- {
- DoCast(m_creature, SPELL_PROTECTIVE_BUBBLE);
- bIsExploded = false;
- uiShowup_Counter = 0;
- m_creature->SetVisibility(VISIBILITY_ON);
- m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
- }
- uiBuubleChecker_Timer = 1000;
+
+ if (!bIsWaterElementsAlive)
+ DoExplodeCompleted();
}
+ uiBubbleCheckerTimer = 1000;
}
- else uiBuubleChecker_Timer -= uiDiff;
+ else uiBubbleCheckerTimer -= uiDiff;
}
if (!bIsExploded)
{
- if (uiWaterBoltVolley_Timer < uiDiff)
+ if (uiWaterBoltVolleyTimer <= uiDiff)
{
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;
+ else uiWaterBoltVolleyTimer -= uiDiff;
- if (!bIsFrenzy && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25)
- {
- DoCast(m_creature, DUNGEON_MODE(SPELL_FRENZY, SPELL_FRENZY_H));
- bIsFrenzy = true;
- }
-
- DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
}
}
@@ -247,10 +261,19 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
{
DoScriptText(SAY_DEATH, m_creature);
+ if (bIsExploded)
+ {
+ bIsExploded = false;
+ m_creature->SetVisibility(VISIBILITY_ON);
+ }
+
DespawnWaterElements();
if (pInstance)
{
+ if (IsHeroic() && bAchievement)
+ pInstance->DoCompleteAchievement(ACHIEVEMENT_DEHYDRATION);
+
if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
{
pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
@@ -266,9 +289,15 @@ struct TRINITY_DLL_DECL boss_ichoronAI : public ScriptedAI
void JustSummoned(Creature* pSummoned)
{
- pSummoned->SetSpeed(MOVE_RUN, 0.2f);
+ pSummoned->SetSpeed(MOVE_RUN, 0.3f);
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)
@@ -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))))
{
- //maybe 12.0f is not offlike, maybe 2.00f ?
- float fDistance = m_creature->GetDistance(pIchoron);
- if (m_creature->IsWithinDist(pIchoron, fDistance <= 12.0f , false))
+ if (m_creature->IsWithinDist(pIchoron, 2.0f , false))
{
- ((boss_ichoronAI*)pIchoron->AI())->WaterElementHit();
- m_creature->Kill(m_creature, false);
+ if (pIchoron->AI())
+ 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)
{
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);
}
};