rendered paste body/* Copyright (C) 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../../sc_defines.h"
#include "../../../../../shared/WorldPacket.h"
#define SAY_READY "Splendid, I'm going to get the audience ready. Break a leg!"
#define SAY_OZ_INTRO1 "Finally, everything is in place. Are you ready for your big stage debut?"
#define OZ_GOSSIP1 "I'm not an actor."
#define SAY_OZ_INTRO2 "Don't worry, you'll be fine. You look like a natural!"
#define OZ_GOSSIP2 "Ok, I'll give it a try, then."
#define SAY_RAJ_INTRO1 "The romantic plays are really tough, but you'll do better this time. You have TALENT. Ready?"
#define RAJ_GOSSIP1 "I've never been more ready."
// I made this one up for Big Bad Wolf event, as I do not know what it is on official
#define SAY_HOOD_INTRO1 "Whoa! Scared me for a second there, I thought you were someone else"
#define HOOD_GOSSIP1 "I get that a lot."
#define SOUND_OZ1 9174
#define SAY_OZ1 "Welcome Ladies and Gentlemen, to this evening's presentation!"
#define SOUND_OZ2 9338
#define SAY_OZ2 "Tonight we plumb the depths of the human soul as we join a lost, lonely girl trying desperately -- with the help of her loyal companions -- to find her way home!"
#define SOUND_OZ3 9339
#define SAY_OZ3 "But she is pursued ... by a wicked malevolent crone!"
#define SOUND_OZ4 9340
#define SAY_OZ4 "Will she survive? Will she prevail? Only time will tell. And now ... on with the show!"
#define SOUND_HOOD1 9175
#define SAY_HOOD1 "Good evening, Ladies and Gentlemen! Welcome to this evening's presentation!"
#define SOUND_HOOD2 9335
#define SAY_HOOD2 "Tonight, things are not what they seem. For tonight, your eyes may not be trusted."
#define SOUND_HOOD3 9336
#define SAY_HOOD3 "Take for instance, this quiet, elderly woman, waiting for a visit from her granddaughter. Surely there is nothing to fear from this sweet, grey-haired, old lady."
#define SOUND_HOOD4 9337
#define SAY_HOOD4 "But don't let me pull the wool over your eyes. See for yourself what lies beneath those covers! And now...on with the show!"
#define SOUND_RAJ1 9176
#define SAY_RAJ1 "Welcome, Ladies and Gentlemen, to this evening's presentation!"
#define SOUND_RAJ2 9341
#define SAY_RAJ2 "Tonight, we explore a tale of forbidden love!"
#define SOUND_RAJ3 9342
#define SAY_RAJ3 "But beware, for not all love stories end happily, as you may find out. Sometimes, love pricks like a thorn."
#define SOUND_RAJ4 9343
#define SAY_RAJ4 "But don't take it from me, see for yourself what tragedy lies ahead as the paths of star-crossed lovers meet. And now...on with the show!"
#define SAY_JUL_RES_ROMEO "Come, gentle night; and give me back my Romulo!"
#define SPELL_ETERNALAFF 30878
#define EVENT_HOOD 1
#define EVENT_OZ 2
#define EVENT_RAJ 3
#define POS_Z 90.5
#define POS_OR 4.5
#define WOLF_X -10892
#define WOLF_Y -1758
#define OZ_Y -1750
#define ROAR_X -10891
#define DOR_X -10896
#define TIN_X -10884
#define STRAW_X -10902
#define CRONE_X -10890
#define CRONE_Y -1747
#define JUL_X -10892
#define JUL_Y -1758
#define B_X1 -10868
#define B_Y1 -1781
#define B_O1 1.56
#define B_X2 -10867.9
#define B_Y2 -1779.7
#define B_O2 3.13
#define B_X3 -10890.9
#define B_Y3 -1777.9
#define B_O3 3.00
#define B_X4 -10891.1
#define B_Y4 -1781.4
#define B_O4 4.68
#define SPELL_SPOTLIGHT 25824
#define SPELL_ROOTSELF 31366
struct MANGOS_DLL_DECL npc_barnesAI : public ScriptedAI
{
npc_barnesAI(Creature *barnes) : ScriptedAI(barnes) {EnterEvadeMode();}
uint32 Event;
uint32 DeathCount;
uint32 SpeechTimer;
uint32 SpeechNum;
uint32 WalkTimer;
uint32 WalkPos;
uint32 ResurrectTimer; // RAJ only
uint32 HealTimer; // RAJ only
bool SpeechOz;
bool SpeechHood;
bool SpeechRAJ;
bool StageWalk;
bool SpawnWalk;
bool HasSummoned;
bool HasSummonedCrone; // OZ only
bool HasSummonedRomulo; // RAJ only
bool InCombat;
Unit* Holder;
Creature* Performer;
Creature* Wolf;
Creature* Dorothee;
Creature* Tinhead;
Creature* Strawman;
Creature* Roar;
Creature* Crone;
Creature* Romulo;
Creature* Julianne;
void EnterEvadeMode()
{
Event = 0;
DeathCount = 0;
SpeechTimer = NULL;
SpeechNum = 0;
WalkTimer = NULL;
WalkPos = 0;
HealTimer = 20000; // RAJ only
ResurrectTimer = 10000; // RAJ only
SpeechOz = false;
SpeechHood = false;
SpeechRAJ = false;
StageWalk = false;
SpawnWalk = false;
HasSummoned = false;
HasSummonedCrone = false;
HasSummonedRomulo = false;
InCombat = false;
Holder = NULL;
Performer = NULL;
Wolf = NULL;
Dorothee = NULL;
Tinhead = NULL;
Strawman = NULL;
Roar = NULL;
Crone = NULL;
Romulo = NULL;
Julianne = NULL;
Yell("Resetting");
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
DoGoHome();
}
void AttackStart(Unit *who)
{
if (!who)
return;
if (who->isTargetableForAttack() && who!= m_creature)
{
//Begin melee attack if we are within range
DoStartMeleeAttack(who);
}
}
void JustDied(Unit *killer)
{
DoTextEmote("is dead", NULL);
}
void WalkToStage(Player* player, uint32 EventID)
{
Holder = ((Unit*)player);
WalkTimer = 0;
WalkPos = 1;
StageWalk = true;
Event = EventID;
}
void BeginSpeechOz()
{
//7 seconds
DoYell(SAY_OZ1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_OZ1);
SpeechTimer = 7000;
SpeechNum = 1;
SpeechOz = true;
}
void BeginSpeechHood()
{
//10 seconds
DoYell(SAY_HOOD1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_HOOD1);
SpeechTimer = 10000;
SpeechNum = 1;
SpeechHood = true;
}
void BeginSpeechRAJ()
{
//10 seconds
DoYell(SAY_RAJ1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_RAJ1);
SpeechTimer = 10000;
SpeechNum = 1;
SpeechRAJ = true;
}
void BeginEventHood()
{
if(!HasSummoned)
{
Yell("Summoning Big Bad Wolf");
Wolf = m_creature->SummonCreature(17521, WOLF_X, WOLF_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
HasSummoned = true;
}
}
void BeginEventOz()
{
if(!HasSummoned)
{
Yell("Summoning Dorothee, Tinhead, Strawman and Roar");
Dorothee = m_creature->SummonCreature(17535, DOR_X, OZ_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
Tinhead = m_creature->SummonCreature(17547, TIN_X, OZ_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
Strawman = m_creature->SummonCreature(17543, STRAW_X, OZ_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
Roar = m_creature->SummonCreature(17546, ROAR_X, OZ_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
HasSummoned = true;
}
}
void BeginEventRAJ()
{
if(!HasSummoned)
{
Yell("Summoning Julianne");
Julianne = m_creature->SummonCreature(17534, JUL_X, JUL_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
HasSummoned = true;
}
}
void UpdateAI(const uint32 diff)
{
if(StageWalk)
{
if(WalkTimer < diff)
{
DoTextEmote("is walking", NULL);
switch(WalkPos)
{
case 0:
Yell("Case 0");
SpecialMove(B_X1, B_Y1, POS_Z, 5000);
m_creature->Relocate(B_X1, B_Y1, POS_Z, B_O1);
Yell("Move complete");
if(SpawnWalk)
{
Yell("Rooting self");
Performer = m_creature->SummonCreature(16473, B_X4, B_Y4, 80, 5, TEMPSUMMON_TIMED_DESPAWN, 2000);
if(Performer)
Performer->Yell("It's so cold, so dark ... I'm not overacting, am I?", LANG_UNIVERSAL, NULL);
Yell("Rooting self");
DoCast(m_creature, SPELL_ROOTSELF);
if(Event == 1)
{
Yell("Event Hood");
BeginEventHood();
}
if(Event == 2)
{
Yell("Event Oz");
BeginEventOz();
}
if(Event == 3)
{
Yell("Event RAJ");
BeginEventRAJ();
}
if(Holder)
{
Yell("Attack Start $N");
AttackStart(Holder);
}
Yell("End of ifs");
StageWalk = false;
Yell("StageWalk set to false");
break;
}
case 1:
Yell("Case 1");
SpecialMove(B_X2, B_Y2, POS_Z, 5000);
m_creature->Relocate(B_X2, B_Y2, POS_Z, B_O2);
Yell("Movements complete");
WalkTimer = 5000;
Yell("WAlk Timer at 5000, breaking");
if(SpawnWalk) WalkPos = 0;
else WalkPos = 2;
break;
case 2:
Yell("Case 2");
if(SpawnWalk)
{
SpecialMove(B_X3, B_Y3, POS_Z, 5000);
m_creature->Relocate(B_X3, B_Y3, POS_Z, B_O3);
Yell("Movements complete, SpawnWalk true, WalkPos 1");
WalkPos = 1;
}
else
{
SpecialMove(B_X3, B_Y3, POS_Z, 15000);
m_creature->Relocate(B_X3, B_Y3, POS_Z, B_O3);
Yell("Movements complete, Spawnwalk false, WalkPos 3");
WalkPos = 3;
}
Yell("Walktimer set to 15000, breaking");
WalkTimer = 15000;
break;
case 3:
Yell("Case 3");
if(SpawnWalk)
{
m_creature->setEmoteState(EMOTE_STATE_NONE);
Yell("EMOTE_STATE_NONE");
SpecialMove(B_X4, B_Y4, POS_Z, 15000);
m_creature->Relocate(B_X4, B_Y4, POS_Z, B_O4);
Yell("Movements complete, SpawnWalk true, WalkPos 2");
WalkPos = 2;
}
else
{
SpecialMove(B_X4, B_Y4, POS_Z, 5000);
m_creature->Relocate(B_X4, B_Y4, POS_Z, B_O4);
Yell("Movements complete, SpawnWalk false, WalkPos 4");
WalkPos = 4;
}
Yell("Walktimer set to 5000, breaking");
WalkTimer = 5000;
break;
case 4:
DoCast(m_creature, SPELL_SPOTLIGHT);
Yell("Casting spotlight");
m_creature->setEmoteState(EMOTE_STATE_TALK);
Yell("Talking");
if(Event == 1)
BeginSpeechHood();
if(Event == 2)
BeginSpeechOz();
if(Event == 3)
BeginSpeechRAJ();
Yell("WalkPos set to 2, StageWalk set to false, breaking");
StageWalk = false;
break;
}
}else WalkTimer -= diff;
}
if(SpeechOz)
{
if(SpeechTimer < diff)
{
switch(SpeechNum)
{
case 1:
DoYell(SAY_OZ2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_OZ2);
SpeechTimer = 16000;
SpeechNum = 2;
break;
case 2:
DoYell(SAY_OZ3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_OZ3);
SpeechTimer = 7000;
SpeechNum = 3;
break;
case 3:
DoYell(SAY_OZ4, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_OZ4);
SpeechTimer = 10000;
SpeechNum = 4;
break;
case 4:
StageWalk = true;
SpawnWalk = true;
Yell("StageWalk, SpawnWalk true; removing all auras, WalkPos 3, SpeechOz false");
m_creature->RemoveAllAuras();
WalkPos = 3;
SpeechOz = false;
break;
}
}else SpeechTimer -= diff;
}
if(SpeechHood)
{
if(SpeechTimer < diff)
{
switch(SpeechNum)
{
case 1:
DoYell(SAY_HOOD2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_HOOD2);
SpeechTimer = 6000;
SpeechNum = 2;
break;
case 2:
DoYell(SAY_HOOD3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_HOOD3);
SpeechTimer = 15000;
SpeechNum = 3;
break;
case 3:
DoYell(SAY_HOOD4, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_HOOD4);
StageWalk = true;
SpawnWalk = true;
WalkPos = 3;
Yell("StageWalk, SpawnWalk true; removing all auras, WalkPos 3, SpeechHood false");
m_creature->RemoveAllAuras();
SpeechHood = false;
break;
}
}else SpeechTimer -= diff;
}
if(SpeechRAJ)
{
if(SpeechTimer < diff)
{
switch(SpeechNum)
{
case 1:
DoYell(SAY_RAJ2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_RAJ2);
SpeechTimer = 6000;
SpeechNum = 2;
break;
case 2:
DoYell(SAY_RAJ3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_RAJ3);
SpeechTimer = 15000;
SpeechNum = 3;
break;
case 3:
DoYell(SAY_RAJ4, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_RAJ4);
StageWalk = true;
SpawnWalk = true;
WalkPos = 3;
Yell("StageWalk, SpawnWalk true; removing all auras, WalkPos 3, SpeechRAJ false");
m_creature->RemoveAllAuras();
SpeechRAJ = false;
break;
}
}else SpeechTimer -= diff;
}
//Return since we have no target
if (!m_creature->SelectHostilTarget())
return;
//Check if we have a current target
if( m_creature->getVictim() && m_creature->isAlive())
{
if(Event == 1) // Red Riding Hood
{
if(Wolf && (!Wolf->isAlive()))
{
Wolf = NULL;
Yell("Big Bad Wolf dead, killing self");
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
}
}
if(Event == 2) // Wizard of Oz
{
if(Dorothee && (!Dorothee->isAlive()))
{
Yell("Dorothee dead");
DeathCount++;
}
if(Tinhead && (!Tinhead->isAlive()))
{
Yell("Tinhead dead");
DeathCount++;
}
if(Strawman && (!Strawman->isAlive()))
{
Yell("Strawman dead");
DeathCount++;
}
if(Roar && (!Roar->isAlive()))
{
Yell("Roar dead");
DeathCount++;
}
if(DeathCount >= 4 && (!HasSummonedCrone))
{
Yell("Summoning Crone");
Crone = m_creature->SummonCreature(17535, CRONE_X, CRONE_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
HasSummonedCrone = true;
}
if(Crone && (!Crone->isAlive()))
{
Dorothee = NULL;
Tinhead = NULL;
Strawman = NULL;
Roar = NULL;
Crone = NULL;
Yell("Crone dead, killing self");
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
}
}
if(Event == 3) //Romeo and Juliet
{
if(Julianne && (!Julianne->isAlive()))
{
Yell("Julianne dead");
DeathCount++;
}
if(DeathCount >= 1 && (!HasSummonedRomulo) && Julianne)
{
Yell("Summoning Romulo");
Romulo = Julianne->SummonCreature(17533, JUL_X, JUL_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
HasSummonedRomulo = true;
}
if((Julianne) && HealTimer < diff)
{
Yell("Beginning heal");
if(!Romulo || (!Romulo->isAlive()))
{
Yell("Julianne heal Julianne");
Julianne->CastSpell(Julianne, SPELL_ETERNALAFF, false);
}
else
{
switch(rand()&2)
{
case 0:
Yell("Switch 0, Julianne heal Julianne");
Julianne->CastSpell(Julianne, SPELL_ETERNALAFF, false);
break;
case 1:
Yell("Switch 1, Julianne heal Romulo");
Julianne->CastSpell(Romulo, SPELL_ETERNALAFF, false);
break;
}
}
HealTimer = 20000;
}else HealTimer -= diff;
if(HasSummonedRomulo && Julianne && Romulo)
{
if(ResurrectTimer < diff)
{
Yell("Beginning Resurrection");
if((!Romulo->isAlive()) && (Julianne->isAlive()))
{
Julianne->Yell(SAY_JUL_RES_ROMEO, LANG_UNIVERSAL, NULL);
Romulo = Julianne->SummonCreature(17533, JUL_X, JUL_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
}
if((!Julianne->isAlive()) && (Romulo->isAlive()))
{
Yell("Resummoning Julianne");
Julianne = m_creature->SummonCreature(17534, JUL_X, JUL_Y, POS_Z, POS_OR, TEMPSUMMON_CORPSE_TIMED_DESPAWN,6000);
}
ResurrectTimer = 10000;
}else ResurrectTimer -= diff;
}
if(HasSummonedRomulo && (!Romulo->isAlive()) && (!Julianne->isAlive()))
{
Yell("Both Romulo and Julianne dead, killing self");
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
}
}
}
}
void SpecialMove(float X, float Y, float Z, uint32 Time)
{
WorldPacket data( SMSG_MONSTER_MOVE, (41+m_creature->GetPackGUID().size()) );
data.append(m_creature->GetPackGUID());
data << m_creature->GetPositionX() << m_creature->GetPositionY() << m_creature->GetPositionZ();
// unknown field - unrelated to orientation
// seems to increment about 1000 for every 1.7 seconds
// for now, we'll just use mstime
data << getMSTime();
data << uint8(0); // walkback when walking from A to B
data << uint32(0x100);
//data << uint32(0x0200); // flags
/* Flags:
512: Floating, moving without walking/running
*/
data << Time; // Time in between points
data << uint32(1); // 1 single waypoint
data << X << Y << Z; // the single waypoint Point B
m_creature->SendMessageToSet( &data, true );
}
// Temporary to make debug yells easier.
void Yell(const char* text)
{
DoYell(text, LANG_UNIVERSAL, NULL);
}
};
CreatureAI* GetAI_npc_barnes(Creature *_Creature)
{
return new npc_barnesAI (_Creature);
}
void SendBarnesFirstGossip(Player *player, Creature *_Creature, uint32 action)
{
if(action == GOSSIP_ACTION_INFO_DEF + 1) // Oz
{
_Creature->Yell(SAY_OZ_INTRO2, LANG_UNIVERSAL, NULL);
player->ADD_GOSSIP_ITEM( 0, OZ_GOSSIP2, GOSSIP_SENDER_INFO, GOSSIP_ACTION_INFO_DEF + 1);
}
if(action == GOSSIP_ACTION_INFO_DEF + 2) // RAJ
{
_Creature->Yell(SAY_READY, LANG_UNIVERSAL, NULL);
((npc_barnesAI*)_Creature->AI())->WalkToStage(player, EVENT_RAJ);
}
if(action == GOSSIP_ACTION_INFO_DEF + 3) // Hood
{
_Creature->Yell(SAY_READY, LANG_UNIVERSAL, NULL);
((npc_barnesAI*)_Creature->AI())->WalkToStage(player, EVENT_HOOD);
}
player->PlayerTalkClass->CloseGossip();
}
void SendBarnesOzReady(Player *player, Creature *_Creature, uint32 action)
{
if(action == GOSSIP_ACTION_INFO_DEF + 1)
{
_Creature->Yell(SAY_READY, LANG_UNIVERSAL, NULL);
((npc_barnesAI*)_Creature->AI())->WalkToStage(player, EVENT_OZ);
}
player->PlayerTalkClass->CloseGossip();
}
bool GossipSelect_npc_barnes(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if(sender == GOSSIP_SENDER_MAIN)
SendBarnesFirstGossip(player, _Creature, action);
if(sender == GOSSIP_SENDER_INFO)
SendBarnesOzReady(player, _Creature, action);
return true;
}
bool GossipHello_npc_barnes(Player *player, Creature *_Creature)
{
switch(rand()%3)
{
case 0:
_Creature->Yell(SAY_OZ_INTRO1, LANG_UNIVERSAL, NULL);
player->ADD_GOSSIP_ITEM( 0, OZ_GOSSIP1 , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
break;
case 1:
_Creature->Yell(SAY_RAJ_INTRO1, LANG_UNIVERSAL, NULL);
player->ADD_GOSSIP_ITEM( 0, RAJ_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
break;
case 2:
_Creature->Yell(SAY_HOOD_INTRO1, LANG_UNIVERSAL, NULL);
player->ADD_GOSSIP_ITEM( 0, HOOD_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
break;
}
player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
return true;
}
void AddSC_npc_barnes()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_barnes";
newscript->GetAI = GetAI_npc_barnes;
newscript->pGossipHello = &GossipHello_npc_barnes;
newscript->pGossipSelect = &GossipSelect_npc_barnes;
m_scripts[nrscripts++] = newscript;
}