Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2022-09-19 09:23:59 -06:00
committed by GitHub
33 changed files with 677 additions and 148 deletions

View File

@@ -76,6 +76,8 @@ enum CreaturesIds
NPC_BLACKHAND_INCARCERATOR = 10316,
NPC_LORD_VICTOR_NEFARIUS = 10162,
NPC_SCARSHIELD_INFILTRATOR = 10299,
NPC_SOLAKAR = 10264,
NPC_ROOKERY_GUARDIAN = 10258,
NPC_ROOKERY_HATCHER = 10683,
@@ -95,7 +97,8 @@ enum AdditionalData
AREATRIGGER = 1,
AREATRIGGER_DRAGONSPIRE_HALL = 2046,
AREATRIGGER_BLACKROCK_STADIUM = 2026,
SAY_FINKLE_GANG = 0
SAY_FINKLE_GANG = 0,
ITEM_UNADORNED_SEAL = 12219
};
enum GameObjectsIds

View File

@@ -53,7 +53,8 @@ Position SolakarPosBoss = Position(80.0f, -280.0f, 93.0f, 3.0f * M_PI / 2.0);
enum Texts
{
SAY_NEFARIUS_REND_WIPE = 11,
SAY_SOLAKAR_FIRST_HATCHER = 0
SAY_SOLAKAR_FIRST_HATCHER = 0,
SAY_SCARSHIELD_INF_WHISPER = 0
};
MinionData const minionData[] =
@@ -823,10 +824,65 @@ public:
}
};
class near_scarshield_infiltrator : public AreaTriggerScript
{
public:
near_scarshield_infiltrator() : AreaTriggerScript("near_scarshield_infiltrator") { }
bool OnTrigger(Player* player, const AreaTrigger* /*at*/) override
{
if (player && player->IsAlive())
{
if (Creature* creature = player->FindNearestCreature(NPC_SCARSHIELD_INFILTRATOR, 100.0f, true))
{
bool transformHasStarted = creature->AI()->GetData(0) == 1;
if ((player->getLevel() < 57 || !player->HasItemCount(ITEM_UNADORNED_SEAL)) && !transformHasStarted)
{
// Send whisper if not already sent
std::list<ObjectGuid>::iterator itr = std::find(whisperedTargets.begin(), whisperedTargets.end(), player->GetGUID());
if (itr == whisperedTargets.end())
{
creature->AI()->Talk(SAY_SCARSHIELD_INF_WHISPER, player);
whisperedTargets.push_back(player->GetGUID());
return true;
}
}
}
}
return false;
}
private:
GuidList whisperedTargets;
};
class at_scarshield_infiltrator : public AreaTriggerScript
{
public:
at_scarshield_infiltrator() : AreaTriggerScript("at_scarshield_infiltrator") { }
bool OnTrigger(Player* player, const AreaTrigger* /*at*/) override
{
if (player && player->IsAlive())
{
if (Creature* creature = player->FindNearestCreature(NPC_SCARSHIELD_INFILTRATOR, 100.0f, true))
{
if (player->getLevel() >= 57 && player->HasItemCount(ITEM_UNADORNED_SEAL))
{
creature->AI()->SetData(0, 1); // Start transform into Vaelan
return true;
}
}
}
return false;
}
};
void AddSC_instance_blackrock_spire()
{
new instance_blackrock_spire();
new at_dragonspire_hall();
new at_blackrock_stadium();
new go_father_flame();
new near_scarshield_infiltrator();
new at_scarshield_infiltrator();
}

View File

