aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts/World
diff options
context:
space:
mode:
authorXanadu <none@none>2010-07-17 22:58:24 +0200
committerXanadu <none@none>2010-07-17 22:58:24 +0200
commitb5f8bfd66561e4a63fa8c28961b829a35ceb2fb0 (patch)
tree6691fda7c0985077aeb6ff3a93e829447dddd736 /src/server/scripts/World
parentec244dbe366e84a93c8fa1ef294af4a2e4e3b0b1 (diff)
parentdc510c9a143de1977daedea0aefb9589c01adde2 (diff)
Merge
--HG-- branch : trunk
Diffstat (limited to 'src/server/scripts/World')
-rw-r--r--src/server/scripts/World/areatrigger_scripts.cpp285
-rw-r--r--src/server/scripts/World/boss_emeriss.cpp144
-rw-r--r--src/server/scripts/World/boss_lethon.cpp25
-rw-r--r--src/server/scripts/World/boss_taerar.cpp263
-rw-r--r--src/server/scripts/World/boss_ysondre.cpp203
-rw-r--r--src/server/scripts/World/go_scripts.cpp1182
-rw-r--r--src/server/scripts/World/guards.cpp227
-rw-r--r--src/server/scripts/World/item_scripts.cpp479
-rw-r--r--src/server/scripts/World/mob_generic_creature.cpp228
-rw-r--r--src/server/scripts/World/npc_innkeeper.cpp131
-rw-r--r--src/server/scripts/World/npc_professions.cpp1342
-rw-r--r--src/server/scripts/World/npc_taxi.cpp326
-rw-r--r--src/server/scripts/World/npcs_special.cpp2600
13 files changed, 7435 insertions, 0 deletions
diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp
new file mode 100644
index 00000000000..9a75263d35c
--- /dev/null
+++ b/src/server/scripts/World/areatrigger_scripts.cpp
@@ -0,0 +1,285 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Areatrigger_Scripts
+SD%Complete: 100
+SDComment: Scripts for areatriggers
+SDCategory: Areatrigger
+EndScriptData */
+
+/* ContentData
+at_aldurthar_gate q13315/q13351
+at_coilfang_waterfall 4591
+at_legion_teleporter 4560 Teleporter TO Invasion Point: Cataclysm
+at_ravenholdt
+at_warsong_slaughterhouse
+at_warsong_grainery
+at_torp_farm
+at_warsong_farms q11686
+at_stormwright_shelf q12741
+EndContentData */
+
+#include "ScriptedPch.h"
+
+/*######
+## AreaTrigger_at_aldurthar_gate
+######*/
+
+enum eAldurtharGate
+{
+ TRIGGER_SOUTH = 5284,
+
+ TRIGGER_CENTRAL = 5285,
+ TRIGGER_NORTH = 5286,
+ TRIGGER_NORTHWEST = 5287,
+
+ NPC_SOUTH_GATE = 32195,
+ NPC_CENTRAL_GATE = 32196,
+ NPC_NORTH_GATE = 32197,
+ NPC_NORTHWEST_GATE = 32199
+};
+
+bool AreaTrigger_at_aldurthar_gate(Player* pPlayer, const AreaTriggerEntry* pAt)
+{
+ switch(pAt->id)
+ {
+ case TRIGGER_SOUTH: pPlayer->KilledMonsterCredit(NPC_SOUTH_GATE, 0); break;
+ case TRIGGER_CENTRAL: pPlayer->KilledMonsterCredit(NPC_CENTRAL_GATE, 0); break;
+ case TRIGGER_NORTH: pPlayer->KilledMonsterCredit(NPC_NORTH_GATE, 0); break;
+ case TRIGGER_NORTHWEST: pPlayer->KilledMonsterCredit(NPC_NORTHWEST_GATE, 0); break;
+ }
+ return true;
+}
+
+/*######
+## at_coilfang_waterfall
+######*/
+
+enum eCoilfangGOs
+{
+ GO_COILFANG_WATERFALL = 184212
+};
+
+bool AreaTrigger_at_coilfang_waterfall(Player *pPlayer, const AreaTriggerEntry * /*pAt*/)
+{
+ if (GameObject* pGo = GetClosestGameObjectWithEntry(pPlayer, GO_COILFANG_WATERFALL, 35.0f))
+ if (pGo->getLootState() == GO_READY)
+ pGo->UseDoorOrButton();
+
+ return false;
+}
+
+/*#####
+## at_legion_teleporter
+#####*/
+
+enum eLegionTeleporter
+{
+ SPELL_TELE_A_TO = 37387,
+ QUEST_GAINING_ACCESS_A = 10589,
+
+ SPELL_TELE_H_TO = 37389,
+ QUEST_GAINING_ACCESS_H = 10604
+};
+
+bool AreaTrigger_at_legion_teleporter(Player *pPlayer, const AreaTriggerEntry * /*pAt*/)
+{
+ if (pPlayer->isAlive() && !pPlayer->isInCombat())
+ {
+ if (pPlayer->GetTeam() == ALLIANCE && pPlayer->GetQuestRewardStatus(QUEST_GAINING_ACCESS_A))
+ {
+ pPlayer->CastSpell(pPlayer, SPELL_TELE_A_TO, false);
+ return true;
+ }
+
+ if (pPlayer->GetTeam() == HORDE && pPlayer->GetQuestRewardStatus(QUEST_GAINING_ACCESS_H))
+ {
+ pPlayer->CastSpell(pPlayer, SPELL_TELE_H_TO, false);
+ return true;
+ }
+
+ return false;
+ }
+ return false;
+}
+
+enum eRavenholdt
+{
+ QUEST_MANOR_RAVENHOLDT = 6681,
+ NPC_RAVENHOLDT = 13936
+};
+
+bool AreaTrigger_at_ravenholdt(Player* pPlayer, const AreaTriggerEntry* /*pAt*/)
+{
+ if (pPlayer->GetQuestStatus(QUEST_MANOR_RAVENHOLDT) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->KilledMonsterCredit(NPC_RAVENHOLDT, 0);
+
+ return false;
+}
+
+/*######
+## at_warsong_farms
+######*/
+
+enum eWarsongFarms
+{
+ QUEST_THE_WARSONG_FARMS = 11686,
+
+ NPC_CREDIT_SLAUGHTERHOUSE = 25672,
+ NPC_CREDIT_GRAINERY = 25669,
+ NPC_CREDIT_TORP_FARM = 25671,
+
+ AT_SLAUGHTERHOUSE = 4873,
+ AT_GRAINERY = 4871,
+ AT_TORP_FARM = 4872
+};
+
+bool AreaTrigger_at_warsong_farms(Player* pPlayer, const AreaTriggerEntry* pAt)
+{
+ if (!pPlayer->isDead() && pPlayer->GetQuestStatus(QUEST_THE_WARSONG_FARMS) == QUEST_STATUS_INCOMPLETE)
+ {
+ switch(pAt->id)
+ {
+ case AT_SLAUGHTERHOUSE: pPlayer->KilledMonsterCredit(NPC_CREDIT_SLAUGHTERHOUSE, 0); break;
+ case AT_GRAINERY: pPlayer->KilledMonsterCredit(NPC_CREDIT_GRAINERY, 0); break;
+ case AT_TORP_FARM: pPlayer->KilledMonsterCredit(NPC_CREDIT_TORP_FARM, 0); break;
+ }
+ }
+ return true;
+ }
+
+/*######
+## at_stormwright_shelf
+######*/
+
+enum eStormwrightShelf
+{
+ QUEST_STRENGTH_OF_THE_TEMPEST = 12741,
+
+ SPELL_CREATE_TRUE_POWER_OF_THE_TEMPEST = 53067
+};
+
+bool AreaTrigger_at_stormwright_shelf(Player* pPlayer, const AreaTriggerEntry* /*pAt*/)
+{
+ if (!pPlayer->isDead() && pPlayer->GetQuestStatus(QUEST_STRENGTH_OF_THE_TEMPEST) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->CastSpell(pPlayer, SPELL_CREATE_TRUE_POWER_OF_THE_TEMPEST, false);
+
+ return true;
+}
+
+/*######
+## at_scent_larkorwi
+######*/
+
+enum eScentLarkorwi
+{
+ QUEST_SCENT_OF_LARKORWI = 4291,
+ NPC_LARKORWI_MATE = 9683
+};
+
+bool AreaTrigger_at_scent_larkorwi(Player* pPlayer, const AreaTriggerEntry* /*pAt*/)
+{
+ if (!pPlayer->isDead() && pPlayer->GetQuestStatus(QUEST_SCENT_OF_LARKORWI) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (!pPlayer->FindNearestCreature(NPC_LARKORWI_MATE,15))
+ pPlayer->SummonCreature(NPC_LARKORWI_MATE, pPlayer->GetPositionX()+5, pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 3.3, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 100000);
+ }
+
+ return false;
+}
+
+/*#####
+## at_last_rites
+#####*/
+
+enum eAtLastRites
+{
+ QUEST_LAST_RITES = 12019
+};
+
+bool AreaTrigger_at_last_rites(Player* pPlayer, const AreaTriggerEntry* pAt)
+{
+ if (pPlayer->GetQuestStatus(QUEST_LAST_RITES) != QUEST_STATUS_INCOMPLETE)
+ return false;
+
+ WorldLocation pPosition;
+
+ switch(pAt->id)
+ {
+ case 5332:
+ case 5338:
+ pPosition = WorldLocation(571,3733.68,3563.25,290.812,3.665192);
+ break;
+ case 5334:
+ pPosition = WorldLocation(571,3802.38,3585.95,49.5765,0);
+ break;
+ case 5340:
+ pPosition = WorldLocation(571,3687.91,3577.28,473.342,0);
+ break;
+ default:
+ return false;
+ }
+
+ pPlayer->TeleportTo(pPosition);
+
+ return false;
+}
+
+void AddSC_areatrigger_scripts()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "at_aldurthar_gate";
+ newscript->pAreaTrigger = &AreaTrigger_at_aldurthar_gate;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_coilfang_waterfall";
+ newscript->pAreaTrigger = &AreaTrigger_at_coilfang_waterfall;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_legion_teleporter";
+ newscript->pAreaTrigger = &AreaTrigger_at_legion_teleporter;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_ravenholdt";
+ newscript->pAreaTrigger = &AreaTrigger_at_ravenholdt;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_warsong_farms";
+ newscript->pAreaTrigger = &AreaTrigger_at_warsong_farms;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_stormwright_shelf";
+ newscript->pAreaTrigger = &AreaTrigger_at_stormwright_shelf;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_scent_larkorwi";
+ newscript->pAreaTrigger = &AreaTrigger_at_scent_larkorwi;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_last_rites";
+ newscript->pAreaTrigger = &AreaTrigger_at_last_rites;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/World/boss_emeriss.cpp b/src/server/scripts/World/boss_emeriss.cpp
new file mode 100644
index 00000000000..3dc14969786
--- /dev/null
+++ b/src/server/scripts/World/boss_emeriss.cpp
@@ -0,0 +1,144 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Emeriss
+SD%Complete: 90
+SDComment: Teleport function & Mark of Nature missing
+SDCategory: Bosses
+EndScriptData */
+
+#include "ScriptedPch.h"
+
+enum eEnums
+{
+ SAY_AGGRO = -1000401,
+ SAY_CASTCORRUPTION = -1000402, //signed for 6182
+
+ SPELL_SLEEP = 24777,
+ SPELL_NOXIOUSBREATH = 24818,
+ SPELL_TAILSWEEP = 15847,
+ //SPELL_MARKOFNATURE = 25040, // Not working
+ SPELL_VOLATILEINFECTION = 24928,
+ SPELL_CORRUPTIONOFEARTH = 24910
+};
+
+struct boss_emerissAI : public ScriptedAI
+{
+ boss_emerissAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 m_uiSleep_Timer;
+ uint32 m_uiNoxiousBreath_Timer;
+ uint32 m_uiTailSweep_Timer;
+ //uint32 m_uiMarkOfNature_Timer;
+ uint32 m_uiVolatileInfection_Timer;
+ uint32 m_uiCorruptionsCasted;
+
+ void Reset()
+ {
+ m_uiSleep_Timer = 15000 + rand()%5000;
+ m_uiNoxiousBreath_Timer = 8000;
+ m_uiTailSweep_Timer = 4000;
+ //m_uiMarkOfNature_Timer = 45000;
+ m_uiVolatileInfection_Timer = 12000;
+ m_uiCorruptionsCasted = 0;
+ }
+
+ void Aggro(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //Sleep_Timer
+ if (m_uiSleep_Timer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SLEEP);
+
+ m_uiSleep_Timer = 8000 + rand()%8000;
+ }
+ else
+ m_uiSleep_Timer -= uiDiff;
+
+ //NoxiousBreath_Timer
+ if (m_uiNoxiousBreath_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_NOXIOUSBREATH);
+ m_uiNoxiousBreath_Timer = 14000 + rand()%6000;
+ }
+ else
+ m_uiNoxiousBreath_Timer -= uiDiff;
+
+ //Tailsweep every 2 seconds
+ if (m_uiTailSweep_Timer <= uiDiff)
+ {
+ DoCast(me, SPELL_TAILSWEEP);
+ m_uiTailSweep_Timer = 2000;
+ }
+ else
+ m_uiTailSweep_Timer -= uiDiff;
+
+ //MarkOfNature_Timer
+ //if (m_uiMarkOfNature_Timer <= uiDiff)
+ //{
+ // DoCast(me->getVictim(), SPELL_MARKOFNATURE);
+ // m_uiMarkOfNature_Timer = 45000;
+ //}
+ //else
+ // m_uiMarkOfNature_Timer -= uiDiff;
+
+ //VolatileInfection_Timer
+ if (m_uiVolatileInfection_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_VOLATILEINFECTION);
+ m_uiVolatileInfection_Timer = 7000 + rand()%5000;
+ }
+ else
+ m_uiVolatileInfection_Timer -= uiDiff;
+
+ //CorruptionofEarth_Timer
+ //CorruptionofEarth at 75%, 50% and 25%
+ if ((me->GetHealth()*100 / me->GetMaxHealth()) <= (100-(25*m_uiCorruptionsCasted)))
+ {
+ ++m_uiCorruptionsCasted; // prevent casting twice on same hp
+ DoScriptText(SAY_CASTCORRUPTION, me);
+ DoCast(me->getVictim(), SPELL_CORRUPTIONOFEARTH);
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_emeriss(Creature* pCreature)
+{
+ return new boss_emerissAI (pCreature);
+}
+
+void AddSC_boss_emeriss()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_emeriss";
+ newscript->GetAI = &GetAI_boss_emeriss;
+ newscript->RegisterSelf();
+}
+
diff --git a/src/server/scripts/World/boss_lethon.cpp b/src/server/scripts/World/boss_lethon.cpp
new file mode 100644
index 00000000000..cc316223a2f
--- /dev/null
+++ b/src/server/scripts/World/boss_lethon.cpp
@@ -0,0 +1,25 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Lethon
+SD%Complete: 0
+SDComment: Place Holder
+SDCategory: Bosses
+EndScriptData */
+
+#include "ScriptedPch.h"
+
diff --git a/src/server/scripts/World/boss_taerar.cpp b/src/server/scripts/World/boss_taerar.cpp
new file mode 100644
index 00000000000..079f7b387a8
--- /dev/null
+++ b/src/server/scripts/World/boss_taerar.cpp
@@ -0,0 +1,263 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Taerar
+SD%Complete: 70
+SDComment: Mark of Nature & Teleport NYI. Fix the way to be banished.
+SDCategory: Bosses
+EndScriptData */
+
+#include "ScriptedPch.h"
+
+enum eEnums
+{
+ SAY_AGGRO = -1000399, //signed for 20021
+ SAY_SUMMONSHADE = -1000400, //signed for 20021
+
+ //Spells of Taerar
+ SPELL_SLEEP = 24777,
+ SPELL_NOXIOUSBREATH = 24818,
+ SPELL_TAILSWEEP = 15847,
+ // SPELL_MARKOFNATURE = 25040, // Not working
+ SPELL_ARCANEBLAST = 24857,
+ SPELL_BELLOWINGROAR = 22686,
+
+ SPELL_SUMMONSHADE_1 = 24841,
+ SPELL_SUMMONSHADE_2 = 24842,
+ SPELL_SUMMONSHADE_3 = 24843,
+
+ //Spells of Shades of Taerar
+ SPELL_POSIONCLOUD = 24840,
+ SPELL_POSIONBREATH = 20667
+};
+
+uint32 m_auiSpellSummonShade[]=
+{
+ SPELL_SUMMONSHADE_1, SPELL_SUMMONSHADE_2, SPELL_SUMMONSHADE_3
+};
+
+struct boss_taerarAI : public ScriptedAI
+{
+ boss_taerarAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 m_uiSleep_Timer;
+ uint32 m_uiNoxiousBreath_Timer;
+ uint32 m_uiTailSweep_Timer;
+ //uint32 m_uiMarkOfNature_Timer;
+ uint32 m_uiArcaneBlast_Timer;
+ uint32 m_uiBellowingRoar_Timer;
+ uint32 m_uiShades_Timer;
+ uint32 m_uiShadesSummoned;
+
+ bool m_bShades;
+
+ void Reset()
+ {
+ m_uiSleep_Timer = 15000 + rand()%5000;
+ m_uiNoxiousBreath_Timer = 8000;
+ m_uiTailSweep_Timer = 4000;
+ //m_uiMarkOfNature_Timer = 45000;
+ m_uiArcaneBlast_Timer = 12000;
+ m_uiBellowingRoar_Timer = 30000;
+ m_uiShades_Timer = 60000; //The time that Taerar is banished
+ m_uiShadesSummoned = 0;
+
+ m_bShades = false;
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ pSummoned->AI()->AttackStart(pTarget);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_bShades && m_uiShades_Timer <= uiDiff)
+ {
+ //Become unbanished again
+ me->setFaction(14);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_bShades = false;
+ }
+ else if (m_bShades)
+ {
+ m_uiShades_Timer -= uiDiff;
+ //Do nothing while banished
+ return;
+ }
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //Sleep_Timer
+ if (m_uiSleep_Timer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SLEEP);
+
+ m_uiSleep_Timer = 8000 + rand()%7000;
+ }
+ else
+ m_uiSleep_Timer -= uiDiff;
+
+ //NoxiousBreath_Timer
+ if (m_uiNoxiousBreath_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_NOXIOUSBREATH);
+ m_uiNoxiousBreath_Timer = 14000 + rand()%6000;
+ }
+ else
+ m_uiNoxiousBreath_Timer -= uiDiff;
+
+ //Tailsweep every 2 seconds
+ if (m_uiTailSweep_Timer <= uiDiff)
+ {
+ DoCast(me, SPELL_TAILSWEEP);
+ m_uiTailSweep_Timer = 2000;
+ }
+ else
+ m_uiTailSweep_Timer -= uiDiff;
+
+ //MarkOfNature_Timer
+ //if (m_uiMarkOfNature_Timer <= uiDiff)
+ //{
+ // DoCast(me->getVictim(), SPELL_MARKOFNATURE);
+ // m_uiMarkOfNature_Timer = 45000;
+ //}
+ //else
+ // m_uiMarkOfNature_Timer -= uiDiff;
+
+ //ArcaneBlast_Timer
+ if (m_uiArcaneBlast_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_ARCANEBLAST);
+ m_uiArcaneBlast_Timer = 7000 + rand()%5000;
+ }
+ else
+ m_uiArcaneBlast_Timer -= uiDiff;
+
+ //BellowingRoar_Timer
+ if (m_uiBellowingRoar_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_BELLOWINGROAR);
+ m_uiBellowingRoar_Timer = 20000 + rand()%10000;
+ }
+ else
+ m_uiBellowingRoar_Timer -= uiDiff;
+
+ //Summon 3 Shades at 75%, 50% and 25% (if bShades is true we already left in line 117, no need to check here again)
+ if (!m_bShades && (me->GetHealth()*100 / me->GetMaxHealth()) <= (100-(25*m_uiShadesSummoned)))
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ //Inturrupt any spell casting
+ me->InterruptNonMeleeSpells(false);
+
+ //horrible workaround, need to fix
+ me->setFaction(35);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ DoScriptText(SAY_SUMMONSHADE, me);
+
+ int iSize = sizeof(m_auiSpellSummonShade) / sizeof(uint32);
+
+ for (int i = 0; i < iSize; ++i)
+ DoCast(pTarget, m_auiSpellSummonShade[i], true);
+
+ ++m_uiShadesSummoned; // prevent casting twice at same health
+ m_bShades = true;
+ }
+ m_uiShades_Timer = 60000;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+// Shades of Taerar Script
+struct boss_shadeoftaerarAI : public ScriptedAI
+{
+ boss_shadeoftaerarAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 m_uiPoisonCloud_Timer;
+ uint32 m_uiPosionBreath_Timer;
+
+ void Reset()
+ {
+ m_uiPoisonCloud_Timer = 8000;
+ m_uiPosionBreath_Timer = 12000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ //PoisonCloud_Timer
+ if (m_uiPoisonCloud_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_POSIONCLOUD);
+ m_uiPoisonCloud_Timer = 30000;
+ }
+ else
+ m_uiPoisonCloud_Timer -= uiDiff;
+
+ //PosionBreath_Timer
+ if (m_uiPosionBreath_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_POSIONBREATH);
+ m_uiPosionBreath_Timer = 12000;
+ }
+ else
+ m_uiPosionBreath_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_taerar(Creature* pCreature)
+{
+ return new boss_taerarAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_shadeoftaerar(Creature* pCreature)
+{
+ return new boss_shadeoftaerarAI (pCreature);
+}
+
+void AddSC_boss_taerar()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_taerar";
+ newscript->GetAI = &GetAI_boss_taerar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_shade_of_taerar";
+ newscript->GetAI = &GetAI_boss_shadeoftaerar;
+ newscript->RegisterSelf();
+}
+
diff --git a/src/server/scripts/World/boss_ysondre.cpp b/src/server/scripts/World/boss_ysondre.cpp
new file mode 100644
index 00000000000..50b8f724e68
--- /dev/null
+++ b/src/server/scripts/World/boss_ysondre.cpp
@@ -0,0 +1,203 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Ysondre
+SD%Complete: 90
+SDComment: Mark of Nature & Teleport missing
+SDCategory: Bosses
+EndScriptData */
+
+#include "ScriptedPch.h"
+
+enum eEnums
+{
+ SAY_AGGRO = -1000360, //signed for 17969
+ SAY_SUMMONDRUIDS = -1000361, //signed for 17969
+
+ SPELL_SLEEP = 24777,
+ SPELL_NOXIOUSBREATH = 24818,
+ SPELL_TAILSWEEP = 15847,
+ //SPELL_MARKOFNATURE = 25040, // Not working
+ SPELL_LIGHTNINGWAVE = 24819,
+ SPELL_SUMMONDRUIDS = 24795,
+
+ SPELL_SUMMON_PLAYER = 24776,
+
+ //druid spells
+ SPELL_MOONFIRE = 21669
+};
+
+// Ysondre script
+struct boss_ysondreAI : public ScriptedAI
+{
+ boss_ysondreAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 m_uiSleep_Timer;
+ uint32 m_uiNoxiousBreath_Timer;
+ uint32 m_uiTailSweep_Timer;
+ //uint32 m_uiMarkOfNature_Timer;
+ uint32 m_uiLightningWave_Timer;
+ uint32 m_uiSummonDruidModifier;
+
+ void Reset()
+ {
+ m_uiSleep_Timer = 15000 + rand()%5000;
+ m_uiNoxiousBreath_Timer = 8000;
+ m_uiTailSweep_Timer = 4000;
+ //m_uiMarkOfNature_Timer = 45000;
+ m_uiLightningWave_Timer = 12000;
+ m_uiSummonDruidModifier = 0;
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ pSummoned->AI()->AttackStart(pTarget);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ //Sleep_Timer
+ if (m_uiSleep_Timer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SLEEP);
+
+ m_uiSleep_Timer = 8000 + rand()%7000;
+ }
+ else
+ m_uiSleep_Timer -= uiDiff;
+
+ //NoxiousBreath_Timer
+ if (m_uiNoxiousBreath_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_NOXIOUSBREATH);
+ m_uiNoxiousBreath_Timer = 14000 + rand()%6000;
+ }
+ else
+ m_uiNoxiousBreath_Timer -= uiDiff;
+
+ //Tailsweep every 2 seconds
+ if (m_uiTailSweep_Timer <= uiDiff)
+ {
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_TAILSWEEP);
+
+ m_uiTailSweep_Timer = 2000;
+ }
+ else
+ m_uiTailSweep_Timer -= uiDiff;
+
+ //MarkOfNature_Timer
+ //if (m_uiMarkOfNature_Timer <= uiDiff)
+ //{
+ // DoCast(me->getVictim(), SPELL_MARKOFNATURE);
+ // m_uiMarkOfNature_Timer = 45000;
+ //}
+ //else
+ // m_uiMarkOfNature_Timer -= uiDiff;
+
+ //LightningWave_Timer
+ if (m_uiLightningWave_Timer <= uiDiff)
+ {
+ //Cast LIGHTNINGWAVE on a Random target
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_LIGHTNINGWAVE);
+
+ m_uiLightningWave_Timer = 7000 + rand()%5000;
+ }
+ else
+ m_uiLightningWave_Timer -= uiDiff;
+
+ //Summon Druids
+ if ((me->GetHealth()*100 / me->GetMaxHealth()) <= (100-(25*m_uiSummonDruidModifier)))
+ {
+ DoScriptText(SAY_SUMMONDRUIDS, me);
+
+ for (int i = 0; i < 10; ++i)
+ DoCast(me, SPELL_SUMMONDRUIDS, true);
+
+ ++m_uiSummonDruidModifier;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+// Summoned druid script
+struct mob_dementeddruidsAI : public ScriptedAI
+{
+ mob_dementeddruidsAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 m_uiMoonFire_Timer;
+
+ void Reset()
+ {
+ m_uiMoonFire_Timer = 3000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ //MoonFire_Timer
+ if (m_uiMoonFire_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_MOONFIRE);
+ m_uiMoonFire_Timer = 5000;
+ }
+ else
+ m_uiMoonFire_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_ysondre(Creature* pCreature)
+{
+ return new boss_ysondreAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_dementeddruids(Creature* pCreature)
+{
+ return new mob_dementeddruidsAI (pCreature);
+}
+
+void AddSC_boss_ysondre()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_ysondre";
+ newscript->GetAI = &GetAI_boss_ysondre;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_dementeddruids";
+ newscript->GetAI = &GetAI_mob_dementeddruids;
+ newscript->RegisterSelf();
+}
+
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
new file mode 100644
index 00000000000..6f06ac78fd7
--- /dev/null
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -0,0 +1,1182 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>>
+* Copyright (C) 2006 - 20010 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: GO_Scripts
+SD%Complete: 100
+SDComment: Quest support: 4285,4287,4288(crystal pylons), 4296, 6481, 10990, 10991, 10992, Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089,12843,12982, 2936. Soulwell
+SDCategory: Game Objects
+EndScriptData */
+
+/* ContentData
+go_cat_figurine (the "trap" version of GO, two different exist)
+go_northern_crystal_pylon
+go_eastern_crystal_pylon
+go_western_crystal_pylon
+go_barov_journal
+go_ethereum_prison
+go_ethereum_stasis
+go_sacred_fire_of_life
+go_shrine_of_the_birds
+go_southfury_moonstone
+go_field_repair_bot_74A
+go_orb_of_command
+go_resonite_cask
+go_tablet_of_madness
+go_tablet_of_the_seven
+go_tele_to_dalaran_crystal
+go_tele_to_violet_stand
+go_rusty_cage
+go_scourge_cage
+go_jotunheim_cage
+go_table_theka
+go_soulwell
+go_bashir_crystalforge
+EndContentData */
+
+#include "ScriptedPch.h"
+
+/*######
+## go_cat_figurine
+######*/
+
+enum eCatFigurine
+{
+ SPELL_SUMMON_GHOST_SABER = 5968,
+};
+
+bool GOHello_go_cat_figurine(Player *pPlayer, GameObject * /*pGO*/)
+{
+ pPlayer->CastSpell(pPlayer,SPELL_SUMMON_GHOST_SABER,true);
+ return false;
+}
+
+/*######
+## go_crystal_pylons (3x)
+######*/
+
+bool GOHello_go_northern_crystal_pylon(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
+ {
+ pPlayer->PrepareQuestMenu(pGO->GetGUID());
+ pPlayer->SendPreparedQuest(pGO->GetGUID());
+ }
+
+ if (pPlayer->GetQuestStatus(4285) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->AreaExploredOrEventHappens(4285);
+
+ return true;
+}
+
+bool GOHello_go_eastern_crystal_pylon(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
+ {
+ pPlayer->PrepareQuestMenu(pGO->GetGUID());
+ pPlayer->SendPreparedQuest(pGO->GetGUID());
+ }
+
+ if (pPlayer->GetQuestStatus(4287) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->AreaExploredOrEventHappens(4287);
+
+ return true;
+}
+
+bool GOHello_go_western_crystal_pylon(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
+ {
+ pPlayer->PrepareQuestMenu(pGO->GetGUID());
+ pPlayer->SendPreparedQuest(pGO->GetGUID());
+ }
+
+ if (pPlayer->GetQuestStatus(4288) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->AreaExploredOrEventHappens(4288);
+
+ return true;
+}
+
+/*######
+## go_barov_journal
+######*/
+
+bool GOHello_go_barov_journal(Player *pPlayer, GameObject * /*pGO*/)
+{
+ if (pPlayer->HasSkill(SKILL_TAILORING) && pPlayer->GetBaseSkillValue(SKILL_TAILORING) >= 280 && !pPlayer->HasSpell(26086))
+ {
+ pPlayer->CastSpell(pPlayer,26095,false);
+ }
+ return true;
+}
+
+/*######
+## go_field_repair_bot_74A
+######*/
+
+bool GOHello_go_field_repair_bot_74A(Player *pPlayer, GameObject * /*pGO*/)
+{
+ if (pPlayer->HasSkill(SKILL_ENGINERING) && pPlayer->GetBaseSkillValue(SKILL_ENGINERING) >= 300 && !pPlayer->HasSpell(22704))
+ {
+ pPlayer->CastSpell(pPlayer,22864,false);
+ }
+ return true;
+}
+
+/*######
+## go_gilded_brazier (Paladin First Trail quest (9678))
+######*/
+
+enum eGildedBrazier
+{
+ NPC_STILLBLADE = 17716,
+};
+
+bool GOHello_go_gilded_brazier(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
+ {
+ if (pPlayer->GetQuestStatus(9678) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (Creature* Stillblade = pPlayer->SummonCreature(NPC_STILLBLADE, 8106.11, -7542.06, 151.775, 3.02598, TEMPSUMMON_DEAD_DESPAWN, 60000))
+ Stillblade->AI()->AttackStart(pPlayer);
+ }
+ }
+ return true;
+}
+
+/*######
+## go_orb_of_command
+######*/
+
+bool GOHello_go_orb_of_command(Player *pPlayer, GameObject * /*pGO*/)
+{
+ if (pPlayer->GetQuestRewardStatus(7761))
+ pPlayer->CastSpell(pPlayer,23460,true);
+
+ return true;
+}
+
+/*######
+## go_tablet_of_madness
+######*/
+
+bool GOHello_go_tablet_of_madness(Player *pPlayer, GameObject * /*pGO*/)
+{
+ if (pPlayer->HasSkill(SKILL_ALCHEMY) && pPlayer->GetSkillValue(SKILL_ALCHEMY) >= 300 && !pPlayer->HasSpell(24266))
+ {
+ pPlayer->CastSpell(pPlayer,24267,false);
+ }
+ return true;
+}
+
+/*######
+## go_tablet_of_the_seven
+######*/
+
+//TODO: use gossip option ("Transcript the Tablet") instead, if Trinity adds support.
+bool GOHello_go_tablet_of_the_seven(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
+ return true;
+
+ if (pPlayer->GetQuestStatus(4296) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->CastSpell(pPlayer,15065,false);
+
+ return true;
+}
+
+/*#####
+## go_jump_a_tron
+######*/
+
+bool GOHello_go_jump_a_tron(Player *pPlayer, GameObject * /*pGO*/)
+{
+ if (pPlayer->GetQuestStatus(10111) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->CastSpell(pPlayer,33382,true);
+
+ return true;
+}
+
+/*######
+## go_ethereum_prison
+######*/
+
+enum eEthereumPrison
+{
+ SPELL_REP_LC = 39456,
+ SPELL_REP_SHAT = 39457,
+ SPELL_REP_CE = 39460,
+ SPELL_REP_CON = 39474,
+ SPELL_REP_KT = 39475,
+ SPELL_REP_SPOR = 39476
+};
+
+const uint32 NpcPrisonEntry[] =
+{
+ 22810, 22811, 22812, 22813, 22814, 22815, //good guys
+ 20783, 20784, 20785, 20786, 20788, 20789, 20790 //bad guys
+};
+
+bool GOHello_go_ethereum_prison(Player *pPlayer, GameObject *pGO)
+{
+ int Random = rand() % (sizeof(NpcPrisonEntry) / sizeof(uint32));
+
+ if (Creature* pCreature = pPlayer->SummonCreature(NpcPrisonEntry[Random],
+ pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), pGO->GetAngle(pPlayer),
+ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ if (!pCreature->IsHostileTo(pPlayer))
+ {
+ uint32 Spell = 0;
+
+ if (FactionTemplateEntry const* pFaction = pCreature->getFactionTemplateEntry())
+ {
+ switch(pFaction->faction)
+ {
+ case 1011: Spell = SPELL_REP_LC; break;
+ case 935: Spell = SPELL_REP_SHAT; break;
+ case 942: Spell = SPELL_REP_CE; break;
+ case 933: Spell = SPELL_REP_CON; break;
+ case 989: Spell = SPELL_REP_KT; break;
+ case 970: Spell = SPELL_REP_SPOR; break;
+ }
+
+ if (Spell)
+ pCreature->CastSpell(pPlayer, Spell, false);
+ else
+ error_log("TSCR: go_ethereum_prison summoned Creature (entry %u) but faction (%u) are not expected by script.", pCreature->GetEntry(), pCreature->getFaction());
+ }
+ }
+ }
+
+ return false;
+}
+
+/*######
+## go_ethereum_stasis
+######*/
+
+const uint32 NpcStasisEntry[] =
+{
+ 22825, 20888, 22827, 22826, 22828
+};
+
+bool GOHello_go_ethereum_stasis(Player *pPlayer, GameObject *pGO)
+{
+ int Random = rand() % (sizeof(NpcStasisEntry) / sizeof(uint32));
+
+ pPlayer->SummonCreature(NpcStasisEntry[Random],
+ pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), pGO->GetAngle(pPlayer),
+ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
+
+ return false;
+}
+
+/*######
+## go_resonite_cask
+######*/
+
+enum eResoniteCask
+{
+ NPC_GOGGEROC = 11920
+};
+
+bool GOHello_go_resonite_cask(Player * /*pPlayer*/, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
+ pGO->SummonCreature(NPC_GOGGEROC, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000);
+
+ return false;
+}
+
+/*######
+## go_sacred_fire_of_life
+######*/
+
+#define NPC_ARIKARA 10882
+
+bool GOHello_go_sacred_fire_of_life(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
+ pPlayer->SummonCreature(NPC_ARIKARA, -5008.338, -2118.894, 83.657, 0.874, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
+
+ return true;
+}
+
+/*######
+## go_shrine_of_the_birds
+######*/
+
+enum eShrineOfTheBirds
+{
+ NPC_HAWK_GUARD = 22992,
+ NPC_EAGLE_GUARD = 22993,
+ NPC_FALCON_GUARD = 22994,
+ GO_SHRINE_HAWK = 185551,
+ GO_SHRINE_EAGLE = 185547,
+ GO_SHRINE_FALCON = 185553
+};
+
+bool GOHello_go_shrine_of_the_birds(Player *pPlayer, GameObject *pGO)
+{
+ uint32 BirdEntry = 0;
+
+ float fX, fY, fZ;
+ pGO->GetClosePoint(fX, fY, fZ, pGO->GetObjectSize(), INTERACTION_DISTANCE);
+
+ switch(pGO->GetEntry())
+ {
+ case GO_SHRINE_HAWK:
+ BirdEntry = NPC_HAWK_GUARD;
+ break;
+ case GO_SHRINE_EAGLE:
+ BirdEntry = NPC_EAGLE_GUARD;
+ break;
+ case GO_SHRINE_FALCON:
+ BirdEntry = NPC_FALCON_GUARD;
+ break;
+ }
+
+ if (BirdEntry)
+ pPlayer->SummonCreature(BirdEntry, fX, fY, fZ, pGO->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
+
+ return false;
+}
+
+/*######
+## go_southfury_moonstone
+######*/
+
+enum eSouthfury
+{
+ NPC_RIZZLE = 23002,
+ SPELL_BLACKJACK = 39865, //stuns player
+ SPELL_SUMMON_RIZZLE = 39866
+
+};
+
+bool GOHello_go_southfury_moonstone(Player *pPlayer, GameObject * /*pGO*/)
+{
+ //implicitTarget=48 not implemented as of writing this code, and manual summon may be just ok for our purpose
+ //pPlayer->CastSpell(pPlayer,SPELL_SUMMON_RIZZLE,false);
+
+ if (Creature* pCreature = pPlayer->SummonCreature(NPC_RIZZLE, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0))
+ pCreature->CastSpell(pPlayer,SPELL_BLACKJACK,false);
+
+ return false;
+}
+
+/*######
+## go_tele_to_dalaran_crystal
+######*/
+
+enum eDalaranCrystal
+{
+ QUEST_LEARN_LEAVE_RETURN = 12790,
+ QUEST_TELE_CRYSTAL_FLAG = 12845
+};
+
+#define GO_TELE_TO_DALARAN_CRYSTAL_FAILED "This teleport crystal cannot be used until the teleport crystal in Dalaran has been used at least once."
+
+bool GOHello_go_tele_to_dalaran_crystal(Player *pPlayer, GameObject * /*pGO*/)
+{
+ if (pPlayer->GetQuestRewardStatus(QUEST_TELE_CRYSTAL_FLAG))
+ {
+ return false;
+ }
+ else
+ pPlayer->GetSession()->SendNotification(GO_TELE_TO_DALARAN_CRYSTAL_FAILED);
+
+ return true;
+}
+
+/*######
+## go_tele_to_violet_stand
+######*/
+
+bool GOHello_go_tele_to_violet_stand(Player *pPlayer, GameObject * /*pGO*/)
+{
+ if (pPlayer->GetQuestRewardStatus(QUEST_LEARN_LEAVE_RETURN) || pPlayer->GetQuestStatus(QUEST_LEARN_LEAVE_RETURN) == QUEST_STATUS_INCOMPLETE)
+ return false;
+
+ return true;
+}
+
+/*######
+## go_fel_crystalforge
+######*/
+
+#define GOSSIP_FEL_CRYSTALFORGE_TEXT 31000
+#define GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN 31001
+#define GOSSIP_FEL_CRYSTALFORGE_ITEM_1 "Purchase 1 Unstable Flask of the Beast for the cost of 10 Apexis Shards"
+#define GOSSIP_FEL_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Beast for the cost of 50 Apexis Shards"
+#define GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN "Use the fel crystalforge to make another purchase."
+
+enum eFelCrystalforge
+{
+ SPELL_CREATE_1_FLASK_OF_BEAST = 40964,
+ SPELL_CREATE_5_FLASK_OF_BEAST = 40965,
+};
+
+bool GOHello_go_fel_crystalforge(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) /* != GAMEOBJECT_TYPE_QUESTGIVER) */
+ pPlayer->PrepareQuestMenu(pGO->GetGUID()); /* return true*/
+
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_TEXT, pGO->GetGUID());
+
+ return true;
+}
+
+bool GOSelect_go_fel_crystalforge(Player *pPlayer, GameObject *pGO, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF:
+ pPlayer->CastSpell(pPlayer,SPELL_CREATE_1_FLASK_OF_BEAST,false);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ pPlayer->CastSpell(pPlayer,SPELL_CREATE_5_FLASK_OF_BEAST,false);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_TEXT, pGO->GetGUID());
+ break;
+ }
+ return true;
+}
+
+/*######
+## go_bashir_crystalforge
+######*/
+
+#define GOSSIP_BASHIR_CRYSTALFORGE_TEXT 31100
+#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN 31101
+#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1 "Purchase 1 Unstable Flask of the Sorcerer for the cost of 10 Apexis Shards"
+#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Sorcerer for the cost of 50 Apexis Shards"
+#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN "Use the bashir crystalforge to make another purchase."
+
+enum eBashirCrystalforge
+{
+ SPELL_CREATE_1_FLASK_OF_SORCERER = 40968,
+ SPELL_CREATE_5_FLASK_OF_SORCERER = 40970,
+};
+
+bool GOHello_go_bashir_crystalforge(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) /* != GAMEOBJECT_TYPE_QUESTGIVER) */
+ pPlayer->PrepareQuestMenu(pGO->GetGUID()); /* return true*/
+
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_TEXT, pGO->GetGUID());
+
+ return true;
+}
+
+bool GOSelect_go_bashir_crystalforge(Player *pPlayer, GameObject *pGO, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF:
+ pPlayer->CastSpell(pPlayer,SPELL_CREATE_1_FLASK_OF_SORCERER,false);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ pPlayer->CastSpell(pPlayer,SPELL_CREATE_5_FLASK_OF_SORCERER,false);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_TEXT, pGO->GetGUID());
+ break;
+ }
+ return true;
+}
+
+/*######
+## matrix_punchograph
+######*/
+
+enum eMatrixPunchograph
+{
+ ITEM_WHITE_PUNCH_CARD = 9279,
+ ITEM_YELLOW_PUNCH_CARD = 9280,
+ ITEM_BLUE_PUNCH_CARD = 9282,
+ ITEM_RED_PUNCH_CARD = 9281,
+ ITEM_PRISMATIC_PUNCH_CARD = 9316,
+ SPELL_YELLOW_PUNCH_CARD = 11512,
+ SPELL_BLUE_PUNCH_CARD = 11525,
+ SPELL_RED_PUNCH_CARD = 11528,
+ SPELL_PRISMATIC_PUNCH_CARD = 11545,
+ MATRIX_PUNCHOGRAPH_3005_A = 142345,
+ MATRIX_PUNCHOGRAPH_3005_B = 142475,
+ MATRIX_PUNCHOGRAPH_3005_C = 142476,
+ MATRIX_PUNCHOGRAPH_3005_D = 142696,
+};
+
+bool GOHello_go_matrix_punchograph(Player *pPlayer, GameObject *pGO)
+{
+ switch(pGO->GetEntry())
+ {
+ case MATRIX_PUNCHOGRAPH_3005_A:
+ if (pPlayer->HasItemCount(ITEM_WHITE_PUNCH_CARD, 1))
+ {
+ pPlayer->DestroyItemCount(ITEM_WHITE_PUNCH_CARD, 1, true);
+ pPlayer->CastSpell(pPlayer,SPELL_YELLOW_PUNCH_CARD,true);
+ }
+ break;
+ case MATRIX_PUNCHOGRAPH_3005_B:
+ if (pPlayer->HasItemCount(ITEM_YELLOW_PUNCH_CARD, 1))
+ {
+ pPlayer->DestroyItemCount(ITEM_YELLOW_PUNCH_CARD, 1, true);
+ pPlayer->CastSpell(pPlayer,SPELL_BLUE_PUNCH_CARD,true);
+ }
+ break;
+ case MATRIX_PUNCHOGRAPH_3005_C:
+ if (pPlayer->HasItemCount(ITEM_BLUE_PUNCH_CARD, 1))
+ {
+ pPlayer->DestroyItemCount(ITEM_BLUE_PUNCH_CARD, 1, true);
+ pPlayer->CastSpell(pPlayer,SPELL_RED_PUNCH_CARD,true);
+ }
+ break;
+ case MATRIX_PUNCHOGRAPH_3005_D:
+ if (pPlayer->HasItemCount(ITEM_RED_PUNCH_CARD, 1))
+ {
+ pPlayer->DestroyItemCount(ITEM_RED_PUNCH_CARD, 1, true);
+ pPlayer->CastSpell(pPlayer, SPELL_PRISMATIC_PUNCH_CARD, true);
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*######
+## go_rusty_cage
+######*/
+
+enum eRustyCage
+{
+ NPC_GOBLIN_PRISIONER = 29466
+};
+
+bool GOHello_go_rusty_cage(Player *pPlayer, GameObject *pGO)
+{
+ if (Creature *pGoblinPrisoner = pGO->FindNearestCreature(NPC_GOBLIN_PRISIONER, 5.0f, true))
+ {
+ pGO->SetGoState(GO_STATE_ACTIVE);
+ pPlayer->KilledMonsterCredit(NPC_GOBLIN_PRISIONER, pGoblinPrisoner->GetGUID());
+ pGoblinPrisoner->DisappearAndDie();
+ }
+
+ return true;
+}
+
+/*######
+## go_scourge_cage
+######*/
+
+enum eScourgeCage
+{
+ NPC_SCOURGE_PRISONER = 25610
+};
+
+bool GOHello_go_scourge_cage(Player *pPlayer, GameObject *pGO)
+{
+ if (Creature *pNearestPrisoner = pGO->FindNearestCreature(NPC_SCOURGE_PRISONER, 5.0f, true))
+ {
+ pGO->SetGoState(GO_STATE_ACTIVE);
+ pPlayer->KilledMonsterCredit(NPC_SCOURGE_PRISONER, pNearestPrisoner->GetGUID());
+ pNearestPrisoner->DisappearAndDie();
+ }
+
+ return true;
+}
+
+/*######
+## go_arcane_prison
+######*/
+
+enum eArcanePrison
+{
+ QUEST_PRISON_BREAK = 11587,
+ SPELL_ARCANE_PRISONER_KILL_CREDIT = 45456
+};
+
+bool GOHello_go_arcane_prison(Player *pPlayer, GameObject *pGO)
+{
+ if (pPlayer->GetQuestStatus(QUEST_PRISON_BREAK) == QUEST_STATUS_INCOMPLETE)
+ {
+ pGO->SummonCreature(25318, 3485.089844, 6115.7422188, 70.966812, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
+ pPlayer->CastSpell(pPlayer, SPELL_ARCANE_PRISONER_KILL_CREDIT, true);
+ return true;
+ } else
+ return false;
+}
+
+/*######
+## go_blood_filled_orb
+######*/
+
+#define NPC_ZELEMAR 17830
+
+bool GOHello_go_blood_filled_orb(Player *pPlayer, GameObject *pGO)
+{
+ if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
+ pPlayer->SummonCreature(NPC_ZELEMAR, -369.746, 166.759, -21.50, 5.235, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
+
+ return true;
+}
+
+/*######
+## go_jotunheim_cage
+######*/
+
+enum eJotunheimCage
+{
+ NPC_EBON_BLADE_PRISONER_HUMAN = 30186,
+ NPC_EBON_BLADE_PRISONER_NE = 30194,
+ NPC_EBON_BLADE_PRISONER_TROLL = 30196,
+ NPC_EBON_BLADE_PRISONER_ORC = 30195,
+
+ SPELL_SUMMON_BLADE_KNIGHT_H = 56207,
+ SPELL_SUMMON_BLADE_KNIGHT_NE = 56209,
+ SPELL_SUMMON_BLADE_KNIGHT_ORC = 56212,
+ SPELL_SUMMON_BLADE_KNIGHT_TROLL = 56214
+};
+
+bool GOHello_go_jotunheim_cage(Player* pPlayer, GameObject* pGO)
+{
+ Creature* pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_HUMAN, 5.0f, true);
+ if (!pPrisoner)
+ {
+ pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_TROLL, 5.0f, true);
+ if (!pPrisoner)
+ {
+ pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_ORC, 5.0f, true);
+ if (!pPrisoner)
+ pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_NE, 5.0f, true);
+ }
+ }
+ if (!pPrisoner || !pPrisoner->isAlive())
+ return false;
+
+ pPrisoner->DisappearAndDie();
+ pPlayer->KilledMonsterCredit(NPC_EBON_BLADE_PRISONER_HUMAN, 0);
+ switch(pPrisoner->GetEntry())
+ {
+ case NPC_EBON_BLADE_PRISONER_HUMAN:
+ pPlayer->CastSpell(pPlayer,SPELL_SUMMON_BLADE_KNIGHT_H,true);
+ break;
+ case NPC_EBON_BLADE_PRISONER_NE:
+ pPlayer->CastSpell(pPlayer,SPELL_SUMMON_BLADE_KNIGHT_NE,true);
+ break;
+ case NPC_EBON_BLADE_PRISONER_TROLL:
+ pPlayer->CastSpell(pPlayer,SPELL_SUMMON_BLADE_KNIGHT_TROLL,true);
+ break;
+ case NPC_EBON_BLADE_PRISONER_ORC:
+ pPlayer->CastSpell(pPlayer,SPELL_SUMMON_BLADE_KNIGHT_ORC,true);
+ break;
+ }
+ return true;
+}
+enum eTableTheka
+{
+ GOSSIP_TABLE_THEKA = 1653,
+
+ QUEST_SPIDER_GOLD = 2936
+};
+
+bool GOHello_go_table_theka(Player* pPlayer, GameObject* pGO)
+{
+ if (pPlayer->GetQuestStatus(QUEST_SPIDER_GOLD) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->AreaExploredOrEventHappens(QUEST_SPIDER_GOLD);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TABLE_THEKA, pGO->GetGUID());
+
+ return true;
+}
+
+/*######
+## go_inconspicuous_landmark
+######*/
+
+enum eInconspicuousLandmark
+{
+ SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB = 11462,
+ ITEM_CUERGOS_KEY = 9275,
+};
+
+bool GOHello_go_inconspicuous_landmark(Player *pPlayer, GameObject* /*pGO*/)
+{
+ if (pPlayer->HasItemCount(ITEM_CUERGOS_KEY,1))
+ return false;
+
+ pPlayer->CastSpell(pPlayer,SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB,true);
+
+ return true;
+}
+
+/*######
+## go_soulwell
+######*/
+
+bool GOHello_go_soulwell(Player *pPlayer, GameObject* pGO)
+{
+ Unit *caster = pGO->GetOwner(false);
+ if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return true;
+
+ if (!pPlayer->IsInSameRaidWith(static_cast<Player *>(caster)))
+ return true;
+
+ // Repeating this at every use is ugly and inefficient. But as long as we don't have proper
+ // GO scripting with at least On Create and On Update events, the other options are no less
+ // ugly and hacky.
+ uint32 newSpell = 0;
+ if (pGO->GetEntry() == 193169) // Soulwell for rank 2
+ {
+ if (caster->HasAura(18693)) // Improved Healthstone rank 2
+ newSpell = 58898;
+ else if (caster->HasAura(18692)) // Improved Healthstone rank 1
+ newSpell = 58896;
+ else newSpell = 58890;
+ }
+ else if (pGO->GetEntry() == 181621) // Soulwell for rank 1
+ {
+ if (caster->HasAura(18693)) // Improved Healthstone rank 2
+ newSpell = 34150;
+ else if (caster->HasAura(18692)) // Improved Healthstone rank 1
+ newSpell = 34149;
+ else newSpell = 34130;
+ }
+
+ pGO->AddUse();
+ pPlayer->CastSpell(pPlayer, newSpell, true);
+ return true;
+}
+
+/*######
+## Quest 11255: Prisoners of Wyrmskull
+## go_dragonflayer_cage
+######*/
+
+enum ePrisonersOfWyrmskull
+{
+ QUEST_PRISONERS_OF_WYRMSKULL = 11255,
+ NPC_PRISONER_PRIEST = 24086,
+ NPC_PRISONER_MAGE = 24088,
+ NPC_PRISONER_WARRIOR = 24089,
+ NPC_PRISONER_PALADIN = 24090
+};
+
+bool GOHello_go_dragonflayer_cage(Player *pPlayer, GameObject *pGO)
+{
+ if (pPlayer->GetQuestStatus(QUEST_PRISONERS_OF_WYRMSKULL) != QUEST_STATUS_INCOMPLETE)
+ return true;
+
+ Creature* pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_PRIEST, 2.0f);
+ if (!pPrisoner)
+ {
+ pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_MAGE, 2.0f);
+ if (!pPrisoner)
+ {
+ pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_WARRIOR, 2.0f);
+ if (!pPrisoner)
+ pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_PALADIN, 2.0f);
+ }
+ }
+
+ if (!pPrisoner || !pPrisoner->isAlive())
+ return true;
+
+ Quest const* qInfo = objmgr.GetQuestTemplate(QUEST_PRISONERS_OF_WYRMSKULL);
+ if (qInfo)
+ {
+ //TODO: prisoner should help player for a short period of time
+ pPlayer->KilledMonsterCredit(qInfo->ReqCreatureOrGOId[0],0);
+ pPrisoner->DisappearAndDie();
+ }
+ return true;
+}
+
+/*######
+## Quest 11560: Oh Noes, the Tadpoles!
+## go_tadpole_cage
+######*/
+
+enum eTadpoles
+{
+ QUEST_OH_NOES_THE_TADPOLES = 11560,
+ NPC_WINTERFIN_TADPOLE = 25201
+};
+
+bool GOHello_go_tadpole_cage(Player *pPlayer, GameObject *pGO)
+{
+ if (pPlayer->GetQuestStatus(QUEST_OH_NOES_THE_TADPOLES) == QUEST_STATUS_INCOMPLETE)
+ {
+ Creature *pTadpole = pGO->FindNearestCreature(NPC_WINTERFIN_TADPOLE,1.0f);
+ if (pTadpole)
+ {
+ pGO->UseDoorOrButton();
+ pTadpole->DisappearAndDie();
+ pPlayer->KilledMonsterCredit(NPC_WINTERFIN_TADPOLE,0);
+ //FIX: Summon minion tadpole
+ }
+ }
+ return true;
+}
+
+/*######
+## Quest 14096 & 14142: You've Really Done It This Time, Kul
+## go_black_cage
+######*/
+
+enum eReallyDoneItThisTime
+{
+ QUEST_ALLIANCE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL = 14096,
+ QUEST_HORDE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL = 14142,
+ NPC_CAPTIVE_ASPIRANT = 34716,
+ NPC_KUL = 34956
+};
+
+bool GOHello_go_black_cage(Player *pPlayer, GameObject *pGO)
+{
+ if ((pPlayer->GetTeamId() == TEAM_ALLIANCE && pPlayer->GetQuestStatus(QUEST_ALLIANCE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL) == QUEST_STATUS_INCOMPLETE) ||
+ (pPlayer->GetTeamId() == TEAM_HORDE && pPlayer->GetQuestStatus(QUEST_HORDE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL) == QUEST_STATUS_INCOMPLETE))
+ {
+ Creature *pPrisoner = pGO->FindNearestCreature(NPC_CAPTIVE_ASPIRANT,1.0f);
+ if (!pPrisoner)
+ pPrisoner = pGO->FindNearestCreature(NPC_KUL,1.0f);
+ if (pPrisoner)
+ {
+ pGO->UseDoorOrButton();
+ pPrisoner->DisappearAndDie();
+ pPlayer->KilledMonsterCredit(pPrisoner->GetEntry(),0);
+ }
+ }
+ return true;
+}
+
+/*######
+## go_amberpine_outhouse
+######*/
+
+#define GOSSIP_USE_OUTHOUSE "Use the outhouse."
+#define GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND "Quest item Anderhol's Slider Cider not found."
+
+enum eAmberpineOuthouse
+{
+ ITEM_ANDERHOLS_SLIDER_CIDER = 37247,
+ NPC_OUTHOUSE_BUNNY = 27326,
+ QUEST_DOING_YOUR_DUTY = 12227,
+ SPELL_INDISPOSED = 53017,
+ SPELL_INDISPOSED_III = 48341,
+ SPELL_CREATE_AMBERSEEDS = 48330,
+ GOSSIP_OUTHOUSE_INUSE = 12775,
+ GOSSIP_OUTHOUSE_VACANT = 12779
+};
+
+bool GOHello_go_amberpine_outhouse(Player *pPlayer, GameObject *pGO)
+{
+ if (pPlayer->GetQuestStatus(QUEST_DOING_YOUR_DUTY) == QUEST_STATUS_INCOMPLETE ||
+ (pPlayer->GetQuestStatus(QUEST_DOING_YOUR_DUTY) == QUEST_STATUS_COMPLETE))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_USE_OUTHOUSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_OUTHOUSE_VACANT, pGO->GetGUID());
+ return true;
+ }
+ else
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_OUTHOUSE_INUSE, pGO->GetGUID());
+ return true;
+}
+
+bool GOSelect_go_amberpine_outhouse(Player *pPlayer, GameObject *pGO, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF +1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ Creature* pTarget = GetClosestCreatureWithEntry(pPlayer, NPC_OUTHOUSE_BUNNY, 3.0f);
+ if (pTarget)
+ {
+ pTarget->AI()->SetData(1,pPlayer->getGender());
+ pGO->CastSpell(pTarget, SPELL_INDISPOSED_III);
+ }
+ pGO->CastSpell(pPlayer, SPELL_INDISPOSED);
+ if (pPlayer->HasItemCount(ITEM_ANDERHOLS_SLIDER_CIDER,1))
+ pGO->CastSpell(pPlayer, SPELL_CREATE_AMBERSEEDS);
+ return true;
+ }
+ else
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->GetSession()->SendNotification(GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND);
+ return false;
+}
+
+/*######
+## Quest 9544: The Prophecy of Akida
+######*/
+
+enum eProphecy
+{
+ QUEST_PROPHECY_OF_AKIDA = 9544,
+ NPC_STILLPINE_CAPTIVE = 17375
+};
+
+bool GOHello_go_stillpine_cage(Player *pPlayer, GameObject *pGO)
+{
+ if (pPlayer->GetQuestStatus(QUEST_PROPHECY_OF_AKIDA) == QUEST_STATUS_INCOMPLETE)
+ if (Creature *pPrisoner = pGO->FindNearestCreature(NPC_STILLPINE_CAPTIVE,1.0f))
+ {
+ pGO->UseDoorOrButton();
+ pPrisoner->DisappearAndDie();
+ pPlayer->KilledMonsterCredit(pPrisoner->GetEntry(),0);
+ }
+ return true;
+}
+
+/*######
+## Quest 1126: Hive in the Tower
+######*/
+
+enum eHives
+{
+ QUEST_HIVE_IN_THE_TOWER = 9544,
+ NPC_HIVE_AMBUSHER = 13301
+};
+
+bool GOHello_go_hive_pod(Player *pPlayer, GameObject *pGO)
+{
+ pPlayer->SendLoot(pGO->GetGUID(), LOOT_CORPSE);
+ pGO->SummonCreature(NPC_HIVE_AMBUSHER,pGO->GetPositionX()+1,pGO->GetPositionY(),pGO->GetPositionZ(),pGO->GetAngle(pPlayer),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
+ pGO->SummonCreature(NPC_HIVE_AMBUSHER,pGO->GetPositionX(),pGO->GetPositionY()+1,pGO->GetPositionZ(),pGO->GetAngle(pPlayer),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
+ return true;
+}
+
+bool GOHello_go_massive_seaforium_charge(Player* pPlayer, GameObject *pGo)
+{
+ pGo->SetLootState(GO_JUST_DEACTIVATED);
+ return true;
+}
+
+void AddSC_go_scripts()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "go_cat_figurine";
+ newscript->pGOHello = &GOHello_go_cat_figurine;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_northern_crystal_pylon";
+ newscript->pGOHello = &GOHello_go_northern_crystal_pylon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_eastern_crystal_pylon";
+ newscript->pGOHello = &GOHello_go_eastern_crystal_pylon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_western_crystal_pylon";
+ newscript->pGOHello = &GOHello_go_western_crystal_pylon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_barov_journal";
+ newscript->pGOHello = &GOHello_go_barov_journal;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_field_repair_bot_74A";
+ newscript->pGOHello = &GOHello_go_field_repair_bot_74A;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_gilded_brazier";
+ newscript->pGOHello = &GOHello_go_gilded_brazier;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_orb_of_command";
+ newscript->pGOHello = &GOHello_go_orb_of_command;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_shrine_of_the_birds";
+ newscript->pGOHello = &GOHello_go_shrine_of_the_birds;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_southfury_moonstone";
+ newscript->pGOHello = &GOHello_go_southfury_moonstone;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_tablet_of_madness";
+ newscript->pGOHello = &GOHello_go_tablet_of_madness;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_tablet_of_the_seven";
+ newscript->pGOHello = &GOHello_go_tablet_of_the_seven;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_jump_a_tron";
+ newscript->pGOHello = &GOHello_go_jump_a_tron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_ethereum_prison";
+ newscript->pGOHello = &GOHello_go_ethereum_prison;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_ethereum_stasis";
+ newscript->pGOHello = &GOHello_go_ethereum_stasis;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_resonite_cask";
+ newscript->pGOHello = &GOHello_go_resonite_cask;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_sacred_fire_of_life";
+ newscript->pGOHello = &GOHello_go_sacred_fire_of_life;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_tele_to_dalaran_crystal";
+ newscript->pGOHello = &GOHello_go_tele_to_dalaran_crystal;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_tele_to_violet_stand";
+ newscript->pGOHello = &GOHello_go_tele_to_violet_stand;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_fel_crystalforge";
+ newscript->pGOHello = &GOHello_go_fel_crystalforge;
+ newscript->pGOSelect = &GOSelect_go_fel_crystalforge;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_bashir_crystalforge";
+ newscript->pGOHello = &GOHello_go_bashir_crystalforge;
+ newscript->pGOSelect = &GOSelect_go_bashir_crystalforge;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_matrix_punchograph";
+ newscript->pGOHello = &GOHello_go_matrix_punchograph;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_rusty_cage";
+ newscript->pGOHello = &GOHello_go_rusty_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_scourge_cage";
+ newscript->pGOHello = &GOHello_go_scourge_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_arcane_prison";
+ newscript->pGOHello = &GOHello_go_arcane_prison;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_blood_filled_orb";
+ newscript->pGOHello = &GOHello_go_blood_filled_orb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_jotunheim_cage";
+ newscript->pGOHello = &GOHello_go_jotunheim_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_table_theka";
+ newscript->pGOHello = &GOHello_go_table_theka;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_inconspicuous_landmark";
+ newscript->pGOHello = &GOHello_go_inconspicuous_landmark;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_soulwell";
+ newscript->pGOHello = &GOHello_go_soulwell;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_tadpole_cage";
+ newscript->pGOHello = &GOHello_go_tadpole_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_dragonflayer_cage";
+ newscript->pGOHello = &GOHello_go_dragonflayer_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_black_cage";
+ newscript->pGOHello = &GOHello_go_black_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_stillpine_cage";
+ newscript->pGOHello = &GOHello_go_stillpine_cage;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_amberpine_outhouse";
+ newscript->pGOHello = &GOHello_go_amberpine_outhouse;
+ newscript->pGOSelect = &GOSelect_go_amberpine_outhouse;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_hive_pod";
+ newscript->pGOHello = &GOHello_go_hive_pod;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_massive_seaforium_charge";
+ newscript->pGOHello = &GOHello_go_massive_seaforium_charge;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/World/guards.cpp b/src/server/scripts/World/guards.cpp
new file mode 100644
index 00000000000..5faf9c73f7d
--- /dev/null
+++ b/src/server/scripts/World/guards.cpp
@@ -0,0 +1,227 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Guards
+SD%Complete: 100
+SDComment: All Guard gossip data, quite some npc_text-id's still missing, adding constantly as new id's are known. CombatAI should be organized better for future.
+SDCategory: Guards
+EndScriptData */
+
+/* ContentData
+guard_generic
+guard_orgrimmar
+guard_shattrath_aldor
+guard_shattrath_scryer
+guard_stormwind
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "ScriptedGuardAI.h"
+
+/*******************************************************
+ * guard_generic
+ *******************************************************/
+
+CreatureAI* GetAI_guard_generic(Creature* pCreature)
+{
+ return new guardAI (pCreature);
+}
+
+/*******************************************************
+ * guard_orgrimmar
+ *******************************************************/
+
+CreatureAI* GetAI_guard_orgrimmar(Creature* pCreature)
+{
+ return new guardAI_orgrimmar (pCreature);
+}
+
+/*******************************************************
+ * guard_shattrath_aldor
+ *******************************************************/
+
+#define SPELL_BANISHED_SHATTRATH_A 36642
+#define SPELL_BANISHED_SHATTRATH_S 36671
+#define SPELL_BANISH_TELEPORT 36643
+#define SPELL_EXILE 39533
+
+struct guard_shattrath_aldorAI : public guardAI
+{
+ guard_shattrath_aldorAI(Creature *c) : guardAI(c) {}
+
+ uint32 Exile_Timer;
+ uint32 Banish_Timer;
+ uint64 PlayerGUID;
+ bool CanTeleport;
+
+ void Reset()
+ {
+ Banish_Timer = 5000;
+ Exile_Timer = 8500;
+ PlayerGUID = 0;
+ CanTeleport = false;
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (CanTeleport)
+ {
+ if (Exile_Timer <= diff)
+ {
+ if (Unit* temp = Unit::GetUnit(*me,PlayerGUID))
+ {
+ temp->CastSpell(temp,SPELL_EXILE,true);
+ temp->CastSpell(temp,SPELL_BANISH_TELEPORT,true);
+ }
+ PlayerGUID = 0;
+ Exile_Timer = 8500;
+ CanTeleport = false;
+ } else Exile_Timer -= diff;
+ }
+ else if (Banish_Timer <= diff)
+ {
+ Unit* temp = me->getVictim();
+ if (temp && temp->GetTypeId() == TYPEID_PLAYER)
+ {
+ DoCast(temp, SPELL_BANISHED_SHATTRATH_A);
+ Banish_Timer = 9000;
+ PlayerGUID = temp->GetGUID();
+ if (PlayerGUID)
+ CanTeleport = true;
+ }
+ } else Banish_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_guard_shattrath_aldor(Creature* pCreature)
+{
+ return new guard_shattrath_aldorAI (pCreature);
+}
+
+/*******************************************************
+ * guard_shattrath_scryer
+ *******************************************************/
+
+struct guard_shattrath_scryerAI : public guardAI
+{
+ guard_shattrath_scryerAI(Creature *c) : guardAI(c) {}
+
+ uint32 Exile_Timer;
+ uint32 Banish_Timer;
+ uint64 PlayerGUID;
+ bool CanTeleport;
+
+ void Reset()
+ {
+ Banish_Timer = 5000;
+ Exile_Timer = 8500;
+ PlayerGUID = 0;
+ CanTeleport = false;
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (CanTeleport)
+ {
+ if (Exile_Timer <= diff)
+ {
+ if (Unit* temp = Unit::GetUnit(*me,PlayerGUID))
+ {
+ temp->CastSpell(temp,SPELL_EXILE,true);
+ temp->CastSpell(temp,SPELL_BANISH_TELEPORT,true);
+ }
+ PlayerGUID = 0;
+ Exile_Timer = 8500;
+ CanTeleport = false;
+ } else Exile_Timer -= diff;
+ }
+ else if (Banish_Timer <= diff)
+ {
+ Unit* temp = me->getVictim();
+ if (temp && temp->GetTypeId() == TYPEID_PLAYER)
+ {
+ DoCast(temp, SPELL_BANISHED_SHATTRATH_S);
+ Banish_Timer = 9000;
+ PlayerGUID = temp->GetGUID();
+ if (PlayerGUID)
+ CanTeleport = true;
+ }
+ } else Banish_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_guard_shattrath_scryer(Creature* pCreature)
+{
+ return new guard_shattrath_scryerAI (pCreature);
+}
+
+/*******************************************************
+ * guard_stormwind
+ *******************************************************/
+
+CreatureAI* GetAI_guard_stormwind(Creature* pCreature)
+{
+ return new guardAI_stormwind (pCreature);
+}
+
+/*******************************************************
+ * AddSC
+ *******************************************************/
+
+void AddSC_guards()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "guard_generic";
+ newscript->GetAI = &GetAI_guard_generic;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "guard_orgrimmar";
+ newscript->GetAI = &GetAI_guard_orgrimmar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "guard_shattrath_aldor";
+ newscript->GetAI = &GetAI_guard_shattrath_aldor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "guard_shattrath_scryer";
+ newscript->GetAI = &GetAI_guard_shattrath_scryer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "guard_stormwind";
+ newscript->GetAI = &GetAI_guard_stormwind;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp
new file mode 100644
index 00000000000..dbf5f3c1a84
--- /dev/null
+++ b/src/server/scripts/World/item_scripts.cpp
@@ -0,0 +1,479 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Item_Scripts
+SD%Complete: 100
+SDComment: Items for a range of different items. See content below (in script)
+SDCategory: Items
+EndScriptData */
+
+/* ContentData
+item_draenei_fishing_net(i23654) Hacklike implements chance to spawn item or creature
+item_nether_wraith_beacon(i31742) Summons creatures for quest Becoming a Spellfire Tailor (q10832)
+item_flying_machine(i34060,i34061) Engineering crafted flying machines
+item_gor_dreks_ointment(i30175) Protecting Our Own(q10488)
+item_only_for_flight Items which should only useable while flying
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "Spell.h"
+
+/*#####
+# item_only_for_flight
+#####*/
+
+enum eOnlyForFlight
+{
+ SPELL_ARCANE_CHARGES = 45072
+};
+
+bool ItemUse_item_only_for_flight(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/)
+{
+ uint32 itemId = pItem->GetEntry();
+ bool disabled = false;
+
+ //for special scripts
+ switch(itemId)
+ {
+ case 24538:
+ if (pPlayer->GetAreaId() != 3628)
+ disabled = true;
+ break;
+ case 34489:
+ if (pPlayer->GetZoneId() != 4080)
+ disabled = true;
+ break;
+ case 34475:
+ if (const SpellEntry* pSpellInfo = GetSpellStore()->LookupEntry(SPELL_ARCANE_CHARGES))
+ Spell::SendCastResult(pPlayer, pSpellInfo, 1, SPELL_FAILED_NOT_ON_GROUND);
+ break;
+ }
+
+ // allow use in flight only
+ if (pPlayer->isInFlight() && !disabled)
+ return false;
+
+ // error
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,pItem,NULL);
+ return true;
+}
+
+/*#####
+# item_draenei_fishing_net
+#####*/
+
+//This is just a hack and should be removed from here.
+//Creature/Item are in fact created before spell are sucessfully casted, without any checks at all to ensure proper/expected behavior.
+bool ItemUse_item_draenei_fishing_net(Player* pPlayer, Item* /*pItem*/, SpellCastTargets const& /*targets*/)
+{
+ //if (targets.getGOTarget() && targets.getGOTarget()->GetTypeId() == TYPEID_GAMEOBJECT &&
+ //targets.getGOTarget()->GetGOInfo()->type == GAMEOBJECT_TYPE_SPELL_FOCUS && targets.getGOTarget()->GetEntry() == 181616)
+ //{
+ if (pPlayer->GetQuestStatus(9452) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (urand(0,99) < 35)
+ {
+ Creature *Murloc = pPlayer->SummonCreature(17102, pPlayer->GetPositionX(), pPlayer->GetPositionY()+20, pPlayer->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
+ if (Murloc)
+ Murloc->AI()->AttackStart(pPlayer);
+ }
+ else
+ {
+ ItemPosCountVec dest;
+ uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 23614, 1);
+ if (msg == EQUIP_ERR_OK)
+ {
+ if (Item* item = pPlayer->StoreNewItem(dest,23614,true))
+ pPlayer->SendNewItem(item,1,false,true);
+ } else
+ pPlayer->SendEquipError(msg,NULL,NULL);
+ }
+ }
+ //}
+ return false;
+}
+
+/*#####
+# item_nether_wraith_beacon
+#####*/
+
+bool ItemUse_item_nether_wraith_beacon(Player* pPlayer, Item* /*pItem*/, SpellCastTargets const& /*targets*/)
+{
+ if (pPlayer->GetQuestStatus(10832) == QUEST_STATUS_INCOMPLETE)
+ {
+ Creature *Nether;
+ Nether = pPlayer->SummonCreature(22408, pPlayer->GetPositionX(), pPlayer->GetPositionY()+20, pPlayer->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
+ Nether = pPlayer->SummonCreature(22408, pPlayer->GetPositionX(), pPlayer->GetPositionY()-20, pPlayer->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
+ if (Nether)
+ Nether->AI()->AttackStart(pPlayer);
+ }
+ return false;
+}
+
+/*#####
+# item_flying_machine
+#####*/
+
+bool ItemUse_item_flying_machine(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/)
+{
+ uint32 itemId = pItem->GetEntry();
+ if (itemId == 34060)
+ if (pPlayer->GetBaseSkillValue(SKILL_RIDING) >= 225)
+ return false;
+
+ if (itemId == 34061)
+ if (pPlayer->GetBaseSkillValue(SKILL_RIDING) == 300)
+ return false;
+
+ debug_log("TSCR: Player attempt to use item %u, but did not meet riding requirement",itemId);
+ pPlayer->SendEquipError(EQUIP_ERR_ERR_CANT_EQUIP_SKILL,pItem,NULL);
+ return true;
+}
+
+/*#####
+# item_gor_dreks_ointment
+#####*/
+
+bool ItemUse_item_gor_dreks_ointment(Player *pPlayer, Item *pItem, SpellCastTargets const& targets)
+{
+ if (targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId() == TYPEID_UNIT &&
+ targets.getUnitTarget()->GetEntry() == 20748 && !targets.getUnitTarget()->HasAura(32578))
+ return false;
+
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,pItem,NULL);
+ return true;
+}
+
+/*#####
+# item_incendiary_explosives
+#####*/
+
+bool ItemUse_item_incendiary_explosives(Player *pPlayer, Item *pItem, SpellCastTargets const & /*targets*/)
+{
+ if (pPlayer->FindNearestCreature(26248,15) || pPlayer->FindNearestCreature(26249,15))
+ return false;
+ else
+ {
+ pPlayer->SendEquipError(EQUIP_ERR_OUT_OF_RANGE,pItem,NULL);
+ return true;
+ }
+}
+
+/*#####
+# item_mysterious_egg
+#####*/
+
+bool ItemExpire_item_mysterious_egg(Player *pPlayer, ItemPrototype const * /*pItemProto*/)
+{
+ ItemPosCountVec dest;
+ uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 39883, 1); // Cracked Egg
+ if (msg == EQUIP_ERR_OK)
+ pPlayer->StoreNewItem(dest, 39883, true, Item::GenerateItemRandomPropertyId(39883));
+
+ return true;
+}
+
+/*#####
+# item_disgusting_jar
+#####*/
+
+bool ItemExpire_item_disgusting_jar(Player *pPlayer, ItemPrototype const * /*pItemProto*/)
+{
+ ItemPosCountVec dest;
+ uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 44718, 1); // Ripe Disgusting Jar
+ if (msg == EQUIP_ERR_OK)
+ pPlayer->StoreNewItem(dest, 44718, true, Item::GenerateItemRandomPropertyId(44718));
+
+ return true;
+}
+
+/*#####
+# item_harvesters_gift
+#####*/
+#define GHOULS 28845
+bool ItemUse_item_harvesters_gift(Player* pPlayer, Item* /*pItem*/, SpellCastTargets const& /*targets*/)
+{
+ std::list<Creature*> MinionList;
+ pPlayer->GetAllMinionsByEntry(MinionList,GHOULS);
+
+ if (pPlayer->GetQuestStatus(12698) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (!MinionList.empty())
+ {
+ if (MinionList.size() < 5)
+ return false;
+ else
+ {
+ //This should be sent to the player as red text.
+ pPlayer->Say("You have created enough ghouls. Return to Gothik the Harvester at Death's Breach.",LANG_UNIVERSAL);
+ return true;
+ }
+ }
+ else
+ return false;
+ }
+ return true;
+}
+
+/*#####
+# item_pile_fake_furs
+#####*/
+
+enum ePileFakeFur
+{
+ GO_CARIBOU_TRAP_1 = 187982,
+ GO_CARIBOU_TRAP_2 = 187995,
+ GO_CARIBOU_TRAP_3 = 187996,
+ GO_CARIBOU_TRAP_4 = 187997,
+ GO_CARIBOU_TRAP_5 = 187998,
+ GO_CARIBOU_TRAP_6 = 187999,
+ GO_CARIBOU_TRAP_7 = 188000,
+ GO_CARIBOU_TRAP_8 = 188001,
+ GO_CARIBOU_TRAP_9 = 188002,
+ GO_CARIBOU_TRAP_10 = 188003,
+ GO_CARIBOU_TRAP_11 = 188004,
+ GO_CARIBOU_TRAP_12 = 188005,
+ GO_CARIBOU_TRAP_13 = 188006,
+ GO_CARIBOU_TRAP_14 = 188007,
+ GO_CARIBOU_TRAP_15 = 188008,
+ GO_HIGH_QUALITY_FUR = 187983,
+ NPC_NESINGWARY_TRAPPER = 25835
+};
+
+#define CaribouTrapsNum 15
+const uint32 CaribouTraps[CaribouTrapsNum] =
+{
+ GO_CARIBOU_TRAP_1, GO_CARIBOU_TRAP_2, GO_CARIBOU_TRAP_3, GO_CARIBOU_TRAP_4, GO_CARIBOU_TRAP_5,
+ GO_CARIBOU_TRAP_6, GO_CARIBOU_TRAP_7, GO_CARIBOU_TRAP_8, GO_CARIBOU_TRAP_9, GO_CARIBOU_TRAP_10,
+ GO_CARIBOU_TRAP_11, GO_CARIBOU_TRAP_12, GO_CARIBOU_TRAP_13, GO_CARIBOU_TRAP_14, GO_CARIBOU_TRAP_15,
+};
+
+
+bool ItemUse_item_pile_fake_furs(Player *pPlayer, Item * /*pItem*/, SpellCastTargets const & /*targets*/)
+{
+ GameObject *pGo = NULL;
+ for (uint8 i = 0; i < CaribouTrapsNum; ++i)
+ {
+ pGo = pPlayer->FindNearestGameObject(CaribouTraps[i], 5.0f);
+ if (pGo)
+ break;
+ }
+
+ if (!pGo)
+ return false;
+
+ if (pGo->FindNearestCreature(NPC_NESINGWARY_TRAPPER, 10.0f, true) || pGo->FindNearestCreature(NPC_NESINGWARY_TRAPPER, 10.0f, false) || pGo->FindNearestGameObject(GO_HIGH_QUALITY_FUR, 2.0f))
+ return true;
+
+ float x, y, z;
+ pGo->GetClosePoint(x, y, z, pGo->GetObjectSize() / 3, 7.0f);
+ pGo->SummonGameObject(GO_HIGH_QUALITY_FUR, pGo->GetPositionX(), pGo->GetPositionY(), pGo->GetPositionZ(), 0, 0, 0, 0, 0, 1000);
+ if (TempSummon* summon = pPlayer->SummonCreature(NPC_NESINGWARY_TRAPPER, x, y, z, pGo->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 1000))
+ {
+ summon->SetVisibility(VISIBILITY_OFF);
+ summon->SetReactState(REACT_PASSIVE);
+ summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ }
+ return false;
+}
+
+/*#####
+# item_petrov_cluster_bombs
+#####*/
+
+enum ePetrovClusterBombs
+{
+ SPELL_PETROV_BOMB = 42406,
+ AREA_ID_SHATTERED_STRAITS = 4064,
+ ZONE_ID_HOWLING = 495
+};
+
+bool ItemUse_item_petrov_cluster_bombs(Player* pPlayer, Item* pItem, const SpellCastTargets & /*pTargets*/)
+{
+ if (pPlayer->GetZoneId() != ZONE_ID_HOWLING)
+ return false;
+
+ if (!pPlayer->GetTransport() || pPlayer->GetAreaId() != AREA_ID_SHATTERED_STRAITS)
+ {
+ pPlayer->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
+
+ if (const SpellEntry* pSpellInfo = GetSpellStore()->LookupEntry(SPELL_PETROV_BOMB))
+ Spell::SendCastResult(pPlayer, pSpellInfo, 1, SPELL_FAILED_NOT_HERE);
+
+ return true;
+ }
+
+ return false;
+}
+
+/*######
+# item_dehta_trap_smasher
+# For quest 11876, Help Those That Cannot Help Themselves
+######*/
+enum eHelpThemselves
+{
+ QUEST_CANNOT_HELP_THEMSELVES = 11876,
+ NPC_TRAPPED_MAMMOTH_CALF = 25850,
+ GO_MAMMOTH_TRAP_1 = 188022,
+ GO_MAMMOTH_TRAP_2 = 188024,
+ GO_MAMMOTH_TRAP_3 = 188025,
+ GO_MAMMOTH_TRAP_4 = 188026,
+ GO_MAMMOTH_TRAP_5 = 188027,
+ GO_MAMMOTH_TRAP_6 = 188028,
+ GO_MAMMOTH_TRAP_7 = 188029,
+ GO_MAMMOTH_TRAP_8 = 188030,
+ GO_MAMMOTH_TRAP_9 = 188031,
+ GO_MAMMOTH_TRAP_10 = 188032,
+ GO_MAMMOTH_TRAP_11 = 188033,
+ GO_MAMMOTH_TRAP_12 = 188034,
+ GO_MAMMOTH_TRAP_13 = 188035,
+ GO_MAMMOTH_TRAP_14 = 188036,
+ GO_MAMMOTH_TRAP_15 = 188037,
+ GO_MAMMOTH_TRAP_16 = 188038,
+ GO_MAMMOTH_TRAP_17 = 188039,
+ GO_MAMMOTH_TRAP_18 = 188040,
+ GO_MAMMOTH_TRAP_19 = 188041,
+ GO_MAMMOTH_TRAP_20 = 188042,
+ GO_MAMMOTH_TRAP_21 = 188043,
+ GO_MAMMOTH_TRAP_22 = 188044,
+};
+
+#define MammothTrapsNum 22
+const uint32 MammothTraps[MammothTrapsNum] =
+{
+ GO_MAMMOTH_TRAP_1, GO_MAMMOTH_TRAP_2, GO_MAMMOTH_TRAP_3, GO_MAMMOTH_TRAP_4, GO_MAMMOTH_TRAP_5,
+ GO_MAMMOTH_TRAP_6, GO_MAMMOTH_TRAP_7, GO_MAMMOTH_TRAP_8, GO_MAMMOTH_TRAP_9, GO_MAMMOTH_TRAP_10,
+ GO_MAMMOTH_TRAP_11, GO_MAMMOTH_TRAP_12, GO_MAMMOTH_TRAP_13, GO_MAMMOTH_TRAP_14, GO_MAMMOTH_TRAP_15,
+ GO_MAMMOTH_TRAP_16, GO_MAMMOTH_TRAP_17, GO_MAMMOTH_TRAP_18, GO_MAMMOTH_TRAP_19, GO_MAMMOTH_TRAP_20,
+ GO_MAMMOTH_TRAP_21, GO_MAMMOTH_TRAP_22
+};
+
+bool ItemUse_item_dehta_trap_smasher(Player* pPlayer, Item* /*pItem*/, const SpellCastTargets & /*pTargets*/)
+{
+ if (pPlayer->GetQuestStatus(QUEST_CANNOT_HELP_THEMSELVES) != QUEST_STATUS_INCOMPLETE)
+ return false;
+
+ Creature* pMammoth;
+ pMammoth = pPlayer->FindNearestCreature(NPC_TRAPPED_MAMMOTH_CALF,5.0f);
+ if (!pMammoth)
+ return false;
+
+ GameObject* pTrap;
+ for (uint8 i = 0; i < MammothTrapsNum; ++i)
+ {
+ pTrap = pPlayer->FindNearestGameObject(MammothTraps[i],11.0f);
+ if (pTrap)
+ {
+ pMammoth->AI()->DoAction(1);
+ pTrap->SetGoState(GO_STATE_READY);
+ pPlayer->KilledMonsterCredit(NPC_TRAPPED_MAMMOTH_CALF,0);
+ return true;
+ }
+ }
+ return false;
+}
+
+enum TheEmissary
+{
+ QUEST_THE_EMISSARY = 11626,
+ NPC_LEVIROTH = 26452
+};
+
+bool ItemUse_item_Trident_of_Nazjan(Player* pPlayer, Item* pItem, const SpellCastTargets & /*pTargets*/)
+{
+ if (pPlayer->GetQuestStatus(QUEST_THE_EMISSARY) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (Creature* pLeviroth = pPlayer->FindNearestCreature(NPC_LEVIROTH, 10.0f)) // spell range
+ {
+ pLeviroth->AI()->AttackStart(pPlayer);
+ return false;
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_OUT_OF_RANGE, pItem, NULL);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW ,pItem, NULL);
+ return true;
+}
+
+void AddSC_item_scripts()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "item_only_for_flight";
+ newscript->pItemUse = &ItemUse_item_only_for_flight;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_draenei_fishing_net";
+ newscript->pItemUse = &ItemUse_item_draenei_fishing_net;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_nether_wraith_beacon";
+ newscript->pItemUse = &ItemUse_item_nether_wraith_beacon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_flying_machine";
+ newscript->pItemUse = &ItemUse_item_flying_machine;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_gor_dreks_ointment";
+ newscript->pItemUse = &ItemUse_item_gor_dreks_ointment;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_incendiary_explosives";
+ newscript->pItemUse = &ItemUse_item_incendiary_explosives;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_mysterious_egg";
+ newscript->pItemExpire = &ItemExpire_item_mysterious_egg;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_disgusting_jar";
+ newscript->pItemExpire = &ItemExpire_item_disgusting_jar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_harvesters_gift";
+ newscript->pItemUse = &ItemUse_item_harvesters_gift;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_pile_fake_furs";
+ newscript->pItemUse = &ItemUse_item_pile_fake_furs;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_petrov_cluster_bombs";
+ newscript->pItemUse = &ItemUse_item_petrov_cluster_bombs;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_dehta_trap_smasher";
+ newscript->pItemUse = &ItemUse_item_dehta_trap_smasher;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "item_Trident_of_Nazjan";
+ newscript->pItemUse = &ItemUse_item_Trident_of_Nazjan;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/World/mob_generic_creature.cpp b/src/server/scripts/World/mob_generic_creature.cpp
new file mode 100644
index 00000000000..3ab515d8206
--- /dev/null
+++ b/src/server/scripts/World/mob_generic_creature.cpp
@@ -0,0 +1,228 @@
+
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+* 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: Generic_Creature
+SD%Complete: 80
+SDComment: Should be replaced with core based AI
+SDCategory: Creatures
+EndScriptData */
+
+#include "ScriptedPch.h"
+
+#define GENERIC_CREATURE_COOLDOWN 5000
+
+struct generic_creatureAI : public ScriptedAI
+{
+ generic_creatureAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 GlobalCooldown; //This variable acts like the global cooldown that players have (1.5 seconds)
+ uint32 BuffTimer; //This variable keeps track of buffs
+ bool IsSelfRooted;
+
+ void Reset()
+ {
+ GlobalCooldown = 0;
+ BuffTimer = 0; //Rebuff as soon as we can
+ IsSelfRooted = false;
+ }
+
+ void EnterCombat(Unit *who)
+ {
+ if (!me->IsWithinMeleeRange(who))
+ {
+ IsSelfRooted = true;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Always decrease our global cooldown first
+ if (GlobalCooldown > diff)
+ GlobalCooldown -= diff;
+ else GlobalCooldown = 0;
+
+ //Buff timer (only buff when we are alive and not in combat
+ if (!me->isInCombat() && me->isAlive())
+ if (BuffTimer <= diff)
+ {
+ //Find a spell that targets friendly and applies an aura (these are generally buffs)
+ SpellEntry const *info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA);
+
+ if (info && !GlobalCooldown)
+ {
+ //Cast the buff spell
+ DoCastSpell(me, info);
+
+ //Set our global cooldown
+ GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
+
+ //Set our timer to 10 minutes before rebuff
+ BuffTimer = 600000;
+ }//Try agian in 30 seconds
+ else BuffTimer = 30000;
+ } else BuffTimer -= diff;
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //If we are within range melee the target
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ //Make sure our attack is ready and we arn't currently casting
+ if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false))
+ {
+ bool Healing = false;
+ SpellEntry const *info = NULL;
+
+ //Select a healing spell if less than 30% hp
+ if (me->GetHealth()*100 / me->GetMaxHealth() < 30)
+ info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
+
+ //No healing spell available, select a hostile spell
+ if (info) Healing = true;
+ else info = SelectSpell(me->getVictim(), 0, 0, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE);
+
+ //50% chance if elite or higher, 20% chance if not, to replace our white hit with a spell
+ if (info && (rand() % (me->GetCreatureInfo()->rank > 1 ? 2 : 5) == 0) && !GlobalCooldown)
+ {
+ //Cast the spell
+ if (Healing)DoCastSpell(me, info);
+ else DoCastSpell(me->getVictim(), info);
+
+ //Set our global cooldown
+ GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
+ }
+ else me->AttackerStateUpdate(me->getVictim());
+
+ me->resetAttackTimer();
+ }
+ }
+ else
+ {
+ //Only run this code if we arn't already casting
+ if (!me->IsNonMeleeSpellCasted(false))
+ {
+ bool Healing = false;
+ SpellEntry const *info = NULL;
+
+ //Select a healing spell if less than 30% hp ONLY 33% of the time
+ if (me->GetHealth()*100 / me->GetMaxHealth() < 30 && rand() % 3 == 0)
+ info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
+
+ //No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
+ if (info) Healing = true;
+ else info = SelectSpell(me->getVictim(), 0, 0, SELECT_TARGET_ANY_ENEMY, 0, 0, NOMINAL_MELEE_RANGE, 0, SELECT_EFFECT_DONTCARE);
+
+ //Found a spell, check if we arn't on cooldown
+ if (info && !GlobalCooldown)
+ {
+ //If we are currently moving stop us and set the movement generator
+ if (!IsSelfRooted)
+ {
+ IsSelfRooted = true;
+ }
+
+ //Cast spell
+ if (Healing) DoCastSpell(me,info);
+ else DoCastSpell(me->getVictim(),info);
+
+ //Set our global cooldown
+ GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
+
+ }//If no spells available and we arn't moving run to target
+ else if (IsSelfRooted)
+ {
+ //Cancel our current spell and then allow movement agian
+ me->InterruptNonMeleeSpells(false);
+ IsSelfRooted = false;
+ }
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_generic_creature(Creature* pCreature)
+{
+ return new generic_creatureAI (pCreature);
+}
+
+struct trigger_periodicAI : public NullCreatureAI
+{
+ trigger_periodicAI(Creature* c) : NullCreatureAI(c)
+ {
+ spell = me->m_spells[0] ? GetSpellStore()->LookupEntry(me->m_spells[0]) : NULL;
+ interval = me->GetAttackTime(BASE_ATTACK);
+ timer = interval;
+ }
+
+ uint32 timer, interval;
+ const SpellEntry * spell;
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (timer <= diff)
+ {
+ if (spell)
+ me->CastSpell(me, spell, true);
+ timer = interval;
+ }
+ else
+ timer -= diff;
+ }
+};
+
+struct trigger_deathAI : public NullCreatureAI
+{
+ trigger_deathAI(Creature* c) : NullCreatureAI(c) {}
+ void JustDied(Unit *killer)
+ {
+ if (me->m_spells[0])
+ me->CastSpell(killer, me->m_spells[0], true);
+ }
+};
+
+CreatureAI* GetAI_trigger_periodic(Creature* pCreature)
+{
+ return new trigger_periodicAI (pCreature);
+}
+
+CreatureAI* GetAI_trigger_death(Creature* pCreature)
+{
+ return new trigger_deathAI (pCreature);
+}
+
+void AddSC_generic_creature()
+{
+ Script *newscript;
+ /*newscript = new Script;
+ newscript->Name = "generic_creature";
+ newscript->GetAI = &GetAI_generic_creature;
+ newscript->RegisterSelf();*/
+
+ newscript = new Script;
+ newscript->Name = "trigger_periodic";
+ newscript->GetAI = &GetAI_trigger_periodic;
+ newscript->RegisterSelf();
+
+ /*newscript = new Script;
+ newscript->Name = "trigger_death";
+ newscript->GetAI = &GetAI_trigger_death;
+ newscript->RegisterSelf();*/
+}
+
diff --git a/src/server/scripts/World/npc_innkeeper.cpp b/src/server/scripts/World/npc_innkeeper.cpp
new file mode 100644
index 00000000000..9bda7a53516
--- /dev/null
+++ b/src/server/scripts/World/npc_innkeeper.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Npc_Innkeeper
+SDAuthor: WarHead
+SD%Complete: 99%
+SDComment: Complete
+SDCategory: NPCs
+EndScriptData */
+
+#include "ScriptedPch.h"
+
+#define HALLOWEEN_EVENTID 12
+#define SPELL_TRICK_OR_TREATED 24755
+#define SPELL_TREAT 24715
+
+#define LOCALE_TRICK_OR_TREAT_0 "Trick or Treat!"
+#define LOCALE_TRICK_OR_TREAT_2 "Des bonbons ou des blagues!"
+#define LOCALE_TRICK_OR_TREAT_3 "Süßes oder Saures!"
+#define LOCALE_TRICK_OR_TREAT_6 "¡Truco o trato!"
+
+#define LOCALE_INNKEEPER_0 "Make this inn my home."
+#define LOCALE_INNKEEPER_3 "Ich möchte dieses Gasthaus zu meinem Heimatort machen."
+
+bool GossipHello_npc_innkeeper(Player *pPlayer, Creature *pCreature)
+{
+ if (IsEventActive(HALLOWEEN_EVENTID) && !pPlayer->HasAura(SPELL_TRICK_OR_TREATED))
+ {
+ char* localizedEntry;
+ switch (pPlayer->GetSession()->GetSessionDbcLocale())
+ {
+ case LOCALE_frFR: localizedEntry = LOCALE_TRICK_OR_TREAT_2; break;
+ case LOCALE_deDE: localizedEntry = LOCALE_TRICK_OR_TREAT_3; break;
+ case LOCALE_esES: localizedEntry = LOCALE_TRICK_OR_TREAT_6; break;
+ case LOCALE_enUS: default: localizedEntry = LOCALE_TRICK_OR_TREAT_0;
+ }
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, localizedEntry, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+HALLOWEEN_EVENTID);
+ }
+
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pCreature->isVendor())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+
+ if (pCreature->isInnkeeper())
+ {
+ char* localizedEntry;
+ switch (pPlayer->GetSession()->GetSessionDbcLocale())
+ {
+ case LOCALE_deDE: localizedEntry = LOCALE_INNKEEPER_3; break;
+ case LOCALE_enUS: default: localizedEntry = LOCALE_INNKEEPER_0;
+ }
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_INTERACT_1, localizedEntry, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INN);
+ }
+
+ pPlayer->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID());
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_innkeeper(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+HALLOWEEN_EVENTID && IsEventActive(HALLOWEEN_EVENTID) && !pPlayer->HasAura(SPELL_TRICK_OR_TREATED))
+ {
+ pPlayer->CastSpell(pPlayer, SPELL_TRICK_OR_TREATED, true);
+
+ if (urand(0, 1))
+ pPlayer->CastSpell(pPlayer, SPELL_TREAT, true);
+ else
+ {
+ uint32 trickspell = 0;
+ switch (urand(0, 13))
+ {
+ case 0: trickspell = 24753; break; // cannot cast, random 30sec
+ case 1: trickspell = 24713; break; // lepper gnome costume
+ case 2: trickspell = 24735; break; // male ghost costume
+ case 3: trickspell = 24736; break; // female ghostcostume
+ case 4: trickspell = 24710; break; // male ninja costume
+ case 5: trickspell = 24711; break; // female ninja costume
+ case 6: trickspell = 24708; break; // male pirate costume
+ case 7: trickspell = 24709; break; // female pirate costume
+ case 8: trickspell = 24723; break; // skeleton costume
+ case 9: trickspell = 24753; break; // Trick
+ case 10: trickspell = 24924; break; // Hallow's End Candy
+ case 11: trickspell = 24925; break; // Hallow's End Candy
+ case 12: trickspell = 24926; break; // Hallow's End Candy
+ case 13: trickspell = 24927; break; // Hallow's End Candy
+ }
+ pPlayer->CastSpell(pPlayer, trickspell, true);
+ }
+ pPlayer->CLOSE_GOSSIP_MENU();
+ return true;
+ }
+
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_TRADE: pPlayer->SEND_VENDORLIST(pCreature->GetGUID()); break;
+ case GOSSIP_ACTION_INN: pPlayer->SetBindPoint(pCreature->GetGUID()); break;
+ }
+ return true;
+}
+
+void AddSC_npc_innkeeper()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "npc_innkeeper";
+ newscript->pGossipHello = &GossipHello_npc_innkeeper;
+ newscript->pGossipSelect = &GossipSelect_npc_innkeeper;
+ newscript->RegisterSelf();
+}
+
diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp
new file mode 100644
index 00000000000..ed22225d0d4
--- /dev/null
+++ b/src/server/scripts/World/npc_professions.cpp
@@ -0,0 +1,1342 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Npc_Professions
+SD%Complete: 80
+SDComment: Provides learn/unlearn/relearn-options for professions. Not supported: Unlearn engineering, re-learn engineering, re-learn leatherworking.
+SDCategory: NPCs
+EndScriptData */
+
+#include "ScriptedPch.h"
+
+/*
+A few notes for future developement:
+- A full implementation of gossip for GO's is required. They must have the same scripting capabilities as creatures. Basically,
+there is no difference here (except that default text is chosen with `gameobject_template`.`data3` (for GO type2, different dataN for a few others)
+- It's possible blacksmithing still require some tweaks and adjustments due to the way we _have_ to use reputation.
+*/
+
+/*
+-- UPDATE `gameobject_template` SET `ScriptName` = 'go_soothsaying_for_dummies' WHERE `entry` = 177226;
+*/
+
+/*###
+# to be removed from here (->ncp_text). This is data for database projects.
+###*/
+#define TALK_MUST_UNLEARN_WEAPON "You must forget your weapon type specialty before I can help you. Go to Everlook in Winterspring and seek help there."
+
+#define TALK_HAMMER_LEARN "Ah, a seasoned veteran you once were. I know you are capable, you merely need to ask and I shall teach you the way of the hammersmith."
+#define TALK_AXE_LEARN "Ah, a seasoned veteran you once were. I know you are capable, you merely need to ask and I shall teach you the way of the axesmith."
+#define TALK_SWORD_LEARN "Ah, a seasoned veteran you once were. I know you are capable, you merely need to ask and I shall teach you the way of the swordsmith."
+
+#define TALK_HAMMER_UNLEARN "Forgetting your Hammersmithing skill is not something to do lightly. If you choose to abandon it you will forget all recipes that require Hammersmithing to create!"
+#define TALK_AXE_UNLEARN "Forgetting your Axesmithing skill is not something to do lightly. If you choose to abandon it you will forget all recipes that require Axesmithing to create!"
+#define TALK_SWORD_UNLEARN "Forgetting your Swordsmithing skill is not something to do lightly. If you choose to abandon it you will forget all recipes that require Swordsmithing to create!"
+
+/*###
+# generic defines
+###*/
+
+#define GOSSIP_SENDER_LEARN 50
+#define GOSSIP_SENDER_UNLEARN 51
+#define GOSSIP_SENDER_CHECK 52
+
+/*###
+# gossip item and box texts
+###*/
+
+#define GOSSIP_LEARN_POTION "Please teach me how to become a Master of Potions, Lauranna"
+#define GOSSIP_UNLEARN_POTION "I wish to unlearn Potion Mastery"
+#define GOSSIP_LEARN_TRANSMUTE "Please teach me how to become a Master of Transmutations, Zarevhi"
+#define GOSSIP_UNLEARN_TRANSMUTE "I wish to unlearn Transmutation Mastery"
+#define GOSSIP_LEARN_ELIXIR "Please teach me how to become a Master of Elixirs, Lorokeem"
+#define GOSSIP_UNLEARN_ELIXIR "I wish to unlearn Elixir Mastery"
+
+#define BOX_UNLEARN_ALCHEMY_SPEC "Do you really want to unlearn your alchemy specialty and lose all associated recipes? \n Cost: "
+
+#define GOSSIP_WEAPON_LEARN "Please teach me how to become a Weaponsmith"
+#define GOSSIP_WEAPON_UNLEARN "I wish to unlearn the art of Weaponsmithing"
+#define GOSSIP_ARMOR_LEARN "Please teach me how to become a Armorsmith"
+#define GOSSIP_ARMOR_UNLEARN "I wish to unlearn the art of Armorsmithing"
+
+#define GOSSIP_UNLEARN_SMITH_SPEC "I wish to unlearn my blacksmith specialty"
+#define BOX_UNLEARN_ARMORORWEAPON "Do you really want to unlearn your blacksmith specialty and lose all associated recipes? \n Cost: "
+
+#define GOSSIP_LEARN_HAMMER "Please teach me how to become a Hammersmith, Lilith"
+#define GOSSIP_UNLEARN_HAMMER "I wish to unlearn Hammersmithing"
+#define GOSSIP_LEARN_AXE "Please teach me how to become a Axesmith, Kilram"
+#define GOSSIP_UNLEARN_AXE "I wish to unlearn Axesmithing"
+#define GOSSIP_LEARN_SWORD "Please teach me how to become a Swordsmith, Seril"
+#define GOSSIP_UNLEARN_SWORD "I wish to unlearn Swordsmithing"
+
+#define BOX_UNLEARN_WEAPON_SPEC "Do you really want to unlearn your weaponsmith specialty and lose all associated recipes? \n Cost: "
+
+#define GOSSIP_LEARN_DRAGON "I am absolutely certain that i want to learn dragonscale leatherworking"
+#define GOSSIP_UNLEARN_DRAGON "I wish to unlearn Dragonscale Leatherworking"
+#define GOSSIP_LEARN_ELEMENTAL "I am absolutely certain that i want to learn elemental leatherworking"
+#define GOSSIP_UNLEARN_ELEMENTAL "I wish to unlearn Elemental Leatherworking"
+#define GOSSIP_LEARN_TRIBAL "I am absolutely certain that i want to learn tribal leatherworking"
+#define GOSSIP_UNLEARN_TRIBAL "I wish to unlearn Tribal Leatherworking"
+
+#define BOX_UNLEARN_LEATHER_SPEC "Do you really want to unlearn your leatherworking specialty and lose all associated recipes? \n Cost: "
+
+#define GOSSIP_LEARN_SPELLFIRE "Please teach me how to become a Spellcloth tailor"
+#define GOSSIP_UNLEARN_SPELLFIRE "I wish to unlearn Spellfire Tailoring"
+#define GOSSIP_LEARN_MOONCLOTH "Please teach me how to become a Mooncloth tailor"
+#define GOSSIP_UNLEARN_MOONCLOTH "I wish to unlearn Mooncloth Tailoring"
+#define GOSSIP_LEARN_SHADOWEAVE "Please teach me how to become a Shadoweave tailor"
+#define GOSSIP_UNLEARN_SHADOWEAVE "I wish to unlearn Shadoweave Tailoring"
+
+#define BOX_UNLEARN_TAILOR_SPEC "Do you really want to unlearn your tailoring specialty and lose all associated recipes? \n Cost: "
+
+#define GOSSIP_LEARN_GOBLIN "I am absolutely certain that i want to learn Goblin engineering"
+#define GOSSIP_LEARN_GNOMISH "I am absolutely certain that i want to learn Gnomish engineering"
+
+/*###
+# spells defines
+###*/
+
+#define S_WEAPON 9787
+#define S_ARMOR 9788
+#define S_HAMMER 17040
+#define S_AXE 17041
+#define S_SWORD 17039
+
+#define S_LEARN_WEAPON 9789
+#define S_LEARN_ARMOR 9790
+#define S_LEARN_HAMMER 39099
+#define S_LEARN_AXE 39098
+#define S_LEARN_SWORD 39097
+
+#define S_UNLEARN_WEAPON 36436
+#define S_UNLEARN_ARMOR 36435
+#define S_UNLEARN_HAMMER 36441
+#define S_UNLEARN_AXE 36439
+#define S_UNLEARN_SWORD 36438
+
+#define S_REP_ARMOR 17451
+#define S_REP_WEAPON 17452
+
+#define REP_ARMOR 46
+#define REP_WEAPON 289
+#define REP_HAMMER 569
+#define REP_AXE 570
+#define REP_SWORD 571
+
+#define S_DRAGON 10656
+#define S_ELEMENTAL 10658
+#define S_TRIBAL 10660
+
+#define S_LEARN_DRAGON 10657
+#define S_LEARN_ELEMENTAL 10659
+#define S_LEARN_TRIBAL 10661
+
+#define S_UNLEARN_DRAGON 36434
+#define S_UNLEARN_ELEMENTAL 36328
+#define S_UNLEARN_TRIBAL 36433
+
+#define S_GOBLIN 20222
+#define S_GNOMISH 20219
+
+#define S_LEARN_GOBLIN 20221
+#define S_LEARN_GNOMISH 20220
+
+#define S_SPELLFIRE 26797
+#define S_MOONCLOTH 26798
+#define S_SHADOWEAVE 26801
+
+#define S_LEARN_SPELLFIRE 26796
+#define S_LEARN_MOONCLOTH 26799
+#define S_LEARN_SHADOWEAVE 26800
+
+#define S_UNLEARN_SPELLFIRE 41299
+#define S_UNLEARN_MOONCLOTH 41558
+#define S_UNLEARN_SHADOWEAVE 41559
+
+#define S_TRANSMUTE 28672
+#define S_ELIXIR 28677
+#define S_POTION 28675
+
+#define S_LEARN_TRANSMUTE 28674
+#define S_LEARN_ELIXIR 28678
+#define S_LEARN_POTION 28676
+
+#define S_UNLEARN_TRANSMUTE 41565
+#define S_UNLEARN_ELIXIR 41564
+#define S_UNLEARN_POTION 41563
+
+/*###
+# formulas to calculate unlearning cost
+###*/
+
+int32 DoLearnCost(Player* /*pPlayer*/) //tailor, alchemy
+{
+ return 200000;
+}
+
+int32 DoHighUnlearnCost(Player* /*pPlayer*/) //tailor, alchemy
+{
+ return 1500000;
+}
+
+int32 DoMedUnlearnCost(Player* pPlayer) //blacksmith, leatherwork
+{
+ uint8 level = pPlayer->getLevel();
+ if (level < 51)
+ return 250000;
+ else if (level < 66)
+ return 500000;
+ else
+ return 1000000;
+}
+
+int32 DoLowUnlearnCost(Player* pPlayer) //blacksmith
+{
+ uint8 level = pPlayer->getLevel();
+ if (level < 66)
+ return 50000;
+ else
+ return 100000;
+}
+
+/*###
+# unlearning related profession spells
+###*/
+
+bool EquippedOk(Player* pPlayer, uint32 spellId)
+{
+ SpellEntry const* spell = GetSpellStore()->LookupEntry(spellId);
+
+ if (!spell)
+ return false;
+
+ for (uint8 i = 0; i < 3; ++i)
+ {
+ uint32 reqSpell = spell->EffectTriggerSpell[i];
+ if (!reqSpell)
+ continue;
+
+ Item* pItem;
+ for (uint8 j = EQUIPMENT_SLOT_START; j < EQUIPMENT_SLOT_END; ++j)
+ {
+ pItem = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, j);
+ if (pItem)
+ if (pItem->GetProto()->RequiredSpell == reqSpell)
+ {
+ //player has item equipped that require specialty. Not allow to unlearn, player has to unequip first
+ debug_log("TSCR: player attempt to unlearn spell %u, but item %u is equipped.",reqSpell,pItem->GetProto()->ItemId);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void ProfessionUnlearnSpells(Player* pPlayer, uint32 type)
+{
+ switch (type)
+ {
+ case 36436: // S_UNLEARN_WEAPON
+ pPlayer->removeSpell(36125); // Light Earthforged Blade
+ pPlayer->removeSpell(36128); // Light Emberforged Hammer
+ pPlayer->removeSpell(36126); // Light Skyforged Axe
+ break;
+ case 36435: // S_UNLEARN_ARMOR
+ pPlayer->removeSpell(36122); // Earthforged Leggings
+ pPlayer->removeSpell(36129); // Heavy Earthforged Breastplate
+ pPlayer->removeSpell(36130); // Stormforged Hauberk
+ pPlayer->removeSpell(34533); // Breastplate of Kings
+ pPlayer->removeSpell(34529); // Nether Chain Shirt
+ pPlayer->removeSpell(34534); // Bulwark of Kings
+ pPlayer->removeSpell(36257); // Bulwark of the Ancient Kings
+ pPlayer->removeSpell(36256); // Embrace of the Twisting Nether
+ pPlayer->removeSpell(34530); // Twisting Nether Chain Shirt
+ pPlayer->removeSpell(36124); // Windforged Leggings
+ break;
+ case 36441: // S_UNLEARN_HAMMER
+ pPlayer->removeSpell(36262); // Dragonstrike
+ pPlayer->removeSpell(34546); // Dragonmaw
+ pPlayer->removeSpell(34545); // Drakefist Hammer
+ pPlayer->removeSpell(36136); // Lavaforged Warhammer
+ pPlayer->removeSpell(34547); // Thunder
+ pPlayer->removeSpell(34567); // Deep Thunder
+ pPlayer->removeSpell(36263); // Stormherald
+ pPlayer->removeSpell(36137); // Great Earthforged Hammer
+ break;
+ case 36439: // S_UNLEARN_AXE
+ pPlayer->removeSpell(36260); // Wicked Edge of the Planes
+ pPlayer->removeSpell(34562); // Black Planar Edge
+ pPlayer->removeSpell(34541); // The Planar Edge
+ pPlayer->removeSpell(36134); // Stormforged Axe
+ pPlayer->removeSpell(36135); // Skyforged Great Axe
+ pPlayer->removeSpell(36261); // Bloodmoon
+ pPlayer->removeSpell(34543); // Lunar Crescent
+ pPlayer->removeSpell(34544); // Mooncleaver
+ break;
+ case 36438: // S_UNLEARN_SWORD
+ pPlayer->removeSpell(36258); // Blazefury
+ pPlayer->removeSpell(34537); // Blazeguard
+ pPlayer->removeSpell(34535); // Fireguard
+ pPlayer->removeSpell(36131); // Windforged Rapier
+ pPlayer->removeSpell(36133); // Stoneforged Claymore
+ pPlayer->removeSpell(34538); // Lionheart Blade
+ pPlayer->removeSpell(34540); // Lionheart Champion
+ pPlayer->removeSpell(36259); // Lionheart Executioner
+ break;
+ case 36434: // S_UNLEARN_DRAGON
+ pPlayer->removeSpell(36076); // Dragonstrike Leggings
+ pPlayer->removeSpell(36079); // Golden Dragonstrike Breastplate
+ pPlayer->removeSpell(35576); // Ebon Netherscale Belt
+ pPlayer->removeSpell(35577); // Ebon Netherscale Bracers
+ pPlayer->removeSpell(35575); // Ebon Netherscale Breastplate
+ pPlayer->removeSpell(35582); // Netherstrike Belt
+ pPlayer->removeSpell(35584); // Netherstrike Bracers
+ pPlayer->removeSpell(35580); // Netherstrike Breastplate
+ break;
+ case 36328: // S_UNLEARN_ELEMENTAL
+ pPlayer->removeSpell(36074); // Blackstorm Leggings
+ pPlayer->removeSpell(36077); // Primalstorm Breastplate
+ pPlayer->removeSpell(35590); // Primalstrike Belt
+ pPlayer->removeSpell(35591); // Primalstrike Bracers
+ pPlayer->removeSpell(35589); // Primalstrike Vest
+ break;
+ case 36433: // S_UNLEARN_TRIBAL
+ pPlayer->removeSpell(35585); // Windhawk Hauberk
+ pPlayer->removeSpell(35587); // Windhawk Belt
+ pPlayer->removeSpell(35588); // Windhawk Bracers
+ pPlayer->removeSpell(36075); // Wildfeather Leggings
+ pPlayer->removeSpell(36078); // Living Crystal Breastplate
+ break;
+ case 41299: // S_UNLEARN_SPELLFIRE
+ pPlayer->removeSpell(26752); // Spellfire Belt
+ pPlayer->removeSpell(26753); // Spellfire Gloves
+ pPlayer->removeSpell(26754); // Spellfire Robe
+ break;
+ case 41558: // S_UNLEARN_MOONCLOTH
+ pPlayer->removeSpell(26760); // Primal Mooncloth Belt
+ pPlayer->removeSpell(26761); // Primal Mooncloth Shoulders
+ pPlayer->removeSpell(26762); // Primal Mooncloth Robe
+ break;
+ case 41559: // S_UNLEARN_SHADOWEAVE
+ pPlayer->removeSpell(26756); // Frozen Shadoweave Shoulders
+ pPlayer->removeSpell(26757); // Frozen Shadoweave Boots
+ pPlayer->removeSpell(26758); // Frozen Shadoweave Robe
+ break;
+ }
+}
+
+/*###
+# start menues alchemy
+###*/
+
+bool HasAlchemySpell(Player* pPlayer)
+{
+ if (pPlayer->HasSpell(S_TRANSMUTE) || pPlayer->HasSpell(S_ELIXIR) || pPlayer->HasSpell(S_POTION))
+ return true;
+ return false;
+}
+
+bool GossipHello_npc_prof_alchemy(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+ if (pCreature->isVendor())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+ if (pCreature->isTrainer())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
+
+ uint32 eCreature = pCreature->GetEntry();
+
+ if (pPlayer->HasSkill(SKILL_ALCHEMY) && pPlayer->GetBaseSkillValue(SKILL_ALCHEMY) >= 350 && pPlayer->getLevel() > 67)
+ {
+ if (pPlayer->GetQuestRewardStatus(10899) || pPlayer->GetQuestRewardStatus(10902) || pPlayer->GetQuestRewardStatus(10897))
+ {
+ switch (eCreature)
+ {
+ case 22427: //Zarevhi
+ if (!HasAlchemySpell(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 1);
+ if (pPlayer->HasSpell(S_TRANSMUTE))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4);
+ break;
+ case 19052: //Lorokeem
+ if (!HasAlchemySpell(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 2);
+ if (pPlayer->HasSpell(S_ELIXIR))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 5);
+ break;
+ case 17909: //Lauranna Thar'well
+ if (!HasAlchemySpell(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 3);
+ if (pPlayer->HasSpell(S_POTION))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_POTION, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 6);
+ break;
+ }
+ }
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+void SendActionMenu_npc_prof_alchemy(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_TRADE:
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_TRAIN:
+ pPlayer->SEND_TRAINERLIST(pCreature->GetGUID());
+ break;
+ //Learn Alchemy
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!pPlayer->HasSpell(S_TRANSMUTE) && pPlayer->GetMoney() >= DoLearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_TRANSMUTE, true);
+ pPlayer->ModifyMoney(-DoLearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ if (!pPlayer->HasSpell(S_ELIXIR) && pPlayer->GetMoney() >= DoLearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_ELIXIR, true);
+ pPlayer->ModifyMoney(-DoLearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ if (!pPlayer->HasSpell(S_POTION) && pPlayer->GetMoney() >= DoLearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_POTION, true);
+ pPlayer->ModifyMoney(-DoLearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ //Unlearn Alchemy
+ case GOSSIP_ACTION_INFO_DEF + 4:
+ if (pPlayer->GetMoney() >= DoHighUnlearnCost(pPlayer))
+ {
+ pCreature->CastSpell(pPlayer, S_UNLEARN_TRANSMUTE, true);
+ pPlayer->ModifyMoney(-DoHighUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 5:
+ if (pPlayer->GetMoney() >= DoHighUnlearnCost(pPlayer))
+ {
+ pCreature->CastSpell(pPlayer, S_UNLEARN_ELIXIR, true);
+ pPlayer->ModifyMoney(-DoHighUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 6:
+ if (pPlayer->GetMoney() >= DoHighUnlearnCost(pPlayer))
+ {
+ pCreature->CastSpell(pPlayer, S_UNLEARN_POTION, true);
+ pPlayer->ModifyMoney(-DoHighUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+}
+
+void SendConfirmLearn_npc_prof_alchemy(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ if (uiAction)
+ {
+ uint32 eCreature = pCreature->GetEntry();
+ switch(eCreature)
+ {
+ case 22427:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 19052:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 17909:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ }
+ }
+}
+
+void SendConfirmUnlearn_npc_prof_alchemy(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ if (uiAction)
+ {
+ uint32 eCreature = pCreature->GetEntry();
+ switch(eCreature)
+ {
+ case 22427: //Zarevhi
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 19052: //Lorokeem
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 17909: //Lauranna Thar'well
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_POTION, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ }
+ }
+}
+
+bool GossipSelect_npc_prof_alchemy(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch(uiSender)
+ {
+ case GOSSIP_SENDER_MAIN: SendActionMenu_npc_prof_alchemy(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_LEARN: SendConfirmLearn_npc_prof_alchemy(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_UNLEARN: SendConfirmUnlearn_npc_prof_alchemy(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_CHECK: SendActionMenu_npc_prof_alchemy(pPlayer, pCreature, uiAction); break;
+ }
+ return true;
+}
+
+/*###
+# start menues blacksmith
+###*/
+
+bool HasWeaponSub(Player* pPlayer)
+{
+ if (pPlayer->HasSpell(S_HAMMER) || pPlayer->HasSpell(S_AXE) || pPlayer->HasSpell(S_SWORD))
+ return true;
+ return false;
+}
+
+bool GossipHello_npc_prof_blacksmith(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+ if (pCreature->isVendor())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+ if (pCreature->isTrainer())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
+
+ uint32 eCreature = pCreature->GetEntry();
+ //WEAPONSMITH & ARMORSMITH
+ if (pPlayer->GetBaseSkillValue(SKILL_BLACKSMITHING) >= 225)
+ {
+ switch (eCreature)
+ {
+ case 11145: //Myolor Sunderfury
+ case 11176: //Krathok Moltenfist
+ if (!pPlayer->HasSpell(S_ARMOR) && !pPlayer->HasSpell(S_WEAPON) && pPlayer->GetReputationRank(REP_ARMOR) >= REP_FRIENDLY)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARMOR_LEARN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ if (!pPlayer->HasSpell(S_WEAPON) && !pPlayer->HasSpell(S_ARMOR) && pPlayer->GetReputationRank(REP_WEAPON) >= REP_FRIENDLY)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WEAPON_LEARN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ break;
+ case 11146: //Ironus Coldsteel
+ case 11178: //Borgosh Corebender
+ if (pPlayer->HasSpell(S_WEAPON))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WEAPON_UNLEARN, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 3);
+ break;
+ case 5164: //Grumnus Steelshaper
+ case 11177: //Okothos Ironrager
+ if (pPlayer->HasSpell(S_ARMOR))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARMOR_UNLEARN, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4);
+ break;
+ }
+ }
+ //WEAPONSMITH SPEC
+ if (pPlayer->HasSpell(S_WEAPON) && pPlayer->getLevel() > 49 && pPlayer->GetBaseSkillValue(SKILL_BLACKSMITHING) >= 250)
+ {
+ switch (eCreature)
+ {
+ case 11191: //Lilith the Lithe
+ if (!HasWeaponSub(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_HAMMER, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 5);
+ if (pPlayer->HasSpell(S_HAMMER))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_HAMMER, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 8);
+ break;
+ case 11192: //Kilram
+ if (!HasWeaponSub(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_AXE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 6);
+ if (pPlayer->HasSpell(S_AXE))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_AXE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 9);
+ break;
+ case 11193: //Seril Scourgebane
+ if (!HasWeaponSub(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SWORD, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 7);
+ if (pPlayer->HasSpell(S_SWORD))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_SWORD, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 10);
+ break;
+ }
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+void SendActionMenu_npc_prof_blacksmith(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_TRADE:
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_TRAIN:
+ pPlayer->SEND_TRAINERLIST(pCreature->GetGUID());
+ break;
+ //Learn Armor/Weapon
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!pPlayer->HasSpell(S_ARMOR))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_ARMOR, true);
+ //_Creature->CastSpell(pPlayer, S_REP_ARMOR, true);
+ }
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ if (!pPlayer->HasSpell(S_WEAPON))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_WEAPON, true);
+ //_Creature->CastSpell(pPlayer, S_REP_WEAPON, true);
+ }
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ //Unlearn Armor/Weapon
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ if (HasWeaponSub(pPlayer))
+ {
+ //unknown textID (TALK_MUST_UNLEARN_WEAPON)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ }
+ else if (EquippedOk(pPlayer,S_UNLEARN_WEAPON))
+ {
+ if (pPlayer->GetMoney() >= DoLowUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_WEAPON, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_WEAPON);
+ pPlayer->ModifyMoney(-DoLowUnlearnCost(pPlayer));
+ pCreature->CastSpell(pPlayer, S_REP_ARMOR, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ }
+ else
+ {
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 4:
+ if (EquippedOk(pPlayer,S_UNLEARN_ARMOR))
+ {
+ if (pPlayer->GetMoney() >= DoLowUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_ARMOR, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_ARMOR);
+ pPlayer->ModifyMoney(-DoLowUnlearnCost(pPlayer));
+ pCreature->CastSpell(pPlayer, S_REP_WEAPON, true);
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ //Learn Hammer/Axe/Sword
+ case GOSSIP_ACTION_INFO_DEF + 5:
+ pPlayer->CastSpell(pPlayer, S_LEARN_HAMMER, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 6:
+ pPlayer->CastSpell(pPlayer, S_LEARN_AXE, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 7:
+ pPlayer->CastSpell(pPlayer, S_LEARN_SWORD, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ //Unlearn Hammer/Axe/Sword
+ case GOSSIP_ACTION_INFO_DEF + 8:
+ if (EquippedOk(pPlayer,S_UNLEARN_HAMMER))
+ {
+ if (pPlayer->GetMoney() >= DoMedUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_HAMMER, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_HAMMER);
+ pPlayer->ModifyMoney(-DoMedUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 9:
+ if (EquippedOk(pPlayer,S_UNLEARN_AXE))
+ {
+ if (pPlayer->GetMoney() >= DoMedUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_AXE, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_AXE);
+ pPlayer->ModifyMoney(-DoMedUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 10:
+ if (EquippedOk(pPlayer,S_UNLEARN_SWORD))
+ {
+ if (pPlayer->GetMoney() >= DoMedUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_SWORD, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_SWORD);
+ pPlayer->ModifyMoney(-DoMedUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+}
+
+void SendConfirmLearn_npc_prof_blacksmith(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ if (uiAction)
+ {
+ uint32 eCreature = pCreature->GetEntry();
+ switch(eCreature)
+ {
+ case 11191:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_HAMMER, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID (TALK_HAMMER_LEARN)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 11192:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_AXE, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID (TALK_AXE_LEARN)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 11193:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SWORD, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID (TALK_SWORD_LEARN)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ }
+ }
+}
+
+void SendConfirmUnlearn_npc_prof_blacksmith(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ if (uiAction)
+ {
+ uint32 eCreature = pCreature->GetEntry();
+ switch(eCreature)
+ {
+ case 11146: //Ironus Coldsteel
+ case 11178: //Borgosh Corebender
+ case 5164: //Grumnus Steelshaper
+ case 11177: //Okothos Ironrager
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SMITH_SPEC, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_ARMORORWEAPON, DoLowUnlearnCost(pPlayer),false);
+ //unknown textID (TALK_UNLEARN_AXEORWEAPON)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+
+ case 11191:
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_HAMMER, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(pPlayer),false);
+ //unknown textID (TALK_HAMMER_UNLEARN)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 11192:
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_AXE, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(pPlayer),false);
+ //unknown textID (TALK_AXE_UNLEARN)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 11193:
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SWORD, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(pPlayer),false);
+ //unknown textID (TALK_SWORD_UNLEARN)
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ }
+ }
+}
+
+bool GossipSelect_npc_prof_blacksmith(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch(uiSender)
+ {
+ case GOSSIP_SENDER_MAIN: SendActionMenu_npc_prof_blacksmith(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_LEARN: SendConfirmLearn_npc_prof_blacksmith(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_UNLEARN: SendConfirmUnlearn_npc_prof_blacksmith(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_CHECK: SendActionMenu_npc_prof_blacksmith(pPlayer, pCreature, uiAction); break;
+ }
+ return true;
+}
+
+/*bool QuestComplete_npc_prof_blacksmith(Player* pPlayer, Creature* pCreature, Quest const *_Quest)
+{
+ if ((_Quest->GetQuestId() == 5283) || (_Quest->GetQuestId() == 5301)) //armorsmith
+ pCreature->CastSpell(pPlayer, 17451, true);
+
+ if ((_Quest->GetQuestId() == 5284) || (_Quest->GetQuestId() == 5302)) //weaponsmith
+ pCreature->CastSpell(pPlayer, 17452, true);
+
+ return true;
+}*/
+
+/*###
+# engineering trinkets
+###*/
+
+enum eEngineeringTrinkets
+{
+ NPC_ZAP = 14742,
+ NPC_JHORDY = 14743,
+ NPC_KABLAM = 21493,
+ NPC_SMILES = 21494,
+
+ SPELL_LEARN_TO_EVERLOOK = 23490,
+ SPELL_LEARN_TO_GADGET = 23491,
+ SPELL_LEARN_TO_AREA52 = 36956,
+ SPELL_LEARN_TO_TOSHLEY = 36957,
+
+ SPELL_TO_EVERLOOK = 23486,
+ SPELL_TO_GADGET = 23489,
+ SPELL_TO_AREA52 = 36954,
+ SPELL_TO_TOSHLEY = 36955,
+
+ ITEM_GNOMISH_CARD = 10790,
+ ITEM_GOBLIN_CARD = 10791
+};
+
+#define GOSSIP_ITEM_ZAP "[PH] Unknown"
+#define GOSSIP_ITEM_JHORDY "I must build a beacon for this marvelous device!"
+#define GOSSIP_ITEM_KABLAM "[PH] Unknown"
+#define GOSSIP_ITEM_SMILES "[PH] Unknown"
+
+bool GossipHello_npc_engineering_tele_trinket(Player* pPlayer, Creature* pCreature)
+{
+ uint32 NpcTextId = 0;
+ std::string GossipItem;
+ bool CanLearn = false;
+
+ if (pPlayer->HasSkill(SKILL_ENGINERING))
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_ZAP:
+ NpcTextId = 7249;
+ if (pPlayer->GetBaseSkillValue(SKILL_ENGINERING) >= 260 && pPlayer->HasSpell(S_GOBLIN))
+ {
+ if (!pPlayer->HasSpell(SPELL_TO_EVERLOOK))
+ {
+ CanLearn = true;
+ GossipItem = GOSSIP_ITEM_ZAP;
+ }
+ else if (pPlayer->HasSpell(SPELL_TO_EVERLOOK))
+ NpcTextId = 0;
+ }
+ break;
+ case NPC_JHORDY:
+ NpcTextId = 7251;
+ if (pPlayer->GetBaseSkillValue(SKILL_ENGINERING) >= 260 && pPlayer->HasSpell(S_GNOMISH))
+ {
+ if (!pPlayer->HasSpell(SPELL_TO_GADGET))
+ {
+ CanLearn = true;
+ GossipItem = GOSSIP_ITEM_JHORDY;
+ }
+ else if (pPlayer->HasSpell(SPELL_TO_GADGET))
+ NpcTextId = 7252;
+ }
+ break;
+ case NPC_KABLAM:
+ NpcTextId = 10365;
+ if (pPlayer->GetBaseSkillValue(SKILL_ENGINERING) >= 350 && pPlayer->HasSpell(S_GOBLIN))
+ {
+ if (!pPlayer->HasSpell(SPELL_TO_AREA52))
+ {
+ CanLearn = true;
+ GossipItem = GOSSIP_ITEM_KABLAM;
+ }
+ else if (pPlayer->HasSpell(SPELL_TO_AREA52))
+ NpcTextId = 0;
+ }
+ break;
+ case NPC_SMILES:
+ NpcTextId = 10363;
+ if (pPlayer->GetBaseSkillValue(SKILL_ENGINERING) >= 350 && pPlayer->HasSpell(S_GNOMISH))
+ {
+ if (!pPlayer->HasSpell(SPELL_TO_TOSHLEY))
+ {
+ CanLearn = true;
+ GossipItem = GOSSIP_ITEM_SMILES;
+ }
+ else if (pPlayer->HasSpell(SPELL_TO_TOSHLEY))
+ NpcTextId = 0;
+ }
+ break;
+ }
+ }
+
+ if (CanLearn)
+ {
+ if (pPlayer->HasItemCount(ITEM_GOBLIN_CARD,1) || pPlayer->HasItemCount(ITEM_GNOMISH_CARD,1))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GossipItem, pCreature->GetEntry(), GOSSIP_ACTION_INFO_DEF+1);
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(NpcTextId ? NpcTextId : pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_engineering_tele_trinket(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ if (uiSender != pCreature->GetEntry())
+ return true;
+
+ switch(uiSender)
+ {
+ case NPC_ZAP:
+ pPlayer->CastSpell(pPlayer, SPELL_LEARN_TO_EVERLOOK, false);
+ break;
+ case NPC_JHORDY:
+ pPlayer->CastSpell(pPlayer, SPELL_LEARN_TO_GADGET, false);
+ break;
+ case NPC_KABLAM:
+ pPlayer->CastSpell(pPlayer, SPELL_LEARN_TO_AREA52, false);
+ break;
+ case NPC_SMILES:
+ pPlayer->CastSpell(pPlayer, SPELL_LEARN_TO_TOSHLEY, false);
+ break;
+ }
+
+ return true;
+}
+
+/*###
+# start menues leatherworking
+###*/
+
+bool GossipHello_npc_prof_leather(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+ if (pCreature->isVendor())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+ if (pCreature->isTrainer())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
+
+ uint32 eCreature = pCreature->GetEntry();
+
+ if (pPlayer->HasSkill(SKILL_LEATHERWORKING) && pPlayer->GetBaseSkillValue(SKILL_LEATHERWORKING) >= 250 && pPlayer->getLevel() > 49)
+ {
+ switch (eCreature)
+ {
+ case 7866: //Peter Galen
+ case 7867: //Thorkaf Dragoneye
+ if (pPlayer->HasSpell(S_DRAGON))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_DRAGON, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 1);
+ break;
+ case 7868: //Sarah Tanner
+ case 7869: //Brumn Winterhoof
+ if (pPlayer->HasSpell(S_ELEMENTAL))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_ELEMENTAL, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 2);
+ break;
+ case 7870: //Caryssia Moonhunter
+ case 7871: //Se'Jib
+ if (pPlayer->HasSpell(S_TRIBAL))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_TRIBAL, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 3);
+ break;
+ }
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+void SendActionMenu_npc_prof_leather(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_TRADE:
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_TRAIN:
+ pPlayer->SEND_TRAINERLIST(pCreature->GetGUID());
+ break;
+ //Unlearn Leather
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (EquippedOk(pPlayer,S_UNLEARN_DRAGON))
+ {
+ if (pPlayer->GetMoney() >= DoMedUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_DRAGON, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_DRAGON);
+ pPlayer->ModifyMoney(-DoMedUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ if (EquippedOk(pPlayer,S_UNLEARN_ELEMENTAL))
+ {
+ if (pPlayer->GetMoney() >= DoMedUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_ELEMENTAL, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_ELEMENTAL);
+ pPlayer->ModifyMoney(-DoMedUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ if (EquippedOk(pPlayer,S_UNLEARN_TRIBAL))
+ {
+ if (pPlayer->GetMoney() >= DoMedUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_TRIBAL, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_TRIBAL);
+ pPlayer->ModifyMoney(-DoMedUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+}
+
+void SendConfirmUnlearn_npc_prof_leather(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ if (uiAction)
+ {
+ uint32 eCreature = pCreature->GetEntry();
+ switch(eCreature)
+ {
+ case 7866: //Peter Galen
+ case 7867: //Thorkaf Dragoneye
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_DRAGON, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 7868: //Sarah Tanner
+ case 7869: //Brumn Winterhoof
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_ELEMENTAL, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 7870: //Caryssia Moonhunter
+ case 7871: //Se'Jib
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_TRIBAL, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ }
+ }
+}
+
+bool GossipSelect_npc_prof_leather(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch(uiSender)
+ {
+ case GOSSIP_SENDER_MAIN: SendActionMenu_npc_prof_leather(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_UNLEARN: SendConfirmUnlearn_npc_prof_leather(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_CHECK: SendActionMenu_npc_prof_leather(pPlayer, pCreature, uiAction); break;
+ }
+ return true;
+}
+
+/*###
+# start menues tailoring
+###*/
+
+bool HasTailorSpell(Player* pPlayer)
+{
+ if (pPlayer->HasSpell(S_MOONCLOTH) || pPlayer->HasSpell(S_SHADOWEAVE) || pPlayer->HasSpell(S_SPELLFIRE))
+ return true;
+ return false;
+}
+
+bool GossipHello_npc_prof_tailor(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+ if (pCreature->isVendor())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+ if (pCreature->isTrainer())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
+
+ uint32 eCreature = pCreature->GetEntry();
+ //TAILORING SPEC
+ if (pPlayer->HasSkill(SKILL_TAILORING) && pPlayer->GetBaseSkillValue(SKILL_TAILORING) >= 350 && pPlayer->getLevel() > 59)
+ {
+ if (pPlayer->GetQuestRewardStatus(10831) || pPlayer->GetQuestRewardStatus(10832) || pPlayer->GetQuestRewardStatus(10833))
+ {
+ switch (eCreature)
+ {
+ case 22213: //Gidge Spellweaver
+ if (!HasTailorSpell(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SPELLFIRE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 1);
+ if (pPlayer->HasSpell(S_SPELLFIRE))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_SPELLFIRE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4);
+ break;
+ case 22208: //Nasmara Moonsong
+ if (!HasTailorSpell(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_MOONCLOTH, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 2);
+ if (pPlayer->HasSpell(S_MOONCLOTH))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_MOONCLOTH, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 5);
+ break;
+ case 22212: //Andrion Darkspinner
+ if (!HasTailorSpell(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SHADOWEAVE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 3);
+ if (pPlayer->HasSpell(S_SHADOWEAVE))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_SHADOWEAVE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 6);
+ break;
+ }
+ }
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+void SendActionMenu_npc_prof_tailor(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_TRADE:
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_TRAIN:
+ pPlayer->SEND_TRAINERLIST(pCreature->GetGUID());
+ break;
+ //Learn Tailor
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!pPlayer->HasSpell(S_SPELLFIRE) && pPlayer->GetMoney() >= DoLearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_SPELLFIRE, true);
+ pPlayer->ModifyMoney(-DoLearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ if (!pPlayer->HasSpell(S_MOONCLOTH) && pPlayer->GetMoney() >= DoLearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_MOONCLOTH, true);
+ pPlayer->ModifyMoney(-DoLearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ if (!pPlayer->HasSpell(S_SHADOWEAVE) && pPlayer->GetMoney() >= DoLearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_LEARN_SHADOWEAVE, true);
+ pPlayer->ModifyMoney(-DoLearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ //Unlearn Tailor
+ case GOSSIP_ACTION_INFO_DEF + 4:
+ if (EquippedOk(pPlayer,S_UNLEARN_SPELLFIRE))
+ {
+ if (pPlayer->GetMoney() >= DoHighUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_SPELLFIRE, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_SPELLFIRE);
+ pPlayer->ModifyMoney(-DoHighUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 5:
+ if (EquippedOk(pPlayer,S_UNLEARN_MOONCLOTH))
+ {
+ if (pPlayer->GetMoney() >= DoHighUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_MOONCLOTH, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_MOONCLOTH);
+ pPlayer->ModifyMoney(-DoHighUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 6:
+ if (EquippedOk(pPlayer,S_UNLEARN_SHADOWEAVE))
+ {
+ if (pPlayer->GetMoney() >= DoHighUnlearnCost(pPlayer))
+ {
+ pPlayer->CastSpell(pPlayer, S_UNLEARN_SHADOWEAVE, true);
+ ProfessionUnlearnSpells(pPlayer, S_UNLEARN_SHADOWEAVE);
+ pPlayer->ModifyMoney(-DoHighUnlearnCost(pPlayer));
+ } else
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, 0, 0);
+ } else
+ pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,NULL,NULL);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+}
+
+void SendConfirmLearn_npc_prof_tailor(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ if (uiAction)
+ {
+ uint32 eCreature = pCreature->GetEntry();
+ switch(eCreature)
+ {
+ case 22213:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SPELLFIRE, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 22208:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_MOONCLOTH, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 22212:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SHADOWEAVE, GOSSIP_SENDER_CHECK, uiAction);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ }
+ }
+}
+
+void SendConfirmUnlearn_npc_prof_tailor(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ if (uiAction)
+ {
+ uint32 eCreature = pCreature->GetEntry();
+ switch(eCreature)
+ {
+ case 22213: //Gidge Spellweaver
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SPELLFIRE, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 22208: //Nasmara Moonsong
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_MOONCLOTH, GOSSIP_SENDER_CHECK, uiAction, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ case 22212: //Andrion Darkspinner
+ pPlayer->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SHADOWEAVE, GOSSIP_SENDER_CHECK, uiAction,BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(pPlayer),false);
+ //unknown textID ()
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ break;
+ }
+ }
+}
+
+bool GossipSelect_npc_prof_tailor(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch(uiSender)
+ {
+ case GOSSIP_SENDER_MAIN: SendActionMenu_npc_prof_tailor(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_LEARN: SendConfirmLearn_npc_prof_tailor(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_UNLEARN: SendConfirmUnlearn_npc_prof_tailor(pPlayer, pCreature, uiAction); break;
+ case GOSSIP_SENDER_CHECK: SendActionMenu_npc_prof_tailor(pPlayer, pCreature, uiAction); break;
+ }
+ return true;
+}
+
+/*###
+# start menues for GO (engineering and leatherworking)
+###*/
+
+/*bool GOHello_go_soothsaying_for_dummies(Player* pPlayer, GameObject* pGo)
+{
+ pPlayer->PlayerTalkClass->GetGossipMenu()->AddMenuItem(0,GOSSIP_LEARN_DRAGON, GOSSIP_SENDER_INFO, GOSSIP_ACTION_INFO_DEF, "", 0);
+
+ pPlayer->SEND_GOSSIP_MENU(5584, pGo->GetGUID());
+
+ return true;
+}*/
+
+/*###
+#
+###*/
+
+void AddSC_npc_professions()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_prof_alchemy";
+ newscript->pGossipHello = &GossipHello_npc_prof_alchemy;
+ newscript->pGossipSelect = &GossipSelect_npc_prof_alchemy;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_prof_blacksmith";
+ newscript->pGossipHello = &GossipHello_npc_prof_blacksmith;
+ newscript->pGossipSelect = &GossipSelect_npc_prof_blacksmith;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_engineering_tele_trinket";
+ newscript->pGossipHello = &GossipHello_npc_engineering_tele_trinket;
+ newscript->pGossipSelect = &GossipSelect_npc_engineering_tele_trinket;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_prof_leather";
+ newscript->pGossipHello = &GossipHello_npc_prof_leather;
+ newscript->pGossipSelect = &GossipSelect_npc_prof_leather;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_prof_tailor";
+ newscript->pGossipHello = &GossipHello_npc_prof_tailor;
+ newscript->pGossipSelect = &GossipSelect_npc_prof_tailor;
+ newscript->RegisterSelf();
+
+ /*newscript = new Script;
+ newscript->Name = "go_soothsaying_for_dummies";
+ newscript->pGOHello = &GOHello_go_soothsaying_for_dummies;
+ //newscript->pGossipSelect = &GossipSelect_go_soothsaying_for_dummies;
+ newscript->RegisterSelf();*/
+}
+
diff --git a/src/server/scripts/World/npc_taxi.cpp b/src/server/scripts/World/npc_taxi.cpp
new file mode 100644
index 00000000000..2a8efd4e0cb
--- /dev/null
+++ b/src/server/scripts/World/npc_taxi.cpp
@@ -0,0 +1,326 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Npc_Taxi
+SD%Complete: 0%
+SDComment: To be used for taxi NPCs that are located globally.
+SDCategory: NPCs
+EndScriptData
+*/
+
+#include "ScriptedPch.h"
+
+#define GOSSIP_SUSURRUS "I am ready."
+#define GOSSIP_NETHER_DRAKE "I'm ready to fly! Take me up, dragon!"
+#define GOSSIP_BRAZEN "I am ready to go to Durnholde Keep."
+#define GOSSIP_IRONWING "I'd like to take a flight around Stormwind Harbor."
+#define GOSSIP_DABIREE1 "Fly me to Murketh and Shaadraz Gateways"
+#define GOSSIP_DABIREE2 "Fly me to Shatter Point"
+#define GOSSIP_WINDBELLOW1 "Fly me to The Abyssal Shelf"
+#define GOSSIP_WINDBELLOW2 "Fly me to Honor Point"
+#define GOSSIP_BRACK1 "Fly me to Murketh and Shaadraz Gateways"
+#define GOSSIP_BRACK2 "Fly me to The Abyssal Shelf"
+#define GOSSIP_BRACK3 "Fly me to Spinebreaker Post"
+#define GOSSIP_IRENA "Fly me to Skettis please"
+#define GOSSIP_CLOUDBREAKER1 "Speaking of uiAction, I've been ordered to undertake an air strike."
+#define GOSSIP_CLOUDBREAKER2 "I need to intercept the Dawnblade reinforcements."
+#define GOSSIP_DRAGONHAWK "<Ride the dragonhawk to Sun's Reach>"
+#define GOSSIP_VERONIA "Fly me to Manaforge Coruu please"
+#define GOSSIP_DEESAK "Fly me to Ogri'la please"
+#define GOSSIP_AFRASASTRASZ1 "I would like to take a flight to the ground, Lord Of Afrasastrasz."
+#define GOSSIP_AFRASASTRASZ2 "My Lord, I must go to the upper floor of the temple."
+#define GOSSIP_TARIOLSTRASZ1 "My Lord, I must go to the upper floor of the temple."
+#define GOSSIP_TARIOLSTRASZ2 "Can you spare a drake to travel to Lord Of Afrasastrasz, in the middle of the temple?"
+#define GOSSIP_TORASTRASZA1 "I would like to see Lord Of Afrasastrasz, in the middle of the temple."
+#define GOSSIP_TORASTRASZA2 "Yes, Please. I would like to return to the ground floor of the temple."
+#define GOSSIP_CAMILLE1 "I need to fly to the Windrunner Official business!"
+#define GOSSIP_CAMILLE2 "<The riding bat for the special task is necessary to me.>"
+#define GOSSIP_CRIMSONWING "<Ride the gryphons to Survey Alcaz Island>"
+#define GOSSIP_THRICESTAR1 "Do you think I could take a ride on one of those flying machines?"
+#define GOSSIP_THRICESTAR2 "Kara, I need to be flown out the Dens of Dying to find Bixie."
+#define GOSSIP_WILLIAMKEILAR1 "Take me to Northpass Tower."
+#define GOSSIP_WILLIAMKEILAR2 "Take me to Eastwall Tower."
+#define GOSSIP_WILLIAMKEILAR3 "Take me to Crown Guard Tower."
+
+bool GossipHello_npc_taxi(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ switch(pCreature->GetEntry()) {
+ case 17435: // Azuremyst Isle - Susurrus
+ if (pPlayer->HasItemCount(23843,1,true))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SUSURRUS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ break;
+ case 20903: // Netherstorm - Protectorate Nether Drake
+ if (pPlayer->GetQuestStatus(10438) == QUEST_STATUS_INCOMPLETE && pPlayer->HasItemCount(29778,1))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_NETHER_DRAKE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ break;
+ case 18725: // Old Hillsbrad Foothills - Brazen
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BRAZEN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ break;
+ case 29154: // Stormwind City - Thargold Ironwing
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_IRONWING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ break;
+ case 19409: // Hellfire Peninsula - Wing Commander Dabir'ee
+ //Mission: The Murketh and Shaadraz Gateways
+ if (pPlayer->GetQuestStatus(10146) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DABIREE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
+
+ //Shatter Point
+ if (!pPlayer->GetQuestRewardStatus(10340))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DABIREE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
+ break;
+ case 20235: // Hellfire Peninsula - Gryphoneer Windbellow
+ //Mission: The Abyssal Shelf || Return to the Abyssal Shelf
+ if (pPlayer->GetQuestStatus(10163) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(10346) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WINDBELLOW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
+
+ //Go to the Front
+ if (pPlayer->GetQuestStatus(10382) != QUEST_STATUS_NONE && !pPlayer->GetQuestRewardStatus(10382))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WINDBELLOW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
+ break;
+ case 19401: // Hellfire Peninsula - Wing Commander Brack
+ //Mission: The Murketh and Shaadraz Gateways
+ if (pPlayer->GetQuestStatus(10129) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BRACK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8);
+
+ //Mission: The Abyssal Shelf || Return to the Abyssal Shelf
+ if (pPlayer->GetQuestStatus(10162) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(10347) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BRACK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
+
+ //Spinebreaker Post
+ if (pPlayer->GetQuestStatus(10242) == QUEST_STATUS_COMPLETE && !pPlayer->GetQuestRewardStatus(10242))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BRACK3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
+ break;
+ case 23413: // Blade's Edge Mountains - Skyguard Handler Irena
+ if (pPlayer->GetReputationRank(1031) >= REP_HONORED)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_IRENA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11);
+ break;
+ case 25059: // Isle of Quel'Danas - Ayren Cloudbreaker
+ if (pPlayer->GetQuestStatus(11532) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(11533) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CLOUDBREAKER1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12);
+
+ if (pPlayer->GetQuestStatus(11542) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(11543) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CLOUDBREAKER2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13);
+ break;
+ case 25236: // Isle of Quel'Danas - Unrestrained Dragonhawk
+ if (pPlayer->GetQuestStatus(11542) == QUEST_STATUS_COMPLETE || pPlayer->GetQuestStatus(11543) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DRAGONHAWK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14);
+ break;
+ case 20162: // Netherstorm - Veronia
+ //Behind Enemy Lines
+ if (pPlayer->GetQuestStatus(10652) && !pPlayer->GetQuestRewardStatus(10652))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VERONIA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15);
+ break;
+ case 23415: // Terokkar Forest - Skyguard Handler Deesak
+ if (pPlayer->GetReputationRank(1031) >= REP_HONORED)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEESAK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 16);
+ break;
+ case 27575: // Dragonblight - Lord Afrasastrasz
+ // middle -> ground
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_AFRASASTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 17);
+ // middle -> top
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_AFRASASTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 18);
+ break;
+ case 26443: // Dragonblight - Tariolstrasz //need to check if quests are required before gossip available (12123, 12124)
+ // ground -> top
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TARIOLSTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 19);
+ // ground -> middle
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TARIOLSTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20);
+ break;
+ case 26949: // Dragonblight - Torastrasza
+ // top -> middle
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TORASTRASZA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21);
+ // top -> ground
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TORASTRASZA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22);
+ break;
+ case 23816: // Howling Fjord - Bat Handler Camille
+ if (!pPlayer->GetQuestRewardStatus(11229))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CAMILLE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23);
+ if (pPlayer->GetQuestStatus(11170) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CAMILLE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24);
+ break;
+ case 23704: // Dustwallow Marsh - Cassa Crimsonwing
+ if (pPlayer->GetQuestStatus(11142) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CRIMSONWING,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+25);
+ break;
+ case 26602:
+ if (pCreature->isTaxi())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TAXI, GOSSIP_THRICESTAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 26);
+ if (pPlayer->GetQuestStatus(11692) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_THRICESTAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 27);
+ break;
+ case 17209:
+ pPlayer->SetTaxiCheater(true);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 28);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 29);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 30);
+ break;
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_taxi(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction) {
+ case GOSSIP_ACTION_INFO_DEF:
+ //spellId is correct, however it gives flight a somewhat funny effect //TaxiPath 506.
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,32474,true);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(627); //TaxiPath 627 (possibly 627+628(152->153->154->155))
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ if (!pPlayer->HasItemCount(25853,1)) {
+ pPlayer->SEND_GOSSIP_MENU(9780, pCreature->GetGUID());
+ } else {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(534); //TaxiPath 534
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,53335,true); //TaxiPath 1041 (Stormwind Harbor)
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 4:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,33768,true); //TaxiPath 585 (Gateways Murket and Shaadraz)
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 5:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,35069,true); //TaxiPath 612 (Taxi - Hellfire Peninsula - Expedition Point to Shatter Point)
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 6:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,33899,true); //TaxiPath 589 (Aerial Assault Flight (Alliance))
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 7:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,35065,true); //TaxiPath 607 (Taxi - Hellfire Peninsula - Shatter Point to Beach Head)
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 8:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,33659,true); //TaxiPath 584 (Gateways Murket and Shaadraz)
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 9:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,33825,true); //TaxiPath 587 (Aerial Assault Flight (Horde))
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 10:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,34578,true); //TaxiPath 604 (Taxi - Reaver's Fall to Spinebreaker Ridge)
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 11:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,41278,true); //TaxiPath 706
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 12:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,45071,true); //TaxiPath 779
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 13:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,45113,true); //TaxiPath 784
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 14:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,45353,true); //TaxiPath 788
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 15:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,34905,true); //TaxiPath 606
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 16:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,41279,true); //TaxiPath 705 (Taxi - Skettis to Skyguard Outpost)
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 17:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(882);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 18:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(881);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 19:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(878);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 20:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(883);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 21:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(880);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 22:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(879);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 23:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,43074,true); //TaxiPath 736
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 24:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ //pPlayer->ActivateTaxiPathTo(738);
+ pPlayer->CastSpell(pPlayer, 43136, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 25:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,42295,true);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 26:
+ pPlayer->GetSession()->SendTaxiMenu(pCreature);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 27:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, 51446, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 28:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(494);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 29:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(495);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 30:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->ActivateTaxiPathTo(496);
+ break;
+ }
+
+ return true;
+}
+
+void AddSC_npc_taxi()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_taxi";
+ newscript->pGossipHello = &GossipHello_npc_taxi;
+ newscript->pGossipSelect = &GossipSelect_npc_taxi;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
new file mode 100644
index 00000000000..cfd1b7698fc
--- /dev/null
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -0,0 +1,2600 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Npcs_Special
+SD%Complete: 100
+SDComment: To be used for special NPCs that are located globally.
+SDCategory: NPCs
+EndScriptData
+*/
+
+/* ContentData
+npc_air_force_bots 80% support for misc (invisible) guard bots in areas where player allowed to fly. Summon guards after a preset time if tagged by spell
+npc_lunaclaw_spirit 80% support for quests 6001/6002 (Body and Heart)
+npc_chicken_cluck 100% support for quest 3861 (Cluck!)
+npc_dancing_flames 100% midsummer event NPC
+npc_guardian 100% guardianAI used to prevent players from accessing off-limits areas. Not in use by SD2
+npc_garments_of_quests 80% NPC's related to all Garments of-quests 5621, 5624, 5625, 5648, 565
+npc_injured_patient 100% patients for triage-quests (6622 and 6624)
+npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622 and 6624 (Triage)
+npc_kingdom_of_dalaran_quests Misc NPC's gossip option related to quests 12791, 12794 and 12796
+npc_mount_vendor 100% Regular mount vendors all over the world. Display gossip if player doesn't meet the requirements to buy
+npc_rogue_trainer 80% Scripted trainers, so they are able to offer item 17126 for class quest 6681
+npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given
+npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap
+npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage
+npc_locksmith 75% list of keys needs to be confirmed
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+#include "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "World.h"
+
+/*########
+# npc_air_force_bots
+#########*/
+
+enum SpawnType
+{
+ SPAWNTYPE_TRIPWIRE_ROOFTOP, // no warning, summon Creature at smaller range
+ SPAWNTYPE_ALARMBOT, // cast guards mark and summon npc - if player shows up with that buff duration < 5 seconds attack
+};
+
+struct SpawnAssociation
+{
+ uint32 m_uiThisCreatureEntry;
+ uint32 m_uiSpawnedCreatureEntry;
+ SpawnType m_SpawnType;
+};
+
+enum eEnums
+{
+ SPELL_GUARDS_MARK = 38067,
+ AURA_DURATION_TIME_LEFT = 5000
+};
+
+const float RANGE_TRIPWIRE = 15.0f;
+const float RANGE_GUARDS_MARK = 50.0f;
+
+SpawnAssociation m_aSpawnAssociations[] =
+{
+ {2614, 15241, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Alliance)
+ {2615, 15242, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Horde)
+ {21974, 21976, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Area 52)
+ {21993, 15242, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Horde - Bat Rider)
+ {21996, 15241, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Alliance - Gryphon)
+ {21997, 21976, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Goblin - Area 52 - Zeppelin)
+ {21999, 15241, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Rooftop (Alliance)
+ {22001, 15242, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Rooftop (Horde)
+ {22002, 15242, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Ground (Horde)
+ {22003, 15241, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Ground (Alliance)
+ {22063, 21976, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Rooftop (Goblin - Area 52)
+ {22065, 22064, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Ethereal - Stormspire)
+ {22066, 22067, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Scryer - Dragonhawk)
+ {22068, 22064, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Rooftop (Ethereal - Stormspire)
+ {22069, 22064, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Stormspire)
+ {22070, 22067, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Rooftop (Scryer)
+ {22071, 22067, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Scryer)
+ {22078, 22077, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Aldor)
+ {22079, 22077, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Aldor - Gryphon)
+ {22080, 22077, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Rooftop (Aldor)
+ {22086, 22085, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Sporeggar)
+ {22087, 22085, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Sporeggar - Spore Bat)
+ {22088, 22085, SPAWNTYPE_TRIPWIRE_ROOFTOP}, //Air Force Trip Wire - Rooftop (Sporeggar)
+ {22090, 22089, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Toshley's Station - Flying Machine)
+ {22124, 22122, SPAWNTYPE_ALARMBOT}, //Air Force Alarm Bot (Cenarion)
+ {22125, 22122, SPAWNTYPE_ALARMBOT}, //Air Force Guard Post (Cenarion - Stormcrow)
+ {22126, 22122, SPAWNTYPE_ALARMBOT} //Air Force Trip Wire - Rooftop (Cenarion Expedition)
+};
+
+struct npc_air_force_botsAI : public ScriptedAI
+{
+ npc_air_force_botsAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pSpawnAssoc = NULL;
+ m_uiSpawnedGUID = 0;
+
+ // find the correct spawnhandling
+ static uint32 uiEntryCount = sizeof(m_aSpawnAssociations)/sizeof(SpawnAssociation);
+
+ for (uint8 i=0; i<uiEntryCount; ++i)
+ {
+ if (m_aSpawnAssociations[i].m_uiThisCreatureEntry == pCreature->GetEntry())
+ {
+ m_pSpawnAssoc = &m_aSpawnAssociations[i];
+ break;
+ }
+ }
+
+ if (!m_pSpawnAssoc)
+ error_db_log("TCSR: Creature template entry %u has ScriptName npc_air_force_bots, but it's not handled by that script", pCreature->GetEntry());
+ else
+ {
+ CreatureInfo const* spawnedTemplate = GetCreatureTemplateStore(m_pSpawnAssoc->m_uiSpawnedCreatureEntry);
+
+ if (!spawnedTemplate)
+ {
+ m_pSpawnAssoc = NULL;
+ error_db_log("TCSR: Creature template entry %u does not exist in DB, which is required by npc_air_force_bots", m_pSpawnAssoc->m_uiSpawnedCreatureEntry);
+ return;
+ }
+ }
+ }
+
+ SpawnAssociation* m_pSpawnAssoc;
+ uint64 m_uiSpawnedGUID;
+
+ void Reset() {}
+
+ Creature* SummonGuard()
+ {
+ Creature* pSummoned = me->SummonCreature(m_pSpawnAssoc->m_uiSpawnedCreatureEntry, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000);
+
+ if (pSummoned)
+ m_uiSpawnedGUID = pSummoned->GetGUID();
+ else
+ {
+ error_db_log("TCSR: npc_air_force_bots: wasn't able to spawn Creature %u", m_pSpawnAssoc->m_uiSpawnedCreatureEntry);
+ m_pSpawnAssoc = NULL;
+ }
+
+ return pSummoned;
+ }
+
+ Creature* GetSummonedGuard()
+ {
+ Creature* pCreature = Unit::GetCreature(*me, m_uiSpawnedGUID);
+
+ if (pCreature && pCreature->isAlive())
+ return pCreature;
+
+ return NULL;
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!m_pSpawnAssoc)
+ return;
+
+ if (pWho->isTargetableForAttack() && me->IsHostileTo(pWho))
+ {
+ Player* pPlayerTarget = pWho->GetTypeId() == TYPEID_PLAYER ? CAST_PLR(pWho) : NULL;
+
+ // airforce guards only spawn for players
+ if (!pPlayerTarget)
+ return;
+
+ Creature* pLastSpawnedGuard = m_uiSpawnedGUID == 0 ? NULL : GetSummonedGuard();
+
+ // prevent calling Unit::GetUnit at next MoveInLineOfSight call - speedup
+ if (!pLastSpawnedGuard)
+ m_uiSpawnedGUID = 0;
+
+ switch(m_pSpawnAssoc->m_SpawnType)
+ {
+ case SPAWNTYPE_ALARMBOT:
+ {
+ if (!pWho->IsWithinDistInMap(me, RANGE_GUARDS_MARK))
+ return;
+
+ Aura* pMarkAura = pWho->GetAura(SPELL_GUARDS_MARK);
+ if (pMarkAura)
+ {
+ // the target wasn't able to move out of our range within 25 seconds
+ if (!pLastSpawnedGuard)
+ {
+ pLastSpawnedGuard = SummonGuard();
+
+ if (!pLastSpawnedGuard)
+ return;
+ }
+
+ if (pMarkAura->GetDuration() < AURA_DURATION_TIME_LEFT)
+ {
+ if (!pLastSpawnedGuard->getVictim())
+ pLastSpawnedGuard->AI()->AttackStart(pWho);
+ }
+ }
+ else
+ {
+ if (!pLastSpawnedGuard)
+ pLastSpawnedGuard = SummonGuard();
+
+ if (!pLastSpawnedGuard)
+ return;
+
+ pLastSpawnedGuard->CastSpell(pWho, SPELL_GUARDS_MARK, true);
+ }
+ break;
+ }
+ case SPAWNTYPE_TRIPWIRE_ROOFTOP:
+ {
+ if (!pWho->IsWithinDistInMap(me, RANGE_TRIPWIRE))
+ return;
+
+ if (!pLastSpawnedGuard)
+ pLastSpawnedGuard = SummonGuard();
+
+ if (!pLastSpawnedGuard)
+ return;
+
+ // ROOFTOP only triggers if the player is on the ground
+ if (!pPlayerTarget->IsFlying())
+ {
+ if (!pLastSpawnedGuard->getVictim())
+ pLastSpawnedGuard->AI()->AttackStart(pWho);
+ }
+ break;
+ }
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_air_force_bots(Creature* pCreature)
+{
+ return new npc_air_force_botsAI(pCreature);
+}
+
+/*######
+## npc_lunaclaw_spirit
+######*/
+
+enum
+{
+ QUEST_BODY_HEART_A = 6001,
+ QUEST_BODY_HEART_H = 6002,
+
+ TEXT_ID_DEFAULT = 4714,
+ TEXT_ID_PROGRESS = 4715
+};
+
+#define GOSSIP_ITEM_GRANT "You have thought well, spirit. I ask you to grant me the strength of your body and the strength of your heart."
+
+bool GossipHello_npc_lunaclaw_spirit(Player *pPlayer, Creature *pCreature)
+{
+ if (pPlayer->GetQuestStatus(QUEST_BODY_HEART_A) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(QUEST_BODY_HEART_H) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_GRANT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(TEXT_ID_DEFAULT, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_lunaclaw_spirit(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->SEND_GOSSIP_MENU(TEXT_ID_PROGRESS, pCreature->GetGUID());
+ pPlayer->AreaExploredOrEventHappens(pPlayer->GetTeam() == ALLIANCE ? QUEST_BODY_HEART_A : QUEST_BODY_HEART_H);
+ }
+ return true;
+}
+
+/*########
+# npc_chicken_cluck
+#########*/
+
+#define EMOTE_HELLO -1070004
+#define EMOTE_CLUCK_TEXT -1070006
+
+#define QUEST_CLUCK 3861
+#define FACTION_FRIENDLY 35
+#define FACTION_CHICKEN 31
+
+struct npc_chicken_cluckAI : public ScriptedAI
+{
+ npc_chicken_cluckAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 ResetFlagTimer;
+
+ void Reset()
+ {
+ ResetFlagTimer = 120000;
+ me->setFaction(FACTION_CHICKEN);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Reset flags after a certain time has passed so that the next player has to start the 'event' again
+ if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
+ {
+ if (ResetFlagTimer <= diff)
+ {
+ EnterEvadeMode();
+ return;
+ } else ResetFlagTimer -= diff;
+ }
+
+ if (UpdateVictim())
+ DoMeleeAttackIfReady();
+ }
+
+ void ReceiveEmote(Player* pPlayer, uint32 emote)
+ {
+ switch(emote)
+ {
+ case TEXTEMOTE_CHICKEN:
+ if (pPlayer->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_NONE && rand()%30 == 1)
+ {
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ me->setFaction(FACTION_FRIENDLY);
+ DoScriptText(EMOTE_HELLO, me);
+ }
+ break;
+ case TEXTEMOTE_CHEER:
+ if (pPlayer->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_COMPLETE)
+ {
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ me->setFaction(FACTION_FRIENDLY);
+ DoScriptText(EMOTE_CLUCK_TEXT, me);
+ }
+ break;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_chicken_cluck(Creature* pCreature)
+{
+ return new npc_chicken_cluckAI(pCreature);
+}
+
+bool QuestAccept_npc_chicken_cluck(Player* /*pPlayer*/, Creature* pCreature, const Quest *_Quest)
+{
+ if (_Quest->GetQuestId() == QUEST_CLUCK)
+ CAST_AI(npc_chicken_cluckAI, pCreature->AI())->Reset();
+
+ return true;
+}
+
+bool QuestComplete_npc_chicken_cluck(Player* /*pPlayer*/, Creature* pCreature, const Quest *_Quest)
+{
+ if (_Quest->GetQuestId() == QUEST_CLUCK)
+ CAST_AI(npc_chicken_cluckAI, pCreature->AI())->Reset();
+
+ return true;
+}
+
+/*######
+## npc_dancing_flames
+######*/
+
+#define SPELL_BRAZIER 45423
+#define SPELL_SEDUCTION 47057
+#define SPELL_FIERY_AURA 45427
+
+struct npc_dancing_flamesAI : public ScriptedAI
+{
+ npc_dancing_flamesAI(Creature *c) : ScriptedAI(c) {}
+
+ bool active;
+ uint32 can_iteract;
+
+ void Reset()
+ {
+ active = true;
+ can_iteract = 3500;
+ DoCast(me, SPELL_BRAZIER, true);
+ DoCast(me, SPELL_FIERY_AURA, false);
+ float x, y, z;
+ me->GetPosition(x,y,z);
+ me->Relocate(x,y,z + 0.94f);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
+ WorldPacket data; //send update position to client
+ me->BuildHeartBeatMsg(&data);
+ me->SendMessageToSet(&data,true);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!active)
+ {
+ if (can_iteract <= diff){
+ active = true;
+ can_iteract = 3500;
+ me->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
+ } else can_iteract -= diff;
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/){}
+
+ void ReceiveEmote(Player* pPlayer, uint32 emote)
+ {
+ if (me->IsWithinLOS(pPlayer->GetPositionX(),pPlayer->GetPositionY(),pPlayer->GetPositionZ()) && me->IsWithinDistInMap(pPlayer,30.0f))
+ {
+ me->SetInFront(pPlayer);
+ active = false;
+
+ WorldPacket data;
+ me->BuildHeartBeatMsg(&data);
+ me->SendMessageToSet(&data,true);
+ switch(emote)
+ {
+ case TEXTEMOTE_KISS: me->HandleEmoteCommand(EMOTE_ONESHOT_SHY); break;
+ case TEXTEMOTE_WAVE: me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break;
+ case TEXTEMOTE_BOW: me->HandleEmoteCommand(EMOTE_ONESHOT_BOW); break;
+ case TEXTEMOTE_JOKE: me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); break;
+ case TEXTEMOTE_DANCE:
+ {
+ if (!pPlayer->HasAura(SPELL_SEDUCTION))
+ DoCast(pPlayer, SPELL_SEDUCTION, true);
+ }
+ break;
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_dancing_flames(Creature* pCreature)
+{
+ return new npc_dancing_flamesAI(pCreature);
+}
+
+/*######
+## Triage quest
+######*/
+
+//signed for 9623
+#define SAY_DOC1 -1000201
+#define SAY_DOC2 -1000202
+#define SAY_DOC3 -1000203
+
+#define DOCTOR_ALLIANCE 12939
+#define DOCTOR_HORDE 12920
+#define ALLIANCE_COORDS 7
+#define HORDE_COORDS 6
+
+struct Location
+{
+ float x, y, z, o;
+};
+
+static Location AllianceCoords[]=
+{
+ {-3757.38, -4533.05, 14.16, 3.62}, // Top-far-right bunk as seen from entrance
+ {-3754.36, -4539.13, 14.16, 5.13}, // Top-far-left bunk
+ {-3749.54, -4540.25, 14.28, 3.34}, // Far-right bunk
+ {-3742.10, -4536.85, 14.28, 3.64}, // Right bunk near entrance
+ {-3755.89, -4529.07, 14.05, 0.57}, // Far-left bunk
+ {-3749.51, -4527.08, 14.07, 5.26}, // Mid-left bunk
+ {-3746.37, -4525.35, 14.16, 5.22}, // Left bunk near entrance
+};
+
+//alliance run to where
+#define A_RUNTOX -3742.96
+#define A_RUNTOY -4531.52
+#define A_RUNTOZ 11.91
+
+static Location HordeCoords[]=
+{
+ {-1013.75, -3492.59, 62.62, 4.34}, // Left, Behind
+ {-1017.72, -3490.92, 62.62, 4.34}, // Right, Behind
+ {-1015.77, -3497.15, 62.82, 4.34}, // Left, Mid
+ {-1019.51, -3495.49, 62.82, 4.34}, // Right, Mid
+ {-1017.25, -3500.85, 62.98, 4.34}, // Left, front
+ {-1020.95, -3499.21, 62.98, 4.34} // Right, Front
+};
+
+//horde run to where
+#define H_RUNTOX -1016.44
+#define H_RUNTOY -3508.48
+#define H_RUNTOZ 62.96
+
+const uint32 AllianceSoldierId[3] =
+{
+ 12938, // 12938 Injured Alliance Soldier
+ 12936, // 12936 Badly injured Alliance Soldier
+ 12937 // 12937 Critically injured Alliance Soldier
+};
+
+const uint32 HordeSoldierId[3] =
+{
+ 12923, //12923 Injured Soldier
+ 12924, //12924 Badly injured Soldier
+ 12925 //12925 Critically injured Soldier
+};
+
+/*######
+## npc_doctor (handles both Gustaf Vanhowzen and Gregory Victor)
+######*/
+
+struct npc_doctorAI : public ScriptedAI
+{
+ npc_doctorAI(Creature *c) : ScriptedAI(c) {}
+
+ uint64 PlayerGUID;
+
+ uint32 SummonPatient_Timer;
+ uint32 SummonPatientCount;
+ uint32 PatientDiedCount;
+ uint32 PatientSavedCount;
+
+ bool Event;
+
+ std::list<uint64> Patients;
+ std::vector<Location*> Coordinates;
+
+ void Reset()
+ {
+ PlayerGUID = 0;
+
+ SummonPatient_Timer = 10000;
+ SummonPatientCount = 0;
+ PatientDiedCount = 0;
+ PatientSavedCount = 0;
+
+ Patients.clear();
+ Coordinates.clear();
+
+ Event = false;
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void BeginEvent(Player* pPlayer);
+ void PatientDied(Location* Point);
+ void PatientSaved(Creature* soldier, Player* pPlayer, Location* Point);
+ void UpdateAI(const uint32 diff);
+
+ void EnterCombat(Unit* /*who*/){}
+};
+
+/*#####
+## npc_injured_patient (handles all the patients, no matter Horde or Alliance)
+#####*/
+
+struct npc_injured_patientAI : public ScriptedAI
+{
+ npc_injured_patientAI(Creature *c) : ScriptedAI(c) {}
+
+ uint64 Doctorguid;
+ Location* Coord;
+
+ void Reset()
+ {
+ Doctorguid = 0;
+ Coord = NULL;
+
+ //no select
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ //no regen health
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
+
+ //to make them lay with face down
+ me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
+
+ uint32 mobId = me->GetEntry();
+
+ switch (mobId)
+ { //lower max health
+ case 12923:
+ case 12938: //Injured Soldier
+ me->SetHealth(uint32(me->GetMaxHealth()*.75));
+ break;
+ case 12924:
+ case 12936: //Badly injured Soldier
+ me->SetHealth(uint32(me->GetMaxHealth()*.50));
+ break;
+ case 12925:
+ case 12937: //Critically injured Soldier
+ me->SetHealth(uint32(me->GetMaxHealth()*.25));
+ break;
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/){}
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ if (caster->GetTypeId() == TYPEID_PLAYER && me->isAlive() && spell->Id == 20804)
+ {
+ if ((CAST_PLR(caster)->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (CAST_PLR(caster)->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
+ if (Doctorguid)
+ if (Creature* Doctor = Unit::GetCreature(*me, Doctorguid))
+ CAST_AI(npc_doctorAI, Doctor->AI())->PatientSaved(me, CAST_PLR(caster), Coord);
+
+ //make not selectable
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ //regen health
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
+
+ //stand up
+ me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
+
+ DoScriptText(RAND(SAY_DOC1,SAY_DOC2,SAY_DOC3), me);
+
+ uint32 mobId = me->GetEntry();
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+
+ switch (mobId)
+ {
+ case 12923:
+ case 12924:
+ case 12925:
+ me->GetMotionMaster()->MovePoint(0, H_RUNTOX, H_RUNTOY, H_RUNTOZ);
+ break;
+ case 12936:
+ case 12937:
+ case 12938:
+ me->GetMotionMaster()->MovePoint(0, A_RUNTOX, A_RUNTOY, A_RUNTOZ);
+ break;
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ //lower HP on every world tick makes it a useful counter, not officlone though
+ if (me->isAlive() && me->GetHealth() > 6)
+ {
+ me->SetHealth(uint32(me->GetHealth()-5));
+ }
+
+ if (me->isAlive() && me->GetHealth() <= 6)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->setDeathState(JUST_DIED);
+ me->SetFlag(UNIT_DYNAMIC_FLAGS, 32);
+
+ if (Doctorguid)
+ {
+ if (Creature* Doctor = Unit::GetCreature((*me), Doctorguid))
+ CAST_AI(npc_doctorAI, Doctor->AI())->PatientDied(Coord);
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_injured_patient(Creature* pCreature)
+{
+ return new npc_injured_patientAI (pCreature);
+}
+
+/*
+npc_doctor (continue)
+*/
+
+void npc_doctorAI::BeginEvent(Player* pPlayer)
+{
+ PlayerGUID = pPlayer->GetGUID();
+
+ SummonPatient_Timer = 10000;
+ SummonPatientCount = 0;
+ PatientDiedCount = 0;
+ PatientSavedCount = 0;
+
+ switch(me->GetEntry())
+ {
+ case DOCTOR_ALLIANCE:
+ for (uint8 i = 0; i < ALLIANCE_COORDS; ++i)
+ Coordinates.push_back(&AllianceCoords[i]);
+ break;
+ case DOCTOR_HORDE:
+ for (uint8 i = 0; i < HORDE_COORDS; ++i)
+ Coordinates.push_back(&HordeCoords[i]);
+ break;
+ }
+
+ Event = true;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+}
+
+void npc_doctorAI::PatientDied(Location* Point)
+{
+ Player* pPlayer = Unit::GetPlayer(PlayerGUID);
+ if (pPlayer && ((pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)))
+ {
+ ++PatientDiedCount;
+
+ if (PatientDiedCount > 5 && Event)
+ {
+ if (pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->FailQuest(6624);
+ else if (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->FailQuest(6622);
+
+ Reset();
+ return;
+ }
+
+ Coordinates.push_back(Point);
+ }
+ else
+ // If no player or player abandon quest in progress
+ Reset();
+}
+
+void npc_doctorAI::PatientSaved(Creature* /*soldier*/, Player* pPlayer, Location* Point)
+{
+ if (pPlayer && PlayerGUID == pPlayer->GetGUID())
+ {
+ if ((pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
+ {
+ ++PatientSavedCount;
+
+ if (PatientSavedCount == 15)
+ {
+ if (!Patients.empty())
+ {
+ std::list<uint64>::const_iterator itr;
+ for (itr = Patients.begin(); itr != Patients.end(); ++itr)
+ {
+ if (Creature* Patient = Unit::GetCreature((*me), *itr))
+ Patient->setDeathState(JUST_DIED);
+ }
+ }
+
+ if (pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->AreaExploredOrEventHappens(6624);
+ else if (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->AreaExploredOrEventHappens(6622);
+
+ Reset();
+ return;
+ }
+
+ Coordinates.push_back(Point);
+ }
+ }
+}
+
+void npc_doctorAI::UpdateAI(const uint32 diff)
+{
+ if (Event && SummonPatientCount >= 20)
+ {
+ Reset();
+ return;
+ }
+
+ if (Event)
+ {
+ if (SummonPatient_Timer <= diff)
+ {
+ Creature* Patient = NULL;
+ Location* Point = NULL;
+
+ if (Coordinates.empty())
+ return;
+
+ std::vector<Location*>::iterator itr = Coordinates.begin()+rand()%Coordinates.size();
+ uint32 patientEntry = 0;
+
+ switch(me->GetEntry())
+ {
+ case DOCTOR_ALLIANCE: patientEntry = AllianceSoldierId[rand()%3]; break;
+ case DOCTOR_HORDE: patientEntry = HordeSoldierId[rand()%3]; break;
+ default:
+ error_log("TSCR: Invalid entry for Triage doctor. Please check your database");
+ return;
+ }
+
+ Point = *itr;
+
+ Patient = me->SummonCreature(patientEntry, Point->x, Point->y, Point->z, Point->o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+
+ if (Patient)
+ {
+ //303, this flag appear to be required for client side item->spell to work (TARGET_SINGLE_FRIEND)
+ Patient->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ Patients.push_back(Patient->GetGUID());
+ CAST_AI(npc_injured_patientAI, Patient->AI())->Doctorguid = me->GetGUID();
+
+ if (Point)
+ CAST_AI(npc_injured_patientAI, Patient->AI())->Coord = Point;
+
+ Coordinates.erase(itr);
+ }
+ SummonPatient_Timer = 10000;
+ ++SummonPatientCount;
+ } else SummonPatient_Timer -= diff;
+ }
+}
+
+bool QuestAccept_npc_doctor(Player* pPlayer, Creature* pCreature, Quest const *quest)
+{
+ if ((quest->GetQuestId() == 6624) || (quest->GetQuestId() == 6622))
+ CAST_AI(npc_doctorAI, pCreature->AI())->BeginEvent(pPlayer);
+
+ return true;
+}
+
+CreatureAI* GetAI_npc_doctor(Creature* pCreature)
+{
+ return new npc_doctorAI (pCreature);
+}
+
+/*######
+## npc_garments_of_quests
+######*/
+
+//TODO: get text for each NPC
+
+enum eGarments
+{
+ SPELL_LESSER_HEAL_R2 = 2052,
+ SPELL_FORTITUDE_R1 = 1243,
+
+ QUEST_MOON = 5621,
+ QUEST_LIGHT_1 = 5624,
+ QUEST_LIGHT_2 = 5625,
+ QUEST_SPIRIT = 5648,
+ QUEST_DARKNESS = 5650,
+
+ ENTRY_SHAYA = 12429,
+ ENTRY_ROBERTS = 12423,
+ ENTRY_DOLF = 12427,
+ ENTRY_KORJA = 12430,
+ ENTRY_DG_KEL = 12428,
+
+ //used by 12429,12423,12427,12430,12428, but signed for 12429
+ SAY_COMMON_HEALED = -1000164,
+ SAY_DG_KEL_THANKS = -1000165,
+ SAY_DG_KEL_GOODBYE = -1000166,
+ SAY_ROBERTS_THANKS = -1000167,
+ SAY_ROBERTS_GOODBYE = -1000168,
+ SAY_KORJA_THANKS = -1000169,
+ SAY_KORJA_GOODBYE = -1000170,
+ SAY_DOLF_THANKS = -1000171,
+ SAY_DOLF_GOODBYE = -1000172,
+ SAY_SHAYA_THANKS = -1000173,
+ SAY_SHAYA_GOODBYE = -1000174, //signed for 21469
+};
+
+struct npc_garments_of_questsAI : public npc_escortAI
+{
+ npc_garments_of_questsAI(Creature *c) : npc_escortAI(c) {Reset();}
+
+ uint64 caster;
+
+ bool bIsHealed;
+ bool bCanRun;
+
+ uint32 RunAwayTimer;
+
+ void Reset()
+ {
+ caster = 0;
+
+ bIsHealed = false;
+ bCanRun = false;
+
+ RunAwayTimer = 5000;
+
+ me->SetStandState(UNIT_STAND_STATE_KNEEL);
+ //expect database to have RegenHealth=0
+ me->SetHealth(int(me->GetMaxHealth()*0.7));
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+
+ void SpellHit(Unit* pCaster, const SpellEntry *Spell)
+ {
+ if (Spell->Id == SPELL_LESSER_HEAL_R2 || Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ //not while in combat
+ if (me->isInCombat())
+ return;
+
+ //nothing to be done now
+ if (bIsHealed && bCanRun)
+ return;
+
+ if (pCaster->GetTypeId() == TYPEID_PLAYER)
+ {
+ switch(me->GetEntry())
+ {
+ case ENTRY_SHAYA:
+ if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_MOON) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_SHAYA_THANKS,me,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,me,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_ROBERTS:
+ if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_LIGHT_1) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_ROBERTS_THANKS,me,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,me,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_DOLF:
+ if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_LIGHT_2) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_DOLF_THANKS,me,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,me,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_KORJA:
+ if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_SPIRIT) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_KORJA_THANKS,me,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,me,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ case ENTRY_DG_KEL:
+ if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_DARKNESS) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
+ {
+ DoScriptText(SAY_DG_KEL_THANKS,me,pCaster);
+ bCanRun = true;
+ }
+ else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
+ {
+ caster = pCaster->GetGUID();
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_COMMON_HEALED,me,pCaster);
+ bIsHealed = true;
+ }
+ }
+ break;
+ }
+
+ //give quest credit, not expect any special quest objectives
+ if (bCanRun)
+ CAST_PLR(pCaster)->TalkedToCreature(me->GetEntry(),me->GetGUID());
+ }
+ }
+ }
+
+ void WaypointReached(uint32 /*uiPoint*/)
+ {
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (bCanRun && !me->isInCombat())
+ {
+ if (RunAwayTimer <= diff)
+ {
+ if (Unit *pUnit = Unit::GetUnit(*me,caster))
+ {
+ switch(me->GetEntry())
+ {
+ case ENTRY_SHAYA: DoScriptText(SAY_SHAYA_GOODBYE,me,pUnit); break;
+ case ENTRY_ROBERTS: DoScriptText(SAY_ROBERTS_GOODBYE,me,pUnit); break;
+ case ENTRY_DOLF: DoScriptText(SAY_DOLF_GOODBYE,me,pUnit); break;
+ case ENTRY_KORJA: DoScriptText(SAY_KORJA_GOODBYE,me,pUnit); break;
+ case ENTRY_DG_KEL: DoScriptText(SAY_DG_KEL_GOODBYE,me,pUnit); break;
+ }
+
+ Start(false,true,true);
+ }
+ else
+ EnterEvadeMode(); //something went wrong
+
+ RunAwayTimer = 30000;
+ } else RunAwayTimer -= diff;
+ }
+
+ npc_escortAI::UpdateAI(diff);
+ }
+};
+
+CreatureAI* GetAI_npc_garments_of_quests(Creature* pCreature)
+{
+ return new npc_garments_of_questsAI(pCreature);
+}
+
+/*######
+## npc_guardian
+######*/
+
+#define SPELL_DEATHTOUCH 5
+
+struct npc_guardianAI : public ScriptedAI
+{
+ npc_guardianAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->isAttackReady())
+ {
+ DoCast(me->getVictim(), SPELL_DEATHTOUCH, true);
+ me->resetAttackTimer();
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_guardian(Creature* pCreature)
+{
+ return new npc_guardianAI (pCreature);
+}
+
+/*######
+## npc_kingdom_of_dalaran_quests
+######*/
+
+enum eKingdomDalaran
+{
+ SPELL_TELEPORT_DALARAN = 53360,
+ ITEM_KT_SIGNET = 39740,
+ QUEST_MAGICAL_KINGDOM_A = 12794,
+ QUEST_MAGICAL_KINGDOM_H = 12791,
+ QUEST_MAGICAL_KINGDOM_N = 12796
+};
+
+#define GOSSIP_ITEM_TELEPORT_TO "I am ready to be teleported to Dalaran."
+
+bool GossipHello_npc_kingdom_of_dalaran_quests(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->HasItemCount(ITEM_KT_SIGNET,1) && (!pPlayer->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_A) ||
+ !pPlayer->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_H) || !pPlayer->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_N)))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TELEPORT_TO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_kingdom_of_dalaran_quests(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,SPELL_TELEPORT_DALARAN,false);
+ }
+ return true;
+}
+
+/*######
+## npc_mount_vendor
+######*/
+
+bool GossipHello_npc_mount_vendor(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ bool canBuy;
+ canBuy = false;
+ uint32 vendor = pCreature->GetEntry();
+ uint8 race = pPlayer->getRace();
+
+ switch (vendor)
+ {
+ case 384: //Katie Hunter
+ case 1460: //Unger Statforth
+ case 2357: //Merideth Carlson
+ case 4885: //Gregor MacVince
+ if (pPlayer->GetReputationRank(72) != REP_EXALTED && race != RACE_HUMAN)
+ pPlayer->SEND_GOSSIP_MENU(5855, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 1261: //Veron Amberstill
+ if (pPlayer->GetReputationRank(47) != REP_EXALTED && race != RACE_DWARF)
+ pPlayer->SEND_GOSSIP_MENU(5856, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 3362: //Ogunaro Wolfrunner
+ if (pPlayer->GetReputationRank(76) != REP_EXALTED && race != RACE_ORC)
+ pPlayer->SEND_GOSSIP_MENU(5841, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 3685: //Harb Clawhoof
+ if (pPlayer->GetReputationRank(81) != REP_EXALTED && race != RACE_TAUREN)
+ pPlayer->SEND_GOSSIP_MENU(5843, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 4730: //Lelanai
+ if (pPlayer->GetReputationRank(69) != REP_EXALTED && race != RACE_NIGHTELF)
+ pPlayer->SEND_GOSSIP_MENU(5844, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 4731: //Zachariah Post
+ if (pPlayer->GetReputationRank(68) != REP_EXALTED && race != RACE_UNDEAD_PLAYER)
+ pPlayer->SEND_GOSSIP_MENU(5840, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 7952: //Zjolnir
+ if (pPlayer->GetReputationRank(530) != REP_EXALTED && race != RACE_TROLL)
+ pPlayer->SEND_GOSSIP_MENU(5842, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 7955: //Milli Featherwhistle
+ if (pPlayer->GetReputationRank(54) != REP_EXALTED && race != RACE_GNOME)
+ pPlayer->SEND_GOSSIP_MENU(5857, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 16264: //Winaestra
+ if (pPlayer->GetReputationRank(911) != REP_EXALTED && race != RACE_BLOODELF)
+ pPlayer->SEND_GOSSIP_MENU(10305, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ case 17584: //Torallius the Pack Handler
+ if (pPlayer->GetReputationRank(930) != REP_EXALTED && race != RACE_DRAENEI)
+ pPlayer->SEND_GOSSIP_MENU(10239, pCreature->GetGUID());
+ else canBuy = true;
+ break;
+ }
+
+ if (canBuy)
+ {
+ if (pCreature->isVendor())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ }
+ return true;
+}
+
+bool GossipSelect_npc_mount_vendor(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_TRADE)
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+
+ return true;
+}
+
+/*######
+## npc_rogue_trainer
+######*/
+
+#define GOSSIP_HELLO_ROGUE1 "I wish to unlearn my talents"
+#define GOSSIP_HELLO_ROGUE2 "<Take the letter>"
+#define GOSSIP_HELLO_ROGUE3 "Purchase a Dual Talent Specialization."
+
+bool GossipHello_npc_rogue_trainer(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pCreature->isTrainer())
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
+
+ if (pCreature->isCanTrainingAndResetTalentsOf(pPlayer))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_HELLO_ROGUE1, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_UNLEARNTALENTS);
+
+ if (!(pPlayer->GetSpecsCount() == 1 && pCreature->isCanTrainingAndResetTalentsOf(pPlayer) && !(pPlayer->getLevel() < sWorld.getConfig(CONFIG_MIN_DUALSPEC_LEVEL))))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_HELLO_ROGUE3, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_LEARNDUALSPEC);
+
+ if (pPlayer->getClass() == CLASS_ROGUE && pPlayer->getLevel() >= 24 && !pPlayer->HasItemCount(17126,1) && !pPlayer->GetQuestRewardStatus(6681))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_ROGUE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(5996, pCreature->GetGUID());
+ } else
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_rogue_trainer(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer,21100,false);
+ break;
+ case GOSSIP_ACTION_TRAIN:
+ pPlayer->SEND_TRAINERLIST(pCreature->GetGUID());
+ break;
+ case GOSSIP_OPTION_UNLEARNTALENTS:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->SendTalentWipeConfirm(pCreature->GetGUID());
+ break;
+ case GOSSIP_OPTION_LEARNDUALSPEC:
+ if (pPlayer->GetSpecsCount() == 1 && !(pPlayer->getLevel() < sWorld.getConfig(CONFIG_MIN_DUALSPEC_LEVEL)))
+ {
+ if (pPlayer->GetMoney() < 10000000)
+ {
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
+ pPlayer->PlayerTalkClass->CloseGossip();
+ break;
+ }
+ else
+ {
+ pPlayer->ModifyMoney(-10000000);
+
+ // Cast spells that teach dual spec
+ // Both are also ImplicitTarget self and must be cast by player
+ pPlayer->CastSpell(pPlayer,63680,true,NULL,NULL,pPlayer->GetGUID());
+ pPlayer->CastSpell(pPlayer,63624,true,NULL,NULL,pPlayer->GetGUID());
+
+ // Should show another Gossip text with "Congratulations..."
+ pPlayer->PlayerTalkClass->CloseGossip();
+ }
+ }
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_sayge
+######*/
+
+#define SPELL_DMG 23768 //dmg
+#define SPELL_RES 23769 //res
+#define SPELL_ARM 23767 //arm
+#define SPELL_SPI 23738 //spi
+#define SPELL_INT 23766 //int
+#define SPELL_STM 23737 //stm
+#define SPELL_STR 23735 //str
+#define SPELL_AGI 23736 //agi
+#define SPELL_FORTUNE 23765 //faire fortune
+
+#define GOSSIP_HELLO_SAYGE "Yes"
+#define GOSSIP_SENDACTION_SAYGE1 "Slay the Man"
+#define GOSSIP_SENDACTION_SAYGE2 "Turn him over to liege"
+#define GOSSIP_SENDACTION_SAYGE3 "Confiscate the corn"
+#define GOSSIP_SENDACTION_SAYGE4 "Let him go and have the corn"
+#define GOSSIP_SENDACTION_SAYGE5 "Execute your friend painfully"
+#define GOSSIP_SENDACTION_SAYGE6 "Execute your friend painlessly"
+#define GOSSIP_SENDACTION_SAYGE7 "Let your friend go"
+#define GOSSIP_SENDACTION_SAYGE8 "Confront the diplomat"
+#define GOSSIP_SENDACTION_SAYGE9 "Show not so quiet defiance"
+#define GOSSIP_SENDACTION_SAYGE10 "Remain quiet"
+#define GOSSIP_SENDACTION_SAYGE11 "Speak against your brother openly"
+#define GOSSIP_SENDACTION_SAYGE12 "Help your brother in"
+#define GOSSIP_SENDACTION_SAYGE13 "Keep your brother out without letting him know"
+#define GOSSIP_SENDACTION_SAYGE14 "Take credit, keep gold"
+#define GOSSIP_SENDACTION_SAYGE15 "Take credit, share the gold"
+#define GOSSIP_SENDACTION_SAYGE16 "Let the knight take credit"
+#define GOSSIP_SENDACTION_SAYGE17 "Thanks"
+
+bool GossipHello_npc_sayge(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->HasSpellCooldown(SPELL_INT) ||
+ pPlayer->HasSpellCooldown(SPELL_ARM) ||
+ pPlayer->HasSpellCooldown(SPELL_DMG) ||
+ pPlayer->HasSpellCooldown(SPELL_RES) ||
+ pPlayer->HasSpellCooldown(SPELL_STR) ||
+ pPlayer->HasSpellCooldown(SPELL_AGI) ||
+ pPlayer->HasSpellCooldown(SPELL_STM) ||
+ pPlayer->HasSpellCooldown(SPELL_SPI))
+ pPlayer->SEND_GOSSIP_MENU(7393, pCreature->GetGUID());
+ else
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_SAYGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(7339, pCreature->GetGUID());
+ }
+
+ return true;
+}
+
+void SendAction_npc_sayge(Player* pPlayer, Creature* pCreature, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
+ pPlayer->SEND_GOSSIP_MENU(7340, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE5, GOSSIP_SENDER_MAIN+1, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE6, GOSSIP_SENDER_MAIN+2, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE7, GOSSIP_SENDER_MAIN+3, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->SEND_GOSSIP_MENU(7341, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE8, GOSSIP_SENDER_MAIN+4, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE9, GOSSIP_SENDER_MAIN+5, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE10, GOSSIP_SENDER_MAIN+2, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->SEND_GOSSIP_MENU(7361, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+4:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE11, GOSSIP_SENDER_MAIN+6, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE12, GOSSIP_SENDER_MAIN+7, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE13, GOSSIP_SENDER_MAIN+8, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->SEND_GOSSIP_MENU(7362, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+5:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE14, GOSSIP_SENDER_MAIN+5, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE15, GOSSIP_SENDER_MAIN+4, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE16, GOSSIP_SENDER_MAIN+3, GOSSIP_ACTION_INFO_DEF);
+ pPlayer->SEND_GOSSIP_MENU(7363, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE17, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
+ pPlayer->SEND_GOSSIP_MENU(7364, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+6:
+ pCreature->CastSpell(pPlayer, SPELL_FORTUNE, false);
+ pPlayer->SEND_GOSSIP_MENU(7365, pCreature->GetGUID());
+ break;
+ }
+}
+
+bool GossipSelect_npc_sayge(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch(uiSender)
+ {
+ case GOSSIP_SENDER_MAIN:
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+1:
+ pCreature->CastSpell(pPlayer, SPELL_DMG, false);
+ pPlayer->AddSpellCooldown(SPELL_DMG,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+2:
+ pCreature->CastSpell(pPlayer, SPELL_RES, false);
+ pPlayer->AddSpellCooldown(SPELL_RES,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+3:
+ pCreature->CastSpell(pPlayer, SPELL_ARM, false);
+ pPlayer->AddSpellCooldown(SPELL_ARM,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+4:
+ pCreature->CastSpell(pPlayer, SPELL_SPI, false);
+ pPlayer->AddSpellCooldown(SPELL_SPI,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+5:
+ pCreature->CastSpell(pPlayer, SPELL_INT, false);
+ pPlayer->AddSpellCooldown(SPELL_INT,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+6:
+ pCreature->CastSpell(pPlayer, SPELL_STM, false);
+ pPlayer->AddSpellCooldown(SPELL_STM,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+7:
+ pCreature->CastSpell(pPlayer, SPELL_STR, false);
+ pPlayer->AddSpellCooldown(SPELL_STR,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ case GOSSIP_SENDER_MAIN+8:
+ pCreature->CastSpell(pPlayer, SPELL_AGI, false);
+ pPlayer->AddSpellCooldown(SPELL_AGI,0,time(NULL) + 7200);
+ SendAction_npc_sayge(pPlayer, pCreature, uiAction);
+ break;
+ }
+ return true;
+}
+
+struct npc_steam_tonkAI : public ScriptedAI
+{
+ npc_steam_tonkAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit * /*who*/) {}
+
+ void OnPossess(bool apply)
+ {
+ if (apply)
+ {
+ // Initialize the action bar without the melee attack command
+ me->InitCharmInfo();
+ me->GetCharmInfo()->InitEmptyActionBar(false);
+
+ me->SetReactState(REACT_PASSIVE);
+ }
+ else
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+
+};
+
+CreatureAI* GetAI_npc_steam_tonk(Creature* pCreature)
+{
+ return new npc_steam_tonkAI(pCreature);
+}
+
+#define SPELL_TONK_MINE_DETONATE 25099
+
+struct npc_tonk_mineAI : public ScriptedAI
+{
+ npc_tonk_mineAI(Creature *c) : ScriptedAI(c)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ uint32 ExplosionTimer;
+
+ void Reset()
+ {
+ ExplosionTimer = 3000;
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+ void AttackStart(Unit * /*who*/) {}
+ void MoveInLineOfSight(Unit * /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (ExplosionTimer <= diff)
+ {
+ DoCast(me, SPELL_TONK_MINE_DETONATE, true);
+ me->setDeathState(DEAD); // unsummon it
+ } else
+ ExplosionTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_npc_tonk_mine(Creature* pCreature)
+{
+ return new npc_tonk_mineAI(pCreature);
+}
+
+/*####
+## npc_brewfest_reveler
+####*/
+
+struct npc_brewfest_revelerAI : public ScriptedAI
+{
+ npc_brewfest_revelerAI(Creature* c) : ScriptedAI(c) {}
+ void ReceiveEmote(Player* pPlayer, uint32 emote)
+ {
+ if (!IsHolidayActive(HOLIDAY_BREWFEST))
+ return;
+
+ if (emote == TEXTEMOTE_DANCE)
+ me->CastSpell(pPlayer, 41586, false);
+ }
+};
+
+CreatureAI* GetAI_npc_brewfest_reveler(Creature* pCreature)
+{
+ return new npc_brewfest_revelerAI(pCreature);
+}
+
+/*####
+## npc_winter_reveler
+####*/
+
+struct npc_winter_revelerAI : public ScriptedAI
+{
+ npc_winter_revelerAI(Creature* c) : ScriptedAI(c) {}
+ void ReceiveEmote(Player* pPlayer, uint32 emote)
+ {
+ if (!IsHolidayActive(HOLIDAY_FEAST_OF_WINTER_VEIL))
+ return;
+ //TODO: check auralist.
+ if (pPlayer->HasAura(26218))
+ return;
+
+ if (emote == TEXTEMOTE_KISS)
+ {
+ me->CastSpell(me, 26218, false);
+ pPlayer->CastSpell(pPlayer, 26218, false);
+ switch (urand(0,2))
+ {
+ case 0: me->CastSpell(pPlayer, 26207, false); break;
+ case 1: me->CastSpell(pPlayer, 26206, false); break;
+ case 2: me->CastSpell(pPlayer, 45036, false); break;
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_winter_reveler(Creature* pCreature)
+{
+ return new npc_winter_revelerAI(pCreature);
+}
+
+
+/*####
+## npc_snake_trap_serpents
+####*/
+
+#define SPELL_MIND_NUMBING_POISON 25810 //Viper
+#define SPELL_DEADLY_POISON 34655 //Venomous Snake
+#define SPELL_CRIPPLING_POISON 30981 //Viper
+
+#define VENOMOUS_SNAKE_TIMER 1500
+#define VIPER_TIMER 3000
+
+#define C_VIPER 19921
+
+#define RAND 5
+
+struct npc_snake_trap_serpentsAI : public ScriptedAI
+{
+ npc_snake_trap_serpentsAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 SpellTimer;
+ bool IsViper;
+ bool Spawn;
+
+ void EnterCombat(Unit * /*who*/) {}
+
+ void Reset()
+ {
+ Spawn = true;
+ SpellTimer = 0;
+
+ CreatureInfo const *Info = me->GetCreatureInfo();
+
+ if (Info->Entry == C_VIPER)
+ IsViper = true;
+ else
+ IsViper = false;
+
+ //Add delta to make them not all hit the same time
+ uint32 delta = (rand() % 7) * 100;
+ me->SetStatFloatValue(UNIT_FIELD_BASEATTACKTIME, Info->baseattacktime + delta);
+ me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER , Info->attackpower);
+ }
+
+ //Redefined for random target selection:
+ void MoveInLineOfSight(Unit *who)
+ {
+ if (!me->getVictim() && who->isTargetableForAttack() && (me->IsHostileTo(who)) && who->isInAccessiblePlaceFor(me))
+ {
+ if (me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = me->GetAttackDistance(who);
+ if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who))
+ {
+ if (!(rand() % RAND))
+ {
+ me->setAttackTimer(BASE_ATTACK, (rand() % 10) * 100);
+ SpellTimer = (rand() % 10) * 100;
+ AttackStart(who);
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (Spawn)
+ {
+ Spawn = false;
+ // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
+ if (!me->getVictim() && me->isSummon())
+ if (Unit * Owner = CAST_SUM(me)->GetSummoner())
+ if (Owner->getAttackerForHelper())
+ AttackStart(Owner->getAttackerForHelper());
+ }
+
+ if (!me->getVictim())
+ {
+ if (me->isInCombat())
+ DoStopAttack();
+ return;
+ }
+
+ if (SpellTimer <= diff)
+ {
+ if (IsViper) //Viper
+ {
+ if (urand(0,2) == 0) //33% chance to cast
+ {
+ uint32 spell;
+ if (urand(0,1) == 0)
+ spell = SPELL_MIND_NUMBING_POISON;
+ else
+ spell = SPELL_CRIPPLING_POISON;
+
+ DoCast(me->getVictim(), spell);
+ }
+
+ SpellTimer = VIPER_TIMER;
+ }
+ else //Venomous Snake
+ {
+ if (urand(0,2) == 0) //33% chance to cast
+ DoCast(me->getVictim(), SPELL_DEADLY_POISON);
+ SpellTimer = VENOMOUS_SNAKE_TIMER + (rand() %5)*100;
+ }
+ } else SpellTimer -= diff;
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_snake_trap_serpents(Creature* pCreature)
+{
+ return new npc_snake_trap_serpentsAI(pCreature);
+}
+
+#define SAY_RANDOM_MOJO0 "Now that's what I call froggy-style!"
+#define SAY_RANDOM_MOJO1 "Your lily pad or mine?"
+#define SAY_RANDOM_MOJO2 "This won't take long, did it?"
+#define SAY_RANDOM_MOJO3 "I thought you'd never ask!"
+#define SAY_RANDOM_MOJO4 "I promise not to give you warts..."
+#define SAY_RANDOM_MOJO5 "Feelin' a little froggy, are ya?"
+#define SAY_RANDOM_MOJO6a "Listen, "
+#define SAY_RANDOM_MOJO6b ", I know of a little swamp not too far from here...."
+#define SAY_RANDOM_MOJO7 "There's just never enough Mojo to go around..."
+
+struct mob_mojoAI : public ScriptedAI
+{
+ mob_mojoAI(Creature *c) : ScriptedAI(c) {Reset();}
+ uint32 hearts;
+ uint64 victimGUID;
+ void Reset()
+ {
+ victimGUID = 0;
+ hearts = 15000;
+ if (Unit* own = me->GetOwner())
+ me->GetMotionMaster()->MoveFollow(own,0,0);
+ }
+ void Aggro(Unit * /*who*/){}
+ void UpdateAI(const uint32 diff)
+ {
+ if (me->HasAura(20372))
+ {
+ if (hearts <= diff)
+ {
+ me->RemoveAurasDueToSpell(20372);
+ hearts = 15000;
+ } hearts -= diff;
+ }
+ }
+ void ReceiveEmote(Player* pPlayer, uint32 emote)
+ {
+ me->HandleEmoteCommand(emote);
+ Unit* own = me->GetOwner();
+ if (!own || own->GetTypeId() != TYPEID_PLAYER || CAST_PLR(own)->GetTeam() != pPlayer->GetTeam())
+ return;
+ if (emote == TEXTEMOTE_KISS)
+ {
+ std::string whisp = "";
+ switch (rand()%8)
+ {
+ case 0:whisp.append(SAY_RANDOM_MOJO0);break;
+ case 1:whisp.append(SAY_RANDOM_MOJO1);break;
+ case 2:whisp.append(SAY_RANDOM_MOJO2);break;
+ case 3:whisp.append(SAY_RANDOM_MOJO3);break;
+ case 4:whisp.append(SAY_RANDOM_MOJO4);break;
+ case 5:whisp.append(SAY_RANDOM_MOJO5);break;
+ case 6:
+ whisp.append(SAY_RANDOM_MOJO6a);
+ whisp.append(pPlayer->GetName());
+ whisp.append(SAY_RANDOM_MOJO6b);
+ break;
+ case 7:whisp.append(SAY_RANDOM_MOJO7);break;
+ }
+ me->MonsterWhisper(whisp.c_str(),pPlayer->GetGUID());
+ if (victimGUID)
+ {
+ Player* victim = Unit::GetPlayer(victimGUID);
+ if (victim)
+ victim->RemoveAura(43906);//remove polymorph frog thing
+ }
+ me->AddAura(43906,pPlayer);//add polymorph frog thing
+ victimGUID = pPlayer->GetGUID();
+ DoCast(me, 20372, true);//tag.hearts
+ me->GetMotionMaster()->MoveFollow(pPlayer,0,0);
+ hearts = 15000;
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_mojo(Creature* pCreature)
+{
+ return new mob_mojoAI (pCreature);
+}
+
+struct npc_mirror_image : CasterAI
+{
+ npc_mirror_image(Creature *c) : CasterAI(c) {}
+
+ void InitializeAI()
+ {
+ CasterAI::InitializeAI();
+ Unit * owner = me->GetOwner();
+ if (!owner)
+ return;
+ // Inherit Master's Threat List (not yet implemented)
+ owner->CastSpell((Unit*)NULL, 58838, true);
+ // here mirror image casts on summoner spell (not present in client dbc) 49866
+ // here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
+ // Clone Me!
+ owner->CastSpell(me, 45204, false);
+ }
+
+ // Do not reload Creature templates on evade mode enter - prevent visual lost
+ void EnterEvadeMode()
+ {
+ if (me->IsInEvadeMode() || !me->isAlive())
+ return;
+
+ Unit *owner = me->GetCharmerOrOwner();
+
+ me->CombatStop(true);
+ if (owner && !me->hasUnitState(UNIT_STAT_FOLLOW))
+ {
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_mirror_image(Creature* pCreature)
+{
+ return new npc_mirror_image (pCreature);
+}
+
+struct npc_ebon_gargoyleAI : CasterAI
+{
+ npc_ebon_gargoyleAI(Creature *c) : CasterAI(c) {}
+
+ int despawnTimer;
+
+ void InitializeAI()
+ {
+ CasterAI::InitializeAI();
+ Unit * owner = me->GetOwner();
+ if (!owner)
+ return;
+ // Not needed to be despawned now
+ despawnTimer = 0;
+ // Find victim of Summon Gargoyle spell
+ std::list<Unit*> targets;
+ Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check);
+ me->VisitNearbyObject(30, searcher);
+ for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
+ if ((*iter)->GetAura(49206,owner->GetGUID()))
+ {
+ me->Attack((*iter),false);
+ break;
+ }
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ // Stop Feeding Gargoyle when it dies
+ if (Unit *owner = me->GetOwner())
+ owner->RemoveAurasDueToSpell(50514);
+ }
+
+ // Fly away when dismissed
+ void SpellHit(Unit *source, const SpellEntry *spell)
+ {
+ if (spell->Id != 50515 || !me->isAlive())
+ return;
+
+ Unit *owner = me->GetOwner();
+
+ if (!owner || owner != source)
+ return;
+
+ // Stop Fighting
+ me->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, true);
+ // Sanctuary
+ me->CastSpell(me, 54661, true);
+ me->SetReactState(REACT_PASSIVE);
+
+ // Fly Away
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE|MOVEMENTFLAG_ASCEND|MOVEMENTFLAG_FLYING);
+ me->SetSpeed(MOVE_FLIGHT, 0.75f, true);
+ me->SetSpeed(MOVE_RUN, 0.75f, true);
+ float x = me->GetPositionX() + 20 * cos(me->GetOrientation());
+ float y = me->GetPositionY() + 20 * sin(me->GetOrientation());
+ float z = me->GetPositionZ() + 40;
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MovePoint(0, x, y, z);
+
+ // Despawn as soon as possible
+ despawnTimer = 4 * IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (despawnTimer > 0)
+ {
+ if (despawnTimer > diff)
+ despawnTimer -= diff;
+ else
+ {
+ me->ForcedDespawn();
+ }
+ return;
+ }
+ CasterAI::UpdateAI(diff);
+ }
+};
+
+CreatureAI* GetAI_npc_ebon_gargoyle(Creature* pCreature)
+{
+ return new npc_ebon_gargoyleAI (pCreature);
+}
+
+struct npc_lightwellAI : public PassiveAI
+{
+ npc_lightwellAI(Creature *c) : PassiveAI(c) {}
+
+ void Reset()
+ {
+ DoCast(me, 59907, false); // Spell for Lightwell Charges
+ }
+};
+
+CreatureAI* GetAI_npc_lightwellAI(Creature* pCreature)
+{
+ return new npc_lightwellAI (pCreature);
+}
+
+struct npc_training_dummy : Scripted_NoMovementAI
+{
+ npc_training_dummy(Creature *c) : Scripted_NoMovementAI(c)
+ {
+ m_Entry = c->GetEntry();
+ }
+
+ uint64 m_Entry;
+ uint32 ResetTimer;
+ uint32 DespawnTimer;
+ void Reset()
+ {
+ me->SetControlled(true,UNIT_STAT_STUNNED);//disable rotate
+ me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);//imune to knock aways like blast wave
+ me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);
+ ResetTimer = 10000;
+ DespawnTimer = 15000;
+ }
+
+ void EnterEvadeMode()
+ {
+ if (!_EnterEvadeMode())
+ return;
+
+ Reset();
+ }
+
+ void DamageTaken(Unit * /*done_by*/, uint32 &damage)
+ {
+ ResetTimer = 10000;
+ damage = 0;
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ if (m_Entry != 2674 && m_Entry != 2673)
+ return;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+ if (!me->hasUnitState(UNIT_STAT_STUNNED))
+ me->SetControlled(true,UNIT_STAT_STUNNED);//disable rotate
+
+ if (m_Entry != 2674 && m_Entry != 2673)
+ {
+ if (ResetTimer <= diff)
+ {
+ EnterEvadeMode();
+ ResetTimer = 10000;
+ }
+ else
+ ResetTimer -= diff;
+ return;
+ }
+ else
+ {
+ if (DespawnTimer <= diff)
+ me->ForcedDespawn();
+ else
+ DespawnTimer -= diff;
+ }
+ }
+ void MoveInLineOfSight(Unit * /*who*/){return;}
+};
+
+CreatureAI* GetAI_npc_training_dummy(Creature* pCreature)
+{
+ return new npc_training_dummy (pCreature);
+}
+
+/*######
+# npc_shadowfiend
+######*/
+#define GLYPH_OF_SHADOWFIEND_MANA 58227
+#define GLYPH_OF_SHADOWFIEND 58228
+
+struct npc_shadowfiendAI : public ScriptedAI
+{
+ npc_shadowfiendAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ void DamageTaken(Unit* /*pKiller*/, uint32 &damage)
+ {
+ if (me->isSummon())
+ if (Unit* pOwner = CAST_SUM(me)->GetSummoner())
+ {
+ if (pOwner->HasAura(GLYPH_OF_SHADOWFIEND))
+ if (damage >= me->GetHealth())
+ pOwner->CastSpell(pOwner,GLYPH_OF_SHADOWFIEND_MANA,true);
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_shadowfiend(Creature* pCreature)
+{
+ return new npc_shadowfiendAI(pCreature);
+}
+
+/*######
+# npc_wormhole
+######*/
+
+#define GOSSIP_ENGINEERING1 "Borean Tundra."
+#define GOSSIP_ENGINEERING2 "Howling Fjord."
+#define GOSSIP_ENGINEERING3 "Sholazar Basin."
+#define GOSSIP_ENGINEERING4 "Icecrown."
+#define GOSSIP_ENGINEERING5 "Storm Peaks."
+
+enum eWormhole
+{
+ SPELL_HOWLING_FJORD = 67838,
+ SPELL_SHOLAZAR_BASIN = 67835,
+ SPELL_ICECROWN = 67836,
+ SPELL_STORM_PEAKS = 67837,
+
+ TEXT_WORMHOLE = 907
+};
+
+bool GossipHello_npc_wormhole(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isSummon())
+ {
+ if (pPlayer == CAST_SUM(pCreature)->GetSummoner())
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
+
+ pPlayer->PlayerTalkClass->SendGossipMenu(TEXT_WORMHOLE, pCreature->GetGUID());
+ }
+ }
+ return true;
+}
+
+bool GossipSelect_npc_wormhole(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ bool roll = urand(0,1);
+
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1: //Borean Tundra
+ pPlayer->CLOSE_GOSSIP_MENU();
+ if (roll) //At the moment we don't have chance on spell_target_position table so we hack this
+ pPlayer->TeleportTo(571, 4305.505859, 5450.839844, 63.005806, 0.627286);
+ else
+ pPlayer->TeleportTo(571, 3201.936279, 5630.123535, 133.658798, 3.855272);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2: //Howling Fjord
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_HOWLING_FJORD, true);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 3: //Sholazar Basin
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_SHOLAZAR_BASIN, true);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 4: //Icecrown
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_ICECROWN, true);
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 5: //Storm peaks
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_STORM_PEAKS, true);
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_pet_trainer
+######*/
+
+enum ePetTrainer
+{
+ TEXT_ISHUNTER = 5838,
+ TEXT_NOTHUNTER = 5839,
+ TEXT_PETINFO = 13474,
+ TEXT_CONFIRM = 7722
+};
+
+#define GOSSIP_PET1 "How do I train my pet?"
+#define GOSSIP_PET2 "I wish to untrain my pet."
+#define GOSSIP_PET_CONFIRM "Yes, please do."
+
+bool GossipHello_npc_pet_trainer(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->getClass() == CLASS_HUNTER)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_PET1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ if (pPlayer->GetPet() && pPlayer->GetPet()->getPetType() == HUNTER_PET)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_PET2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ pPlayer->PlayerTalkClass->SendGossipMenu(TEXT_ISHUNTER, pCreature->GetGUID());
+ return true;
+ }
+ pPlayer->PlayerTalkClass->SendGossipMenu(TEXT_NOTHUNTER, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_pet_trainer(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ pPlayer->PlayerTalkClass->SendGossipMenu(TEXT_PETINFO, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_PET_CONFIRM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ pPlayer->PlayerTalkClass->SendGossipMenu(TEXT_CONFIRM, pCreature->GetGUID());
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ {
+ pPlayer->ResetPetTalents();
+ pPlayer->CLOSE_GOSSIP_MENU();
+ }
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_locksmith
+######*/
+
+enum eLockSmith
+{
+ QUEST_HOW_TO_BRAKE_IN_TO_THE_ARCATRAZ = 10704,
+ QUEST_DARK_IRON_LEGACY = 3802,
+ QUEST_THE_KEY_TO_SCHOLOMANCE_A = 5505,
+ QUEST_THE_KEY_TO_SCHOLOMANCE_H = 5511,
+ QUEST_HOTTER_THAN_HELL_A = 10758,
+ QUEST_HOTTER_THAN_HELL_H = 10764,
+ QUEST_RETURN_TO_KHAGDAR = 9837,
+ QUEST_CONTAINMENT = 13159,
+
+ ITEM_ARCATRAZ_KEY = 31084,
+ ITEM_SHADOWFORGE_KEY = 11000,
+ ITEM_SKELETON_KEY = 13704,
+ ITEM_SHATTERED_HALLS_KEY = 28395,
+ ITEM_THE_MASTERS_KEY = 24490,
+ ITEM_VIOLET_HOLD_KEY = 42482,
+
+ SPELL_ARCATRAZ_KEY = 54881,
+ SPELL_SHADOWFORGE_KEY = 54882,
+ SPELL_SKELETON_KEY = 54883,
+ SPELL_SHATTERED_HALLS_KEY = 54884,
+ SPELL_THE_MASTERS_KEY = 54885,
+ SPELL_VIOLET_HOLD_KEY = 67253
+};
+
+#define GOSSIP_LOST_ARCATRAZ_KEY "I've lost my key to the Arcatraz."
+#define GOSSIP_LOST_SHADOWFORGE_KEY "I've lost my key to the Blackrock Depths."
+#define GOSSIP_LOST_SKELETON_KEY "I've lost my key to the Scholomance."
+#define GOSSIP_LOST_SHATTERED_HALLS_KEY "I've lost my key to the Shattered Halls."
+#define GOSSIP_LOST_THE_MASTERS_KEY "I've lost my key to the Karazhan."
+#define GOSSIP_LOST_VIOLET_HOLD_KEY "I've lost my key to the Violet Hold."
+
+
+bool GossipHello_npc_locksmith(Player* pPlayer, Creature* pCreature)
+{
+
+ // Arcatraz Key
+ if (pPlayer->GetQuestRewardStatus(QUEST_HOW_TO_BRAKE_IN_TO_THE_ARCATRAZ) && !pPlayer->HasItemCount(ITEM_ARCATRAZ_KEY, 1, true))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_ARCATRAZ_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +1);
+
+ // Shadowforge Key
+ if (pPlayer->GetQuestRewardStatus(QUEST_DARK_IRON_LEGACY) && !pPlayer->HasItemCount(ITEM_SHADOWFORGE_KEY, 1, true))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_SHADOWFORGE_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +2);
+
+ // Skeleton Key
+ if ((pPlayer->GetQuestRewardStatus(QUEST_THE_KEY_TO_SCHOLOMANCE_A) || pPlayer->GetQuestRewardStatus(QUEST_THE_KEY_TO_SCHOLOMANCE_H)) &&
+ !pPlayer->HasItemCount(ITEM_SKELETON_KEY, 1, true))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_SKELETON_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +3);
+
+ // Shatered Halls Key
+ if ((pPlayer->GetQuestRewardStatus(QUEST_HOTTER_THAN_HELL_A) || pPlayer->GetQuestRewardStatus(QUEST_HOTTER_THAN_HELL_H)) &&
+ !pPlayer->HasItemCount(ITEM_SHATTERED_HALLS_KEY, 1, true))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_SHATTERED_HALLS_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +4);
+
+ // Master's Key
+ if (pPlayer->GetQuestRewardStatus(QUEST_RETURN_TO_KHAGDAR) && !pPlayer->HasItemCount(ITEM_THE_MASTERS_KEY, 1, true))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_THE_MASTERS_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +5);
+
+ // Violet Hold Key
+ if (pPlayer->GetQuestRewardStatus(QUEST_CONTAINMENT) && !pPlayer->HasItemCount(ITEM_VIOLET_HOLD_KEY, 1, true))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_VIOLET_HOLD_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +6);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_locksmith(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_ARCATRAZ_KEY, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_SHADOWFORGE_KEY, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_SKELETON_KEY, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+4:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_SHATTERED_HALLS_KEY, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+5:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_THE_MASTERS_KEY, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+6:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_VIOLET_HOLD_KEY, false);
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_tabard_vendor
+######*/
+
+enum
+{
+ QUEST_TRUE_MASTERS_OF_LIGHT = 9737,
+ QUEST_THE_UNWRITTEN_PROPHECY = 9762,
+ QUEST_INTO_THE_BREACH = 10259,
+ QUEST_BATTLE_OF_THE_CRIMSON_WATCH = 10781,
+ QUEST_SHARDS_OF_AHUNE = 11972,
+
+ ACHIEVEMENT_EXPLORE_NORTHREND = 45,
+ ACHIEVEMENT_TWENTYFIVE_TABARDS = 1021,
+ ACHIEVEMENT_THE_LOREMASTER_A = 1681,
+ ACHIEVEMENT_THE_LOREMASTER_H = 1682,
+
+ ITEM_TABARD_OF_THE_HAND = 24344,
+ ITEM_TABARD_OF_THE_BLOOD_KNIGHT = 25549,
+ ITEM_TABARD_OF_THE_PROTECTOR = 28788,
+ ITEM_OFFERING_OF_THE_SHATAR = 31408,
+ ITEM_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI = 31404,
+ ITEM_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI = 31405,
+ ITEM_TABARD_OF_THE_SUMMER_SKIES = 35279,
+ ITEM_TABARD_OF_THE_SUMMER_FLAMES = 35280,
+ ITEM_TABARD_OF_THE_ACHIEVER = 40643,
+ ITEM_LOREMASTERS_COLORS = 43300,
+ ITEM_TABARD_OF_THE_EXPLORER = 43348,
+
+ SPELL_TABARD_OF_THE_BLOOD_KNIGHT = 54974,
+ SPELL_TABARD_OF_THE_HAND = 54976,
+ SPELL_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI = 54977,
+ SPELL_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI = 54982,
+ SPELL_TABARD_OF_THE_ACHIEVER = 55006,
+ SPELL_TABARD_OF_THE_PROTECTOR = 55008,
+ SPELL_LOREMASTERS_COLORS = 58194,
+ SPELL_TABARD_OF_THE_EXPLORER = 58224,
+ SPELL_TABARD_OF_SUMMER_SKIES = 62768,
+ SPELL_TABARD_OF_SUMMER_FLAMES = 62769
+};
+
+#define GOSSIP_LOST_TABARD_OF_BLOOD_KNIGHT "I've lost my Tabard of Blood Knight."
+#define GOSSIP_LOST_TABARD_OF_THE_HAND "I've lost my Tabard of the Hand."
+#define GOSSIP_LOST_TABARD_OF_THE_PROTECTOR "I've lost my Tabard of the Protector."
+#define GOSSIP_LOST_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI "I've lost my Green Trophy Tabard of the Illidari."
+#define GOSSIP_LOST_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI "I've lost my Purple Trophy Tabard of the Illidari."
+#define GOSSIP_LOST_TABARD_OF_SUMMER_SKIES "I've lost my Tabard of Summer Skies."
+#define GOSSIP_LOST_TABARD_OF_SUMMER_FLAMES "I've lost my Tabard of Summer Flames."
+#define GOSSIP_LOST_LOREMASTERS_COLORS "I've lost my Loremaster's Colors."
+#define GOSSIP_LOST_TABARD_OF_THE_EXPLORER "I've lost my Tabard of the Explorer."
+#define GOSSIP_LOST_TABARD_OF_THE_ACHIEVER "I've lost my Tabard of the Achiever."
+
+bool GossipHello_npc_tabard_vendor(Player* pPlayer, Creature* pCreature)
+{
+ bool m_bLostBloodKnight = false;
+ bool m_bLostHand = false;
+ bool m_bLostProtector = false;
+ bool m_bLostIllidari = false;
+ bool m_bLostSummer = false;
+
+ //Tabard of the Blood Knight
+ if (pPlayer->GetQuestRewardStatus(QUEST_TRUE_MASTERS_OF_LIGHT) && !pPlayer->HasItemCount(ITEM_TABARD_OF_THE_BLOOD_KNIGHT, 1, true))
+ m_bLostBloodKnight = true;
+
+ //Tabard of the Hand
+ if (pPlayer->GetQuestRewardStatus(QUEST_THE_UNWRITTEN_PROPHECY) && !pPlayer->HasItemCount(ITEM_TABARD_OF_THE_HAND, 1, true))
+ m_bLostHand = true;
+
+ //Tabard of the Protector
+ if (pPlayer->GetQuestRewardStatus(QUEST_INTO_THE_BREACH) && !pPlayer->HasItemCount(ITEM_TABARD_OF_THE_PROTECTOR, 1, true))
+ m_bLostProtector = true;
+
+ //Green Trophy Tabard of the Illidari
+ //Purple Trophy Tabard of the Illidari
+ if (pPlayer->GetQuestRewardStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) &&
+ (!pPlayer->HasItemCount(ITEM_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, 1, true) &&
+ !pPlayer->HasItemCount(ITEM_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, 1, true) &&
+ !pPlayer->HasItemCount(ITEM_OFFERING_OF_THE_SHATAR, 1, true)))
+ m_bLostIllidari = true;
+
+ //Tabard of Summer Skies
+ //Tabard of Summer Flames
+ if (pPlayer->GetQuestRewardStatus(QUEST_SHARDS_OF_AHUNE) &&
+ !pPlayer->HasItemCount(ITEM_TABARD_OF_THE_SUMMER_SKIES, 1, true) &&
+ !pPlayer->HasItemCount(ITEM_TABARD_OF_THE_SUMMER_FLAMES, 1, true))
+ m_bLostSummer = true;
+
+ if (m_bLostBloodKnight || m_bLostHand || m_bLostProtector || m_bLostIllidari || m_bLostSummer)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+
+ if (m_bLostBloodKnight)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_BLOOD_KNIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +1);
+
+ if (m_bLostHand)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_THE_HAND, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF +2);
+
+ if (m_bLostProtector)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_THE_PROTECTOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+
+ if (m_bLostIllidari)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
+ }
+
+ if (m_bLostSummer)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_SUMMER_SKIES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_SUMMER_FLAMES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(13583, pCreature->GetGUID());
+ }
+ else
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_tabard_vendor(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_TRADE:
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_TABARD_OF_THE_BLOOD_KNIGHT, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_TABARD_OF_THE_HAND, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_TABARD_OF_THE_PROTECTOR, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+4:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+5:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+6:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_TABARD_OF_SUMMER_SKIES, false);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+7:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_TABARD_OF_SUMMER_FLAMES, false);
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_experience
+######*/
+
+#define EXP_COST 100000//10 00 00 copper (10golds)
+#define GOSSIP_TEXT_EXP 14736
+#define GOSSIP_XP_OFF "I no longer wish to gain experience."
+#define GOSSIP_XP_ON "I wish to start gaining experience again."
+
+
+bool GossipHello_npc_experience(Player* pPlayer, Creature* pCreature)
+{
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_XP_OFF, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_XP_ON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXT_EXP, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_experience(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ bool noXPGain = pPlayer->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
+ bool doSwitch = false;
+
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1://xp off
+ {
+ if (!noXPGain)//does gain xp
+ doSwitch = true;//switch to don't gain xp
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2://xp on
+ {
+ if (noXPGain)//doesn't gain xp
+ doSwitch = true;//switch to gain xp
+ }
+ break;
+ }
+ if (doSwitch)
+ {
+ if (pPlayer->GetMoney() < EXP_COST)
+ pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
+ else if (noXPGain)
+ {
+ pPlayer->ModifyMoney(-EXP_COST);
+ pPlayer->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
+ }
+ else if (!noXPGain)
+ {
+ pPlayer->ModifyMoney(-EXP_COST);
+ pPlayer->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
+ }
+ }
+ pPlayer->PlayerTalkClass->CloseGossip();
+ return true;
+}
+
+void AddSC_npcs_special()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_air_force_bots";
+ newscript->GetAI = &GetAI_npc_air_force_bots;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_lunaclaw_spirit";
+ newscript->pGossipHello = &GossipHello_npc_lunaclaw_spirit;
+ newscript->pGossipSelect = &GossipSelect_npc_lunaclaw_spirit;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_chicken_cluck";
+ newscript->GetAI = &GetAI_npc_chicken_cluck;
+ newscript->pQuestAccept = &QuestAccept_npc_chicken_cluck;
+ newscript->pQuestComplete = &QuestComplete_npc_chicken_cluck;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_dancing_flames";
+ newscript->GetAI = &GetAI_npc_dancing_flames;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_injured_patient";
+ newscript->GetAI = &GetAI_npc_injured_patient;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_doctor";
+ newscript->GetAI = &GetAI_npc_doctor;
+ newscript->pQuestAccept = &QuestAccept_npc_doctor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_garments_of_quests";
+ newscript->GetAI = &GetAI_npc_garments_of_quests;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_guardian";
+ newscript->GetAI = &GetAI_npc_guardian;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_kingdom_of_dalaran_quests";
+ newscript->pGossipHello = &GossipHello_npc_kingdom_of_dalaran_quests;
+ newscript->pGossipSelect = &GossipSelect_npc_kingdom_of_dalaran_quests;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_mount_vendor";
+ newscript->pGossipHello = &GossipHello_npc_mount_vendor;
+ newscript->pGossipSelect = &GossipSelect_npc_mount_vendor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_rogue_trainer";
+ newscript->pGossipHello = &GossipHello_npc_rogue_trainer;
+ newscript->pGossipSelect = &GossipSelect_npc_rogue_trainer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_sayge";
+ newscript->pGossipHello = &GossipHello_npc_sayge;
+ newscript->pGossipSelect = &GossipSelect_npc_sayge;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_steam_tonk";
+ newscript->GetAI = &GetAI_npc_steam_tonk;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_tonk_mine";
+ newscript->GetAI = &GetAI_npc_tonk_mine;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_winter_reveler";
+ newscript->GetAI = &GetAI_npc_winter_reveler;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_brewfest_reveler";
+ newscript->GetAI = &GetAI_npc_winter_reveler;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_snake_trap_serpents";
+ newscript->GetAI = &GetAI_npc_snake_trap_serpents;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_mirror_image";
+ newscript->GetAI = &GetAI_npc_mirror_image;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_ebon_gargoyle";
+ newscript->GetAI = &GetAI_npc_ebon_gargoyle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_lightwell";
+ newscript->GetAI = &GetAI_npc_lightwellAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_mojo";
+ newscript->GetAI = &GetAI_mob_mojo;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_training_dummy";
+ newscript->GetAI = &GetAI_npc_training_dummy;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_shadowfiend";
+ newscript->GetAI = &GetAI_npc_shadowfiend;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_wormhole";
+ newscript->pGossipHello = &GossipHello_npc_wormhole;
+ newscript->pGossipSelect = &GossipSelect_npc_wormhole;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_pet_trainer";
+ newscript->pGossipHello = &GossipHello_npc_pet_trainer;
+ newscript->pGossipSelect = &GossipSelect_npc_pet_trainer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_locksmith";
+ newscript->pGossipHello = &GossipHello_npc_locksmith;
+ newscript->pGossipSelect = &GossipSelect_npc_locksmith;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_tabard_vendor";
+ newscript->pGossipHello = &GossipHello_npc_tabard_vendor;
+ newscript->pGossipSelect = &GossipSelect_npc_tabard_vendor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_experience";
+ newscript->pGossipHello = &GossipHello_npc_experience;
+ newscript->pGossipSelect = &GossipSelect_npc_experience;
+ newscript->RegisterSelf();
+}
+