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
2009-11-17 16:03:13 -08:00
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
2009-11-17 16:03:13 -08:00
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)
2009-04-15 21:40:09 +02:00
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
2009-11-17 16:03:13 -08:00
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
2009-11-17 16:03:13 -08:00
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"
2010-02-05 13:01:32 +01:00
#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
2009-10-18 16:07:41 -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
2009-11-17 16:03:13 -08: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
2009-06-17 03:05:40 +02: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
2009-06-17 03:05:40 +02:00
#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
{
2009-03-31 18:12:49 -06: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
{
2009-06-17 03:05:40 +02: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
{
2009-06-17 03:05:40 +02: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
}
2009-06-17 03:05:40 +02:00
break ;
case TEXTEMOTE_CHEER :
2009-08-14 00:02:13 +02:00
if ( pPlayer -> GetQuestStatus ( QUEST_CLUCK ) == QUEST_STATUS_COMPLETE )
2009-06-17 03:05:40 +02:00
{
m_creature -> SetFlag ( UNIT_NPC_FLAGS , UNIT_NPC_FLAG_QUESTGIVER );
m_creature -> setFaction ( FACTION_FRIENDLY );
DoScriptText ( EMOTE_CLUCK_TEXT , m_creature );
}
break ;
2009-04-15 19:12:22 -05:00
}
2008-11-21 19:27:24 -05:00
}
2009-04-15 19:12:22 -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-04-15 19:12:22 -05:00
{
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
{
2009-03-31 18:12:49 -06: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
2009-01-17 20:09:33 +01:00
void Reset ()
2009-02-09 08:16:34 -05:00
{
active = true ;
can_iteract = 3500 ;
2009-11-11 13:47:21 -08:00
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
2009-01-17 20:09:33 +01: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 );
2009-04-15 19:12:22 -05:00
active = false ;
2009-10-17 15:51:44 -07:00
2009-04-15 19:12:22 -05:00
WorldPacket data ;
m_creature -> BuildHeartBeatMsg ( & data );
m_creature -> SendMessageToSet ( & data , true );
switch ( emote )
2009-02-09 08:16:34 -05:00
{
2009-04-15 19:12:22 -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 ))
2009-11-11 13:47:21 -08:00
DoCast ( pPlayer , SPELL_SEDUCTION , true );
2009-04-15 19:12:22 -05:00
}
break ;
2009-02-09 08:16:34 -05:00
}
}
}
2009-04-15 19:12:22 -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-04-15 19:12:22 -05:00
{
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
2009-09-10 16:25:19 +02: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
{
2009-03-31 18:12:49 -06: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
2009-10-17 06:26:32 -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 >:: 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
2009-06-16 00:55:22 +02: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
2009-09-10 16:25:19 +02: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 ,
2009-09-10 16:25:19 +02:00
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
{
2009-03-31 18:12:49 -06: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 ())
{
2009-11-11 13:47:21 -08:00
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
2009-04-15 21:40:09 +02:00
/*######
## npc_kingdom_of_dalaran_quests
######*/
2009-10-17 15:51:44 -07:00
2009-10-17 07:42:48 -07:00
enum eKingdomDalaran
2009-04-15 21:40:09 +02:00
{
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
2009-04-15 21:40:09 +02:00
#define GOSSIP_ITEM_TELEPORT_TO "I am ready to be teleported to Dalaran."
2009-10-17 15:51:44 -07:00
2009-04-15 21:40:09 +02: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
2009-04-15 21:40:09 +02: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
2009-12-20 13:35:08 +02:00
pPlayer -> SEND_GOSSIP_MENU ( pPlayer -> GetGossipTextId ( pCreature ), pCreature -> GetGUID ());
2009-04-15 21:40:09 +02:00
return true ;
}
2009-10-17 15:51:44 -07:00
2009-04-15 21:40:09 +02: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 );
2009-12-20 13:35:08 +02:00
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
2009-08-23 03:48:18 -04:00
#define GOSSIP_HELLO_ROGUE1 "I wish to unlearn my talents"
#define GOSSIP_HELLO_ROGUE2 "<Take the letter>"
2009-11-02 04:42:31 +01:00
#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 ))
2009-08-23 03:48:18 -04:00
pPlayer -> ADD_GOSSIP_ITEM ( GOSSIP_ICON_TRAINER , GOSSIP_HELLO_ROGUE1 , GOSSIP_SENDER_MAIN , GOSSIP_OPTION_UNLEARNTALENTS );
2009-10-17 15:51:44 -07:00
2010-02-05 13:01:32 +01:00
if ( ! ( pPlayer -> GetSpecsCount () == 1 && pCreature -> isCanTrainingAndResetTalentsOf ( pPlayer ) && ! ( pPlayer -> getLevel () < sWorld . getConfig ( CONFIG_MIN_DUALSPEC_LEVEL ))))
2009-11-02 04:42:31 +01:00
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
{
2009-08-23 03:48:18 -04: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
2009-12-20 13:35:08 +02:00
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 ;
2009-11-02 04:42:31 +01:00
case GOSSIP_OPTION_LEARNDUALSPEC :
2010-02-05 13:01:32 +01:00
if ( pPlayer -> GetSpecsCount () == 1 && ! ( pPlayer -> getLevel () < sWorld . getConfig ( CONFIG_MIN_DUALSPEC_LEVEL )))
2009-11-02 04:42:31 +01:00
{
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
2009-08-23 03:48:18 -04: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
{
2009-08-23 03:48:18 -04:00
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 :
2009-08-23 03:48:18 -04:00
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 :
2009-08-23 03:48:18 -04:00
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 :
2009-08-23 03:48:18 -04:00
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 :
2009-08-23 03:48:18 -04:00
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 :
2009-08-23 03:48:18 -04:00
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 :
2009-08-23 03:48:18 -04:00
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
{
2009-03-31 18:12:49 -06: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
2008-12-07 09:21:12 -06:00
m_creature -> SetReactState ( REACT_PASSIVE );
2008-11-21 19:27:24 -05:00
}
else
2008-12-07 09:21:12 -06:00
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
2009-02-04 10:33:18 -06: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
{
2009-02-04 10:33:18 -06:00
npc_tonk_mineAI ( Creature * c ) : ScriptedAI ( c )
2008-11-21 19:27:24 -05:00
{
2008-12-07 09:21:12 -06: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
{
2009-11-11 13:47:21 -08: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
2009-12-16 21:10:26 -06: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 );
2009-12-16 21:10:26 -06:00
}
2008-12-13 15:39:55 +01:00
/*####
## 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
2008-12-13 15:39:55 +01:00
{
2009-12-16 21:10:26 -06:00
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 ))
2009-12-16 21:10:26 -06:00
return ;
2009-12-17 22:08:57 +01:00
2009-12-16 21:10:26 -06: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-12-16 21:10:26 -06:00
}
2009-02-09 08:16:34 -05:00
}
}
2009-12-16 21:10:26 -06: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 );
2008-12-13 15:39:55 +01:00
}
2009-10-17 15:51:44 -07:00
2009-12-16 21:10:26 -06:00
2009-01-21 14:40:17 +01:00
/*####
## npc_snake_trap_serpents
####*/
2009-10-17 15:51:44 -07:00
2009-12-26 19:37:25 -06:00
#define SPELL_MIND_NUMBING_POISON 25810 //Viper
2009-01-21 14:40:17 +01:00
#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
2009-01-21 14:40:17 +01:00
#define VIPER_TIMER 3000
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01:00
#define C_VIPER 19921
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01: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
2009-01-21 14:40:17 +01:00
{
2009-03-31 18:12:49 -06:00
npc_snake_trap_serpentsAI ( Creature * c ) : ScriptedAI ( c ) {}
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01: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
2009-01-21 14:40:17 +01: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 )
2009-01-21 14:40:17 +01:00
IsViper = true ;
2009-08-05 22:24:30 -05:00
else
IsViper = false ;
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01:00
//Add delta to make them not all hit the same time
2010-01-10 22:02:03 +01:00
uint32 delta = ( rand () % 7 ) * 100 ;
2009-01-21 14:40:17 +01:00
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:
2009-01-21 14:40:17 +01:00
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 ))
2009-01-21 14:40:17 +01:00
{
if ( m_creature -> GetDistanceZ ( who ) > CREATURE_Z_ATTACK_RANGE )
return ;
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01: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-02-04 10:33:18 -06:00
{
2009-08-14 00:02:13 +02:00
if ( ! ( rand () % RAND ))
2009-02-04 10:33:18 -06:00
{
m_creature -> setAttackTimer ( BASE_ATTACK , ( rand () % 10 ) * 100 );
2009-01-21 14:40:17 +01:00
SpellTimer = ( rand () % 10 ) * 100 ;
AttackStart ( who );
2009-02-09 08:16:34 -05:00
}
}
}
}
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01:00
void UpdateAI ( const uint32 diff )
{
2009-08-14 00:02:13 +02:00
if ( Spawn )
2009-01-21 14:40:17 +01:00
{
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-01-21 14:40:17 +01:00
}
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01: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 ();
2009-01-21 14:40:17 +01:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-10-27 21:28:20 -07:00
if ( SpellTimer <= diff )
2009-01-21 14:40:17 +01:00
{
2009-02-09 08:16:34 -05:00
if ( IsViper ) //Viper
2009-01-21 14:40:17 +01:00
{
2009-11-17 16:03:13 -08:00
if ( urand ( 0 , 2 ) == 0 ) //33% chance to cast
2009-01-21 14:40:17 +01:00
{
2009-02-04 10:33:18 -06:00
uint32 spell ;
2009-11-17 16:03:13 -08:00
if ( urand ( 0 , 1 ) == 0 )
2009-01-21 14:40:17 +01:00
spell = SPELL_MIND_NUMBING_POISON ;
else
spell = SPELL_CRIPPLING_POISON ;
2009-10-17 15:51:44 -07:00
2009-11-11 13:47:21 -08:00
DoCast ( m_creature -> getVictim (), spell );
2009-01-21 14:40:17 +01:00
}
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
SpellTimer = VIPER_TIMER ;
2009-01-21 14:40:17 +01:00
}
else //Venomous Snake
{
2010-01-13 18:24:23 +01:00
if ( urand ( 0 , 2 ) == 0 ) //33% chance to cast
2009-11-11 13:47:21 -08:00
DoCast ( m_creature -> getVictim (), SPELL_DEADLY_POISON );
2009-01-21 14:40:17 +01:00
SpellTimer = VENOMOUS_SNAKE_TIMER + ( rand () % 5 ) * 100 ;
}
2009-11-17 16:03:13 -08:00
} else SpellTimer -= diff ;
2009-02-09 08:16:34 -05:00
DoMeleeAttackIfReady ();
2009-01-21 14:40:17 +01:00
}
};
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-01-21 14:40:17 +01:00
{
2009-08-14 00:39:07 +02:00
return new npc_snake_trap_serpentsAI ( pCreature );
2009-01-21 14:40:17 +01:00
}
2009-10-17 15:51:44 -07:00
2009-08-23 03:48:18 -04: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
2009-08-23 01:42:57 +02:00
{
2009-07-18 18:18:33 +02:00
mob_mojoAI ( Creature * c ) : ScriptedAI ( c ) { Reset ();}
uint32 hearts ;
uint64 victimGUID ;
void Reset ()
{
victimGUID = 0 ;
hearts = 15000 ;
2009-11-17 16:03:13 -08:00
if ( Unit * own = m_creature -> GetOwner ())
2009-07-18 18:18:33 +02:00
m_creature -> GetMotionMaster () -> MoveFollow ( own , 0 , 0 );
}
void Aggro ( Unit * who ){}
void UpdateAI ( const uint32 diff )
{
2009-11-17 16:03:13 -08:00
if ( m_creature -> HasAura ( 20372 ))
2009-07-18 18:18:33 +02:00
{
2009-11-17 16:03:13 -08:00
if ( hearts <= diff )
2009-07-18 18:18:33 +02:00
{
m_creature -> RemoveAurasDueToSpell ( 20372 );
hearts = 15000 ;
2009-11-17 16:03:13 -08:00
} hearts -= diff ;
2009-07-18 18:18:33 +02:00
}
}
2009-08-14 00:02:13 +02:00
void ReceiveEmote ( Player * pPlayer , uint32 emote )
2009-07-18 18:18:33 +02:00
{
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 ())
2009-07-18 18:18:33 +02:00
return ;
if ( emote == TEXTEMOTE_KISS )
{
std :: string whisp = "" ;
switch ( rand () % 8 )
{
2009-08-23 03:48:18 -04:00
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 ;
2009-07-18 18:18:33 +02:00
case 6 :
2009-08-23 03:48:18 -04:00
whisp . append ( SAY_RANDOM_MOJO6a );
2009-08-14 00:02:13 +02:00
whisp . append ( pPlayer -> GetName ());
2009-08-23 03:48:18 -04:00
whisp . append ( SAY_RANDOM_MOJO6b );
2009-07-18 18:18:33 +02:00
break ;
2009-08-23 03:48:18 -04:00
case 7 : whisp . append ( SAY_RANDOM_MOJO7 ); break ;
2009-07-18 18:18:33 +02:00
}
2009-08-14 00:02:13 +02:00
m_creature -> MonsterWhisper ( whisp . c_str (), pPlayer -> GetGUID ());
if ( victimGUID )
2009-07-18 18:18:33 +02:00
{
Player * victim = Unit :: GetPlayer ( victimGUID );
2009-08-14 00:02:13 +02:00
if ( victim )
2009-07-18 18:18:33 +02:00
victim -> RemoveAura ( 43906 ); //remove polymorph frog thing
}
2009-08-14 00:02:13 +02:00
m_creature -> AddAura ( 43906 , pPlayer ); //add polymorph frog thing
2009-08-23 01:42:57 +02:00
victimGUID = pPlayer -> GetGUID ();
2009-11-11 13:47:21 -08:00
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-08-23 01:42:57 +02:00
}
2009-07-18 18:18:33 +02:00
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI * GetAI_mob_mojo ( Creature * pCreature )
2009-07-18 18:18:33 +02:00
{
2009-08-14 00:39:07 +02:00
return new mob_mojoAI ( pCreature );
2009-07-18 18:18:33 +02:00
}
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_mirror_image : CasterAI
2009-07-22 17:10:30 +02:00
{
2009-08-23 14:20:07 -05:00
npc_mirror_image ( Creature * c ) : CasterAI ( c ) {}
2009-10-17 15:51:44 -07:00
2009-08-06 23:10:36 +02:00
void InitializeAI ()
2009-07-22 17:10:30 +02:00
{
2009-08-23 14:20:07 -05:00
CasterAI :: InitializeAI ();
2009-08-05 22:24:30 -05:00
Unit * owner = me -> GetOwner ();
2009-07-22 17:10:30 +02:00
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-07-22 17:10:30 +02:00
};
2009-10-17 15:51:44 -07:00
2009-08-14 00:39:07 +02:00
CreatureAI * GetAI_npc_mirror_image ( Creature * pCreature )
2009-07-22 17:10:30 +02:00
{
2009-08-14 00:39:07 +02:00
return new npc_mirror_image ( pCreature );
2009-07-22 17:10:30 +02:00
}
2009-10-17 15:51:44 -07:00
2010-02-05 00:31:28 +01:00
struct npc_ebon_gargoyleAI : CasterAI
2009-08-14 15:30:47 +02:00
{
2009-08-23 14:20:07 -05:00
npc_ebon_gargoyleAI ( Creature * c ) : CasterAI ( c ) {}
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02:00
int despawnTimer ;
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02:00
void InitializeAI ()
{
2009-08-23 14:20:07 -05:00
CasterAI :: InitializeAI ();
2009-08-14 15:30:47 +02:00
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 );
2009-10-17 16:20:24 -07:00
for ( std :: list < Unit *>:: iterator iter = targets . begin (); iter != targets . end (); ++ iter )
2009-08-14 15:30:47 +02:00
if (( * iter ) -> GetAura ( 49206 , owner -> GetGUID ()))
{
me -> Attack (( * iter ), false );
break ;
}
}
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02: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
2009-08-14 15:30:47 +02: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
2009-08-14 15:30:47 +02:00
Unit * owner = me -> GetOwner ();
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02:00
if ( ! owner || owner != source )
return ;
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02: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
2009-08-14 15:30:47 +02: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 );
2009-08-14 15:30:47 +02:00
me -> GetMotionMaster () -> MovePoint ( 0 , x , y , z );
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02:00
// Despawn as soon as possible
despawnTimer = 4 * IN_MILISECONDS ;
}
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02: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-08-14 15:30:47 +02:00
}
};
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02: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 ()
{
2009-11-11 13:47:21 -08:00
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
{
2009-11-02 07:37:13 +01:00
npc_training_dummy ( Creature * c ) : Scripted_NoMovementAI ( c )
{
m_Entry = c -> GetEntry ();
}
2009-10-17 15:51:44 -07:00
2009-11-02 07:37:13 +01:00
uint64 m_Entry ;
2009-08-04 12:38:35 +02:00
uint32 ResetTimer ;
2009-11-02 07:37:13 +01:00
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 ;
2009-11-02 07:37:13 +01:00
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
2009-11-02 07:37:13 +01: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
2009-11-02 07:37:13 +01:00
if ( m_Entry != 2674 && m_Entry != 2673 )
2009-08-04 12:38:35 +02:00
{
2009-11-02 07:37:13 +01: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 );
}
2010-01-31 22:02:15 -03:00
/*######
# 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 ())
2010-02-01 01:59:46 -03:00
{
2010-01-31 22:02:15 -03:00
if ( pPlayer == CAST_SUM ( pCreature ) -> GetSummoner ())
2010-02-01 01:59:46 -03:00
{
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 );
2010-01-31 22:02:15 -03:00
pPlayer -> PlayerTalkClass -> SendGossipMenu ( TEXT_WORMHOLE , pCreature -> GetGUID ());
2010-02-01 01:59:46 -03:00
}
}
2010-01-31 22:02:15 -03:00
return true ;
}
bool GossipSelect_npc_wormhole ( Player * pPlayer , Creature * pCreature , uint32 uiSender , uint32 uiAction )
{
bool roll = urand ( 0 , 1 );
switch ( uiAction )
2010-02-01 01:59:46 -03:00
{
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
2010-01-31 22:02:15 -03:00
pPlayer -> TeleportTo ( 571 , 4305.505859 , 5450.839844 , 63.005806 , 0.627286 );
2010-02-01 01:59:46 -03:00
else
2010-01-31 22:02:15 -03:00
pPlayer -> TeleportTo ( 571 , 3201.936279 , 5630.123535 , 133.658798 , 3.855272 );
2010-02-01 01:59:46 -03:00
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 ;
}
2010-01-31 22:02:15 -03:00
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
2009-11-17 16:03:13 -08: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 ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_chicken_cluck" ;
2008-12-22 23:11:25 +01:00
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 ;
2009-10-17 04:23:24 -07:00
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 ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_injured_patient" ;
2008-12-22 23:11:25 +01:00
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 ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_doctor" ;
2008-12-22 23:11:25 +01:00
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 ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_guardian" ;
2008-12-22 23:11:25 +01:00
newscript -> GetAI = & GetAI_npc_guardian ;
2008-11-21 19:27:24 -05:00
newscript -> RegisterSelf ();
2009-10-17 15:51:44 -07:00
2009-04-15 21:40:09 +02:00
newscript = new Script ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_kingdom_of_dalaran_quests" ;
2009-04-15 21:40:09 +02:00
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 ;
2009-10-17 04:23:24 -07:00
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 ;
2009-10-17 04:23:24 -07:00
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 ;
2009-10-17 04:23:24 -07:00
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 ;
2009-10-17 04:23:24 -07:00
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 ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_tonk_mine" ;
2008-11-21 19:27:24 -05:00
newscript -> GetAI = & GetAI_npc_tonk_mine ;
2008-12-13 15:39:55 +01:00
newscript -> RegisterSelf ();
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
newscript = new Script ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_winter_reveler" ;
2009-12-16 21:10:26 -06:00
newscript -> GetAI = & GetAI_npc_winter_reveler ;
2008-12-13 15:39:55 +01:00
newscript -> RegisterSelf ();
2009-10-17 15:51:44 -07:00
2009-02-09 08:16:34 -05:00
newscript = new Script ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_brewfest_reveler" ;
2009-12-16 21:10:26 -06:00
newscript -> GetAI = & GetAI_npc_winter_reveler ;
2008-11-21 19:27:24 -05:00
newscript -> RegisterSelf ();
2009-10-17 15:51:44 -07:00
2009-01-21 14:40:17 +01:00
newscript = new Script ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_snake_trap_serpents" ;
2009-01-21 14:40:17 +01:00
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 ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_mirror_image" ;
2009-08-14 15:30:47 +02:00
newscript -> GetAI = & GetAI_npc_mirror_image ;
2009-08-10 15:52:11 -05:00
newscript -> RegisterSelf ();
2009-10-17 15:51:44 -07:00
2009-07-22 17:10:30 +02:00
newscript = new Script ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_ebon_gargoyle" ;
2009-08-14 15:30:47 +02:00
newscript -> GetAI = & GetAI_npc_ebon_gargoyle ;
newscript -> RegisterSelf ();
2009-10-17 15:51:44 -07:00
2009-08-14 15:30:47 +02:00
newscript = new Script ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "npc_lightwell" ;
2009-08-14 15:30:47 +02:00
newscript -> GetAI = & GetAI_npc_lightwellAI ;
2009-07-22 17:10:30 +02:00
newscript -> RegisterSelf ();
2009-10-17 15:51:44 -07:00
2009-07-18 18:18:33 +02:00
newscript = new Script ;
2009-10-17 04:23:24 -07:00
newscript -> Name = "mob_mojo" ;
2009-07-18 18:18:33 +02:00
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 ;
2009-10-17 04:23:24 -07:00
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 ();
2010-01-31 22:02:15 -03:00
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