mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 18:40:28 +00:00
fix(Scripts/ZulGurub): Mandokir's Threatening Gaze. (#12095)
* fix(Scripts/ZulGurub: Mandokir's Threatening Gaze. Boss can melee attack while casting. Boss charges after the debuff run out. Guillotine is casted on hit rather than on launch. Properly coded Threatening Gaze Charge (with dot/hot exceptions) Whirlwind is removed during charge. Fixes #11748 * Update * missing * Update * Update. * Update. * Update. * Update. * Update.
This commit is contained in:
@@ -80,7 +80,8 @@ enum Misc
|
||||
MODEL_OHGAN_MOUNT = 15271,
|
||||
PATH_MANDOKIR = 492861,
|
||||
POINT_MANDOKIR_END = 24,
|
||||
CHAINED_SPIRIT_COUNT = 20
|
||||
CHAINED_SPIRIT_COUNT = 20,
|
||||
ACTION_CHARGE = 1
|
||||
};
|
||||
|
||||
Position const PosSummonChainedSpirits[CHAINED_SPIRIT_COUNT] =
|
||||
@@ -169,6 +170,7 @@ public:
|
||||
me->Mount(MODEL_OHGAN_MOUNT);
|
||||
reviveGUID.Clear();
|
||||
_useExecute = false;
|
||||
_chargeTarget.first.Clear();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -226,9 +228,44 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SetGUID(ObjectGuid const guid, int32 /*type = 0 */) override
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
reviveGUID = guid;
|
||||
if (action == ACTION_START_REVIVE)
|
||||
{
|
||||
std::list<Creature*> creatures;
|
||||
GetCreatureListWithEntryInGrid(creatures, me, NPC_CHAINED_SPIRIT, 200.0f);
|
||||
if (creatures.empty())
|
||||
return;
|
||||
|
||||
for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
|
||||
{
|
||||
if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, (*itr)->GetGUID()))
|
||||
{
|
||||
chainedSpirit->AI()->SetGUID(reviveGUID);
|
||||
chainedSpirit->AI()->DoAction(ACTION_REVIVE);
|
||||
reviveGUID.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetGUID(ObjectGuid const guid, int32 type) override
|
||||
{
|
||||
if (type == ACTION_CHARGE)
|
||||
{
|
||||
if (_chargeTarget.first == guid && _chargeTarget.second > 0.f)
|
||||
{
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*me, _chargeTarget.first))
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_WHIRLWIND);
|
||||
DoCast(target, SPELL_WATCH_CHARGE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reviveGUID = guid;
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
@@ -244,6 +281,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateThreat(Unit* hatedUnit, float& threat, SpellInfo const* threatSpell) override
|
||||
{
|
||||
if (_chargeTarget.first == hatedUnit->GetGUID())
|
||||
{
|
||||
// Do not count DOTs/HOTs
|
||||
if (!threatSpell || !threatSpell->HasAttribute(SPELL_ATTR0_CU_NO_INITIAL_THREAT))
|
||||
{
|
||||
_chargeTarget.second += threat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/) override
|
||||
{
|
||||
if (doneTo && doneTo == me->GetVictim())
|
||||
@@ -264,6 +313,43 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void DoMeleeAttackIfReady(bool ignoreCasting)
|
||||
{
|
||||
if (!ignoreCasting && me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = me->GetVictim();
|
||||
if (!victim || !victim->IsInWorld())
|
||||
return;
|
||||
|
||||
if (!me->IsWithinMeleeRange(victim))
|
||||
return;
|
||||
|
||||
//Make sure our attack is ready and we aren't currently casting before checking distance
|
||||
if (me->isAttackReady())
|
||||
{
|
||||
// xinef: prevent base and off attack in same time, delay attack at 0.2 sec
|
||||
if (me->haveOffhandWeapon())
|
||||
if (me->getAttackTimer(OFF_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
me->setAttackTimer(OFF_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
|
||||
me->AttackerStateUpdate(victim, BASE_ATTACK, false, ignoreCasting);
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
|
||||
if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK))
|
||||
{
|
||||
// xinef: delay main hand attack if both will hit at the same time (players code)
|
||||
if (me->getAttackTimer(BASE_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
me->setAttackTimer(BASE_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
|
||||
me->AttackerStateUpdate(victim, OFF_ATTACK, false, ignoreCasting);
|
||||
me->resetAttackTimer(OFF_ATTACK);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
@@ -299,7 +385,14 @@ public:
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_CHARGING))
|
||||
{
|
||||
if (me->GetCurrentSpellCastTime(SPELL_WATCH) >= 0)
|
||||
{
|
||||
DoMeleeAttackIfReady(true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
@@ -339,6 +432,7 @@ public:
|
||||
{
|
||||
DoCast(player, SPELL_WATCH);
|
||||
Talk(SAY_WATCH, player);
|
||||
_chargeTarget = std::make_pair(player->GetGUID(), 0.f);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 24000));
|
||||
break;
|
||||
@@ -393,13 +487,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
DoMeleeAttackIfReady(false);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 killCount;
|
||||
ObjectGuid reviveGUID;
|
||||
bool _useExecute;
|
||||
std::pair<ObjectGuid, float> _chargeTarget;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -614,13 +709,16 @@ public:
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
|
||||
{
|
||||
if (Unit* target = GetTarget())
|
||||
{
|
||||
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
|
||||
if (Creature* caster = GetCaster()->ToCreature())
|
||||
{
|
||||
caster->CastSpell(target, SPELL_WATCH_CHARGE, true);
|
||||
if (caster->IsAIEnabled)
|
||||
{
|
||||
caster->AI()->SetGUID(target->GetGUID(), ACTION_CHARGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -656,6 +754,29 @@ class spell_mandokir_charge : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_threatening_gaze_charge : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_threatening_gaze_charge)
|
||||
|
||||
void PreventLaunchHit(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
}
|
||||
|
||||
void LaunchHit(SpellEffIndex effIndex)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Unit* target = GetHitUnit())
|
||||
caster->CastSpell(target, GetSpellInfo()->Effects[effIndex].TriggerSpell, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectLaunchTarget += SpellEffectFn(spell_threatening_gaze_charge::PreventLaunchHit, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_threatening_gaze_charge::LaunchHit, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_mandokir()
|
||||
{
|
||||
new boss_mandokir();
|
||||
@@ -664,4 +785,5 @@ void AddSC_boss_mandokir()
|
||||
RegisterZulGurubCreatureAI(npc_vilebranch_speaker);
|
||||
new spell_threatening_gaze();
|
||||
RegisterSpellScript(spell_mandokir_charge);
|
||||
RegisterSpellScript(spell_threatening_gaze_charge);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user