mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-18 03:15:41 +00:00
fix(Scripts/ShadowmoonValley): Rewrite Dragonmaw Races (#19084)
* init * fly :) * finally * melee attack :/ * Update zone_shadowmoon_valley.cpp Co-Authored-By: Dan <83884799+elthehablo@users.noreply.github.com> * Update zone_shadowmoon_valley.cpp * Update zone_shadowmoon_valley.cpp * Update zone_shadowmoon_valley.cpp --------- Co-authored-by: Dan <83884799+elthehablo@users.noreply.github.com>
This commit is contained in:
@@ -1818,6 +1818,418 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
######
|
||||
# Dragonmaw Races
|
||||
######
|
||||
*/
|
||||
|
||||
enum DragonmawRaces
|
||||
{
|
||||
QUEST_MUCKJAW = 11064,
|
||||
QUEST_TROPE = 11067,
|
||||
QUEST_CORLOK = 11068,
|
||||
QUEST_ICHMAN = 11069,
|
||||
QUEST_MULVERICK = 11070,
|
||||
QUEST_SKYSHATTER = 11071,
|
||||
|
||||
NPC_MUCKJAW = 23340,
|
||||
NPC_TROPE = 23342,
|
||||
NPC_CORLOK = 23344,
|
||||
NPC_ICHMAN = 23345,
|
||||
NPC_MULVERICK = 23346,
|
||||
NPC_SKYSHATTER = 23348,
|
||||
|
||||
PATH_MUCKJAW = 233401,
|
||||
PATH_TROPE = 233421,
|
||||
PATH_CORLOK = 233441,
|
||||
PATH_ICHMAN = 233451,
|
||||
PATH_MULVERICK = 233461,
|
||||
PATH_SKYSHATTER = 233481,
|
||||
|
||||
NPC_TARGET_MUCKJAW = 23356,
|
||||
NPC_TARGET_TROPE = 23357,
|
||||
NPC_TARGET_CORLOK = 23358,
|
||||
NPC_TARGET_ICHMAN = 23359,
|
||||
NPC_TARGET_MULVERICK = 23360,
|
||||
NPC_TARGET_SKYSHATTER = 23361,
|
||||
|
||||
SAY_START = 0,
|
||||
SAY_COMPLETE = 1,
|
||||
SAY_SKYSHATTER_SPECIAL = 2,
|
||||
};
|
||||
|
||||
struct dragonmaw_race_npc : public ScriptedAI
|
||||
{
|
||||
dragonmaw_race_npc(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_player = nullptr;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
scheduler.CancelAll();
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
|
||||
me->SetWalk(true);
|
||||
me->SetDisableGravity(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
|
||||
void sQuestAccept(Player* player, Quest const* /*quest*/) override
|
||||
{
|
||||
_player = player;
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
|
||||
if (_player)
|
||||
Talk(SAY_START, _player);
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_MUCKJAW:
|
||||
me->GetMotionMaster()->MovePath(PATH_MUCKJAW, false);
|
||||
break;
|
||||
case NPC_TROPE:
|
||||
me->GetMotionMaster()->MovePath(PATH_TROPE, false);
|
||||
break;
|
||||
case NPC_CORLOK:
|
||||
me->GetMotionMaster()->MovePath(PATH_CORLOK, false);
|
||||
break;
|
||||
case NPC_ICHMAN:
|
||||
me->GetMotionMaster()->MovePath(PATH_ICHMAN, false);
|
||||
break;
|
||||
case NPC_MULVERICK:
|
||||
me->GetMotionMaster()->MovePath(PATH_MULVERICK, false);
|
||||
break;
|
||||
case NPC_SKYSHATTER:
|
||||
me->GetMotionMaster()->MovePath(PATH_SKYSHATTER, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TakeOff()
|
||||
{
|
||||
me->SetDisableGravity(true);
|
||||
}
|
||||
|
||||
void StartRace()
|
||||
{
|
||||
me->SetWalk(false);
|
||||
ScheduleTimedEvent(5s, [&]
|
||||
{
|
||||
if (!_player)
|
||||
FailQuest();
|
||||
else if (!me->IsWithinDist(_player, 100.f))
|
||||
FailQuest();
|
||||
}, 5s);
|
||||
}
|
||||
|
||||
void FailQuest()
|
||||
{
|
||||
if (_player)
|
||||
{
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_MUCKJAW:
|
||||
_player->FailQuest(QUEST_MUCKJAW);
|
||||
break;
|
||||
case NPC_TROPE:
|
||||
_player->FailQuest(QUEST_TROPE);
|
||||
break;
|
||||
case NPC_CORLOK:
|
||||
_player->FailQuest(QUEST_CORLOK);
|
||||
break;
|
||||
case NPC_ICHMAN:
|
||||
_player->FailQuest(QUEST_ICHMAN);
|
||||
break;
|
||||
case NPC_MULVERICK:
|
||||
_player->FailQuest(QUEST_MULVERICK);
|
||||
break;
|
||||
case NPC_SKYSHATTER:
|
||||
_player->FailQuest(QUEST_SKYSHATTER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
scheduler.CancelAll();
|
||||
me->DespawnOnEvade();
|
||||
}
|
||||
|
||||
void StartRaceAttacks()
|
||||
{
|
||||
/*
|
||||
* Timers are placeholders
|
||||
* After spawned, the rest is done via SmartAI
|
||||
*/
|
||||
if (!_player)
|
||||
return;
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_MUCKJAW:
|
||||
ScheduleTimedEvent(4s, [&]
|
||||
{
|
||||
if (_player)
|
||||
{
|
||||
Position summonPos;
|
||||
summonPos = me->GetRandomPoint(_player->GetPosition(), 15.f);
|
||||
summonPos.m_positionZ = _player->GetPositionZ(); // So they don't spawn at ground height
|
||||
me->SummonCreature(NPC_TARGET_MUCKJAW, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}, 4s, 8s);
|
||||
break;
|
||||
case NPC_TROPE:
|
||||
ScheduleTimedEvent(4s, [&]
|
||||
{
|
||||
if (_player)
|
||||
{
|
||||
Position summonPos;
|
||||
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
|
||||
summonPos.m_positionZ = _player->GetPositionZ();
|
||||
me->SummonCreature(NPC_TARGET_TROPE, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}, 1s, 3s);
|
||||
break;
|
||||
case NPC_CORLOK:
|
||||
ScheduleTimedEvent(4s, [&]
|
||||
{
|
||||
if (_player)
|
||||
{
|
||||
Position summonPos;
|
||||
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
|
||||
summonPos.m_positionZ = _player->GetPositionZ();
|
||||
me->SummonCreature(NPC_TARGET_CORLOK, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}, 1s, 3s);
|
||||
break;
|
||||
case NPC_ICHMAN:
|
||||
ScheduleTimedEvent(4s, [&]
|
||||
{
|
||||
if (_player)
|
||||
{
|
||||
Position summonPos;
|
||||
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
|
||||
summonPos.m_positionZ = _player->GetPositionZ();
|
||||
me->SummonCreature(NPC_TARGET_ICHMAN, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}, 1s, 3s);
|
||||
break;
|
||||
case NPC_MULVERICK:
|
||||
ScheduleTimedEvent(4s, [&]
|
||||
{
|
||||
if (_player)
|
||||
{
|
||||
Position summonPos;
|
||||
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
|
||||
summonPos.m_positionZ = _player->GetPositionZ();
|
||||
me->SummonCreature(NPC_TARGET_MULVERICK, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}, 1s, 3s);
|
||||
break;
|
||||
case NPC_SKYSHATTER:
|
||||
ScheduleTimedEvent(4s, [&]
|
||||
{
|
||||
if (_player)
|
||||
{
|
||||
Position summonPos;
|
||||
summonPos = me->GetRandomPoint(_player->GetPosition(), 7.f);
|
||||
summonPos.m_positionZ = _player->GetPositionZ(); // So they don't spawn at ground height
|
||||
me->SummonCreature(NPC_TARGET_SKYSHATTER, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}, 1s, 3s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FinishRace()
|
||||
{
|
||||
scheduler.CancelAll();
|
||||
me->SetHover(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetWalk(true);
|
||||
|
||||
if (_player)
|
||||
{
|
||||
Talk(SAY_COMPLETE, _player);
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_MUCKJAW:
|
||||
_player->AreaExploredOrEventHappens(QUEST_MUCKJAW);
|
||||
break;
|
||||
case NPC_TROPE:
|
||||
_player->AreaExploredOrEventHappens(QUEST_TROPE);
|
||||
break;
|
||||
case NPC_CORLOK:
|
||||
_player->AreaExploredOrEventHappens(QUEST_CORLOK);
|
||||
break;
|
||||
case NPC_ICHMAN:
|
||||
_player->AreaExploredOrEventHappens(QUEST_ICHMAN);
|
||||
break;
|
||||
case NPC_MULVERICK:
|
||||
_player->AreaExploredOrEventHappens(QUEST_MULVERICK);
|
||||
break;
|
||||
case NPC_SKYSHATTER:
|
||||
_player->AreaExploredOrEventHappens(QUEST_SKYSHATTER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 /*type*/, uint32 id) override
|
||||
{
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_MUCKJAW:
|
||||
switch (id)
|
||||
{
|
||||
case 4:
|
||||
TakeOff();
|
||||
break;
|
||||
case 7:
|
||||
StartRace();
|
||||
break;
|
||||
case 9:
|
||||
StartRaceAttacks();
|
||||
break;
|
||||
case 35:
|
||||
FinishRace();
|
||||
break;
|
||||
case 37:
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_TROPE:
|
||||
switch (id)
|
||||
{
|
||||
case 5:
|
||||
TakeOff();
|
||||
break;
|
||||
case 7:
|
||||
StartRace();
|
||||
break;
|
||||
case 10:
|
||||
StartRaceAttacks();
|
||||
break;
|
||||
case 53:
|
||||
FinishRace();
|
||||
break;
|
||||
case 60:
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_CORLOK:
|
||||
switch (id)
|
||||
{
|
||||
case 6:
|
||||
TakeOff();
|
||||
break;
|
||||
case 9:
|
||||
StartRace();
|
||||
break;
|
||||
case 12:
|
||||
StartRaceAttacks();
|
||||
break;
|
||||
case 79:
|
||||
FinishRace();
|
||||
break;
|
||||
case 89:
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_ICHMAN:
|
||||
switch (id)
|
||||
{
|
||||
case 4:
|
||||
TakeOff();
|
||||
StartRace();
|
||||
break;
|
||||
case 12:
|
||||
StartRaceAttacks();
|
||||
break;
|
||||
case 107:
|
||||
FinishRace();
|
||||
break;
|
||||
case 111:
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_MULVERICK:
|
||||
switch (id)
|
||||
{
|
||||
case 5:
|
||||
TakeOff();
|
||||
break;
|
||||
case 9:
|
||||
StartRace();
|
||||
break;
|
||||
case 12:
|
||||
StartRaceAttacks();
|
||||
break;
|
||||
case 166:
|
||||
FinishRace();
|
||||
break;
|
||||
case 172:
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_SKYSHATTER:
|
||||
switch (id)
|
||||
{
|
||||
case 3:
|
||||
TakeOff();
|
||||
break;
|
||||
case 7:
|
||||
StartRace();
|
||||
if (_player)
|
||||
Talk(SAY_SKYSHATTER_SPECIAL, _player);
|
||||
break;
|
||||
case 10:
|
||||
StartRaceAttacks();
|
||||
break;
|
||||
case 140:
|
||||
FinishRace();
|
||||
break;
|
||||
case 145:
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
Player* _player;
|
||||
};
|
||||
|
||||
void AddSC_shadowmoon_valley()
|
||||
{
|
||||
// Ours
|
||||
@@ -1825,6 +2237,7 @@ void AddSC_shadowmoon_valley()
|
||||
RegisterSpellScript(spell_q10563_q10596_to_legion_hold_aura);
|
||||
|
||||
// Theirs
|
||||
RegisterCreatureAI(dragonmaw_race_npc);
|
||||
new npc_invis_infernal_caster();
|
||||
new npc_infernal_attacker();
|
||||
new npc_mature_netherwing_drake();
|
||||
|
||||
@@ -436,68 +436,24 @@ enum q11520Roots
|
||||
SPELL_SUMMON_RAZORTHORN_ROOT = 44941,
|
||||
};
|
||||
|
||||
class spell_q11520_discovering_your_roots : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_q11520_discovering_your_roots);
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (GameObject* go = GetCaster()->FindNearestGameObject(GO_RAZORTHORN_DIRT_MOUNT, 20.0f))
|
||||
{
|
||||
GetCaster()->GetMotionMaster()->MovePoint(0, *go);
|
||||
go->SetLootState(GO_JUST_DEACTIVATED);
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_RAZORTHORN_ROOT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_q11520_discovering_your_roots::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_quest_dragonmaw_race_generic : public SpellScript
|
||||
class spell_q11520_discovering_your_roots : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_quest_dragonmaw_race_generic);
|
||||
PrepareSpellScript(spell_q11520_discovering_your_roots);
|
||||
|
||||
bool Load() override
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
_x = _y = _z = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
SpellCastResult RelocateDest()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
float o = Position::NormalizeOrientation(caster->GetOrientation() + frand(0.0f, 2 * M_PI));
|
||||
float dist = frand(5.0f, 30.0f);
|
||||
_x = caster->GetPositionX() + dist * cos(o);
|
||||
_y = caster->GetPositionY() + dist * std::sin(o);
|
||||
_z = caster->GetPositionZ() + frand(-10.0f, 15.0f);
|
||||
GetSpell()->m_targets.SetDst(_x, _y, _z, 0.0f, caster->GetMapId());
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
void ChangeDest(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
Unit* caster = GetCaster();
|
||||
if (Creature* trigger = caster->SummonCreature(23356, _x, _y, _z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1500))
|
||||
if (GameObject* go = GetCaster()->FindNearestGameObject(GO_RAZORTHORN_DIRT_MOUNT, 20.0f))
|
||||
{
|
||||
trigger->CastSpell(trigger, GetSpellInfo()->Effects[effIndex].TriggerSpell, true);
|
||||
if (GetSpellInfo()->Effects[effIndex].TriggerSpell == 41064)
|
||||
trigger->CastSpell(trigger, 41284, true);
|
||||
GetCaster()->GetMotionMaster()->MovePoint(0, *go);
|
||||
go->SetLootState(GO_JUST_DEACTIVATED);
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_RAZORTHORN_ROOT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCheckCast += SpellCheckCastFn(spell_quest_dragonmaw_race_generic::RelocateDest);
|
||||
OnEffectHit += SpellEffectFn(spell_quest_dragonmaw_race_generic::ChangeDest, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_q11520_discovering_your_roots::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
|
||||
private:
|
||||
float _x, _y, _z;
|
||||
};
|
||||
|
||||
class spell_q11670_it_was_the_orcs_honest : public SpellScript
|
||||
@@ -2508,7 +2464,6 @@ void AddSC_quest_spell_scripts()
|
||||
RegisterSpellScript(spell_q12943_shadow_vault_decree);
|
||||
RegisterSpellAndAuraScriptPair(spell_q10769_dissension_amongst_the_ranks, spell_q10769_dissension_amongst_the_ranks_aura);
|
||||
RegisterSpellScript(spell_q11520_discovering_your_roots);
|
||||
RegisterSpellScript(spell_quest_dragonmaw_race_generic);
|
||||
RegisterSpellScript(spell_q11670_it_was_the_orcs_honest);
|
||||
RegisterSpellScript(spell_quest_test_flight_charging);
|
||||
RegisterSpellScript(spell_q12274_a_fall_from_grace_costume);
|
||||
|
||||
Reference in New Issue
Block a user