*Headless horseman script. By Silver1ce.

--HG--
branch : trunk
This commit is contained in:
megamage
2008-12-08 17:30:52 -06:00
parent be88f3c313
commit b0c0cb90ad
8 changed files with 1069 additions and 0 deletions
+4
View File
@@ -411,6 +411,7 @@ extern void AddSC_boss_amnennar_the_coldbringer();
extern void AddSC_boss_arcanist_doan();
extern void AddSC_boss_azshir_the_sleepless();
extern void AddSC_boss_bloodmage_thalnos();
extern void AddSC_boss_headless_horseman();
extern void AddSC_boss_herod();
extern void AddSC_boss_high_inquisitor_fairbanks();
extern void AddSC_boss_high_inquisitor_whitemane();
@@ -418,6 +419,7 @@ extern void AddSC_boss_houndmaster_loksey();
extern void AddSC_boss_interrogator_vishas();
extern void AddSC_boss_scarlet_commander_mograine();
extern void AddSC_boss_scorn();
extern void AddSC_instance_scarlet_monastery();
//Scholomance
extern void AddSC_boss_darkmaster_gandling();
@@ -1603,6 +1605,7 @@ void ScriptsInit()
AddSC_boss_arcanist_doan();
AddSC_boss_azshir_the_sleepless();
AddSC_boss_bloodmage_thalnos();
AddSC_boss_headless_horseman();
AddSC_boss_herod();
AddSC_boss_high_inquisitor_fairbanks();
AddSC_boss_high_inquisitor_whitemane();
@@ -1610,6 +1613,7 @@ void ScriptsInit()
AddSC_boss_interrogator_vishas();
AddSC_boss_scarlet_commander_mograine();
AddSC_boss_scorn();
AddSC_instance_scarlet_monastery();
//Scholomance
AddSC_boss_darkmaster_gandling();
@@ -758,6 +758,14 @@
RelativePath="..\scripts\zone\scarlet_monastery\boss_bloodmage_thalnos.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\boss_headless_horseman.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\boss_headless_horseman.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\boss_herod.cpp"
>
@@ -786,6 +794,22 @@
RelativePath="..\scripts\zone\scarlet_monastery\boss_scorn.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\def_scarlet_monastery.h"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\instance_scarlet_monastery.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\def_scarlet_monastery.h"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\instance_scarlet_monastery.cpp"
>
</File>
</Filter>
<Filter
Name="Scholomance"
@@ -744,6 +744,14 @@
RelativePath="..\scripts\zone\scarlet_monastery\boss_bloodmage_thalnos.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\boss_headless_horseman.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\boss_headless_horseman.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\boss_herod.cpp"
>
@@ -772,6 +780,22 @@
RelativePath="..\scripts\zone\scarlet_monastery\boss_scorn.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\def_scarlet_monastery.h"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\instance_scarlet_monastery.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\def_scarlet_monastery.h"
>
</File>
<File
RelativePath="..\scripts\zone\scarlet_monastery\instance_scarlet_monastery.cpp"
>
</File>
</Filter>
<Filter
Name="Scholomance"
@@ -0,0 +1,851 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Headless_Horseman
SD%Complete:
SDComment:
SDCategory: Scarlet Monastery
EndScriptData */
#include "precompiled.h"
#include "SpellMgr.h"
#include "def_scarlet_monastery.h"
#define SAY_ENTRANCE -1189001
#define SAY_REJOINED -1189002
#define SAY_LOST_HEAD -1189003
#define SAY_CONFLAGRATION -1189004
#define SAY_SPROUTING_PUMPKINS -1189005
#define SAY_PLAYER_DEATH -1189006
#define SAY_DEATH -1189007
uint32 RandomLaught[] = {11965, 11975, 11976};
// Entryes
#define HH_MOUNTED 23682
#define HH_UNHORSED 23800
#define HEAD 23775
#define PULSING_PUMPKIN 23694
#define PUMPKIN_FIEND 23545
#define HELPER 23686
#define WISP_INVIS 24034
//Spells
#define SPELL_CLEAVE 42587
#define SPELL_CONFLAGRATION 42380 //Phase 2, can't find real spell(Dim Fire?)
//#define SPELL_CONFL_SPEED 22587 //8% increase speed, value 22587 from SPELL_CONFLAGRATION mains that spell?
#define SPELL_SUMMON_PUMPKIN 42394
#define SPELL_WHIRLWIND 43116
#define SPELL_IMMUNE 42556
#define SPELL_BODY_REGEN 42403
#define SPELL_CONFUSE 43105
#define SPELL_FLYING_HEAD 42399 //visual flying head
#define SPELL_HEAD 42413 //visual buff, "head"
#define SPELL_HEAD_IS_DEAD 42428 //at killing head, Phase 3
#define SPELL_PUMPKIN_AURA 42280
#define SPELL_PUMPKIN_AURA_GREEN 42294
#define SPELL_SQUASH_SOUL 42514
#define SPELL_SPROUTING 42281
#define SPELL_SPROUT_BODY 42285
//Effects
#define SPELL_RHYME_BIG 42909
//#define SPELL_RHYME_SMALL 42910
#define SPELL_HEAD_SPEAKS 43129
#define SPELL_HEAD_LANDS 42400
#define SPELL_BODY_FLAME 42074
#define SPELL_HEAD_FLAME 42971
//#define SPELL_ENRAGE_VISUAL 42438 // he uses this spell?
#define SPELL_WISP_BLUE 42821
#define SPELL_WISP_FLIGHT_PORT 42818
//#define SPELL_WISP_INVIS 42823
#define SPELL_SMOKE 42355
#define SPELL_DEATH 42566 //not correct spell
struct Locations
{
float x, y, z;
};
static Locations FlightPoint[]=
{
{1754.00,1346.00,17.50},
{1765.00,1347.00,19.00},
{1784.00,1346.80,25.40},
{1803.30,1347.60,33.00},
{1824.00,1350.00,42.60},
{1838.80,1353.20,49.80},
{1852.00,1357.60,55.70},
{1861.30,1364.00,59.40},
{1866.30,1374.80,61.70},
{1864.00,1387.30,63.20},
{1854.80,1399.40,64.10},
{1844.00,1406.90,64.10},
{1824.30,1411.40,63.30},
{1801.00,1412.30,60.40},
{1782.00,1410.10,55.50},
{1770.50,1405.20,50.30},
{1765.20,1400.70,46.60},
{1761.40,1393.40,41.70},
{1759.10,1386.70,36.60},
{1757.80,1378.20,29.00},
{1758.00,1367.00,19.51}
};
static Locations Spawn[]=
{
{1776.27,1348.74,19.20}, //spawn point for pumpkin shrine mob
{1765.28,1347.46,17.55} //spawn point for smoke
};
struct Summon
{
const std::string text;
};
static Summon Text[]=
{
{"Horseman rise..."},
{"Your time is night..."},
{"You felt death once..."},
{"Now, know demise!"}
};
struct TRINITY_DLL_DECL mob_wisp_invisAI : public ScriptedAI
{
mob_wisp_invisAI(Creature *c) : ScriptedAI(c)
{
Creaturetype = delay = spell = spell2 = 0;
//that's hack but there are no info about range of this spells in dbc
SpellEntry *wisp = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_WISP_BLUE);
if (wisp)
wisp->rangeIndex = 6; //100 yards
SpellEntry *port = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_WISP_FLIGHT_PORT);
if (port)
port->rangeIndex = 6;
}
uint32 Creaturetype;
uint32 delay;
uint32 spell;
uint32 spell2;
void Reset(){}
void Aggro(Unit *who){}
void SetType(uint32 _type)
{
Creaturetype = _type;
switch(Creaturetype)
{
case 1:
spell = SPELL_PUMPKIN_AURA_GREEN; break;
case 2:
delay = 15000; spell = SPELL_BODY_FLAME;spell2 = SPELL_DEATH; break;
case 3:
delay = 15000; spell = SPELL_SMOKE; break;
case 4:
delay = 7000; spell2 = SPELL_WISP_BLUE; break;
}
if (spell)DoCast(m_creature,spell);
}
void SpellHit(Unit* caster, const SpellEntry *spell)
{
if(spell->Id == SPELL_WISP_FLIGHT_PORT && Creaturetype == 4)
m_creature->SetDisplayId(2027);
}
void MoveInLineOfSight(Unit *who)
{
if (!who || Creaturetype != 1 || !who->isTargetableForAttack())
return;
if (m_creature->GetDistance2d(who) < 0.1 && !who->HasAura(SPELL_SQUASH_SOUL,0))
DoCast(who,SPELL_SQUASH_SOUL);
}
void UpdateAI(const uint32 diff)
{
if(delay)
{
if (delay <= diff)
{
m_creature->RemoveAurasDueToSpell(SPELL_SMOKE);
if(spell2)
DoCast(m_creature,spell2);
delay = 0;
}else delay -= diff;
}
}
};
struct TRINITY_DLL_DECL mob_headAI : public ScriptedAI
{
mob_headAI(Creature *c) : ScriptedAI(c) {Reset();}
uint64 bodyGUID;
uint32 Phase;
uint32 laugh;
uint32 wait;
bool withbody;
bool die;
void Reset()
{
Phase = 0;
bodyGUID = 0;
die = false;
withbody = true;
wait = 1000;
laugh = 15000 + rand()%16 * 1000;
}
void Aggro(Unit *who) {}
void SaySound(int32 textEntry, Unit *target = 0)
{
DoScriptText(textEntry, m_creature, target);
//DoCast(m_creature,SPELL_HEAD_SPEAKS,true);
Creature *speaker = DoSpawnCreature(HELPER,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN,1000);
speaker->CastSpell(speaker,SPELL_HEAD_SPEAKS,false);
laugh += 3000;
}
void DamageTaken(Unit* done_by,uint32 &damage)
{
if (withbody)
return;
switch(Phase)
{
case 1:
if(((m_creature->GetHealth() - damage)*100)/m_creature->GetMaxHealth() < 67)
Disappear();break;
case 2:
if(((m_creature->GetHealth() - damage)*100)/m_creature->GetMaxHealth() < 34)
Disappear();break;
case 3:
if (damage >= m_creature->GetHealth())
{
die = true;
withbody = true;
wait = 300;
damage = m_creature->GetHealth() - m_creature->GetMaxHealth()/100;
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->StopMoving();
//m_creature->GetMotionMaster()->MoveIdle();
DoCast(m_creature,SPELL_HEAD_IS_DEAD);
}break;
}
}
void SpellHit(Unit *caster, const SpellEntry* spell)
{
if (!withbody)
return;
if (spell->Id == SPELL_FLYING_HEAD)
{
if (Phase < 3) ++Phase;
else Phase = 3;
withbody = false;
if(!bodyGUID)
bodyGUID = caster->GetGUID();
m_creature->RemoveAllAuras();
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoCast(m_creature,SPELL_HEAD_LANDS,true);
DoCast(m_creature,SPELL_HEAD,false);
SaySound(SAY_LOST_HEAD);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveFleeing(caster->getVictim());
}
}
void Disappear();//we must set returned=true(this will prevent from "body calls head" while head flying to body), see function below
void UpdateAI(const uint32 diff)
{
if (!withbody)
{
if (wait < diff)
{
wait = 1000;
if (!m_creature->getVictim()) return;
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveFleeing(m_creature->getVictim());
}else wait -= diff;
if (laugh < diff)
{
laugh = 15000 + (rand()%16)*1000;
DoPlaySoundToSet(m_creature, RandomLaught[rand()%3]);
//DoCast(m_creature,SPELL_HEAD_SPEAKS,true); //this spell remove buff "head"
Creature *speaker = DoSpawnCreature(HELPER,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN,1000);
speaker->CastSpell(speaker,SPELL_HEAD_SPEAKS,false);
DoTextEmote("laughts",NULL);
} else laugh -= diff;
} else {
if (die) {
if (wait < diff)
{
die = false;
Unit *body = Unit::GetUnit((*m_creature),bodyGUID);
if (body)
body->DealDamage(body, body->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
m_creature->setDeathState(JUST_DIED);
} else wait -= diff;
}
}
}
};
struct TRINITY_DLL_DECL boss_headless_horsemanAI : public ScriptedAI
{
boss_headless_horsemanAI(Creature *c) : ScriptedAI(c)
{
SpellEntry *confl = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_CONFLAGRATION);
if(confl)
{
confl->EffectApplyAuraName[0] = SPELL_AURA_PERIODIC_DAMAGE_PERCENT;
confl->EffectBasePoints[0] = 10;
confl->EffectBaseDice[0] = 10;
confl->DmgMultiplier[0] = 1;
}
/* SpellEntry *confl = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_CONFLAGRATION);
if(confl)
confl->EffectTriggerSpell[1] = 22587;
SpellEntry *speed = (SpellEntry*)GetSpellStore()->LookupEntry(22587);
if(speed)
{
speed->Effect[1] = SPELL_EFFECT_APPLY_AURA;
speed->EffectApplyAuraName[1] = SPELL_AURA_MOD_CONFUSE;
}*/
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance *pInstance;
uint64 headGUID;
uint64 playerGUID;
uint32 Phase;
uint32 id;
uint32 count;
uint32 say_timer;
uint32 conflagrate;
uint32 summonadds;
uint32 cleave;
uint32 regen;
uint32 whirlwind;
uint32 laugh;
uint32 burn;
bool withhead;
bool returned;
bool IsFlying;
bool wp_reached;
bool burned;
void Reset()
{
Phase = 1;
conflagrate = 15000;
summonadds = 15000;
laugh = 16000 + rand()%5 * 1000;
cleave = 2000;
regen = 1000;
burn = 6000;
count = 0;
say_timer = 3000;
withhead = true;
returned = true;
burned = false;
IsFlying = false;
DoCast(m_creature,SPELL_HEAD);
if (headGUID){
Unit* Head = Unit::GetUnit((*m_creature), headGUID);
if(Head){
Head->SetVisibility(VISIBILITY_OFF);
Head->setDeathState(JUST_DIED);
}
headGUID = 0;
}
if (pInstance)
pInstance->SetData(DATA_HORSEMAN_EVENT, 0);
}
void FlyMode()
{
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
m_creature->SetSpeed(MOVE_WALK,5.0f,true);
wp_reached = false;
count = 0;
say_timer = 3000;
id = 0;
Phase = 0;
}
void MovementInform(uint32 type, uint32 i)
{
if (type != POINT_MOTION_TYPE || !IsFlying)
return;
if (i != id)
return;
wp_reached = true;
switch (id)
{
case 0:
m_creature->SetVisibility(VISIBILITY_ON);break;
case 1: {
Creature *smoke = m_creature->SummonCreature(HELPER,Spawn[1].x,Spawn[1].y,Spawn[1].z,0,TEMPSUMMON_TIMED_DESPAWN,20000);
((mob_wisp_invisAI*)smoke->AI())->SetType(3);
DoCast(m_creature,SPELL_RHYME_BIG);
break;}
case 6:
if(pInstance)
pInstance->SetData(GAMEOBJECT_PUMPKIN_SHRINE, 0); //hide gameobject
break;
case 19:
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING2);break;
case 20: {
Phase = 1;
IsFlying = false;
wp_reached = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
SaySound(SAY_ENTRANCE);
Unit *plr = Unit::GetUnit((*m_creature),playerGUID);
if (plr)
DoStartMovement(plr);
}
break;
}
++id;
}
void Aggro(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_HORSEMAN_EVENT, IN_PROGRESS);
DoZoneInCombat();
}
void AttackStart(Unit* who) {ScriptedAI::AttackStart(who);}
void MoveInLineOfSight(Unit *who)
{
if (withhead && Phase != 0)
ScriptedAI::MoveInLineOfSight(who);
}
void KilledUnit(Unit *plr)
{
if (plr->GetTypeId() == TYPEID_PLAYER)
{
if (withhead)
SaySound(SAY_PLAYER_DEATH);
else { //maybe possible when player dies from conflagration
Creature *Head = (Creature*)Unit::GetUnit((*m_creature), headGUID);
if (Head)
((mob_headAI*)Head->AI())->SaySound(SAY_PLAYER_DEATH);
}
}
}
void SaySound(int32 textEntry, Unit *target = 0)
{
DoScriptText(textEntry, m_creature, target);
laugh += 4000;
}
Player* SelectRandomPlayer(float range = 0.0f, bool checkLoS = true)
{
Map *map = m_creature->GetMap();
if (!map->IsDungeon()) return NULL;
Map::PlayerList const &PlayerList = map->GetPlayers();
Map::PlayerList::const_iterator i;
if(PlayerList.isEmpty()) return NULL;
std::list<Player*> temp;
std::list<Player*>::iterator j;
for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if((m_creature->IsWithinLOSInMap(i->getSource()) || !checkLoS) && m_creature->getVictim() != i->getSource() &&
m_creature->IsWithinDistInMap(i->getSource(), range) && i->getSource()->isAlive())
temp.push_back(i->getSource());
if (temp.size()) {
j = temp.begin();
advance(j, rand()%temp.size());
return (*j);
}
return NULL;
}
void SpellHitTarget(Unit* unit, const SpellEntry* spell)
{
if (spell->Id == SPELL_CONFLAGRATION)
if (unit->HasAura(SPELL_CONFLAGRATION,0))
SaySound(SAY_CONFLAGRATION,unit);
}
void JustDied(Unit* killer)
{
m_creature->StopMoving();
//m_creature->GetMotionMaster()->MoveIdle(); test
SaySound(SAY_DEATH);
Creature *flame = DoSpawnCreature(HELPER,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN,60000);
flame->CastSpell(flame,SPELL_BODY_FLAME,false);
Creature *wisp = DoSpawnCreature(WISP_INVIS,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN,60000);
((mob_wisp_invisAI*)wisp->AI())->SetType(4);
if(pInstance)
pInstance->SetData(DATA_HORSEMAN_EVENT, DONE);
}
void SpellHit(Unit *caster, const SpellEntry* spell)
{
if (withhead)
return;
if (spell->Id == SPELL_FLYING_HEAD)
{
if (Phase < 3) Phase++;
else Phase = 3;
withhead = true;
m_creature->RemoveAllAuras();
m_creature->SetName("Headless Horseman");
m_creature->SetHealth(m_creature->GetMaxHealth());
SaySound(SAY_REJOINED);
DoCast(m_creature,SPELL_HEAD);
caster->GetMotionMaster()->Clear(false);
caster->GetMotionMaster()->MoveFollow(m_creature,6,rand()%6);
//DoResetThreat();//not sure if need
std::list<HostilReference*>::iterator itr;
for(itr = caster->getThreatManager().getThreatList().begin(); itr != caster->getThreatManager().getThreatList().end(); ++itr)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
if(pUnit && pUnit->isAlive() && pUnit != caster)
m_creature->AddThreat(pUnit,caster->getThreatManager().getThreat(pUnit));
}
}
}
void DamageTaken(Unit *done_by, uint32 &damage)
{
if (damage >= m_creature->GetHealth() && withhead)
{
withhead = false;
returned = false;
damage = m_creature->GetHealth() - m_creature->GetMaxHealth()/100;
m_creature->RemoveAllAuras();
m_creature->SetName("Headless Horseman, Unhorsed");
if (!headGUID)
headGUID = DoSpawnCreature(HEAD,rand()%6,rand()%6,0,0,TEMPSUMMON_DEAD_DESPAWN,0)->GetGUID();
Unit* Head = Unit::GetUnit((*m_creature), headGUID);
if (Head && Head->isAlive())
{
Head->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
//Head->CastSpell(Head,SPELL_HEAD_INVIS,false);
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature,SPELL_IMMUNE,true);
DoCast(m_creature,SPELL_BODY_REGEN,true);
m_creature->CastSpell(Head, SPELL_FLYING_HEAD,true);
DoCast(m_creature,SPELL_CONFUSE,false); //test
done_by->ProcDamageAndSpell(m_creature,PROC_FLAG_KILL_AND_GET_XP,PROC_FLAG_KILLED,PROC_EX_NONE,0);
whirlwind = 4000 + (rand()%5)*1000;
regen = 0;
}
}
}
void UpdateAI(const uint32 diff)
{
if (withhead)
{
switch(Phase)
{
case 0: {
if (!IsFlying)
{
if (say_timer < diff) {
say_timer = 3000;
Player *plr = SelectRandomPlayer(100.0f,false);
if (count < 3)
plr->Say(Text[count].text,0);
else {
DoCast(m_creature,SPELL_RHYME_BIG);
plr->Say(Text[count].text,0);
plr->HandleEmoteCommand(ANIM_EMOTE_SHOUT);
wp_reached = true;
IsFlying = true;
count = 0;
break;
}
++count;
}else say_timer -= diff;
}else{
if (wp_reached) {
wp_reached = false;
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MovePoint(id,FlightPoint[id].x,FlightPoint[id].y,FlightPoint[id].z);
}
}
}
break;
case 1:
if(burned) break;
if(burn < diff)
{
Creature *flame = m_creature->SummonCreature(HELPER,Spawn[0].x,Spawn[0].y,Spawn[0].z,0,TEMPSUMMON_TIMED_DESPAWN,17000);
((mob_wisp_invisAI*)flame->AI())->SetType(2);
burned = true;
}else burn -= diff;
break;
case 2:
if (conflagrate < diff)
{
Unit *plr = (Unit*)SelectRandomPlayer(30.0f);
if (plr)
m_creature->CastSpell(plr,SPELL_CONFLAGRATION,false);
conflagrate = 10000 + rand()%7 * 1000;
}else conflagrate -= diff;
break;
case 3:
if (summonadds < diff)
{
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature,SPELL_SUMMON_PUMPKIN);
SaySound(SAY_SPROUTING_PUMPKINS);
summonadds = 25000 + rand()%11 *1000;
}else summonadds -= diff;
break;
}
if (laugh < diff) {
laugh = 11000 + rand()%12 * 1000;
DoTextEmote("laughts",NULL);
DoPlaySoundToSet(m_creature, RandomLaught[rand()%3]);
} else laugh -= diff;
if (m_creature->SelectHostilTarget() && m_creature->getVictim())
{
DoMeleeAttackIfReady();
if (cleave < diff) {
DoCast(m_creature->getVictim(),SPELL_CLEAVE);
cleave = 2000*(1 + rand()%3); //1 cleave per 2.0-6.0sec
} else cleave -= diff;
}
} else {
if (regen < diff)
{
regen = 1000; //"body calls head"
if (m_creature->GetHealth()/m_creature->GetMaxHealth() == 1 && !returned)
{
if (Phase > 1) --Phase;
else Phase = 1;
Creature* Head = (Creature*)Unit::GetUnit((*m_creature), headGUID);
if (Head && Head->isAlive())
{
((mob_headAI*)Head->AI())->Phase = Phase;
((mob_headAI*)Head->AI())->Disappear();
}
return;
}
}
else regen -= diff;
if (whirlwind < diff)
{
whirlwind = 4000 + rand()%5 * 1000;
if (rand()%2) {
m_creature->RemoveAurasDueToSpell(SPELL_CONFUSE);
DoCast(m_creature,SPELL_WHIRLWIND,true);
DoCast(m_creature,SPELL_CONFUSE);
}else
m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND);
}else whirlwind -= diff;
}
}
};
void mob_headAI::Disappear()
{
if (withbody)
return;
if (bodyGUID)
{
Creature *body = (Creature*)Unit::GetUnit((*m_creature), bodyGUID);
if(body && body->isAlive())
{
withbody = true;
m_creature->RemoveAllAuras();
body->RemoveAurasDueToSpell(SPELL_IMMUNE);//hack, SpellHit doesn't calls if body has immune aura
DoCast(body,SPELL_FLYING_HEAD);
m_creature->SetHealth(m_creature->GetMaxHealth());
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->GetMotionMaster()->MoveIdle();
m_creature->StopMoving();
((boss_headless_horsemanAI*)body->AI())->returned = true;
}
}
}
struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI
{
mob_pulsing_pumpkinAI(Creature *c) : ScriptedAI(c) {Reset();}
bool sprouted;
uint64 debuffGUID;
void Reset()
{
float x, y, z;
m_creature->GetPosition(x, y, z); //this visual aura some under ground
m_creature->Relocate(x,y,z + 0.35f);
Despawn();
Creature *debuff = DoSpawnCreature(HELPER,0,0,0,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,14500);
debuff->SetDisplayId(m_creature->GetDisplayId());
debuff->CastSpell(debuff,SPELL_PUMPKIN_AURA_GREEN,false);
((mob_wisp_invisAI*)debuff->AI())->SetType(1);
debuffGUID = debuff->GetGUID();
sprouted = false;
DoCast(m_creature,SPELL_PUMPKIN_AURA,true);
DoCast(m_creature,SPELL_SPROUTING);
m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE);
}
void Aggro(Unit *who){}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
if (spell->Id == SPELL_SPROUTING)
{
sprouted = true;
m_creature->RemoveAllAuras();
m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE);
DoCast(m_creature,SPELL_SPROUT_BODY,true);
m_creature->UpdateEntry(PUMPKIN_FIEND);
DoStartMovement(m_creature->getVictim());
}
}
void Despawn()
{
if (!debuffGUID) return;
Unit *debuff = Unit::GetUnit((*m_creature),debuffGUID);
if(debuff)
debuff->SetVisibility(VISIBILITY_OFF);
debuffGUID = 0;
}
void JustDied(Unit *killer) {if(!sprouted) Despawn();}
void MoveInLineOfSight(Unit *who)
{
if (!who || !who->isTargetableForAttack() || !m_creature->IsHostileTo(who) || m_creature->getVictim())
return;
m_creature->AddThreat(who,0.0f);
if(sprouted)
DoStartMovement(who);
}
void UpdateAI(const uint32 diff)
{
if (sprouted)
if (m_creature->SelectHostilTarget() && m_creature->getVictim())
DoMeleeAttackIfReady();
}
};
bool GOHello_go_loosely_turned_soil(Player *plr, GameObject* soil)
{
/* if (soil->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER && plr->getLevel() > 64)
{
plr->PrepareQuestMenu(soil->GetGUID());
plr->SendPreparedQuest(soil->GetGUID());
}
if (plr->GetQuestStatus(11405) == QUEST_STATUS_INCOMPLETE && plr->getLevel() > 64)
{ */
plr->AreaExploredOrEventHappens(11405);
Creature *horseman = soil->SummonCreature(HH_MOUNTED,FlightPoint[20].x,FlightPoint[20].y,FlightPoint[20].z,0,TEMPSUMMON_MANUAL_DESPAWN,0);
((boss_headless_horsemanAI*)horseman->AI())->playerGUID = plr->GetGUID();
((boss_headless_horsemanAI*)horseman->AI())->FlyMode();
//}
return true;
}
CreatureAI* GetAI_mob_head(Creature *_Creature)
{
return new mob_headAI (_Creature);
}
CreatureAI* GetAI_boss_headless_horseman(Creature *_Creature)
{
return new boss_headless_horsemanAI (_Creature);
}
CreatureAI* GetAI_mob_pulsing_pumpkin(Creature *_Creature)
{
return new mob_pulsing_pumpkinAI (_Creature);
}
CreatureAI* GetAI_mob_wisp_invis(Creature *_Creature)
{
return new mob_wisp_invisAI (_Creature);
}
void AddSC_boss_headless_horseman()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_headless_horseman";
newscript->GetAI = GetAI_boss_headless_horseman;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_head";
newscript->GetAI = GetAI_mob_head;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_pulsing_pumpkin";
newscript->GetAI = GetAI_mob_pulsing_pumpkin;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_wisp_invis";
newscript->GetAI = GetAI_mob_wisp_invis;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "go_loosely_turned_soil";
newscript->pGOHello = &GOHello_go_loosely_turned_soil;
newscript->RegisterSelf();
}
@@ -0,0 +1,10 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_SCARLET_M
#define DEF_SCARLET_M
#define DATA_HORSEMAN_EVENT 1
#define GAMEOBJECT_PUMPKIN_SHRINE 2
#endif
@@ -0,0 +1,99 @@
#include "precompiled.h"
#include "def_scarlet_monastery.h"
#include "sc_creature.h"
#define ENTRY_PUMPKIN_SHRINE 186267
#define ENTRY_HORSEMAN 23682
#define ENTRY_HEAD 23775
#define ENTRY_PUMPKIN 23694
struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
{
instance_scarlet_monastery(Map *Map) : ScriptedInstance(Map) {Initialize();};
uint64 PumpkinShrineGUID;
uint64 HorsemanGUID;
uint64 HeadGUID;
std::set<uint64> HorsemanAdds;
void Initialize()
{
PumpkinShrineGUID = 0;
HorsemanGUID = 0;
HeadGUID = 0;
HorsemanAdds.clear();
}
void OnObjectCreate(GameObject *go)
{
switch(go->GetEntry())
{
case ENTRY_PUMPKIN_SHRINE:
PumpkinShrineGUID = go->GetGUID();break;
}
}
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
switch(creature_entry)
{
case ENTRY_HORSEMAN: HorsemanGUID = creature->GetGUID(); break;
case ENTRY_HEAD: HeadGUID = creature->GetGUID(); break;
case ENTRY_PUMPKIN: HorsemanAdds.insert(creature->GetGUID());break;
}
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case GAMEOBJECT_PUMPKIN_SHRINE:
{
GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);
if(Shrine)
Shrine->SetUInt32Value(GAMEOBJECT_STATE,1);
}break;
case DATA_HORSEMAN_EVENT:
if (data == DONE)
{
for(std::set<uint64>::iterator itr = HorsemanAdds.begin(); itr != HorsemanAdds.end(); ++itr)
{
Creature* add = instance->GetCreatureInMap(*itr);
if(add && add->isAlive())
add->DealDamage(add, add->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
HorsemanAdds.clear();
GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);
if(Shrine)
Shrine->SetUInt32Value(GAMEOBJECT_STATE,1);
}
break;
}
}
/* uint64 GetData64(uint32 type)
{
switch(type)
{
case GAMEOBJECT_PUMPKIN_SHRINE: return PumpkinShrineGUID;
case DATA_HORSEMAN: return HorsemanGUID;
case DATA_HEAD: return HeadGUID;
}
return 0;
}*/
};
InstanceData* GetInstanceData_instance_scarlet_monastery(Map* map)
{
return new instance_scarlet_monastery(map);
}
void AddSC_instance_scarlet_monastery()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_scarlet_monastery";
newscript->GetInstanceData = &GetInstanceData_instance_scarlet_monastery;
newscript->RegisterSelf();
}