From 7571ada7671c809f4e029d7135585c8f7fe4951f Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 8 Feb 2026 15:48:21 +0100 Subject: [PATCH] fix(Script/Quest): Kodo Roundup (#24241) --- .../rev_1766978833232988900.sql | 6 ++ src/server/scripts/Kalimdor/zone_desolace.cpp | 89 +++++++++---------- src/server/scripts/Spells/spell_quest.cpp | 51 +++++++++++ 3 files changed, 100 insertions(+), 46 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1766978833232988900.sql diff --git a/data/sql/updates/pending_db_world/rev_1766978833232988900.sql b/data/sql/updates/pending_db_world/rev_1766978833232988900.sql new file mode 100644 index 000000000..ebabbeb62 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1766978833232988900.sql @@ -0,0 +1,6 @@ +-- +DELETE FROM `spell_script_names` WHERE `spell_id`=18153 AND `ScriptName`='spell_q5561_kodo_roundup_kodo_kombobulator'; +DELETE FROM `spell_script_names` WHERE `spell_id`=18269 AND `ScriptName`='spell_q5561_kodo_roundup_kodo_kombobulator_despawn'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(18153, 'spell_q5561_kodo_roundup_kodo_kombobulator'), +(18269, 'spell_q5561_kodo_roundup_kodo_kombobulator_despawn'); diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 51b37790e..ebe78fe89 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -428,77 +428,74 @@ enum DyingKodo SPELL_KODO_KOMBO_GOSSIP = 18362 }; -class npc_aged_dying_ancient_kodo : public CreatureScript +struct npc_aged_dying_ancient_kodo : public ScriptedAI { -public: - npc_aged_dying_ancient_kodo() : CreatureScript("npc_aged_dying_ancient_kodo") { } + npc_aged_dying_ancient_kodo(Creature* creature) : ScriptedAI(creature) {} - struct npc_aged_dying_ancient_kodoAI : public ScriptedAI + void JustRespawned() override { - npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) {} + me->UpdateEntry(RAND(NPC_AGED_KODO, NPC_DYING_KODO, NPC_ANCIENT_KODO)); + } - void JustRespawned() override + void MoveInLineOfSight(Unit* who) override + { + if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP)) { - me->UpdateEntry(RAND(NPC_AGED_KODO, NPC_DYING_KODO, NPC_ANCIENT_KODO), nullptr, false); + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + + DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); + if (Creature* smeed = who->ToCreature()) + smeed->AI()->Talk(SAY_SMEED_HOME); } + } - void MoveInLineOfSight(Unit* who) override + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (spell->Id == SPELL_KODO_KOMBO_ITEM) { - if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP)) - { - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveIdle(); + me->UpdateEntry(NPC_TAMED_KODO, nullptr, false); + EnterEvadeMode(); + me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); - DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); - if (Creature* smeed = who->ToCreature()) - smeed->AI()->Talk(SAY_SMEED_HOME); - } + caster->CastSpell(caster, SPELL_KODO_KOMBO_PLAYER_BUFF); + DoCastSelf(SPELL_KODO_KOMBO_DESPAWN_BUFF, true); } - - void SpellHit(Unit* caster, SpellInfo const* spell) override + else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP) { - if (spell->Id == SPELL_KODO_KOMBO_ITEM) + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->DespawnOrUnsummon(60s); + } + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) + { + if (Group* group = player->GetGroup()) { - if (!(caster->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) || me->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) - && (me->GetEntry() == NPC_AGED_KODO || me->GetEntry() == NPC_DYING_KODO || me->GetEntry() == NPC_ANCIENT_KODO)) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { - me->UpdateEntry(NPC_TAMED_KODO, nullptr, false); - EnterEvadeMode(); - me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); - - caster->CastSpell(caster, SPELL_KODO_KOMBO_PLAYER_BUFF, true); - DoCast(me, SPELL_KODO_KOMBO_DESPAWN_BUFF, true); + Player* grpPlayer = itr->GetSource(); + if (grpPlayer->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF)) + grpPlayer->TalkedToCreature(creature->GetEntry(), ObjectGuid::Empty); } } - else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP) - { - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->DespawnOrUnsummon(60s); - } - } - }; + else + if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF)) + player->TalkedToCreature(creature->GetEntry(), ObjectGuid::Empty); - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) && creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) - { - player->TalkedToCreature(creature->GetEntry(), ObjectGuid::Empty); player->RemoveAurasDueToSpell(SPELL_KODO_KOMBO_PLAYER_BUFF); } SendGossipMenuFor(player, NPC_TEXT_KODO, creature->GetGUID()); return true; } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_aged_dying_ancient_kodoAI(creature); - } }; void AddSC_desolace() { new npc_cork_gizelton(); - new npc_aged_dying_ancient_kodo(); + RegisterCreatureAI(npc_aged_dying_ancient_kodo); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 4e1b56333..230f9f975 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -32,6 +32,55 @@ * Scriptnames of files in this file should be prefixed with "spell_q#questID_". */ +// Aged Dying Ancient Kodo +std::vector kodoEntry{ 4700, 4701, 4702 }; +class spell_q5561_kodo_roundup_kodo_kombobulator : public SpellScript +{ + PrepareSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator); + + SpellCastResult CheckCast() + { + if (Unit* caster = GetCaster()) + if (Player* player = caster->ToPlayer()) + if (player->HasAura(18172)) // Kodo Kombobulator + return SPELL_FAILED_NOT_READY; + + bool ok = false; + if (Unit* target = GetExplTargetUnit()) + if (Creature* creature = target->ToCreature()) + for (uint32 cid : kodoEntry) + if (creature->GetEntry() == cid) + ok = true; + + if (!ok) + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_q5561_kodo_roundup_kodo_kombobulator::CheckCast); + } +}; + +class spell_q5561_kodo_roundup_kodo_kombobulator_despawn : public SpellScript +{ + PrepareSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator_despawn); + + void HandleDummyEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + if (Creature* creature = caster->ToCreature()) + creature->DespawnOrUnsummon(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_q5561_kodo_roundup_kodo_kombobulator_despawn::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + class spell_q11065_wrangle_some_aether_rays : public SpellScript { PrepareSpellScript(spell_q11065_wrangle_some_aether_rays); @@ -2472,6 +2521,8 @@ class spell_q9847_a_spirit_ally : public SpellScript void AddSC_quest_spell_scripts() { + RegisterSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator); + RegisterSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator_despawn); RegisterSpellAndAuraScriptPair(spell_q11065_wrangle_some_aether_rays, spell_q11065_wrangle_some_aether_rays_aura); RegisterSpellScript(spell_image_of_drakuru_reagent_check); RegisterSpellScript(spell_q12014_steady_as_a_rock);