aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShamage <7515044+shamage@users.noreply.github.com>2022-08-31 22:32:43 +0200
committerGitHub <noreply@github.com>2022-08-31 22:32:43 +0200
commitb1c0bc53726b4825efce2fde5a2f6c95dc58d5f5 (patch)
tree093fa9967383b5d05412b8e4b4002c433a12ccc8 /src
parente65e5fe29447a779bbb3e3d7aefb9c35266c9c31 (diff)
Scripts/Pandaria: Fixed The Lesson of Stifled Pride (#28128)
* also added some cosmetic stuff Co-authored-by: ModoX <moardox@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Pandaria/pandaria_scripts_loader.cpp26
-rw-r--r--src/server/scripts/Pandaria/zone_the_wandering_isle.cpp410
2 files changed, 436 insertions, 0 deletions
diff --git a/src/server/scripts/Pandaria/pandaria_scripts_loader.cpp b/src/server/scripts/Pandaria/pandaria_scripts_loader.cpp
new file mode 100644
index 00000000000..e84ea05039c
--- /dev/null
+++ b/src/server/scripts/Pandaria/pandaria_scripts_loader.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts loading function should be declared:
+void AddSC_zone_the_wandering_isle();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddPandariaScripts()
+{
+ AddSC_zone_the_wandering_isle();
+}
diff --git a/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp b/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp
new file mode 100644
index 00000000000..b5ad265fbb3
--- /dev/null
+++ b/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp
@@ -0,0 +1,410 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "MotionMaster.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "TaskScheduler.h"
+
+enum TraineeMisc
+{
+ SAY_FINISH_FIGHT = 0,
+
+ SPELL_BLACKOUT_KICK = 109080,
+
+ QUEST_29524_KILLCREDIT = 54586,
+
+ POINT_DESPAWN = 0,
+
+ NPC_HUOJIN_TRAINEE_MALE = 54586,
+ NPC_HUOJIN_TRAINEE_FEMALE = 65470,
+ NPC_TUSHUI_TRAINEE_MALE = 54587,
+ NPC_TUSHUI_TRAINEE_FEMALE = 65471,
+};
+
+Position const TraineeEndpoints[] = {
+ { 1465.3872f, 3283.8604f, 137.69096f },
+ { 1431.401f, 3264.001f, 136.02579f },
+ { 1397.2067f, 3276.5618f, 133.84508f },
+ { 1441.566f, 3232.8013f, 135.01802f },
+ { 1403.632f, 3229.1094f, 132.14877f },
+ { 1347.1927f, 3286.5842f, 131.94803f },
+ { 1365.1865f, 3338.9502f, 128.57233f },
+ { 1349.6024f, 3315.0574f, 130.97443f },
+ { 1335.4618f, 3344.019f, 130.42047f },
+ { 1360.1198f, 3378.02f, 127.34183f },
+ { 1435.8524f, 3355.6423f, 173.77744f },
+ { 1432.7031f, 3385.1572f, 184.4187f },
+ { 1452.6094f, 3373.3315f, 187.0402f },
+ { 1426.7778f, 3364.7517f, 184.39569f },
+ { 1450.3646f, 3361.264f, 184.42484f },
+};
+
+Emote const TraineeEmotes[5] =
+{
+ EMOTE_ONESHOT_MONKOFFENSE_ATTACKUNARMED,
+ EMOTE_ONESHOT_MONKOFFENSE_SPECIALUNARMED,
+ EMOTE_ONESHOT_MONKOFFENSE_PARRYUNARMED,
+ EMOTE_ONESHOT_PALMSTRIKE,
+ EMOTE_ONESHOT_MONKOFFENSE_ATTACKUNARMEDOFF,
+};
+
+// 54586 - Huojin Trainee
+// 65470 - Huojin Trainee
+// 54587 - Tushui Trainee
+// 65471 - Tushui Trainee
+struct npc_tushui_huojin_trainee : public ScriptedAI
+{
+ npc_tushui_huojin_trainee(Creature* creature) : ScriptedAI(creature), _defeated(false) { }
+
+ Emote PlayRandomEmote()
+ {
+ Emote emote = Trinity::Containers::SelectRandomContainerElement(TraineeEmotes);
+ me->HandleEmoteCommand(emote);
+ return emote;
+ }
+
+ void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (me->HealthBelowPctDamaged(20, damage))
+ {
+ damage = 0;
+ if (_defeated)
+ return;
+
+ _defeated = true;
+ if (attacker)
+ {
+ if (Player* player = attacker->ToPlayer())
+ player->KilledMonsterCredit(QUEST_29524_KILLCREDIT);
+ }
+
+ me->SetEmoteState(EMOTE_ONESHOT_NONE);
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ me->CombatStop();
+
+ _scheduler.Schedule(Seconds(1), [this](TaskContext /*task*/)
+ {
+ Talk(SAY_FINISH_FIGHT);
+ });
+
+ _scheduler.Schedule(Seconds(3), [this](TaskContext /*task*/)
+ {
+ Position currentPosition;
+ float currentDist = 1000.0f;
+ for (Position const& pos : TraineeEndpoints)
+ {
+ float dist = pos.GetExactDist(me);
+ if (dist >= currentDist)
+ continue;
+
+ currentPosition = pos;
+ currentDist = dist;
+ }
+ me->GetMotionMaster()->MovePoint(POINT_DESPAWN, currentPosition);
+ });
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (id != POINT_DESPAWN)
+ return;
+
+ me->DespawnOrUnsummon();
+ }
+
+ void JustEngagedWith(Unit* /*attacker*/) override
+ {
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ if (me->GetVictim())
+ DoCastVictim(SPELL_BLACKOUT_KICK);
+
+ task.Repeat(Seconds(8));
+ });
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ if (!_defeated)
+ ScriptedAI::EnterEvadeMode(why);
+ }
+
+protected:
+ TaskScheduler _scheduler;
+ bool _defeated;
+};
+
+enum HuojinTraineeMisc
+{
+ ACTION_PARTNER_ENTERED_COMBAT = 1,
+};
+
+class HuojinTraineePartnerSearch
+{
+public:
+ HuojinTraineePartnerSearch(Creature* partner) : _partner(partner), _minDist(10.0f) { }
+
+ bool operator()(Creature* target)
+ {
+ if (target->GetEntry() != NPC_HUOJIN_TRAINEE_MALE && target->GetEntry() != NPC_HUOJIN_TRAINEE_FEMALE)
+ return false;
+ if (target == _partner)
+ return false;
+ if (target->IsInCombat())
+ return false;
+ if (target->IsInEvadeMode())
+ return false;
+ if (target->isDead())
+ return false;
+
+ float dist = target->GetDistance(_partner);
+ if (dist >= _minDist)
+ return false;
+
+ _minDist = dist;
+ return true;
+ }
+
+private:
+ Unit* _partner;
+ float _minDist;
+};
+
+// 54586 - Huojin Trainee
+// 65470 - Huojin Trainee
+struct npc_huojin_trainee : public npc_tushui_huojin_trainee
+{
+ npc_huojin_trainee(Creature* creature) : npc_tushui_huojin_trainee(creature) { }
+
+ void JustEngagedWith(Unit* attacker) override
+ {
+ _scheduler.CancelAll();
+ npc_tushui_huojin_trainee::JustEngagedWith(attacker);
+
+ Creature* partner = ObjectAccessor::GetCreature(*me, _partnerGuid);
+ if (!partner)
+ return;
+
+ if (partner->AI())
+ partner->AI()->DoAction(ACTION_PARTNER_ENTERED_COMBAT);
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_PARTNER_ENTERED_COMBAT)
+ {
+ _scheduler.CancelAll();
+
+ me->SetEmoteState(EMOTE_ONESHOT_NONE);
+ _scheduler.Schedule(Seconds(1), [this](TaskContext /*task*/ )
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_BOW);
+ });
+ }
+ }
+
+ void BeginSparring(ObjectGuid guid)
+ {
+ _partnerGuid = guid;
+ me->SetEmoteState(EMOTE_ONESHOT_NONE);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_BOW);
+
+ _scheduler.Schedule(Seconds(1), [this](TaskContext /*task*/)
+ {
+ me->SetEmoteState(EMOTE_STATE_MONKOFFENSE_READYUNARMED);
+ });
+
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ PlayRandomEmote();
+ task.Repeat(Seconds(4));
+ });
+ }
+
+ Creature* GetNewPartner()
+ {
+ Creature* partner = nullptr;
+ HuojinTraineePartnerSearch check(me);
+ Trinity::CreatureLastSearcher<HuojinTraineePartnerSearch> searcher(me, partner, check);
+ Cell::VisitGridObjects(me, searcher, 10.0f);
+ return partner;
+ }
+
+ void BeginSparringDelayed(ObjectGuid partnerGuid)
+ {
+ _partnerGuid = partnerGuid;
+ _scheduler.Schedule(Seconds(1), [this, partnerGuid](TaskContext /*task*/)
+ {
+ BeginSparring(partnerGuid);
+ });
+ }
+
+ void InitiateSparring()
+ {
+ Creature* partner = GetNewPartner();
+
+ if (!partner)
+ return;
+
+ BeginSparring(partner->GetGUID());
+ if (Creature* partner = ObjectAccessor::GetCreature(*me, _partnerGuid))
+ {
+ if (npc_huojin_trainee* ai = CAST_AI(npc_huojin_trainee, partner->GetAI()))
+ ai->BeginSparringDelayed(me->GetGUID());
+ }
+ }
+
+ void JustReachedHome() override
+ {
+ InitiateSparring();
+ }
+
+ void JustAppeared() override
+ {
+ // partner is already assigned, sparring start is delayed
+ if (!ObjectAccessor::GetCreature(*me, _partnerGuid))
+ InitiateSparring();
+ }
+private:
+ ObjectGuid _partnerGuid;
+};
+
+class TushuiTraineeSearch
+{
+public:
+ TushuiTraineeSearch(Creature* leader, float maxDist) : _leader(leader), _maxDist(maxDist) { }
+
+ bool operator()(Creature* target) const
+ {
+ if (target->GetEntry() != NPC_TUSHUI_TRAINEE_MALE && target->GetEntry() != NPC_TUSHUI_TRAINEE_FEMALE)
+ return false;
+ if (target->IsInCombat())
+ return false;
+ if (target->IsInEvadeMode())
+ return false;
+ if (target->GetDistance(_leader) >= _maxDist)
+ return false;
+ if (target->isDead())
+ return false;
+
+ return true;
+ }
+
+private:
+ Creature* _leader;
+ float _maxDist;
+};
+
+void HandleEmoteNearbyTushuiTrainees(Creature* leader, Emote emote)
+{
+ std::list<Creature*> traineeList;
+ TushuiTraineeSearch check(leader, 10.0f);
+ Trinity::CreatureListSearcher<TushuiTraineeSearch> searcher(leader, traineeList, check);
+ Cell::VisitGridObjects(leader, searcher, 10.0f);
+
+ for (Creature* trainee : traineeList)
+ trainee->HandleEmoteCommand(emote);
+}
+
+// 54587 - Tushui Trainee
+// 65471 - Tushui Trainee
+struct npc_tushui_leading_trainee : public npc_tushui_huojin_trainee
+{
+ npc_tushui_leading_trainee(Creature* creature) : npc_tushui_huojin_trainee(creature) { }
+
+ void ScheduleEmoteExecution()
+ {
+ _scheduler.Schedule(Seconds(1), [this](TaskContext task)
+ {
+ Emote emote = PlayRandomEmote();
+ HandleEmoteNearbyTushuiTrainees(me, emote);
+ task.Repeat(Seconds(6));
+ });
+ }
+
+ void JustReachedHome() override
+ {
+ ScheduleEmoteExecution();
+ }
+
+ void JustAppeared() override
+ {
+ ScheduleEmoteExecution();
+ }
+
+ void JustEngagedWith(Unit* attacker) override
+ {
+ _scheduler.CancelAll();
+ npc_tushui_huojin_trainee::JustEngagedWith(attacker);
+ }
+};
+
+// 61411 - Instructor Zhi
+struct npc_instructor_zhi : public ScriptedAI
+{
+ npc_instructor_zhi(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
+ {
+ _scheduler.Schedule(Seconds(6), [this](TaskContext task)
+ {
+ Emote emote = Trinity::Containers::SelectRandomContainerElement(TraineeEmotes);
+ me->HandleEmoteCommand(emote);
+
+ task.Schedule(Seconds(1), [this, emote](TaskContext /*task*/)
+ {
+ HandleEmoteNearbyTushuiTrainees(me, emote);
+ });
+ task.Repeat(Seconds(6));
+ });
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+private:
+ TaskScheduler _scheduler;
+};
+
+void AddSC_zone_the_wandering_isle()
+{
+ RegisterCreatureAI(npc_tushui_huojin_trainee);
+ RegisterCreatureAI(npc_huojin_trainee);
+ RegisterCreatureAI(npc_tushui_leading_trainee);
+ RegisterCreatureAI(npc_instructor_zhi);
+}