Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2022-09-15 09:10:16 -06:00
committed by GitHub
11 changed files with 372 additions and 26 deletions

View File

@@ -34,7 +34,8 @@ enum Spells
SPELL_EARTH_SHOCK = 26194,
SPELL_TRUE_FULFILLMENT = 785,
SPELL_INITIALIZE_IMAGE = 3730,
SPELL_SUMMON_IMAGES = 747
SPELL_SUMMON_IMAGES = 747,
SPELL_BIRTH = 34115
};
enum Events
@@ -42,7 +43,9 @@ enum Events
EVENT_ARCANE_EXPLOSION = 1,
EVENT_FULLFILMENT = 2,
EVENT_BLINK = 3,
EVENT_EARTH_SHOCK = 4
EVENT_EARTH_SHOCK = 4,
EVENT_TELEPORT = 5,
EVENT_INIT_IMAGE = 6
};
uint32 const BlinkSpells[3] = { 4801, 8195, 20449 };
@@ -56,7 +59,9 @@ struct boss_skeram : public BossAI
_Reset();
_flag = 0;
_hpct = 75.0f;
me->SetVisible(true);
me->SetReactState(REACT_AGGRESSIVE);
me->SetImmuneToAll(false);
me->SetControlled(false, UNIT_STATE_ROOT);
}
void KilledUnit(Unit* /*victim*/) override
@@ -72,6 +77,29 @@ struct boss_skeram : public BossAI
}
void JustSummoned(Creature* creature) override
{
BossAI::JustSummoned(creature);
float ImageHealthPct = 0.f;
if (me->GetHealthPct() < 25.0f)
ImageHealthPct = 0.50f;
else if (me->GetHealthPct() < 50.0f)
ImageHealthPct = 0.20f;
else
ImageHealthPct = 0.10f;
creature->SetMaxHealth(me->GetMaxHealth() * ImageHealthPct);
creature->SetHealth(creature->GetMaxHealth() * (me->GetHealthPct() / 100.0f));
creature->CastSpell(creature, SPELL_BIRTH, true);
creature->SetControlled(true, UNIT_STATE_ROOT);
creature->SetReactState(REACT_PASSIVE);
creature->SetImmuneToAll(true);
_copiesGUIDs.push_back(creature->GetGUID());
}
void DoTeleport(Creature* creature)
{
// Shift the boss and images (Get it? *Shift*?)
uint8 rand = 0;
@@ -86,24 +114,18 @@ struct boss_skeram : public BossAI
while (_flag & (1 << rand))
rand = urand(0, 2);
creature->CastSpell(creature, BlinkSpells[rand]);
creature->SetReactState(REACT_AGGRESSIVE);
creature->SetImmuneToAll(false);
creature->SetControlled(false, UNIT_STATE_ROOT);
creature->CastSpell(creature, BlinkSpells[rand], true);
_flag |= (1 << rand);
if (_flag & (1 << 7))
_flag = 0;
float ImageHealthPct;
if (me->GetHealthPct() < 25.0f)
ImageHealthPct = 0.50f;
else if (me->GetHealthPct() < 50.0f)
ImageHealthPct = 0.20f;
else
ImageHealthPct = 0.10f;
creature->SetMaxHealth(me->GetMaxHealth() * ImageHealthPct);
creature->SetHealth(creature->GetMaxHealth() * (me->GetHealthPct() / 100.0f));
BossAI::JustSummoned(creature);
events.ScheduleEvent(EVENT_INIT_IMAGE, 400ms);
}
void JustDied(Unit* /*killer*/) override
@@ -129,7 +151,10 @@ struct boss_skeram : public BossAI
events.ScheduleEvent(EVENT_BLINK, 30s, 45s);
events.ScheduleEvent(EVENT_EARTH_SHOCK, 1200ms);
Talk(SAY_AGGRO);
if (!me->IsSummon())
{
Talk(SAY_AGGRO);
}
}
void UpdateAI(uint32 diff) override
@@ -154,23 +179,42 @@ struct boss_skeram : public BossAI
case EVENT_BLINK:
DoCast(me, BlinkSpells[urand(0, 2)]);
DoResetThreat();
me->SetVisible(true);
events.ScheduleEvent(EVENT_BLINK, 10s, 30s);
break;
case EVENT_EARTH_SHOCK:
DoCastVictim(SPELL_EARTH_SHOCK);
events.ScheduleEvent(EVENT_EARTH_SHOCK, 1200ms);
break;
case EVENT_TELEPORT:
me->SetReactState(REACT_AGGRESSIVE);
me->SetImmuneToAll(false);
me->SetControlled(false, UNIT_STATE_ROOT);
for (ObjectGuid const& guid : _copiesGUIDs)
{
if (Creature* image = ObjectAccessor::GetCreature(*me, guid))
{
DoTeleport(image);
}
}
DoResetThreat();
events.RescheduleEvent(EVENT_BLINK, 10s, 30s);
break;
case EVENT_INIT_IMAGE:
me->CastSpell(me, SPELL_INITIALIZE_IMAGE, true);
break;
}
}
if (!me->IsSummon() && me->GetHealthPct() < _hpct)
{
_copiesGUIDs.clear();
DoCast(me, SPELL_SUMMON_IMAGES, true);
me->SetReactState(REACT_PASSIVE);
me->SetImmuneToAll(true);
me->SetControlled(true, UNIT_STATE_ROOT);
Talk(SAY_SPLIT);
_hpct -= 25.0f;
me->SetVisible(false);
events.RescheduleEvent(EVENT_BLINK, 2s);
events.ScheduleEvent(EVENT_TELEPORT, 2s);
}
if (Unit* myVictim = me->GetVictim())
@@ -193,6 +237,7 @@ struct boss_skeram : public BossAI
private:
float _hpct;
uint8 _flag;
GuidVector _copiesGUIDs;
};
class spell_skeram_arcane_explosion : public SpellScript

