Files
TCPlayerbotCore/src/scripts/world/npcs_special.cpp
T

2191 lines
76 KiB
C++
Raw Normal View History

2009-02-17 18:08:26 +01:00
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
2008-11-21 19:27:24 -05:00
* 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
*/
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/* ScriptData
SDName: Npcs_Special
SD%Complete: 100
2009-03-22 23:11:55 +01:00
SDComment: To be used for special NPCs that are located globally.
2008-11-21 19:27:24 -05:00
SDCategory: NPCs
EndScriptData
*/
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/* ContentData
2009-06-19 00:22:19 +02:00
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)
2008-11-21 19:27:24 -05:00
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
2008-11-21 19:27:24 -05:00
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
2008-11-21 19:27:24 -05:00
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
2008-11-21 19:27:24 -05:00
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
2010-01-01 07:06:47 +01:00
npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage
2008-11-21 19:27:24 -05:00
EndContentData */
2009-10-17 15:51:44 -07:00
2010-01-19 11:36:05 +01:00
#include "ScriptedPch.h"
#include "ScriptedEscortAI.h"
2009-06-19 00:22:19 +02:00
#include "ObjectMgr.h"
2010-01-19 11:36:05 +01:00
#include "ScriptMgr.h"
#include "World.h"
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
/*########
# npc_air_force_bots
#########*/
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
enum SpawnType
{
2009-08-15 00:32:04 +02:00
SPAWNTYPE_TRIPWIRE_ROOFTOP, // no warning, summon Creature at smaller range
2009-06-19 00:22:19 +02:00
SPAWNTYPE_ALARMBOT, // cast guards mark and summon npc - if player shows up with that buff duration < 5 seconds attack
};
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
struct SpawnAssociation
{
uint32 m_uiThisCreatureEntry;
uint32 m_uiSpawnedCreatureEntry;
SpawnType m_SpawnType;
};
2009-10-17 15:51:44 -07:00
2009-10-17 07:42:48 -07:00
enum eEnums
2009-06-19 00:22:19 +02:00
{
SPELL_GUARDS_MARK = 38067,
AURA_DURATION_TIME_LEFT = 5000
};
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
const float RANGE_TRIPWIRE = 15.0f;
const float RANGE_GUARDS_MARK = 50.0f;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
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)
};
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_air_force_botsAI : public ScriptedAI
2009-06-19 00:22:19 +02:00
{
npc_air_force_botsAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pSpawnAssoc = NULL;
m_uiSpawnedGUID = 0;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
// find the correct spawnhandling
static uint32 uiEntryCount = sizeof(m_aSpawnAssociations)/sizeof(SpawnAssociation);
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
for (uint8 i=0; i<uiEntryCount; ++i)
{
if (m_aSpawnAssociations[i].m_uiThisCreatureEntry == pCreature->GetEntry())
{
m_pSpawnAssoc = &m_aSpawnAssociations[i];
break;
}
}
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
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);
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
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;
}
}
}
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
SpawnAssociation* m_pSpawnAssoc;
uint64 m_uiSpawnedGUID;
2009-10-17 15:51:44 -07:00
void Reset() {}
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
Creature* SummonGuard()
{
Creature* pSummoned = m_creature->SummonCreature(m_pSpawnAssoc->m_uiSpawnedCreatureEntry, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000);
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
if (pSummoned)
m_uiSpawnedGUID = pSummoned->GetGUID();
else
{
2009-08-15 00:32:04 +02:00
error_db_log("TCSR: npc_air_force_bots: wasn't able to spawn Creature %u", m_pSpawnAssoc->m_uiSpawnedCreatureEntry);
2009-06-19 00:22:19 +02:00
m_pSpawnAssoc = NULL;
}
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
return pSummoned;
}
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
Creature* GetSummonedGuard()
{
2009-08-05 22:24:30 -05:00
Creature* pCreature = Unit::GetCreature(*m_creature, m_uiSpawnedGUID);
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
if (pCreature && pCreature->isAlive())
return pCreature;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
return NULL;
}
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
void MoveInLineOfSight(Unit* pWho)
{
if (!m_pSpawnAssoc)
return;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
if (pWho->isTargetableForAttack() && m_creature->IsHostileTo(pWho))
{
2009-08-05 22:24:30 -05:00
Player* pPlayerTarget = pWho->GetTypeId() == TYPEID_PLAYER ? CAST_PLR(pWho) : NULL;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
// airforce guards only spawn for players
if (!pPlayerTarget)
return;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
Creature* pLastSpawnedGuard = m_uiSpawnedGUID == 0 ? NULL : GetSummonedGuard();
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
// prevent calling Unit::GetUnit at next MoveInLineOfSight call - speedup
if (!pLastSpawnedGuard)
m_uiSpawnedGUID = 0;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
switch(m_pSpawnAssoc->m_SpawnType)
{
case SPAWNTYPE_ALARMBOT:
{
if (!pWho->IsWithinDistInMap(m_creature, RANGE_GUARDS_MARK))
return;
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
Aura* pMarkAura = pWho->GetAura(SPELL_GUARDS_MARK);
2009-06-19 00:22:19 +02:00
if (pMarkAura)
{
2009-10-27 21:39:53 -07:00
// the target wasn't able to move out of our range within 25 seconds
2009-06-19 00:22:19 +02:00
if (!pLastSpawnedGuard)
{
pLastSpawnedGuard = SummonGuard();
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
if (!pLastSpawnedGuard)
return;
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
if (pMarkAura->GetDuration() < AURA_DURATION_TIME_LEFT)
2009-06-19 00:22:19 +02:00
{
if (!pLastSpawnedGuard->getVictim())
pLastSpawnedGuard->AI()->AttackStart(pWho);
}
}
else
{
if (!pLastSpawnedGuard)
pLastSpawnedGuard = SummonGuard();
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
if (!pLastSpawnedGuard)
return;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
pLastSpawnedGuard->CastSpell(pWho, SPELL_GUARDS_MARK, true);
}
break;
}
case SPAWNTYPE_TRIPWIRE_ROOFTOP:
{
if (!pWho->IsWithinDistInMap(m_creature, RANGE_TRIPWIRE))
return;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
if (!pLastSpawnedGuard)
pLastSpawnedGuard = SummonGuard();
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
if (!pLastSpawnedGuard)
return;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
// ROOFTOP only triggers if the player is on the ground
if (!pPlayerTarget->IsFlying())
{
if (!pLastSpawnedGuard->getVictim())
pLastSpawnedGuard->AI()->AttackStart(pWho);
}
break;
}
}
}
}
};
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
CreatureAI* GetAI_npc_air_force_bots(Creature* pCreature)
{
return new npc_air_force_botsAI(pCreature);
}
2009-10-17 15:51:44 -07:00
/*######
## 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;
}
2008-11-21 19:27:24 -05:00
/*########
# npc_chicken_cluck
#########*/
2009-10-17 15:51:44 -07:00
#define EMOTE_HELLO -1070004
#define EMOTE_CLUCK_TEXT -1070006
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
#define QUEST_CLUCK 3861
#define FACTION_FRIENDLY 35
2008-11-21 19:27:24 -05:00
#define FACTION_CHICKEN 31
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_chicken_cluckAI : public ScriptedAI
2008-11-21 19:27:24 -05:00
{
npc_chicken_cluckAI(Creature *c) : ScriptedAI(c) {}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
uint32 ResetFlagTimer;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void Reset()
{
ResetFlagTimer = 120000;
m_creature->setFaction(FACTION_CHICKEN);
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
}
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit *who) {}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void UpdateAI(const uint32 diff)
{
// Reset flags after a certain time has passed so that the next player has to start the 'event' again
2009-08-14 00:02:13 +02:00
if (m_creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
2008-11-21 19:27:24 -05:00
{
2009-10-27 21:28:20 -07:00
if (ResetFlagTimer <= diff)
2009-05-01 01:06:19 +02:00
{
2008-11-21 19:27:24 -05:00
EnterEvadeMode();
2009-05-01 01:06:19 +02:00
return;
2009-10-27 21:28:20 -07:00
} else ResetFlagTimer -= diff;
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
if (UpdateVictim())
2008-11-21 19:27:24 -05:00
DoMeleeAttackIfReady();
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
void ReceiveEmote(Player* pPlayer, uint32 emote)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
switch(emote)
2008-11-21 19:27:24 -05:00
{
case TEXTEMOTE_CHICKEN:
2009-08-14 00:02:13 +02:00
if (pPlayer->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_NONE && rand()%30 == 1)
2008-11-21 19:27:24 -05:00
{
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
m_creature->setFaction(FACTION_FRIENDLY);
DoScriptText(EMOTE_HELLO, m_creature);
2008-11-21 19:27:24 -05:00
}
break;
case TEXTEMOTE_CHEER:
2009-08-14 00:02:13 +02:00
if (pPlayer->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_COMPLETE)
{
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
m_creature->setFaction(FACTION_FRIENDLY);
DoScriptText(EMOTE_CLUCK_TEXT, m_creature);
}
break;
}
2008-11-21 19:27:24 -05:00
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_chicken_cluck(Creature* pCreature)
{
2009-08-14 00:39:07 +02:00
return new npc_chicken_cluckAI(pCreature);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
bool QuestAccept_npc_chicken_cluck(Player* pPlayer, Creature* pCreature, const Quest *_Quest)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
if (_Quest->GetQuestId() == QUEST_CLUCK)
2009-08-14 00:39:07 +02:00
CAST_AI(npc_chicken_cluckAI, pCreature->AI())->Reset();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
bool QuestComplete_npc_chicken_cluck(Player* pPlayer, Creature* pCreature, const Quest *_Quest)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
if (_Quest->GetQuestId() == QUEST_CLUCK)
2009-08-14 00:39:07 +02:00
CAST_AI(npc_chicken_cluckAI, pCreature->AI())->Reset();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*######
## npc_dancing_flames
######*/
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
#define SPELL_BRAZIER 45423
#define SPELL_SEDUCTION 47057
#define SPELL_FIERY_AURA 45427
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_dancing_flamesAI : public ScriptedAI
2008-11-21 19:27:24 -05:00
{
npc_dancing_flamesAI(Creature *c) : ScriptedAI(c) {}
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
bool active;
uint32 can_iteract;
2009-10-17 15:51:44 -07:00
void Reset()
2009-02-09 08:16:34 -05:00
{
active = true;
can_iteract = 3500;
DoCast(m_creature, SPELL_BRAZIER, true);
DoCast(m_creature, SPELL_FIERY_AURA, false);
2009-02-09 08:16:34 -05:00
float x, y, z;
m_creature->GetPosition(x,y,z);
m_creature->Relocate(x,y,z + 0.94f);
2009-04-22 17:50:26 -05:00
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
2009-02-09 08:16:34 -05:00
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
WorldPacket data; //send update position to client
m_creature->BuildHeartBeatMsg(&data);
m_creature->SendMessageToSet(&data,true);
}
2009-10-17 15:51:44 -07:00
void UpdateAI(const uint32 diff)
2009-02-09 08:16:34 -05:00
{
if (!active)
{
2009-08-14 00:02:13 +02:00
if (can_iteract <= diff){
2009-02-09 08:16:34 -05:00
active = true;
can_iteract = 3500;
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
2009-10-27 21:28:20 -07:00
} else can_iteract -= diff;
2009-02-09 08:16:34 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit* who){}
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
void ReceiveEmote(Player* pPlayer, uint32 emote)
2009-02-09 08:16:34 -05:00
{
2009-08-14 00:02:13 +02:00
if (m_creature->IsWithinLOS(pPlayer->GetPositionX(),pPlayer->GetPositionY(),pPlayer->GetPositionZ()) && m_creature->IsWithinDistInMap(pPlayer,30.0f))
2009-02-09 08:16:34 -05:00
{
2009-08-14 00:02:13 +02:00
m_creature->SetInFront(pPlayer);
active = false;
2009-10-17 15:51:44 -07:00
WorldPacket data;
m_creature->BuildHeartBeatMsg(&data);
m_creature->SendMessageToSet(&data,true);
switch(emote)
2009-02-09 08:16:34 -05:00
{
case TEXTEMOTE_KISS: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SHY); break;
case TEXTEMOTE_WAVE: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break;
case TEXTEMOTE_BOW: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_BOW); break;
case TEXTEMOTE_JOKE: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); break;
case TEXTEMOTE_DANCE:
{
2009-08-14 00:02:13 +02:00
if (!pPlayer->HasAura(SPELL_SEDUCTION))
DoCast(pPlayer, SPELL_SEDUCTION, true);
}
break;
2009-02-09 08:16:34 -05:00
}
}
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_dancing_flames(Creature* pCreature)
{
2009-08-14 00:39:07 +02:00
return new npc_dancing_flamesAI(pCreature);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*######
## Triage quest
######*/
2009-10-17 15:51:44 -07:00
//signed for 9623
2009-02-17 18:08:26 +01:00
#define SAY_DOC1 -1000201
#define SAY_DOC2 -1000202
#define SAY_DOC3 -1000203
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
#define DOCTOR_ALLIANCE 12939
#define DOCTOR_HORDE 12920
#define ALLIANCE_COORDS 7
#define HORDE_COORDS 6
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
struct Location
{
float x, y, z, o;
};
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
static Location AllianceCoords[]=
{
2009-02-20 14:14:16 +01:00
{-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
2008-11-21 19:27:24 -05:00
};
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
//alliance run to where
#define A_RUNTOX -3742.96
#define A_RUNTOY -4531.52
#define A_RUNTOZ 11.91
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
static Location HordeCoords[]=
{
2009-02-20 14:14:16 +01:00
{-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
2008-11-21 19:27:24 -05:00
};
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
//horde run to where
#define H_RUNTOX -1016.44
#define H_RUNTOY -3508.48
#define H_RUNTOZ 62.96
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
const uint32 AllianceSoldierId[3] =
{
12938, // 12938 Injured Alliance Soldier
12936, // 12936 Badly injured Alliance Soldier
12937 // 12937 Critically injured Alliance Soldier
};
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
const uint32 HordeSoldierId[3] =
{
12923, //12923 Injured Soldier
12924, //12924 Badly injured Soldier
12925 //12925 Critically injured Soldier
};
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*######
## npc_doctor (handles both Gustaf Vanhowzen and Gregory Victor)
######*/
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_doctorAI : public ScriptedAI
2008-11-21 19:27:24 -05:00
{
2009-03-31 18:21:45 -06:00
npc_doctorAI(Creature *c) : ScriptedAI(c) {}
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
uint64 PlayerGUID;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
uint32 SummonPatient_Timer;
uint32 SummonPatientCount;
uint32 PatientDiedCount;
uint32 PatientSavedCount;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
bool Event;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
std::list<uint64> Patients;
std::vector<Location*> Coordinates;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
void Reset()
{
2009-08-14 00:02:13 +02:00
PlayerGUID = 0;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
SummonPatient_Timer = 10000;
SummonPatientCount = 0;
PatientDiedCount = 0;
PatientSavedCount = 0;
2009-10-17 15:51:44 -07:00
2009-08-12 23:34:19 +02:00
Patients.clear();
Coordinates.clear();
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
Event = false;
2009-10-17 15:51:44 -07:00
2009-08-12 23:34:19 +02:00
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
2009-02-20 14:14:16 +01:00
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
void BeginEvent(Player* pPlayer);
2008-11-21 19:27:24 -05:00
void PatientDied(Location* Point);
2009-08-14 00:02:13 +02:00
void PatientSaved(Creature* soldier, Player* pPlayer, Location* Point);
2008-11-21 19:27:24 -05:00
void UpdateAI(const uint32 diff);
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit* who){}
2008-11-21 19:27:24 -05:00
};
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*#####
## npc_injured_patient (handles all the patients, no matter Horde or Alliance)
#####*/
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_injured_patientAI : public ScriptedAI
2008-11-21 19:27:24 -05:00
{
npc_injured_patientAI(Creature *c) : ScriptedAI(c) {}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
uint64 Doctorguid;
Location* Coord;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void Reset()
{
Doctorguid = 0;
Coord = NULL;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
//no select
2008-11-21 19:27:24 -05:00
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
//no regen health
2008-11-21 19:27:24 -05:00
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
//to make them lay with face down
2009-01-31 14:41:36 -06:00
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
uint32 mobId = m_creature->GetEntry();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
switch (mobId)
{ //lower max health
case 12923:
case 12938: //Injured Soldier
m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.75));
break;
case 12924:
case 12936: //Badly injured Soldier
m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.50));
break;
case 12925:
case 12937: //Critically injured Soldier
m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.25));
break;
}
}
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit* who){}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void SpellHit(Unit *caster, const SpellEntry *spell)
{
if (caster->GetTypeId() == TYPEID_PLAYER && m_creature->isAlive() && spell->Id == 20804)
{
2009-08-14 00:02:13 +02:00
if ((CAST_PLR(caster)->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (CAST_PLR(caster)->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
2009-02-20 14:14:16 +01:00
if (Doctorguid)
2009-08-14 00:02:13 +02:00
if (Creature* Doctor = Unit::GetCreature(*m_creature, Doctorguid))
2009-06-04 17:03:43 -05:00
CAST_AI(npc_doctorAI, Doctor->AI())->PatientSaved(m_creature, CAST_PLR(caster), Coord);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
//make not selectable
2008-11-21 19:27:24 -05:00
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
//regen health
2008-11-21 19:27:24 -05:00
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
//stand up
2009-01-31 14:41:36 -06:00
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
2009-10-17 15:51:44 -07:00
DoScriptText(RAND(SAY_DOC1,SAY_DOC2,SAY_DOC3), m_creature);
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
uint32 mobId = m_creature->GetEntry();
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
switch (mobId)
{
case 12923:
case 12924:
case 12925:
m_creature->GetMotionMaster()->MovePoint(0, H_RUNTOX, H_RUNTOY, H_RUNTOZ);
break;
case 12936:
case 12937:
case 12938:
m_creature->GetMotionMaster()->MovePoint(0, A_RUNTOX, A_RUNTOY, A_RUNTOZ);
break;
}
}
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void UpdateAI(const uint32 diff)
{
2009-02-20 14:14:16 +01:00
//lower HP on every world tick makes it a useful counter, not officlone though
2008-11-21 19:27:24 -05:00
if (m_creature->isAlive() && m_creature->GetHealth() > 6)
2009-02-20 14:14:16 +01:00
{
2009-08-14 00:02:13 +02:00
m_creature->SetHealth(uint32(m_creature->GetHealth()-5));
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
if (m_creature->isAlive() && m_creature->GetHealth() <= 6)
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->setDeathState(JUST_DIED);
m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, 32);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
if (Doctorguid)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
if (Creature* Doctor = Unit::GetCreature((*m_creature), Doctorguid))
2009-06-04 17:03:43 -05:00
CAST_AI(npc_doctorAI, Doctor->AI())->PatientDied(Coord);
2008-11-21 19:27:24 -05:00
}
}
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_injured_patient(Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
return new npc_injured_patientAI (pCreature);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*
npc_doctor (continue)
*/
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
void npc_doctorAI::BeginEvent(Player* pPlayer)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
PlayerGUID = pPlayer->GetGUID();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
SummonPatient_Timer = 10000;
SummonPatientCount = 0;
PatientDiedCount = 0;
PatientSavedCount = 0;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
switch(m_creature->GetEntry())
{
case DOCTOR_ALLIANCE:
2009-10-17 16:20:24 -07:00
for (uint8 i = 0; i < ALLIANCE_COORDS; ++i)
2008-11-21 19:27:24 -05:00
Coordinates.push_back(&AllianceCoords[i]);
break;
case DOCTOR_HORDE:
2009-10-17 16:20:24 -07:00
for (uint8 i = 0; i < HORDE_COORDS; ++i)
2008-11-21 19:27:24 -05:00
Coordinates.push_back(&HordeCoords[i]);
break;
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
Event = true;
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void npc_doctorAI::PatientDied(Location* Point)
{
2009-08-14 00:02:13 +02:00
Player* pPlayer = Unit::GetPlayer(PlayerGUID);
if (pPlayer && ((pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)))
2008-11-21 19:27:24 -05:00
{
2009-08-12 23:34:19 +02:00
++PatientDiedCount;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
if (PatientDiedCount > 5 && Event)
{
2009-08-14 00:02:13 +02:00
if (pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
pPlayer->FailQuest(6624);
else if (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
pPlayer->FailQuest(6622);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
Reset();
2009-08-12 23:34:19 +02:00
return;
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
Coordinates.push_back(Point);
}
2009-08-12 23:34:19 +02:00
else
// If no player or player abandon quest in progress
Reset();
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
void npc_doctorAI::PatientSaved(Creature* soldier, Player* pPlayer, Location* Point)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
if (pPlayer && PlayerGUID == pPlayer->GetGUID())
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
if ((pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
2008-11-21 19:27:24 -05:00
{
2009-08-12 23:34:19 +02:00
++PatientSavedCount;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
if (PatientSavedCount == 15)
2008-11-21 19:27:24 -05:00
{
2009-02-20 14:14:16 +01:00
if (!Patients.empty())
2008-11-21 19:27:24 -05:00
{
std::list<uint64>::const_iterator itr;
2009-10-17 16:20:24 -07:00
for (itr = Patients.begin(); itr != Patients.end(); ++itr)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:02:13 +02:00
if (Creature* Patient = Unit::GetCreature((*m_creature), *itr))
2008-11-21 19:27:24 -05:00
Patient->setDeathState(JUST_DIED);
}
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
if (pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
pPlayer->AreaExploredOrEventHappens(6624);
else if (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
pPlayer->AreaExploredOrEventHappens(6622);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
Reset();
2009-08-12 23:34:19 +02:00
return;
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
Coordinates.push_back(Point);
}
}
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void npc_doctorAI::UpdateAI(const uint32 diff)
{
2009-02-20 14:14:16 +01:00
if (Event && SummonPatientCount >= 20)
2008-11-21 19:27:24 -05:00
{
2009-02-20 14:14:16 +01:00
Reset();
2009-08-12 23:34:19 +02:00
return;
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
if (Event)
2008-11-21 19:27:24 -05:00
{
2009-10-27 21:28:20 -07:00
if (SummonPatient_Timer <= diff)
2009-02-20 14:14:16 +01:00
{
Creature* Patient = NULL;
Location* Point = NULL;
2009-10-17 15:51:44 -07:00
if (Coordinates.empty())
2009-02-20 14:14:16 +01:00
return;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
std::vector<Location*>::iterator itr = Coordinates.begin()+rand()%Coordinates.size();
uint32 patientEntry = 0;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
switch(m_creature->GetEntry())
{
case DOCTOR_ALLIANCE: patientEntry = AllianceSoldierId[rand()%3]; break;
case DOCTOR_HORDE: patientEntry = HordeSoldierId[rand()%3]; break;
default:
2009-04-24 00:51:09 -04:00
error_log("TSCR: Invalid entry for Triage doctor. Please check your database");
2009-02-20 14:14:16 +01:00
return;
}
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
Point = *itr;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
Patient = m_creature->SummonCreature(patientEntry, Point->x, Point->y, Point->z, Point->o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
if (Patient)
{
2009-04-06 21:14:51 +02:00
//303, this flag appear to be required for client side item->spell to work (TARGET_SINGLE_FRIEND)
2009-02-20 14:14:16 +01:00
Patient->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
Patients.push_back(Patient->GetGUID());
2009-06-04 17:03:43 -05:00
CAST_AI(npc_injured_patientAI, Patient->AI())->Doctorguid = m_creature->GetGUID();
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
if (Point)
2009-06-04 17:03:43 -05:00
CAST_AI(npc_injured_patientAI, Patient->AI())->Coord = Point;
2009-10-17 15:51:44 -07:00
2009-02-20 14:14:16 +01:00
Coordinates.erase(itr);
}
SummonPatient_Timer = 10000;
2009-10-27 22:09:45 -07:00
++SummonPatientCount;
2009-10-27 21:28:20 -07:00
} else SummonPatient_Timer -= diff;
2009-02-20 14:14:16 +01:00
}
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-15 00:32:04 +02:00
bool QuestAccept_npc_doctor(Player* pPlayer, Creature* pCreature, Quest const *quest)
2008-11-21 19:27:24 -05:00
{
2009-02-20 14:14:16 +01:00
if ((quest->GetQuestId() == 6624) || (quest->GetQuestId() == 6622))
2009-08-15 00:32:04 +02:00
CAST_AI(npc_doctorAI, pCreature->AI())->BeginEvent(pPlayer);
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_doctor(Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
return new npc_doctorAI (pCreature);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
/*######
## npc_garments_of_quests
######*/
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
//TODO: get text for each NPC
2009-10-17 15:51:44 -07:00
2009-10-17 07:42:48 -07:00
enum eGarments
2009-03-22 23:11:55 +01:00
{
SPELL_LESSER_HEAL_R2 = 2052,
SPELL_FORTITUDE_R1 = 1243,
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
QUEST_MOON = 5621,
QUEST_LIGHT_1 = 5624,
QUEST_LIGHT_2 = 5625,
QUEST_SPIRIT = 5648,
QUEST_DARKNESS = 5650,
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
ENTRY_SHAYA = 12429,
ENTRY_ROBERTS = 12423,
ENTRY_DOLF = 12427,
ENTRY_KORJA = 12430,
ENTRY_DG_KEL = 12428,
2009-10-17 15:51:44 -07:00
//used by 12429,12423,12427,12430,12428, but signed for 12429
2009-03-22 23:11:55 +01:00
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
2009-03-22 23:11:55 +01:00
};
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_garments_of_questsAI : public npc_escortAI
2009-03-22 23:11:55 +01:00
{
2009-04-19 21:16:11 +02:00
npc_garments_of_questsAI(Creature *c) : npc_escortAI(c) {Reset();}
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
uint64 caster;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
bool bIsHealed;
bool bCanRun;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
uint32 RunAwayTimer;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
void Reset()
{
caster = 0;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
bIsHealed = false;
bCanRun = false;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
RunAwayTimer = 5000;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
//expect database to have RegenHealth=0
m_creature->SetHealth(int(m_creature->GetMaxHealth()*0.7));
}
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit *who) {}
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
void SpellHit(Unit* pCaster, const SpellEntry *Spell)
{
if (Spell->Id == SPELL_LESSER_HEAL_R2 || Spell->Id == SPELL_FORTITUDE_R1)
{
//not while in combat
2009-04-27 21:23:42 -05:00
if (m_creature->isInCombat())
2009-03-22 23:11:55 +01:00
return;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
//nothing to be done now
if (bIsHealed && bCanRun)
return;
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
if (pCaster->GetTypeId() == TYPEID_PLAYER)
{
switch(m_creature->GetEntry())
{
case ENTRY_SHAYA:
2009-06-04 16:36:33 -05:00
if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_MOON) == QUEST_STATUS_INCOMPLETE)
2009-03-22 23:11:55 +01:00
{
if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
{
DoScriptText(SAY_SHAYA_THANKS,m_creature,pCaster);
bCanRun = true;
}
else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
{
caster = pCaster->GetGUID();
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
bIsHealed = true;
}
}
break;
case ENTRY_ROBERTS:
2009-06-04 16:36:33 -05:00
if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_LIGHT_1) == QUEST_STATUS_INCOMPLETE)
2009-03-22 23:11:55 +01:00
{
if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
{
DoScriptText(SAY_ROBERTS_THANKS,m_creature,pCaster);
bCanRun = true;
}
else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
{
caster = pCaster->GetGUID();
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
bIsHealed = true;
}
}
break;
case ENTRY_DOLF:
2009-06-04 16:36:33 -05:00
if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_LIGHT_2) == QUEST_STATUS_INCOMPLETE)
2009-03-22 23:11:55 +01:00
{
if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
{
DoScriptText(SAY_DOLF_THANKS,m_creature,pCaster);
bCanRun = true;
}
else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
{
caster = pCaster->GetGUID();
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
bIsHealed = true;
}
}
break;
case ENTRY_KORJA:
2009-06-04 16:36:33 -05:00
if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_SPIRIT) == QUEST_STATUS_INCOMPLETE)
2009-03-22 23:11:55 +01:00
{
if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
{
DoScriptText(SAY_KORJA_THANKS,m_creature,pCaster);
bCanRun = true;
}
else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
{
caster = pCaster->GetGUID();
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
bIsHealed = true;
}
}
break;
case ENTRY_DG_KEL:
2009-06-04 16:36:33 -05:00
if (CAST_PLR(pCaster)->GetQuestStatus(QUEST_DARKNESS) == QUEST_STATUS_INCOMPLETE)
2009-03-22 23:11:55 +01:00
{
if (bIsHealed && !bCanRun && Spell->Id == SPELL_FORTITUDE_R1)
{
DoScriptText(SAY_DG_KEL_THANKS,m_creature,pCaster);
bCanRun = true;
}
else if (!bIsHealed && Spell->Id == SPELL_LESSER_HEAL_R2)
{
caster = pCaster->GetGUID();
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_COMMON_HEALED,m_creature,pCaster);
bIsHealed = true;
}
}
break;
}
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
//give quest credit, not expect any special quest objectives
if (bCanRun)
2009-06-04 16:36:33 -05:00
CAST_PLR(pCaster)->TalkedToCreature(m_creature->GetEntry(),m_creature->GetGUID());
2009-03-22 23:11:55 +01:00
}
}
}
2009-10-17 15:51:44 -07:00
2009-04-19 21:16:11 +02:00
void WaypointReached(uint32 uiPoint)
2009-03-22 23:11:55 +01:00
{
}
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
void UpdateAI(const uint32 diff)
{
2009-04-27 21:23:42 -05:00
if (bCanRun && !m_creature->isInCombat())
2009-03-22 23:11:55 +01:00
{
if (RunAwayTimer <= diff)
{
if (Unit *pUnit = Unit::GetUnit(*m_creature,caster))
{
switch(m_creature->GetEntry())
{
2009-04-19 21:16:11 +02:00
case ENTRY_SHAYA: DoScriptText(SAY_SHAYA_GOODBYE,m_creature,pUnit); break;
case ENTRY_ROBERTS: DoScriptText(SAY_ROBERTS_GOODBYE,m_creature,pUnit); break;
case ENTRY_DOLF: DoScriptText(SAY_DOLF_GOODBYE,m_creature,pUnit); break;
case ENTRY_KORJA: DoScriptText(SAY_KORJA_GOODBYE,m_creature,pUnit); break;
case ENTRY_DG_KEL: DoScriptText(SAY_DG_KEL_GOODBYE,m_creature,pUnit); break;
2009-03-22 23:11:55 +01:00
}
2009-10-17 15:51:44 -07:00
2009-04-19 21:16:11 +02:00
Start(false,true,true);
2009-03-22 23:11:55 +01:00
}
else
EnterEvadeMode(); //something went wrong
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
RunAwayTimer = 30000;
2009-10-27 21:28:20 -07:00
} else RunAwayTimer -= diff;
2009-03-22 23:11:55 +01:00
}
2009-10-17 15:51:44 -07:00
2009-04-19 21:16:11 +02:00
npc_escortAI::UpdateAI(diff);
2009-03-22 23:11:55 +01:00
}
};
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
CreatureAI* GetAI_npc_garments_of_quests(Creature* pCreature)
{
2009-08-16 02:12:14 +02:00
return new npc_garments_of_questsAI(pCreature);
2009-03-22 23:11:55 +01:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*######
## npc_guardian
######*/
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
#define SPELL_DEATHTOUCH 5
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_guardianAI : public ScriptedAI
2008-11-21 19:27:24 -05:00
{
npc_guardianAI(Creature *c) : ScriptedAI(c) {}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void Reset()
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit *who)
2008-11-21 19:27:24 -05:00
{
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void UpdateAI(const uint32 diff)
{
2009-01-30 18:10:05 -06:00
if (!UpdateVictim())
2008-11-21 19:27:24 -05:00
return;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
if (m_creature->isAttackReady())
{
DoCast(m_creature->getVictim(), SPELL_DEATHTOUCH, true);
2008-11-21 19:27:24 -05:00
m_creature->resetAttackTimer();
}
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_guardian(Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
return new npc_guardianAI (pCreature);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
/*######
## npc_kingdom_of_dalaran_quests
######*/
2009-10-17 15:51:44 -07:00
2009-10-17 07:42:48 -07:00
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
};
2009-10-17 15:51:44 -07:00
#define GOSSIP_ITEM_TELEPORT_TO "I am ready to be teleported to Dalaran."
2009-10-17 15:51:44 -07:00
bool GossipHello_npc_kingdom_of_dalaran_quests(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
2009-10-17 15:51:44 -07:00
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)))
2009-06-19 05:17:25 +02:00
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TELEPORT_TO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
2009-10-17 15:51:44 -07:00
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
2009-10-17 15:51:44 -07:00
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;
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*######
## npc_mount_vendor
######*/
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
bool GossipHello_npc_mount_vendor(Player* pPlayer, Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
bool canBuy;
canBuy = false;
2009-08-14 00:39:07 +02:00
uint32 vendor = pCreature->GetEntry();
2009-08-14 00:02:13 +02:00
uint8 race = pPlayer->getRace();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
switch (vendor)
{
case 384: //Katie Hunter
case 1460: //Unger Statforth
case 2357: //Merideth Carlson
case 4885: //Gregor MacVince
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(72) != REP_EXALTED && race != RACE_HUMAN)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5855, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 1261: //Veron Amberstill
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(47) != REP_EXALTED && race != RACE_DWARF)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5856, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 3362: //Ogunaro Wolfrunner
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(76) != REP_EXALTED && race != RACE_ORC)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5841, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 3685: //Harb Clawhoof
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(81) != REP_EXALTED && race != RACE_TAUREN)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5843, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 4730: //Lelanai
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(69) != REP_EXALTED && race != RACE_NIGHTELF)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5844, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 4731: //Zachariah Post
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(68) != REP_EXALTED && race != RACE_UNDEAD_PLAYER)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5840, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 7952: //Zjolnir
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(530) != REP_EXALTED && race != RACE_TROLL)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5842, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 7955: //Milli Featherwhistle
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(54) != REP_EXALTED && race != RACE_GNOME)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5857, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 16264: //Winaestra
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(911) != REP_EXALTED && race != RACE_BLOODELF)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(10305, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
case 17584: //Torallius the Pack Handler
2009-08-14 00:02:13 +02:00
if (pPlayer->GetReputationRank(930) != REP_EXALTED && race != RACE_DRAENEI)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(10239, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else canBuy = true;
break;
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
if (canBuy)
{
2009-08-14 00:39:07 +02:00
if (pCreature->isVendor())
2009-08-14 00:02:13 +02:00
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());
2008-11-21 19:27:24 -05:00
}
return true;
}
2009-10-17 15:51:44 -07:00
2009-08-15 00:32:04 +02:00
bool GossipSelect_npc_mount_vendor(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
2008-11-21 19:27:24 -05:00
{
2009-08-15 00:32:04 +02:00
if (uiAction == GOSSIP_ACTION_TRADE)
2009-08-14 00:39:07 +02:00
pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*######
## npc_rogue_trainer
######*/
2009-10-17 15:51:44 -07:00
#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."
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
bool GossipHello_npc_rogue_trainer(Player* pPlayer, Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
if (pCreature->isTrainer())
2009-08-14 00:02:13 +02:00
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
if (pCreature->isCanTrainingAndResetTalentsOf(pPlayer))
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_HELLO_ROGUE1, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_UNLEARNTALENTS);
2009-10-17 15:51:44 -07:00
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);
2009-08-14 00:02:13 +02:00
if (pPlayer->getClass() == CLASS_ROGUE && pPlayer->getLevel() >= 24 && !pPlayer->HasItemCount(17126,1) && !pPlayer->GetQuestRewardStatus(6681))
2008-11-21 19:27:24 -05:00
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_ROGUE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(5996, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
} else
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2009-08-15 00:32:04 +02:00
bool GossipSelect_npc_rogue_trainer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
2008-11-21 19:27:24 -05:00
{
2009-08-15 00:32:04 +02:00
switch(uiAction)
2008-11-21 19:27:24 -05:00
{
case GOSSIP_ACTION_INFO_DEF+1:
2009-08-14 00:02:13 +02:00
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->CastSpell(pPlayer,21100,false);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_ACTION_TRAIN:
2009-08-14 00:39:07 +02:00
pPlayer->SEND_TRAINERLIST(pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_OPTION_UNLEARNTALENTS:
2009-08-14 00:02:13 +02:00
pPlayer->CLOSE_GOSSIP_MENU();
2009-08-14 00:39:07 +02:00
pPlayer->SendTalentWipeConfirm(pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
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;
2008-11-21 19:27:24 -05:00
}
return true;
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
/*######
## npc_sayge
######*/
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
#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
2009-10-17 15:51:44 -07:00
#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"
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
bool GossipHello_npc_sayge(Player* pPlayer, Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
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))
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7393, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
else
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_SAYGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7339, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
return true;
}
2009-10-17 15:51:44 -07:00
2009-08-15 00:32:04 +02:00
void SendAction_npc_sayge(Player* pPlayer, Creature* pCreature, uint32 uiAction)
2008-11-21 19:27:24 -05:00
{
2009-08-15 00:32:04 +02:00
switch(uiAction)
2008-11-21 19:27:24 -05:00
{
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);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7340, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
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);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7341, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
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);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7361, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
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);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7362, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
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);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7363, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_ACTION_INFO_DEF:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SENDACTION_SAYGE17, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
2009-08-14 00:39:07 +02:00
pPlayer->SEND_GOSSIP_MENU(7364, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_ACTION_INFO_DEF+6:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_FORTUNE, false);
pPlayer->SEND_GOSSIP_MENU(7365, pCreature->GetGUID());
2008-11-21 19:27:24 -05:00
break;
}
}
2009-10-17 15:51:44 -07:00
2009-08-15 00:32:04 +02:00
bool GossipSelect_npc_sayge(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
2008-11-21 19:27:24 -05:00
{
2009-08-15 00:32:04 +02:00
switch(uiSender)
2008-11-21 19:27:24 -05:00
{
case GOSSIP_SENDER_MAIN:
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+1:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_DMG, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_DMG,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+2:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_RES, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_RES,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+3:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_ARM, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_ARM,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+4:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_SPI, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_SPI,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+5:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_INT, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_INT,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+6:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_STM, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_STM,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+7:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_STR, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_STR,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
case GOSSIP_SENDER_MAIN+8:
2009-08-14 00:39:07 +02:00
pCreature->CastSpell(pPlayer, SPELL_AGI, false);
2009-08-14 00:02:13 +02:00
pPlayer->AddSpellCooldown(SPELL_AGI,0,time(NULL) + 7200);
2009-08-15 00:32:04 +02:00
SendAction_npc_sayge(pPlayer, pCreature, uiAction);
2008-11-21 19:27:24 -05:00
break;
}
return true;
}
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_steam_tonkAI : public ScriptedAI
2008-11-21 19:27:24 -05:00
{
npc_steam_tonkAI(Creature *c) : ScriptedAI(c) {}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void Reset() {}
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit *who) {}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void OnPossess(bool apply)
{
if (apply)
{
// Initialize the action bar without the melee attack command
2009-03-05 18:48:56 -06:00
m_creature->InitCharmInfo();
2008-11-21 19:27:24 -05:00
m_creature->GetCharmInfo()->InitEmptyActionBar(false);
2009-10-17 15:51:44 -07:00
m_creature->SetReactState(REACT_PASSIVE);
2008-11-21 19:27:24 -05:00
}
else
m_creature->SetReactState(REACT_AGGRESSIVE);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_steam_tonk(Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
return new npc_steam_tonkAI(pCreature);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
#define SPELL_TONK_MINE_DETONATE 25099
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_tonk_mineAI : public ScriptedAI
2008-11-21 19:27:24 -05:00
{
npc_tonk_mineAI(Creature *c) : ScriptedAI(c)
2008-11-21 19:27:24 -05:00
{
m_creature->SetReactState(REACT_PASSIVE);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
uint32 ExplosionTimer;
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void Reset()
{
ExplosionTimer = 3000;
}
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit *who) {}
2008-11-21 19:27:24 -05:00
void AttackStart(Unit *who) {}
void MoveInLineOfSight(Unit *who) {}
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
void UpdateAI(const uint32 diff)
{
2009-10-27 21:28:20 -07:00
if (ExplosionTimer <= diff)
2008-11-21 19:27:24 -05:00
{
DoCast(m_creature, SPELL_TONK_MINE_DETONATE, true);
2008-11-21 19:27:24 -05:00
m_creature->setDeathState(DEAD); // unsummon it
} else
ExplosionTimer -= diff;
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_tonk_mine(Creature* pCreature)
2008-11-21 19:27:24 -05:00
{
2009-08-14 00:39:07 +02:00
return new npc_tonk_mineAI(pCreature);
2008-11-21 19:27:24 -05:00
}
2009-10-17 15:51:44 -07:00
/*####
## npc_brewfest_reveler
####*/
2010-02-05 00:31:28 +01:00
struct npc_brewfest_revelerAI : public ScriptedAI
2009-12-17 22:08:57 +01:00
{
npc_brewfest_revelerAI(Creature* c) : ScriptedAI(c) {}
void ReceiveEmote(Player* pPlayer, uint32 emote)
{
if (!IsHolidayActive(HOLIDAY_BREWFEST))
return;
2010-01-02 02:22:47 -03:00
2009-12-17 22:08:57 +01:00
if (emote == TEXTEMOTE_DANCE)
m_creature->CastSpell(pPlayer, 41586, false);
}
};
CreatureAI* GetAI_npc_brewfest_reveler(Creature* pCreature)
{
return new npc_brewfest_revelerAI(pCreature);
}
/*####
## npc_winter_reveler
####*/
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_winter_revelerAI : public ScriptedAI
{
npc_winter_revelerAI(Creature* c) : ScriptedAI(c) {}
2009-12-17 22:08:57 +01:00
void ReceiveEmote(Player* pPlayer, uint32 emote)
{
if (!IsHolidayActive(HOLIDAY_FEAST_OF_WINTER_VEIL))
return;
//TODO: check auralist.
if (pPlayer->HasAura(26218))
return;
2009-12-17 22:08:57 +01:00
if (emote == TEXTEMOTE_KISS)
2009-02-09 08:16:34 -05:00
{
2009-12-17 22:08:57 +01:00
m_creature->CastSpell(m_creature, 26218, false);
pPlayer->CastSpell(pPlayer, 26218, false);
switch (urand(0,2))
{
case 0: m_creature->CastSpell(pPlayer, 26207, false); break;
case 1: m_creature->CastSpell(pPlayer, 26206, false); break;
case 2: m_creature->CastSpell(pPlayer, 45036, false); break;
}
2009-02-09 08:16:34 -05:00
}
}
};
2009-10-17 15:51:44 -07:00
2009-12-17 22:08:57 +01:00
CreatureAI* GetAI_npc_winter_reveler(Creature* pCreature)
{
return new npc_winter_revelerAI(pCreature);
}
2009-10-17 15:51:44 -07:00
/*####
## npc_snake_trap_serpents
####*/
2009-10-17 15:51:44 -07:00
#define SPELL_MIND_NUMBING_POISON 25810 //Viper
#define SPELL_DEADLY_POISON 34655 //Venomous Snake
2010-01-27 15:57:14 +01:00
#define SPELL_CRIPPLING_POISON 30981 //Viper
2009-10-17 15:51:44 -07:00
2010-01-13 18:24:23 +01:00
#define VENOMOUS_SNAKE_TIMER 1500
#define VIPER_TIMER 3000
2009-10-17 15:51:44 -07:00
#define C_VIPER 19921
2009-10-17 15:51:44 -07:00
#define RAND 5
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_snake_trap_serpentsAI : public ScriptedAI
{
npc_snake_trap_serpentsAI(Creature *c) : ScriptedAI(c) {}
2009-10-17 15:51:44 -07:00
uint32 SpellTimer;
bool IsViper;
2009-07-09 17:02:29 +02:00
bool Spawn;
2009-10-17 15:51:44 -07:00
2009-04-27 21:23:42 -05:00
void EnterCombat(Unit *who) {}
2009-10-17 15:51:44 -07:00
void Reset()
{
2009-07-09 17:02:29 +02:00
Spawn = true;
2009-08-05 22:24:30 -05:00
SpellTimer = 0;
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
CreatureInfo const *Info = m_creature->GetCreatureInfo();
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
if (Info->Entry == C_VIPER)
IsViper = true;
2009-08-05 22:24:30 -05:00
else
IsViper = false;
2009-10-17 15:51:44 -07:00
//Add delta to make them not all hit the same time
uint32 delta = (rand() % 7) * 100;
m_creature->SetStatFloatValue(UNIT_FIELD_BASEATTACKTIME, Info->baseattacktime + delta);
2010-01-21 18:38:49 -07:00
m_creature->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER , Info->attackpower);
2009-02-09 08:16:34 -05:00
}
2009-10-17 15:51:44 -07:00
2009-10-27 21:39:53 -07:00
//Redefined for random target selection:
void MoveInLineOfSight(Unit *who)
{
2009-08-14 00:02:13 +02:00
if (!m_creature->getVictim() && who->isTargetableForAttack() && (m_creature->IsHostileTo(who)) && who->isInAccessiblePlaceFor(m_creature))
{
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
2009-10-17 15:51:44 -07:00
float attackRadius = m_creature->GetAttackDistance(who);
2009-08-14 00:02:13 +02:00
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
{
2009-08-14 00:02:13 +02:00
if (!(rand() % RAND))
{
m_creature->setAttackTimer(BASE_ATTACK, (rand() % 10) * 100);
SpellTimer = (rand() % 10) * 100;
AttackStart(who);
2009-02-09 08:16:34 -05:00
}
}
}
}
2009-10-17 15:51:44 -07:00
void UpdateAI(const uint32 diff)
{
2009-08-14 00:02:13 +02:00
if (Spawn)
{
2009-07-09 17:02:29 +02:00
Spawn = false;
// Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
if (!m_creature->getVictim() && m_creature->isSummon())
2009-08-05 22:24:30 -05:00
if (Unit * Owner = CAST_SUM(m_creature)->GetSummoner())
2009-08-14 00:02:13 +02:00
if (Owner->getAttackerForHelper())
2009-07-09 17:02:29 +02:00
AttackStart(Owner->getAttackerForHelper());
}
2009-10-17 15:51:44 -07:00
if (!m_creature->getVictim())
{
2009-04-27 21:23:42 -05:00
if (m_creature->isInCombat())
2009-02-09 08:16:34 -05:00
DoStopAttack();
return;
}
2009-10-17 15:51:44 -07:00
2009-10-27 21:28:20 -07:00
if (SpellTimer <= diff)
{
2009-02-09 08:16:34 -05:00
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;
2009-10-17 15:51:44 -07:00
DoCast(m_creature->getVictim(), spell);
}
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
SpellTimer = VIPER_TIMER;
}
else //Venomous Snake
{
2010-01-13 18:24:23 +01:00
if (urand(0,2) == 0) //33% chance to cast
DoCast(m_creature->getVictim(), SPELL_DEADLY_POISON);
SpellTimer = VENOMOUS_SNAKE_TIMER + (rand() %5)*100;
}
} else SpellTimer -= diff;
2009-02-09 08:16:34 -05:00
DoMeleeAttackIfReady();
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_snake_trap_serpents(Creature* pCreature)
{
2009-08-14 00:39:07 +02:00
return new npc_snake_trap_serpentsAI(pCreature);
}
2009-10-17 15:51:44 -07:00
#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..."
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
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 = m_creature->GetOwner())
m_creature->GetMotionMaster()->MoveFollow(own,0,0);
}
void Aggro(Unit *who){}
void UpdateAI(const uint32 diff)
{
if (m_creature->HasAura(20372))
{
if (hearts <= diff)
{
m_creature->RemoveAurasDueToSpell(20372);
hearts = 15000;
} hearts -= diff;
}
}
2009-08-14 00:02:13 +02:00
void ReceiveEmote(Player* pPlayer, uint32 emote)
{
m_creature->HandleEmoteCommand(emote);
Unit* own = m_creature->GetOwner();
2009-08-14 00:02:13 +02:00
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);
2009-08-14 00:02:13 +02:00
whisp.append(pPlayer->GetName());
whisp.append(SAY_RANDOM_MOJO6b);
break;
case 7:whisp.append(SAY_RANDOM_MOJO7);break;
}
2009-08-14 00:02:13 +02:00
m_creature->MonsterWhisper(whisp.c_str(),pPlayer->GetGUID());
if (victimGUID)
{
Player* victim = Unit::GetPlayer(victimGUID);
2009-08-14 00:02:13 +02:00
if (victim)
victim->RemoveAura(43906);//remove polymorph frog thing
}
2009-08-14 00:02:13 +02:00
m_creature->AddAura(43906,pPlayer);//add polymorph frog thing
victimGUID = pPlayer->GetGUID();
DoCast(m_creature, 20372, true);//tag.hearts
2009-08-14 00:02:13 +02:00
m_creature->GetMotionMaster()->MoveFollow(pPlayer,0,0);
2009-08-04 12:38:35 +02:00
hearts = 15000;
}
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_mob_mojo(Creature* pCreature)
{
2009-08-14 00:39:07 +02:00
return new mob_mojoAI (pCreature);
}
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_mirror_image : CasterAI
{
2009-08-23 14:20:07 -05:00
npc_mirror_image(Creature *c) : CasterAI(c) {}
2009-10-17 15:51:44 -07:00
void InitializeAI()
{
2009-08-23 14:20:07 -05:00
CasterAI::InitializeAI();
2009-08-05 22:24:30 -05:00
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);
}
2009-10-17 15:51:44 -07:00
2009-08-15 00:32:04 +02:00
// Do not reload Creature templates on evade mode enter - prevent visual lost
2009-08-06 08:53:29 -05:00
void EnterEvadeMode()
{
2009-08-14 00:02:13 +02:00
if (me->IsInEvadeMode() || !me->isAlive())
2009-08-06 08:53:29 -05:00
return;
2009-10-17 15:51:44 -07:00
2009-08-06 08:53:29 -05:00
Unit *owner = me->GetCharmerOrOwner();
2009-10-17 15:51:44 -07:00
2009-08-06 08:53:29 -05:00
me->CombatStop(true);
2009-08-14 00:02:13 +02:00
if (owner && !me->hasUnitState(UNIT_STAT_FOLLOW))
2009-08-06 08:53:29 -05:00
{
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, m_creature->GetFollowAngle(), MOTION_SLOT_ACTIVE);
}
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_mirror_image(Creature* pCreature)
{
2009-08-14 00:39:07 +02:00
return new npc_mirror_image (pCreature);
}
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_ebon_gargoyleAI : CasterAI
{
2009-08-23 14:20:07 -05:00
npc_ebon_gargoyleAI(Creature *c) : CasterAI(c) {}
2009-10-17 15:51:44 -07:00
int despawnTimer;
2009-10-17 15:51:44 -07:00
void InitializeAI()
{
2009-08-23 14:20:07 -05:00
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(m_creature, m_creature, 30);
Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_creature, targets, u_check);
m_creature->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;
}
}
2009-10-17 15:51:44 -07:00
void JustDied(Unit *killer)
{
// Stop Feeding Gargoyle when it dies
if (Unit *owner = me->GetOwner())
owner->RemoveAurasDueToSpell(50514);
}
2009-10-17 15:51:44 -07:00
// Fly away when dismissed
void SpellHit(Unit *source, const SpellEntry *spell)
{
if(spell->Id != 50515 || !me->isAlive() )
return;
2009-10-17 15:51:44 -07:00
Unit *owner = me->GetOwner();
2009-10-17 15:51:44 -07:00
if (!owner || owner != source)
return;
2009-10-17 15:51:44 -07:00
// Stop Fighting
me->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, true);
// Sanctuary
me->CastSpell(m_creature, 54661, true);
me->SetReactState(REACT_PASSIVE);
2009-10-17 15:51:44 -07:00
// Fly Away
2010-01-13 11:27:41 +01:00
me->AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE|MOVEMENTFLAG_ASCEND|MOVEMENTFLAG_FLYING);
2010-01-13 18:25:46 +01:00
me->SetSpeed(MOVE_FLIGHT, 0.75f, true);
2010-01-13 11:27:41 +01:00
me->SetSpeed(MOVE_RUN, 0.75f, true);
2010-01-13 18:25:46 +01:00
float x = me->GetPositionX() + 20 * cos(me->GetOrientation());
float y = me->GetPositionY() + 20 * sin(me->GetOrientation());
2010-01-13 11:27:41 +01:00
float z = me->GetPositionZ() + 40;
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MovePoint(0, x, y, z);
2009-10-17 15:51:44 -07:00
// Despawn as soon as possible
despawnTimer = 4 * IN_MILISECONDS;
}
2009-10-17 15:51:44 -07:00
void UpdateAI(const uint32 diff)
{
if (despawnTimer > 0)
{
if (despawnTimer > diff)
despawnTimer -= diff;
else
{
me->ForcedDespawn();
}
return;
}
2009-08-23 14:20:07 -05:00
CasterAI::UpdateAI(diff);
}
};
2009-10-17 15:51:44 -07:00
CreatureAI* GetAI_npc_ebon_gargoyle(Creature* pCreature)
{
return new npc_ebon_gargoyleAI (pCreature);
}
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_lightwellAI : public PassiveAI
2009-08-10 15:52:11 -05:00
{
npc_lightwellAI(Creature *c) : PassiveAI(c) {}
2009-10-17 15:51:44 -07:00
2009-08-10 15:52:11 -05:00
void Reset()
{
DoCast(m_creature, 59907, false); // Spell for Lightwell Charges
2009-08-10 15:52:11 -05:00
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_lightwellAI(Creature* pCreature)
2009-08-10 15:52:11 -05:00
{
2009-08-14 00:39:07 +02:00
return new npc_lightwellAI (pCreature);
2009-08-10 15:52:11 -05:00
}
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_training_dummy : Scripted_NoMovementAI
2009-08-04 12:38:35 +02:00
{
npc_training_dummy(Creature *c) : Scripted_NoMovementAI(c)
{
m_Entry = c->GetEntry();
}
2009-10-17 15:51:44 -07:00
uint64 m_Entry;
2009-08-04 12:38:35 +02:00
uint32 ResetTimer;
uint32 DespawnTimer;
2009-08-04 12:38:35 +02:00
void Reset()
{
m_creature->SetControlled(true,UNIT_STAT_STUNNED);//disable rotate
m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);//imune to knock aways like blast wave
m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);
ResetTimer = 10000;
DespawnTimer = 15000;
2009-08-04 12:38:35 +02:00
}
2009-10-17 15:51:44 -07:00
2009-08-04 12:38:35 +02:00
void DamageTaken(Unit *done_by, uint32 &damage)
{
ResetTimer = 10000;
damage = 0;
}
2009-10-17 15:51:44 -07:00
void EnterCombat(Unit *who)
{
if (m_Entry != 2674 && m_Entry != 2673)
return;
}
2009-10-17 15:51:44 -07:00
2009-08-04 12:38:35 +02:00
void UpdateAI(const uint32 diff)
{
2009-08-14 00:02:13 +02:00
if (!UpdateVictim())
2009-08-04 12:38:35 +02:00
return;
2009-08-14 00:02:13 +02:00
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED))
2009-08-04 12:38:35 +02:00
m_creature->SetControlled(true,UNIT_STAT_STUNNED);//disable rotate
if (m_Entry != 2674 && m_Entry != 2673)
2009-08-04 12:38:35 +02:00
{
if (ResetTimer <= diff)
{
EnterEvadeMode();
ResetTimer = 10000;
}
else
ResetTimer -= diff;
return;
}
else
{
if (DespawnTimer <= diff)
m_creature->ForcedDespawn();
else
DespawnTimer -= diff;
}
2009-08-04 12:38:35 +02:00
}
void MoveInLineOfSight(Unit *who){return;}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI* GetAI_npc_training_dummy(Creature* pCreature)
2009-08-04 12:38:35 +02:00
{
2009-08-14 00:39:07 +02:00
return new npc_training_dummy (pCreature);
2009-08-04 12:38:35 +02:00
}
2009-10-17 15:51:44 -07:00
2010-01-01 07:06:47 +01:00
/*######
# npc_shadowfiend
######*/
#define GLYPH_OF_SHADOWFIEND_MANA 58227
#define GLYPH_OF_SHADOWFIEND 58228
2010-02-05 00:31:28 +01:00
struct npc_shadowfiendAI : public ScriptedAI
2010-01-01 07:06:47 +01:00
{
2010-01-02 02:22:47 -03:00
npc_shadowfiendAI(Creature* pCreature) : ScriptedAI(pCreature) {}
2010-01-01 07:06:47 +01:00
2010-01-02 02:22:47 -03:00
void DamageTaken(Unit* pKiller, uint32 &damage)
2010-01-01 07:06:47 +01:00
{
2010-01-02 02:22:47 -03:00
if (m_creature->isSummon())
if (Unit* pOwner = CAST_SUM(m_creature)->GetSummoner())
{
if (pOwner->HasAura(GLYPH_OF_SHADOWFIEND))
if (damage >= m_creature->GetHealth())
pOwner->CastSpell(pOwner,GLYPH_OF_SHADOWFIEND_MANA,true);
}
2010-01-01 07:06:47 +01:00
}
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;
}
2008-11-21 19:27:24 -05:00
void AddSC_npcs_special()
{
Script *newscript;
2009-10-17 15:51:44 -07:00
2009-06-19 00:22:19 +02:00
newscript = new Script;
newscript->Name = "npc_air_force_bots";
newscript->GetAI = &GetAI_npc_air_force_bots;
newscript->RegisterSelf();
2010-01-02 02:22:47 -03:00
newscript = new Script;
newscript->Name = "npc_lunaclaw_spirit";
newscript->pGossipHello = &GossipHello_npc_lunaclaw_spirit;
newscript->pGossipSelect = &GossipSelect_npc_lunaclaw_spirit;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_chicken_cluck";
newscript->GetAI = &GetAI_npc_chicken_cluck;
2008-11-21 19:27:24 -05:00
newscript->pQuestAccept = &QuestAccept_npc_chicken_cluck;
newscript->pQuestComplete = &QuestComplete_npc_chicken_cluck;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_dancing_flames";
2009-02-09 08:16:34 -05:00
newscript->GetAI = &GetAI_npc_dancing_flames;
2008-11-21 19:27:24 -05:00
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_injured_patient";
newscript->GetAI = &GetAI_npc_injured_patient;
2008-11-21 19:27:24 -05:00
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_doctor";
newscript->GetAI = &GetAI_npc_doctor;
2008-11-21 19:27:24 -05:00
newscript->pQuestAccept = &QuestAccept_npc_doctor;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
newscript = new Script;
newscript->Name = "npc_garments_of_quests";
newscript->GetAI = &GetAI_npc_garments_of_quests;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_guardian";
newscript->GetAI = &GetAI_npc_guardian;
2008-11-21 19:27:24 -05:00
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
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();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_mount_vendor";
2008-11-21 19:27:24 -05:00
newscript->pGossipHello = &GossipHello_npc_mount_vendor;
newscript->pGossipSelect = &GossipSelect_npc_mount_vendor;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_rogue_trainer";
2008-11-21 19:27:24 -05:00
newscript->pGossipHello = &GossipHello_npc_rogue_trainer;
newscript->pGossipSelect = &GossipSelect_npc_rogue_trainer;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_sayge";
2008-11-21 19:27:24 -05:00
newscript->pGossipHello = &GossipHello_npc_sayge;
newscript->pGossipSelect = &GossipSelect_npc_sayge;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_steam_tonk";
2008-11-21 19:27:24 -05:00
newscript->GetAI = &GetAI_npc_steam_tonk;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2008-11-21 19:27:24 -05:00
newscript = new Script;
newscript->Name = "npc_tonk_mine";
2008-11-21 19:27:24 -05:00
newscript->GetAI = &GetAI_npc_tonk_mine;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
newscript = new Script;
newscript->Name = "npc_winter_reveler";
newscript->GetAI = &GetAI_npc_winter_reveler;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
newscript = new Script;
newscript->Name = "npc_brewfest_reveler";
newscript->GetAI = &GetAI_npc_winter_reveler;
2008-11-21 19:27:24 -05:00
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
newscript = new Script;
newscript->Name = "npc_snake_trap_serpents";
newscript->GetAI = &GetAI_npc_snake_trap_serpents;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2009-08-10 15:52:11 -05:00
newscript = new Script;
newscript->Name = "npc_mirror_image";
newscript->GetAI = &GetAI_npc_mirror_image;
2009-08-10 15:52:11 -05:00
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
newscript = new Script;
newscript->Name = "npc_ebon_gargoyle";
newscript->GetAI = &GetAI_npc_ebon_gargoyle;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
newscript = new Script;
newscript->Name = "npc_lightwell";
newscript->GetAI = &GetAI_npc_lightwellAI;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
newscript = new Script;
newscript->Name = "mob_mojo";
newscript->GetAI = &GetAI_mob_mojo;
newscript->RegisterSelf();
2009-10-17 15:51:44 -07:00
2009-08-04 12:38:35 +02:00
newscript = new Script;
newscript->Name = "npc_training_dummy";
2009-08-04 12:38:35 +02:00
newscript->GetAI = &GetAI_npc_training_dummy;
newscript->RegisterSelf();
2010-01-01 07:06:47 +01:00
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();
2008-11-21 19:27:24 -05:00
}
2009-02-17 20:07:49 -06:00