@@ -89,6 +89,7 @@ struct boss_ayamiss : public BossAI
_enraged = false;
SetCombatMovement(false);
_scheduler.CancelAll();
me->SetReactState(REACT_AGGRESSIVE);
}
void JustSummoned(Creature* who) override
@@ -120,6 +121,7 @@ struct boss_ayamiss : public BossAI
me->m_Events.AddEventAtOffset([this]()
{
me->SetReactState(REACT_AGGRESSIVE);
if (me->GetVictim())
{
me->GetMotionMaster()->MoveChase(me->GetVictim());
@@ -157,7 +159,7 @@ struct boss_ayamiss : public BossAI
}
context.Repeat(RAND(2400ms, 3600ms));
}).Schedule(15s, [this](TaskContext context) {
}).Schedule(15s, 28s, [this](TaskContext context) {
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0, true))
{
DoCast(target, SPELL_PARALYZE, true);
@@ -215,6 +217,7 @@ struct boss_ayamiss : public BossAI
{
_phase = PHASE_GROUND;
me->ClearUnitState(UNIT_STATE_ROOT);
me->SetReactState(REACT_PASSIVE);
me->SetCanFly(false);
me->SetDisableGravity(false);
me->GetMotionMaster()->MovePath(me->GetEntry() * 10, false);

View File

@@ -134,8 +134,6 @@ struct boss_skeram : public BossAI
{
_JustDied();
Talk(SAY_DEATH);
instance->HandleGameObject(instance->GetGuidData(AQ40_DOOR_3), true);
}
else
me->RemoveCorpse();

View File

@@ -31,6 +31,14 @@ ObjectData const creatureData[] =
{ NPC_VEKNILASH, DATA_VEKNILASH }
};
DoorData const doorData[] =
{
{ AQ40_DOOR_SKERAM, DATA_SKERAM, DOOR_TYPE_PASSAGE },
{ AQ40_DOOR_TE_ENTRANCE, DATA_TWIN_EMPERORS, DOOR_TYPE_ROOM },
{ AQ40_DOOR_TE_EXIT, DATA_TWIN_EMPERORS, DOOR_TYPE_PASSAGE },
{ 0, 0, DOOR_TYPE_ROOM}
};
class instance_temple_of_ahnqiraj : public InstanceMapScript
{
public:
@@ -45,9 +53,9 @@ public:
{
instance_temple_of_ahnqiraj_InstanceMapScript(Map* map) : InstanceScript(map)
{
LoadObjectData(creatureData, nullptr);
doorGUIDs.fill(ObjectGuid::Empty);
SetBossNumber(MAX_BOSS_NUMBER);
LoadObjectData(creatureData, nullptr);
LoadDoorData(doorData);
}
ObjectGuid SkeramGUID;
@@ -57,7 +65,6 @@ public:
ObjectGuid ViscidusGUID;
ObjectGuid CThunGUID;
GuidVector CThunGraspGUIDs;
std::array<ObjectGuid, 3> doorGUIDs;
uint32 BugTrioDeathCount;
uint32 CthunPhase;
@@ -74,10 +81,6 @@ public:
{
case NPC_SKERAM:
SkeramGUID = creature->GetGUID();
if (!creature->IsAlive())
{
HandleGameObject(doorGUIDs[2], true);
}
break;
case NPC_VEM:
VemGUID = creature->GetGUID();
@@ -123,29 +126,6 @@ public:
{
switch (go->GetEntry())
{
case AQ40_DOOR_1:
doorGUIDs[0] = go->GetGUID();
break;
case AQ40_DOOR_2:
doorGUIDs[1] = go->GetGUID();
if (Creature* veklor = GetCreature(DATA_VEKLOR))
{
if (!veklor->IsAlive())
{
HandleGameObject(go->GetGUID(), true);
}
}
break;
case AQ40_DOOR_3:
doorGUIDs[2] = go->GetGUID();
if (Creature* skeram = instance->GetCreature(SkeramGUID))
{
if (!skeram->IsAlive())
{
HandleGameObject(go->GetGUID(), true);
}
}
break;
case GO_CTHUN_GRASP:
CThunGraspGUIDs.push_back(go->GetGUID());
if (Creature* CThun = instance->GetCreature(CThunGUID))
@@ -190,12 +170,6 @@ public:
return YaujGUID;
case DATA_VISCIDUS:
return ViscidusGUID;
case AQ40_DOOR_1:
return doorGUIDs[0];
case AQ40_DOOR_2:
return doorGUIDs[1];
case AQ40_DOOR_3:
return doorGUIDs[2];
}
return ObjectGuid::Empty;
}

View File

@@ -36,25 +36,30 @@ enum Spells
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
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,
// Obsidian Eradicator
SPELL_SHOCK_BLAST = 26458,
SPELL_DRAIN_MANA = 25671,
SPELL_DRAIN_MANA_VISUAL = 26639,
// Anubisath Warder
SPELL_FEAR = 26070,
SPELL_ENTAGLING_ROOTS = 26071,
SPELL_SILENCE = 26069,
SPELL_DUST_CLOUD = 26072,
SPELL_FIRE_NOVA = 26073,
// Obsidian Nullifier
SPELL_NULLIFY = 26552,
SPELL_CLEAVE = 40504
};
struct npc_anubisath_defender : public ScriptedAI
@@ -220,38 +225,6 @@ private:
TaskScheduler _scheduler;
};
enum NPCs
{
NPC_VEKNISS_DRONE = 15300
};
class spell_aggro_drones : public SpellScript
{
PrepareSpellScript(spell_aggro_drones);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
{
if (Creature* target = GetHitCreature())
{
if (target->GetEntry() == NPC_VEKNISS_DRONE)
{
if (Unit* victim = caster->GetVictim())
{
target->AI()->AttackStart(victim);
}
}
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_aggro_drones::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
struct npc_obsidian_eradicator : public ScriptedAI
{
npc_obsidian_eradicator(Creature* creature) : ScriptedAI(creature)
@@ -316,27 +289,6 @@ private:
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)
@@ -406,12 +358,132 @@ private:
TaskScheduler _scheduler;
};
struct npc_obsidian_nullifier : public ScriptedAI
{
npc_obsidian_nullifier(Creature* creature) : ScriptedAI(creature)
{
}
void Reset() override
{
_scheduler.CancelAll();
me->SetPower(POWER_MANA, 0);
_targets.clear();
}
void EnterCombat(Unit* /*who*/) override
{
_scheduler.Schedule(6s, [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, 11);
}
for (Unit* target : _targets)
{
DoCast(target, SPELL_DRAIN_MANA, true);
}
if (me->GetPowerPct(POWER_MANA) >= 100.f)
{
DoCastAOE(SPELL_NULLIFY, true);
}
context.Repeat(6s);
})
.Schedule(6000ms, 8400ms, [this](TaskContext context)
{
DoCastVictim(SPELL_CLEAVE, true);
context.Repeat(6000ms, 8400ms);
});
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
_scheduler.Update(diff,
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
}
private:
TaskScheduler _scheduler;
std::list<Player*> _targets;
};
enum NPCs
{
NPC_VEKNISS_DRONE = 15300
};
class spell_aggro_drones : public SpellScript
{
PrepareSpellScript(spell_aggro_drones);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
{
if (Creature* target = GetHitCreature())
{
if (target->GetEntry() == NPC_VEKNISS_DRONE)
{
if (Unit* victim = caster->GetVictim())
{
target->AI()->AttackStart(victim);
}
}
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_aggro_drones::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
class spell_nullify : public AuraScript
{
PrepareAuraScript(spell_nullify);
void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* target = GetTarget())
{
target->SetHealth(1);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_nullify::HandleApply, EFFECT_1, SPELL_AURA_SCHOOL_IMMUNITY, AURA_EFFECT_HANDLE_REAL);
}
};
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);
RegisterTempleOfAhnQirajCreatureAI(npc_obsidian_nullifier);
RegisterSpellScript(spell_aggro_drones);
RegisterSpellScript(spell_nullify);
}

View File

@@ -80,9 +80,9 @@ enum Creatures
enum ObjectsAQ40
{
AQ40_DOOR_1 = 180634,
AQ40_DOOR_2 = 180635,
AQ40_DOOR_3 = 180636,
AQ40_DOOR_TE_ENTRANCE = 180634,
AQ40_DOOR_TE_EXIT = 180635,
AQ40_DOOR_SKERAM = 180636,
GO_CTHUN_GRASP = 180745
};

View File

@@ -87,19 +87,25 @@ public:
switch (waypointId)
{
case 19:
me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
Talk(SAY_AGGRO1, player);
if (Creature* summoned = me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000))
{
Talk(SAY_AGGRO1, summoned);
}
break;
case 28:
Talk(SAY_SEARCH, player);
break;
case 38:
me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
Talk(SAY_AGGRO2, player);
if (Creature* summoned = me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000))
{
Talk(SAY_AGGRO2, summoned);
}
break;
case 49:
me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
Talk(SAY_AGGRO3, player);
if (Creature* summoned = me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000))
{
Talk(SAY_AGGRO3, summoned);
}
break;
case 55:
Talk(SAY_FINISH, player);