View File

@@ -15,6 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MapReference.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
@@ -23,22 +25,36 @@
enum Spells
{
// Anubisath Defender
SPELL_SHADOW_FROST_REFLECT = 19595,
SPELL_FIRE_ARCANE_REFLECT = 13022,
SPELL_METEOR = 26558,
SPELL_PLAGUE = 26556,
SPELL_SHADOW_STORM = 26555,
SPELL_THUNDERCLAP = 26554,
SPELL_ENRAGE = 14204,
SPELL_EXPLODE = 25699,
SPELL_SUMMON_WARRIOR = 17431,
SPELL_SUMMON_SWARMGUARD = 17430,
SPELL_FEAR = 26070,
SPELL_ENTAGLING_ROOTS = 26071,
SPELL_SILENCE = 26069,
SPELL_DUST_CLOUD = 26072,
SPELL_FIRE_NOVA = 26073,
SPELL_SUMMON_LARGE_OBSIDIAN_CHUNK = 27630, // Server-side
TALK_ENRAGE = 0
SPELL_SHOCK_BLAST = 26458,
SPELL_DRAIN_MANA = 25671,
SPELL_DRAIN_MANA_VISUAL = 26639,
TALK_ENRAGE = 0,
// Vekniss Stinger
SPELL_VEKNISS_CATALYST = 26078,
SPELL_STINGER_CHARGE_NORMAL = 26081,
SPELL_STINGER_CHARGE_BUFFED = 26082,
};
struct npc_anubisath_defender : public ScriptedAI
@@ -151,6 +167,59 @@ private:
bool _enraged;
};
struct npc_vekniss_stinger : public ScriptedAI
{
npc_vekniss_stinger(Creature* creature) : ScriptedAI(creature)
{
}
void Reset() override
{
_scheduler.CancelAll();
}
void EnterCombat(Unit* who) override
{
DoCast(who ,who->HasAura(SPELL_VEKNISS_CATALYST) ? SPELL_STINGER_CHARGE_BUFFED : SPELL_STINGER_CHARGE_NORMAL, true);
_scheduler.Schedule(6s, [this](TaskContext context)
{
Unit* target = SelectTarget(SelectTargetMethod::Random, 0, [&](Unit* u)
{
return u && !u->IsPet() && u->IsWithinDist2d(me, 20.f) && u->HasAura(SPELL_VEKNISS_CATALYST);
});
if (!target)
{
target = SelectTarget(SelectTargetMethod::Random, 0, [&](Unit* u)
{
return u && !u->IsPet() && u->IsWithinDist2d(me, 20.f);
});
}
if (target)
{
DoCast(target, target->HasAura(SPELL_VEKNISS_CATALYST) ? SPELL_STINGER_CHARGE_BUFFED : SPELL_STINGER_CHARGE_NORMAL, true);
}
context.Repeat(6s);
});
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
_scheduler.Update(diff,
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
}
private:
TaskScheduler _scheduler;
};
enum NPCs
{
NPC_VEKNISS_DRONE = 15300
@@ -183,8 +252,166 @@ class spell_aggro_drones : public SpellScript
}
};
struct npc_obsidian_eradicator : public ScriptedAI
{
npc_obsidian_eradicator(Creature* creature) : ScriptedAI(creature)
{
}
void Reset() override
{
_scheduler.CancelAll();
me->SetPower(POWER_MANA, 0);
_targets.clear();
}
void EnterCombat(Unit* /*who*/) override
{
_scheduler.Schedule(3500ms, [this](TaskContext context)
{
if (_targets.empty())
{
Map::PlayerList const& players = me->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
if (Player* player = itr->GetSource())
{
if (player->IsAlive() && !player->IsGameMaster() && !player->IsSpectator() && player->GetPower(POWER_MANA) > 0)
{
_targets.push_back(player);
}
}
}
Acore::Containers::RandomResize(_targets, 10);
}
for (Unit* target : _targets)
{
DoCast(target, SPELL_DRAIN_MANA, true);
}
if (me->GetPowerPct(POWER_MANA) >= 100.f)
{
DoCastAOE(SPELL_SHOCK_BLAST, true);
}
context.Repeat(3500ms);
});
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
_scheduler.Update(diff,
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
}
private:
TaskScheduler _scheduler;
std::list<Player*> _targets;
};
class spell_drain_mana : public SpellScript
{
PrepareSpellScript(spell_drain_mana);
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
{
if (Unit* target = GetHitUnit())
{
target->CastSpell(caster, SPELL_DRAIN_MANA_VISUAL, true);
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_drain_mana::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
struct npc_anubisath_warder : public ScriptedAI
{
npc_anubisath_warder(Creature* creature) : ScriptedAI(creature)
{
}
void Reset() override
{
_scheduler.CancelAll();
}
void EnterCombat(Unit* /*who*/) override
{
if (urand(0, 1))
{
_scheduler.Schedule(5s, 5s, [this](TaskContext context)
{
DoCastAOE(SPELL_FEAR, true);
context.Repeat(20s, 20s);
});
}
else
{
_scheduler.Schedule(5s, 5s, [this](TaskContext context)
{
DoCastAOE(SPELL_ENTAGLING_ROOTS, true);
context.Repeat(20s, 20s);
});
}
if (urand(0, 1))
{
_scheduler.Schedule(4s, 4s, [this](TaskContext context)
{
DoCastAOE(SPELL_SILENCE, true);
context.Repeat(15s, 15s);
});
}
else
{
_scheduler.Schedule(4s, 4s, [this](TaskContext context)
{
DoCastAOE(SPELL_DUST_CLOUD, true);
context.Repeat(15s, 15s);
});
}
_scheduler.Schedule(2s, 2s, [this](TaskContext context)
{
DoCastAOE(SPELL_FIRE_NOVA, true);
context.Repeat(8s, 15s);
});
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
_scheduler.Update(diff,
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
}
private:
TaskScheduler _scheduler;
};
void AddSC_temple_of_ahnqiraj()
{
RegisterTempleOfAhnQirajCreatureAI(npc_anubisath_defender);
RegisterTempleOfAhnQirajCreatureAI(npc_vekniss_stinger);
RegisterSpellScript(spell_aggro_drones);
RegisterTempleOfAhnQirajCreatureAI(npc_obsidian_eradicator);
RegisterSpellScript(spell_drain_mana);
RegisterTempleOfAhnQirajCreatureAI(npc_anubisath_warder);
}