Merge [SD2]

r1241 Add text to ysondre and also replace manual summon with spell. Clean up script. Patch by Turok
r1242 Add support for quest 4770
r1243 Add support for quest 4904
r1244 Update most scripts calling escortAI's Start() from outside creature AI with more safe method.

--HG--
branch : trunk
This commit is contained in:
Kudlaty
2009-08-14 04:21:52 +02:00
parent 9ce4f8a768
commit 93e420ed29
25 changed files with 484 additions and 845 deletions
+80
View File
@@ -13,6 +13,86 @@ CREATE TABLE script_waypoint (
PRIMARY KEY (entry, pointid)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Script Creature waypoints';
DELETE FROM script_waypoint WHERE entry=10646;
INSERT INTO script_waypoint VALUES
(10646, 0, -4792.401855, -2137.775146, 82.423, 0, ''),
(10646, 1, -4813.508301, -2141.543457, 80.774, 0, ''),
(10646, 2, -4828.630859, -2154.309814, 82.074, 0, ''),
(10646, 3, -4833.772949, -2149.182617, 81.676, 0, ''),
(10646, 4, -4846.418945, -2136.045410, 77.871, 0, ''),
(10646, 5, -4865.076660, -2116.549561, 76.483, 0, ''),
(10646, 6, -4888.434570, -2090.729248, 80.907, 0, ''),
(10646, 7, -4893.068359, -2085.468994, 82.094, 0, ''),
(10646, 8, -4907.256836, -2074.929932, 84.437, 5000, 'SAY_LAKO_LOOK_OUT'),
(10646, 9, -4899.899902, -2062.143555, 83.780, 0, ''),
(10646, 10, -4897.762207, -2056.520020, 84.184, 0, ''),
(10646, 11, -4888.331543, -2033.182495, 83.654, 0, ''),
(10646, 12, -4876.343750, -2003.916138, 90.887, 0, ''),
(10646, 13, -4872.227051, -1994.173340, 91.513, 0, ''),
(10646, 14, -4879.569336, -1976.985229, 92.185, 5000, 'SAY_LAKO_HERE_COME'),
(10646, 15, -4879.049316, -1964.349609, 92.001, 0, ''),
(10646, 16, -4874.720215, -1956.939819, 90.737, 0, ''),
(10646, 17, -4869.474609, -1952.612671, 89.206, 0, ''),
(10646, 18, -4842.466797, -1929.000732, 84.147, 0, ''),
(10646, 19, -4804.444824, -1897.302734, 89.362, 0, ''),
(10646, 20, -4798.072754, -1892.383545, 89.368, 0, ''),
(10646, 21, -4779.447754, -1882.759155, 90.169, 5000, 'SAY_LAKO_MORE'),
(10646, 22, -4762.081055, -1866.530640, 89.481, 0, ''),
(10646, 23, -4766.267090, -1861.867798, 87.847, 0, ''),
(10646, 24, -4782.929688, -1852.174683, 78.354, 0, ''),
(10646, 25, -4793.605469, -1850.961182, 77.658, 0, ''),
(10646, 26, -4803.323730, -1855.102661, 78.958, 0, ''),
(10646, 27, -4807.971680, -1854.501221, 77.743, 0, ''),
(10646, 28, -4837.212891, -1848.493408, 64.488, 0, ''),
(10646, 29, -4884.619629, -1840.401123, 56.219, 0, ''),
(10646, 30, -4889.705566, -1839.623291, 54.417, 0, ''),
(10646, 31, -4893.904297, -1843.685791, 53.012, 0, ''),
(10646, 32, -4903.142090, -1872.383545, 32.266, 0, ''),
(10646, 33, -4910.940918, -1879.864868, 29.940, 0, ''),
(10646, 34, -4920.047363, -1880.940796, 30.597, 0, ''),
(10646, 35, -4924.457031, -1881.447144, 29.292, 0, ''),
(10646, 36, -4966.120117, -1886.033081, 10.977, 0, ''),
(10646, 37, -4999.369629, -1890.847290, 4.430, 0, ''),
(10646, 38, -5007.271484, -1891.669678, 2.771, 0, ''),
(10646, 39, -5013.334473, -1879.588257, -1.947, 0, ''),
(10646, 40, -5023.328613, -1855.959961, -17.103, 0, ''),
(10646, 41, -5038.513184, -1825.986694, -35.821, 0, ''),
(10646, 42, -5048.733887, -1809.798218, -46.457, 0, ''),
(10646, 43, -5053.188965, -1791.682983, -57.186, 0, ''),
(10646, 44, -5062.093750, -1794.399780, -56.515, 0, ''),
(10646, 45, -5052.657227, -1797.044800, -54.734, 5000, 'SAY_LAKO_END');
DELETE FROM script_waypoint WHERE entry=10427;
INSERT INTO script_waypoint VALUES
(10427, 0, -5185.463, -1185.927, 45.951, 0, ''),
(10427, 1, -5184.880, -1154.210, 45.035, 0, ''),
(10427, 2, -5175.880, -1126.526, 43.701, 0, ''),
(10427, 3, -5138.651, -1111.874, 44.024, 0, ''),
(10427, 4, -5134.728, -1104.796, 47.365, 0, ''),
(10427, 5, -5129.681, -1097.878, 49.449, 2500, ''),
(10427, 6, -5125.303, -1080.572, 47.033, 0, ''),
(10427, 7, -5146.668, -1053.694, 28.415, 0, ''),
(10427, 8, -5147.463, -1027.539, 13.818, 0, ''),
(10427, 9, -5139.238, -1018.889, 8.220, 0, ''),
(10427, 10, -5121.168, -1013.126, -0.619, 0, ''),
(10427, 11, -5091.919, -1014.205, -4.902, 0, ''),
(10427, 12, -5069.240, -994.299, -4.631, 0, ''),
(10427, 13, -5059.975, -944.112, -5.377, 0, ''),
(10427, 14, -5013.546, -906.184, -5.490, 0, ''),
(10427, 15, -4992.461, -920.983, -4.980, 5000, 'SAY_WYVERN'),
(10427, 16, -4976.355, -1002.997, -5.380, 0, ''),
(10427, 17, -4958.478, -1033.185, -5.433, 0, ''),
(10427, 18, -4953.353, -1052.211, -10.836, 0, ''),
(10427, 19, -4937.447, -1056.351, -22.139, 0, ''),
(10427, 20, -4908.455, -1050.433, -33.458, 0, ''),
(10427, 21, -4905.530, -1056.885, -33.722, 0, ''),
(10427, 22, -4920.830, -1073.284, -45.515, 0, ''),
(10427, 23, -4933.368, -1082.700, -50.186, 0, ''),
(10427, 24, -4935.313, -1092.353, -52.785, 0, ''),
(10427, 25, -4929.553, -1101.268, -50.637, 0, ''),
(10427, 26, -4920.679, -1100.028, -51.944, 10000, 'SAY_COMPLETE'),
(10427, 27, -4920.679, -1100.028, -51.944, 0, 'quest complete');
DELETE FROM script_waypoint WHERE entry=16812;
INSERT INTO script_waypoint VALUES
(16812, 0, -10868.260, -1779.836, 90.476, 2500, 'Open door, begin walking'),
+2 -1
View File
@@ -997,8 +997,9 @@ UPDATE `creature_template` SET `ScriptName`='mob_unkor_the_ruthless' WHERE `entr
UPDATE `creature_template` SET `ScriptName`='npc_slim' WHERE `entry`=19679;
/* THOUSAND NEEDLES */
UPDATE `creature_template` SET `ScriptName`='npc_swiftmountain' WHERE `entry`=10427;
UPDATE `creature_template` SET `ScriptName`='npc_paoka_swiftmountain' WHERE `entry`=10427;
UPDATE `creature_template` SET `ScriptName`='npc_plucky' WHERE `entry`=6626;
UPDATE `creature_template` SET `ScriptName`='npc_lakota_windsong' WHERE `entry`=10646;
/* THUNDER BLUFF */
UPDATE `creature_template` SET `ScriptName`='npc_cairne_bloodhoof' WHERE `entry`=3057;
+33
View File
@@ -0,0 +1,33 @@
DELETE FROM script_waypoint WHERE entry=10427;
INSERT INTO script_waypoint VALUES
(10427, 0, -5185.463, -1185.927, 45.951, 0, ''),
(10427, 1, -5184.880, -1154.210, 45.035, 0, ''),
(10427, 2, -5175.880, -1126.526, 43.701, 0, ''),
(10427, 3, -5138.651, -1111.874, 44.024, 0, ''),
(10427, 4, -5134.728, -1104.796, 47.365, 0, ''),
(10427, 5, -5129.681, -1097.878, 49.449, 2500, ''),
(10427, 6, -5125.303, -1080.572, 47.033, 0, ''),
(10427, 7, -5146.668, -1053.694, 28.415, 0, ''),
(10427, 8, -5147.463, -1027.539, 13.818, 0, ''),
(10427, 9, -5139.238, -1018.889, 8.220, 0, ''),
(10427, 10, -5121.168, -1013.126, -0.619, 0, ''),
(10427, 11, -5091.919, -1014.205, -4.902, 0, ''),
(10427, 12, -5069.240, -994.299, -4.631, 0, ''),
(10427, 13, -5059.975, -944.112, -5.377, 0, ''),
(10427, 14, -5013.546, -906.184, -5.490, 0, ''),
(10427, 15, -4992.461, -920.983, -4.980, 5000, 'SAY_WYVERN'),
(10427, 16, -4976.355, -1002.997, -5.380, 0, ''),
(10427, 17, -4958.478, -1033.185, -5.433, 0, ''),
(10427, 18, -4953.353, -1052.211, -10.836, 0, ''),
(10427, 19, -4937.447, -1056.351, -22.139, 0, ''),
(10427, 20, -4908.455, -1050.433, -33.458, 0, ''),
(10427, 21, -4905.530, -1056.885, -33.722, 0, ''),
(10427, 22, -4920.830, -1073.284, -45.515, 0, ''),
(10427, 23, -4933.368, -1082.700, -50.186, 0, ''),
(10427, 24, -4935.313, -1092.353, -52.785, 0, ''),
(10427, 25, -4929.553, -1101.268, -50.637, 0, ''),
(10427, 26, -4920.679, -1100.028, -51.944, 10000, 'SAY_COMPLETE'),
(10427, 27, -4920.679, -1100.028, -51.944, 0, 'quest complete');
UPDATE `creature_template` SET `ScriptName`='npc_paoka_swiftmountain' WHERE `entry`=10427;
UPDATE `creature_template` SET `ScriptName`='npc_lakota_windsong' WHERE `entry`=10646;
+103 -117
View File
@@ -23,201 +23,187 @@ EndScriptData */
#include "precompiled.h"
#define SPELL_SLEEP 24777
#define SPELL_NOXIOUSBREATH 24818
#define SPELL_TAILSWEEP 15847
//#define SPELL_MARKOFNATURE 25040 // Not working
#define SPELL_LIGHTNINGWAVE 24819
#define SPELL_SUMMONDRUIDS 24795
enum
{
SAY_AGGRO = -1000360, // sound unknown
SAY_SUMMONDRUIDS = -1000361, // sound unknown
//druid spells
#define SPELL_MOONFIRE 21669
SPELL_SLEEP = 24777,
SPELL_NOXIOUSBREATH = 24818,
SPELL_TAILSWEEP = 15847,
//#SPELL_MARKOFNATURE = 25040, // Not working
SPELL_LIGHTNINGWAVE = 24819,
SPELL_SUMMONDRUIDS = 24795,
//druid spells
SPELL_MOONFIRE = 21669
};
// Ysondre script
struct TRINITY_DLL_DECL boss_ysondreAI : public ScriptedAI
{
boss_ysondreAI(Creature *c) : ScriptedAI(c) {}
boss_ysondreAI(Creature* pCreature) : ScriptedAI(pCreature) {}
uint32 Sleep_Timer;
uint32 NoxiousBreath_Timer;
uint32 TailSweep_Timer;
//uint32 MarkOfNature_Timer;
uint32 LightningWave_Timer;
uint32 SummonDruids1_Timer;
uint32 SummonDruids2_Timer;
uint32 SummonDruids3_Timer;
int Rand;
int RandX;
int RandY;
Creature* Summoned;
uint32 m_uiSleep_Timer;
uint32 m_uiNoxiousBreath_Timer;
uint32 m_uiTailSweep_Timer;
//uint32 m_uiMarkOfNature_Timer;
uint32 m_uiLightningWave_Timer;
uint32 m_uiSummonDruids1_Timer;
uint32 m_uiSummonDruids2_Timer;
uint32 m_uiSummonDruids3_Timer;
void Reset()
{
Sleep_Timer = 15000 + rand()%5000;
NoxiousBreath_Timer = 8000;
TailSweep_Timer = 4000;
//MarkOfNature_Timer = 45000;
LightningWave_Timer = 12000;
SummonDruids1_Timer = 0;
SummonDruids2_Timer = 0;
SummonDruids3_Timer = 0;
m_uiSleep_Timer = 15000 + rand()%5000;
m_uiNoxiousBreath_Timer = 8000;
m_uiTailSweep_Timer = 4000;
//m_uiMarkOfNature_Timer = 45000;
m_uiLightningWave_Timer = 12000;
m_uiSummonDruids1_Timer = 0;
m_uiSummonDruids2_Timer = 0;
m_uiSummonDruids3_Timer = 0;
}
void EnterCombat(Unit *who)
void EnterCombat(Unit* pWho)
{
DoScriptText(SAY_AGGRO, m_creature);
}
void SummonDruids(Unit* victim)
void DoSummonDruids()
{
if (!victim)
return;
Rand = rand()%10;
switch (rand()%2)
for(int i = 0; i < 10; ++i)
{
case 0: RandX = 0 - Rand; break;
case 1: RandX = 0 + Rand; break;
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_SUMMONDRUIDS, true);
}
Rand = 0;
Rand = rand()%10;
switch (rand()%2)
{
case 0: RandY = 0 - Rand; break;
case 1: RandY = 0 + Rand; break;
}
Rand = 0;
Summoned = DoSpawnCreature(15260, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
if (Summoned)
(Summoned->AI())->AttackStart(victim);
}
void UpdateAI(const uint32 diff)
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
//Sleep_Timer
if (Sleep_Timer < diff)
if (m_uiSleep_Timer < uiDiff)
{
if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(target,SPELL_SLEEP);
if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_SLEEP);
Sleep_Timer = 8000 + rand()%7000;
}else Sleep_Timer -= diff;
m_uiSleep_Timer = 8000 + rand()%7000;
}
else
m_uiSleep_Timer -= uiDiff;
//NoxiousBreath_Timer
if (NoxiousBreath_Timer < diff)
if (m_uiNoxiousBreath_Timer < uiDiff)
{
DoCast(m_creature->getVictim(),SPELL_NOXIOUSBREATH);
NoxiousBreath_Timer = 14000 + rand()%6000;
}else NoxiousBreath_Timer -= diff;
DoCast(m_creature->getVictim(), SPELL_NOXIOUSBREATH);
m_uiNoxiousBreath_Timer = 14000 + rand()%6000;
}
else
m_uiNoxiousBreath_Timer -= uiDiff;
//Tailsweep every 2 seconds
if (TailSweep_Timer < diff)
if (m_uiTailSweep_Timer < uiDiff)
{
if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(target,SPELL_TAILSWEEP);
if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_TAILSWEEP);
TailSweep_Timer = 2000;
}else TailSweep_Timer -= diff;
m_uiTailSweep_Timer = 2000;
}
else
m_uiTailSweep_Timer -= uiDiff;
//MarkOfNature_Timer
//if (MarkOfNature_Timer < diff)
//if (m_uiMarkOfNature_Timer < uiDiff)
//{
// DoCast(m_creature->getVictim(),SPELL_MARKOFNATURE);
// MarkOfNature_Timer = 45000;
//}else MarkOfNature_Timer -= diff;
// DoCast(m_creature->getVictim(), SPELL_MARKOFNATURE);
// m_uiMarkOfNature_Timer = 45000;
//}
//else
// m_uiMarkOfNature_Timer -= uiDiff;
//LightningWave_Timer
if (LightningWave_Timer < diff)
if (m_uiLightningWave_Timer < uiDiff)
{
//Cast LIGHTNINGWAVE on a Random target
if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(target,SPELL_LIGHTNINGWAVE);
if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_LIGHTNINGWAVE);
LightningWave_Timer = 7000 + rand()%5000;
}else LightningWave_Timer -= diff;
m_uiLightningWave_Timer = 7000 + rand()%5000;
}
else
m_uiLightningWave_Timer -= uiDiff;
//Summon Druids
if ((int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 75)
{
if (SummonDruids1_Timer < diff)
if (m_uiSummonDruids1_Timer < uiDiff)
{
// summon 10 druids
Unit* target = NULL;
for(uint8 i = 0; i < 10; ++i)
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonDruids(target);
}
SummonDruids1_Timer = 60000;
} else SummonDruids1_Timer -= diff;
DoScriptText(SAY_SUMMONDRUIDS, m_creature);
DoSummonDruids();
m_uiSummonDruids1_Timer = 60000;
}
else
m_uiSummonDruids1_Timer -= uiDiff;
}
//Summon Druids
if ((int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 50)
{
if (SummonDruids2_Timer < diff)
if (m_uiSummonDruids2_Timer < uiDiff)
{
// summon 10 druids
Unit* target = NULL;
for(uint8 i = 0; i < 10; ++i)
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonDruids(target);
}
SummonDruids2_Timer = 60000;
} else SummonDruids2_Timer -= diff;
DoScriptText(SAY_SUMMONDRUIDS, m_creature);
DoSummonDruids();
m_uiSummonDruids2_Timer = 60000;
}
else
m_uiSummonDruids2_Timer -= uiDiff;
}
//Summon Druids
if ((int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 25)
{
if (SummonDruids3_Timer < diff)
if (m_uiSummonDruids3_Timer < uiDiff)
{
// summon 10 druids
Unit* target = NULL;
for(uint8 i = 0; i < 10; ++i)
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonDruids(target);
}
SummonDruids3_Timer = 60000;
} else SummonDruids3_Timer -= diff;
DoScriptText(SAY_SUMMONDRUIDS, m_creature);
DoSummonDruids();
m_uiSummonDruids3_Timer = 60000;
}
else
m_uiSummonDruids3_Timer -= uiDiff;
}
DoMeleeAttackIfReady();
}
};
// Summoned druid script
struct TRINITY_DLL_DECL mob_dementeddruidsAI : public ScriptedAI
{
mob_dementeddruidsAI(Creature *c) : ScriptedAI(c) {}
uint32 MoonFire_Timer;
uint32 m_uiMoonFire_Timer;
void Reset()
{
MoonFire_Timer = 3000;
m_uiMoonFire_Timer = 3000;
}
void EnterCombat(Unit *who)
{
}
void UpdateAI(const uint32 diff)
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
//MoonFire_Timer
if (MoonFire_Timer < diff)
if (m_uiMoonFire_Timer < uiDiff)
{
DoCast(m_creature->getVictim(),SPELL_MOONFIRE);
MoonFire_Timer = 5000;
}else MoonFire_Timer -= diff;
DoCast(m_creature->getVictim(), SPELL_MOONFIRE);
m_uiMoonFire_Timer = 5000;
}
else
m_uiMoonFire_Timer -= uiDiff;
DoMeleeAttackIfReady();
}
@@ -183,10 +183,14 @@ bool GossipHello_example_escort(Player* pPlayer, Creature* pCreature)
bool GossipSelect_example_escort(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action)
{
npc_escortAI* pEscortAI = CAST_AI(example_escortAI, pCreature->AI());
if (action == GOSSIP_ACTION_INFO_DEF+1)
{
pPlayer->CLOSE_GOSSIP_MENU();
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, true, pPlayer->GetGUID());
if (pEscortAI)
pEscortAI->Start(true, true, pPlayer->GetGUID());
return true; // prevent mangos core handling
}
@@ -194,7 +198,9 @@ bool GossipSelect_example_escort(Player* pPlayer, Creature* pCreature, uint32 se
if (action == GOSSIP_ACTION_INFO_DEF+2)
{
pPlayer->CLOSE_GOSSIP_MENU();
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(false, false, pPlayer->GetGUID());
if (pEscortAI)
pEscortAI->Start(false, false, pPlayer->GetGUID());
return true; // prevent mangos core handling
}
@@ -202,7 +208,9 @@ bool GossipSelect_example_escort(Player* pPlayer, Creature* pCreature, uint32 se
if (action == GOSSIP_ACTION_INFO_DEF+3)
{
pPlayer->CLOSE_GOSSIP_MENU();
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(false, true, pPlayer->GetGUID());
if (pEscortAI)
pEscortAI->Start(false, true, pPlayer->GetGUID());
return true; // prevent mangos core handling
}
@@ -50,7 +50,7 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI
{
npc_professor_phizzlethorpeAI(Creature *c) : npc_escortAI(c) {}
bool Completed;
bool m_bCompleted;
void WaypointReached(uint32 i)
{
@@ -73,7 +73,7 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI
case 20:
DoScriptText(EMOTE_PROGRESS_8, m_creature);
DoScriptText(SAY_PROGRESS_9, m_creature, pPlayer);
Completed = true;
m_bCompleted = true;
if (pPlayer)
CAST_PLR(pPlayer)->GroupEventHappens(QUEST_SUNKEN_TREASURE, m_creature);
break;
@@ -87,7 +87,7 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI
void Reset()
{
Completed = true;
m_bCompleted = true;
m_creature->setFaction(35);
}
@@ -98,7 +98,7 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI
void JustDied(Unit* killer)
{
if (PlayerGUID && !Completed)
if (PlayerGUID && !m_bCompleted)
{
Player* pPlayer = Unit::GetPlayer(PlayerGUID);
if (pPlayer)
@@ -112,13 +112,15 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI
}
};
bool QuestAccept_npc_professor_phizzlethorpe(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_professor_phizzlethorpe(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_SUNKEN_TREASURE)
{
DoScriptText(SAY_PROGRESS_1, creature, pPlayer);
CAST_AI(npc_escortAI, (creature->AI()))->Start(false, false, pPlayer->GetGUID());
creature->setFaction(113);
DoScriptText(SAY_PROGRESS_1, pCreature, pPlayer);
if (npc_escortAI* pEscortAI = CAST_AI(npc_professor_phizzlethorpeAI, (pCreature->AI())))
pEscortAI->Start(false, false, pPlayer->GetGUID());
pCreature->setFaction(113);
}
return true;
}
@@ -139,14 +139,16 @@ struct TRINITY_DLL_DECL npc_torekAI : public npc_escortAI
}
};
bool QuestAccept_npc_torek(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_torek(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_TOREK_ASSULT)
{
//TODO: find companions, make them follow Torek, at any time (possibly done by mangos/database in future?)
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, true, pPlayer->GetGUID());
DoScriptText(SAY_READY, creature, pPlayer);
creature->setFaction(113);
DoScriptText(SAY_READY, pCreature, pPlayer);
pCreature->setFaction(113);
if (npc_escortAI* pEscortAI = CAST_AI(npc_torekAI, pCreature->AI()))
pEscortAI->Start(true, true, pPlayer->GetGUID());
}
return true;
@@ -239,12 +241,14 @@ struct TRINITY_DLL_DECL npc_ruul_snowhoofAI : public npc_escortAI
}
};
bool QuestAccept_npc_ruul_snowhoof(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_ruul_snowhoof(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL)
{
creature->setFaction(113);
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
pCreature->setFaction(113);
if (npc_escortAI* pEscortAI = CAST_AI(npc_ruul_snowhoofAI, (pCreature->AI())))
pEscortAI->Start(true, false, pPlayer->GetGUID());
}
return true;
}
@@ -389,12 +389,13 @@ struct TRINITY_DLL_DECL npc_magwinAI : public npc_escortAI
}
};
bool QuestAccept_npc_magwin(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_magwin(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_A_CRY_FOR_SAY_HELP)
{
creature->setFaction(113);
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
pCreature->setFaction(113);
if (npc_escortAI* pEscortAI = CAST_AI(npc_escortAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
}
return true;
}
@@ -499,12 +499,13 @@ struct TRINITY_DLL_DECL npc_wizzlecrank_shredderAI : public npc_escortAI
}
};
bool QuestAccept_npc_wizzlecrank_shredder(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_wizzlecrank_shredder(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_ESCAPE)
{
creature->setFaction(FACTION_RATCHET);
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
pCreature->setFaction(FACTION_RATCHET);
if (npc_escortAI* pEscortAI = CAST_AI(npc_wizzlecrank_shredderAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
}
return true;
}
@@ -1,535 +0,0 @@
/* 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: Boss_Teron_Gorefiend
SD%Complete: 60
SDComment: Requires Mind Control support for Ghosts.
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
//Speech'n'sound
#define SAY_INTRO -1564037
#define SAY_AGGRO -1564038
#define SAY_SLAY1 -1564039
#define SAY_SLAY2 -1564040
#define SAY_SPELL1 -1564041
#define SAY_SPELL2 -1564042
#define SAY_SPECIAL1 -1564043
#define SAY_SPECIAL2 -1564044
#define SAY_ENRAGE -1564045
#define SAY_DEATH -1564046
//Spells
#define SPELL_INCINERATE 40239
#define SPELL_CRUSHING_SHADOWS 40243
#define SPELL_SHADOWBOLT 40185
#define SPELL_PASSIVE_SHADOWFORM 40326
#define SPELL_SHADOW_OF_DEATH 40251
#define SPELL_BERSERK 45078
#define SPELL_ATROPHY 40327 // Shadowy Constructs use this when they get within melee range of a player
#define CREATURE_DOOM_BLOSSOM 23123
#define CREATURE_SHADOWY_CONSTRUCT 23111
struct TRINITY_DLL_DECL mob_doom_blossomAI : public ScriptedAI
{
mob_doom_blossomAI(Creature *c) : ScriptedAI(c) {}
uint32 CheckTeronTimer;
uint32 ShadowBoltTimer;
uint64 TeronGUID;
void Reset()
{
CheckTeronTimer = 5000;
ShadowBoltTimer = 12000;
TeronGUID = 0;
}
void Aggro(Unit *who) { }
void AttackStart(Unit* who) { }
void MoveInLineOfSight(Unit* who) { }
void Despawn()
{
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
m_creature->RemoveCorpse();
}
void UpdateAI(const uint32 diff)
{
if(CheckTeronTimer < diff)
{
if(TeronGUID)
{
DoZoneInCombat();
Creature* Teron = ((Creature*)Unit::GetUnit((*m_creature), TeronGUID));
if((Teron) && (!Teron->isAlive() || Teron->IsInEvadeMode()))
Despawn();
}
else
Despawn();
CheckTeronTimer = 5000;
}else CheckTeronTimer -= diff;
if(ShadowBoltTimer < diff && m_creature->isInCombat())
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOWBOLT);
ShadowBoltTimer = 10000;
}else ShadowBoltTimer -= diff;
return;
}
void SetTeronGUID(uint64 guid){ TeronGUID = guid; }
};
//This is used to sort the players by distance for Constructs to see who to cast Atrophy on
struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
{
const Unit* MainTarget;
TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
// functor for operator "<"
bool operator()(const Unit* _Left, const Unit* _Right) const
{
return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right));
}
};
struct TRINITY_DLL_DECL mob_shadowy_constructAI : public ScriptedAI
{
mob_shadowy_constructAI(Creature* c) : ScriptedAI(c) {}
uint64 GhostGUID;
uint64 TeronGUID;
uint32 CheckPlayerTimer;
uint32 CheckTeronTimer;
void Reset()
{
GhostGUID = 0;
TeronGUID = 0;
CheckPlayerTimer = 2000;
CheckTeronTimer = 5000;
}
void Aggro(Unit* who) { }
void MoveInLineOfSight(Unit *who)
{
if(!who || (!who->isAlive()) || (who->GetGUID() == GhostGUID))
return;
ScriptedAI::MoveInLineOfSight(who);
}
/* Comment it out for now. NOTE TO FUTURE DEV: UNCOMMENT THIS OUT ONLY AFTER MIND CONTROL IS IMPLEMENTED
void DamageTaken(Unit* done_by, uint32 &damage)
{
if(done_by->GetGUID() != GhostGUID)
damage = 0; // Only the ghost can deal damage.
}
*/
void CheckPlayers()
{
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
if(m_threatlist.empty())
return; // No threat list. Don't continue.
std::list<HostilReference*>::iterator itr = m_threatlist.begin();
std::list<Unit*> targets;
for( ; itr != m_threatlist.end(); ++itr)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
if(pUnit && pUnit->isAlive())
targets.push_back(pUnit);
}
targets.sort(TargetDistanceOrder(m_creature));
Unit* target = targets.front();
if(target && m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target)))
{
DoCast(target, SPELL_ATROPHY);
m_creature->AI()->AttackStart(target);
}
}
void UpdateAI(const uint32 diff)
{
if(CheckPlayerTimer < diff)
{
CheckPlayers();
CheckPlayerTimer = 3000;
}else CheckPlayerTimer -= diff;
if(CheckTeronTimer < diff)
{
Creature* Teron = ((Creature*)Unit::GetUnit((*m_creature), TeronGUID));
if(!Teron || !Teron->isAlive() || Teron->IsInEvadeMode())
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
CheckTeronTimer = 5000;
}else CheckTeronTimer -= diff;
}
};
struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
{
boss_teron_gorefiendAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
}
ScriptedInstance* pInstance;
uint32 IncinerateTimer;
uint32 SummonDoomBlossomTimer;
uint32 EnrageTimer;
uint32 CrushingShadowsTimer;
uint32 ShadowOfDeathTimer;
uint32 SummonShadowsTimer;
uint32 RandomYellTimer;
uint32 AggroTimer;
uint64 AggroTargetGUID;
uint64 GhostGUID; // Player that gets killed by Shadow of Death and gets turned into a ghost
bool Intro;
void Reset()
{
if(pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, NOT_STARTED);
IncinerateTimer = 20000 + rand()%11000;
SummonDoomBlossomTimer = 12000;
EnrageTimer = 600000;
CrushingShadowsTimer = 22000;
SummonShadowsTimer = 60000;
RandomYellTimer = 50000;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
// Start off unattackable so that the intro is done properly
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
AggroTimer = 20000;
AggroTargetGUID = 0;
Intro = false;
}
void Aggro(Unit *who) {}
void MoveInLineOfSight(Unit *who)
{
if(!who || (!who->isAlive())) return;
if(who->isTargetableForAttack() && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
//if(who->HasStealthAura())
// who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
m_creature->AddThreat(who, 1.0f);
}
if(!m_creature->isInCombat() && !Intro && m_creature->IsWithinDistInMap(who, 60.0f) && (who->GetTypeId() == TYPEID_PLAYER))
{
if(pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, IN_PROGRESS);
m_creature->GetMotionMaster()->Clear(false);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoScriptText(SAY_INTRO, m_creature);
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
AggroTargetGUID = who->GetGUID();
Intro = true;
}
}
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0: DoScriptText(SAY_SLAY1, m_creature); break;
case 1: DoScriptText(SAY_SLAY2, m_creature); break;
}
}
void JustDied(Unit *victim)
{
if(pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, DONE);
DoScriptText(SAY_DEATH, m_creature);
}
float CalculateRandomLocation(float Loc, uint32 radius)
{
float coord = Loc;
switch(rand()%2)
{
case 0:
coord += rand()%radius;
break;
case 1:
coord -= rand()%radius;
break;
}
return coord;
}
void SetThreatList(Creature* Blossom)
{
if(!Blossom) return;
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator i = m_threatlist.begin();
for(i = m_threatlist.begin(); i != m_threatlist.end(); i++)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
if(pUnit && pUnit->isAlive())
{
float threat = DoGetThreat(pUnit);
Blossom->AddThreat(pUnit, threat);
}
}
}
void MindControlGhost()
{
/************************************************************************/
/** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
/** ONLY AFTER TrinIty FULLY IMPLEMENTS MIND CONTROL ABILITIES *****/
/** THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF *****/
/** WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE *****/
/************************************************************************/
Unit* Ghost = NULL;
if(GhostGUID)
Ghost = Unit::GetUnit((*m_creature), GhostGUID);
if(Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH, 0))
{
/*float x,y,z;
Ghost->GetPosition(x,y,z);
Creature* control = m_creature->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000);
if(control)
{
((Player*)Ghost)->Possess(control);
Ghost->DealDamage(Ghost, Ghost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL,
false);
}*/
for(uint8 i = 0; i < 4; ++i)
{
Creature* Construct = NULL;
float X = CalculateRandomLocation(Ghost->GetPositionX(), 10);
float Y = CalculateRandomLocation(Ghost->GetPositionY(), 10);
Construct = m_creature->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, Y, Ghost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
if(Construct)
{
Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true);
SetThreatList(Construct); // Use same function as Doom Blossom to set Threat List.
((mob_shadowy_constructAI*)Construct->AI())->GhostGUID = GhostGUID;
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target) // someone's trying to solo.
target = m_creature->getVictim();
if(target)
Construct->GetMotionMaster()->MoveChase(target);
}
}
}
}
void UpdateAI(const uint32 diff)
{
if(Intro)
{
if(AggroTimer < diff)
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
DoScriptText(SAY_AGGRO, m_creature);
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
Intro = false;
if(AggroTargetGUID)
{
Unit* pUnit = Unit::GetUnit((*m_creature), AggroTargetGUID);
if(pUnit)
AttackStart(pUnit);
DoZoneInCombat();
}else EnterEvadeMode();
}else AggroTimer -= diff;
}
if(!UpdateVictim() || Intro)
return;
if(SummonShadowsTimer < diff)
{
//MindControlGhost();
for(uint8 i = 0; i < 2; ++i)
{
Creature* Shadow = NULL;
float X = CalculateRandomLocation(m_creature->GetPositionX(), 10);
Shadow = m_creature->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
if(Shadow)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target)
Shadow->AI()->AttackStart(target);
}
}
SummonShadowsTimer = 60000;
}else SummonShadowsTimer -= diff;
if(SummonDoomBlossomTimer < diff)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
float X = CalculateRandomLocation(target->GetPositionX(), 20);
float Y = CalculateRandomLocation(target->GetPositionY(), 20);
float Z = target->GetPositionZ();
Z = m_creature->GetMap()->GetVmapHeight(X, Y, Z, true);
Creature* DoomBlossom = m_creature->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
if(DoomBlossom)
{
DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoomBlossom->setFaction(m_creature->getFaction());
DoomBlossom->AddThreat(target, 1.0f);
((mob_doom_blossomAI*)DoomBlossom->AI())->SetTeronGUID(m_creature->GetGUID());
SetThreatList(DoomBlossom);
SummonDoomBlossomTimer = 35000;
}
}
}else SummonDoomBlossomTimer -= diff;
if(IncinerateTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target)
{
switch(rand()%2)
{
case 0: DoScriptText(SAY_SPECIAL1, m_creature); break;
case 1: DoScriptText(SAY_SPECIAL2, m_creature); break;
}
DoCast(target, SPELL_INCINERATE);
IncinerateTimer = 20000 + rand()%31 * 1000;
}
}else IncinerateTimer -= diff;
if(CrushingShadowsTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target && target->isAlive())
DoCast(target, SPELL_CRUSHING_SHADOWS);
CrushingShadowsTimer = 10000 + rand()%16 * 1000;
}else CrushingShadowsTimer -= diff;
/*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
/*if(ShadowOfDeathTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
{
DoCast(target, SPELL_SHADOW_OF_DEATH);
GhostGUID = target->GetGUID();
ShadowOfDeathTimer = 30000;
SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
}
}else ShadowOfDeathTimer -= diff;*/
if(RandomYellTimer < diff)
{
switch(rand()%2)
{
case 0: DoScriptText(SAY_SPELL1, m_creature); break;
case 1: DoScriptText(SAY_SPELL2, m_creature); break;
}
RandomYellTimer = 50000 + rand()%51 * 1000;
}else RandomYellTimer -= diff;
if(!m_creature->HasAura(SPELL_BERSERK, 0))
{
if(EnrageTimer < diff)
{
DoCast(m_creature, SPELL_BERSERK);
DoScriptText(SAY_ENRAGE, m_creature);
}else EnrageTimer -= diff;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_doom_blossom(Creature *_Creature)
{
return new mob_doom_blossomAI(_Creature);
}
CreatureAI* GetAI_mob_shadowy_construct(Creature *_Creature)
{
return new mob_shadowy_constructAI(_Creature);
}
CreatureAI* GetAI_boss_teron_gorefiend(Creature *_Creature)
{
return new boss_teron_gorefiendAI (_Creature);
}
void AddSC_boss_teron_gorefiend()
{
Script *newscript;
newscript = new Script;
newscript->Name = "mob_doom_blossom";
newscript->GetAI = &GetAI_mob_doom_blossom;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_shadowy_construct";
newscript->GetAI = &GetAI_mob_shadowy_construct;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_teron_gorefiend";
newscript->GetAI = &GetAI_boss_teron_gorefiend;
newscript->RegisterSelf();
}
@@ -1196,7 +1196,8 @@ bool ChooseReward_npc_rocknot(Player* pPlayer, Creature* pCreature, const Quest
{
DoScriptText(SAY_GOT_BEER, pCreature);
pCreature->CastSpell(pCreature,SPELL_DRUNKEN_RAGE,false);
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(false, false);
if (npc_escortAI* pEscortAI = CAST_AI(npc_rocknotAI, pCreature->AI()))
pEscortAI->Start(false, false);
}
}
@@ -537,7 +537,9 @@ bool GossipSelect_npc_thrall_old_hillsbrad(Player* pPlayer, Creature* pCreature,
DoScriptText(SAY_TH_START_EVENT_PART1, pCreature);
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, true, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_thrall_old_hillsbradAI, pCreature->AI()))
pEscortAI->Start(true, true, pPlayer->GetGUID());
CAST_AI(npc_escortAI, (pCreature->AI()))->SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far
CAST_AI(npc_escortAI, (pCreature->AI()))->SetDespawnAtEnd(false);
CAST_AI(npc_escortAI, (pCreature->AI()))->SetDespawnAtFar(false);
@@ -156,7 +156,9 @@ bool QuestAccept_npc_prospector_remtravel(Player* pPlayer, Creature* pCreature,
{
if (pQuest->GetQuestId() == QUEST_ABSENT_MINDED_PT2)
{
CAST_AI(npc_escortAI, pCreature->AI())->Start(false, false, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_prospector_remtravelAI, pCreature->AI()))
pEscortAI->Start(false, false, pPlayer->GetGUID());
pCreature->setFaction(FACTION_ESCORTEE);
}
@@ -659,7 +659,9 @@ bool QuestAccept_npc_koltira_deathweaver(Player* pPlayer, Creature* pCreature, c
if (pQuest->GetQuestId() == QUEST_BREAKOUT)
{
pCreature->SetStandState(UNIT_STAND_STATE_STAND);
CAST_AI(npc_escortAI,pCreature->AI())->Start(false, false, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_koltira_deathweaverAI,pCreature->AI()))
pEscortAI->Start(false, false, pPlayer->GetGUID());
}
return true;
}
@@ -111,7 +111,8 @@ bool GossipSelect_npc_prospector_anvilward(Player* pPlayer, Creature* pCreature,
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->CLOSE_GOSSIP_MENU();
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_prospector_anvilwardAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
break;
}
return true;
@@ -190,7 +190,8 @@ bool QuestAccept_npc_oox22fe(Player* pPlayer, Creature* pCreature, const Quest*
if (pPlayer->GetTeam() == HORDE)
pCreature->setFaction(FACTION_ESCORTEE_H);
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_oox22feAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
}
return true;
@@ -241,12 +241,14 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
}
};
bool QuestAccept_npc_ranger_lilatha(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_ranger_lilatha(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_ESCAPE_FROM_THE_CATACOMBS)
{
creature->setFaction(113);
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
pCreature->setFaction(113);
if (npc_escortAI* pEscortAI = CAST_AI(npc_ranger_lilathaAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
}
return true;
}
@@ -227,13 +227,15 @@ CreatureAI* GetAI_npc_wounded_blood_elf(Creature* pCreature)
return welfAI;
}
bool QuestAccept_npc_wounded_blood_elf(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_wounded_blood_elf(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_ROAD_TO_FALCON_WATCH)
{
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_wounded_blood_elfAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
// Change faction so mobs attack
creature->setFaction(775);
pCreature->setFaction(775);
}
return true;
@@ -126,7 +126,9 @@ bool GossipSelect_npc_shadowfang_prisoner(Player* pPlayer, Creature* pCreature,
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
pPlayer->CLOSE_GOSSIP_MENU();
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(false, false);
if (npc_escortAI* pEscortAI = CAST_AI(npc_shadowfang_prisonerAI, pCreature->AI()))
pEscortAI->Start(false, false);
}
return true;
}
@@ -166,12 +166,14 @@ struct TRINITY_DLL_DECL npc_deathstalker_erlandAI : public npc_escortAI
}
};
bool QuestAccept_npc_deathstalker_erland(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_deathstalker_erland(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_ESCORTING)
{
DoScriptText(SAY_QUESTACCEPT, creature, pPlayer);
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
DoScriptText(SAY_QUESTACCEPT, pCreature, pPlayer);
if (npc_escortAI* pEscortAI = CAST_AI(npc_deathstalker_erlandAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
}
return true;
@@ -147,14 +147,16 @@ struct TRINITY_DLL_DECL npc_kaya_flathoofAI : public npc_escortAI
}
};
bool QuestAccept_npc_kaya_flathoof(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_kaya_flathoof(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_PROTECT_KAYA)
{
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
DoScriptText(SAY_START, creature);
creature->setFaction(113);
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
if (npc_escortAI* pEscortAI = CAST_AI(npc_kaya_flathoofAI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
DoScriptText(SAY_START, pCreature);
pCreature->setFaction(113);
pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
}
return true;
}
@@ -426,17 +426,18 @@ struct TRINITY_DLL_DECL npc_OOX17AI : public npc_escortAI
}
};
bool QuestAccept_npc_OOX17(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_OOX17(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == Q_OOX17)
{
creature->setFaction(113);
creature->SetHealth(creature->GetMaxHealth());
creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
DoScriptText(SAY_CHICKEN_ACC, creature);
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
pCreature->setFaction(113);
pCreature->SetHealth(pCreature->GetMaxHealth());
pCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
DoScriptText(SAY_CHICKEN_ACC, pCreature);
if (npc_escortAI* pEscortAI = CAST_AI(npc_OOX17AI, pCreature->AI()))
pEscortAI->Start(true, false, pPlayer->GetGUID());
}
return true;
}
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Thousand Needles
SD%Complete: 100
SDComment: Support for Quest: 4770, 1950
SDComment: Support for Quest: 1950, 4770, 4904
SDCategory: Thousand Needles
EndScriptData */
@@ -30,163 +30,189 @@ EndContentData */
#include "../../npc/npc_escortAI.h"
/*#####
# npc_swiftmountain
# npc_lakota_windsong
######*/
#define SAY_READY -1000147
#define SAY_AGGRO -1000148
#define SAY_FINISH -1000149
#define QUEST_HOMEWARD_BOUND 4770
#define ENTRY_WYVERN 4107
struct TRINITY_DLL_DECL npc_swiftmountainAI : public npc_escortAI
enum
{
npc_swiftmountainAI(Creature *c) : npc_escortAI(c) {}
SAY_LAKO_START = -1000365,
SAY_LAKO_LOOK_OUT = -1000366,
SAY_LAKO_HERE_COME = -1000367,
SAY_LAKO_MORE = -1000368,
SAY_LAKO_END = -1000369,
void WaypointReached(uint32 i)
QUEST_FREE_AT_LAST = 4904,
NPC_GRIM_BANDIT = 10758,
FACTION_ESCORTEE_LAKO = 232, //guessed
ID_AMBUSH_1 = 0,
ID_AMBUSH_2 = 2,
ID_AMBUSH_3 = 4
};
float m_afBanditLoc[6][6]=
{
{-4905.479492, -2062.732666, 84.352},
{-4915.201172, -2073.528320, 84.733},
{-4878.883301, -1986.947876, 91.966},
{-4877.503906, -1966.113403, 91.859},
{-4767.985352, -1873.169189, 90.192},
{-4788.861328, -1888.007813, 89.888}
};
struct TRINITY_DLL_DECL npc_lakota_windsongAI : public npc_escortAI
{
npc_lakota_windsongAI(Creature* pCreature) : npc_escortAI(pCreature) { }
void Reset() { }
void WaypointReached(uint32 uiPointId)
{
Player* pPlayer = Unit::GetPlayer(PlayerGUID);
if (!pPlayer)
return;
switch (i)
switch(uiPointId)
{
case 46:
DoScriptText(SAY_AGGRO, m_creature, pPlayer);
break;
case 47:
m_creature->SummonCreature(ENTRY_WYVERN, -5016.45, -935.01, -5.46, 5.36,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
m_creature->SummonCreature(ENTRY_WYVERN, -5001.98, -934.96, -5.55, 3.18,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
m_creature->SummonCreature(ENTRY_WYVERN, -4999.06, -949.61, -5.42, 2.04,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
break;
case 70:
DoScriptText(SAY_FINISH, m_creature, pPlayer);
if (pPlayer && pPlayer->GetTypeId() == TYPEID_PLAYER)
CAST_PLR(pPlayer)->GroupEventHappens(QUEST_HOMEWARD_BOUND,m_creature);
break;
case 8:
DoScriptText(SAY_LAKO_LOOK_OUT, m_creature);
DoSpawnBandits(ID_AMBUSH_1);
break;
case 14:
DoScriptText(SAY_LAKO_HERE_COME, m_creature);
DoSpawnBandits(ID_AMBUSH_2);
break;
case 21:
DoScriptText(SAY_LAKO_MORE, m_creature);
DoSpawnBandits(ID_AMBUSH_3);
break;
case 45:
if (Player* pPlayer = (Player*)Unit::GetUnit(*m_creature, PlayerGUID))
pPlayer->GroupEventHappens(QUEST_FREE_AT_LAST, m_creature);
break;
}
}
void Reset()
void DoSpawnBandits(int uiAmbushId)
{
m_creature->setFaction(104);
for(int i = 0; i < 2; ++i)
m_creature->SummonCreature(NPC_GRIM_BANDIT,
m_afBanditLoc[i+uiAmbushId][0], m_afBanditLoc[i+uiAmbushId][1], m_afBanditLoc[i+uiAmbushId][2], 0.0f,
TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
}
void EnterCombat(Unit* who){}
void JustSummoned(Creature* summoned)
void JustDied(Unit* pKiller)
{
summoned->AI()->AttackStart(m_creature);
}
void JustDied(Unit* killer)
{
if (PlayerGUID)
if (Player* pPlayer = (Player*)Unit::GetUnit(*m_creature, PlayerGUID))
{
if (Player* pPlayer = Unit::GetPlayer(PlayerGUID))
CAST_PLR(pPlayer)->FailQuest(QUEST_HOMEWARD_BOUND);
if (pPlayer->GetQuestStatus(QUEST_FREE_AT_LAST) == QUEST_STATUS_INCOMPLETE)
pPlayer->FailQuest(QUEST_FREE_AT_LAST);
}
}
void UpdateAI(const uint32 diff)
{
npc_escortAI::UpdateAI(diff);
}
};
bool QuestAccept_npc_swiftmountain(Player* pPlayer, Creature* creature, Quest const* quest)
CreatureAI* GetAI_npc_lakota_windsong(Creature* pCreature)
{
if (quest->GetQuestId() == QUEST_HOMEWARD_BOUND)
{
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, pPlayer->GetGUID());
DoScriptText(SAY_READY, creature, pPlayer);
creature->setFaction(113);
}
npc_lakota_windsongAI* pTempAI = new npc_lakota_windsongAI(pCreature);
pTempAI->FillPointMovementListForCreature();
return (CreatureAI*)pTempAI;
}
bool QuestAccept_npc_lakota_windsong(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
{
if (pQuest->GetQuestId() == QUEST_FREE_AT_LAST)
{
DoScriptText(SAY_LAKO_START, pCreature, pPlayer);
pCreature->setFaction(FACTION_ESCORTEE_LAKO);
if (npc_lakota_windsongAI* pEscortAI = CAST_AI(npc_lakota_windsongAI, pCreature->AI()))
pEscortAI->Start(false, false, pPlayer->GetGUID(), pQuest);
}
return true;
}
CreatureAI* GetAI_npc_swiftmountain(Creature* pCreature)
/*######
# npc_paoka_swiftmountain
######*/
enum
{
npc_swiftmountainAI* thisAI = new npc_swiftmountainAI(pCreature);
SAY_START = -1000147,
SAY_WYVERN = -1000148,
SAY_COMPLETE = -1000149,
thisAI->AddWaypoint(0, -5156.69, -1220.49, 48.78, 5000);
thisAI->AddWaypoint(1, -5157.12, -1220.13, 48.67);
thisAI->AddWaypoint(2, -5171.7, -1205.36, 47.43);
thisAI->AddWaypoint(3, -5174.08, -1197.7, 46.90);
thisAI->AddWaypoint(4, -5178.24, -1183.78, 45.97);
thisAI->AddWaypoint(5, -5181.52, -1171.03, 45.29);
thisAI->AddWaypoint(6, -5184.29, -1159.21, 44.62);
thisAI->AddWaypoint(7, -5184.84, -1152.95, 44.84);
thisAI->AddWaypoint(8, -5182.04, -1142.83, 44.07);
thisAI->AddWaypoint(9, -5178.44, -1133.57, 43.91);
thisAI->AddWaypoint(10, -5176.68, -1129.48, 43.81);
thisAI->AddWaypoint(11, -5164.85, -1123.33, 43.99);
thisAI->AddWaypoint(12, -5153.07, -1117.7, 43.66);
thisAI->AddWaypoint(13, -5143.52, -1113.14, 43.78);
thisAI->AddWaypoint(14, -5135.86, -1104.42, 47.23);
thisAI->AddWaypoint(15, -5129.86, -1097.22, 49.52);
thisAI->AddWaypoint(16, -5127.48, -1087.29, 49.03);
thisAI->AddWaypoint(17, -5127.57, -1080.4, 46.64);
thisAI->AddWaypoint(18, -5129.65, -1077.58, 45.29);
thisAI->AddWaypoint(19, -5135.86, -1069.12, 39.53);
thisAI->AddWaypoint(20, -5141.97, -1060.58, 32.70);
thisAI->AddWaypoint(21, -5145.99, -1054.85, 28.98);
thisAI->AddWaypoint(22, -5147.08, -1050.35, 26.36);
thisAI->AddWaypoint(23, -5147.5, -1043.37, 21.84);
thisAI->AddWaypoint(24, -5147.68, -1036.37, 17.05);
thisAI->AddWaypoint(25, -5147.68, -1029.37, 14.59);
thisAI->AddWaypoint(26, -5144.62, -1023.9, 11.67);
thisAI->AddWaypoint(27, -5138.67, -1020.23, 7.81);
thisAI->AddWaypoint(28, -5135.6, -1018.55, 6.19);
thisAI->AddWaypoint(29, -5126.25, -1014.76, 1.08);
thisAI->AddWaypoint(30, -5120.03, -1013.12, -1.11);
thisAI->AddWaypoint(31, -5112.3, -1027.65, -5.39);
thisAI->AddWaypoint(32, -5106.99, -1023.09, -5.10);
thisAI->AddWaypoint(33, -5099.07, -1016.19, -4.92);
thisAI->AddWaypoint(34, -5091.23, -1009.21, -5.22);
thisAI->AddWaypoint(35, -5083.62, -1001.97, -5.22);
thisAI->AddWaypoint(36, -5076.1, -994.652, -4.92);
thisAI->AddWaypoint(37, -5066.71, -985.507, -4.97);
thisAI->AddWaypoint(38, -5065.13, -978.689, -5.02);
thisAI->AddWaypoint(39, -5062.33, -968.57, -5.08);
thisAI->AddWaypoint(40, -5059.46, -958.469, -5.16);
thisAI->AddWaypoint(41, -5056.59, -948.375, -5.10);
thisAI->AddWaypoint(42, -5053.73, -938.274, -5.69);
thisAI->AddWaypoint(43, -5043.06, -934.822, -5.35);
thisAI->AddWaypoint(44, -5029.35, -932.007, -5.27);
thisAI->AddWaypoint(45, -5024.58, -933.781, -5.40);
thisAI->AddWaypoint(46, -5019.13, -938.172, -5.54);
thisAI->AddWaypoint(47, -5011, -944.812, -5.47);
thisAI->AddWaypoint(48, -5002.86, -951.455, -5.44);
thisAI->AddWaypoint(49, -4994.73, -958.099, -5.41);
thisAI->AddWaypoint(50, -4990.57, -963.782, -5.33);
thisAI->AddWaypoint(51, -4987.43, -970.041, -5.17);
thisAI->AddWaypoint(52, -4981.41, -982.678, -5.10);
thisAI->AddWaypoint(53, -4977.03, -992.221, -4.97);
thisAI->AddWaypoint(54, -4972.6, -1001.74, -5.24);
thisAI->AddWaypoint(55, -4968.15, -1011.25, -5.49);
thisAI->AddWaypoint(56, -4963.75, -1020.78, -5.07);
thisAI->AddWaypoint(57, -4959.3, -1030.3, -5.28);
thisAI->AddWaypoint(58, -4956.28, -1036.61, -5.84);
thisAI->AddWaypoint(59, -4952.05, -1043.75, -9.04);
thisAI->AddWaypoint(60, -4943.8, -1055.06, -17.91);
thisAI->AddWaypoint(61, -4939.47, -1055.61, -20.73);
thisAI->AddWaypoint(62, -4929.16, -1053.64, -25.65);
thisAI->AddWaypoint(63, -4922.28, -1052.37, -28.72);
thisAI->AddWaypoint(64, -4913.26, -1051.3, -31.80);
thisAI->AddWaypoint(65, -4903.54, -1054.17, -33.48);
thisAI->AddWaypoint(66, -4905.95, -1056.71, -33.68);
thisAI->AddWaypoint(67, -4913.18, -1064.32, -39.46);
thisAI->AddWaypoint(68, -4925.27, -1076.98, -47.39);
thisAI->AddWaypoint(69, -4932.68, -1084.42, -51.00);
thisAI->AddWaypoint(70, -4938.3, -1100.41, -50.71, 5000);
thisAI->AddWaypoint(71, -4937.34, -1102.87, -49.82);
QUEST_HOMEWARD = 4770,
NPC_WYVERN = 4107,
FACTION_ESCORTEE = 232 //guessed
};
return thisAI;
float m_afWyvernLoc[3][3]=
{
{-4990.606, -906.057, -5.343},
{-4970.241, -927.378, -4.951},
{-4985.364, -952.528, -5.199}
};
struct TRINITY_DLL_DECL npc_paoka_swiftmountainAI : public npc_escortAI
{
npc_paoka_swiftmountainAI(Creature* pCreature) : npc_escortAI(pCreature) { }
void Reset() { }
void WaypointReached(uint32 uiPointId)
{
switch(uiPointId)
{
case 15:
DoScriptText(SAY_WYVERN, m_creature);
DoSpawnWyvern();
break;
case 26:
DoScriptText(SAY_COMPLETE, m_creature);
break;
case 27:
if (Player* pPlayer = (Player*)Unit::GetUnit(*m_creature, PlayerGUID))
pPlayer->GroupEventHappens(QUEST_HOMEWARD, m_creature);
break;
}
}
void DoSpawnWyvern()
{
for(int i = 0; i < 3; ++i)
m_creature->SummonCreature(NPC_WYVERN,
m_afWyvernLoc[i][0], m_afWyvernLoc[i][1], m_afWyvernLoc[i][2], 0.0f,
TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
}
void JustDied(Unit* pKiller)
{
if (Player* pPlayer = (Player*)Unit::GetUnit(*m_creature, PlayerGUID))
{
if (pPlayer->GetQuestStatus(QUEST_HOMEWARD) == QUEST_STATUS_INCOMPLETE)
pPlayer->FailQuest(QUEST_HOMEWARD);
}
}
};
CreatureAI* GetAI_npc_paoka_swiftmountain(Creature* pCreature)
{
npc_paoka_swiftmountainAI* pTempAI = new npc_paoka_swiftmountainAI(pCreature);
pTempAI->FillPointMovementListForCreature();
return (CreatureAI*)pTempAI;
}
bool QuestAccept_npc_paoka_swiftmountain(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
{
if (pQuest->GetQuestId() == QUEST_HOMEWARD)
{
DoScriptText(SAY_START, pCreature, pPlayer);
pCreature->setFaction(FACTION_ESCORTEE);
if (npc_paoka_swiftmountainAI* pEscortAI = CAST_AI(npc_paoka_swiftmountainAI,pCreature->AI()))
pEscortAI->Start(false, false, pPlayer->GetGUID(), pQuest);
}
return true;
}
/*#####
@@ -308,9 +334,15 @@ void AddSC_thousand_needles()
Script *newscript;
newscript = new Script;
newscript->Name = "npc_swiftmountain";
newscript->GetAI = &GetAI_npc_swiftmountain;
newscript->pQuestAccept = &QuestAccept_npc_swiftmountain;
newscript->Name = "npc_lakota_windsong";
newscript->GetAI = &GetAI_npc_lakota_windsong;
newscript->pQuestAccept = &QuestAccept_npc_lakota_windsong;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_paoka_swiftmountain";
newscript->GetAI = &GetAI_npc_paoka_swiftmountain;
newscript->pQuestAccept = &QuestAccept_npc_paoka_swiftmountain;
newscript->RegisterSelf();
newscript = new Script;
@@ -175,7 +175,9 @@ bool QuestAccept_npc_daphne_stilwell(Player* pPlayer, Creature* pCreature, const
if (pQuest->GetQuestId() == QUEST_TOME_VALOR)
{
DoScriptText(SAY_DS_START, pCreature);
CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, true, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_daphne_stilwellAI, pCreature->AI()))
pEscortAI->Start(true, true, pPlayer->GetGUID());
}
return true;
@@ -257,12 +259,14 @@ struct TRINITY_DLL_DECL npc_defias_traitorAI : public npc_escortAI
}
};
bool QuestAccept_npc_defias_traitor(Player* pPlayer, Creature* creature, Quest const* quest)
bool QuestAccept_npc_defias_traitor(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_DEFIAS_BROTHERHOOD)
{
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, true, pPlayer->GetGUID());
DoScriptText(SAY_START, creature, pPlayer);
if (npc_escortAI* pEscortAI = CAST_AI(npc_defias_traitorAI, pCreature->AI()))
pEscortAI->Start(true, true, pPlayer->GetGUID());
DoScriptText(SAY_START, pCreature, pPlayer);
}
return true;
@@ -338,7 +338,9 @@ bool QuestAccept_npc_kayra_longmane(Player* pPlayer, Creature* pCreature, Quest
if (pQuest->GetQuestId() == QUEST_ESCAPE_FROM)
{
DoScriptText(SAY_START, pCreature, pPlayer);
CAST_AI(npc_escortAI, pCreature->AI())->Start(false, false, pPlayer->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_kayra_longmaneAI, pCreature->AI()))
pEscortAI->Start(false, false, pPlayer->GetGUID());
}
return true;
}