diff options
author | Kudlaty <none@none> | 2009-06-18 12:31:54 +0200 |
---|---|---|
committer | Kudlaty <none@none> | 2009-06-18 12:31:54 +0200 |
commit | ee2945aac3bbd89dc87ec762cdf9c5e4b846f8df (patch) | |
tree | b17d1e81040a2769ceb6a3b982eab73b4d656c26 /src | |
parent | 6f151ca4ea6c64baa5f6c15505ffb9f1a4523494 (diff) |
Take back changes in SSC.
Merge [SD2]
r1037 Correcting some details for shaffar and simplify code. Let movement expire when using blink ability. Fix some possible issues with summoned beacons.
--HG--
branch : trunk
Diffstat (limited to 'src')
6 files changed, 1296 insertions, 918 deletions
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp index f24abe4a4c7..e847973ac7a 100644 --- a/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp +++ b/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp @@ -28,35 +28,34 @@ EndContentData */ #include "precompiled.h" -#define SAY_INTRO -1557000 - -#define SAY_AGGRO_1 -1557001 -#define SAY_AGGRO_2 -1557002 -#define SAY_AGGRO_3 -1557003 - -#define SAY_SLAY_1 -1557004 -#define SAY_SLAY_2 -1557005 - -#define SAY_SUMMON -1557006 - -#define SAY_DEAD -1557007 - -#define SPELL_BLINK 34605 -#define SPELL_FROSTBOLT 32370 -#define SPELL_FIREBALL 20420 -#define SPELL_FROSTNOVA 32365 - -#define SPELL_ETHEREAL_BEACON 32371 // Summon 18431 -#define SPELL_ETHEREAL_BEACON_VISUAL 32368 - -#define ENTRY_BEACON 18431 -#define ENTRY_SHAFFAR 18344 - -#define NR_INITIAL_BEACONS 3 +enum +{ + SAY_INTRO = -1557000, + SAY_AGGRO_1 = -1557001, + SAY_AGGRO_2 = -1557002, + SAY_AGGRO_3 = -1557003, + SAY_SLAY_1 = -1557004, + SAY_SLAY_2 = -1557005, + SAY_SUMMON = -1557006, + SAY_DEAD = -1557007, + + SPELL_BLINK = 34605, + SPELL_FROSTBOLT = 32364, + SPELL_FIREBALL = 32363, + SPELL_FROSTNOVA = 32365, + + SPELL_ETHEREAL_BEACON = 32371, // Summons NPC_BEACON + SPELL_ETHEREAL_BEACON_VISUAL = 32368, + + NPC_BEACON = 18431, + NPC_SHAFFAR = 18344, + + NR_INITIAL_BEACONS = 3 +}; struct TRINITY_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI { - boss_nexusprince_shaffarAI(Creature *c) : ScriptedAI(c) {} + boss_nexusprince_shaffarAI(Creature *c) : ScriptedAI(c) { HasTaunted = false; } uint32 Blink_Timer; uint32 Beacon_Timer; @@ -84,7 +83,6 @@ struct TRINITY_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI Frostbolt_Timer = 4000; FrostNova_Timer = 15000; - HasTaunted = false; CanBlink = false; float dist = 8.0f; @@ -120,23 +118,10 @@ struct TRINITY_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI void MoveInLineOfSight(Unit *who) { - if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessiblePlaceFor(m_creature) ) + if (!HasTaunted && who->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(who, 100.0f)) { - if( !HasTaunted && m_creature->IsWithinDistInMap(who, 100.0) ) - { - DoScriptText(SAY_INTRO, m_creature); - HasTaunted = true; - } - - if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) - return; - - float attackRadius = m_creature->GetAttackDistance(who); - if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) ) - { - //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - AttackStart(who); - } + DoScriptText(SAY_INTRO, m_creature); + HasTaunted = true; } } @@ -214,6 +199,11 @@ struct TRINITY_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI if( m_creature->IsNonMeleeSpellCasted(false) ) m_creature->InterruptNonMeleeSpells(true); + //expire movement, will prevent from running right back to victim after cast + //(but should MoveChase be used again at a certain time or should he not move?) + if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) + m_creature->GetMotionMaster()->MovementExpired(); + DoCast(m_creature,SPELL_BLINK); Blink_Timer = 1000 + rand()%1500; CanBlink = false; @@ -228,7 +218,7 @@ struct TRINITY_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI if( !urand(0,3) ) DoScriptText(SAY_SUMMON, m_creature); - DoCast(m_creature,SPELL_ETHEREAL_BEACON); + DoCast(m_creature,SPELL_ETHEREAL_BEACON, true); Beacon_Timer = 10000; }else Beacon_Timer -= diff; @@ -242,8 +232,11 @@ CreatureAI* GetAI_boss_nexusprince_shaffar(Creature *_Creature) return new boss_nexusprince_shaffarAI (_Creature); } -#define SPELL_ARCANE_BOLT 15254 -#define SPELL_ETHEREAL_APPRENTICE 32372 // Summon 18430 +enum +{ + SPELL_ARCANE_BOLT = 15254, + SPELL_ETHEREAL_APPRENTICE = 32372 // Summon 18430 +}; struct TRINITY_DLL_DECL mob_ethereal_beaconAI : public ScriptedAI { @@ -272,7 +265,7 @@ struct TRINITY_DLL_DECL mob_ethereal_beaconAI : public ScriptedAI void EnterCombat(Unit *who) { // Send Shaffar to fight - Unit* Shaffar = me->FindNearestCreature(ENTRY_SHAFFAR, 100); + Unit* Shaffar = me->FindNearestCreature(NPC_SHAFFAR, 100); if(!Shaffar || Shaffar->isDead()) { KillSelf(); @@ -289,7 +282,7 @@ struct TRINITY_DLL_DECL mob_ethereal_beaconAI : public ScriptedAI void JustDied(Unit* Killer) { - Unit *Shaffar = me->FindNearestCreature(ENTRY_SHAFFAR, 100); + Unit *Shaffar = me->FindNearestCreature(NPC_SHAFFAR, 100); if(Shaffar) CAST_AI(boss_nexusprince_shaffarAI, (CAST_CRE(Shaffar)->AI()))->RemoveBeaconFromList(m_creature); } @@ -301,7 +294,7 @@ struct TRINITY_DLL_DECL mob_ethereal_beaconAI : public ScriptedAI if(Check_Timer < diff) { - Unit *Shaffar = me->FindNearestCreature(ENTRY_SHAFFAR, 100); + Unit *Shaffar = me->FindNearestCreature(NPC_SHAFFAR, 100); if(!Shaffar || Shaffar->isDead() || !Shaffar->isInCombat()) { KillSelf(); @@ -333,8 +326,11 @@ CreatureAI* GetAI_mob_ethereal_beacon(Creature *_Creature) return new mob_ethereal_beaconAI (_Creature); } -#define SPELL_ETHEREAL_APPRENTICE_FIREBOLT 32369 -#define SPELL_ETHEREAL_APPRENTICE_FROSTBOLT 32370 +enum +{ + SPELL_ETHEREAL_APPRENTICE_FIREBOLT = 32369, + SPELL_ETHEREAL_APPRENTICE_FROSTBOLT = 32370 +}; struct TRINITY_DLL_DECL mob_ethereal_apprenticeAI : public ScriptedAI { diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp index 1d0083d9d0d..fb15b427bfa 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp @@ -642,6 +642,8 @@ 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; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp index daeefa36159..29c5216dee9 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp @@ -6,316 +6,381 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* ScriptData SDName: Boss_Hydross_The_Unstable SD%Complete: 90 -SDComment: Some details and adjustments left to do, probably nothing major. Spawns may be spawned in different way/location. code cleanup needed +SDComment: Some details and adjustments left to do, probably nothing major. Spawns may be spawned in different way/location. SDCategory: Coilfang Resevoir, Serpent Shrine Cavern EndScriptData */ #include "precompiled.h" #include "def_serpent_shrine.h" -enum -{ - SAY_AGGRO = -1548000, - SAY_SWITCH_TO_CLEAN = -1548001, - SAY_CLEAN_SLAY1 = -1548002, - SAY_CLEAN_SLAY2 = -1548003, - SAY_CLEAN_DEATH = -1548004, - SAY_SWITCH_TO_CORRUPT = -1548005, - SAY_CORRUPT_SLAY1 = -1548006, - SAY_CORRUPT_SLAY2 = -1548007, - SAY_CORRUPT_DEATH = -1548008, - - SWITCH_RADIUS = 18, - - MODEL_CORRUPT = 20609, - MODEL_CLEAN = 20162, - - SPELL_WATER_TOMB = 38235, - SPELL_MARK_OF_HYDROSS1 = 38215, - SPELL_MARK_OF_HYDROSS2 = 38216, - SPELL_MARK_OF_HYDROSS3 = 38217, - SPELL_MARK_OF_HYDROSS4 = 38218, - SPELL_MARK_OF_HYDROSS5 = 38231, - SPELL_MARK_OF_HYDROSS6 = 40584, - SPELL_MARK_OF_CORRUPTION1 = 38219, - SPELL_MARK_OF_CORRUPTION2 = 38220, - SPELL_MARK_OF_CORRUPTION3 = 38221, - SPELL_MARK_OF_CORRUPTION4 = 38222, - SPELL_MARK_OF_CORRUPTION5 = 38230, - SPELL_MARK_OF_CORRUPTION6 = 40583, - SPELL_VILE_SLUDGE = 38246, - SPELL_ENRAGE = 27680, //this spell need verification - SPELL_SUMMON_WATER_ELEMENT = 36459, //not in use yet(in use ever?) - SPELL_ELEMENTAL_SPAWNIN = 25035, - SPELL_BLUE_BEAM = 38015, //channeled Hydross Beam Helper (not in use yet) - - NPC_PURE_SPAWN = 22035, - NPC_TAINTED_SPAWN = 22036 -}; - -const float afSpawnDiffs[4][2] = -{ - {6.934003f , -11.255012f}, // diff 1 - {-6.934003f , 11.255012f }, // diff 2 - {-12.577011f, -4.72702f }, // diff 3 - {12.577011f , 4.72702f } // diff 4 -}; +#define SAY_AGGRO -1548000 +#define SAY_SWITCH_TO_CLEAN -1548001 +#define SAY_CLEAN_SLAY1 -1548002 +#define SAY_CLEAN_SLAY2 -1548003 +#define SAY_CLEAN_DEATH -1548004 +#define SAY_SWITCH_TO_CORRUPT -1548005 +#define SAY_CORRUPT_SLAY1 -1548006 +#define SAY_CORRUPT_SLAY2 -1548007 +#define SAY_CORRUPT_DEATH -1548008 + +#define SWITCH_RADIUS 18 + +#define MODEL_CORRUPT 20609 +#define MODEL_CLEAN 20162 + +#define SPELL_WATER_TOMB 38235 +#define SPELL_MARK_OF_HYDROSS1 38215 +#define SPELL_MARK_OF_HYDROSS2 38216 +#define SPELL_MARK_OF_HYDROSS3 38217 +#define SPELL_MARK_OF_HYDROSS4 38218 +#define SPELL_MARK_OF_HYDROSS5 38231 +#define SPELL_MARK_OF_HYDROSS6 40584 +#define SPELL_MARK_OF_CORRUPTION1 38219 +#define SPELL_MARK_OF_CORRUPTION2 38220 +#define SPELL_MARK_OF_CORRUPTION3 38221 +#define SPELL_MARK_OF_CORRUPTION4 38222 +#define SPELL_MARK_OF_CORRUPTION5 38230 +#define SPELL_MARK_OF_CORRUPTION6 40583 +#define SPELL_VILE_SLUDGE 38246 +#define SPELL_ENRAGE 27680 //this spell need verification +#define SPELL_SUMMON_WATER_ELEMENT 36459 //not in use yet(in use ever?) +#define SPELL_ELEMENTAL_SPAWNIN 25035 +#define SPELL_BLUE_BEAM /*40227*/40227 //channeled Hydross Beam Helper (not in use yet) + +#define ENTRY_PURE_SPAWN 22035 +#define ENTRY_TAINTED_SPAWN 22036 +#define ENTRY_BEAM_DUMMY 21934 + +#define HYDROSS_X -239.439 +#define HYDROSS_Y -363.481 + +#define SPAWN_X_DIFF1 6.934003 +#define SPAWN_Y_DIFF1 -11.255012 +#define SPAWN_X_DIFF2 -6.934003 +#define SPAWN_Y_DIFF2 11.255012 +#define SPAWN_X_DIFF3 -12.577011 +#define SPAWN_Y_DIFF3 -4.72702 +#define SPAWN_X_DIFF4 12.577011 +#define SPAWN_Y_DIFF4 4.72702 struct TRINITY_DLL_DECL boss_hydross_the_unstableAI : public ScriptedAI { - boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c) + boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c), Summons(m_creature) { - m_pInstance = c->GetInstanceData(); + pInstance = c->GetInstanceData(); } - ScriptedInstance* m_pInstance; // the instance - - uint32 m_uiPosCheck_Timer; - uint32 m_uiMarkOfHydross_Timer; - uint32 m_uiMarkOfCorruption_Timer; - uint32 m_uiWaterTomb_Timer; - uint32 m_uiVileSludge_Timer; - uint32 m_uiMarkOfHydross_Count; - uint32 m_uiMarkOfCorruption_Count; - uint32 m_uiEnrageTimer; - bool m_bCorruptedForm; + ScriptedInstance* pInstance; + uint64 beams[2]; + uint32 PosCheck_Timer; + uint32 MarkOfHydross_Timer; + uint32 MarkOfCorruption_Timer; + uint32 WaterTomb_Timer; + uint32 VileSludge_Timer; + uint32 MarkOfHydross_Count; + uint32 MarkOfCorruption_Count; + uint32 EnrageTimer; + bool CorruptedForm; + bool beam; + SummonList Summons; void Reset() { - m_uiPosCheck_Timer = 2500; - m_uiMarkOfHydross_Timer = 15000; - m_uiMarkOfCorruption_Timer = 15000; - m_uiWaterTomb_Timer = 7000; - m_uiVileSludge_Timer = 7000; - m_uiMarkOfHydross_Count = 0; - m_uiMarkOfCorruption_Count = 0; - m_uiEnrageTimer = 600000; - - m_bCorruptedForm = false; - + DeSummonBeams(); + beams[0] = 0; + beams[1] = 0; + PosCheck_Timer = 2500; + MarkOfHydross_Timer = 15000; + MarkOfCorruption_Timer = 15000; + WaterTomb_Timer = 7000; + VileSludge_Timer = 7000; + MarkOfHydross_Count = 0; + MarkOfCorruption_Count = 0; + EnrageTimer = 600000; + + CorruptedForm = false; m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_FROST); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false); - m_creature->SetDisplayId(MODEL_CLEAN); + m_creature->SetDisplayId( MODEL_CLEAN); - if (m_pInstance) - m_pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED); + if (pInstance) + pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED); + beam = false; + Summons.DespawnAll(); } - void EnterCombat(Unit* pWho) + void SummonBeams() + { + Creature* beamer = m_creature->SummonCreature(ENTRY_BEAM_DUMMY,-258.333,-356.34,22.0499,5.90835,TEMPSUMMON_CORPSE_DESPAWN,0); + if(beamer) + { + beamer->CastSpell(m_creature,SPELL_BLUE_BEAM,true); + beamer->SetDisplayId(11686); //invisible + beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + beams[0]=beamer->GetGUID(); + } + beamer = beamer = m_creature->SummonCreature(ENTRY_BEAM_DUMMY,-219.918,-371.308,22.0042,2.73072,TEMPSUMMON_CORPSE_DESPAWN,0); + if(beamer) + { + beamer->CastSpell(m_creature,SPELL_BLUE_BEAM,true); + beamer->SetDisplayId(11686); //invisible + beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + beams[1]=beamer->GetGUID(); + } + } + void DeSummonBeams() + { + for(uint8 i=0;i<2;i++) + { + Creature* mob = Unit::GetCreature(*m_creature,beams[i]); + if(mob) + { + mob->setDeathState(DEAD); + mob->RemoveCorpse(); + } + } + } + void EnterCombat(Unit *who) { DoScriptText(SAY_AGGRO, m_creature); - if (m_pInstance) - m_pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, IN_PROGRESS); + if (pInstance) + pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, IN_PROGRESS); } - void KilledUnit(Unit* pVictim) + void KilledUnit(Unit *victim) { - if (m_bCorruptedForm) - DoScriptText(urand(0,1) ? SAY_CORRUPT_SLAY1 : SAY_CORRUPT_SLAY2, m_creature); + if (CorruptedForm) + { + switch(rand()%2) + { + case 0: DoScriptText(SAY_CORRUPT_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_CORRUPT_SLAY2, m_creature); break; + } + } else - DoScriptText(urand(0,1) ? SAY_CLEAN_SLAY1 : SAY_CLEAN_SLAY2, m_creature); + { + switch(rand()%2) + { + case 0: DoScriptText(SAY_CLEAN_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_CLEAN_SLAY2, m_creature); break; + } + } } - void JustSummoned(Creature* pSummoned) + void JustSummoned(Creature* summoned) { - if (pSummoned->GetEntry() == NPC_PURE_SPAWN) - pSummoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); - else if (pSummoned->GetEntry() == NPC_TAINTED_SPAWN) - pSummoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); - - pSummoned->CastSpell(pSummoned, SPELL_ELEMENTAL_SPAWNIN, true); + if (summoned->GetEntry() == ENTRY_PURE_SPAWN) + { + summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); + summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true); + Summons.Summon(summoned); + } + if (summoned->GetEntry() == ENTRY_TAINTED_SPAWN) + { + summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); + summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true); + Summons.Summon(summoned); + } } - void JustDied(Unit* pVictim) + void SummonedCreatureDespawn(Creature *summon) { - DoScriptText(m_bCorruptedForm ? SAY_CORRUPT_DEATH : SAY_CLEAN_DEATH, m_creature); - - if (m_pInstance) - m_pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED); + Summons.Despawn(summon); } - void SpawnAdds() + void JustDied(Unit *victim) { - for(uint8 i = 0; i < 4; ++i) - DoSpawnCreature(m_bCorruptedForm ? NPC_TAINTED_SPAWN : NPC_PURE_SPAWN, - afSpawnDiffs[i][0], afSpawnDiffs[i][1], 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); + if (CorruptedForm) + DoScriptText(SAY_CORRUPT_DEATH, m_creature); + else + DoScriptText(SAY_CLEAN_DEATH, m_creature); + if (pInstance) + pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, DONE); + Summons.DespawnAll(); } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 diff) { + if(!beam) + { + SummonBeams(); + beam=true; + } //Return since we have no target - if (!UpdateVictim()) + if (!UpdateVictim() ) return; // corrupted form - if (m_bCorruptedForm) + if (CorruptedForm) { //MarkOfCorruption_Timer - if (m_uiMarkOfCorruption_Timer < uiDiff) + if (MarkOfCorruption_Timer < diff) { - if (m_uiMarkOfCorruption_Count <= 5) + if (MarkOfCorruption_Count <= 5) { - uint32 uiMarkSpell = 0; + uint32 mark_spell; - switch(m_uiMarkOfCorruption_Count) + switch(MarkOfCorruption_Count) { - case 0: uiMarkSpell = SPELL_MARK_OF_CORRUPTION1; break; - case 1: uiMarkSpell = SPELL_MARK_OF_CORRUPTION2; break; - case 2: uiMarkSpell = SPELL_MARK_OF_CORRUPTION3; break; - case 3: uiMarkSpell = SPELL_MARK_OF_CORRUPTION4; break; - case 4: uiMarkSpell = SPELL_MARK_OF_CORRUPTION5; break; - case 5: uiMarkSpell = SPELL_MARK_OF_CORRUPTION6; break; + case 0: mark_spell = SPELL_MARK_OF_CORRUPTION1; break; + case 1: mark_spell = SPELL_MARK_OF_CORRUPTION2; break; + case 2: mark_spell = SPELL_MARK_OF_CORRUPTION3; break; + case 3: mark_spell = SPELL_MARK_OF_CORRUPTION4; break; + case 4: mark_spell = SPELL_MARK_OF_CORRUPTION5; break; + case 5: mark_spell = SPELL_MARK_OF_CORRUPTION6; break; } - DoCast(m_creature->getVictim(), uiMarkSpell); + DoCast(m_creature->getVictim(), mark_spell); - if (m_uiMarkOfCorruption_Count < 5) - ++m_uiMarkOfCorruption_Count; + if (MarkOfCorruption_Count < 5) + MarkOfCorruption_Count++; } - m_uiMarkOfCorruption_Timer = 15000; - }else m_uiMarkOfCorruption_Timer -= uiDiff; + MarkOfCorruption_Timer = 15000; + }else MarkOfCorruption_Timer -= diff; //VileSludge_Timer - if (m_uiVileSludge_Timer < uiDiff) + if (VileSludge_Timer < diff) { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_VILE_SLUDGE); + Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (target) + DoCast(target, SPELL_VILE_SLUDGE); - m_uiVileSludge_Timer = 15000; - }else m_uiVileSludge_Timer -= uiDiff; + VileSludge_Timer = 15000; + }else VileSludge_Timer -= diff; //PosCheck_Timer - if (m_uiPosCheck_Timer < uiDiff) + if (PosCheck_Timer < diff) { - float fPosX, fPosY, fPosZ, fPosO; - m_creature->GetHomePosition(fPosX, fPosY, fPosZ, fPosO); - - if (m_creature->GetDistance2d(fPosX, fPosY) < SWITCH_RADIUS) + if (m_creature->GetDistance2d(HYDROSS_X, HYDROSS_Y) < SWITCH_RADIUS) { - DoScriptText(SAY_SWITCH_TO_CLEAN, m_creature); - // switch to clean form - m_creature->SetDisplayId(MODEL_CLEAN); - m_uiMarkOfHydross_Count = 0; + m_creature->SetDisplayId( MODEL_CLEAN); + CorruptedForm = false; + MarkOfHydross_Count = 0; + + DoScriptText(SAY_SWITCH_TO_CLEAN, m_creature); DoResetThreat(); + SummonBeams(); // spawn 4 adds - SpawnAdds(); + DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_FROST); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false); - - m_bCorruptedForm = false; } - m_uiPosCheck_Timer = 2500; - }else m_uiPosCheck_Timer -=uiDiff; + PosCheck_Timer = 2500; + }else PosCheck_Timer -=diff; } // clean form else { //MarkOfHydross_Timer - if (m_uiMarkOfHydross_Timer < uiDiff) + if (MarkOfHydross_Timer < diff) { - if (m_uiMarkOfHydross_Count <= 5) + if (MarkOfHydross_Count <= 5) { - uint32 uiMarkSpell; + uint32 mark_spell; - switch(m_uiMarkOfHydross_Count) + switch(MarkOfHydross_Count) { - case 0: uiMarkSpell = SPELL_MARK_OF_HYDROSS1; break; - case 1: uiMarkSpell = SPELL_MARK_OF_HYDROSS2; break; - case 2: uiMarkSpell = SPELL_MARK_OF_HYDROSS3; break; - case 3: uiMarkSpell = SPELL_MARK_OF_HYDROSS4; break; - case 4: uiMarkSpell = SPELL_MARK_OF_HYDROSS5; break; - case 5: uiMarkSpell = SPELL_MARK_OF_HYDROSS6; break; + case 0: mark_spell = SPELL_MARK_OF_HYDROSS1; break; + case 1: mark_spell = SPELL_MARK_OF_HYDROSS2; break; + case 2: mark_spell = SPELL_MARK_OF_HYDROSS3; break; + case 3: mark_spell = SPELL_MARK_OF_HYDROSS4; break; + case 4: mark_spell = SPELL_MARK_OF_HYDROSS5; break; + case 5: mark_spell = SPELL_MARK_OF_HYDROSS6; break; } - DoCast(m_creature->getVictim(), uiMarkSpell); + DoCast(m_creature->getVictim(), mark_spell); - if (m_uiMarkOfHydross_Count < 5) - ++m_uiMarkOfHydross_Count; + if (MarkOfHydross_Count < 5) + MarkOfHydross_Count++; } - m_uiMarkOfHydross_Timer = 15000; - }else m_uiMarkOfHydross_Timer -= uiDiff; + MarkOfHydross_Timer = 15000; + }else MarkOfHydross_Timer -= diff; //WaterTomb_Timer - if (m_uiWaterTomb_Timer < uiDiff) + if (WaterTomb_Timer < diff) { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_WATER_TOMB); + Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (target) + DoCast(target, SPELL_WATER_TOMB); - m_uiWaterTomb_Timer = 7000; - }else m_uiWaterTomb_Timer -= uiDiff; + WaterTomb_Timer = 7000; + }else WaterTomb_Timer -= diff; //PosCheck_Timer - if (m_uiPosCheck_Timer < uiDiff) + if (PosCheck_Timer < diff) { - float fPosX, fPosY, fPosZ, fPosO; - m_creature->GetHomePosition(fPosX, fPosY, fPosZ, fPosO); - - if (m_creature->GetDistance2d(fPosX, fPosY) >= SWITCH_RADIUS) + if (m_creature->GetDistance2d(HYDROSS_X, HYDROSS_Y) >= SWITCH_RADIUS) { - DoScriptText(SAY_SWITCH_TO_CORRUPT, m_creature); - // switch to corrupted form - m_creature->SetDisplayId(MODEL_CORRUPT); - m_uiMarkOfCorruption_Count = 0; + m_creature->SetDisplayId( MODEL_CORRUPT); + MarkOfCorruption_Count = 0; + CorruptedForm = true; + + DoScriptText(SAY_SWITCH_TO_CORRUPT, m_creature); DoResetThreat(); + DeSummonBeams(); // spawn 4 adds - SpawnAdds(); + DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false); - - m_bCorruptedForm = true; } - m_uiPosCheck_Timer = 2500; - }else m_uiPosCheck_Timer -=uiDiff; + PosCheck_Timer = 2500; + }else PosCheck_Timer -=diff; } //EnrageTimer - if (m_uiEnrageTimer < uiDiff) + if (EnrageTimer < diff) { DoCast(m_creature, SPELL_ENRAGE); - m_uiEnrageTimer = 60000; - }else m_uiEnrageTimer -= uiDiff; + EnrageTimer = 60000; + }else EnrageTimer -= diff; DoMeleeAttackIfReady(); } }; - -CreatureAI* GetAI_boss_hydross_the_unstable(Creature* pCreature) +CreatureAI* GetAI_boss_hydross_the_unstable(Creature *_Creature) { - return new boss_hydross_the_unstableAI(pCreature); + return new boss_hydross_the_unstableAI (_Creature); } void AddSC_boss_hydross_the_unstable() { Script *newscript; newscript = new Script; - newscript->Name = "boss_hydross_the_unstable"; + newscript->Name="boss_hydross_the_unstable"; newscript->GetAI = &GetAI_boss_hydross_the_unstable; newscript->RegisterSelf(); } + diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp index e83498169c2..e1fdcf5ab15 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp @@ -16,178 +16,220 @@ /* ScriptData SDName: Boss_Lady_Vashj -SD%Complete: 60 -SDComment: Code cleanup needed. This script needs further adjustments. +SD%Complete: 99 +SDComment: Missing blizzlike Shield Generators coords SDCategory: Coilfang Resevoir, Serpent Shrine Cavern EndScriptData */ #include "precompiled.h" #include "def_serpent_shrine.h" #include "../../../creature/simple_ai.h" -#include "Item.h" #include "Spell.h" -enum +#define SAY_INTRO -1548042 +#define SAY_AGGRO1 -1548043 +#define SAY_AGGRO2 -1548044 +#define SAY_AGGRO3 -1548045 +#define SAY_AGGRO4 -1548046 +#define SAY_PHASE1 -1548047 +#define SAY_PHASE2 -1548048 +#define SAY_PHASE3 -1548049 +#define SAY_BOWSHOT1 -1548050 +#define SAY_BOWSHOT2 -1548051 +#define SAY_SLAY1 -1548052 +#define SAY_SLAY2 -1548053 +#define SAY_SLAY3 -1548054 +#define SAY_DEATH -1548055 + +#define SPELL_SURGE 38044 +#define SPELL_MULTI_SHOT 38310 +#define SPELL_SHOCK_BLAST 38509 +#define SPELL_ENTANGLE 38316 +#define SPELL_STATIC_CHARGE_TRIGGER 38280 +#define SPELL_FORKED_LIGHTNING 40088 +#define SPELL_SHOOT 40873 +#define SPELL_POISON_BOLT 40095 +#define SPELL_TOXIC_SPORES 38575 +#define SPELL_MAGIC_BARRIER 38112 + +#define MIDDLE_X 30.134 +#define MIDDLE_Y -923.65 +#define MIDDLE_Z 42.9 + +#define SPOREBAT_X 30.977156 +#define SPOREBAT_Y -925.297761 +#define SPOREBAT_Z 77.176567 +#define SPOREBAT_O 5.223932 + +#define SHIED_GENERATOR_CHANNEL 19870 +#define ENCHANTED_ELEMENTAL 21958 +#define TAINTED_ELEMENTAL 22009 +#define COILFANG_STRIDER 22056 +#define COILFANG_ELITE 22055 +#define TOXIC_SPOREBAT 22140 +#define TOXIC_SPORES_TRIGGER 22207 + +float ElementPos[8][4] = { - SAY_INTRO = -1548042, - SAY_AGGRO1 = -1548043, - SAY_AGGRO2 = -1548044, - SAY_AGGRO3 = -1548045, - SAY_AGGRO4 = -1548046, - SAY_PHASE1 = -1548047, - SAY_PHASE2 = -1548048, - SAY_PHASE3 = -1548049, - SAY_BOWSHOT1 = -1548050, - SAY_BOWSHOT2 = -1548051, - SAY_SLAY1 = -1548052, - SAY_SLAY2 = -1548053, - SAY_SLAY3 = -1548054, - SAY_DEATH = -1548055, - - POINT_MOVE_CENTER = 0, - - PHASE_1 = 1, - PHASE_2 = 2, - PHASE_3 = 3, - - MAX_SHIELD_GEN = 4, - - SPELL_MULTI_SHOT = 38310, - SPELL_SHOCK_BLAST = 38509, - SPELL_ENTANGLE = 38316, - SPELL_STATIC_CHARGE_TRIGGER = 38280, - SPELL_FORKED_LIGHTNING = 38145, - SPELL_SHOOT = 38295, - - SPELL_TOXIC_SPORES = 38575, - SPELL_MAGIC_BARRIER = 38112, - SPELL_SURGE = 38044, - - //tainted elemental - SPELL_POISON_BOLT = 38253, - SPELL_SUMMON_TAINTED = 38139, - - NPC_ENCHANTED_ELEMENTAL = 21958, - NPC_TAINTED_ELEMENTAL = 22009, - NPC_COILFANG_STRIDER = 22056, - NPC_COILFANG_ELITE = 22055, - NPC_TOXIC_SPOREBAT = 22140, - - NPC_SHIELD_GENERATOR = 19870 + {8.3, -835.3, 21.9, 5}, + {53.4, -835.3, 21.9, 4.5}, + {96, -861.9, 21.8, 4}, + {96, -986.4, 21.4, 2.5}, + {54.4, -1010.6, 22, 1.8}, + {9.8, -1012, 21.7, 1.4}, + {-35, -987.6, 21.5, 0.8}, + {-58.9, -901.6, 21.5, 6} }; -const float afMiddlePos[3] = {30.134f, -923.65f, 42.9f}; - -const float afSporebatPos[4] = {30.977156f, -925.297761f, 77.176567f, 5.223932f}; +float ElementWPPos[8][3] = +{ + {71.700752, -883.905884, 41.097168}, + {45.039848, -868.022827, 41.097015}, + {14.585141, -867.894470, 41.097061}, + {-25.415508, -906.737732, 41.097061}, + {-11.801594, -963.405884, 41.097067}, + {14.556657, -979.051514, 41.097137}, + {43.466549, -979.406677, 41.097027}, + {69.945908, -964.663940, 41.097054} +}; -const float afElementPos[8][4] = +float SporebatWPPos[8][3] = { - {8.3f , -835.3f , 21.9f, 5.0f}, - {53.4f , -835.3f , 21.9f, 4.5f}, - {96.0f , -861.9f , 21.8f, 4.0f}, - {96.0f , -986.4f , 21.4f, 2.5f}, - {54.4f , -1010.6f, 22.0f, 1.8f}, - {9.8f , -1012.0f, 21.7f, 1.4f}, - {-35.0f, -987.6f , 21.5f, 0.8f}, - {-58.9f, -901.6f , 21.5f, 6.0f} + {31.6,-896.3,59.1}, + {9.1, -913.9, 56}, + {5.2, -934.4, 52.4}, + {20.7, -946.9, 49.7}, + {41, -941.9, 51}, + {47.7, -927.3, 55}, + {42.2, -912.4, 51.7}, + {27, -905.9, 50} }; -const float afCoilfangElitePos[3][4] = +float CoilfangElitePos[3][4] = { - {28.84f , -923.28f , 42.9f , 6.0f }, - {31.183281f, -953.502625f, 41.523602f, 1.640957f}, - {58.895180f, -923.124268f, 41.545307f, 3.152848f} + {28.84, -923.28, 42.9, 6}, + {31.183281, -953.502625, 41.523602, 1.640957}, + {58.895180, -923.124268, 41.545307, 3.152848} }; -const float afCoilfangStriderPos[3][4] = +float CoilfangStriderPos[3][4] = { - {66.427f, -948.778f, 41.262245f, 2.584f}, - {7.513f , -959.538f, 41.300422f, 1.0346f}, - {-12.843f, -907.798f, 41.239620f, 6.087f} + {66.427010, -948.778503, 41.262245, 2.584220}, + {7.513962, -959.538208, 41.300422, 1.034629}, + {-12.843201, -907.798401, 41.239620, 6.087094} }; -const float afShieldGeneratorChannelPos[4][4] = +float ShieldGeneratorChannelPos[4][4] = { - {49.626f, -902.181f, 41.54f, 3.956f}, - {10.988f, -901.616f, 41.54f, 5.437f}, - {10.385f, -944.036f, 41.54f, 0.779f}, - {49.312f, -943.398f, 41.54f, 2.401f} + {49.6262, -902.181, 43.0975, 3.95683}, + {10.988, -901.616, 42.5371, 5.4373}, + {10.3859, -944.036, 42.5446, 0.779888}, + {49.3126, -943.398, 42.5501, 2.40174} }; //Lady Vashj AI struct TRINITY_DLL_DECL boss_lady_vashjAI : public ScriptedAI { - boss_lady_vashjAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_lady_vashjAI (Creature *c) : ScriptedAI(c) { - m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); - - memset(&m_auiShieldGeneratorChannel, 0, sizeof(m_auiShieldGeneratorChannel)); + pInstance = c->GetInstanceData(); + Intro = false; + JustCreated = true; + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); //set it only once on creature create (no need do intro if wiped) } - ScriptedInstance *m_pInstance; // the instance - - uint64 m_auiShieldGeneratorChannel[MAX_SHIELD_GEN]; - - // timers - uint32 m_uiShockBlast_Timer; - uint32 m_uiEntangle_Timer; - uint32 m_uiStaticCharge_Timer; - uint32 m_uiForkedLightning_Timer; - uint32 m_uiCheck_Timer; - uint32 m_uiEnchantedElemental_Timer; - uint32 m_uiTaintedElemental_Timer; - uint32 m_uiCoilfangElite_Timer; - uint32 m_uiCoilfangStrider_Timer; - uint32 m_uiSummonSporebat_Timer; - uint32 m_uiSummonSporebat_StaticTimer; - uint8 m_uiEnchantedElemental_Pos; - uint8 m_uiPhase; - - bool m_bEntangle; + ScriptedInstance *pInstance; + + uint64 ShieldGeneratorChannel[4]; + + uint32 AggroTimer; + uint32 ShockBlast_Timer; + uint32 Entangle_Timer; + uint32 StaticCharge_Timer; + uint32 ForkedLightning_Timer; + uint32 Check_Timer; + uint32 EnchantedElemental_Timer; + uint32 TaintedElemental_Timer; + uint32 CoilfangElite_Timer; + uint32 CoilfangStrider_Timer; + uint32 SummonSporebat_Timer; + uint32 SummonSporebat_StaticTimer; + uint8 EnchantedElemental_Pos; + uint8 Phase; + + bool Entangle; + bool Intro; + bool CanAttack; + bool JustCreated; void Reset() { - SetCombatMovement(true); - - m_uiShockBlast_Timer = 1+rand()%60000; - m_uiEntangle_Timer = 30000; - m_uiStaticCharge_Timer = 10000+rand()%15000; - m_uiCheck_Timer = 1000; - - m_uiForkedLightning_Timer = 43000+rand()%6000; - m_uiEnchantedElemental_Timer = 10000; - m_uiTaintedElemental_Timer = 50000; - m_uiCoilfangElite_Timer = 45000; - m_uiCoilfangStrider_Timer = 60000; - - m_uiSummonSporebat_Timer = 10000; - m_uiSummonSporebat_StaticTimer = 30000; - m_uiEnchantedElemental_Pos = 0; - m_uiPhase = PHASE_1; + AggroTimer = 19000; + ShockBlast_Timer = 1+rand()%60000; + Entangle_Timer = 30000; + StaticCharge_Timer = 10000+rand()%15000; + ForkedLightning_Timer = 2000; + Check_Timer = 15000; + EnchantedElemental_Timer = 5000; + TaintedElemental_Timer = 50000; + CoilfangElite_Timer = 45000+rand()%5000; + CoilfangStrider_Timer = 60000+rand()%10000; + SummonSporebat_Timer = 10000; + SummonSporebat_StaticTimer = 30000; + EnchantedElemental_Pos = 0; + Phase = 0; + + Entangle = false; + if(JustCreated) + { + CanAttack = false; + JustCreated = false; + }else CanAttack = true; - m_bEntangle = false; + Unit *remo; + for(uint8 i = 0; i < 4; i++) + { + remo = Unit::GetUnit(*m_creature, ShieldGeneratorChannel[i]); + if (remo) + remo->setDeathState(JUST_DIED); + } - RemoveAllShieldGenerators(); + if(pInstance) + pInstance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED); + ShieldGeneratorChannel[0] = 0; + ShieldGeneratorChannel[1] = 0; + ShieldGeneratorChannel[2] = 0; + ShieldGeneratorChannel[3] = 0; - if (m_pInstance) - m_pInstance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED); + m_creature->SetCorpseDelay(1000*60*60); } - void RemoveAllShieldGenerators() + //Called when a tainted elemental dies + void EventTaintedElementalDeath() + { + //the next will spawn 50 seconds after the previous one's death + if(TaintedElemental_Timer > 50000) + TaintedElemental_Timer = 50000; + } + void KilledUnit(Unit *victim) { - for(uint8 i = 0; i < MAX_SHIELD_GEN; i++) + switch(rand()%3) { - if (Unit* pTemp = Unit::GetUnit(*m_creature,m_auiShieldGeneratorChannel[i])) - { - if (pTemp->isAlive()) - pTemp->setDeathState(JUST_DIED); - - m_auiShieldGeneratorChannel[i] = 0; - } + case 0: DoScriptText(SAY_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_SLAY2, m_creature); break; + case 2: DoScriptText(SAY_SLAY3, m_creature); break; } } - void Aggro(Unit* pWho) + void JustDied(Unit *victim) + { + DoScriptText(SAY_DEATH, m_creature); + + if(pInstance) + pInstance->SetData(DATA_LADYVASHJEVENT, DONE); + } + + void StartEvent() { switch(rand()%4) { @@ -197,294 +239,337 @@ struct TRINITY_DLL_DECL boss_lady_vashjAI : public ScriptedAI case 3: DoScriptText(SAY_AGGRO4, m_creature); break; } - if (m_pInstance) - m_pInstance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS); + Phase = 1; + + if(pInstance) + pInstance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS); } - void MovementInform(uint32 uiType, uint32 uiPointId) + void EnterCombat(Unit *who) { - if (uiType != POINT_MOTION_TYPE) - return; - - if (uiPointId == POINT_MOVE_CENTER) + if (pInstance) { - m_creature->RemoveAllAuras(); - - for(uint8 i = 0; i < MAX_SHIELD_GEN; i++) + //remove old tainted cores to prevent cheating in phase 2 + Map *map = m_creature->GetMap(); + Map::PlayerList const &PlayerList = map->GetPlayers(); + for(Map::PlayerList::const_iterator i = PlayerList.begin();i != PlayerList.end(); ++i) { - if (Creature* pCreature = m_creature->SummonCreature(NPC_SHIELD_GENERATOR, afShieldGeneratorChannelPos[i][0], afShieldGeneratorChannelPos[i][1], afShieldGeneratorChannelPos[i][2], afShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0)) - m_auiShieldGeneratorChannel[i] = pCreature->GetGUID(); + if(Player* i_pl = i->getSource()) + { + i_pl->DestroyItemCount(31088, 1, true); + } } } + if(Phase != 2) + AttackStart(who); + + if(!m_creature->isInCombat()) + StartEvent(); } - void JustSummoned(Creature* pSummoned) + void MoveInLineOfSight(Unit *who) { - uint32 uiEntry = pSummoned->GetEntry(); - - if (uiEntry == NPC_COILFANG_STRIDER || uiEntry == NPC_COILFANG_ELITE || uiEntry == NPC_TOXIC_SPOREBAT) + if (!Intro) { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - pSummoned->AI()->AttackStart(pTarget); + Intro = true; + DoScriptText(SAY_INTRO, m_creature); } + if (!CanAttack) + return; + if (!who || m_creature->getVictim()) + return; - if (uiEntry == NPC_SHIELD_GENERATOR) + if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - //we should really expect database to have this set already - if (!pSummoned->HasFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) { - pSummoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - pSummoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } + //if(who->HasStealthAura()) + // who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + if(Phase != 2) + AttackStart(who); - pSummoned->CastSpell(m_creature,SPELL_MAGIC_BARRIER,true); + if(!m_creature->isInCombat()) + StartEvent(); + } } } - //called when any summoned (by m_creature) despawns - void SummonedCreatureDespawn(Creature* pDespawned) + void CastShootOrMultishot() { - if (pDespawned->GetEntry() == NPC_TAINTED_ELEMENTAL) + switch(rand()%2) { - if (m_uiTaintedElemental_Timer > 50000) - m_uiTaintedElemental_Timer = 50000; + case 0: + //Shoot + //Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits her target for 4097-5543 Physical damage. + DoCast(m_creature->getVictim(), SPELL_SHOOT); + break; + case 1: + //Multishot + //Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits 1 person and 4 people around him for 6475-7525 physical damage. + DoCast(m_creature->getVictim(), SPELL_MULTI_SHOT); + break; } - } - - void KilledUnit(Unit* pVictim) - { - switch(rand()%3) + if(rand()%3) { - case 0: DoScriptText(SAY_SLAY1, m_creature); break; - case 1: DoScriptText(SAY_SLAY2, m_creature); break; - case 2: DoScriptText(SAY_SLAY3, m_creature); break; + switch(rand()%2) + { + case 0: DoScriptText(SAY_BOWSHOT1, m_creature); break; + case 1: DoScriptText(SAY_BOWSHOT2, m_creature); break; + } } } - void JustDied(Unit* pVictim) - { - DoScriptText(SAY_DEATH, m_creature); - - if (m_pInstance) - m_pInstance->SetData(DATA_LADYVASHJEVENT, DONE); - } - - void CastShootOrMultishot() - { - //Shoot: Used in m_uiPhases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits her target for 4097-5543 Physical damage. - //Multishot: Used in m_uiPhases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits 1 person and 4 people around him for 6475-7525 physical damage. - DoCast(m_creature->getVictim(), urand(0,1) ? SPELL_SHOOT : SPELL_MULTI_SHOT); - - if (rand()%3) - DoScriptText(urand(0,1) ? SAY_BOWSHOT1 : SAY_BOWSHOT2, m_creature); - } - - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 diff) { + if(!CanAttack && Intro) + { + if(AggroTimer < diff) + { + CanAttack = true; + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + AggroTimer=19000; + }else + { + AggroTimer-=diff; + return; + } + } + //to prevent abuses during phase 2 + if(Phase == 2 && !m_creature->getVictim() && m_creature->isInCombat()) + { + EnterEvadeMode(); + return; + } //Return since we have no target - if (!UpdateVictim()) + if (!UpdateVictim() ) return; - if (m_uiPhase == PHASE_1 || m_uiPhase == PHASE_3) + if(Phase == 1 || Phase == 3) { - //m_uiShockBlast_Timer - if (m_uiShockBlast_Timer < uiDiff) + //ShockBlast_Timer + if (ShockBlast_Timer < diff) { - //Randomly used in m_uiPhases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. + //Shock Burst + //Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCast(m_creature->getVictim(), SPELL_SHOCK_BLAST); + m_creature->TauntApply(m_creature->getVictim()); - m_uiShockBlast_Timer = 1000+rand()%14000; //random cooldown - }else m_uiShockBlast_Timer -= uiDiff; + ShockBlast_Timer = 1000+rand()%14000; //random cooldown + }else ShockBlast_Timer -= diff; - //m_uiStaticCharge_Timer - if (m_uiStaticCharge_Timer < uiDiff) + //StaticCharge_Timer + if(StaticCharge_Timer < diff) { - //Used on random people (only 1 person at any given time) in m_uiPhases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. - Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + //Static Charge + //Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. + Unit *target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); - //cast Static Charge every 2 seconds for 20 seconds - if (pTarget && !pTarget->HasAura(SPELL_STATIC_CHARGE_TRIGGER)) - DoCast(pTarget, SPELL_STATIC_CHARGE_TRIGGER); + if(target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER)) + //cast Static Charge every 2 seconds for 20 seconds + DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); - m_uiStaticCharge_Timer = 10000+rand()%20000; - }else m_uiStaticCharge_Timer -= uiDiff; + StaticCharge_Timer = 10000+rand()%20000; //blizzlike + }else StaticCharge_Timer -= diff; - //m_uiEntangle_Timer - if (m_uiEntangle_Timer < uiDiff) + //Entangle_Timer + if (Entangle_Timer < diff) { - if (!m_bEntangle) + if(!Entangle) { - //Used in m_uiPhases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. + //Entangle + //Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCast(m_creature->getVictim(), SPELL_ENTANGLE); - m_bEntangle = true; - m_uiEntangle_Timer = 10000; + Entangle = true; + Entangle_Timer = 10000; } else { CastShootOrMultishot(); - m_bEntangle = false; - m_uiEntangle_Timer = 20000+rand()%5000; + Entangle = false; + Entangle_Timer = 20000+rand()%5000; } - }else m_uiEntangle_Timer -= uiDiff; + }else Entangle_Timer -= diff; - //m_uiPhase 1 - if (m_uiPhase == PHASE_1) + //Phase 1 + if(Phase == 1) { - //m_uiPhase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. - if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 70) + //Start phase 2 + if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 70) { - DoScriptText(SAY_PHASE2, m_creature); + //Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. + Phase = 2; - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) - { - //set false, so MoveChase is not triggered in AttackStart - SetCombatMovement(false); + m_creature->GetMotionMaster()->Clear(); + DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z); - m_creature->GetMotionMaster()->MovementExpired(); - m_creature->GetMotionMaster()->MovePoint(POINT_MOVE_CENTER, afMiddlePos[0], afMiddlePos[1], afMiddlePos[2]); + Creature *pCreature; + for(uint8 i = 0; i < 4; i++) + { + pCreature = m_creature->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0); + if (pCreature) + ShieldGeneratorChannel[i] = pCreature->GetGUID(); } - - m_uiPhase = PHASE_2; - return; + DoScriptText(SAY_PHASE2, m_creature); } } - //m_uiPhase PHASE_3 + //Phase 3 else { - //m_uiSummonSporebat_Timer - if (m_uiSummonSporebat_Timer < uiDiff) + //SummonSporebat_Timer + if(SummonSporebat_Timer < diff) { - m_creature->SummonCreature(NPC_TOXIC_SPOREBAT, - afSporebatPos[0], afSporebatPos[1], afSporebatPos[2], afSporebatPos[3], - TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + Creature *Sporebat = NULL; + Sporebat = m_creature->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0); + + if(Sporebat) + { + Unit *target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if(target) + Sporebat->AI()->AttackStart(target); + } //summon sporebats faster and faster - if (m_uiSummonSporebat_StaticTimer > 1000) - m_uiSummonSporebat_StaticTimer -= 1000; + if(SummonSporebat_StaticTimer > 1000) + SummonSporebat_StaticTimer -= 1000; + + SummonSporebat_Timer = SummonSporebat_StaticTimer; - m_uiSummonSporebat_Timer = m_uiSummonSporebat_StaticTimer; - }else m_uiSummonSporebat_Timer -= uiDiff; + if(SummonSporebat_Timer < 5000) + SummonSporebat_Timer = 5000; + + }else SummonSporebat_Timer -= diff; } //Melee attack DoMeleeAttackIfReady(); - //m_uiCheck_Timer - used to check if somebody is in melee range - if (m_uiCheck_Timer < uiDiff) + //Check_Timer - used to check if somebody is in melee range + if(Check_Timer < diff) { - bool bInMeleeRange = false; + bool InMeleeRange = false; + Unit *target; std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList(); for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { - Unit* pTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); - - //if in melee range - if (pTarget && pTarget->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) + target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); + //if in melee range + if(target && target->IsWithinDistInMap(m_creature, 5)) { - bInMeleeRange = true; + InMeleeRange = true; break; } } //if nobody is in melee range - if (!bInMeleeRange) + if(!InMeleeRange) CastShootOrMultishot(); - m_uiCheck_Timer = 1500; - }else m_uiCheck_Timer -= uiDiff; + Check_Timer = 5000; + }else Check_Timer -= diff; } - //m_uiPhase PHASE_2 + //Phase 2 else { - //m_uiForkedLightning_Timer - if (m_uiForkedLightning_Timer < uiDiff) + //ForkedLightning_Timer + if(ForkedLightning_Timer < diff) { - //Used constantly in m_uiPhase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. - Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + //Forked Lightning + //Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. + Unit *target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (!pTarget) - pTarget = m_creature->getVictim(); + if(!target) + target = m_creature->getVictim(); - DoCast(pTarget, SPELL_FORKED_LIGHTNING); + DoCast(target, SPELL_FORKED_LIGHTNING); - m_uiForkedLightning_Timer = 3000+rand()%6000; - }else m_uiForkedLightning_Timer -= uiDiff; + ForkedLightning_Timer = 2000+rand()%6000; //blizzlike + }else ForkedLightning_Timer -= diff; - //NPC_ENCHANTED_ELEMENTAL - if (m_uiEnchantedElemental_Timer < uiDiff) + //EnchantedElemental_Timer + if(EnchantedElemental_Timer < diff) { - if (Creature* pElemental = m_creature->SummonCreature(NPC_ENCHANTED_ELEMENTAL, afElementPos[m_uiEnchantedElemental_Pos][0], afElementPos[m_uiEnchantedElemental_Pos][1], afElementPos[m_uiEnchantedElemental_Pos][2], afElementPos[m_uiEnchantedElemental_Pos][3], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000)) - pElemental->GetMotionMaster()->MoveFollow(m_creature, 0.0f, 0.0f); + Creature *Elemental; + Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_CORPSE_DESPAWN, 0); - if (m_uiEnchantedElemental_Pos == 7) - m_uiEnchantedElemental_Pos = 0; + if(EnchantedElemental_Pos == 7) + EnchantedElemental_Pos = 0; else - ++m_uiEnchantedElemental_Pos; + EnchantedElemental_Pos++; - m_uiEnchantedElemental_Timer = 10000+rand()%5000; - }else m_uiEnchantedElemental_Timer -= uiDiff; + EnchantedElemental_Timer = 10000+rand()%5000; + }else EnchantedElemental_Timer -= diff; - //NPC_TAINTED_ELEMENTAL - if (m_uiTaintedElemental_Timer < uiDiff) + //TaintedElemental_Timer + if(TaintedElemental_Timer < diff) { - uint32 uiPos = urand(0,7); - - m_creature->SummonCreature(NPC_TAINTED_ELEMENTAL, - afElementPos[uiPos][0], afElementPos[uiPos][1], afElementPos[uiPos][2], afElementPos[uiPos][3], - TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 15000); + Creature *Tain_Elemental; + uint32 pos = rand()%8; + Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0); - m_uiTaintedElemental_Timer = 120000; - }else m_uiTaintedElemental_Timer -= uiDiff; + TaintedElemental_Timer = 120000; + }else TaintedElemental_Timer -= diff; - //NPC_COILFANG_ELITE - if (m_uiCoilfangElite_Timer < uiDiff) + //CoilfangElite_Timer + if(CoilfangElite_Timer < diff) { - uint32 uiPos = urand(0,2); - - m_creature->SummonCreature(NPC_COILFANG_ELITE, - afCoilfangElitePos[uiPos][0], afCoilfangElitePos[uiPos][1], afCoilfangElitePos[uiPos][2], afCoilfangElitePos[uiPos][3], - TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000); - - //wowwiki says 50 seconds, bosskillers says 45 - m_uiCoilfangElite_Timer = 45000+rand()%5000; - }else m_uiCoilfangElite_Timer -= uiDiff; + uint32 pos = rand()%3; + Creature* CoilfangElite = NULL; + CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + if(CoilfangElite) + { + Unit *target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if(target) + CoilfangElite->AI()->AttackStart(target); + else if(m_creature->getVictim()) + CoilfangElite->AI()->AttackStart(m_creature->getVictim()); + } + CoilfangElite_Timer = 45000+rand()%5000; + }else CoilfangElite_Timer -= diff; - //NPC_COILFANG_STRIDER - if (m_uiCoilfangStrider_Timer < uiDiff) + //CoilfangStrider_Timer + if(CoilfangStrider_Timer < diff) { - uint32 uiPos = urand(0,2); - - m_creature->SummonCreature(NPC_COILFANG_STRIDER, - afCoilfangStriderPos[uiPos][0], afCoilfangStriderPos[uiPos][1], afCoilfangStriderPos[uiPos][2], afCoilfangStriderPos[uiPos][3], - TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - - //wowwiki says 60 seconds, bosskillers says 60-70 - m_uiCoilfangStrider_Timer = 60000+rand()%10000; - }else m_uiCoilfangStrider_Timer -= uiDiff; + uint32 pos = rand()%3; + Creature* CoilfangStrider = NULL; + CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + if(CoilfangStrider) + { + Unit *target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if(target) + CoilfangStrider->AI()->AttackStart(target); + else if(m_creature->getVictim()) + CoilfangStrider->AI()->AttackStart(m_creature->getVictim()); + } + CoilfangStrider_Timer = 60000+rand()%10000; + }else CoilfangStrider_Timer -= diff; - //m_uiCheck_Timer - if (m_uiCheck_Timer < uiDiff) + //Check_Timer + if(Check_Timer < diff) { - //Start m_uiPhase 3 - if (m_pInstance && m_pInstance->GetData(DATA_CANSTARTPHASE3)) + //Start Phase 3 + if(pInstance && pInstance->GetData(DATA_CANSTARTPHASE3)) { - DoScriptText(SAY_PHASE3, m_creature); - - //set life 50%, not correct. Must remove 5% for each generator switched off + //set life 50% m_creature->SetHealth(m_creature->GetMaxHealth()/2); - //m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); + m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); - SetCombatMovement(true); + DoScriptText(SAY_PHASE3, m_creature); - //return to chase top aggro - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE) - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + Phase = 3; - m_uiPhase = PHASE_3; + //return to the tank + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } - m_uiCheck_Timer = 1000; - }else m_uiCheck_Timer -= uiDiff; + Check_Timer = 1000; + }else Check_Timer -= diff; } } }; @@ -493,120 +578,253 @@ struct TRINITY_DLL_DECL boss_lady_vashjAI : public ScriptedAI //If one of them reaches Vashj he will increase her damage done by 5%. struct TRINITY_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI { - mob_enchanted_elementalAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_enchanted_elementalAI(Creature *c) : ScriptedAI(c) { - m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); - SetCombatMovement(false); + pInstance = c->GetInstanceData(); } - ScriptedInstance *m_pInstance; // the instance - - void Reset() { } + ScriptedInstance *pInstance; + uint32 move; + uint32 phase; + float x, y, z; + Creature *Vashj; - void MoveInLineOfSight(Unit* pWho) + void Reset() { - if (m_pInstance) + m_creature->SetSpeed(MOVE_WALK,0.6);//walk + m_creature->SetSpeed(MOVE_RUN,0.6);//run + move = 0; + phase = 1; + Vashj = NULL; + + for (int i = 0;i<8;i++)//search for nearest waypoint (up on stairs) { - if (Unit* pVashj = Unit::GetUnit((*m_creature), m_pInstance->GetData64(DATA_LADYVASHJ))) + if (!x || !y || !z) { - if (pVashj->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) + x = ElementWPPos[i][0]; + y = ElementWPPos[i][1]; + z = ElementWPPos[i][2]; + } + else + { + if (m_creature->GetDistance(ElementWPPos[i][0],ElementWPPos[i][1],ElementWPPos[i][2]) < m_creature->GetDistance(x,y,z)) { - //increase lady vashj damage - if (pVashj->isAlive() && pVashj->isInCombat()) - m_creature->CastSpell(pVashj, SPELL_SURGE, false, 0, 0, pVashj->GetGUID()); - else - m_creature->setDeathState(JUST_DIED); + x = ElementWPPos[i][0]; + y = ElementWPPos[i][1]; + z = ElementWPPos[i][2]; } } } + if (pInstance) + Vashj = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)); } - void UpdateAI(const uint32 uiDiff) { } + void EnterCombat(Unit *who) { return; } + + void MoveInLineOfSight(Unit *who){return;} + + void UpdateAI(const uint32 diff) + { + if(!pInstance) + return; + + if (!Vashj) + { + return; + } + + if(move < diff) + { + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + if (phase == 1) + { + m_creature->GetMotionMaster()->MovePoint(0, x, y, z); + } + if (phase == 1 && m_creature->GetDistance(x,y,z) < 0.1) + { + phase = 2; + } + if (phase == 2) + { + m_creature->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z); + phase = 3; + } + if (phase == 3) + { + m_creature->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z); + if(m_creature->GetDistance(MIDDLE_X, MIDDLE_Y, MIDDLE_Z) < 3) + { + SpellEntry *spell = GET_SPELL(SPELL_SURGE); + if( spell ) + { + uint8 eff_mask=0; + for (int i=0; i<3; i++) + { + if (!spell->Effect[i]) + continue; + eff_mask|=1<<i; + } + Vashj->AddAura(new Aura(spell, eff_mask, NULL, Vashj, Vashj)); + } + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + if(!Vashj->isInCombat() || CAST_AI(boss_lady_vashjAI, Vashj->AI())->Phase != 2 || Vashj->isDead()) + { + //call Unsummon() + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + move = 1000; + }else move -= diff; + } }; //Tainted Elemental //This mob has 7,900 life, doesn't move, and shoots Poison Bolts at one person anywhere in the area, doing 3,000 nature damage and placing a posion doing 2,000 damage every 2 seconds. He will switch targets often, or sometimes just hang on a single player, but there is nothing you can do about it except heal the damage and kill the Tainted Elemental struct TRINITY_DLL_DECL mob_tainted_elementalAI : public ScriptedAI { - mob_tainted_elementalAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_tainted_elementalAI(Creature *c) : ScriptedAI(c) { - m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); - SetCombatMovement(false); + pInstance = c->GetInstanceData(); } - ScriptedInstance* m_pInstance; // the instance + ScriptedInstance *pInstance; - // timers - uint32 m_uiPoisonBolt_Timer; + uint32 PoisonBolt_Timer; + uint32 Despawn_Timer; void Reset() { - m_uiPoisonBolt_Timer = 5000+rand()%5000; + PoisonBolt_Timer = 5000+rand()%5000; + Despawn_Timer = 30000; } - void UpdateAI(const uint32 uiDiff) + void JustDied(Unit *killer) { - if (!UpdateVictim()) - return; + if(pInstance) + { + Creature *Vashj = NULL; + Vashj = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_LADYVASHJ))); - //m_uiPoisonBolt_Timer - if (m_uiPoisonBolt_Timer < uiDiff) + if(Vashj) + CAST_AI(boss_lady_vashjAI, Vashj->AI())->EventTaintedElementalDeath(); + } + } + + void EnterCombat(Unit *who) + { + m_creature->AddThreat(who, 0.1f); + } + + void UpdateAI(const uint32 diff) + { + //PoisonBolt_Timer + if(PoisonBolt_Timer < diff) { - Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + Unit *target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (pTarget && pTarget->IsWithinDistInMap(m_creature, 30.0f)) - DoCast(pTarget, SPELL_POISON_BOLT); + if(target && target->IsWithinDistInMap(m_creature, 30)) + DoCast(target, SPELL_POISON_BOLT); - m_uiPoisonBolt_Timer = 5000+rand()%5000; - }else m_uiPoisonBolt_Timer -= uiDiff; + PoisonBolt_Timer = 5000+rand()%5000; + }else PoisonBolt_Timer -= diff; + + //Despawn_Timer + if(Despawn_Timer < diff) + { + //call Unsummon() + m_creature->setDeathState(DEAD); + + //to prevent crashes + Despawn_Timer = 1000; + }else Despawn_Timer -= diff; } }; //Toxic Sporebat -//Toxic Spores: Used in m_uiPhase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it. +//Toxic Spores: Used in Phase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it. struct TRINITY_DLL_DECL mob_toxic_sporebatAI : public ScriptedAI { - mob_toxic_sporebatAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_toxic_sporebatAI(Creature *c) : ScriptedAI(c) { - m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + pInstance = c->GetInstanceData(); + EnterEvadeMode(); } - ScriptedInstance* m_pInstance; + ScriptedInstance *pInstance; - uint32 m_uiToxicSpore_Timer; - uint32 m_uiCheck_Timer; + uint32 movement_timer; + uint32 ToxicSpore_Timer; + uint32 bolt_timer; + uint32 Check_Timer; void Reset() { + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); m_creature->setFaction(14); - m_uiToxicSpore_Timer = 5000; - m_uiCheck_Timer = 1000; + movement_timer = 0; + ToxicSpore_Timer = 5000; + bolt_timer = 5500; + Check_Timer = 1000; } - void UpdateAI(const uint32 uiDiff) + void EnterCombat(Unit *who) { - //Return since we have no target - if (!UpdateVictim()) + + } + + void MoveInLineOfSight(Unit *who) + { + + } + + void MovementInform(uint32 type, uint32 id) + { + if(type != POINT_MOTION_TYPE) return; - //m_uiToxicSpore_Timer - if (m_uiToxicSpore_Timer < uiDiff) + if(id == 1) + movement_timer = 0; + } + + void UpdateAI (const uint32 diff) + { + //Random movement + if (movement_timer < diff) { - //The Spores will hit you anywhere in the instance: underwater, at the elevator, at the entrance, wherever. - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_TOXIC_SPORES); + uint32 rndpos = rand()%8; + m_creature->GetMotionMaster()->MovePoint(1,SporebatWPPos[rndpos][0], SporebatWPPos[rndpos][1], SporebatWPPos[rndpos][2]); + movement_timer = 6000; + }else movement_timer -= diff; - m_uiToxicSpore_Timer = 20000+rand()%5000; - }else m_uiToxicSpore_Timer -= uiDiff; + //toxic spores + if(bolt_timer < diff) + { + Unit *target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if(target) + { + Creature* trig = m_creature->SummonCreature(TOXIC_SPORES_TRIGGER,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,30000); + if(trig) + { + trig->setFaction(14); + trig->CastSpell(trig, SPELL_TOXIC_SPORES,true); + } + } + bolt_timer = 10000+rand()%5000; + } + else bolt_timer -= diff; - //m_uiCheck_Timer - if (m_uiCheck_Timer < uiDiff) + //Check_Timer + if(Check_Timer < diff) { - if (m_pInstance) + if(pInstance) { //check if vashj is death - Unit* pVashj = Unit::GetUnit((*m_creature), m_pInstance->GetData64(DATA_LADYVASHJ)); - if (!pVashj || !pVashj->isAlive()) + Unit *Vashj = NULL; + Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)); + if(!Vashj || (Vashj && !Vashj->isAlive()) || (Vashj && CAST_AI(boss_lady_vashjAI, CAST_CRE(Vashj)->AI())->Phase != 3)) { //remove m_creature->setDeathState(DEAD); @@ -615,192 +833,235 @@ struct TRINITY_DLL_DECL mob_toxic_sporebatAI : public ScriptedAI } } - m_uiCheck_Timer = 1000; - }else m_uiCheck_Timer -= uiDiff; - - DoMeleeAttackIfReady(); + Check_Timer = 1000; + }else Check_Timer -= diff; } }; //Coilfang Elite //It's an elite Naga mob with 170,000 HP. It does about 5000 damage on plate, and has a nasty cleave hitting for about 7500 damage -CreatureAI* GetAI_mob_coilfang_elite(Creature* pCreature) +CreatureAI* GetAI_mob_coilfang_elite(Creature *_Creature) { - SimpleAI* pAI = new SimpleAI (pCreature); + SimpleAI* ai = new SimpleAI (_Creature); - pAI->Spell[0].Enabled = true; - pAI->Spell[0].Spell_Id = 31345; //Cleave - pAI->Spell[0].Cooldown = 15000; - pAI->Spell[0].CooldownRandomAddition = 5000; - pAI->Spell[0].First_Cast = 5000; - pAI->Spell[0].Cast_Target_Type = CAST_HOSTILE_RANDOM; + ai->Spell[0].Enabled = true; + ai->Spell[0].Spell_Id = 31345; //Cleave + ai->Spell[0].Cooldown = 15000; + ai->Spell[0].CooldownRandomAddition = 5000; + ai->Spell[0].First_Cast = 5000; + ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_RANDOM; - pAI->EnterEvadeMode(); + ai->EnterEvadeMode(); - return pAI; + return ai; } -//Coilfang Strifer +//Coilfang Strider //It hits plate for about 8000 damage, has a Mind Blast spell doing about 3000 shadow damage, and a Psychic Scream Aura, which fears everybody in a 8 yard range of it every 2-3 seconds , for 5 seconds and increasing their movement speed by 150% during the fear. -CreatureAI* GetAI_mob_coilfang_strider(Creature* pCreature) +CreatureAI* GetAI_mob_coilfang_strider(Creature *_Creature) { - SimpleAI* pAI = new SimpleAI (pCreature); + SimpleAI* ai = new SimpleAI (_Creature); - pAI->Spell[0].Enabled = true; - pAI->Spell[0].Spell_Id = 41374; //Mind Blast - pAI->Spell[0].Cooldown = 30000; - pAI->Spell[0].CooldownRandomAddition = 10000; - pAI->Spell[0].First_Cast = 8000; - pAI->Spell[0].Cast_Target_Type = CAST_HOSTILE_TARGET; + ai->Spell[0].Enabled = true; + ai->Spell[0].Spell_Id = 41374; //Mind Blast + ai->Spell[0].Cooldown = 30000; + ai->Spell[0].CooldownRandomAddition = 10000; + ai->Spell[0].First_Cast = 8000; + ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_TARGET; //Scream aura not implemented - pAI->EnterEvadeMode(); + ai->EnterEvadeMode(); - return pAI; + return ai; } -//can probably be removed struct TRINITY_DLL_DECL mob_shield_generator_channelAI : public ScriptedAI { - mob_shield_generator_channelAI(Creature* pCreature) : ScriptedAI(pCreature) + mob_shield_generator_channelAI(Creature *c) : ScriptedAI(c) { - m_pInstance = ((ScriptedInstance*)pCreature->GetInstanceData()); + pInstance = c->GetInstanceData(); } - ScriptedInstance *m_pInstance; // the instance + ScriptedInstance *pInstance; + uint32 Check_Timer; + bool Casted; + void Reset() + { + Check_Timer = 0; + Casted = false; + m_creature->SetDisplayId(11686); //invisible + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void EnterCombat(Unit *who) { return; } - void Reset() { } + void MoveInLineOfSight(Unit *who) { return; } - void MoveInLineOfSight(Unit* pWho) { } + void UpdateAI (const uint32 diff) + { + if(!pInstance) + return; + + if(Check_Timer < diff) + { + Unit *Vashj = NULL; + Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)); + + if(Vashj && Vashj->isAlive()) + { + //start visual channel + if (!Casted || !Vashj->HasAura(SPELL_MAGIC_BARRIER)) + { + m_creature->CastSpell(Vashj,SPELL_MAGIC_BARRIER,true); + Casted = true; + } + } + Check_Timer = 1000; + }else Check_Timer -= diff; + } }; -//this is wrong, alternative script needed -bool ItemUse_item_tainted_core(Player* pPlayer, Item* pItem, SpellCastTargets const& sctTargets) +bool ItemUse_item_tainted_core(Player *player, Item* _Item, SpellCastTargets const& targets) { - ScriptedInstance* pInstance = ((ScriptedInstance*)pPlayer->GetInstanceData()); + ScriptedInstance *pInstance = (player->GetInstanceData()) ? (player->GetInstanceData()) : NULL; if(!pInstance) { - pPlayer->GetSession()->SendNotification("ERROR: Instance script not initialized. Notify your administrator."); - error_log("ERROR: Lady Vashj Tainted Core: Instance Script Not Initialized"); + player->GetSession()->SendNotification("Instance script not initialized"); return true; } - Creature* pVashj = (Creature*)(Unit::GetUnit((*pPlayer), pInstance->GetData64(DATA_LADYVASHJ))); - if(pVashj && ((boss_lady_vashjAI*)pVashj->AI())->m_uiPhase == 2) + Creature *Vashj = NULL; + Vashj = (Unit::GetCreature((*player), pInstance->GetData64(DATA_LADYVASHJ))); + if(Vashj && CAST_AI(boss_lady_vashjAI, Vashj->AI())->Phase == 2) { - if(sctTargets.getGOTarget() && sctTargets.getGOTarget()->GetTypeId()==TYPEID_GAMEOBJECT) + if(targets.getGOTarget() && targets.getGOTarget()->GetTypeId()==TYPEID_GAMEOBJECT) { - uint32 uiIdentifier; - uint8 uiChannelIdentifier; - switch(sctTargets.getGOTarget()->GetEntry()) + uint32 identifier; + uint8 channel_identifier; + switch(targets.getGOTarget()->GetEntry()) { case 185052: - uiIdentifier = DATA_SHIELDGENERATOR1; - uiChannelIdentifier = 0; + identifier = DATA_SHIELDGENERATOR1; + channel_identifier = 0; break; case 185053: - uiIdentifier = DATA_SHIELDGENERATOR2; - uiChannelIdentifier = 1; + identifier = DATA_SHIELDGENERATOR2; + channel_identifier = 1; break; case 185051: - uiIdentifier = DATA_SHIELDGENERATOR3; - uiChannelIdentifier = 2; + identifier = DATA_SHIELDGENERATOR3; + channel_identifier = 2; break; case 185054: - uiIdentifier = DATA_SHIELDGENERATOR4; - uiChannelIdentifier = 3; + identifier = DATA_SHIELDGENERATOR4; + channel_identifier = 3; break; default: return true; - break; } - if(pInstance->GetData(uiIdentifier)) + if(pInstance->GetData(identifier)) { - pPlayer->GetSession()->SendNotification("Already deactivated"); + player->GetSession()->SendNotification("Already deactivated"); return true; } //get and remove channel - if(Unit* pChannel = Unit::GetUnit((*pVashj), ((boss_lady_vashjAI*)pVashj->AI())->m_auiShieldGeneratorChannel[uiChannelIdentifier])) - pChannel->setDeathState(JUST_DIED); //calls Unsummon() + Unit *Channel = NULL; + Channel = Unit::GetCreature(*Vashj, CAST_AI(boss_lady_vashjAI, Vashj->AI())->ShieldGeneratorChannel[channel_identifier]); + if(Channel) + { + //call Unsummon() + Channel->setDeathState(JUST_DIED); + } - pInstance->SetData(uiIdentifier, 1); + pInstance->SetData(identifier, 1); //remove this item - pPlayer->DestroyItemCount(31088, 1, true); + player->DestroyItemCount(31088, 1, true); + return true; + } + else if( targets.getUnitTarget()->GetTypeId() == TYPEID_UNIT ) + return false; + else if(targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER) + { + player->DestroyItemCount(31088, 1, true); + player->CastSpell(targets.getUnitTarget(), 38134, true); + return true; } } return true; } -CreatureAI* GetAI_boss_lady_vashj(Creature* pCreature) +CreatureAI* GetAI_boss_lady_vashj(Creature *_Creature) { - return new boss_lady_vashjAI(pCreature); + return new boss_lady_vashjAI (_Creature); } -CreatureAI* GetAI_mob_enchanted_elemental(Creature* pCreature) +CreatureAI* GetAI_mob_enchanted_elemental(Creature *_Creature) { - return new mob_enchanted_elementalAI(pCreature); + return new mob_enchanted_elementalAI (_Creature); } -CreatureAI* GetAI_mob_tainted_elemental(Creature* pCreature) +CreatureAI* GetAI_mob_tainted_elemental(Creature *_Creature) { - return new mob_tainted_elementalAI(pCreature); + return new mob_tainted_elementalAI (_Creature); } -CreatureAI* GetAI_mob_toxic_sporebat(Creature* pCreature) +CreatureAI* GetAI_mob_toxic_sporebat(Creature *_Creature) { - return new mob_toxic_sporebatAI(pCreature); + return new mob_toxic_sporebatAI (_Creature); } -CreatureAI* GetAI_mob_shield_generator_channel(Creature* pCreature) +CreatureAI* GetAI_mob_shield_generator_channel(Creature *_Creature) { - return new mob_shield_generator_channelAI(pCreature); + return new mob_shield_generator_channelAI (_Creature); } void AddSC_boss_lady_vashj() { Script *newscript; newscript = new Script; - newscript->Name = "boss_lady_vashj"; + newscript->Name="boss_lady_vashj"; newscript->GetAI = &GetAI_boss_lady_vashj; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_enchanted_elemental"; + newscript->Name="mob_enchanted_elemental"; newscript->GetAI = &GetAI_mob_enchanted_elemental; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_tainted_elemental"; + newscript->Name="mob_tainted_elemental"; newscript->GetAI = &GetAI_mob_tainted_elemental; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_toxic_sporebat"; + newscript->Name="mob_toxic_sporebat"; newscript->GetAI = &GetAI_mob_toxic_sporebat; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_coilfang_elite"; + newscript->Name="mob_coilfang_elite"; newscript->GetAI = &GetAI_mob_coilfang_elite; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_coilfang_strider"; + newscript->Name="mob_coilfang_strider"; newscript->GetAI = &GetAI_mob_coilfang_strider; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_shield_generator_channel"; + newscript->Name="mob_shield_generator_channel"; newscript->GetAI = &GetAI_mob_shield_generator_channel; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "item_tainted_core"; + newscript->Name="item_tainted_core"; newscript->pItemUse = &ItemUse_item_tainted_core; newscript->RegisterSelf(); } + diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp index 625e893a4b3..e6d331f5347 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp @@ -24,51 +24,46 @@ EndScriptData */ #include "precompiled.h" #include "def_serpent_shrine.h" -enum -{ - SAY_AGGRO = -1548009, - SAY_SWITCH_TO_DEMON = -1548010, - SAY_INNER_DEMONS = -1548011, - SAY_DEMON_SLAY1 = -1548012, - SAY_DEMON_SLAY2 = -1548013, - SAY_DEMON_SLAY3 = -1548014, - SAY_NIGHTELF_SLAY1 = -1548015, - SAY_NIGHTELF_SLAY2 = -1548016, - SAY_NIGHTELF_SLAY3 = -1548017, - SAY_FINAL_FORM = -1548018, - SAY_FREE = -1548019, - SAY_DEATH = -1548020, - - SPELL_BERSERK = 26662, - - SPELL_WHIRLWIND = 37640, - SPELL_CHAOS_BLAST = 37674, - SPELL_INSIDIOUS_WHISPER = 37676, - SPELL_CONSUMING_MADNESS = 37749, - - AURA_DEMONIC_ALIGNMENT = 37713, - SPELL_SHADOWBOLT = 39309, - - FACTION_DEMON_1 = 1829, - FACTION_DEMON_2 = 1830, - FACTION_DEMON_3 = 1831, - FACTION_DEMON_4 = 1832, - FACTION_DEMON_5 = 1833, - - MODEL_DEMON = 20125, - MODEL_NIGHTELF = 20514, - - INNER_DEMON_ID = 21857, - DEMON_FORM = 21875, - - SPELL_DUAL_WIELD = 42459, - BANISH_BEAM = 38909, - AURA_BANISH = 37833, - SPELL_EARTHSHOCK = 39076, - SPELL_MINDBLAST = 37531, - SPELL_SOUL_LINK = 38007, - MOB_SPELLBINDER = 21806 -}; +// --- Spells used by Leotheras The Blind +#define SPELL_WHIRLWIND 37640 +#define SPELL_CHAOS_BLAST 37674 +#define SPELL_BERSERK 26662 +#define SPELL_INSIDIOUS_WHISPER 37676 +#define SPELL_DUAL_WIELD 42459 + +// --- Spells used in banish phase --- +#define BANISH_BEAM 38909 +#define AURA_BANISH 37833 + +// --- Spells used by Greyheart Spellbinders +#define SPELL_EARTHSHOCK 39076 +#define SPELL_MINDBLAST 37531 + +// --- Spells used by Inner Demons and creature ID +#define INNER_DEMON_ID 21857 +#define AURA_DEMONIC_ALIGNMENT 37713 +#define SPELL_SHADOWBOLT 39309 +#define SPELL_SOUL_LINK 38007 +#define SPELL_CONSUMING_MADNESS 37749 //not supported by core yet + +//Misc. +#define MODEL_DEMON 20125 +#define MODEL_NIGHTELF 20514 +#define DEMON_FORM 21875 +#define MOB_SPELLBINDER 21806 + +#define SAY_AGGRO -1548009 +#define SAY_SWITCH_TO_DEMON -1548010 +#define SAY_INNER_DEMONS -1548011 +#define SAY_DEMON_SLAY1 -1548012 +#define SAY_DEMON_SLAY2 -1548013 +#define SAY_DEMON_SLAY3 -1548014 +#define SAY_NIGHTELF_SLAY1 -1548015 +#define SAY_NIGHTELF_SLAY2 -1548016 +#define SAY_NIGHTELF_SLAY3 -1548017 +#define SAY_FINAL_FORM -1548018 +#define SAY_FREE -1548019 +#define SAY_DEATH -1548020 struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI { @@ -192,10 +187,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI EnrageUsed = false; InnderDemon_Count = 0; m_creature->SetSpeed( MOVE_RUN, 2.0f, true); - - if(m_creature->GetDisplayId() != MODEL_NIGHTELF) - m_creature->SetDisplayId(MODEL_NIGHTELF); - + m_creature->SetDisplayId( MODEL_NIGHTELF); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); @@ -278,7 +270,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, true); // changing model to bloodelf - m_creature->SetDisplayId(MODEL_NIGHTELF); + m_creature->SetDisplayId( MODEL_NIGHTELF); // and reseting equipment m_creature->LoadEquipment(m_creature->GetEquipmentId()); @@ -300,7 +292,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI DoCast(m_creature, AURA_BANISH); // changing model - m_creature->SetDisplayId(MODEL_DEMON); + m_creature->SetDisplayId( MODEL_DEMON); // and removing weapons m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); @@ -353,20 +345,23 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI if (victim->GetTypeId() != TYPEID_PLAYER) return; - switch(rand()%3) + if (DemonForm) { - case 0: DoScriptText(DemonForm ? SAY_DEMON_SLAY1 : SAY_NIGHTELF_SLAY1, m_creature); break; - case 1: DoScriptText(DemonForm ? SAY_DEMON_SLAY2 : SAY_NIGHTELF_SLAY2, m_creature); break; - case 2: DoScriptText(DemonForm ? SAY_DEMON_SLAY3 : SAY_NIGHTELF_SLAY3, m_creature); break; + switch(rand()%3) + { + case 0: DoScriptText(SAY_DEMON_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_DEMON_SLAY2, m_creature); break; + case 2: DoScriptText(SAY_DEMON_SLAY3, m_creature); break; + } } - } - - void JustSummoned(Creature* pSummoned) - { - if (m_creature->getVictim() && pSummoned->GetEntry() == DEMON_FORM) + else { - Demon = pSummoned->GetGUID(); - pSummoned->AI()->AttackStart(m_creature->getVictim()); + switch(rand()%3) + { + case 0: DoScriptText(SAY_NIGHTELF_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_NIGHTELF_SLAY2, m_creature); break; + case 2: DoScriptText(SAY_NIGHTELF_SLAY3, m_creature); break; + } } } @@ -377,7 +372,10 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI //despawn copy if (Demon) { - if (Unit* pUnit = Unit::GetUnit((*m_creature), Demon)) + Unit *pUnit = NULL; + pUnit = Unit::GetUnit((*m_creature), Demon); + + if (pUnit) pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } if (pInstance) @@ -448,7 +446,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI { DoCast(m_creature, SPELL_WHIRLWIND); // while whirlwinding this variable is used to countdown target's change - Whirlwind_Timer = 30000; + Whirlwind_Timer = 2000; NeedThreatReset = true; }else Whirlwind_Timer -= diff; } @@ -459,7 +457,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI { //switch to demon form m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND,0); - m_creature->SetDisplayId(MODEL_DEMON); + m_creature->SetDisplayId( MODEL_DEMON); DoScriptText(SAY_SWITCH_TO_DEMON, m_creature); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); @@ -536,7 +534,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI if(SwitchToHuman_Timer < diff) { //switch to nightelf form - m_creature->SetDisplayId(MODEL_NIGHTELF); + m_creature->SetDisplayId( MODEL_NIGHTELF); m_creature->LoadEquipment(m_creature->GetEquipmentId()); CastConsumingMadness(); @@ -565,7 +563,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI DemonForm = false; DoScriptText(SAY_FINAL_FORM, m_creature); - m_creature->SetDisplayId(MODEL_NIGHTELF); + m_creature->SetDisplayId( MODEL_NIGHTELF); m_creature->LoadEquipment(m_creature->GetEquipmentId()); } } @@ -617,7 +615,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blind_demonformAI : public ScriptedAI void UpdateAI(const uint32 diff) { //Return since we have no target - if (!UpdateVictim()) + if (!UpdateVictim() ) return; //ChaosBlast_Timer if(m_creature->GetDistance(m_creature->getVictim()) < 30) @@ -628,9 +626,9 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blind_demonformAI : public ScriptedAI // will cast only when in range od spell if(m_creature->GetDistance(m_creature->getVictim()) < 30) { - m_creature->CastSpell(m_creature->getVictim(),SPELL_CHAOS_BLAST,true); - //int damage = 100; - //m_creature->CastSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, &damage, NULL, NULL, false, NULL, NULL, m_creature->GetGUID()); + //m_creature->CastSpell(m_creature->getVictim(),SPELL_CHAOS_BLAST,true); + int damage = 100; + m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, &damage, NULL, NULL, false, NULL, NULL, m_creature->GetGUID()); ChaosBlast_Timer = 3000; } }else ChaosBlast_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp index 4c25a037d2c..b014b4b1e45 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp @@ -1,240 +1,289 @@ /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ /* ScriptData SDName: Boss_Morogrim_Tidewalker SD%Complete: 90 -SDComment: +SDComment: Water globules don't explode properly, remove hacks SDCategory: Coilfang Resevoir, Serpent Shrine Cavern EndScriptData */ #include "precompiled.h" #include "def_serpent_shrine.h" -enum +#define SAY_AGGRO -1548030 +#define SAY_SUMMON1 -1548031 +#define SAY_SUMMON2 -1548032 +#define SAY_SUMMON_BUBL1 -1548033 +#define SAY_SUMMON_BUBL2 -1548034 +#define SAY_SLAY1 -1548035 +#define SAY_SLAY2 -1548036 +#define SAY_SLAY3 -1548037 +#define SAY_DEATH -1548038 +#define EMOTE_WATERY_GRAVE -1548039 +#define EMOTE_EARTHQUAKE -1548040 +#define EMOTE_WATERY_GLOBULES -1548041 + +#define SPELL_TIDAL_WAVE 37730 +#define SPELL_WATERY_GRAVE 38049 +#define SPELL_EARTHQUAKE 37764 +#define SPELL_WATERY_GRAVE_EXPLOSION 37852 + +#define WATERY_GRAVE_X1 334.64 +#define WATERY_GRAVE_Y1 -728.89 +#define WATERY_GRAVE_Z1 -14.42 +#define WATERY_GRAVE_X2 365.51 +#define WATERY_GRAVE_Y2 -737.14 +#define WATERY_GRAVE_Z2 -14.44 +#define WATERY_GRAVE_X3 366.19 +#define WATERY_GRAVE_Y3 -709.59 +#define WATERY_GRAVE_Z3 -14.36 +#define WATERY_GRAVE_X4 372.93 +#define WATERY_GRAVE_Y4 -690.96 +#define WATERY_GRAVE_Z4 -14.44 + +#define SPELL_WATERY_GRAVE_1 38023 +#define SPELL_WATERY_GRAVE_2 38024 +#define SPELL_WATERY_GRAVE_3 38025 +#define SPELL_WATERY_GRAVE_4 37850 + +#define SPELL_SUMMON_WATER_GLOBULE_1 37854 +#define SPELL_SUMMON_WATER_GLOBULE_2 37858 +#define SPELL_SUMMON_WATER_GLOBULE_3 37860 +#define SPELL_SUMMON_WATER_GLOBULE_4 37861 + +/*#define SPELL_SUMMON_MURLOC_A6 39813 +#define SPELL_SUMMON_MURLOC_A7 39814 +#define SPELL_SUMMON_MURLOC_A8 39815 +#define SPELL_SUMMON_MURLOC_A9 39816 +#define SPELL_SUMMON_MURLOC_A10 39817 + +#define SPELL_SUMMON_MURLOC_B6 39818 +#define SPELL_SUMMON_MURLOC_B7 39819 +#define SPELL_SUMMON_MURLOC_B8 39820 +#define SPELL_SUMMON_MURLOC_B9 39821 +#define SPELL_SUMMON_MURLOC_B10 39822*/ + +float MurlocCords[10][5] = { - SAY_AGGRO = -1548030, - SAY_SUMMON1 = -1548031, - SAY_SUMMON2 = -1548032, - SAY_SUMMON_BUBL1 = -1548033, - SAY_SUMMON_BUBL2 = -1548034, - SAY_SLAY1 = -1548035, - SAY_SLAY2 = -1548036, - SAY_SLAY3 = -1548037, - SAY_DEATH = -1548038, - EMOTE_WATERY_GRAVE = -1548039, - EMOTE_EARTHQUAKE = -1548040, - EMOTE_WATERY_GLOBULES = -1548041, - - SPELL_TIDAL_WAVE = 37730, - SPELL_EARTHQUAKE = 37764, - - SPELL_WATERY_GRAVE_1 = 37850, - SPELL_WATERY_GRAVE_2 = 38023, - SPELL_WATERY_GRAVE_3 = 38024, - SPELL_WATERY_GRAVE_4 = 38025, - - SPELL_SUMMON_MURLOC_A6 = 39813, - SPELL_SUMMON_MURLOC_A7 = 39814, - SPELL_SUMMON_MURLOC_A8 = 39815, - SPELL_SUMMON_MURLOC_A9 = 39816, - SPELL_SUMMON_MURLOC_A10 = 39817, - - SPELL_SUMMON_MURLOC_B6 = 39818, - SPELL_SUMMON_MURLOC_B7 = 39819, - SPELL_SUMMON_MURLOC_B8 = 39820, - SPELL_SUMMON_MURLOC_B9 = 39821, - SPELL_SUMMON_MURLOC_B10 = 39822, - - SPELL_SUMMON_GLOBULE_1 = 37854, - SPELL_SUMMON_GLOBULE_2 = 37858, - SPELL_SUMMON_GLOBULE_3 = 37860, - SPELL_SUMMON_GLOBULE_4 = 37861, - - NPC_WATER_GLOBULE = 21913, - NPC_TIDEWALKER_LURKER = 21920 + {21920, 424.36, -715.4, -7.14, 0.124}, + {21920, 425.13, -719.3, -7.14, 0.124}, + {21920, 425.05, -724.23, -7.14, 0.124}, + {21920, 424.91, -728.68, -7.14, 0.124}, + {21920, 424.84, -732.18, -7.14, 0.124}, + {21920, 321.05, -734.2, -13.15, 0.124}, + {21920, 321.05, -729.4, -13.15, 0.124}, + {21920, 321.05, -724.03, -13.15, 0.124}, + {21920, 321.05, -718.73, -13.15, 0.124}, + {21920, 321.05, -714.24, -13.15, 0.124} }; +//Creatures +#define WATER_GLOBULE 21913 +#define TIDEWALKER_LURKER 21920 + //Morogrim Tidewalker AI struct TRINITY_DLL_DECL boss_morogrim_tidewalkerAI : public ScriptedAI { - boss_morogrim_tidewalkerAI(Creature* pCreature) : ScriptedAI(pCreature) + boss_morogrim_tidewalkerAI(Creature *c) : ScriptedAI(c) { - m_pInstance = pCreature->GetInstanceData(); + pInstance = c->GetInstanceData(); } - ScriptedInstance* m_pInstance; // the instance + ScriptedInstance* pInstance; + Map::PlayerList const *PlayerList; - // timers - uint32 m_uiTidalWave_Timer; - uint32 m_uiWateryGrave_Timer; - uint32 m_uiEarthquake_Timer; - uint32 m_uiWateryGlobules_Timer; + uint32 TidalWave_Timer; + uint32 WateryGrave_Timer; + uint32 Earthquake_Timer; + uint32 WateryGlobules_Timer; + uint32 globulespell[4]; + int8 Playercount; + int8 counter; - bool m_bEarthquake; - bool m_bPhase2; + bool Earthquake; + bool Phase2; void Reset() { - m_uiTidalWave_Timer = 10000; - m_uiWateryGrave_Timer = 30000; - m_uiEarthquake_Timer = 40000; - m_uiWateryGlobules_Timer = 0; + TidalWave_Timer = 10000; + WateryGrave_Timer = 30000; + Earthquake_Timer = 40000; + WateryGlobules_Timer = 0; + globulespell[0] = SPELL_SUMMON_WATER_GLOBULE_1; + globulespell[1] = SPELL_SUMMON_WATER_GLOBULE_2; + globulespell[2] = SPELL_SUMMON_WATER_GLOBULE_3; + globulespell[3] = SPELL_SUMMON_WATER_GLOBULE_4; + + Earthquake = false; + Phase2 = false; + + if (pInstance) + pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, NOT_STARTED); + } - m_bEarthquake = false; - m_bPhase2 = false; + void StartEvent() + { + DoScriptText(SAY_AGGRO, m_creature); - if (m_pInstance) - m_pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, NOT_STARTED); + if (pInstance) + pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, IN_PROGRESS); } - void KilledUnit(Unit* pVictim) + void KilledUnit(Unit *victim) { switch(rand()%3) { - case 0: DoScriptText(SAY_SLAY1, m_creature); break; - case 1: DoScriptText(SAY_SLAY2, m_creature); break; - case 2: DoScriptText(SAY_SLAY3, m_creature); break; + case 0: DoScriptText(SAY_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_SLAY2, m_creature); break; + case 2: DoScriptText(SAY_SLAY3, m_creature); break; } } - void JustDied(Unit* pVictim) + void JustDied(Unit *victim) { DoScriptText(SAY_DEATH, m_creature); - if (m_pInstance) - m_pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, NOT_STARTED); + if (pInstance) + pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, DONE); } - void EnterCombat(Unit* pWho) + void EnterCombat(Unit *who) { - DoScriptText(SAY_AGGRO, m_creature); - - if (m_pInstance) - m_pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, IN_PROGRESS); + PlayerList = &m_creature->GetMap()->GetPlayers(); + Playercount = PlayerList->getSize(); + StartEvent(); } - void JustSummoned(Creature* pSummoned) + void ApplyWateryGrave(Unit *player, uint8 i) { - if (pSummoned->GetEntry() == NPC_TIDEWALKER_LURKER) + switch(i) { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - pSummoned->AI()->AttackStart(pTarget); - } - - if (pSummoned->GetEntry() == NPC_WATER_GLOBULE) - { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - pSummoned->GetMotionMaster()->MoveFollow(pTarget, 0.0f, 0.0f); + case 0: player->CastSpell(player, SPELL_WATERY_GRAVE_1, true); break; + case 1: player->CastSpell(player, SPELL_WATERY_GRAVE_2, true); break; + case 2: player->CastSpell(player, SPELL_WATERY_GRAVE_3, true); break; + case 3: player->CastSpell(player, SPELL_WATERY_GRAVE_4, true); break; } } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 diff) { //Return since we have no target - if (!UpdateVictim()) + if (!UpdateVictim() ) return; - //m_uiEarthquake_Timer - if (m_uiEarthquake_Timer < uiDiff) + //Earthquake_Timer + if (Earthquake_Timer < diff) { - if (!m_bEarthquake) + if (!Earthquake) { DoCast(m_creature->getVictim(), SPELL_EARTHQUAKE); - m_bEarthquake = true; - m_uiEarthquake_Timer = 5000; + Earthquake = true; + Earthquake_Timer = 10000; } else { - DoScriptText(urand(0,1) ? SAY_SUMMON1 : SAY_SUMMON2, m_creature); - - //north - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_A6,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_A7,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_A8,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_A9,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_A10,true); - - //south - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_B6,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_B7,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_B8,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_B9,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_MURLOC_B10,true); + switch(rand()%2) + { + case 0: DoScriptText(SAY_SUMMON1, m_creature); break; + case 1: DoScriptText(SAY_SUMMON2, m_creature); break; + } + for(uint8 i = 0; i < 10; i++) + { + Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); + Creature* Murloc = m_creature->SummonCreature(MurlocCords[i][0],MurlocCords[i][1],MurlocCords[i][2],MurlocCords[i][3],MurlocCords[i][4], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + if(target && Murloc) + Murloc->AI()->AttackStart(target); + } DoScriptText(EMOTE_EARTHQUAKE, m_creature); - - m_bEarthquake = false; - m_uiEarthquake_Timer = 40000+rand()%5000; + Earthquake = false; + Earthquake_Timer = 40000+rand()%5000; } - }else m_uiEarthquake_Timer -= uiDiff; + }else Earthquake_Timer -= diff; - //m_uiTidalWave_Timer - if (m_uiTidalWave_Timer < uiDiff) + //TidalWave_Timer + if (TidalWave_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_TIDAL_WAVE); - m_uiTidalWave_Timer = 20000; - }else m_uiTidalWave_Timer -= uiDiff; + TidalWave_Timer = 20000; + }else TidalWave_Timer -= diff; - if (!m_bPhase2) + if (!Phase2) { - //m_uiWateryGrave_Timer - if (m_uiWateryGrave_Timer < uiDiff) + //WateryGrave_Timer + if (WateryGrave_Timer < diff) { //Teleport 4 players under the waterfalls + Unit *target; + using std::set; + set<int>list; + set<int>::iterator itr; for(uint8 i = 0; i < 4; i++) { - Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1); - - if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && !pTarget->HasAuraType(SPELL_AURA_MOD_STUN) && pTarget->IsWithinDistInMap(m_creature, 45.0f)) - { - switch(i) - { - case 0: m_creature->CastSpell(pTarget,SPELL_WATERY_GRAVE_1,false); break; - case 1: m_creature->CastSpell(pTarget,SPELL_WATERY_GRAVE_2,false); break; - case 2: m_creature->CastSpell(pTarget,SPELL_WATERY_GRAVE_3,false); break; - case 3: m_creature->CastSpell(pTarget,SPELL_WATERY_GRAVE_4,false); break; - } + counter = 0; + do{target = SelectTarget(SELECT_TARGET_RANDOM, 1, 50, true); //target players only + if(counter < Playercount) + break; + if(target) itr = list.find(target->GetGUID()); + counter++; + }while(itr != list.end()); + if(target){list.insert(target->GetGUID()); + ApplyWateryGrave(target, i); } } - DoScriptText(urand(0,1) ? SAY_SUMMON_BUBL1 : SAY_SUMMON_BUBL2, m_creature); - DoScriptText(EMOTE_WATERY_GRAVE, m_creature); + switch(rand()%2) + { + case 0: DoScriptText(SAY_SUMMON_BUBL1, m_creature); break; + case 1: DoScriptText(SAY_SUMMON_BUBL2, m_creature); break; + } - m_uiWateryGrave_Timer = 30000; - }else m_uiWateryGrave_Timer -= uiDiff; + DoScriptText(EMOTE_WATERY_GRAVE, m_creature); + WateryGrave_Timer = 30000; + }else WateryGrave_Timer -= diff; //Start Phase2 if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25) - m_bPhase2 = true; + Phase2 = true; } else { - //m_uiWateryGlobules_Timer - if (m_uiWateryGlobules_Timer < uiDiff) + //WateryGlobules_Timer + if (WateryGlobules_Timer < diff) { + Unit* globuletarget; + using std::set; + set<int>globulelist; + set<int>::iterator itr; + for (int8 g = 0; g < 4; g++) //one unit cant cast more than one spell per update, so some players have to cast for us XD + { + counter = 0; + do {globuletarget = SelectTarget(SELECT_TARGET_RANDOM, 0,50,true); + if(globuletarget) itr = globulelist.find(globuletarget->GetGUID()); + if (counter > Playercount) + break; + counter++; + } while (itr != globulelist.end()); + if(globuletarget)globulelist.insert(globuletarget->GetGUID()); + globuletarget->CastSpell(globuletarget, globulespell[g], true); + } DoScriptText(EMOTE_WATERY_GLOBULES, m_creature); - - m_creature->CastSpell(m_creature,SPELL_SUMMON_GLOBULE_1,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_GLOBULE_2,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_GLOBULE_3,true); - m_creature->CastSpell(m_creature,SPELL_SUMMON_GLOBULE_4,false); - - m_uiWateryGlobules_Timer = 25000; - }else m_uiWateryGlobules_Timer -= uiDiff; + WateryGlobules_Timer = 25000; + }else WateryGlobules_Timer -= diff; } DoMeleeAttackIfReady(); @@ -242,61 +291,67 @@ struct TRINITY_DLL_DECL boss_morogrim_tidewalkerAI : public ScriptedAI }; //Water Globule AI +#define SPELL_GLOBULE_EXPLOSION 37871 + struct TRINITY_DLL_DECL mob_water_globuleAI : public ScriptedAI { - mob_water_globuleAI(Creature* c) : ScriptedAI(c) { } + mob_water_globuleAI(Creature *c) : ScriptedAI(c) {} - // timers - uint32 m_uiCheck_Timer; + uint32 Check_Timer; void Reset() { - m_uiCheck_Timer = 1000; + Check_Timer = 1000; + + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->setFaction(14); } - void MoveInLineOfSight(Unit* pWho) + void EnterCombat(Unit *who) {} + + void MoveInLineOfSight(Unit *who) { - if (!pWho || m_creature->getVictim()) + if (!who || m_creature->getVictim()) return; - if (pWho->isTargetableForAttack() && pWho->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(pWho)) + if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { //no attack radius check - it attacks the first target that moves in his los - //pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - AttackStart(pWho); + //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + AttackStart(who); } } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 diff) { //Return since we have no target - if (!UpdateVictim()) + if (!UpdateVictim() ) return; - if (m_uiCheck_Timer < uiDiff) + if (Check_Timer < diff) { if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 5)) { - m_creature->DealDamage(m_creature->getVictim(), 4000+rand()%2000, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FROST, NULL, false); + DoCast(m_creature->getVictim(), SPELL_GLOBULE_EXPLOSION); //despawn m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } - m_uiCheck_Timer = 500; - }else m_uiCheck_Timer -= uiDiff; + Check_Timer = 500; + }else Check_Timer -= diff; //do NOT deal any melee damage to the target. } }; -CreatureAI* GetAI_boss_morogrim_tidewalker(Creature* pCreature) +CreatureAI* GetAI_boss_morogrim_tidewalker(Creature *_Creature) { - return new boss_morogrim_tidewalkerAI (pCreature); + return new boss_morogrim_tidewalkerAI (_Creature); } -CreatureAI* GetAI_mob_water_globule(Creature* pCreature) +CreatureAI* GetAI_mob_water_globule(Creature *_Creature) { - return new mob_water_globuleAI (pCreature); + return new mob_water_globuleAI (_Creature); } void AddSC_boss_morogrim_tidewalker() @@ -304,12 +359,13 @@ void AddSC_boss_morogrim_tidewalker() Script *newscript; newscript = new Script; - newscript->Name = "boss_morogrim_tidewalker"; + newscript->Name="boss_morogrim_tidewalker"; newscript->GetAI = &GetAI_boss_morogrim_tidewalker; newscript->RegisterSelf(); newscript = new Script; - newscript->Name = "mob_water_globule"; + newscript->Name="mob_water_globule"; newscript->GetAI = &GetAI_mob_water_globule; newscript->RegisterSelf(); } + |