diff options
5 files changed, 547 insertions, 562 deletions
diff --git a/sql/FULL/world_script_texts.sql b/sql/FULL/world_script_texts.sql index 258f68a779e..601150062b5 100644 --- a/sql/FULL/world_script_texts.sql +++ b/sql/FULL/world_script_texts.sql @@ -345,7 +345,8 @@ INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content (-1000427, 'Something tells me this $r wants the mysterious fossil too. Help!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 7, 0, 'remtravel SAY_REM_AGGRO'), (-1000428, 'Ah...the wondrous sound of kodos. I love the way they make the ground shake... inspect the beast for me.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,'kodo round SAY_SMEED_HOME_1'), (-1000429, 'Hey, look out with that kodo! You had better inspect that beast before i give you credit!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,'kodo round SAY_SMEED_HOME_2'), -(-1000430, 'That kodo sure is a beauty. Wait a minute, where are my bifocals? Perhaps you should inspect the beast for me.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 'kodo round SAY_SMEED_HOME_3'); +(-1000430, 'That kodo sure is a beauty. Wait a minute, where are my bifocals? Perhaps you should inspect the beast for me.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 'kodo round SAY_SMEED_HOME_3'), +(-1000431, 'Okay, okay... gimme a minute to rest now. You gone and beat me up good.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 14, 1, 'calvin SAY_COMPLETE'); -- -1 033 000 SHADOWFANG KEEP INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES diff --git a/sql/updates/4803_script_texts.sql b/sql/updates/4803_script_texts.sql new file mode 100644 index 00000000000..a91fa99c22b --- /dev/null +++ b/sql/updates/4803_script_texts.sql @@ -0,0 +1,3 @@ +DELETE FROM script_texts WHERE entry=-1000431; +INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES +(-1000431,'Okay, okay... gimme a minute to rest now. You gone and beat me up good.',0,0,14,1,'calvin SAY_COMPLETE'); diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp index b33a3030e1d..0766a0ed1f9 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp @@ -15,9 +15,9 @@ */ /* ScriptData -SDName: boss_Kaelthas +SDName: Boss_Kaelthas SD%Complete: 60 -SDComment: Mind Control, Reset Event if Weapons despawn/reset +SDComment: SQL, weapon scripts, mind control, need correct spells(interruptible/uninterruptible), phoenix spawn location & animation, phoenix behaviour & spawn during gravity lapse SDCategory: Tempest Keep, The Eye EndScriptData */ @@ -25,142 +25,158 @@ EndScriptData */ #include "def_the_eye.h" #include "WorldPacket.h" - //kael'thas Speech -#define SAY_INTRO -1550016 -#define SAY_INTRO_CAPERNIAN -1550017 -#define SAY_INTRO_TELONICUS -1550018 -#define SAY_INTRO_THALADRED -1550019 -#define SAY_INTRO_SANGUINAR -1550020 -#define SAY_PHASE2_WEAPON -1550021 -#define SAY_PHASE3_ADVANCE -1550022 -#define SAY_PHASE4_INTRO2 -1550023 -#define SAY_PHASE5_NUTS -1550024 -#define SAY_SLAY1 -1550025 -#define SAY_SLAY2 -1550026 -#define SAY_SLAY3 -1550027 -#define SAY_MINDCONTROL1 -1550028 -#define SAY_MINDCONTROL2 -1550029 -#define SAY_GRAVITYLAPSE1 -1550030 -#define SAY_GRAVITYLAPSE2 -1550031 -#define SAY_SUMMON_PHOENIX1 -1550032 -#define SAY_SUMMON_PHOENIX2 -1550033 -#define SAY_DEATH -1550034 - -//Thaladred the Darkener speech -#define SAY_THALADRED_AGGRO -1550035 -#define SAY_THALADRED_DEATH -1550036 -#define EMOTE_THALADRED_GAZE -1550037 - -//Lord Sanguinar speech -#define SAY_SANGUINAR_AGGRO -1550038 -#define SAY_SANGUINAR_DEATH -1550039 - -//Grand Astromancer Capernian speech -#define SAY_CAPERNIAN_AGGRO -1550040 -#define SAY_CAPERNIAN_DEATH -1550041 - -//Master Engineer Telonicus speech -#define SAY_TELONICUS_AGGRO -1550042 -#define SAY_TELONICUS_DEATH -1550043 - -//Phase 2 spells (Not used) -#define SPELL_SUMMON_WEAPONS 36976 -#define SPELL_SUMMON_WEAPONA 36958 -#define SPELL_SUMMON_WEAPONB 36959 -#define SPELL_SUMMON_WEAPONC 36960 -#define SPELL_SUMMON_WEAPOND 36961 -#define SPELL_SUMMON_WEAPONE 36962 -#define SPELL_SUMMON_WEAPONF 36963 -#define SPELL_SUMMON_WEAPONG 36964 -#define SPELL_RES_VISUAL 24171 -#define SPELL_WEAPON_SPAWN 41236 - -//Phase 4 spells -#define SPELL_FIREBALL 36805 -#define SPELL_PYROBLAST 36819 -#define SPELL_FLAME_STRIKE 36735 -#define SPELL_FLAME_STRIKE_VIS 36730 -#define SPELL_FLAME_STRIKE_DMG 36731 -#define SPELL_ARCANE_DISRUPTION 36834 -#define SPELL_SHOCK_BARRIER 36815 -#define SPELL_SUMMON_PHOENIX 36723 -#define SPELL_MIND_CONTROL 32830 - -//Phase 5 spells -#define SPELL_EXPLODE 36092 -#define SPELL_FULLPOWER 36187 -#define SPELL_KNOCKBACK 11027 -#define SPELL_GRAVITY_LAPSE 34480 -#define SPELL_GRAVITY_LAPSE_AURA 39432 -#define SPELL_NETHER_BEAM 35873 - -//Thaladred the Darkener spells -#define SPELL_PSYCHIC_BLOW 10689 -#define SPELL_SILENCE 30225 - -//Lord Sanguinar spells -#define SPELL_BELLOWING_ROAR 40636 - -//Grand Astromancer Capernian spells -#define CAPERNIAN_DISTANCE 20 //she casts away from the target -#define SPELL_CAPERNIAN_FIREBALL 36971 -#define SPELL_CONFLAGRATION 37018 -#define SPELL_ARCANE_EXPLOSION 36970 - -//Master Engineer Telonicus spells -#define SPELL_BOMB 37036 -#define SPELL_REMOTE_TOY 37027 - -//Nether Vapor spell -#define SPELL_NETHER_VAPOR 35859 - -//Phoenix spell -#define SPELL_BURN 36720 -#define SPELL_EMBER_BLAST 34341 -#define SPELL_REBIRTH 41587 - -//Creature IDs -#define PHOENIX 21362 -#define PHOENIX_EGG 21364 - -//Phoenix egg and phoenix model -#define PHOENIX_MODEL 19682 -#define PHOENIX_EGG_MODEL 20245 - -//weapon id + position -float KaelthasWeapons[7][5] = +enum { - {21270, 794.38, 15, 48.72, 2.9}, //[Cosmic Infuser] - {21269, 785.47, 12.12, 48.72, 3.14}, //[Devastation] - {21271, 781.25, 4.39, 48.72, 3.14}, //[Infinity Blade] - {21273, 777.38, -0.81, 48.72, 3.06}, //[Phaseshift Bulwark] - {21274, 781.48, -6.08, 48.72, 3.9}, //[Staff of Disintegration] - {21272, 785.42, -13.59, 48.72, 3.4}, //[Warp Slicer] - {21268, 793.06, -16.61, 48.72, 3.10} //[Netherstrand Longbow] + //kael'thas Speech + SAY_INTRO = -1550016, + SAY_INTRO_CAPERNIAN = -1550017, + SAY_INTRO_TELONICUS = -1550018, + SAY_INTRO_THALADRED = -1550019, + SAY_INTRO_SANGUINAR = -1550020, + SAY_PHASE2_WEAPON = -1550021, + SAY_PHASE3_ADVANCE = -1550022, + SAY_PHASE4_INTRO2 = -1550023, + SAY_PHASE5_NUTS = -1550024, + SAY_SLAY1 = -1550025, + SAY_SLAY2 = -1550026, + SAY_SLAY3 = -1550027, + SAY_MINDCONTROL1 = -1550028, + SAY_MINDCONTROL2 = -1550029, + SAY_GRAVITYLAPSE1 = -1550030, + SAY_GRAVITYLAPSE2 = -1550031, + SAY_SUMMON_PHOENIX1 = -1550032, + SAY_SUMMON_PHOENIX2 = -1550033, + SAY_DEATH = -1550034, + + //Thaladred the Darkener speech + SAY_THALADRED_AGGRO = -1550035, + SAY_THALADRED_DEATH = -1550036, + EMOTE_THALADRED_GAZE = -1550037, + + //Lord Sanguinar speech + SAY_SANGUINAR_AGGRO = -1550038, + SAY_SANGUINAR_DEATH = -1550039, + + //Grand Astromancer Capernian speech + SAY_CAPERNIAN_AGGRO = -1550040, + SAY_CAPERNIAN_DEATH = -1550041, + + //Master Engineer Telonicus speech + SAY_TELONICUS_AGGRO = -1550042, + SAY_TELONICUS_DEATH = -1550043, + + //Phase 2 spells + SPELL_SUMMON_WEAPONS = 36976, + SPELL_SUMMON_WEAPONA = 36958, + SPELL_SUMMON_WEAPONB = 36959, + SPELL_SUMMON_WEAPONC = 36960, + SPELL_SUMMON_WEAPOND = 36961, + SPELL_SUMMON_WEAPONE = 36962, + SPELL_SUMMON_WEAPONF = 36963, + SPELL_SUMMON_WEAPONG = 36964, + SPELL_RES_VISUAL = 24171, + + //Phase 4 spells + SPELL_FIREBALL = 22088, //wrong but works with CastCustomSpell + SPELL_PYROBLAST = 36819, + SPELL_FLAME_STRIKE = 36735, + SPELL_FLAME_STRIKE_VIS = 36730, + SPELL_FLAME_STRIKE_DMG = 36731, + SPELL_ARCANE_DISRUPTION = 36834, + SPELL_SHOCK_BARRIER = 36815, + SPELL_PHOENIX_ANIMATION = 36723, + SPELL_MIND_CONTROL = 32830, + + //Phase 5 spells + SPELL_EXPLODE = 36092, + SPELL_FULLPOWER = 36187, + SPELL_KNOCKBACK = 11027, + SPELL_GRAVITY_LAPSE = 34480, + SPELL_GRAVITY_LAPSE_AURA = 39432, + SPELL_NETHER_BEAM = 35873, + + //Thaladred the Darkener spells + SPELL_PSYCHIC_BLOW = 10689, + SPELL_SILENCE = 30225, + //Lord Sanguinar spells + SPELL_BELLOWING_ROAR = 40636, + //Grand Astromancer Capernian spells + + SPELL_CAPERNIAN_FIREBALL = 36971, + SPELL_CONFLAGRATION = 37018, + SPELL_ARCANE_EXPLOSION = 36970, + //Master Engineer Telonicus spells + SPELL_BOMB = 37036, + SPELL_REMOTE_TOY = 37027, + //Nether Vapor spell + SPELL_NETHER_VAPOR = 35859, + //Phoenix spell + SPELL_BURN = 36720, + SPELL_EMBER_BLAST = 34341, + SPELL_REBIRTH = 41587, + + //Creature IDs + NPC_PHOENIX = 21362, + NPC_PHOENIX_EGG = 21364, + + //Phoenix egg and phoenix model + MODEL_ID_PHOENIX = 19682, + MODEL_ID_PHOENIX_EGG = 20245, + + MAX_ADVISORS = 4 }; -#define GRAVITY_X 795.0f -#define GRAVITY_Y 0.0f -#define GRAVITY_Z 70.0f +uint32 m_auiSpellSummonWeapon[]= +{ + SPELL_SUMMON_WEAPONA, SPELL_SUMMON_WEAPONB, SPELL_SUMMON_WEAPONC, SPELL_SUMMON_WEAPOND, + SPELL_SUMMON_WEAPONE, SPELL_SUMMON_WEAPONF, SPELL_SUMMON_WEAPONG +}; + +const float CAPERNIAN_DISTANCE = 20.0f; //she casts away from the target +const float KAEL_VISIBLE_RANGE = 50.0f; + +const float afGravityPos[3] = {795.0f, 0.0f, 70.0f}; #define TIME_PHASE_2_3 120000 #define TIME_PHASE_3_4 180000 -#define KAEL_VISIBLE_RANGE 50.0f -#define ROOM_BASE_Z 49.0f - //Base AI for Advisors struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI { - ScriptedInstance* pInstance; + advisorbase_ai(Creature* pCreature) : ScriptedAI(pCreature) + { + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + m_bDoubled_Health = false; + } + + ScriptedInstance* m_pInstance; bool FakeDeath; + bool m_bDoubled_Health; uint32 DelayRes_Timer; uint64 DelayRes_Target; - advisorbase_ai(Creature *c) : ScriptedAI(c) + void Reset() { - pInstance = c->GetInstanceData(); + if (m_bDoubled_Health) + { + m_creature->SetMaxHealth(m_creature->GetMaxHealth() / 2); + m_bDoubled_Health = false; + } + FakeDeath = false; + DelayRes_Timer = 0; + DelayRes_Target = 0; + + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + //reset encounter + if (m_pInstance && (m_pInstance->GetData(DATA_KAELTHASEVENT) == 1 || m_pInstance->GetData(DATA_KAELTHASEVENT) == 3)) + { + if (Creature *Kaelthas = (Creature*)Unit::GetUnit((*m_creature), m_pInstance->GetData64(DATA_KAELTHAS))) + Kaelthas->AI()->EnterEvadeMode(); + } } void MoveInLineOfSight(Unit *who) @@ -179,36 +195,15 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI ScriptedAI::AttackStart(who); } - void Reset() - { - if (FakeDeath) - m_creature->SetMaxHealth(m_creature->GetMaxHealth() / 2); - - m_creature->SetNoCallAssistance(true); - FakeDeath = false; - DelayRes_Timer = 0; - DelayRes_Target = 0; - - m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - //reset encounter - if(pInstance && (pInstance->GetData(DATA_KAELTHASEVENT) == 1 || pInstance->GetData(DATA_KAELTHASEVENT) == 3)) - { - Creature *Kaelthas = NULL; - Kaelthas = (Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_KAELTHAS))); - - if(Kaelthas) - Kaelthas->AI()->EnterEvadeMode(); - } - } - void Revive(Unit* Target) { m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + // double health for phase 3 + m_creature->SetMaxHealth(m_creature->GetMaxHealth() * 2); + m_bDoubled_Health = true; m_creature->SetHealth(m_creature->GetMaxHealth()); - m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + DoCast(m_creature, SPELL_RES_VISUAL, false); DelayRes_Timer = 2000; } @@ -219,13 +214,14 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI return; //Prevent glitch if in fake death - if (FakeDeath) + if (FakeDeath && m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) != 0) { damage = 0; return; } + //Don't really die in phase 1 & 3, only die after that - if(pInstance && pInstance->GetData(DATA_KAELTHASEVENT) != 0) + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) != 0) { //prevent death damage = 0; @@ -233,6 +229,7 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI m_creature->InterruptNonMeleeSpells(false); m_creature->SetHealth(0); + m_creature->StopMoving(); m_creature->ClearComboPointHolders(); m_creature->RemoveAllAurasOnDeath(); m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false); @@ -243,12 +240,7 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveIdle(); m_creature->SetStandState(UNIT_STAND_STATE_DEAD); - - // Double health for Phase 3 - m_creature->SetMaxHealth(m_creature->GetMaxHealth() * 2); - - if (pInstance->GetData(DATA_KAELTHASEVENT) == 3) - JustDied(pKiller); + JustDied(pKiller); } } @@ -264,9 +256,8 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI Unit* Target = Unit::GetUnit((*m_creature), DelayRes_Target); if (!Target) Target = m_creature->getVictim(); + DoResetThreat(); - if(!Target) - return; AttackStart(Target); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(Target); @@ -274,23 +265,19 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI }else DelayRes_Timer -= diff; } } + }; //Kael'thas AI struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI { - boss_kaelthasAI(Creature *c) : ScriptedAI(c), summons(m_creature) + boss_kaelthasAI(Creature* pCreature) : ScriptedAI(pCreature), summons(m_creature) { - pInstance = c->GetInstanceData(); - AdvisorGuid[0] = 0; - AdvisorGuid[1] = 0; - AdvisorGuid[2] = 0; - AdvisorGuid[3] = 0; + m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + memset(&m_auiAdvisorGuid, 0, sizeof(m_auiAdvisorGuid)); } - ScriptedInstance* pInstance; - - std::list<uint64> Phoenix; + ScriptedInstance* m_pInstance; uint32 Fireball_Timer; uint32 ArcaneDisruption_Timer; @@ -302,7 +289,6 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI uint32 NetherVapor_Timer; uint32 FlameStrike_Timer; uint32 MindControl_Timer; - uint32 Check_Timer; uint32 Phase; uint32 PhaseSubphase; //generic uint32 Phase_Timer; //generic timer @@ -312,31 +298,12 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI bool IsCastingFireball; bool ChainPyros; - uint64 AdvisorGuid[4]; - uint64 WeaponGuid[7]; SummonList summons; - void DeleteLegs() - { - Map::PlayerList const &PlayerList = m_creature->GetMap()->GetPlayers(); - for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - { - Player* i_pl = i->getSource(); - i_pl->DestroyItemCount(30312, 1, true); - i_pl->DestroyItemCount(30311, 1, true); - i_pl->DestroyItemCount(30317, 1, true); - i_pl->DestroyItemCount(30316, 1, true); - i_pl->DestroyItemCount(30313, 1, true); - i_pl->DestroyItemCount(30314, 1, true); - i_pl->DestroyItemCount(30318, 1, true); - i_pl->DestroyItemCount(30319, 1, true); - i_pl->DestroyItemCount(30320, 1, true); - } - } + uint64 m_auiAdvisorGuid[MAX_ADVISORS]; void Reset() { - m_creature->SetNoCallAssistance(true); Fireball_Timer = 5000+rand()%10000; ArcaneDisruption_Timer = 45000; MindControl_Timer = 40000; @@ -347,33 +314,29 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI GravityLapse_Phase = 0; NetherBeam_Timer = 8000; NetherVapor_Timer = 10000; - Check_Timer = 4000; PyrosCasted = 0; Phase = 0; InGravityLapse = false; IsCastingFireball = false; ChainPyros = false; - if(m_creature->isInCombat()) + if (m_creature->isInCombat()) PrepareAdvisors(); - DeleteLegs(); summons.DespawnAll(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if(pInstance) - pInstance->SetData(DATA_KAELTHASEVENT, NOT_STARTED); + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 0); } void PrepareAdvisors() { - Creature *pCreature; - for(uint8 i = 0; i < 4; ++i) + for(uint8 i = 0; i < MAX_ADVISORS; i++) { - pCreature = (Unit::GetCreature((*m_creature), AdvisorGuid[i])); - if(pCreature) + if (Creature *pCreature = (Creature*)Unit::GetUnit((*m_creature), m_auiAdvisorGuid[i])) { pCreature->Respawn(); pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); @@ -385,39 +348,38 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI void StartEvent() { - if(!pInstance) + if (!m_pInstance) return; - AdvisorGuid[0] = pInstance->GetData64(DATA_THALADREDTHEDARKENER); - AdvisorGuid[1] = pInstance->GetData64(DATA_LORDSANGUINAR); - AdvisorGuid[2] = pInstance->GetData64(DATA_GRANDASTROMANCERCAPERNIAN); - AdvisorGuid[3] = pInstance->GetData64(DATA_MASTERENGINEERTELONICUS); + m_auiAdvisorGuid[0] = m_pInstance->GetData64(DATA_THALADREDTHEDARKENER); + m_auiAdvisorGuid[1] = m_pInstance->GetData64(DATA_LORDSANGUINAR); + m_auiAdvisorGuid[2] = m_pInstance->GetData64(DATA_GRANDASTROMANCERCAPERNIAN); + m_auiAdvisorGuid[3] = m_pInstance->GetData64(DATA_MASTERENGINEERTELONICUS); - if(!AdvisorGuid[0] || !AdvisorGuid[1] || !AdvisorGuid[2] || !AdvisorGuid[3]) + if (!m_auiAdvisorGuid[0] || !m_auiAdvisorGuid[1] || !m_auiAdvisorGuid[2] || !m_auiAdvisorGuid[3]) { error_log("TSCR: Kael'Thas One or more advisors missing, Skipping Phases 1-3"); - DoYell("TSCR: Kael'Thas One or more advisors missing, Skipping Phases 1-3", LANG_UNIVERSAL, NULL); DoScriptText(SAY_PHASE4_INTRO2, m_creature); + Phase = 4; - pInstance->SetData(DATA_KAELTHASEVENT, 4); + m_pInstance->SetData(DATA_KAELTHASEVENT, 4); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Unit *target = NULL; - target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if(target) + if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0)) AttackStart(target); - } + + } else { PrepareAdvisors(); DoScriptText(SAY_INTRO, m_creature); - pInstance->SetData(DATA_KAELTHASEVENT, IN_PROGRESS); + m_pInstance->SetData(DATA_KAELTHASEVENT, 1); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); PhaseSubphase = 0; @@ -426,26 +388,60 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI } } + void MoveInLineOfSight(Unit *who) + { + if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() && + m_creature->IsHostileTo(who) && who->isInAccessiblePlaceFor(m_creature)) + { + 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)) + { + if (!m_creature->getVictim() && Phase >= 4) + { + who->RemoveAurasDueToSpell(SPELL_AURA_MOD_STEALTH); + AttackStart(who); + } + else if (m_creature->GetMap()->IsDungeon()) + { + if (m_pInstance && !m_pInstance->GetData(DATA_KAELTHASEVENT) && !Phase) + StartEvent(); + + who->SetInCombatWith(m_creature); + m_creature->AddThreat(who, 0.0f); + } + } + } + } + + void Aggro(Unit *who) + { + if (m_pInstance && !m_pInstance->GetData(DATA_KAELTHASEVENT) && !Phase) + StartEvent(); + } + void KilledUnit() { 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 JustSummoned(Creature* summoned) + void JustSummoned(Creature* pSummoned) { - if(summoned->GetEntry() == PHOENIX) + // if not phoenix, then it's one of the 7 weapons + if (pSummoned->GetEntry() != NPC_PHOENIX) { - summoned->setFaction(m_creature->getFaction()); - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if(target) - summoned->AI()->AttackStart(target); + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); + + summons.Summon(pSummoned); } - summons.Summon(summoned); } void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} @@ -457,220 +453,177 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI DoScriptText(SAY_DEATH, m_creature); - DeleteLegs(); summons.DespawnAll(); - if(pInstance) - pInstance->SetData(DATA_KAELTHASEVENT, DONE); + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 0); - Creature *pCreature; - for(uint8 i = 0; i < 4; ++i) + for(uint8 i = 0; i < MAX_ADVISORS; i++) { - pCreature = (Unit::GetCreature((*m_creature), AdvisorGuid[i])); - if(pCreature) - { - pCreature->setDeathState(JUST_DIED); - } - } - } - - void EnterCombat(Unit *who) - { - if (pInstance && !pInstance->GetData(DATA_KAELTHASEVENT) && !Phase) - StartEvent(); - } - - void MoveInLineOfSight(Unit *who) - { - if (!m_creature->getVictim() && who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who)) - { - if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) - return; - - float attackRadius = m_creature->GetAttackDistance(who); - if (Phase >= 4 && m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who)) - { - AttackStart(who); - } - else if(who->isAlive()) - { - if (pInstance && !pInstance->GetData(DATA_KAELTHASEVENT) && !Phase && m_creature->IsWithinDistInMap(who, 60.0f)) - StartEvent(); - - //add to the threat list, so we can use SelectTarget - m_creature->AddThreat(who,0.0f); - } + if (Unit* pAdvisor = Unit::GetUnit((*m_creature), m_auiAdvisorGuid[i])) + pAdvisor->DealDamage(pAdvisor, pAdvisor->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } } void UpdateAI(const uint32 diff) { - - if(pInstance && Phase) - { - if(pInstance->GetData(DATA_KAELTHASEVENT) == IN_PROGRESS && m_creature->getThreatManager().getThreatList().empty()) - { - EnterEvadeMode(); - return; - } - } //Phase 1 switch (Phase) { case 1: { - Unit *target; - Creature* Advisor; + Unit *target = NULL; + Creature* Advisor = NULL; //Subphase switch switch(PhaseSubphase) { //Subphase 1 - Start case 0: - if(Phase_Timer < diff) + if (Phase_Timer < diff) { DoScriptText(SAY_INTRO_THALADRED, m_creature); //start advisor within 7 seconds Phase_Timer = 7000; - - ++PhaseSubphase; + PhaseSubphase++; }else Phase_Timer -= diff; break; - //Subphase 1 - Unlock advisor + //Subphase 1 - Unlock advisor case 1: - if(Phase_Timer < diff) + if (Phase_Timer < diff) { - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[0])); + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[0])); - if(Advisor) + if (Advisor) { Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Advisor->setFaction(m_creature->getFaction()); target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if(target) + if (target) Advisor->AI()->AttackStart(target); } - ++PhaseSubphase; + PhaseSubphase++; }else Phase_Timer -= diff; break; - //Subphase 2 - Start + //Subphase 2 - Start case 2: - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[0])); - if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD)) + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[0])); + + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) { DoScriptText(SAY_INTRO_SANGUINAR, m_creature); //start advisor within 12.5 seconds Phase_Timer = 12500; - - ++PhaseSubphase; + PhaseSubphase++; } break; - //Subphase 2 - Unlock advisor + //Subphase 2 - Unlock advisor case 3: - if(Phase_Timer < diff) + if (Phase_Timer < diff) { - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[1])); + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[1])); - if(Advisor) + if (Advisor) { Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Advisor->setFaction(m_creature->getFaction()); target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if(target) + if (target) Advisor->AI()->AttackStart(target); } - ++PhaseSubphase; + PhaseSubphase++; }else Phase_Timer -= diff; break; - //Subphase 3 - Start + //Subphase 3 - Start case 4: - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[1])); - if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD)) + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[1])); + + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) { DoScriptText(SAY_INTRO_CAPERNIAN, m_creature); //start advisor within 7 seconds Phase_Timer = 7000; - - ++PhaseSubphase; + PhaseSubphase++; } break; - //Subphase 3 - Unlock advisor + //Subphase 3 - Unlock advisor case 5: - if(Phase_Timer < diff) + if (Phase_Timer < diff) { - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[2])); + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[2])); - if(Advisor) + if (Advisor) { Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Advisor->setFaction(m_creature->getFaction()); target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if(target) + if (target) Advisor->AI()->AttackStart(target); } - ++PhaseSubphase; + PhaseSubphase++; }else Phase_Timer -= diff; break; - //Subphase 4 - Start + //Subphase 4 - Start case 6: - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[2])); - if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD)) + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[2])); + + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) { DoScriptText(SAY_INTRO_TELONICUS, m_creature); //start advisor within 8.4 seconds Phase_Timer = 8400; - - ++PhaseSubphase; + PhaseSubphase++; } break; - //Subphase 4 - Unlock advisor + //Subphase 4 - Unlock advisor case 7: - if(Phase_Timer < diff) + if (Phase_Timer < diff) { - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[3])); + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[3])); - if(Advisor) + if (Advisor) { Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Advisor->setFaction(m_creature->getFaction()); target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if(target) + if (target) Advisor->AI()->AttackStart(target); } Phase_Timer = 3000; - - ++PhaseSubphase; + PhaseSubphase++; }else Phase_Timer -= diff; break; - //End of phase 1 + //End of phase 1 case 8: - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[3])); - if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD)) + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[3])); + + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) { Phase = 2; - pInstance->SetData(DATA_KAELTHASEVENT, 2); + m_pInstance->SetData(DATA_KAELTHASEVENT, 2); DoScriptText(SAY_PHASE2_WEAPON, m_creature); + PhaseSubphase = 0; Phase_Timer = 3500; DoCast(m_creature, SPELL_SUMMON_WEAPONS); @@ -692,39 +645,27 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI //Spawn weapons if (PhaseSubphase == 1) { - Creature* Weapon; - for (uint32 i = 0; i < 7; ++i) - { - Unit* Target = SelectUnit(SELECT_TARGET_RANDOM, 0); - Weapon = m_creature->SummonCreature(((uint32)KaelthasWeapons[i][0]),KaelthasWeapons[i][1],KaelthasWeapons[i][2],KaelthasWeapons[i][3],0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); + m_creature->CastSpell(m_creature, SPELL_SUMMON_WEAPONS, false); - if (!Weapon) - error_log("STSCR: Kael'thas weapon %i could not be spawned", i); - else - { - Weapon->setFaction(m_creature->getFaction()); - Weapon->AI()->AttackStart(Target); - Weapon->CastSpell(Weapon, SPELL_WEAPON_SPAWN, false); - WeaponGuid[i] = Weapon->GetGUID(); - } - } + uint8 uiMaxWeapon = sizeof(m_auiSpellSummonWeapon)/sizeof(uint32); + + for (uint32 i = 0; i < uiMaxWeapon; ++i) + m_creature->CastSpell(m_creature,m_auiSpellSummonWeapon[i],true); PhaseSubphase = 2; Phase_Timer = TIME_PHASE_2_3; } if (PhaseSubphase == 2) - if (Phase_Timer < diff) { - DoScriptText(SAY_PHASE3_ADVANCE, m_creature); - - if(pInstance) - pInstance->SetData(DATA_KAELTHASEVENT, 3); - - Phase = 3; - PhaseSubphase = 0; - }else Phase_Timer -= diff; - //missing Resetcheck + if (Phase_Timer < diff) + { + DoScriptText(SAY_PHASE3_ADVANCE, m_creature); + m_pInstance->SetData(DATA_KAELTHASEVENT, 3); + Phase = 3; + PhaseSubphase = 0; + }else Phase_Timer -= diff; + } }break; case 3: @@ -735,34 +676,36 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI Unit* Target = SelectUnit(SELECT_TARGET_RANDOM, 0); Creature* Advisor; - for (uint32 i = 0; i < 4; ++i) + for (uint32 i = 0; i < MAX_ADVISORS; i++) { - Advisor = (Unit::GetCreature((*m_creature), AdvisorGuid[i])); + Advisor = (Creature*)(Unit::GetUnit((*m_creature), m_auiAdvisorGuid[i])); + if (!Advisor) - error_log("TSCR: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i); - else if(Target) - CAST_AI(advisorbase_ai, Advisor->AI())->Revive(Target); + error_log("SD2: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i); + else + ((advisorbase_ai*)Advisor->AI())->Revive(Target); } PhaseSubphase = 1; Phase_Timer = TIME_PHASE_3_4; } - if(Phase_Timer < diff) + if (Phase_Timer < diff) { DoScriptText(SAY_PHASE4_INTRO2, m_creature); Phase = 4; - pInstance->SetData(DATA_KAELTHASEVENT, 4); + m_pInstance->SetData(DATA_KAELTHASEVENT, 4); + + // Sometimes people can collect Aggro in Phase 1-3. Reset threat before releasing Kael. + DoResetThreat(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) - { - DoResetThreat();//only healers will be at top threat, so reset(not delete) all players's threat when Kael comes to fight AttackStart(target); - } + Phase_Timer = 30000; }else Phase_Timer -= diff; } @@ -773,21 +716,22 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI case 6: { //Return since we have no target - if (!UpdateVictim() ) + if (!UpdateVictim()) return; //Fireball_Timer - if(!InGravityLapse && !ChainPyros && Phase != 5) + if (!InGravityLapse && !ChainPyros && Phase != 5) { - if(Fireball_Timer < diff) + if (Fireball_Timer < diff) { - if(!IsCastingFireball) + if (!IsCastingFireball) { - if(!m_creature->IsNonMeleeSpellCasted(false)) + if (!m_creature->IsNonMeleeSpellCasted(false)) { //interruptable m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); - m_creature->CastSpell(m_creature->getVictim(), SPELL_FIREBALL, false); + int32 dmg = 20000+rand()%5000; + m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_FIREBALL, &dmg, 0, 0, false); IsCastingFireball = true; Fireball_Timer = 2500; } @@ -802,16 +746,15 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI }else Fireball_Timer -= diff; //ArcaneDisruption_Timer - if(ArcaneDisruption_Timer < diff) + if (ArcaneDisruption_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_ARCANE_DISRUPTION, true); - ArcaneDisruption_Timer = 60000; }else ArcaneDisruption_Timer -= diff; if (FlameStrike_Timer < diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true)) + if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(pUnit, SPELL_FLAME_STRIKE); FlameStrike_Timer = 30000; @@ -820,14 +763,10 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI if (MindControl_Timer < diff) { if (m_creature->getThreatManager().getThreatList().size() >= 2) - for (uint32 i = 0; i < 3; i++) + for (uint32 i = 0; i < 3; i++) { - - Unit* target =SelectTarget(SELECT_TARGET_RANDOM, 1, 70, true); - if(!target) target = m_creature->getVictim(); - debug_log("TSCR: Kael'Thas mind control not supported."); - if(target) - DoCast(target, SPELL_MIND_CONTROL); + debug_log("SD2: Kael'Thas mind control not supported."); + //DoCast(pUnit, SPELL_MIND_CONTROL); } MindControl_Timer = 60000; @@ -835,32 +774,43 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI } //Phoenix_Timer - if(Phoenix_Timer < diff) + if (Phoenix_Timer < diff) { - DoCast(m_creature, SPELL_SUMMON_PHOENIX); + DoCast(m_creature, SPELL_PHOENIX_ANIMATION); + + if (Creature* pPhoenix = m_creature->SummonCreature(NPC_PHOENIX, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000)) + { + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + pPhoenix->AI()->AttackStart(pTarget); + } + else + error_log("SD2: Kael'Thas Phoenix could not be spawned"); + switch(rand()%2) { - case 0: DoScriptText(SAY_SUMMON_PHOENIX1, m_creature); break; - case 1: DoScriptText(SAY_SUMMON_PHOENIX2, m_creature); break; + case 0: DoScriptText(SAY_SUMMON_PHOENIX1, m_creature); break; + case 1: DoScriptText(SAY_SUMMON_PHOENIX2, m_creature); break; } Phoenix_Timer = 60000; }else Phoenix_Timer -= diff; //Phase 4 specific spells - if(Phase == 4) + if (Phase == 4) { if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50) { - pInstance->SetData(DATA_KAELTHASEVENT, 4); + m_pInstance->SetData(DATA_KAELTHASEVENT, 4); Phase = 5; Phase_Timer = 10000; DoScriptText(SAY_PHASE5_NUTS, m_creature); + m_creature->StopMoving(); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveIdle(); - DoTeleportTo(GRAVITY_X, GRAVITY_Y, GRAVITY_Z); + m_creature->Relocate(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0); + m_creature->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, 0, 0); m_creature->InterruptNonMeleeSpells(false); DoCast(m_creature, SPELL_FULLPOWER); @@ -868,73 +818,75 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI } //ShockBarrier_Timer - if(ShockBarrier_Timer < diff) + if (ShockBarrier_Timer < diff) { DoCast(m_creature, SPELL_SHOCK_BARRIER); ChainPyros = true; PyrosCasted = 0; - Check_Timer = 0; - ShockBarrier_Timer = 60000; }else ShockBarrier_Timer -= diff; //Chain Pyros (3 of them max) - if (ChainPyros){ - if (PyrosCasted < 3 && Check_Timer < diff) + if (ChainPyros && !m_creature->IsNonMeleeSpellCasted(false)) + { + if (PyrosCasted < 3) { DoCast(m_creature->getVictim(), SPELL_PYROBLAST); - ++PyrosCasted; + PyrosCasted++; - Check_Timer = 4400; - }else Check_Timer -= diff; - if(PyrosCasted > 3) + } + else { ChainPyros = false; Fireball_Timer = 2500; ArcaneDisruption_Timer = 60000; } } - }else Check_Timer -= 4100; + } if (Phase == 5) { - if(Phase_Timer < diff) + if (Phase_Timer < diff) { m_creature->InterruptNonMeleeSpells(false); m_creature->RemoveAurasDueToSpell(SPELL_FULLPOWER); + DoCast(m_creature, SPELL_EXPLODE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Phase = 6; - DoStartMovement(m_creature->getVictim()); AttackStart(m_creature->getVictim()); }else Phase_Timer -= diff; } //Phase 5 - if(Phase == 6) + if (Phase == 6) { //GravityLapse_Timer - if(GravityLapse_Timer < diff) + if (GravityLapse_Timer < diff) { std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin(); switch(GravityLapse_Phase) { case 0: + m_creature->StopMoving(); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveIdle(); - DoTeleportTo(GRAVITY_X, GRAVITY_Y, GRAVITY_Z); + m_creature->Relocate(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0); + m_creature->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, 0, 0); + // 1) Kael'thas will portal the whole raid right into his body - for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();) + for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();++i) { Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); - ++i; - if(pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) + if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) { //Use work around packet to prevent player from being dropped from combat - DoTeleportPlayer(pUnit, GRAVITY_X, GRAVITY_Y, GRAVITY_Z, pUnit->GetOrientation()); + DoTeleportPlayer(pUnit, afGravityPos[0], afGravityPos[1], afGravityPos[2], pUnit->GetOrientation()); } } + GravityLapse_Timer = 500; ++GravityLapse_Phase; InGravityLapse = true; @@ -945,16 +897,14 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI case 1: switch(rand()%2) { - case 0: DoScriptText(SAY_GRAVITYLAPSE1, m_creature); break; - case 1: DoScriptText(SAY_GRAVITYLAPSE2, m_creature); break; + case 0: DoScriptText(SAY_GRAVITYLAPSE1, m_creature); break; + case 1: DoScriptText(SAY_GRAVITYLAPSE2, m_creature); break; } // 2) At that point he will put a Gravity Lapse debuff on everyone - for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();) + for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();i++) { - Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); - ++i; - if(pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) + if (Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid())) { m_creature->CastSpell(pUnit, SPELL_KNOCKBACK, true); //Gravity lapse - needs an exception in Spell system to work @@ -971,7 +921,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI } } GravityLapse_Timer = 10000; - ++GravityLapse_Phase; + GravityLapse_Phase++; break; case 2: @@ -980,16 +930,14 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI DoCast(m_creature, SPELL_NETHER_VAPOR); GravityLapse_Timer = 20000; - ++GravityLapse_Phase; + GravityLapse_Phase++; break; case 3: //Remove flight - for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();) + for (i = m_creature->getThreatManager().getThreatList().begin(); i!= m_creature->getThreatManager().getThreatList().end();i++) { - Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); - ++i; - if(pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) + if (Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid())) { //Using packet workaround WorldPacket data(12); @@ -999,28 +947,27 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI pUnit->SendMessageToSet(&data, true); } } + m_creature->RemoveAurasDueToSpell(SPELL_NETHER_VAPOR); InGravityLapse = false; GravityLapse_Timer = 60000; GravityLapse_Phase = 0; - DoStartMovement(m_creature->getVictim()); AttackStart(m_creature->getVictim()); - DoResetThreat(); break; } }else GravityLapse_Timer -= diff; - if(InGravityLapse) + if (InGravityLapse) { //ShockBarrier_Timer - if(ShockBarrier_Timer < diff) + if (ShockBarrier_Timer < diff) { DoCast(m_creature, SPELL_SHOCK_BARRIER); ShockBarrier_Timer = 20000; }else ShockBarrier_Timer -= diff; //NetherBeam_Timer - if(NetherBeam_Timer < diff) + if (NetherBeam_Timer < diff) { if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(pUnit, SPELL_NETHER_BEAM); @@ -1040,7 +987,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI //Thaladred the Darkener AI struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai { - boss_thaladred_the_darkenerAI(Creature *c) : advisorbase_ai(c) {} + boss_thaladred_the_darkenerAI(Creature* pCreature) : advisorbase_ai(pCreature) {} uint32 Gaze_Timer; uint32 Silence_Timer; @@ -1055,12 +1002,7 @@ struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai advisorbase_ai::Reset(); } - void JustDied(Unit* pKiller) - { - DoScriptText(SAY_THALADRED_DEATH, m_creature); - } - - void EnterCombat(Unit *who) + void Aggro(Unit *who) { if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) return; @@ -1072,6 +1014,12 @@ struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai m_creature->AddThreat(who, 5000000.0f); } + void JustDied(Unit* pKiller) + { + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_THALADRED_DEATH, m_creature); + } + void UpdateAI(const uint32 diff) { advisorbase_ai::UpdateAI(diff); @@ -1081,33 +1029,30 @@ struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai return; //Return since we have no target - if (!UpdateVictim() ) + if (!UpdateVictim()) return; //Gaze_Timer - if(Gaze_Timer < diff) + if (Gaze_Timer < diff) { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) { DoResetThreat(); - if(target) - { - m_creature->AddThreat(target, 5000000.0f); - DoScriptText(EMOTE_THALADRED_GAZE, m_creature, target); - } + m_creature->AddThreat(target, 5000000.0f); + DoScriptText(EMOTE_THALADRED_GAZE, m_creature, target); Gaze_Timer = 8500; } }else Gaze_Timer -= diff; //Silence_Timer - if(Silence_Timer < diff) + if (Silence_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_SILENCE); Silence_Timer = 20000; }else Silence_Timer -= diff; //PsychicBlow_Timer - if(PsychicBlow_Timer < diff) + if (PsychicBlow_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_PSYCHIC_BLOW); PsychicBlow_Timer = 20000+rand()%5000; @@ -1120,7 +1065,7 @@ struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai //Lord Sanguinar AI struct TRINITY_DLL_DECL boss_lord_sanguinarAI : public advisorbase_ai { - boss_lord_sanguinarAI(Creature *c) : advisorbase_ai(c){} + boss_lord_sanguinarAI(Creature* pCreature) : advisorbase_ai(pCreature) {} uint32 Fear_Timer; @@ -1130,12 +1075,7 @@ struct TRINITY_DLL_DECL boss_lord_sanguinarAI : public advisorbase_ai advisorbase_ai::Reset(); } - void JustDied(Unit* Killer) - { - DoScriptText(SAY_SANGUINAR_DEATH, m_creature); - } - - void EnterCombat(Unit *who) + void Aggro(Unit *who) { if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) return; @@ -1146,6 +1086,12 @@ struct TRINITY_DLL_DECL boss_lord_sanguinarAI : public advisorbase_ai DoScriptText(SAY_SANGUINAR_AGGRO, m_creature); } + void JustDied(Unit* Killer) + { + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_SANGUINAR_DEATH, m_creature); + } + void UpdateAI(const uint32 diff) { advisorbase_ai::UpdateAI(diff); @@ -1155,11 +1101,11 @@ struct TRINITY_DLL_DECL boss_lord_sanguinarAI : public advisorbase_ai return; //Return since we have no target - if (!UpdateVictim() ) + if (!UpdateVictim()) return; //Fear_Timer - if(Fear_Timer < diff) + if (Fear_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_BELLOWING_ROAR); Fear_Timer = 25000+rand()%10000; //approximately every 30 seconds @@ -1172,7 +1118,7 @@ struct TRINITY_DLL_DECL boss_lord_sanguinarAI : public advisorbase_ai //Grand Astromancer Capernian AI struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ai { - boss_grand_astromancer_capernianAI(Creature *c) : advisorbase_ai(c){} + boss_grand_astromancer_capernianAI(Creature* pCreature) : advisorbase_ai(pCreature) {} uint32 Fireball_Timer; uint32 Conflagration_Timer; @@ -1193,7 +1139,8 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ void JustDied(Unit* pKiller) { - DoScriptText(SAY_CAPERNIAN_DEATH, m_creature); + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_CAPERNIAN_DEATH, m_creature); } void AttackStart(Unit* who) @@ -1203,11 +1150,15 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ if (m_creature->Attack(who, true)) { - DoStartMovement(who, CAPERNIAN_DISTANCE, M_PI/2); + m_creature->AddThreat(who, 0.0f); + m_creature->SetInCombatWith(who); + who->SetInCombatWith(m_creature); + + m_creature->GetMotionMaster()->MoveChase(who, CAPERNIAN_DISTANCE); } } - void EnterCombat(Unit *who) + void Aggro(Unit *who) { if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) return; @@ -1225,34 +1176,33 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ return; //Return since we have no target - if (!UpdateVictim() ) + if (!UpdateVictim()) return; //Yell_Timer - if(!Yell) + if (!Yell) { - if(Yell_Timer < diff) + if (Yell_Timer < diff) { DoScriptText(SAY_CAPERNIAN_AGGRO, m_creature); - Yell = true; }else Yell_Timer -= diff; } //Fireball_Timer - if(Fireball_Timer < diff) + if (Fireball_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_CAPERNIAN_FIREBALL); Fireball_Timer = 4000; }else Fireball_Timer -= diff; //Conflagration_Timer - if(Conflagration_Timer < diff) + if (Conflagration_Timer < diff) { Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); - if(target && m_creature->IsWithinDistInMap(target, 30)) + if (target && m_creature->IsWithinDistInMap(target, 30)) DoCast(target, SPELL_CONFLAGRATION); else DoCast(m_creature->getVictim(), SPELL_CONFLAGRATION); @@ -1261,7 +1211,7 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ }else Conflagration_Timer -= diff; //ArcaneExplosion_Timer - if(ArcaneExplosion_Timer < diff) + if (ArcaneExplosion_Timer < diff) { bool InMeleeRange = false; Unit *target = NULL; @@ -1270,7 +1220,7 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ { Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); //if in melee range - if(pUnit && pUnit->IsWithinDistInMap(m_creature, 5)) + if (pUnit && pUnit->IsWithinDistInMap(m_creature, 5)) { InMeleeRange = true; target = pUnit; @@ -1278,7 +1228,7 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ } } - if(InMeleeRange) + if (InMeleeRange) DoCast(target, SPELL_ARCANE_EXPLOSION); ArcaneExplosion_Timer = 4000+rand()%2000; @@ -1291,7 +1241,7 @@ struct TRINITY_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_ //Master Engineer Telonicus AI struct TRINITY_DLL_DECL boss_master_engineer_telonicusAI : public advisorbase_ai { - boss_master_engineer_telonicusAI(Creature *c) : advisorbase_ai(c){} + boss_master_engineer_telonicusAI(Creature* pCreature) : advisorbase_ai(pCreature) {} uint32 Bomb_Timer; uint32 RemoteToy_Timer; @@ -1306,10 +1256,11 @@ struct TRINITY_DLL_DECL boss_master_engineer_telonicusAI : public advisorbase_ai void JustDied(Unit* pKiller) { - DoScriptText(SAY_TELONICUS_DEATH, m_creature); + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_TELONICUS_DEATH, m_creature); } - void EnterCombat(Unit *who) + void Aggro(Unit *who) { if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) return; @@ -1329,18 +1280,18 @@ struct TRINITY_DLL_DECL boss_master_engineer_telonicusAI : public advisorbase_ai return; //Return since we have no target - if (!UpdateVictim() ) + if (!UpdateVictim()) return; //Bomb_Timer - if(Bomb_Timer < diff) + if (Bomb_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_BOMB); Bomb_Timer = 25000; }else Bomb_Timer -= diff; //RemoteToy_Timer - if(RemoteToy_Timer < diff) + if (RemoteToy_Timer < diff) { if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_REMOTE_TOY); @@ -1355,7 +1306,7 @@ struct TRINITY_DLL_DECL boss_master_engineer_telonicusAI : public advisorbase_ai //Flame Strike AI struct TRINITY_DLL_DECL mob_kael_flamestrikeAI : public ScriptedAI { - mob_kael_flamestrikeAI(Creature *c) : ScriptedAI(c) {} + mob_kael_flamestrikeAI(Creature* pCreature) : ScriptedAI(pCreature) {} uint32 Timer; bool Casting; @@ -1371,13 +1322,7 @@ struct TRINITY_DLL_DECL mob_kael_flamestrikeAI : public ScriptedAI m_creature->setFaction(14); } - void EnterCombat(Unit *who) - { - } - - void MoveInLineOfSight(Unit *who) - { - } + void MoveInLineOfSight(Unit *who) { } void UpdateAI(const uint32 diff) { @@ -1388,7 +1333,7 @@ struct TRINITY_DLL_DECL mob_kael_flamestrikeAI : public ScriptedAI } //Timer - if(Timer < diff) + if (Timer < diff) { if (!KillSelf) { @@ -1405,71 +1350,37 @@ struct TRINITY_DLL_DECL mob_kael_flamestrikeAI : public ScriptedAI //Phoenix AI struct TRINITY_DLL_DECL mob_phoenix_tkAI : public ScriptedAI { - mob_phoenix_tkAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } + mob_phoenix_tkAI(Creature* pCreature) : ScriptedAI(pCreature) {} - ScriptedInstance* pInstance; uint32 Cycle_Timer; - bool egg; - - void JustDied(Unit *victim) - { - if(egg) - { - float x,y,z; - m_creature->GetPosition(x,y,z); - z = m_creature->GetMap()->GetVmapHeight(x,y,z,true); - if(z == INVALID_HEIGHT) - z = ROOM_BASE_Z; - m_creature->SummonCreature(PHOENIX_EGG,x,y,z,m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,16000); - m_creature->RemoveCorpse(); - } - } - void Reset() { - m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);//birds can fly! :) - egg = true; Cycle_Timer = 2000; m_creature->CastSpell(m_creature,SPELL_BURN,true); } - void EnterCombat(Unit *who) { } - - void DamageTaken(Unit* pKiller, uint32 &damage) + void JustDied(Unit* killer) { - + //is this spell in use anylonger? + //m_creature->CastSpell(m_creature,SPELL_EMBER_BLAST,true); + m_creature->SummonCreature(NPC_PHOENIX_EGG,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,16000); } void UpdateAI(const uint32 diff) { + if (!UpdateVictim()) + return; + if (Cycle_Timer < diff) { - if(pInstance)//check for boss reset - { - Creature* Kael = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_KAELTHAS)); - if (Kael && Kael->getThreatManager().getThreatList().empty()) - { - egg = false; - m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - Cycle_Timer = 2000; - return; - } - } //spell Burn should possible do this, but it doesn't, so do this for now. uint32 dmg = urand(4500,5500); if (m_creature->GetHealth() > dmg) m_creature->SetHealth(uint32(m_creature->GetHealth()-dmg)); - else//kill itt - m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); Cycle_Timer = 2000; }else Cycle_Timer -= diff; - if (!UpdateVictim()) - return; DoMeleeAttackIfReady(); } }; @@ -1477,14 +1388,13 @@ struct TRINITY_DLL_DECL mob_phoenix_tkAI : public ScriptedAI //Phoenix Egg AI struct TRINITY_DLL_DECL mob_phoenix_egg_tkAI : public ScriptedAI { - mob_phoenix_egg_tkAI(Creature *c) : ScriptedAI(c) {} + mob_phoenix_egg_tkAI(Creature* pCreature) : ScriptedAI(pCreature) {} uint32 Rebirth_Timer; - bool summoned; - void Reset(){ - Rebirth_Timer = 15000; - summoned = false; + void Reset() + { + Rebirth_Timer = 15000; } //ignore any @@ -1494,12 +1404,13 @@ struct TRINITY_DLL_DECL mob_phoenix_egg_tkAI : public ScriptedAI { if (m_creature->Attack(who, false)) { + m_creature->SetInCombatWith(who); + who->SetInCombatWith(m_creature); + DoStartNoMovement(who); } } - void EnterCombat(Unit *who) { } - void JustSummoned(Creature* summoned) { summoned->AddThreat(m_creature->getVictim(), 0.0f); @@ -1508,82 +1419,82 @@ struct TRINITY_DLL_DECL mob_phoenix_egg_tkAI : public ScriptedAI void UpdateAI(const uint32 diff) { - if (Rebirth_Timer < diff) + if (!Rebirth_Timer) + return; + + if (Rebirth_Timer <= diff) { - if(!summoned) - { - Creature* Phoenix = m_creature->SummonCreature(PHOENIX,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_CORPSE_DESPAWN,5000); - summoned = true; - } - m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_creature->SummonCreature(NPC_PHOENIX,m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),m_creature->GetOrientation(),TEMPSUMMON_CORPSE_DESPAWN,5000); + Rebirth_Timer = 0; }else Rebirth_Timer -= diff; } }; -CreatureAI* GetAI_boss_kaelthas(Creature *_Creature) +CreatureAI* GetAI_boss_kaelthas(Creature* pCreature) { - return new boss_kaelthasAI (_Creature); + return new boss_kaelthasAI(pCreature); } -CreatureAI* GetAI_boss_thaladred_the_darkener(Creature *_Creature) +CreatureAI* GetAI_boss_thaladred_the_darkener(Creature* pCreature) { - return new boss_thaladred_the_darkenerAI (_Creature); + return new boss_thaladred_the_darkenerAI(pCreature); } -CreatureAI* GetAI_boss_lord_sanguinar(Creature *_Creature) +CreatureAI* GetAI_boss_lord_sanguinar(Creature* pCreature) { - return new boss_lord_sanguinarAI (_Creature); + return new boss_lord_sanguinarAI(pCreature); } -CreatureAI* GetAI_boss_grand_astromancer_capernian(Creature *_Creature) +CreatureAI* GetAI_boss_grand_astromancer_capernian(Creature* pCreature) { - return new boss_grand_astromancer_capernianAI (_Creature); + return new boss_grand_astromancer_capernianAI(pCreature); } -CreatureAI* GetAI_boss_master_engineer_telonicus(Creature *_Creature) +CreatureAI* GetAI_boss_master_engineer_telonicus(Creature* pCreature) { - return new boss_master_engineer_telonicusAI (_Creature); + return new boss_master_engineer_telonicusAI(pCreature); } -CreatureAI* GetAI_mob_kael_flamestrike(Creature *_Creature) +CreatureAI* GetAI_mob_kael_flamestrike(Creature* pCreature) { - return new mob_kael_flamestrikeAI (_Creature); + return new mob_kael_flamestrikeAI(pCreature); } -CreatureAI* GetAI_mob_phoenix_tk(Creature *_Creature) +CreatureAI* GetAI_mob_phoenix_tk(Creature* pCreature) { - return new mob_phoenix_tkAI (_Creature); + return new mob_phoenix_tkAI(pCreature); } -CreatureAI* GetAI_mob_phoenix_egg_tk(Creature *_Creature) +CreatureAI* GetAI_mob_phoenix_egg_tk(Creature* pCreature) { - return new mob_phoenix_egg_tkAI (_Creature); + return new mob_phoenix_egg_tkAI(pCreature); } + void AddSC_boss_kaelthas() { Script *newscript; newscript = new Script; - newscript->Name="boss_kaelthas"; + newscript->Name = "boss_kaelthas"; newscript->GetAI = &GetAI_boss_kaelthas; newscript->RegisterSelf(); newscript = new Script; - newscript->Name="boss_thaladred_the_darkener"; + newscript->Name = "boss_thaladred_the_darkener"; newscript->GetAI = &GetAI_boss_thaladred_the_darkener; newscript->RegisterSelf(); newscript = new Script; - newscript->Name="boss_lord_sanguinar"; + newscript->Name = "boss_lord_sanguinar"; newscript->GetAI = &GetAI_boss_lord_sanguinar; newscript->RegisterSelf(); newscript = new Script; - newscript->Name="boss_grand_astromancer_capernian"; + newscript->Name = "boss_grand_astromancer_capernian"; newscript->GetAI = &GetAI_boss_grand_astromancer_capernian; newscript->RegisterSelf(); newscript = new Script; - newscript->Name="boss_master_engineer_telonicus"; + newscript->Name = "boss_master_engineer_telonicus"; newscript->GetAI = &GetAI_boss_master_engineer_telonicus; newscript->RegisterSelf(); @@ -1593,7 +1504,7 @@ void AddSC_boss_kaelthas() newscript->RegisterSelf(); newscript = new Script; - newscript->Name="mob_phoenix_tk"; + newscript->Name = "mob_phoenix_tk"; newscript->GetAI = &GetAI_mob_phoenix_tk; newscript->RegisterSelf(); @@ -1602,4 +1513,3 @@ void AddSC_boss_kaelthas() newscript->GetAI = &GetAI_mob_phoenix_egg_tk; newscript->RegisterSelf(); } - diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp index 137e7270dc0..aea073a89f8 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp @@ -79,6 +79,7 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI void JustDied(Unit *victim) { DoScriptText(SAY_DEATH, m_creature); + DoZoneInCombat(); if(pInstance) pInstance->SetData(DATA_VOIDREAVEREVENT, DONE); @@ -119,13 +120,20 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); - //18 yard radius minimum + // exclude pets & totems + if (target->GetTypeId() != TYPEID_PLAYER) + continue; + + //18 yard radius minimum if(target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive() && !target->IsWithinDist(m_creature, 18, false)) target_list.push_back(target); target = NULL; } + if(target_list.size()) target = *(target_list.begin()+rand()%target_list.size()); + else + target = m_creature->getVictim(); if (target) m_creature->CastSpell(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), SPELL_ARCANE_ORB, false, NULL, NULL, NULL, target); diff --git a/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp b/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp index 1078a740a89..08e88782580 100644 --- a/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp +++ b/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp @@ -33,31 +33,94 @@ EndContentData */ ## npc_calvin_montague ######*/ -#define QUEST_590 590 -#define FACTION_FRIENDLY 68 -#define FACTION_HOSTILE 16 +enum +{ + SAY_COMPLETE = -1000431, + SPELL_DRINK = 2639, // possibly not correct spell (but iconId is correct) + QUEST_590 = 590, + FACTION_HOSTILE = 168 +}; struct TRINITY_DLL_DECL npc_calvin_montagueAI : public ScriptedAI { - npc_calvin_montagueAI(Creature* c) : ScriptedAI(c) {} + npc_calvin_montagueAI(Creature* pCreature) : ScriptedAI(pCreature) { } + + uint32 m_uiPhase; + uint32 m_uiPhaseTimer; + uint64 m_uiPlayerGUID; void Reset() { - m_creature->setFaction(FACTION_FRIENDLY); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + m_uiPhase = 0; + m_uiPhaseTimer = 5000; + m_uiPlayerGUID = 0; + + me->RestoreFaction(); + + if (!m_creature->HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_ATTACKABLE_2)) + m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_ATTACKABLE_2); } void EnterCombat(Unit* who) { } - void JustDied(Unit* Killer) + void AttackedBy(Unit* pAttacker) { - if( Killer->GetTypeId() == TYPEID_PLAYER ) - if( CAST_PLR(Killer)->GetQuestStatus(QUEST_590) == QUEST_STATUS_INCOMPLETE ) - CAST_PLR(Killer)->AreaExploredOrEventHappens(QUEST_590); + if (m_creature->getVictim() || m_creature->IsFriendlyTo(pAttacker)) + return; + + AttackStart(pAttacker); } - void UpdateAI(const uint32 diff) + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) { + if (uiDamage > m_creature->GetHealth() || ((m_creature->GetHealth() - uiDamage)*100 / m_creature->GetMaxHealth() < 15)) + { + uiDamage = 0; + + me->RestoreFaction(); + m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_ATTACKABLE_2); + m_creature->CombatStop(true); + + m_uiPhase = 1; + + if (pDoneBy->GetTypeId() == TYPEID_PLAYER) + m_uiPlayerGUID = pDoneBy->GetGUID(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiPhase) + { + if (m_uiPhaseTimer < uiDiff) + m_uiPhaseTimer = 7500; + else + { + m_uiPhaseTimer -= uiDiff; + return; + } + + switch(m_uiPhase) + { + case 1: + DoScriptText(SAY_COMPLETE, m_creature); + ++m_uiPhase; + break; + case 2: + if (Unit* pUnit = Unit::GetUnit(*m_creature, m_uiPlayerGUID)) + CAST_PLR(pUnit)->AreaExploredOrEventHappens(QUEST_590); + + m_creature->CastSpell(m_creature,SPELL_DRINK,true); + ++m_uiPhase; + break; + case 3: + EnterEvadeMode(); + break; + } + + return; + } + if (!UpdateVictim()) return; @@ -69,13 +132,13 @@ CreatureAI* GetAI_npc_calvin_montague(Creature *_Creature) return new npc_calvin_montagueAI (_Creature); } -bool QuestAccept_npc_calvin_montague(Player* player, Creature* creature, Quest const* quest) +bool QuestAccept_npc_calvin_montague(Player* pPlayer, Creature* pCreature, Quest const* quest) { if( quest->GetQuestId() == QUEST_590 ) { - creature->setFaction(FACTION_HOSTILE); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); - CAST_AI(npc_calvin_montagueAI, creature->AI())->AttackStart(player); + pCreature->setFaction(FACTION_HOSTILE); + pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + CAST_AI(npc_calvin_montagueAI, pCreature->AI())->AttackStart(pPlayer); } return true; } |