diff options
author | Trazom62 <none@none> | 2010-04-03 16:51:56 +0200 |
---|---|---|
committer | Trazom62 <none@none> | 2010-04-03 16:51:56 +0200 |
commit | bcfd44f9781f58b997c28922fa03a78db8a90bc9 (patch) | |
tree | 16623f9d925a98e718e18f1265facf1c118f9a10 /src | |
parent | 1f477b49c325618245e856714cfb1f191f48a64f (diff) |
Fix Script HoL/Ionar.
Fixes issue #1132.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp | 238 |
1 files changed, 72 insertions, 166 deletions
diff --git a/src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp b/src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp index c3d3656d9be..67f090da32a 100644 --- a/src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp +++ b/src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp @@ -60,50 +60,42 @@ enum eEnums struct boss_ionarAI : public ScriptedAI { - boss_ionarAI(Creature *pCreature) : ScriptedAI(pCreature) + boss_ionarAI(Creature *pCreature) : ScriptedAI(pCreature), m_sparkList(pCreature) { m_pInstance = pCreature->GetInstanceData(); } ScriptedInstance* m_pInstance; - std::list<uint64> m_lSparkGUIDList; + SummonList m_sparkList; bool m_bIsSplitPhase; - uint32 m_uiSplit_Timer; - uint32 m_uiSparkAtHomeCount; + uint32 m_uiSplitTimer; - uint32 m_uiStaticOverload_Timer; - uint32 m_uiBallLightning_Timer; + uint32 m_uiStaticOverloadTimer; + uint32 m_uiBallLightningTimer; uint32 m_uiHealthAmountModifier; void Reset() { - m_lSparkGUIDList.clear(); + m_sparkList.DespawnAll(); m_bIsSplitPhase = true; - m_uiSplit_Timer = 25000; - m_uiSparkAtHomeCount = 0; + m_uiSplitTimer = 25000; - m_uiStaticOverload_Timer = 5000 + rand()%1000; - m_uiBallLightning_Timer = 10000 + rand()%1000; + m_uiStaticOverloadTimer = urand(5000, 6000); + m_uiBallLightningTimer = urand(10000, 11000); m_uiHealthAmountModifier = 1; - if (m_creature->GetVisibility() == VISIBILITY_OFF) - m_creature->SetVisibility(VISIBILITY_ON); - } - - void AttackedBy(Unit* pAttacker) - { - if (m_creature->getVictim()) - return; + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE); if (m_creature->GetVisibility() == VISIBILITY_OFF) - return; + m_creature->SetVisibility(VISIBILITY_ON); - AttackStart(pAttacker); + if (m_pInstance) + m_pInstance->SetData(TYPE_IONAR, NOT_STARTED); } void EnterCombat(Unit* who) @@ -114,29 +106,11 @@ struct boss_ionarAI : public ScriptedAI m_pInstance->SetData(TYPE_IONAR, IN_PROGRESS); } - void JustReachedHome() - { - if (m_pInstance) - m_pInstance->SetData(TYPE_IONAR, NOT_STARTED); - } - - void AttackStart(Unit* pWho) - { - if (m_creature->Attack(pWho, true)) - { - m_creature->AddThreat(pWho, 0.0f); - m_creature->SetInCombatWith(pWho); - pWho->SetInCombatWith(m_creature); - - if (m_creature->GetVisibility() != VISIBILITY_OFF) - m_creature->GetMotionMaster()->MoveChase(pWho); - } - } - void JustDied(Unit* killer) { DoScriptText(SAY_DEATH, m_creature); - DespawnSpark(); + + m_sparkList.DespawnAll(); if (m_pInstance) m_pInstance->SetData(TYPE_IONAR, DONE); @@ -147,92 +121,74 @@ struct boss_ionarAI : public ScriptedAI DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature); } - void DespawnSpark() - { - if (m_lSparkGUIDList.empty()) - return; - - for (std::list<uint64>::const_iterator itr = m_lSparkGUIDList.begin(); itr != m_lSparkGUIDList.end(); ++itr) - { - if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) - { - if (pTemp->isAlive()) - pTemp->ForcedDespawn(); - } - } - m_lSparkGUIDList.clear(); - } - //make sparks come back void CallBackSparks() { //should never be empty here, but check - if (m_lSparkGUIDList.empty()) + if (m_sparkList.empty()) return; Position pos; m_creature->GetPosition(&pos); - for (std::list<uint64>::const_iterator itr = m_lSparkGUIDList.begin(); itr != m_lSparkGUIDList.end(); ++itr) + for (std::list<uint64>::const_iterator itr = m_sparkList.begin(); itr != m_sparkList.end(); ++itr) { if (Creature* pSpark = Unit::GetCreature(*m_creature, *itr)) { if (pSpark->isAlive()) { - // Interrupt attack to prevent further attacking player - pSpark->AttackStop(); - - if (pSpark->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) - pSpark->GetMotionMaster()->MovementExpired(); - - //now handle by db - //pSpark->SetSpeed(MOVE_RUN, pSpark->GetCreatureInfo()->speed * 2); + pSpark->SetSpeed(MOVE_RUN, 2.0f); + pSpark->GetMotionMaster()->Clear(); pSpark->GetMotionMaster()->MovePoint(POINT_CALLBACK, pos); } + else + pSpark->ForcedDespawn(); } } } - void RegisterSparkAtHome() + void DamageTaken(Unit *pDoneBy, uint32 &uiDamage) { - ++m_uiSparkAtHomeCount; + if (m_creature->GetVisibility() == VISIBILITY_OFF) + uiDamage = 0; } void JustSummoned(Creature* pSummoned) { if (pSummoned->GetEntry() == NPC_SPARK_OF_IONAR) { - pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_SPARK_VISUAL_TRIGGER_N,SPELL_SPARK_VISUAL_TRIGGER_H), true); + m_sparkList.Summon(pSummoned); - // You can do nothing against these npcs but only run away! - // They must never get damage at all! - pSummoned->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, true); - pSummoned->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); + pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_SPARK_VISUAL_TRIGGER_N,SPELL_SPARK_VISUAL_TRIGGER_H), true); Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - - if (m_creature->getVictim()) - pSummoned->AI()->AttackStart(pTarget ? pTarget : m_creature->getVictim()); - - m_lSparkGUIDList.push_back(pSummoned->GetGUID()); + if (pTarget) + { + pSummoned->SetInCombatWith(pTarget); + pSummoned->GetMotionMaster()->Clear(); + pSummoned->GetMotionMaster()->MoveFollow(pTarget, 0.0f, 0.0f); + } } } + void SummonedCreatureDespawn(Creature *pSummoned) + { + if (pSummoned->GetEntry() == NPC_SPARK_OF_IONAR) + m_sparkList.Despawn(pSummoned); + } + void UpdateAI(const uint32 uiDiff) { + //Return since we have no target + if (!UpdateVictim()) + return; + // Splitted if (m_creature->GetVisibility() == VISIBILITY_OFF) { - // Reset if there is no target anymore! - if (!UpdateVictim()) - { - DespawnSpark(); - EnterEvadeMode(); - } - - if (m_uiSplit_Timer <= uiDiff) + if (m_uiSplitTimer <= uiDiff) { - m_uiSplit_Timer = 2500; + m_uiSplitTimer = 2500; // Return sparks to where Ionar splitted if (m_bIsSplitPhase) @@ -241,57 +197,46 @@ struct boss_ionarAI : public ScriptedAI m_bIsSplitPhase = false; } // Lightning effect and restore Ionar - else if (m_uiSparkAtHomeCount == MAX_SPARKS) + else if (m_sparkList.empty()) { - m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, false); - m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false); m_creature->SetVisibility(VISIBILITY_ON); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE); DoCast(m_creature, SPELL_SPARK_DESPAWN, false); - DespawnSpark(); - - m_uiSparkAtHomeCount = 0; - m_uiSplit_Timer = 25000; + m_uiSplitTimer = 25000; m_bIsSplitPhase = true; - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE) - { - if (m_creature->getVictim()) - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); - } + if (m_creature->getVictim()) + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } } else - m_uiSplit_Timer -= uiDiff; + m_uiSplitTimer -= uiDiff; return; } - //Return since we have no target - if (!UpdateVictim()) - return; - - if (m_uiStaticOverload_Timer <= uiDiff) + if (m_uiStaticOverloadTimer <= uiDiff) { if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, DUNGEON_MODE(SPELL_STATIC_OVERLOAD_N, SPELL_STATIC_OVERLOAD_H)); - m_uiStaticOverload_Timer = 5000 + rand()%1000; + m_uiStaticOverloadTimer = urand(5000, 6000); } else - m_uiStaticOverload_Timer -= uiDiff; + m_uiStaticOverloadTimer -= uiDiff; - if (m_uiBallLightning_Timer <= uiDiff) + if (m_uiBallLightningTimer <= uiDiff) { DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_BALL_LIGHTNING_N, SPELL_BALL_LIGHTNING_H)); - m_uiBallLightning_Timer = 10000 + rand()%1000; + m_uiBallLightningTimer = urand(10000, 11000); } else - m_uiBallLightning_Timer -= uiDiff; + m_uiBallLightningTimer -= uiDiff; // Health check - if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(20*m_uiHealthAmountModifier))) + if (HealthBelowPct(100-(20*m_uiHealthAmountModifier))) { ++m_uiHealthAmountModifier; @@ -300,7 +245,7 @@ struct boss_ionarAI : public ScriptedAI if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); - DoCast(m_creature, SPELL_DISPERSE); + DoCast(m_creature, SPELL_DISPERSE, true); } DoMeleeAttackIfReady(); @@ -325,13 +270,10 @@ bool EffectDummyCreature_boss_ionar(Unit* pCaster, uint32 uiSpellId, uint32 uiEf pCreatureTarget->AttackStop(); pCreatureTarget->SetVisibility(VISIBILITY_OFF); + pCreatureTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE); - // he never must get damage (e.g. through aoe) if he isn't there - pCreatureTarget->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, true); - pCreatureTarget->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); - - if (pCreatureTarget->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) - pCreatureTarget->GetMotionMaster()->MovementExpired(); + pCreatureTarget->GetMotionMaster()->Clear(); + pCreatureTarget->GetMotionMaster()->MoveIdle(); //always return true when we are handling this spell and effect return true; @@ -357,6 +299,7 @@ struct mob_spark_of_ionarAI : public ScriptedAI void Reset() { uiCheckTimer = 2000; + m_creature->SetReactState(REACT_PASSIVE); } void MovementInform(uint32 uiType, uint32 uiPointId) @@ -365,50 +308,20 @@ struct mob_spark_of_ionarAI : public ScriptedAI return; if (uiPointId == POINT_CALLBACK) - { - if (Creature* pIonar = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_IONAR))) - { - if (!pIonar->isAlive()) - { - if (m_creature->isAlive()) - m_creature->ForcedDespawn(); - - return; - } - - if (boss_ionarAI* pIonarAI = dynamic_cast<boss_ionarAI*>(pIonar->AI())) - pIonarAI->RegisterSparkAtHome(); - } - else - if (m_creature->isAlive()) - m_creature->ForcedDespawn(); - } - } - - void EnterCombat(Unit* who) - { // Prevent to get aggro / start attack if we move home - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) - return; - - ScriptedAI::EnterCombat(who); + m_creature->ForcedDespawn(); } - void AttackStart(Unit* pWho) - { // Prevent to get aggro / start attack if we move home - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) - return; - - ScriptedAI::AttackStart(pWho); + void DamageTaken(Unit *pDoneBy, uint32 &uiDamage) + { + uiDamage = 0; } void UpdateAI(const uint32 uiDiff) { - // Despawn since we have no target and the encounter is not running - if (!UpdateVictim() && m_pInstance && m_pInstance->GetData(TYPE_IONAR) != IN_PROGRESS) + // Despawn if the encounter is not running + if (m_pInstance && m_pInstance->GetData(TYPE_IONAR) != IN_PROGRESS) { - if (m_creature->isAlive()) - m_creature->ForcedDespawn(); - + m_creature->ForcedDespawn(); return; } @@ -425,20 +338,13 @@ struct mob_spark_of_ionarAI : public ScriptedAI Position pos; pIonar->GetPosition(&pos); - // Interrupt attack to prevent further attacking player - m_creature->AttackStop(); - - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) - m_creature->GetMotionMaster()->MovementExpired(); - - //now handle by db - //m_creature->SetSpeed(MOVE_RUN, m_creature->GetCreatureInfo()->speed * 2); + m_creature->SetSpeed(MOVE_RUN, 2.0f); + m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MovePoint(POINT_CALLBACK, pos); } } else - if (m_creature->isAlive()) - m_creature->ForcedDespawn(); + m_creature->ForcedDespawn(); } uiCheckTimer = 2000; } |