diff options
author | Kudlaty <none@none> | 2009-08-07 02:03:27 +0200 |
---|---|---|
committer | Kudlaty <none@none> | 2009-08-07 02:03:27 +0200 |
commit | 0aef1a9a486f4262540d10c331a5cb0115d3e11e (patch) | |
tree | 5beb32c4aab348fafb23073f803de006ac2ac9ca /src | |
parent | 6d6d7803708dade1f9068fb3c07c42ffa93ea6a4 (diff) |
Merge [SD2]
r1142 Fix: Kael'thas advisors gain double health in phase 3 and dropp them on reset
Fix: Void Reaver will now ignore pets and totems when casting arcane orb
r1143 Remove old workaround for summon kael(TK) weapons and use spells instead. Apply code style to parts of code.
r1144 Added lost sql from revision 1119 and 1121 - skip
r1145 Correcting details for npc related to quest 590
--HG--
branch : trunk
Diffstat (limited to 'src')
3 files changed, 542 insertions, 561 deletions
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; } |