mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2025-11-29 17:38:24 +08:00
Revert "Prince rework and Nightbane code clean up"
This reverts commit 25a3b5fb0e.
This commit is contained in:
@@ -135,7 +135,6 @@ public:
|
||||
{
|
||||
me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,26 +295,20 @@ public:
|
||||
{
|
||||
DoCastVictim(SPELL_BELLOWING_ROAR);
|
||||
BellowingRoarTimer = urand(30000, 40000);
|
||||
}
|
||||
else
|
||||
BellowingRoarTimer -= diff;
|
||||
} else BellowingRoarTimer -= diff;
|
||||
|
||||
if (SmolderingBreathTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SMOLDERING_BREATH);
|
||||
SmolderingBreathTimer = 20000;
|
||||
}
|
||||
else
|
||||
SmolderingBreathTimer -= diff;
|
||||
} else SmolderingBreathTimer -= diff;
|
||||
|
||||
if (CharredEarthTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_CHARRED_EARTH);
|
||||
CharredEarthTimer = 20000;
|
||||
}
|
||||
else
|
||||
CharredEarthTimer -= diff;
|
||||
} else CharredEarthTimer -= diff;
|
||||
|
||||
if (TailSweepTimer <= diff)
|
||||
{
|
||||
@@ -323,18 +316,14 @@ public:
|
||||
if (!me->HasInArc(M_PI, target))
|
||||
DoCast(target, SPELL_TAIL_SWEEP);
|
||||
TailSweepTimer = 15000;
|
||||
}
|
||||
else
|
||||
TailSweepTimer -= diff;
|
||||
} else TailSweepTimer -= diff;
|
||||
|
||||
if (SearingCindersTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_SEARING_CINDERS);
|
||||
SearingCindersTimer = 10000;
|
||||
}
|
||||
else
|
||||
SearingCindersTimer -= diff;
|
||||
} else SearingCindersTimer -= diff;
|
||||
|
||||
uint32 Prozent = uint32(me->GetHealthPct());
|
||||
|
||||
@@ -369,18 +358,14 @@ public:
|
||||
DoCastVictim(SPELL_RAIN_OF_BONES);
|
||||
RainBones = true;
|
||||
SmokingBlastTimer = 20000;
|
||||
}
|
||||
else
|
||||
RainofBonesTimer -= diff;
|
||||
} else RainofBonesTimer -= diff;
|
||||
|
||||
if (DistractingAshTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_DISTRACTING_ASH);
|
||||
DistractingAshTimer = 2000; //timer wrong
|
||||
}
|
||||
else
|
||||
DistractingAshTimer -= diff;
|
||||
} else DistractingAshTimer -= diff;
|
||||
}
|
||||
|
||||
if (RainBones)
|
||||
@@ -389,9 +374,7 @@ public:
|
||||
{
|
||||
DoCastVictim(SPELL_SMOKING_BLAST);
|
||||
SmokingBlastTimer = 1500; //timer wrong
|
||||
}
|
||||
else
|
||||
SmokingBlastTimer -= diff;
|
||||
} else SmokingBlastTimer -= diff;
|
||||
}
|
||||
|
||||
if (FireballBarrageTimer <= diff)
|
||||
@@ -399,8 +382,7 @@ public:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0))
|
||||
DoCast(target, SPELL_FIREBALL_BARRAGE);
|
||||
FireballBarrageTimer = 20000;
|
||||
} else
|
||||
FireballBarrageTimer -= diff;
|
||||
} else FireballBarrageTimer -= diff;
|
||||
|
||||
if (FlyTimer <= diff) //landing
|
||||
{
|
||||
@@ -410,9 +392,7 @@ public:
|
||||
me->GetMotionMaster()->MovePoint(3, IntroWay[3][0], IntroWay[3][1], IntroWay[3][2]);
|
||||
|
||||
Flying = true;
|
||||
}
|
||||
else
|
||||
FlyTimer -= diff;
|
||||
} else FlyTimer -= diff;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -429,12 +409,8 @@ public:
|
||||
if (InstanceScript* pInstance = pGo->GetInstanceScript())
|
||||
{
|
||||
if (pInstance->GetData(DATA_NIGHTBANE) != DONE && !pGo->FindNearestCreature(NPC_NIGHTBANE, 40.0f))
|
||||
{
|
||||
if (Creature *cr = ObjectAccessor::GetCreature(*pPlayer, pInstance->GetData64(DATA_NIGHTBANE)))
|
||||
{
|
||||
cr->GetMotionMaster()->MovePoint(0, IntroWay[0][0], IntroWay[0][1], IntroWay[0][2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,55 +2,27 @@
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
* Rescripted By Lee (Talamortis)
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Prince_Malchezzar
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Karazhan
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "karazhan.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
|
||||
enum PrinceSay
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_AXE_TOSS1 = 1,
|
||||
SAY_AXE_TOSS2 = 2,
|
||||
SAY_SLAY = 6,
|
||||
SAY_SUMMON = 7,
|
||||
SAY_DEATH = 8,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ENFEEBLE = 30843, //Enfeeble during phase 1 and 2
|
||||
SPELL_ENFEEBLE_EFFECT = 41624,
|
||||
SPELL_SHADOWNOVA = 30852, //Shadownova used during all phases
|
||||
SPELL_SW_PAIN = 30854, //Shadow word pain during phase 1 and 3 (different targeting rules though)
|
||||
SPELL_THRASH_PASSIVE = 12787, //Extra attack chance during phase 2
|
||||
SPELL_SUNDER_ARMOR = 30901, //Sunder armor during phase 2
|
||||
SPELL_THRASH_AURA = 12787, //Passive proc chance for thrash
|
||||
SPELL_EQUIP_AXES = 30857, //Visual for axe equiping
|
||||
SPELL_AMPLIFY_DAMAGE = 39095, //Amplifiy during phase 3
|
||||
SPELL_CLEAVE = 30131, //Same as Nightbane.
|
||||
SPELL_HELLFIRE = 30859, //Infenals' hellfire aura
|
||||
};
|
||||
|
||||
enum creatures
|
||||
{
|
||||
NETHERSPITE_INFERNAL = 17646,
|
||||
MALCHEZARS_AXE = 17650,
|
||||
INFERNAL_MODEL_INVISIBLE = 11686,
|
||||
SPELL_INFERNAL_RELAY = 30834,
|
||||
EQUIP_ID_AXE = 33542
|
||||
};
|
||||
|
||||
// 18 Coordinates for Infernal spawns
|
||||
struct InfernalPoint
|
||||
{
|
||||
float x, y;
|
||||
};
|
||||
|
||||
#define INFERNAL_Z 275.5f
|
||||
#define INFERNAL_Z 275.5f
|
||||
|
||||
static InfernalPoint InfernalPoints[] =
|
||||
{
|
||||
@@ -74,6 +46,43 @@ static InfernalPoint InfernalPoints[] =
|
||||
{ -10935.7f, -1996.0f }
|
||||
};
|
||||
|
||||
//Enfeeble is supposed to reduce hp to 1 and then heal player back to full when it ends
|
||||
//Along with reducing healing and regen while enfeebled to 0%
|
||||
//This spell effect will only reduce healing
|
||||
enum PrinceMalchezaar
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_AXE_TOSS1 = 1,
|
||||
SAY_AXE_TOSS2 = 2,
|
||||
// SAY_SPECIAL1 = 3, Not used, needs to be implemented, but I don't know where it should be used.
|
||||
// SAY_SPECIAL2 = 4, Not used, needs to be implemented, but I don't know where it should be used.
|
||||
// SAY_SPECIAL3 = 5, Not used, needs to be implemented, but I don't know where it should be used.
|
||||
SAY_SLAY = 6,
|
||||
SAY_SUMMON = 7,
|
||||
SAY_DEATH = 8,
|
||||
|
||||
TOTAL_INFERNAL_POINTS = 18,
|
||||
|
||||
SPELL_ENFEEBLE = 30843, //Enfeeble during phase 1 and 2
|
||||
SPELL_ENFEEBLE_EFFECT = 41624,
|
||||
|
||||
SPELL_SHADOWNOVA = 30852, //Shadownova used during all phases
|
||||
SPELL_SW_PAIN = 30854, //Shadow word pain during phase 1 and 3 (different targeting rules though)
|
||||
SPELL_THRASH_PASSIVE = 12787, //Extra attack chance during phase 2
|
||||
SPELL_SUNDER_ARMOR = 30901, //Sunder armor during phase 2
|
||||
SPELL_THRASH_AURA = 12787, //Passive proc chance for thrash
|
||||
SPELL_EQUIP_AXES = 30857, //Visual for axe equiping
|
||||
SPELL_AMPLIFY_DAMAGE = 39095, //Amplifiy during phase 3
|
||||
SPELL_CLEAVE = 30131, //Same as Nightbane.
|
||||
SPELL_HELLFIRE = 30859, //Infenals' hellfire aura
|
||||
NETHERSPITE_INFERNAL = 17646, //The netherspite infernal creature
|
||||
MALCHEZARS_AXE = 17650, //Malchezar's axes (creatures), summoned during phase 3
|
||||
|
||||
INFERNAL_MODEL_INVISIBLE = 11686, //Infernal Effects
|
||||
SPELL_INFERNAL_RELAY = 30834,
|
||||
|
||||
EQUIP_ID_AXE = 33542 //Axes info
|
||||
};
|
||||
|
||||
//---------Infernal code first
|
||||
class netherspite_infernal : public CreatureScript
|
||||
@@ -110,18 +119,17 @@ public:
|
||||
DoCast(me, SPELL_HELLFIRE);
|
||||
HellfireTimer = 0;
|
||||
}
|
||||
else
|
||||
HellfireTimer -= diff;
|
||||
else HellfireTimer -= diff;
|
||||
}
|
||||
|
||||
if (CleanupTimer)
|
||||
{
|
||||
if (CleanupTimer <= diff)
|
||||
{
|
||||
Cleanup();
|
||||
CleanupTimer = 0;
|
||||
}
|
||||
else
|
||||
CleanupTimer -= diff;
|
||||
else CleanupTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,16 +156,17 @@ public:
|
||||
if (!done_by || done_by->GetGUID() != malchezaar)
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void Cleanup();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class boss_malchezaar : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_malchezaar() : CreatureScript("boss_malchezaar") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_malchezaarAI>(creature);
|
||||
}
|
||||
@@ -167,9 +176,9 @@ public:
|
||||
boss_malchezaarAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
memset(axes, 0, sizeof(axes));
|
||||
}
|
||||
|
||||
|
||||
InstanceScript* instance;
|
||||
uint32 EnfeebleTimer;
|
||||
uint32 EnfeebleResetTimer;
|
||||
@@ -179,60 +188,105 @@ public:
|
||||
uint32 AmplifyDamageTimer;
|
||||
uint32 Cleave_Timer;
|
||||
uint32 InfernalTimer;
|
||||
uint32 AxesTargetSwitchTimer;
|
||||
uint32 InfernalCleanupTimer;
|
||||
uint32 phase;
|
||||
uint32 enfeeble_health[5];
|
||||
uint64 enfeeble_targets[5];
|
||||
|
||||
std::vector<uint64> infernals;
|
||||
std::vector<InfernalPoint*> positions;
|
||||
|
||||
void Initialize()
|
||||
uint64 axes[2];
|
||||
uint64 enfeeble_targets[5];
|
||||
uint32 enfeeble_health[5];
|
||||
|
||||
uint32 phase;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
AxesCleanup();
|
||||
ClearWeapons();
|
||||
InfernalCleanup();
|
||||
positions.clear();
|
||||
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
{
|
||||
enfeeble_targets[i] = 0;
|
||||
enfeeble_health[i] = 0;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < TOTAL_INFERNAL_POINTS; ++i)
|
||||
positions.push_back(&InfernalPoints[i]);
|
||||
|
||||
EnfeebleTimer = 30000;
|
||||
EnfeebleResetTimer = 38000;
|
||||
ShadowNovaTimer = 35500;
|
||||
SWPainTimer = 20000;
|
||||
Cleave_Timer = 8000;
|
||||
InfernalCleanupTimer = 47000;
|
||||
AmplifyDamageTimer = 5000;
|
||||
SunderArmorTimer = urand(5000, 10000);
|
||||
Cleave_Timer = 8000;
|
||||
InfernalTimer = 40000;
|
||||
InfernalCleanupTimer = 47000;
|
||||
AxesTargetSwitchTimer = urand(7500, 20000);
|
||||
SunderArmorTimer = urand(5000, 10000);
|
||||
phase = 1;
|
||||
clearweapons();
|
||||
positions.clear();
|
||||
|
||||
instance->HandleGameObject(instance->GetData64(DATA_GO_NETHER_DOOR), true);
|
||||
}
|
||||
|
||||
void clearweapons()
|
||||
{
|
||||
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
me->SetCanDualWield(false);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
AxesCleanup();
|
||||
ClearWeapons();
|
||||
InfernalCleanup();
|
||||
positions.clear();
|
||||
|
||||
for (uint8 i = 0; i < TOTAL_INFERNAL_POINTS; ++i)
|
||||
positions.push_back(&InfernalPoints[i]);
|
||||
|
||||
instance->HandleGameObject(instance->GetData64(DATA_GO_NETHER_DOOR), true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
instance->HandleGameObject(instance->GetData64(DATA_GO_NETHER_DOOR), false); // Open the door leading further in
|
||||
}
|
||||
|
||||
void SummonAxes()
|
||||
void InfernalCleanup()
|
||||
{
|
||||
Creature* axe = me->SummonCreature(MALCHEZARS_AXE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
|
||||
//Infernal Cleanup
|
||||
for (std::vector<uint64>::const_iterator itr = infernals.begin(); itr != infernals.end(); ++itr)
|
||||
if (Unit* pInfernal = ObjectAccessor::GetUnit(*me, *itr))
|
||||
if (pInfernal->IsAlive())
|
||||
{
|
||||
pInfernal->SetVisible(false);
|
||||
pInfernal->setDeathState(JUST_DIED);
|
||||
}
|
||||
|
||||
infernals.clear();
|
||||
}
|
||||
|
||||
void AxesCleanup()
|
||||
{
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
{
|
||||
Unit* axe = ObjectAccessor::GetUnit(*me, axes[i]);
|
||||
if (axe && axe->IsAlive())
|
||||
Unit::Kill(axe, axe);
|
||||
axes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearWeapons()
|
||||
{
|
||||
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
me->SetCanDualWield(false);
|
||||
}
|
||||
|
||||
void EnfeebleHealthEffect()
|
||||
@@ -283,78 +337,176 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SummonInfernal()
|
||||
void SummonInfernal(const uint32 /*diff*/)
|
||||
{
|
||||
InfernalPoint *point = 0;
|
||||
Position pos;
|
||||
InfernalPoint *point = NULL;
|
||||
Position pos;
|
||||
|
||||
if ((me->GetMapId() != 532) || positions.empty())
|
||||
me->GetRandomNearPosition(pos, 60);
|
||||
else
|
||||
{
|
||||
point = Trinity::Containers::SelectRandomContainerElement(positions);
|
||||
pos.Relocate(point->x, point->y, INFERNAL_Z, frand(0.0f, float(M_PI * 2)));
|
||||
}
|
||||
|
||||
if ((me->GetMapId() != 532) || positions.empty())
|
||||
me->GetRandomNearPosition(pos, 40);
|
||||
else
|
||||
{
|
||||
point = Trinity::Containers::SelectRandomContainerElement(positions);
|
||||
pos.Relocate(point->x, point->y, INFERNAL_Z, frand(0.0f, float(M_PI * 2)));
|
||||
}
|
||||
Creature* infernal = me->SummonCreature(NETHERSPITE_INFERNAL, pos, TEMPSUMMON_TIMED_DESPAWN, 180000);
|
||||
|
||||
if (Creature* RELAY = me->FindNearestCreature(NPC_RELAY, 100.0f))
|
||||
{
|
||||
Creature* infernal = RELAY->SummonCreature(NETHERSPITE_INFERNAL, pos, TEMPSUMMON_TIMED_DESPAWN, 180000);
|
||||
if (infernal)
|
||||
{
|
||||
|
||||
infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE);
|
||||
infernal->setFaction(me->getFaction());
|
||||
if (point)
|
||||
CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->point = point;
|
||||
CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->malchezaar = me->GetGUID();
|
||||
|
||||
if (infernal)
|
||||
{
|
||||
infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE);
|
||||
infernal->setFaction(me->getFaction());
|
||||
if (point)
|
||||
CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->point = point;
|
||||
CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->malchezaar = me->GetGUID();
|
||||
infernals.push_back(infernal->GetGUID());
|
||||
//Creature* PRINCE = me->FindNearestCreature(NPC_PRINCE, 100.0f);
|
||||
RELAY->AI()->DoCast(infernal ,SPELL_INFERNAL_RELAY);
|
||||
}
|
||||
}
|
||||
Talk(SAY_SUMMON);
|
||||
infernals.push_back(infernal->GetGUID());
|
||||
DoCast(infernal, SPELL_INFERNAL_RELAY);
|
||||
}
|
||||
|
||||
Talk(SAY_SUMMON);
|
||||
}
|
||||
|
||||
void Phase2()
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
phase = 2;
|
||||
DoCast(me, SPELL_EQUIP_AXES);
|
||||
Talk(SAY_AXE_TOSS1);
|
||||
DoCast(me, SPELL_THRASH_AURA, true);
|
||||
SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE, EQUIP_NO_CHANGE);
|
||||
me->SetCanDualWield(true);
|
||||
me->SetAttackTime(OFF_ATTACK, (me->GetAttackTime(BASE_ATTACK) * 150) / 100);
|
||||
}
|
||||
|
||||
void Phase3()
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_THRASH_AURA);
|
||||
Talk(SAY_AXE_TOSS2);
|
||||
phase = 3;
|
||||
clearweapons();
|
||||
SummonAxes();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (EnfeebleResetTimer && EnfeebleResetTimer <= diff) // Let's not forget to reset that
|
||||
{
|
||||
EnfeebleResetHealth();
|
||||
EnfeebleResetTimer = 0;
|
||||
}
|
||||
else EnfeebleResetTimer -= diff;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_STUNNED)) // While shifting to phase 2 malchezaar stuns himself
|
||||
return;
|
||||
|
||||
if (me->GetUInt64Value(UNIT_FIELD_TARGET) != me->GetVictim()->GetGUID())
|
||||
me->SetTarget(me->GetVictim()->GetGUID());
|
||||
|
||||
if (phase == 1)
|
||||
{
|
||||
if (HealthBelowPct(60))
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
phase = 2;
|
||||
|
||||
//animation
|
||||
DoCast(me, SPELL_EQUIP_AXES);
|
||||
|
||||
//text
|
||||
Talk(SAY_AXE_TOSS1);
|
||||
|
||||
//passive thrash aura
|
||||
DoCast(me, SPELL_THRASH_AURA, true);
|
||||
|
||||
//models
|
||||
SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE, EQUIP_NO_CHANGE);
|
||||
|
||||
me->SetAttackTime(OFF_ATTACK, (me->GetAttackTime(BASE_ATTACK) * 150) / 100);
|
||||
me->SetCanDualWield(true);
|
||||
}
|
||||
}
|
||||
else if (phase == 2)
|
||||
{
|
||||
if (HealthBelowPct(30))
|
||||
{
|
||||
InfernalTimer = 15000;
|
||||
|
||||
phase = 3;
|
||||
|
||||
ClearWeapons();
|
||||
|
||||
//remove thrash
|
||||
me->RemoveAurasDueToSpell(SPELL_THRASH_AURA);
|
||||
|
||||
Talk(SAY_AXE_TOSS2);
|
||||
|
||||
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
{
|
||||
Creature* axe = me->SummonCreature(MALCHEZARS_AXE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
|
||||
if (axe)
|
||||
{
|
||||
axe->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
axe->setFaction(me->getFaction());
|
||||
axe->GetGUID();
|
||||
if (target)
|
||||
{
|
||||
axe->AI()->AttackStart(target);
|
||||
//axe->getThreatManager().tauntApply(target); //Taunt Apply and fade out does not work properly
|
||||
// So we'll use a hack to add a lot of threat to our target
|
||||
axe->AddThreat(target, 10000000.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ShadowNovaTimer > 35000)
|
||||
ShadowNovaTimer = EnfeebleTimer + 5000;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (SunderArmorTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SUNDER_ARMOR);
|
||||
SunderArmorTimer = urand(10000, 18000);
|
||||
}
|
||||
else SunderArmorTimer -= diff;
|
||||
|
||||
if (Cleave_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
Cleave_Timer = urand(6000, 12000);
|
||||
}
|
||||
else Cleave_Timer -= diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AxesTargetSwitchTimer <= diff)
|
||||
{
|
||||
AxesTargetSwitchTimer = urand(7500, 20000);
|
||||
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
{
|
||||
if (Unit* axe = ObjectAccessor::GetUnit(*me, axes[0]))
|
||||
{
|
||||
if (axe->GetVictim())
|
||||
DoModifyThreatPercent(axe->GetVictim(), -100);
|
||||
if (target)
|
||||
axe->AddThreat(target, 1000000.0f);
|
||||
//axe->getThreatManager().tauntFadeOut(axe->GetVictim());
|
||||
//axe->getThreatManager().tauntApply(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
else AxesTargetSwitchTimer -= diff;
|
||||
|
||||
if (AmplifyDamageTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_AMPLIFY_DAMAGE);
|
||||
AmplifyDamageTimer = urand(20000, 30000);
|
||||
}
|
||||
else AmplifyDamageTimer -= diff;
|
||||
}
|
||||
|
||||
//Time for global and double timers
|
||||
if (InfernalTimer <= diff)
|
||||
{
|
||||
SummonInfernal();
|
||||
SummonInfernal(diff);
|
||||
InfernalTimer = phase == 3 ? 14500 : 44500; // 15 secs in phase 3, 45 otherwise
|
||||
}
|
||||
else InfernalTimer -= diff;
|
||||
|
||||
if (Cleave_Timer <= diff)
|
||||
if (ShadowNovaTimer <= diff)
|
||||
{
|
||||
DoCast(SPELL_CLEAVE);
|
||||
Cleave_Timer = 8000;
|
||||
DoCastVictim(SPELL_SHADOWNOVA);
|
||||
ShadowNovaTimer = phase == 3 ? 31000 : uint32(-1);
|
||||
}
|
||||
else
|
||||
Cleave_Timer -= diff;
|
||||
else ShadowNovaTimer -= diff;
|
||||
|
||||
if (phase != 2)
|
||||
{
|
||||
@@ -362,7 +514,7 @@ public:
|
||||
{
|
||||
Unit* target = NULL;
|
||||
if (phase == 1)
|
||||
target = me->GetVictim(); // Target the Tank
|
||||
target = me->GetVictim(); // the tank
|
||||
else // anyone but the tank
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
|
||||
|
||||
@@ -371,41 +523,7 @@ public:
|
||||
|
||||
SWPainTimer = 20000;
|
||||
}
|
||||
else
|
||||
SWPainTimer -= diff;
|
||||
}
|
||||
|
||||
if (ShadowNovaTimer <= diff)
|
||||
{
|
||||
DoCast(SPELL_SHADOWNOVA);
|
||||
ShadowNovaTimer = 35500;
|
||||
}
|
||||
else
|
||||
ShadowNovaTimer -= diff;
|
||||
|
||||
if (phase == 1)
|
||||
{
|
||||
if (HealthBelowPct(60))
|
||||
{
|
||||
Phase2();
|
||||
}
|
||||
}
|
||||
if (phase == 2)
|
||||
{
|
||||
if (HealthBelowPct(30))
|
||||
{
|
||||
Phase3();
|
||||
|
||||
if (AmplifyDamageTimer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
|
||||
DoCast(target, SPELL_AMPLIFY_DAMAGE);
|
||||
AmplifyDamageTimer = urand(20000, 30000);
|
||||
}
|
||||
else
|
||||
AmplifyDamageTimer -= diff;
|
||||
}
|
||||
else SWPainTimer -= diff;
|
||||
}
|
||||
|
||||
if (phase != 3)
|
||||
@@ -420,84 +538,56 @@ public:
|
||||
else EnfeebleTimer -= diff;
|
||||
}
|
||||
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
class prince_axes : public CreatureScript
|
||||
{
|
||||
public:
|
||||
prince_axes() : CreatureScript("prince_axes") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<prince_axesAI>(creature);
|
||||
}
|
||||
|
||||
struct prince_axesAI : public ScriptedAI
|
||||
{
|
||||
|
||||
prince_axesAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 AxesTargetSwitchTimer;
|
||||
InstanceScript* instance;
|
||||
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
AxesTargetSwitchTimer = 7500;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetCanDualWield(true);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void changetarget()
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
{
|
||||
if (me->GetVictim())
|
||||
DoModifyThreatPercent(me->GetVictim(), -100);
|
||||
if (target)
|
||||
me->AddThreat(target, 1000000.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (AxesTargetSwitchTimer <= diff)
|
||||
{
|
||||
AxesTargetSwitchTimer = urand(7500, 20000);
|
||||
changetarget();
|
||||
}
|
||||
if (phase == 2)
|
||||
DoMeleeAttacksIfReady();
|
||||
else
|
||||
AxesTargetSwitchTimer -= diff;
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
void DoMeleeAttacksIfReady()
|
||||
{
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()) && !me->IsNonMeleeSpellCast(false))
|
||||
{
|
||||
//Check for base attack
|
||||
if (me->isAttackReady() && me->GetVictim())
|
||||
{
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
//Check for offhand attack
|
||||
if (me->isAttackReady(OFF_ATTACK) && me->GetVictim())
|
||||
{
|
||||
me->AttackerStateUpdate(me->GetVictim(), OFF_ATTACK);
|
||||
me->resetAttackTimer(OFF_ATTACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cleanup(Creature* infernal, InfernalPoint *point)
|
||||
{
|
||||
for (std::vector<uint64>::iterator itr = infernals.begin(); itr != infernals.end(); ++itr)
|
||||
if (*itr == infernal->GetGUID())
|
||||
{
|
||||
infernals.erase(itr);
|
||||
break;
|
||||
}
|
||||
|
||||
positions.push_back(point);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void netherspite_infernal::netherspite_infernalAI::Cleanup()
|
||||
{
|
||||
Creature* pMalchezaar = ObjectAccessor::GetCreature(*me, malchezaar);
|
||||
|
||||
if (pMalchezaar && pMalchezaar->IsAlive())
|
||||
CAST_AI(boss_malchezaar::boss_malchezaarAI, pMalchezaar->AI())->Cleanup(me, point);
|
||||
|
||||
}
|
||||
|
||||
void AddSC_boss_malchezaar()
|
||||
{
|
||||
new boss_malchezaar();
|
||||
new prince_axes();
|
||||
new netherspite_infernal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,8 +193,7 @@ public:
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
AggroTimer = 0;
|
||||
} else
|
||||
AggroTimer -= diff;
|
||||
} else AggroTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
@@ -204,22 +203,19 @@ public:
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_WATERBOLT);
|
||||
WaterBoltTimer = TitoDied ? 1500 : 5000;
|
||||
} else
|
||||
WaterBoltTimer -= diff;
|
||||
} else WaterBoltTimer -= diff;
|
||||
|
||||
if (FearTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SCREAM);
|
||||
FearTimer = 30000;
|
||||
} else
|
||||
FearTimer -= diff;
|
||||
} else FearTimer -= diff;
|
||||
|
||||
if (!SummonedTito)
|
||||
{
|
||||
if (SummonTitoTimer <= diff)
|
||||
SummonTito();
|
||||
else
|
||||
SummonTitoTimer -= diff;
|
||||
else SummonTitoTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
@@ -277,8 +273,7 @@ public:
|
||||
{
|
||||
DoCastVictim(SPELL_YIPPING);
|
||||
YipTimer = 10000;
|
||||
} else
|
||||
YipTimer -= diff;
|
||||
} else YipTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
@@ -388,8 +383,7 @@ public:
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
AggroTimer = 0;
|
||||
} else
|
||||
AggroTimer -= diff;
|
||||
} else AggroTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
@@ -399,16 +393,14 @@ public:
|
||||
{
|
||||
DoCastVictim(SPELL_BRAIN_BASH);
|
||||
BrainBashTimer = 15000;
|
||||
} else
|
||||
BrainBashTimer -= diff;
|
||||
} else BrainBashTimer -= diff;
|
||||
|
||||
if (BrainWipeTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_BRAIN_WIPE);
|
||||
BrainWipeTimer = 20000;
|
||||
} else
|
||||
BrainWipeTimer -= diff;
|
||||
} else BrainWipeTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
@@ -497,8 +489,7 @@ public:
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
AggroTimer = 0;
|
||||
} else
|
||||
AggroTimer -= diff;
|
||||
} else AggroTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
@@ -508,8 +499,7 @@ public:
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
CleaveTimer = 5000;
|
||||
} else
|
||||
CleaveTimer -= diff;
|
||||
} else CleaveTimer -= diff;
|
||||
|
||||
if (RustCount < 8)
|
||||
{
|
||||
@@ -519,8 +509,7 @@ public:
|
||||
Talk(EMOTE_RUST);
|
||||
DoCast(me, SPELL_RUST);
|
||||
RustTimer = 6000;
|
||||
} else
|
||||
RustTimer -= diff;
|
||||
} else RustTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
@@ -608,8 +597,7 @@ public:
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
AggroTimer = 0;
|
||||
} else
|
||||
AggroTimer -= diff;
|
||||
} else AggroTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
@@ -619,22 +607,19 @@ public:
|
||||
{
|
||||
DoCastVictim(SPELL_MANGLE);
|
||||
MangleTimer = urand(5000, 8000);
|
||||
} else
|
||||
MangleTimer -= diff;
|
||||
} else MangleTimer -= diff;
|
||||
|
||||
if (ShredTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SHRED);
|
||||
ShredTimer = urand(10000, 15000);
|
||||
} else
|
||||
ShredTimer -= diff;
|
||||
} else ShredTimer -= diff;
|
||||
|
||||
if (ScreamTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FRIGHTENED_SCREAM);
|
||||
ScreamTimer = urand(20000, 30000);
|
||||
} else
|
||||
ScreamTimer -= diff;
|
||||
} else ScreamTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
@@ -710,15 +695,13 @@ public:
|
||||
if (Creature* Cyclone = DoSpawnCreature(CREATURE_CYCLONE, float(urand(0, 9)), float(urand(0, 9)), 0, 0, TEMPSUMMON_TIMED_DESPAWN, 15000))
|
||||
Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_VISUAL, true);
|
||||
CycloneTimer = 22000;
|
||||
} else
|
||||
CycloneTimer -= diff;
|
||||
} else CycloneTimer -= diff;
|
||||
|
||||
if (ChainLightningTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CHAIN_LIGHTNING);
|
||||
ChainLightningTimer = 8000;
|
||||
} else
|
||||
ChainLightningTimer -= diff;
|
||||
} else ChainLightningTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
@@ -47,10 +47,6 @@ public:
|
||||
break;
|
||||
case NPC_NIGHTBANE:
|
||||
m_uiNightBaneGUID = creature->GetGUID();
|
||||
case NPC_RELAY:
|
||||
m_uiInfernalRelay = creature->GetGUID();
|
||||
case NPC_INFERNAL_TARGET:
|
||||
m_uiInfernaltargetGUID = creature->GetGUID();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +215,7 @@ public:
|
||||
return OperaEvent;
|
||||
case DATA_OPERA_OZ_DEATHCOUNT:
|
||||
return OzDeathCount;
|
||||
|
||||
case DATA_KILREK:
|
||||
return m_uiKilrekGUID;
|
||||
case DATA_TERESTIAN:
|
||||
@@ -276,14 +273,12 @@ public:
|
||||
case DATA_MASTERS_TERRACE_DOOR_2: return MastersTerraceDoor[1];
|
||||
case DATA_IMAGE_OF_MEDIVH: return ImageGUID;
|
||||
case DATA_NIGHTBANE: return m_uiNightBaneGUID;
|
||||
case DATA_PRINCE_INFERNAL_RELAY: return m_uiInfernalRelay;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64 InfernalTargetsGuidList;
|
||||
uint32 OperaEvent;
|
||||
uint32 OzDeathCount;
|
||||
uint32 OptionalBossCount;
|
||||
@@ -307,9 +302,6 @@ public:
|
||||
uint64 MastersTerraceDoor[2];
|
||||
uint64 ImageGUID;
|
||||
uint64 DustCoveredChest;
|
||||
uint64 m_uiInfernalRelay; // Summoning Infernals From sky.
|
||||
uint64 m_uiInfernaltargetGUID;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -57,8 +57,7 @@ enum KZDataTypes
|
||||
DATA_MASTERS_TERRACE_DOOR_1 = 27,
|
||||
DATA_MASTERS_TERRACE_DOOR_2 = 28,
|
||||
DATA_GO_SIDE_ENTRANCE_DOOR = 29,
|
||||
DATA_PRINCE = 30,
|
||||
DATA_PRINCE_INFERNAL_RELAY = 31
|
||||
DATA_PRINCE = 30
|
||||
};
|
||||
|
||||
enum KZOperaEvents
|
||||
@@ -78,8 +77,6 @@ enum KZMiscCreatures
|
||||
NPC_ATTUMEN_THE_HUNTSMAN = 15550,
|
||||
NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED = 16152,
|
||||
NPC_NIGHTBANE = 17225,
|
||||
NPC_RELAY = 17645,
|
||||
NPC_PRINCE = 15690,
|
||||
|
||||
// Trash
|
||||
NPC_COLDMIST_WIDOW = 16171,
|
||||
@@ -90,8 +87,7 @@ enum KZMiscCreatures
|
||||
NPC_PHASE_HOUND = 16178,
|
||||
NPC_DREADBEAST = 16177,
|
||||
NPC_SHADOWBEAST = 16176,
|
||||
NPC_KILREK = 17229,
|
||||
NPC_INFERNAL_TARGET = 17644
|
||||
NPC_KILREK = 17229
|
||||
};
|
||||
|
||||
enum KZGameObjectIds
|
||||
|
||||
Reference in New Issue
Block a user