View File

@@ -55,6 +55,7 @@ enum MageSpells
SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT = 70908,
SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY = 70907,
SPELL_MAGE_GLYPH_OF_BLAST_WAVE = 62126,
SPELL_MAGE_FINGERS_OF_FROST = 44543
};
class spell_mage_arcane_blast : public SpellScript
@@ -932,6 +933,114 @@ class spell_mage_summon_water_elemental : public SpellScript
}
};
#define FingersOfFrostScriptName "spell_mage_fingers_of_frost_proc_aura"
class spell_mage_fingers_of_frost_proc_aura : public AuraScript
{ PrepareAuraScript(spell_mage_fingers_of_frost_proc_aura);
bool CheckProc(ProcEventInfo& eventInfo)
{
if (eventInfo.GetSpellPhaseMask() != PROC_SPELL_PHASE_CAST)
{
eventInfo.SetProcChance(_chance);
}
return true;
}
bool CheckAfterProc(ProcEventInfo& eventInfo)
{
if (eventInfo.GetSpellPhaseMask() != PROC_SPELL_PHASE_CAST)
{
eventInfo.ResetProcChance();
}
return true;
}
void HandleOnEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_CAST)
{
_chance = 100.f;
_spell = eventInfo.GetProcSpell();
if (!_spell || _spell->GetDelayMoment() <= 0)
{
PreventDefaultAction();
}
}
else
{
if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_FINISH || ((_spell && _spell->GetDelayMoment() > 0) || !eventInfo.GetDamageInfo()))
{
PreventDefaultAction();
}
_chance = 0.f;
_spell = nullptr;
}
}
void HandleAfterEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_HIT)
{
_chance = 100.f;
}
else if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_FINISH)
{
_chance = 0.f;
_spell = nullptr;
}
}
void Register()
{
DoCheckProc += AuraCheckProcFn(spell_mage_fingers_of_frost_proc_aura::CheckProc);
DoCheckAfterProc += AuraCheckProcFn(spell_mage_fingers_of_frost_proc_aura::CheckAfterProc);
OnEffectProc += AuraEffectProcFn(spell_mage_fingers_of_frost_proc_aura::HandleOnEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
AfterEffectProc += AuraEffectProcFn(spell_mage_fingers_of_frost_proc_aura::HandleAfterEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
public:
Spell const* GetProcSpell() const { return _spell; }
private:
float _chance = 0.f;
Spell const* _spell = nullptr;
};
typedef spell_mage_fingers_of_frost_proc_aura spell_mage_fingers_of_frost_proc_aura_script;
class spell_mage_fingers_of_frost_proc : public AuraScript
{
PrepareAuraScript(spell_mage_fingers_of_frost_proc);
bool CheckProc(ProcEventInfo& eventInfo)
{
if (Aura* aura = GetCaster()->GetAuraOfRankedSpell(SPELL_MAGE_FINGERS_OF_FROST))
{
if (spell_mage_fingers_of_frost_proc_aura_script* script = dynamic_cast<spell_mage_fingers_of_frost_proc_aura_script*>(aura->GetScriptByName(FingersOfFrostScriptName)))
{
if (Spell const* fofProcSpell = script->GetProcSpell())
{
if (fofProcSpell == eventInfo.GetProcSpell())
{
return false;
}
}
}
}
return true;
}
void Register()
{
DoCheckProc += AuraCheckProcFn(spell_mage_fingers_of_frost_proc::CheckProc);
}
};
void AddSC_mage_spell_scripts()
{
RegisterSpellScript(spell_mage_arcane_blast);
@@ -955,4 +1064,6 @@ void AddSC_mage_spell_scripts()
RegisterSpellScript(spell_mage_master_of_elements);
RegisterSpellScript(spell_mage_polymorph_cast_visual);
RegisterSpellScript(spell_mage_summon_water_elemental);
RegisterSpellScript(spell_mage_fingers_of_frost_proc_aura);
RegisterSpellScript(spell_mage_fingers_of_frost_proc);
}