diff options
3 files changed, 495 insertions, 0 deletions
diff --git a/sql/updates/world/4.3.4/2017_04_29_00_world.sql b/sql/updates/world/4.3.4/2017_04_29_00_world.sql new file mode 100644 index 00000000000..f88378a5e88 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_04_29_00_world.sql @@ -0,0 +1,13 @@ +-- Fix several quest gameobjects in Coldridge Valley +UPDATE `gameobject_template_addon` SET `flags`=4 WHERE `entry` IN (201608,201609,201610,201611,201704,201705,201706); + +-- Scripts +UPDATE `creature_template` SET `ScriptName`= 'npc_wounded_coldridge_mountaineer' WHERE `entry`=37080; +UPDATE `creature_template` SET `ScriptName`= 'npc_wounded_milita' WHERE `entry`=44405; +UPDATE `creature_template` SET `ScriptName`= 'npc_milos_gyro' WHERE `entry`=37198; + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (70046,70047,76143); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(70046, 'spell_a_trip_to_ironforge_quest_complete'), +(70047, 'spell_follow_that_gyrocopter_quest_start'), +(76143, 'spell_low_health'); diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 56efa051c3b..a04729a0ac3 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -181,6 +181,7 @@ void AddSC_instance_zulgurub(); void AddSC_arathi_highlands(); void AddSC_blasted_lands(); void AddSC_burning_steppes(); +void AddSC_dun_morogh_area_coldridge_valley(); void AddSC_duskwood(); void AddSC_eastern_plaguelands(); void AddSC_ghostlands(); @@ -367,6 +368,7 @@ void AddEasternKingdomsScripts() AddSC_arathi_highlands(); AddSC_blasted_lands(); AddSC_burning_steppes(); + AddSC_dun_morogh_area_coldridge_valley(); AddSC_duskwood(); AddSC_eastern_plaguelands(); AddSC_ghostlands(); diff --git a/src/server/scripts/EasternKingdoms/zone_dun_morogh_area_coldridge_valley.cpp b/src/server/scripts/EasternKingdoms/zone_dun_morogh_area_coldridge_valley.cpp new file mode 100644 index 00000000000..323cc3546da --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_dun_morogh_area_coldridge_valley.cpp @@ -0,0 +1,480 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * 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 "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "MoveSplineInit.h" +#include "SpellScript.h" + +enum WoundedColdridgeMountaineer +{ + NPC_JOREN_IRONSTOCK = 37081, + SAY_THANK_PLAYER = 0, + SPELL_HEAL_WOUNDED_MOUNTAINEER = 69855, + SPELL_LOW_HEALTH = 76143, + EVENT_TURN_TO_PLAYER = 1, + EVENT_THANK_PLAYER = 2, + EVENT_MOVE_TO_SAFETY = 3 +}; + +/*###### +# wounded_coldridge_mountaineer +######*/ + +class npc_wounded_coldridge_mountaineer : public CreatureScript +{ +public: + npc_wounded_coldridge_mountaineer() : CreatureScript("npc_wounded_coldridge_mountaineer") { } + + struct npc_wounded_coldridge_mountaineerAI : public ScriptedAI + { + npc_wounded_coldridge_mountaineerAI(Creature* creature) : ScriptedAI(creature) + { + Initialize(); + } + + void Initialize() + { + tapped = false; + } + + void Reset() override + { + Initialize(); + _events.Reset(); + me->CastSpell(me, SPELL_LOW_HEALTH); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (tapped) + return; + + if (spell->Id == SPELL_HEAL_WOUNDED_MOUNTAINEER) + { + if (caster->GetTypeId() == TYPEID_PLAYER) + { + tapped = true; + playerGUID = caster->GetGUID(); + me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); + me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); + _events.ScheduleEvent(EVENT_TURN_TO_PLAYER, Seconds(2)); + } + } + } + + void UpdateAI(uint32 diff) override + { + if (!tapped) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_TURN_TO_PLAYER: + me->SetFacingToObject(ObjectAccessor::GetUnit(*me, playerGUID)); + _events.ScheduleEvent(EVENT_THANK_PLAYER, Seconds(1)); + break; + case EVENT_THANK_PLAYER: + Talk(SAY_THANK_PLAYER, ObjectAccessor::GetUnit(*me, playerGUID)); + _events.ScheduleEvent(EVENT_MOVE_TO_SAFETY, Seconds(5)); + break; + case EVENT_MOVE_TO_SAFETY: + if (Creature* joren = me->FindNearestCreature(NPC_JOREN_IRONSTOCK, 75.0f, true)) + me->GetMotionMaster()->MovePoint(0, joren->GetPosition(), true); + me->DespawnOrUnsummon(Seconds(5)); + break; + default: + break; + } + } + } + private: + EventMap _events; + ObjectGuid playerGUID; + bool tapped; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_wounded_coldridge_mountaineerAI(creature); + } +}; + +/*#### +## npc_wounded_milita +####*/ + +enum WoundedMilita +{ + QUEST_KILL_CREDIT = 44175, + SPELL_FLASH_HEAL = 2061, + EVENT_RESET_HEALTH = 4 +}; + +class npc_wounded_milita : public CreatureScript +{ +public: + npc_wounded_milita() : CreatureScript("npc_wounded_milita") { } + + struct npc_wounded_militaAI : public ScriptedAI + { + npc_wounded_militaAI(Creature* creature) : ScriptedAI(creature) + { + Initialize(); + } + + void Initialize() + { + hitBySpell = false; + PercentHP = urand(15, 55); + } + + void Reset() override + { + Initialize(); + me->SetHealth(me->CountPctFromMaxHealth(PercentHP)); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (!hitBySpell) + { + hitBySpell = true; + _events.ScheduleEvent(EVENT_RESET_HEALTH, Seconds(30)); + } + if (spell->Id == SPELL_FLASH_HEAL) + if (caster->GetTypeId() == TYPEID_PLAYER) + caster->ToPlayer()->KilledMonsterCredit(QUEST_KILL_CREDIT); + } + + void UpdateAI(uint32 diff) override + { + if (!hitBySpell) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RESET_HEALTH: + me->SetHealth(me->CountPctFromMaxHealth(PercentHP)); + hitBySpell = false; + break; + default: + break; + } + } + } + private: + EventMap _events; + int8 PercentHP; + bool hitBySpell; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_wounded_militaAI(creature); + } +}; + +/*###### +## npc_milos_gyro +######*/ + +enum MilosGyro +{ + NPC_MILO = 37518, + SPELL_RIDE_VEHICLE_HARD_CODED = 46598, + SPELL_EJECT_ALL_PASSENGERS = 50630, + SAY_MILO_FLIGHT_1 = 0, + SAY_MILO_FLIGHT_2 = 1, + SAY_MILO_FLIGHT_3 = 2, + SAY_MILO_FLIGHT_4 = 3, + SAY_MILO_FLIGHT_5 = 4, + SAY_MILO_FLIGHT_6 = 5, + SAY_MILO_FLIGHT_7 = 6, + EVENT_START_PATH = 5, + EVENT_MILO_SAY_0 = 6, + EVENT_MILO_SAY_1 = 7, + EVENT_MILO_SAY_2 = 8, + EVENT_MILO_SAY_3 = 9, + EVENT_MILO_SAY_4 = 10, + EVENT_MILO_SAY_5 = 11, + EVENT_MILO_SAY_6 = 12, + EVENT_MILO_DESPAWN = 13 +}; + +uint32 const pathSize = 24; +G3D::Vector3 const kharanosPath[pathSize] = +{ + { -6247.328f, 299.5365f, 390.266f }, + { -6247.328f, 299.5365f, 390.266f }, + { -6250.934f, 283.5417f, 393.46f }, + { -6253.335f, 252.7066f, 403.0702f }, + { -6257.292f, 217.4167f, 424.3807f }, + { -6224.2f, 159.9861f, 447.0882f }, + { -6133.597f, 164.3177f, 491.0316f }, + { -6084.236f, 183.375f, 508.5401f }, + { -6020.382f, 179.5052f, 521.5396f }, + { -5973.592f, 161.7396f, 521.5396f }, + { -5953.665f, 151.6111f, 514.5687f }, + { -5911.031f, 146.4462f, 482.1806f }, + { -5886.389f, 124.125f, 445.6252f }, + { -5852.08f, 55.80903f, 406.7922f }, + { -5880.707f, 12.59028f, 406.7922f }, + { -5927.887f, -74.02257f, 406.7922f }, + { -5988.436f, -152.0174f, 425.6251f }, + { -6015.274f, -279.467f, 449.528f }, + { -5936.465f, -454.1875f, 449.528f }, + { -5862.575f, -468.0504f, 444.3899f }, + { -5783.58f, -458.6042f, 432.5026f }, + { -5652.707f, -463.4427f, 415.0308f }, + { -5603.897f, -466.3438f, 409.8931f }, + { -5566.957f, -472.5642f, 399.0056f } +}; + +class npc_milos_gyro : public CreatureScript +{ +public: + npc_milos_gyro() : CreatureScript("npc_milos_gyro") { } + + struct npc_milos_gyro_AI : public VehicleAI + { + npc_milos_gyro_AI(Creature* creature) : VehicleAI(creature) + + { + Initialize(); + } + + void Initialize() + { + miloGUID.Clear(); + waitBeforePath = true; + } + + void Reset() override + { + _events.Reset(); + Initialize(); + } + + void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override + { + if (apply && passenger->GetTypeId() == TYPEID_PLAYER) + { + if (Creature* milo = passenger->SummonCreature(NPC_MILO, me->GetPosition(), TEMPSUMMON_CORPSE_DESPAWN, 0)) + { + waitBeforePath = false; + miloGUID = milo->GetGUID(); + milo->CastSpell(me, SPELL_RIDE_VEHICLE_HARD_CODED); + _events.ScheduleEvent(EVENT_START_PATH, Seconds(1)); + } + } + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type == EFFECT_MOTION_TYPE && pointId == pathSize) + _events.ScheduleEvent(EVENT_MILO_DESPAWN, Seconds(1)); + } + + void UpdateAI(uint32 diff) override + { + if (waitBeforePath) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_START_PATH: + me->GetMotionMaster()->MoveSmoothPath(pathSize, kharanosPath, pathSize, false, true); + _events.ScheduleEvent(EVENT_MILO_SAY_0, Seconds(5)); + break; + case EVENT_MILO_SAY_0: + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->AI()->Talk(SAY_MILO_FLIGHT_1, me); + _events.ScheduleEvent(EVENT_MILO_SAY_1, Seconds(6)); + break; + case EVENT_MILO_SAY_1: + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->AI()->Talk(SAY_MILO_FLIGHT_2, me); + _events.ScheduleEvent(EVENT_MILO_SAY_2, Seconds(11)); + break; + case EVENT_MILO_SAY_2: + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->AI()->Talk(SAY_MILO_FLIGHT_3, me); + _events.ScheduleEvent(EVENT_MILO_SAY_3, Seconds(11)); + break; + case EVENT_MILO_SAY_3: + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->AI()->Talk(SAY_MILO_FLIGHT_4, me); + _events.ScheduleEvent(EVENT_MILO_SAY_4, Seconds(18)); + break; + case EVENT_MILO_SAY_4: + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->AI()->Talk(SAY_MILO_FLIGHT_5, me); + _events.ScheduleEvent(EVENT_MILO_SAY_5, Seconds(11)); + break; + case EVENT_MILO_SAY_5: + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->AI()->Talk(SAY_MILO_FLIGHT_6, me); + _events.ScheduleEvent(EVENT_MILO_SAY_6, Seconds(14)); + break; + case EVENT_MILO_SAY_6: + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->AI()->Talk(SAY_MILO_FLIGHT_7, me); + break; + case EVENT_MILO_DESPAWN: + me->RemoveAllAuras(); + if (Creature* milo = ObjectAccessor::GetCreature(*me, miloGUID)) + milo->DespawnOrUnsummon(); + waitBeforePath = true; + break; + default: + break; + } + } + } + private: + EventMap _events; + ObjectGuid miloGUID; + bool waitBeforePath; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_milos_gyro_AI(creature); + } +}; + +/*###### +# spell_a_trip_to_ironforge_quest_complete +######*/ + +class spell_a_trip_to_ironforge_quest_complete : public SpellScriptLoader +{ +public: + spell_a_trip_to_ironforge_quest_complete() : SpellScriptLoader("spell_a_trip_to_ironforge_quest_complete") { } + + class spell_a_trip_to_ironforge_quest_complete_SpellScript : public SpellScript + { + PrepareSpellScript(spell_a_trip_to_ironforge_quest_complete_SpellScript); + + void HandleForceCast(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_a_trip_to_ironforge_quest_complete_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_a_trip_to_ironforge_quest_complete_SpellScript(); + } +}; + +/*###### +# spell_follow_that_gyrocopter_quest_start +######*/ + +class spell_follow_that_gyrocopter_quest_start : public SpellScriptLoader +{ +public: + spell_follow_that_gyrocopter_quest_start() : SpellScriptLoader("spell_follow_that_gyrocopter_quest_start") { } + + class spell_follow_that_gyrocopter_quest_start_SpellScript : public SpellScript + { + PrepareSpellScript(spell_follow_that_gyrocopter_quest_start_SpellScript); + + void HandleForceCast(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_follow_that_gyrocopter_quest_start_SpellScript::HandleForceCast, EFFECT_1, SPELL_EFFECT_FORCE_CAST); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_follow_that_gyrocopter_quest_start_SpellScript(); + } +}; + +/*###### +# spell_low_health +######*/ + +class spell_low_health: public SpellScriptLoader +{ +public: + spell_low_health() : SpellScriptLoader("spell_low_health") { } + + class spell_low_health_SpellScript : public SpellScript + { + PrepareSpellScript(spell_low_health_SpellScript); + + void HandleDummyEffect(SpellEffIndex /*eff*/) + { + if (GetHitUnit()->GetTypeId() == TYPEID_UNIT) + { + GetHitUnit()->ToCreature()->setRegeneratingHealth(false); + GetHitUnit()->SetHealth(GetHitUnit()->CountPctFromMaxHealth(10)); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_low_health_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_low_health_SpellScript(); + } +}; + +void AddSC_dun_morogh_area_coldridge_valley() +{ + new npc_wounded_coldridge_mountaineer(); + new npc_wounded_milita(); + new npc_milos_gyro(); + new spell_a_trip_to_ironforge_quest_complete(); + new spell_follow_that_gyrocopter_quest_start(); + new spell_low_health(); +} |