diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index bd2cd95..65fac9c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -19436,6 +19436,17 @@ void Unit::SetControlled(bool apply, UnitState state) } } +void Unit::DisableRotate(bool apply) +{ + if (GetTypeId() != TYPEID_UNIT) + return; + + if (apply) + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + else if (!HasUnitState(UNIT_STATE_POSSESSED)) + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); +} + void Unit::SendLossOfControl(AuraApplication const* aurApp, Mechanics mechanic, SpellEffIndex index) { if (!ToPlayer()) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 69c4b02..3aaeafd 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2189,6 +2189,7 @@ class Unit : public WorldObject float GetPositionZMinusOffset() const; void SetControlled(bool apply, UnitState state); + void DisableRotate(bool apply); void SendLossOfControl(AuraApplication const* aurApp, Mechanics mechanic, SpellEffIndex index); void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); } diff --git a/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_malkorok.cpp b/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_malkorok.cpp index 8e16ebc..c6f0473 100644 --- a/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_malkorok.cpp +++ b/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_malkorok.cpp @@ -2,176 +2,645 @@ #include "ScriptedCreature.h" #include "siege_of_orgrimmar.h" +enum eSpells +{ + SPELL_ANCIENT_MIASMA = 142861, + SPELL_ARCING_SMASH = 142815, + SPELL_SEISMIC_SLAM = 142849, + SPELL_DISPLACED_ENERGY = 142913, + SPELL_EXPEL_MIASMA = 143199, + SPELL_BREATH_OF_YSHAARJ = 142842, + SPELL_ERADICATE = 143916, + SPELL_BLOOD_RAGE = 142879, + SPELL_IMPLODING_ENERGY = 142986, + SPELL_FATAL_STRIKE = 142990, + SPELL_RELENTLESS_ASSAULT = 143261, + SPELL_BREATH_DAMAGE = 142816, + SPELL_DISPLACED_ENERGY_D = 142928, + SPELL_BLOOD_RAGE_DAMAGE = 142890, + SPELL_ANCIENT_BARRIER_L = 142864, + SPELL_ANCIENT_BARRIER_M = 142865, + SPELL_ANCIENT_BARRIER_H = 142866, + SPELL_ANCIENT_MIASMA_VIS = 143018, + SPELL_ANCIENT_MIASMA_DMG = 142906, +}; + +enum eEvents +{ + EVENT_ARCING_SMASH_FIRST = 1, + EVENT_ARCING_SMASH_SECOND = 2, + EVENT_ARCING_SMASH_THIRD = 3, + EVENT_ARCING_SMASH_ROOT = 4, + EVENT_DESPAWN_ARCING_SMASH = 5, + EVENT_SEISMIC_SLAM = 6, + EVENT_DISPLACED_ENERGY = 7, + EVENT_ERADICATE = 8, + EVENT_BREATH_OF_YSHARRJ = 9, + EVENT_EXPEL_MIASMA = 10, + EVENT_AGRESSIVE = 11, + EVENT_BLOOD_RAGE = 12, + EVENT_PHASE_ONE = 13, + EVENT_IMPLODING_ENERGY = 14, + EVENT_PHASE_TWO = 15, +}; -enum Texts +enum Phases { - SAY_AGGRO = 0, - SAY_EARTHQUAKE = 1, - SAY_OVERRUN = 2, - SAY_SLAY = 3, - SAY_DEATH = 4 + PHASE_ONE = 1, + PHASE_TWO = 2, }; -enum Spells +enum eCreatures { - SPELL_EARTHQUAKE = 142826, - SPELL_SUNDER_ARMOR = 142842, - SPELL_CHAIN_LIGHTNING = 142851, - SPELL_OVERRUN = 142990, - SPELL_ENRAGE = 142879, - SPELL_MARK_DEATH = 143261, - SPELL_AURA_DEATH = 40736 + CREATURE_ARCING_SMASH = 71455, + CREATURE_ANCIENT_MIASMA = 71513, }; -enum Events +enum eTexts { - EVENT_ENRAGE = 1, - EVENT_ARMOR = 2, - EVENT_CHAIN = 3, - EVENT_QUAKE = 4, - EVENT_OVERRUN = 5 + MALKOROK_INTRO = 1, + MALKOROK_AGGRO = 2, + MALKOROK_ARCING_SMASH = 3, // 0, 1 or 2 in database + MALKOROK_BREATH_OF_YSHAARJ = 6, // 0 or 1 in database + MALKOROK_BLOOD_RAGE = 7, + MALKOROK_BERSERK = 9, + MALKOROK_WIPE = 10, + MALKOROK_DEATH = 11, }; +static void DespawnCreaturesInArea(uint32 entry, WorldObject* object) +{ + std::list creatures; + GetCreatureListWithEntryInGrid(creatures, object, entry, 300.0f); + if (creatures.empty()) + return; + + for (std::list::iterator iter = creatures.begin(); iter != creatures.end(); ++iter) + (*iter)->DespawnOrUnsummon(); +} + +// 71454 - Malkorok class boss_malkorok : public CreatureScript { -public: - boss_malkorok() : CreatureScript("boss_malkorok") { } + public: + boss_malkorok() : CreatureScript("boss_malkorok") { } - struct boss_malkorokAI : public ScriptedAI - { - boss_malkorokAI(Creature* creature) : ScriptedAI(creature) + struct boss_malkorokAI : public BossAI { - Initialize(); - } + boss_malkorokAI(Creature* creature) : BossAI(creature, DATA_MALKOROK) + { + pInstance = creature->GetInstanceScript(); + } + + InstanceScript* pInstance; + + uint8 arcingSmashController; + + void Reset() + { + _Reset(); + arcingSmashController = 0; + + me->SetReactState(REACT_AGGRESSIVE); + me->setFaction(16); + me->setPowerType(POWER_RAGE); + me->SetMaxPower(POWER_RAGE, 100); + + events.Reset(); + events.SetPhase(PHASE_ONE); + } + + void JustDied(Unit* /*killer*/) + { + Talk(MALKOROK_DEATH); + } + + void KilledUnit(Unit* u) + { + } + + + void EnterCombat(Unit* unit) + { + Talk(MALKOROK_AGGRO); + + float homeX = me->GetHomePosition().GetPositionX(); + float homeY = me->GetHomePosition().GetPositionY(); + float homeZ = me->GetHomePosition().GetPositionZ(); + me->SummonCreature(CREATURE_ANCIENT_MIASMA, homeX, homeY, homeZ, 5.0f, TEMPSUMMON_MANUAL_DESPAWN); + + events.SetPhase(PHASE_ONE); + events.ScheduleEvent(EVENT_ARCING_SMASH_FIRST, 15000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SEISMIC_SLAM, 16000, 0, PHASE_ONE); // 1 second after Arcing Smash + events.ScheduleEvent(EVENT_IMPLODING_ENERGY, 17000, 0, PHASE_ONE); // 2 seconds after Arcing Smash + events.ScheduleEvent(EVENT_PHASE_TWO, 120000, 0, PHASE_ONE); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + events.Update(diff); + + + switch (events.ExecuteEvent()) + { + case EVENT_PHASE_ONE: + { + DoCast(me, SPELL_RELENTLESS_ASSAULT); + float homeX = me->GetHomePosition().GetPositionX(); + float homeY = me->GetHomePosition().GetPositionY(); + float homeZ = me->GetHomePosition().GetPositionZ(); + me->SummonCreature(CREATURE_ANCIENT_MIASMA, homeX, homeY, homeZ, 5.0f, TEMPSUMMON_MANUAL_DESPAWN); + + events.SetPhase(PHASE_ONE); + events.ScheduleEvent(EVENT_SEISMIC_SLAM, urand(13000, 17000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_ARCING_SMASH_FIRST, 15000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_IMPLODING_ENERGY, urand(13000, 17000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_PHASE_TWO, 120000, 0, PHASE_ONE); + break; + } + + case EVENT_ARCING_SMASH_ROOT: + { + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + break; + } - void Initialize() + case EVENT_ARCING_SMASH_FIRST: + { + float homeX = me->GetHomePosition().GetPositionX(); + float homeY = me->GetHomePosition().GetPositionY(); + float homeZ = me->GetHomePosition().GetPositionZ(); + me->GetMotionMaster()->MoveJump(homeX, homeY, homeZ, 40.0f, 40.0f); + + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + { + if (Creature* summArcingSmash = me->SummonCreature(CREATURE_ARCING_SMASH, *target, TEMPSUMMON_MANUAL_DESPAWN)) + { + me->SetOrientation(me->GetAngle(summArcingSmash)); + me->SetControlled(true, UNIT_STATE_ROOT); + me->DisableRotate(true); + me->SetFacingTo(me->GetAngle(summArcingSmash)); + me->SendMovementFlagUpdate(); + Talk(MALKOROK_ARCING_SMASH); + DoCast(summArcingSmash, SPELL_ARCING_SMASH); + } + } + + events.ScheduleEvent(EVENT_ARCING_SMASH_ROOT, 0, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_ARCING_SMASH_SECOND, 15000, 0, PHASE_ONE); + break; + } + + case EVENT_ARCING_SMASH_SECOND: + { + float homeX = me->GetHomePosition().GetPositionX(); + float homeY = me->GetHomePosition().GetPositionY(); + float homeZ = me->GetHomePosition().GetPositionZ(); + me->GetMotionMaster()->MoveJump(homeX, homeY, homeZ, 40.0f, 40.0f); + + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + { + if (Creature* summArcingSmash = me->SummonCreature(CREATURE_ARCING_SMASH, *target, TEMPSUMMON_MANUAL_DESPAWN)) + { + me->SetOrientation(me->GetAngle(summArcingSmash)); + me->SetControlled(true, UNIT_STATE_ROOT); + me->DisableRotate(true); + me->SetFacingTo(me->GetAngle(summArcingSmash)); + me->SendMovementFlagUpdate(); + Talk(MALKOROK_ARCING_SMASH); + DoCast(summArcingSmash, SPELL_ARCING_SMASH); + } + } + + events.ScheduleEvent(EVENT_ARCING_SMASH_ROOT, 0, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_ARCING_SMASH_THIRD, 15000, 0, PHASE_ONE); + break; + } + + case EVENT_ARCING_SMASH_THIRD: + { + float homeX = me->GetHomePosition().GetPositionX(); + float homeY = me->GetHomePosition().GetPositionY(); + float homeZ = me->GetHomePosition().GetPositionZ(); + me->GetMotionMaster()->MoveJump(homeX, homeY, homeZ, 40.0f, 40.0f); + + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + { + if (Creature* summArcingSmash = me->SummonCreature(CREATURE_ARCING_SMASH, *target, TEMPSUMMON_MANUAL_DESPAWN)) + { + me->SetOrientation(me->GetAngle(summArcingSmash)); + me->SetControlled(true, UNIT_STATE_ROOT); + me->DisableRotate(true); + me->SetFacingTo(me->GetAngle(summArcingSmash)); + me->SendMovementFlagUpdate(); + Talk(MALKOROK_ARCING_SMASH); + DoCast(summArcingSmash, SPELL_ARCING_SMASH); + } + } + + events.ScheduleEvent(EVENT_ARCING_SMASH_ROOT, 0, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_BREATH_OF_YSHARRJ, 10000, 0, PHASE_ONE); + break; + } + + case EVENT_BREATH_OF_YSHARRJ: + { + DoCast(SPELL_BREATH_OF_YSHAARJ); + + events.ScheduleEvent(EVENT_ARCING_SMASH_FIRST, 15000, 0, PHASE_ONE); + break; + } + + case EVENT_SEISMIC_SLAM: + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + { + std::list pl_list; + target->GetPlayerListInGrid(pl_list, 5.0f); + for (auto itr : pl_list) + { + DoCast(itr, SPELL_SEISMIC_SLAM); + } + + DoCast(target, SPELL_SEISMIC_SLAM); + } + + events.ScheduleEvent(EVENT_SEISMIC_SLAM, 16000, 0, PHASE_ONE); + break; + } + + case EVENT_IMPLODING_ENERGY: + { + DoCast(SPELL_IMPLODING_ENERGY); + + events.ScheduleEvent(EVENT_IMPLODING_ENERGY, 17000, 0, PHASE_ONE); + break; + } + + case EVENT_PHASE_TWO: + { + events.Reset(); + events.SetPhase(PHASE_TWO); + DespawnCreaturesInArea(CREATURE_ANCIENT_MIASMA, me); + std::list pl_list; + me->GetPlayerListInGrid(pl_list, 100.0f); + for (auto itr : pl_list) + { + if (itr->HasAura(SPELL_ANCIENT_MIASMA_DMG)) + itr->RemoveAura(SPELL_ANCIENT_MIASMA_DMG); + + if (itr->HasAura(SPELL_ANCIENT_MIASMA)) + itr->RemoveAura(SPELL_ANCIENT_MIASMA); + } + + DoCast(SPELL_BLOOD_RAGE); + events.ScheduleEvent(EVENT_BLOOD_RAGE, 1000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_DISPLACED_ENERGY, 5000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_PHASE_ONE, 20000, 0, PHASE_TWO); + break; + } + + case EVENT_BLOOD_RAGE: + { + DoCast(SPELL_BLOOD_RAGE_DAMAGE); + + events.ScheduleEvent(EVENT_BLOOD_RAGE, 1000, 0, PHASE_TWO); + break; + } + + case EVENT_DISPLACED_ENERGY: + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + { + DoCast(target, SPELL_DISPLACED_ENERGY); + } + + events.ScheduleEvent(EVENT_DISPLACED_ENERGY, 5000, 0, PHASE_TWO); + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* pCreature) const { - _inEnrage = false; + return new boss_malkorokAI(pCreature); } +}; + +// 71513 - Ancient Miasma +class mob_ancient_miasma : public CreatureScript +{ + public: + mob_ancient_miasma() : CreatureScript("mob_ancient_miasma") { } - void Reset() override + struct mob_ancient_miasmaAI : public ScriptedAI { - _events.Reset(); - _events.ScheduleEvent(EVENT_ENRAGE, 0); - _events.ScheduleEvent(EVENT_ARMOR, urand(5000, 13000)); - _events.ScheduleEvent(EVENT_CHAIN, urand(10000, 30000)); - _events.ScheduleEvent(EVENT_QUAKE, urand(25000, 35000)); - _events.ScheduleEvent(EVENT_OVERRUN, urand(30000, 45000)); - Initialize(); + mob_ancient_miasmaAI(Creature* creature) : ScriptedAI(creature) + { + pInstance = creature->GetInstanceScript(); + } + + InstanceScript* pInstance; + EventMap events; + + void Reset() override + { + me->SetInCombatWithZone(); + DoCast(SPELL_ANCIENT_MIASMA_VIS); + std::list pl_list; + me->GetPlayerListInGrid(pl_list, 100.0f); + for (auto itr : pl_list) + { + if (!itr->HasAura(SPELL_ANCIENT_MIASMA_DMG)) + me->AddAura(SPELL_ANCIENT_MIASMA_DMG, itr); + + if (!itr->HasAura(SPELL_ANCIENT_MIASMA)) + me->AddAura(SPELL_ANCIENT_MIASMA, itr); + } + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE); + me->AddUnitMovementFlag(MOVEMENTFLAG_ROOT); + } + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new mob_ancient_miasmaAI(pCreature); } +}; - void KilledUnit(Unit* victim) override + +// 142913 - Displaced Energy +class spell_displaced_energy : public SpellScriptLoader +{ + public: + spell_displaced_energy() : SpellScriptLoader("spell_displaced_energy") { } + + class spell_displaced_energy_AuraScript : public AuraScript { + PrepareAuraScript(spell_displaced_energy_AuraScript); + void OnRemove(constAuraEffectPtr /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, SPELL_DISPLACED_ENERGY_D); + } - if (urand(0, 4)) - return; + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_displaced_energy_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; - Talk(SAY_SLAY); + AuraScript* GetAuraScript() const + { + return new spell_displaced_energy_AuraScript(); } +}; - void JustDied(Unit* killer) override +// 142890 - Blood Rage +class spell_blood_rage : public SpellScriptLoader +{ + public: + spell_blood_rage() : SpellScriptLoader("spell_blood_rage") { } + + class spell_blood_rage_SpellScript : public SpellScript { - if (killer) { if (killer->GetTypeId() == TYPEID_PLAYER) if (AchievementEntry const* achievementEntry = sAchievementStore.LookupEntry(8472)) killer->ToPlayer()->CompletedAchievement(achievementEntry); }Talk(SAY_DEATH); - } + PrepareSpellScript(spell_blood_rage_SpellScript); + + bool Load() + { + players = 1; + return true; + } + + void CountTargets(std::list& targets) + { + players = targets.size(); + } + + void SplitDamage(SpellEffIndex /*eff*/) + { + SetHitDamage(int32(GetHitDamage() / players)); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_rage_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_blood_rage_SpellScript::SplitDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + + private: + uint8 players; + }; - void EnterCombat(Unit* /*who*/) override + SpellScript* GetSpellScript() const { - Talk(SAY_AGGRO); + return new spell_blood_rage_SpellScript(); } +}; - void MoveInLineOfSight(Unit* who) override +// 142861 - Ancient Miasma +class spell_ancient_barrier : public SpellScriptLoader +{ + public: + spell_ancient_barrier() : SpellScriptLoader("spell_ancient_barrier") { } + class spell_ancient_barrier_AuraScript : public AuraScript { + PrepareAuraScript(spell_ancient_barrier_AuraScript); + void OnUpdate(uint32 diff) + { + if (Unit* caster = GetCaster()) + if (Unit* player = GetTarget()) + { + int32 absorb = player->GetHealingTakenInPastSecs(1); + int32 health = player->GetMaxHealth(); + if (!(player->HasAura(SPELL_ANCIENT_BARRIER_L)) && !(player->HasAura(SPELL_ANCIENT_BARRIER_M)) && !(player->HasAura(SPELL_ANCIENT_BARRIER_H))) + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_L, &absorb, NULL, NULL, true); - } + int32 remainingAbsorb; + int32 newAbsorb; + uint32 casterGuid = caster->GetGUID(); + + if (player->HasAura(SPELL_ANCIENT_BARRIER_L)) + { + remainingAbsorb = player->GetRemainingPeriodicAmount(casterGuid, SPELL_ANCIENT_BARRIER_L, SPELL_AURA_SCHOOL_ABSORB); + newAbsorb = remainingAbsorb+absorb; + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_M)) + { + remainingAbsorb = player->GetRemainingPeriodicAmount(casterGuid, SPELL_ANCIENT_BARRIER_M, SPELL_AURA_SCHOOL_ABSORB); + newAbsorb = remainingAbsorb + absorb; + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_H)) + { + remainingAbsorb = player->GetRemainingPeriodicAmount(casterGuid, SPELL_ANCIENT_BARRIER_H, SPELL_AURA_SCHOOL_ABSORB); + newAbsorb = remainingAbsorb + absorb; + } + + // If the remaining absorb + the new absorb is between 15% and 85% health cast visual for medium strenght shield + if (newAbsorb >= health * 15 / 100 && newAbsorb < health * 85 / 100) + { + if (player->HasAura(SPELL_ANCIENT_BARRIER_L)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_L); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_M, &newAbsorb, NULL, NULL, true); + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_M)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_M); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_M, &newAbsorb, NULL, NULL, true); + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_H)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_H); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_M, &newAbsorb, NULL, NULL, true); + } + } + + // If the remaining absorb + the new absorb is lower than 15% health cast visual for low strenght shield + if (newAbsorb < health * 15 / 100 && newAbsorb >= 0) + { + if (player->HasAura(SPELL_ANCIENT_BARRIER_L)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_L); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_L, &newAbsorb, NULL, NULL, true); + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_M)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_M); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_L, &newAbsorb, NULL, NULL, true); + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_H)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_H); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_L, &newAbsorb, NULL, NULL, true); + } + } + + // If the remaining absorb + the new absorb is lower or equal to max health and bigger than 85% health cast visual for high strenght shield + if (newAbsorb >= health * 85 / 100 && newAbsorb <= health) + { + if (player->HasAura(SPELL_ANCIENT_BARRIER_L)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_L); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_H, &newAbsorb, NULL, NULL, true); + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_M)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_M); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_H, &newAbsorb, NULL, NULL, true); + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_H)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_H); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_H, &newAbsorb, NULL, NULL, true); + } + } + // If the remaining absorb + the new absorb is bigger than max health set it to be equal to the max health + if (newAbsorb > health) + { + newAbsorb = health; + + if (player->HasAura(SPELL_ANCIENT_BARRIER_L)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_L); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_H, &newAbsorb, NULL, NULL, true); + } + + if (player->HasAura(SPELL_ANCIENT_BARRIER_M)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_M); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_H, &newAbsorb, NULL, NULL, true); + } - void UpdateAI(uint32 const diff) override + if (player->HasAura(SPELL_ANCIENT_BARRIER_H)) + { + player->RemoveAura(SPELL_ANCIENT_BARRIER_H); // prevents buggs + caster->CastCustomSpell(player, SPELL_ANCIENT_BARRIER_H, &newAbsorb, NULL, NULL, true); + } + } + } + } + + void Register() + { + OnAuraUpdate += AuraUpdateFn(spell_ancient_barrier_AuraScript::OnUpdate); + } + }; + + AuraScript* GetAuraScript() const { - if (!UpdateVictim()) - return; + return new spell_ancient_barrier_AuraScript(); + } +}; - _events.Update(diff); +// 142842 - Breath of Y'shaarj +class spell_breath_of_yshaarj : public SpellScriptLoader +{ + public: + spell_breath_of_yshaarj() : SpellScriptLoader("spell_breath_of_yshaarj") { } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + class spell_breath_of_yshaarj_SpellScript : public SpellScript + { + PrepareSpellScript(spell_breath_of_yshaarj_SpellScript); - while (uint32 eventId = _events.ExecuteEvent()) + void HandleAfterCast() { - switch (eventId) - { - case EVENT_ENRAGE: - if (!HealthAbovePct(30)) + if (InstanceScript* m_Instance = GetCaster()->GetInstanceScript()) + if (Creature * malkorok = m_Instance->instance->GetCreature(m_Instance->GetData64(DATA_MALKOROK))) { - DoCast(me, SPELL_ENRAGE); - _events.ScheduleEvent(EVENT_ENRAGE, 6000); - _inEnrage = true; + std::list npc_list; + malkorok->GetCreatureListWithEntryInGrid(npc_list, CREATURE_ARCING_SMASH, 100.0f); + for (auto itr : npc_list) + { + malkorok->CastSpell(itr, SPELL_BREATH_DAMAGE); + itr->DespawnOrUnsummon(0); + } } - break; - case EVENT_OVERRUN: - Talk(SAY_OVERRUN); - DoCastVictim(SPELL_OVERRUN); - _events.ScheduleEvent(EVENT_OVERRUN, urand(25000, 40000)); - break; - case EVENT_QUAKE: - if (urand(0, 1)) - return; - - Talk(SAY_EARTHQUAKE); - - //remove enrage before casting earthquake because enrage + earthquake = 16000dmg over 8sec and all dead - if (_inEnrage) - me->RemoveAurasDueToSpell(SPELL_ENRAGE); - - DoCastVictim(SPELL_EARTHQUAKE); - _events.ScheduleEvent(EVENT_QUAKE, urand(30000, 55000)); - break; - case EVENT_CHAIN: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) - DoCast(target, SPELL_CHAIN_LIGHTNING); - _events.ScheduleEvent(EVENT_CHAIN, urand(7000, 27000)); - break; - case EVENT_ARMOR: - Talk(irand(5, 12)); if (irand(0, 5) == 0) DoCastVictim(SPELL_MARK_DEATH); else if (irand(0, 5) == 1) DoCastVictim(SPELL_AURA_DEATH); else DoCastVictim(SPELL_SUNDER_ARMOR); - _events.ScheduleEvent(EVENT_ARMOR, urand(10000, 25000)); - break; - default: - break; - } } - DoMeleeAttackIfReady(); - } - private: - EventMap _events; - bool _inEnrage; - }; + void Register() + { + AfterCast += SpellCastFn(spell_breath_of_yshaarj_SpellScript::HandleAfterCast); + } + }; - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_malkorokAI(creature); - } + SpellScript* GetSpellScript() const + { + return new spell_breath_of_yshaarj_SpellScript(); + } }; void AddSC_malkorok() { - new boss_malkorok(); -}; + new boss_malkorok(); -/* -INSERT INTO creature_text VALUES -(71454, 0, 0, "Nazgrim has failed us. Kor'kron, destroy these intruders!", 14, 0, 100, 0, 0, 'MALKOROK_INTRO'), -(71454, 1, 0, "I will never fail the Warchief!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_AGGRO'), -(71454, 2, 0, "Weaklings!", 14, 0, 100, soundId, 'MALKOROK_ARCING_SMASH_1'), -(71454, 2, 1, "You dare challenge the Warchief?", 14, 0, 100, 0, 0, soundId, 'MALKOROK_ARCING_SMASH_2'), -(71454, 2, 2, "Garrosh gives me strength!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_ARCING_SMASH_3'), -(71454, 3, 0, "Witness the might of the True Horde!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_BREATH_OF_YSHAARJ_1'), -(71454, 3, 1, "The power of the Warchief will overwhelm you!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_BREATH_OF_YSHAARJ_2'), -(71454, 4, 0, "The True Horde cannot be STOPPED!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_BLOOD_RAGE_1'), -(71454, 4, 1, "Stand and FACE ME!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_BLOOD_RAGE_2'), -(71454, 5, 0, "The overwhelming power!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_BERSERK'), -(71454, 6, 0, "The Warchief demands it!", 14, 0, 100, 0, 0, soundId, 'MALKOROK_WIPE'), -(71454, 7, 0, "To die... for the warchief... is... an... honor...", 14, 0, 100, 0, 0, soundId, 'MALKOROK_DEATH'); -*/ \ No newline at end of file + new mob_ancient_miasma(); + + new spell_displaced_energy(); + new spell_blood_rage(); + new spell_ancient_barrier(); + new spell_breath_of_yshaarj(); +}; diff --git a/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_sha_of_pride.cpp b/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_sha_of_pride.cpp index e25d33d..b6fa9d3 100644 --- a/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_sha_of_pride.cpp +++ b/src/server/scripts/Pandaria/SiegeOfOrgrimmar/boss_sha_of_pride.cpp @@ -1,4 +1,3 @@ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "GridNotifiers.h" @@ -7,7 +6,6 @@ #include "siege_of_orgrimmar.h" /* -#include "siege_of_orgrimmar.h" #include "MoveSplineInit.h" /* General Information: (Icy-veins.com):