aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/426_world_scripts.sql (renamed from sql/updates/425_world_scripts.sql)0
-rw-r--r--sql/updates/427_world_scripts.sql57
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp4
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj24
-rw-r--r--src/bindings/scripts/VC90/90ScriptDev2.vcproj24
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp851
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h10
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp99
8 files changed, 1069 insertions, 0 deletions
diff --git a/sql/updates/425_world_scripts.sql b/sql/updates/426_world_scripts.sql
index 1d653e57891..1d653e57891 100644
--- a/sql/updates/425_world_scripts.sql
+++ b/sql/updates/426_world_scripts.sql
diff --git a/sql/updates/427_world_scripts.sql b/sql/updates/427_world_scripts.sql
new file mode 100644
index 00000000000..dd5d8c7b597
--- /dev/null
+++ b/sql/updates/427_world_scripts.sql
@@ -0,0 +1,57 @@
+Update `instance_template` set `script`='instance_scarlet_monastery' where `map`='189';
+Update `gameobject_template` set `ScriptName`='go_loosely_turned_soil' where`entry`='186314';
+
+update `creature_template` set `scriptname`='boss_headless_horseman',
+`minlevel`=70, `maxlevel`=70, `minhealth`=67068, `maxhealth`=67068,
+`minmana`=3155, `maxmana`=3155, `type`=6
+ where `entry` = 23682;
+
+update `creature_template` set `scriptname`='mob_head',
+ `minlevel`=70, `maxlevel`=70, `type`=6, `modelid_h`=21908,
+`minhealth`=24300, `maxhealth`=24300,
+`faction_A`=14, `faction_H`=14
+where `entry` = 23775;
+
+update `creature_template` set `scriptname`='mob_pulsing_pumpkin',
+`faction_A`=14, `faction_H`=14, `type`=6,
+`minlevel`=70, `maxlevel`=70,
+`minhealth`=9781, `maxhealth`=9781,
+`minmana`=3155, `maxmana`=3155
+where `entry` = 23694;
+
+--helper
+Update `creature_template` set `scriptname`='mob_wisp_invis',
+`faction_A`=35, `faction_H`=35,
+`unit_flags`='33554434' where `entry`='23686';
+
+-- pumpkin fiend
+Update `creature_template` set
+ `minlevel`=70, `maxlevel`=70,
+`faction_A`=14, `faction_H`=14,
+`type`=6
+where `entry`='23545';
+
+-- wisp
+Update `creature_template` set `scriptname`='mob_wisp_invis',
+`modelid_a`=21342, `modelid_h`=21342,
+`faction_A`=35, `faction_H`=35, `unit_flags`='33554434'
+where `entry`='24034';
+
+update `creature_template` set `equipment_id`=23682 where `entry` = 23682;
+replace into`creature_equip_template` (`entry`, `equipmodel1`, `equipmodel2`, `equipmodel3`, `equipinfo1`, `equipinfo2`, `equipinfo3`, `equipslot1`, `equipslot2`, `equipslot3`)
+VALUES (23682, 50495, 0, 0, 33490690, 0, 0, 781, 0, 0);
+
+Replace into `script_texts` values
+(-1189001, 'It is over, your search is done! Let fate choose now, the righteous one',0,0,0,0,0,0,0,0,11961,1,0,'Headless Horseman SAY_ENTRANCE'),
+
+(-1189002, 'Here\'s my body, fit and pure! Now, your blackened souls I\'ll cure!',0,0,0,0,0,0,0,0,12567,1,0,'Headless Horseman SAY_REJOINED'),
+
+(-1189003, 'Over here, you idiot!',0,0,0,0,0,0,0,0,12569,1,0,'Headless Horseman SAY_LOST_HEAD'),
+
+(-1189004, 'Harken, cur! Tis you I spurn! Now, $N, feel the burn!',0,0,0,0,0,0,0,0,12573,1,0,'Headless Horseman SAY_CONFLAGRATION'),
+
+(-1189005, 'Soldiers arise, stand and fight! Bring victory at last to this fallen knight!',0,0,0,0,0,0,0,0,11963,1,0,'Headless Horseman SAY_SPROUTING_PUMPKINS'),
+
+(-1189006, 'Your body lies beaten, battered and broken. Let my curse be your own, fate has spoken',0,0,0,0,0,0,0,0,11962,0,0,'Headless Horseman SAY_PLAYER_DEATH'),
+
+(-1189007, 'This end have I reached before. What new adventure lies in store?',0,0,0,0,0,0,0,0,11964,0,0,'Headless Horseman SAY_DEATH'); \ No newline at end of file
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index f045a33970a..a4f54c0579c 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -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();
diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
index b578b23d880..d5919cfb903 100644
--- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
@@ -759,6 +759,14 @@
>
</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"
>
</File>
@@ -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"
diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
index ac26d53065b..c5ab1dd69f8 100644
--- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
@@ -745,6 +745,14 @@
>
</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"
>
</File>
@@ -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"
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
new file mode 100644
index 00000000000..b8416c91952
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
@@ -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();
+}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h b/src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h
new file mode 100644
index 00000000000..fc0991df091
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/def_scarlet_monastery.h
@@ -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 \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
new file mode 100644
index 00000000000..a510ea06fab
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
@@ -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();
+}