Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-02-06 17:51:47 +08:00
32 changed files with 1008 additions and 61 deletions

View File

@@ -485,6 +485,27 @@ struct npc_midsummer_torch_target : public ScriptedAI
// SPELLS
///////////////////////////////
class spell_fire_festival_fortitude : public SpellScript
{
PrepareSpellScript(spell_fire_festival_fortitude)
void SelectTargets(std::list<WorldObject*>& targets)
{
targets.clear();
GetCaster()->GetMap()->DoForAllPlayers([&](Player* p)
{
if (p->GetZoneId() == GetCaster()->GetZoneId())
targets.push_back(p);
});
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_fire_festival_fortitude::SelectTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
class spell_bonfires_blessing : public AuraScript
{
PrepareAuraScript(spell_bonfires_blessing)
@@ -1249,6 +1270,7 @@ void AddSC_event_midsummer_scripts()
RegisterCreatureAI(npc_midsummer_ribbon_pole_target);
// Spells
RegisterSpellScript(spell_fire_festival_fortitude);
RegisterSpellScript(spell_bonfires_blessing);
RegisterSpellScript(spell_gen_crab_disguise);
RegisterSpellScript(spell_midsummer_ribbon_pole_firework);

View File

@@ -17,6 +17,7 @@
#include "CreatureScript.h"
#include "Player.h"
#include "MoveSplineInit.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "World.h"
@@ -795,6 +796,61 @@ public:
};
};
enum ToyPlane
{
NPC_DND_DALARAN_TOY_STORE_PLANE_STRING_HOOK = 29807,
SPELL_TOY_PLANE_CABLE = 55281,
};
struct npc_cosmetic_toy_plane : public ScriptedAI
{
npc_cosmetic_toy_plane(Creature* creature) : ScriptedAI(creature)
{
}
void Reset() override
{
Movement::MoveSplineInit init(me);
init.MovebyPath(_movementArray);
init.SetFly();
init.SetCyclic();
// one full loop is 10.76 seconds (sniffed value)
// loop diameter is approx. 9.225f (calculated from waypoints below)
// with a circumference of approx. 28.98f
// this results in flying speed of approx. 2.7f
init.SetVelocity(2.7f);
init.Launch();
scheduler.Schedule(420ms, [this](TaskContext context)
{
if (Creature* cr = me->FindNearestCreature(NPC_DND_DALARAN_TOY_STORE_PLANE_STRING_HOOK, 42.0f))
DoCast(cr, SPELL_TOY_PLANE_CABLE, true);
else
context.Repeat();
});
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
Movement::PointsArray const _movementArray = {
// cyclic movementspine unfortunately includes spawn into loop
// which results in an imperfect loop right now
// CO1 SPAWN(5809.888, 683.5779, 653.6859)
G3D::Vector3(5813.709, 682.51855, 653.6033),
G3D::Vector3(5816.815, 684.8459, 653.5755),
G3D::Vector3(5817.1997, 688.83527, 653.631),
G3D::Vector3(5814.235, 691.6307, 653.6587),
G3D::Vector3(5809.9287, 690.98224, 653.7697),
G3D::Vector3(5808.225, 687.1498, 653.6322),
G3D::Vector3(5809.8423, 683.6158, 653.6862),
};
};
void AddSC_dalaran()
{
// our
@@ -804,6 +860,7 @@ void AddSC_dalaran()
new npc_archmage_landalock();
new npc_dalaran_mage();
new npc_dalaran_warrior();
RegisterCreatureAI(npc_cosmetic_toy_plane);
// theirs
new npc_mageguard_dalaran();

View File

@@ -86,6 +86,7 @@ struct boss_lady_vashj : public BossAI
_count = 0;
_recentlySpoken = false;
_batTimer = 20s;
_playerAngle = 0.0f;
BossAI::Reset();
ScheduleHealthCheckEvent(70, [&]{
@@ -180,7 +181,12 @@ struct boss_lady_vashj : public BossAI
scheduler.CancelAll();
scheduler.Schedule(2400ms, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_FORKED_LIGHTNING);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
_playerAngle = me->GetAngle(target);
me->SetOrientation(_playerAngle);
DoCast(target, SPELL_FORKED_LIGHTNING);
}
context.Repeat(2400ms, 12450ms);
}).Schedule(0s, [this](TaskContext context)
{
@@ -258,6 +264,7 @@ struct boss_lady_vashj : public BossAI
}
private:
float _playerAngle;
bool _recentlySpoken;
bool _intro;
int32 _count;

View File

@@ -45,7 +45,12 @@ enum Yells
SAY_THALADRED_AGGRO = 0,
SAY_SANGUINAR_AGGRO = 0,
SAY_CAPERNIAN_AGGRO = 0,
SAY_TELONICUS_AGGRO = 0
SAY_TELONICUS_AGGRO = 0,
SAY_THALADRED_DEATH = 1,
SAY_SANGUINAR_DEATH = 1,
SAY_CAPERNIAN_DEATH = 1,
SAY_TELONICUS_DEATH = 1,
EMOTE_THALADRED_FIXATE = 2
};
enum Spells
@@ -103,7 +108,28 @@ enum Spells
SPELL_NETHER_BEAM = 35869,
SPELL_NETHER_BEAM_DAMAGE = 35873,
SPELL_REMOTE_TOY_STUN = 37029
SPELL_REMOTE_TOY_STUN = 37029,
// Advisors
// Universal
SPELL_KAEL_PHASE_TWO = 36709,
// Sanguinar
SPELL_BELLOWING_ROAR = 44863,
// Capernian
SPELL_CAPERNIAN_FIREBALL = 36971,
SPELL_CONFLAGRATION = 37018,
SPELL_ARCANE_BURST = 36970,
// Telonicus
SPELL_BOMB = 37036,
SPELL_REMOTE_TOY = 37027,
// Thaladred
SPELL_PSYCHIC_BLOW = 36966,
SPELL_REND = 36965,
SPELL_SILENCE = 30225
};
enum Misc
@@ -721,6 +747,204 @@ public:
}
};
struct npc_lord_sanguinar : public ScriptedAI
{
npc_lord_sanguinar(Creature* creature) : ScriptedAI(creature) {
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void Reset() override
{
scheduler.CancelAll();
}
void JustEngagedWith(Unit* /*who*/) override
{
ScheduleTimedEvent(0s, [&]{
DoCastSelf(SPELL_BELLOWING_ROAR);
}, 15s);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_SANGUINAR_DEATH);
DoCastSelf(SPELL_KAEL_PHASE_TWO, true);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
struct npc_capernian : public ScriptedAI
{
npc_capernian(Creature* creature) : ScriptedAI(creature) {
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void Reset() override
{
scheduler.CancelAll();
}
void JustEngagedWith(Unit* /*who*/) override
{
ScheduleTimedEvent(0ms, [&]{
DoCastVictim(SPELL_CAPERNIAN_FIREBALL);
}, 2500ms);
ScheduleTimedEvent(7000ms, 10000ms, [&]{
DoCastRandomTarget(SPELL_CONFLAGRATION, 0, 30.0f);
}, 18500ms, 20500ms);
ScheduleTimedEvent(3s, [&]{
DoCastRandomTarget(SPELL_ARCANE_BURST, 0, 8.0f);
}, 6s);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_CAPERNIAN_DEATH);
DoCastSelf(SPELL_KAEL_PHASE_TWO, true);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
struct npc_telonicus : public ScriptedAI
{
npc_telonicus(Creature* creature) : ScriptedAI(creature) {
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void Reset() override
{
scheduler.CancelAll();
}
void JustEngagedWith(Unit* /*who*/) override
{
ScheduleTimedEvent(0ms, [&]{
DoCastVictim(SPELL_BOMB);
}, 3600ms, 7100ms);
ScheduleTimedEvent(13250ms, [&]{
DoCastRandomTarget(SPELL_CONFLAGRATION, 0, 100.0f);
}, 15750ms);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_TELONICUS_DEATH);
DoCastSelf(SPELL_KAEL_PHASE_TWO, true);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
struct npc_thaladred : public ScriptedAI
{
npc_thaladred(Creature* creature) : ScriptedAI(creature) {
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void Reset() override
{
scheduler.CancelAll();
me->SetWalk(true);
}
void JustEngagedWith(Unit* /*who*/) override
{
ScheduleTimedEvent(100ms, [&]
{
DoResetThreatList();
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
me->AddThreat(target, 10000000.0f);
Talk(EMOTE_THALADRED_FIXATE, target);
}
}, 10000ms);
ScheduleTimedEvent(4000ms, 19350ms, [&]
{
DoCastVictim(SPELL_PSYCHIC_BLOW);
}, 15700ms, 48900ms);
ScheduleTimedEvent(3000ms, 6050ms, [&]
{
DoCastVictim(SPELL_REND);
}, 15700ms, 48900ms);
ScheduleTimedEvent(3000ms,6050ms, [&]
{
if (Unit* victim = me->GetVictim())
{
if (victim->IsNonMeleeSpellCast(false, false, true))
{
DoCastVictim(SPELL_SILENCE);
}
}
}, 3600ms, 15200ms);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_THALADRED_DEATH);
DoCastSelf(SPELL_KAEL_PHASE_TWO, true);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
class spell_kaelthas_kael_phase_two : public SpellScriptLoader
{
public:
@@ -1052,6 +1276,10 @@ public:
void AddSC_boss_kaelthas()
{
new boss_kaelthas();
RegisterTheEyeAI(npc_lord_sanguinar);
RegisterTheEyeAI(npc_capernian);
RegisterTheEyeAI(npc_telonicus);
RegisterTheEyeAI(npc_thaladred);
new spell_kaelthas_kael_phase_two();
new spell_kaelthas_remote_toy();
new spell_kaelthas_summon_weapons();