mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-23 05:36:23 +00:00
Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -12568,15 +12568,18 @@ bool Player::isHonorOrXPTarget(Unit* victim) const
|
||||
|
||||
// Victim level less gray level
|
||||
if (v_level <= k_grey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (victim->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if (victim->IsTotem() ||
|
||||
victim->IsPet() ||
|
||||
victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP)
|
||||
if (victim->IsTotem() || victim->IsCritter() || victim->IsPet() || (victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8318,6 +8318,12 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
|
||||
if (procEx & PROC_EX_CRITICAL_HIT)
|
||||
damage /= 2;
|
||||
|
||||
// do not proc off from itself
|
||||
if (procSpell->Id == 45297 || procSpell->Id == 45284)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
uint32 spell = 0;
|
||||
@@ -17997,8 +18003,10 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
|
||||
sScriptMgr->OnCreatureKilledByPet( killer->GetCharmerOrOwnerPlayerOrPlayerItself(), victim->ToCreature());
|
||||
}
|
||||
|
||||
if (killer != victim && !victim->IsCritter())
|
||||
if (killer != victim)
|
||||
{
|
||||
Unit::ProcDamageAndSpell(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
|
||||
}
|
||||
|
||||
// Proc auras on death - must be before aura/combat remove
|
||||
Unit::ProcDamageAndSpell(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
|
||||
|
||||
@@ -4501,6 +4501,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->AttributesEx |= SPELL_ATTR1_NO_REFLECTION;
|
||||
});
|
||||
|
||||
// Turn the Tables
|
||||
ApplySpellFix({ 51627, 51628, 51629 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
@@ -3347,13 +3347,19 @@ public:
|
||||
EventMap events;
|
||||
bool _didWebBeam;
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
me->SetDisableGravity(true);
|
||||
me->SetImmuneToAll(true);
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CUSTOM_SPELL_03);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(1, 3s, 10s); // Crypt Scarabs
|
||||
events.ScheduleEvent(2, 15s, 25s); // Dark Mending
|
||||
events.ScheduleEvent(3, 8s, 15s); // Web Wrap
|
||||
me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -3364,9 +3370,10 @@ public:
|
||||
float nx = me->GetPositionX();
|
||||
float ny = me->GetPositionY();
|
||||
float nz = me->GetFloorZ();
|
||||
DoCastSelf(SPELL_WEB_BEAM);
|
||||
me->SetHomePosition(nx, ny, nz, me->GetOrientation());
|
||||
me->CastSpell(me, SPELL_WEB_BEAM, false);
|
||||
me->GetMotionMaster()->MovePoint(1, nx, ny, nz, false);
|
||||
me->GetMotionMaster()->MoveLand(1, nx, ny, nz, false);
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3386,20 +3393,19 @@ public:
|
||||
if (me->IsLevitating())
|
||||
{
|
||||
me->SetDisableGravity(false);
|
||||
me->SetImmuneToAll(false);
|
||||
me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
void MovementInform(uint32 /*type*/, uint32 id) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == 1)
|
||||
if (id == 1)
|
||||
{
|
||||
if (me->IsLevitating())
|
||||
{
|
||||
me->SetDisableGravity(false);
|
||||
me->SetOrientation(0.0f);
|
||||
me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
me->ClearUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3516,7 +3522,7 @@ public:
|
||||
if (spider->GetPositionZ() > 220.0f)
|
||||
{
|
||||
spider->CastSpell(spider, SPELL_WEB_BEAM2, false);
|
||||
spider->GetMotionMaster()->MovePoint(POINT_ENTER_COMBAT, spider->GetPositionX(), spider->GetPositionY(), 213.03f, false);
|
||||
spider->GetMotionMaster()->MoveLand(POINT_ENTER_COMBAT, spider->GetPositionX(), spider->GetPositionY(), 213.03f, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
_Reset();
|
||||
_spoken = false;
|
||||
_manaShield = false;
|
||||
_comboHealthStages.fill(false);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -74,25 +75,13 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
_JustEngagedWith();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
scheduler.Schedule(35s, [this](TaskContext context)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
context.Repeat(35s, 40s);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
});
|
||||
}).Schedule(5s, [this](TaskContext context)
|
||||
scheduler.Schedule(5s, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_VOLLEY);
|
||||
context.Repeat(7s, 12s);
|
||||
}).Schedule(8s, [this](TaskContext context)
|
||||
{
|
||||
IsHeroic() ? DoCastRandomTarget(SPELL_POLYMORPH) : DoCastMaxThreat(SPELL_POLYMORPH);
|
||||
DoCastRandomTarget(SPELL_POLYMORPH);
|
||||
context.Repeat(15s, 17500ms);
|
||||
});
|
||||
|
||||
@@ -119,6 +108,60 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
if (!_comboHealthStages[0] && me->HealthBelowPctDamaged(80, damage))
|
||||
{
|
||||
_comboHealthStages[0] = true;
|
||||
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
if (!_comboHealthStages[1] && me->HealthBelowPctDamaged(50, damage))
|
||||
{
|
||||
_comboHealthStages[1] = true;
|
||||
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
if (!_comboHealthStages[2] && me->HealthBelowPctDamaged(25, damage))
|
||||
{
|
||||
_comboHealthStages[2] = true;
|
||||
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
if (!_manaShield && me->HealthBelowPctDamaged(20, damage))
|
||||
{
|
||||
DoCast(me, SPELL_MANA_SHIELD);
|
||||
@@ -132,9 +175,10 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _spoken;
|
||||
bool _manaShield;
|
||||
private:
|
||||
bool _spoken;
|
||||
bool _manaShield;
|
||||
std::array<bool, 3> _comboHealthStages;
|
||||
};
|
||||
|
||||
// 38194 - Blink
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
|
||||
enum HydromancerThespia
|
||||
{
|
||||
SAY_SUMMON = 0,
|
||||
SAY_SUMMON = 0, // Unused or Unknown Use
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEAD = 3,
|
||||
SAY_SPELL = 4,
|
||||
|
||||
SPELL_LIGHTNING_CLOUD = 25033,
|
||||
SPELL_LUNG_BURST = 31481,
|
||||
@@ -55,9 +56,9 @@ struct boss_hydromancer_thespia : public BossAI
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
_JustEngagedWith();
|
||||
events.ScheduleEvent(EVENT_SPELL_LIGHTNING, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_LUNG, 7000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENVELOPING, 9000);
|
||||
events.ScheduleEvent(EVENT_SPELL_LIGHTNING, 9800);
|
||||
events.ScheduleEvent(EVENT_SPELL_LUNG, 13300);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENVELOPING, 14500);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -69,21 +70,17 @@ struct boss_hydromancer_thespia : public BossAI
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_LIGHTNING:
|
||||
for (uint8 i = 0; i < DUNGEON_MODE(1, 2); ++i)
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_LIGHTNING_CLOUD, false);
|
||||
events.RepeatEvent(urand(15000, 25000));
|
||||
Talk(SAY_SPELL);
|
||||
DoCastRandomTarget(SPELL_LIGHTNING_CLOUD);
|
||||
events.RepeatEvent(urand(12100, 14500));
|
||||
break;
|
||||
case EVENT_SPELL_LUNG:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_LUNG_BURST);
|
||||
events.RepeatEvent(urand(7000, 12000));
|
||||
DoCastRandomTarget(SPELL_LUNG_BURST);
|
||||
events.RepeatEvent(urand(21800, 25400));
|
||||
break;
|
||||
case EVENT_SPELL_ENVELOPING:
|
||||
for (uint8 i = 0; i < DUNGEON_MODE(1, 2); ++i)
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_ENVELOPING_WINDS, false);
|
||||
events.RepeatEvent(urand(10000, 15000));
|
||||
DoCastRandomTarget(SPELL_ENVELOPING_WINDS);
|
||||
events.RepeatEvent(urand(30000, 40000));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "steam_vault.h"
|
||||
|
||||
enum MainChambersAccessPanelSays
|
||||
{
|
||||
SAY_FAINT_ECHO = 0,
|
||||
SAY_LOUD_RUMBLE = 1
|
||||
};
|
||||
|
||||
class go_main_chambers_access_panel : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
@@ -28,11 +34,16 @@ public:
|
||||
{
|
||||
if (InstanceScript* instance = go->GetInstanceScript())
|
||||
{
|
||||
Creature* doorController = instance->GetCreature(DATA_DOOR_CONTROLLER);
|
||||
if (go->GetEntry() == GO_ACCESS_PANEL_HYDRO)
|
||||
{
|
||||
if (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE)
|
||||
{
|
||||
go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
if (doorController && doorController->IsAIEnabled)
|
||||
{
|
||||
doorController->AI()->Talk(SAY_FAINT_ECHO);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -40,12 +51,31 @@ public:
|
||||
if (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE)
|
||||
{
|
||||
go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
if (doorController && doorController->IsAIEnabled)
|
||||
{
|
||||
doorController->AI()->Talk(SAY_FAINT_ECHO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE && instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE)
|
||||
{
|
||||
if (GameObject* mainGate = instance->GetGameObject(DATA_MAIN_CHAMBERS_DOOR))
|
||||
if (doorController)
|
||||
{
|
||||
if (doorController->IsAIEnabled)
|
||||
{
|
||||
doorController->AI()->Talk(SAY_LOUD_RUMBLE);
|
||||
}
|
||||
|
||||
doorController->m_Events.AddEventAtOffset([instance]()
|
||||
{
|
||||
if (GameObject* mainGate = instance->GetGameObject(DATA_MAIN_CHAMBERS_DOOR))
|
||||
{
|
||||
instance->HandleGameObject(ObjectGuid::Empty, true, mainGate);
|
||||
}
|
||||
}, 4s);
|
||||
}
|
||||
else if (GameObject* mainGate = instance->GetGameObject(DATA_MAIN_CHAMBERS_DOOR))
|
||||
{
|
||||
instance->HandleGameObject(ObjectGuid::Empty, true, mainGate);
|
||||
}
|
||||
@@ -60,7 +90,8 @@ public:
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_MEKGINEER_STEAMRIGGER, DATA_MEKGINEER_STEAMRIGGER }
|
||||
{ NPC_MEKGINEER_STEAMRIGGER, DATA_MEKGINEER_STEAMRIGGER },
|
||||
{ NPC_DOOR_CONTROLLER, DATA_DOOR_CONTROLLER }
|
||||
};
|
||||
|
||||
ObjectData const objectData[] =
|
||||
|
||||
@@ -36,7 +36,8 @@ enum steamVault
|
||||
|
||||
DATA_ACCESS_PANEL_HYDROMANCER = 4,
|
||||
DATA_ACCESS_PANEL_MEKGINEER = 5,
|
||||
DATA_MAIN_CHAMBERS_DOOR = 6
|
||||
DATA_MAIN_CHAMBERS_DOOR = 6,
|
||||
DATA_DOOR_CONTROLLER = 7
|
||||
};
|
||||
|
||||
enum steamVaultNPCGO
|
||||
@@ -47,6 +48,7 @@ enum steamVaultNPCGO
|
||||
|
||||
NPC_MEKGINEER_STEAMRIGGER = 17796,
|
||||
NPC_WARLORD_KALITHRESH = 17798,
|
||||
NPC_DOOR_CONTROLLER = 20926
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
|
||||
@@ -67,8 +67,7 @@ enum MillhouseEvents
|
||||
|
||||
EVENT_MILL_CHECK_HEALTH = 20,
|
||||
EVENT_MILL_PYROBLAST = 21,
|
||||
EVENT_MILL_BASE_SPELL = 22,
|
||||
EVENT_MILL_ICEBLOCK = 23
|
||||
EVENT_MILL_BASE_SPELL = 22
|
||||
};
|
||||
|
||||
class npc_millhouse_manastorm : public CreatureScript
|
||||
@@ -81,6 +80,7 @@ public:
|
||||
npc_millhouse_manastormAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
_usedIceblock = false;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
_usedIceblock = false;
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -124,7 +125,16 @@ public:
|
||||
events.ScheduleEvent(EVENT_MILL_CHECK_HEALTH, 1000);
|
||||
events.ScheduleEvent(EVENT_MILL_PYROBLAST, 30000);
|
||||
events.ScheduleEvent(EVENT_MILL_BASE_SPELL, 2000);
|
||||
events.ScheduleEvent(EVENT_MILL_ICEBLOCK, 1000);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(50, damage) && !_usedIceblock)
|
||||
{
|
||||
_usedIceblock = true;
|
||||
Talk(SAY_ICEBLOCK);
|
||||
DoCastSelf(SPELL_ICEBLOCK, true);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -208,15 +218,6 @@ public:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PYROBLAST, false);
|
||||
events.ScheduleEvent(EVENT_MILL_PYROBLAST, 30000);
|
||||
break;
|
||||
case EVENT_MILL_ICEBLOCK:
|
||||
if (me->GetDistance(me->GetVictim()) < 5.0f)
|
||||
{
|
||||
Talk(SAY_ICEBLOCK);
|
||||
me->CastSpell(me, SPELL_ICEBLOCK, true);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_MILL_ICEBLOCK, 1000);
|
||||
break;
|
||||
case EVENT_MILL_BASE_SPELL:
|
||||
switch (RAND(SPELL_FIREBALL, SPELL_ARCANE_MISSILES, SPELL_FROSTBOLT))
|
||||
{
|
||||
@@ -240,6 +241,9 @@ public:
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _usedIceblock;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
|
||||
@@ -44,23 +44,24 @@ enum Spells
|
||||
|
||||
struct boss_dalliah_the_doomsayer : public BossAI
|
||||
{
|
||||
boss_dalliah_the_doomsayer(Creature* creature) : BossAI(creature, DATA_DALLIAH), _percentHealthCheck(false) { }
|
||||
boss_dalliah_the_doomsayer(Creature* creature) : BossAI(creature, DATA_DALLIAH) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
_percentHealthCheck = false;
|
||||
me->SetImmuneToAll(false);
|
||||
|
||||
ScheduleHealthCheckEvent(25, [&]
|
||||
{
|
||||
if (Creature* soccothrates = instance->GetCreature(DATA_SOCCOTHRATES))
|
||||
{
|
||||
soccothrates->AI()->Talk(SAY_DALLIAH_25_PERCENT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
BossAI::InitializeAI();
|
||||
|
||||
if (instance->GetBossState(DATA_SOCCOTHRATES) != DONE)
|
||||
{
|
||||
me->SetImmuneToAll(true);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -117,19 +118,6 @@ struct boss_dalliah_the_doomsayer : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(25, damage) && !_percentHealthCheck)
|
||||
{
|
||||
if (Creature* soccothrates = instance->GetCreature(DATA_SOCCOTHRATES))
|
||||
{
|
||||
soccothrates->AI()->Talk(SAY_DALLIAH_25_PERCENT);
|
||||
}
|
||||
|
||||
_percentHealthCheck = true;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->IsPlayer())
|
||||
@@ -137,9 +125,6 @@ struct boss_dalliah_the_doomsayer : public BossAI
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _percentHealthCheck;
|
||||
};
|
||||
|
||||
void AddSC_boss_dalliah_the_doomsayer()
|
||||
|
||||
@@ -79,7 +79,6 @@ struct boss_wrath_scryer_soccothrates : public BossAI
|
||||
_Reset();
|
||||
events2.Reset();
|
||||
me->CastSpell(me, SPELL_FEL_IMMOLATION, true);
|
||||
me->SetImmuneToAll(false);
|
||||
|
||||
ScheduleHealthCheckEvent(25, [&]
|
||||
{
|
||||
@@ -96,8 +95,6 @@ struct boss_wrath_scryer_soccothrates : public BossAI
|
||||
void InitializeAI() override
|
||||
{
|
||||
BossAI::InitializeAI();
|
||||
if (!preFight)
|
||||
me->SetImmuneToAll(true);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -129,9 +126,10 @@ struct boss_wrath_scryer_soccothrates : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
scheduler.Schedule(11s, 12s, [this](TaskContext context)
|
||||
scheduler.Schedule(30s, 35s, [this](TaskContext context)
|
||||
{
|
||||
me->CastSpell(me, SPELL_KNOCK_AWAY, false);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
|
||||
Talk(SAY_KNOCK_AWAY);
|
||||
|
||||
scheduler.Schedule(4600ms, [this](TaskContext)
|
||||
@@ -141,10 +139,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI
|
||||
|
||||
scheduler.Schedule(300ms, [this](TaskContext context2)
|
||||
{
|
||||
if (me->GetVictim() && !me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
DoCastAOE(SPELL_FELFIRE, true);
|
||||
}
|
||||
DoCastAOE(SPELL_FELFIRE, true);
|
||||
|
||||
if (context2.GetRepeatCounter() <= 6)
|
||||
{
|
||||
@@ -153,7 +148,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI
|
||||
});
|
||||
});
|
||||
|
||||
context.Repeat();
|
||||
context.Repeat(20s, 35s);
|
||||
}).Schedule(12s, 14s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_FELFIRE_SHOCK);
|
||||
|
||||
@@ -1450,39 +1450,6 @@ public:
|
||||
{
|
||||
go_soulwellAI(GameObject* go) : GameObjectAI(go)
|
||||
{
|
||||
_stoneSpell = 0;
|
||||
_stoneId = 0;
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_SOUL_WELL_R1:
|
||||
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0;
|
||||
if (Unit* owner = go->GetOwner())
|
||||
{
|
||||
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
|
||||
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1;
|
||||
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
|
||||
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2;
|
||||
}
|
||||
break;
|
||||
case GO_SOUL_WELL_R2:
|
||||
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0;
|
||||
if (Unit* owner = go->GetOwner())
|
||||
{
|
||||
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
|
||||
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1;
|
||||
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
|
||||
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (_stoneSpell == 0) // Should never happen
|
||||
return;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_stoneSpell);
|
||||
if (!spellInfo)
|
||||
return;
|
||||
|
||||
_stoneId = spellInfo->Effects[EFFECT_0].ItemType;
|
||||
}
|
||||
|
||||
/// Due to the fact that this GameObject triggers CMSG_GAMEOBJECT_USE
|
||||
@@ -1495,40 +1462,93 @@ public:
|
||||
return false;
|
||||
|
||||
Unit* owner = me->GetOwner();
|
||||
if (_stoneSpell == 0 || _stoneId == 0)
|
||||
if (!owner)
|
||||
return true;
|
||||
|
||||
uint32 stoneId = 0;
|
||||
uint32 stoneSpell = 0;
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case GO_SOUL_WELL_R1:
|
||||
stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0;
|
||||
if (Unit* owner = me->GetOwner())
|
||||
{
|
||||
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
|
||||
{
|
||||
stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1;
|
||||
}
|
||||
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
|
||||
{
|
||||
stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GO_SOUL_WELL_R2:
|
||||
stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0;
|
||||
if (Unit* owner = me->GetOwner())
|
||||
{
|
||||
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
|
||||
{
|
||||
stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1;
|
||||
}
|
||||
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
|
||||
{
|
||||
stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!stoneSpell)
|
||||
{
|
||||
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
|
||||
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_ERROR);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer()))
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(stoneSpell);
|
||||
if (!spellInfo)
|
||||
{
|
||||
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
|
||||
return true;
|
||||
}
|
||||
|
||||
stoneId = spellInfo->Effects[EFFECT_0].ItemType;
|
||||
if (!stoneId)
|
||||
{
|
||||
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(stoneSpell))
|
||||
{
|
||||
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_ERROR);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer()))
|
||||
{
|
||||
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(stoneSpell))
|
||||
{
|
||||
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TARGET_NOT_IN_RAID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't try to add a stone if we already have one.
|
||||
if (player->HasItemCount(_stoneId))
|
||||
if (player->HasItemCount(stoneId))
|
||||
{
|
||||
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
|
||||
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(stoneSpell))
|
||||
{
|
||||
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TOO_MANY_OF_ITEM);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
player->CastSpell(player, _stoneSpell, false);
|
||||
player->CastSpell(player, stoneSpell, false);
|
||||
|
||||
// Item has to actually be created to remove a charge on the well.
|
||||
if (player->HasItemCount(_stoneId))
|
||||
if (player->HasItemCount(stoneId))
|
||||
{
|
||||
me->AddUse();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _stoneSpell;
|
||||
uint32 _stoneId;
|
||||
};
|
||||
|
||||
GameObjectAI* GetAI(GameObject* go) const override
|
||||
|
||||
Reference in New Issue
Block a user