Script HoR instance. 1st part.
Fixes issue #1311. - Intro event. - 10 waves including Falric and Marwyn. - Script based on proposal of Synric on trinitycore forum (submitted by Skarabex on GC). --HG-- branch : trunk
This commit is contained in:
@@ -416,6 +416,10 @@ void AddSC_pit_of_saron();
|
||||
void AddSC_boss_garfrost();
|
||||
void AddSC_boss_ick();
|
||||
void AddSC_boss_tyrannus();
|
||||
void AddSC_instance_halls_of_reflection(); // Halls of Reflection
|
||||
void AddSC_halls_of_reflection();
|
||||
void AddSC_boss_falric();
|
||||
void AddSC_boss_marwyn();
|
||||
|
||||
void AddSC_dalaran();
|
||||
void AddSC_borean_tundra();
|
||||
@@ -912,6 +916,10 @@ void AddScripts()
|
||||
AddSC_boss_garfrost();
|
||||
AddSC_boss_ick();
|
||||
AddSC_boss_tyrannus();
|
||||
AddSC_instance_halls_of_reflection(); // Halls of Reflection
|
||||
AddSC_halls_of_reflection();
|
||||
AddSC_boss_falric();
|
||||
AddSC_boss_marwyn();
|
||||
|
||||
AddSC_dalaran();
|
||||
AddSC_borean_tundra();
|
||||
|
||||
+20
-3
@@ -1089,9 +1089,26 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster,
|
||||
switch(GetSpellProto()->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
// Remove the immunity shield marker on Avenging Wrath removal if Forbearance is not present
|
||||
if (GetId() == 61987 && target->HasAura(61988) && !target->HasAura(25771))
|
||||
target->RemoveAura(61988);
|
||||
switch(GetId())
|
||||
{
|
||||
case 61987: // Avenging Wrath
|
||||
// Remove the immunity shield marker on Avenging Wrath removal if Forbearance is not present
|
||||
if (target->HasAura(61988) && !target->HasAura(25771))
|
||||
target->RemoveAura(61988);
|
||||
break;
|
||||
case 72368: // Shared Suffering
|
||||
case 72369:
|
||||
if (caster)
|
||||
{
|
||||
if (AuraEffect* aurEff = GetEffect(0))
|
||||
{
|
||||
int32 remainingDamage = aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber());
|
||||
if (remainingDamage > 0)
|
||||
caster->CastCustomSpell(caster, 72373, NULL, &remainingDamage, NULL, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_MAGE:
|
||||
switch(GetId())
|
||||
|
||||
@@ -3629,6 +3629,7 @@ void SpellMgr::LoadSpellCustomAttr()
|
||||
case 42384: // Brutal Swipe
|
||||
case 45150: // Meteor Slash
|
||||
case 64422: case 64688: // Sonic Screech
|
||||
case 72373: // Shared Suffering
|
||||
// ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE
|
||||
mSpellCustomAttr[i] |= SPELL_ATTR_CU_SHARE_DAMAGE;
|
||||
count++;
|
||||
|
||||
@@ -346,7 +346,10 @@ SET(scripts_STAT_SRCS
|
||||
northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp
|
||||
northrend/frozen_halls/forge_of_souls/forge_of_souls.h
|
||||
northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp
|
||||
northrend/frozen_halls/halls_of_reflection/boss_falric.cpp
|
||||
northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp
|
||||
northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
|
||||
northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp
|
||||
northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
|
||||
northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp
|
||||
northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
|
||||
* 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 "ScriptedPch.h"
|
||||
#include "halls_of_reflection.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = -1668050,
|
||||
SAY_SLAY_1 = -1668051,
|
||||
SAY_SLAY_2 = -1668052,
|
||||
SAY_DEATH = -1668053,
|
||||
SAY_IMPENDING_DESPAIR = -1668054,
|
||||
SAY_DEFILING_HORROR = -1668055,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_QUIVERING_STRIKE = 72422,
|
||||
SPELL_IMPENDING_DESPAIR = 72426,
|
||||
SPELL_DEFILING_HORROR = 72435,
|
||||
SPELL_HOPELESSNESS = 72395,
|
||||
H_SPELL_HOPELESSNESS = 72390, // TODO: not in dbc. Add in DB.
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
EVENT_QUIVERING_STRIKE,
|
||||
EVENT_IMPENDING_DESPAIR,
|
||||
EVENT_DEFILING_HORROR,
|
||||
};
|
||||
|
||||
struct boss_falricAI : public boss_horAI
|
||||
{
|
||||
boss_falricAI(Creature *pCreature) : boss_horAI(pCreature) {}
|
||||
|
||||
uint8 uiHopelessnessCount;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
boss_horAI::Reset();
|
||||
|
||||
uiHopelessnessCount = 0;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_FALRIC_EVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_FALRIC_EVENT, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 23000);
|
||||
events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 9000);
|
||||
events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(25000,45000)); // TODO adjust timer.
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_FALRIC_EVENT, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_QUIVERING_STRIKE:
|
||||
DoCast(SPELL_QUIVERING_STRIKE);
|
||||
events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 10000);
|
||||
break;
|
||||
case EVENT_IMPENDING_DESPAIR:
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
{
|
||||
DoScriptText(SAY_IMPENDING_DESPAIR, me);
|
||||
DoCast(pTarget, SPELL_IMPENDING_DESPAIR);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 13000);
|
||||
break;
|
||||
case EVENT_DEFILING_HORROR:
|
||||
DoCast(SPELL_DEFILING_HORROR);
|
||||
events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(25000,45000)); // TODO adjust timer.
|
||||
break;
|
||||
}
|
||||
|
||||
if ((uiHopelessnessCount < 1 && HealthBelowPct(66))
|
||||
|| (uiHopelessnessCount < 2 && HealthBelowPct(33))
|
||||
|| (uiHopelessnessCount < 3 && HealthBelowPct(10)))
|
||||
{
|
||||
uiHopelessnessCount++;
|
||||
DoCast(DUNGEON_MODE(SPELL_HOPELESSNESS,H_SPELL_HOPELESSNESS));
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_falric(Creature* pCreature)
|
||||
{
|
||||
return new boss_falricAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_falric()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name="boss_falric";
|
||||
newscript->GetAI = &GetAI_boss_falric;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
|
||||
* 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 "ScriptedPch.h"
|
||||
#include "halls_of_reflection.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = -1668060,
|
||||
SAY_SLAY_1 = -1668061,
|
||||
SAY_SLAY_2 = -1668062,
|
||||
SAY_DEATH = -1668063,
|
||||
SAY_CORRUPTED_FLESH_1 = -1668064,
|
||||
SAY_CORRUPTED_FLESH_2 = -1668065,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_OBLITERATE = 72360,
|
||||
SPELL_WELL_OF_CORRUPTION = 72362,
|
||||
SPELL_CORRUPTED_FLESH = 72363,
|
||||
SPELL_SHARED_SUFFERING = 72368,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
EVENT_OBLITERATE,
|
||||
EVENT_WELL_OF_CORRUPTION,
|
||||
EVENT_CORRUPTED_FLESH,
|
||||
EVENT_SHARED_SUFFERING,
|
||||
};
|
||||
|
||||
struct boss_marwynAI : public boss_horAI
|
||||
{
|
||||
boss_marwynAI(Creature *pCreature) : boss_horAI(pCreature) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
boss_horAI::Reset();
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MARWYN_EVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MARWYN_EVENT, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_OBLITERATE, 30000); // TODO Check timer
|
||||
events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
|
||||
events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
|
||||
events.ScheduleEvent(EVENT_SHARED_SUFFERING, 20000); // TODO Check timer
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MARWYN_EVENT, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_OBLITERATE:
|
||||
DoCast(SPELL_OBLITERATE);
|
||||
events.ScheduleEvent(EVENT_OBLITERATE, 30000);
|
||||
break;
|
||||
case EVENT_WELL_OF_CORRUPTION:
|
||||
DoCast(SPELL_WELL_OF_CORRUPTION);
|
||||
events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
|
||||
break;
|
||||
case EVENT_CORRUPTED_FLESH:
|
||||
DoScriptText(RAND(SAY_CORRUPTED_FLESH_1,SAY_CORRUPTED_FLESH_2), me);
|
||||
DoCast(SPELL_CORRUPTED_FLESH);
|
||||
events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
|
||||
break;
|
||||
case EVENT_SHARED_SUFFERING:
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(pTarget, SPELL_SHARED_SUFFERING);
|
||||
events.ScheduleEvent(EVENT_SHARED_SUFFERING, 20000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_marwyn(Creature* pCreature)
|
||||
{
|
||||
return new boss_marwynAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_marwyn()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name="boss_marwyn";
|
||||
newscript->GetAI = &GetAI_boss_marwyn;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,16 +16,141 @@
|
||||
|
||||
#ifndef DEF_HALLS_OF_REFLECTION_H
|
||||
#define DEF_HALLS_OF_REFLECTION_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_FALRIC_EVENT,
|
||||
DATA_MARWYN_EVENT,
|
||||
DATA_LICHKING_EVENT
|
||||
DATA_LICHKING_EVENT,
|
||||
DATA_WAVE_COUNT,
|
||||
DATA_TEAM_IN_INSTANCE,
|
||||
};
|
||||
|
||||
enum Data64
|
||||
{
|
||||
DATA_FALRIC,
|
||||
DATA_MARWYN,
|
||||
DATA_LICHKING,
|
||||
DATA_FROSTMOURNE,
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
CREATURE_FALRIC = 36494,
|
||||
CREATURE_MARWYN = 36476,
|
||||
CREATURE_LICHKING = 36658
|
||||
NPC_FALRIC = 38112,
|
||||
NPC_MARWYN = 38113,
|
||||
NPC_LICH_KING_EVENT = 37226,
|
||||
NPC_LICH_KING_BOSS = 36954,
|
||||
|
||||
NPC_UTHER = 37225,
|
||||
NPC_JAINA_PART1 = 37221,
|
||||
NPC_JAINA_PART2 = 36955,
|
||||
NPC_SYLVANAS_PART1 = 37223,
|
||||
NPC_SYLVANAS_PART2 = 37554,
|
||||
|
||||
NPC_WAVE_MERCENARY = 38177,
|
||||
NPC_WAVE_FOOTMAN = 38173,
|
||||
NPC_WAVE_RIFLEMAN = 38176,
|
||||
NPC_WAVE_PRIEST = 38175,
|
||||
NPC_WAVE_MAGE = 38172,
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_FROSTMOURNE = 202302,
|
||||
GO_FROSTMOURNE_ALTAR = 202236,
|
||||
GO_FRONT_DOOR = 201976,
|
||||
GO_ARTHAS_DOOR = 197341,
|
||||
};
|
||||
|
||||
enum HorWorldStates
|
||||
{
|
||||
WORLD_STATE_HOR = 4884,
|
||||
WORLD_STATE_HOR_WAVE_COUNT = 4882,
|
||||
};
|
||||
|
||||
// Common actions from Instance Script to Boss Script
|
||||
enum Actions
|
||||
{
|
||||
ACTION_ENTER_COMBAT,
|
||||
};
|
||||
|
||||
// Base class for FALRIC and MARWYN
|
||||
// handled the summonList and the notification events to/from the InstanceData
|
||||
struct boss_horAI : ScriptedAI
|
||||
{
|
||||
boss_horAI(Creature *pCreature) : ScriptedAI(pCreature), summons(pCreature)
|
||||
{
|
||||
pInstance = me->GetInstanceData();
|
||||
}
|
||||
|
||||
InstanceData* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
me->SetVisibility(VISIBILITY_OFF);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit *pWho, uint32 &uiDamage)
|
||||
{
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
|
||||
uiDamage = 0;
|
||||
}
|
||||
|
||||
void DoAction(const int32 actionID)
|
||||
{
|
||||
switch(actionID)
|
||||
{
|
||||
case ACTION_ENTER_COMBAT: // called by InstanceData when boss shall enter in combat.
|
||||
// Just in case. Should have been done by InstanceData
|
||||
me->SetVisibility(VISIBILITY_ON);
|
||||
|
||||
// Reset flags
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (Unit *pUnit = me->SelectNearestTarget())
|
||||
AttackStart(pUnit);
|
||||
|
||||
DoZoneInCombat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *pSummoned)
|
||||
{
|
||||
summons.Summon(pSummoned);
|
||||
|
||||
if (Unit *pUnit = pSummoned->SelectNearestTarget())
|
||||
{
|
||||
if (pSummoned->AI())
|
||||
pSummoned->AI()->AttackStart(pUnit);
|
||||
else
|
||||
{
|
||||
pSummoned->GetMotionMaster()->MoveChase(pUnit);
|
||||
pSummoned->Attack(pUnit, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (pSummoned->AI())
|
||||
pSummoned->AI()->DoZoneInCombat();
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature *pSummoned)
|
||||
{
|
||||
summons.Despawn(pSummoned);
|
||||
if (summons.empty())
|
||||
{
|
||||
if (pSummoned->isAlive())
|
||||
pInstance->SetData(DATA_WAVE_COUNT, NOT_STARTED);
|
||||
else
|
||||
pInstance->SetData(DATA_WAVE_COUNT, SPECIAL);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+293
-28
@@ -25,61 +25,212 @@
|
||||
2- The Lich King
|
||||
*/
|
||||
|
||||
enum eEnum
|
||||
{
|
||||
ENCOUNTER_WAVE_MERCENARY = 6,
|
||||
ENCOUNTER_WAVE_FOOTMAN = 10,
|
||||
ENCOUNTER_WAVE_RIFLEMAN = 6,
|
||||
ENCOUNTER_WAVE_PRIEST = 6,
|
||||
ENCOUNTER_WAVE_MAGE = 6,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
EVENT_NEXT_WAVE,
|
||||
EVENT_START_LICH_KING,
|
||||
};
|
||||
|
||||
static Position PriestSpawnPos[ENCOUNTER_WAVE_PRIEST] =
|
||||
{
|
||||
{5277.74,2016.88,707.778,5.96903},
|
||||
{5295.88,2040.34,707.778,5.07891},
|
||||
{5320.37,1980.13,707.778,2.00713},
|
||||
{5280.51,1997.84,707.778,0.296706},
|
||||
{5302.45,2042.22,707.778,4.90438},
|
||||
{5306.57,1977.47,707.778,1.50098},
|
||||
};
|
||||
|
||||
static Position MageSpawnPos[ENCOUNTER_WAVE_MAGE] =
|
||||
{
|
||||
{5312.75,2037.12,707.778,4.59022},
|
||||
{5309.58,2042.67,707.778,4.69494},
|
||||
{5275.08,2008.72,707.778,6.21337},
|
||||
{5279.65,2004.66,707.778,0.069813},
|
||||
{5275.48,2001.14,707.778,0.174533},
|
||||
{5316.7,2041.55,707.778,4.50295},
|
||||
};
|
||||
|
||||
static Position MercenarySpawnPos[ENCOUNTER_WAVE_MERCENARY] =
|
||||
{
|
||||
{5302.25,1972.41,707.778,1.37881},
|
||||
{5311.03,1972.23,707.778,1.64061},
|
||||
{5277.36,1993.23,707.778,0.401426},
|
||||
{5318.7,2036.11,707.778,4.2237},
|
||||
{5335.72,1996.86,707.778,2.74017},
|
||||
{5299.43,1979.01,707.778,1.23918},
|
||||
};
|
||||
|
||||
static Position FootmenSpawnPos[ENCOUNTER_WAVE_FOOTMAN] =
|
||||
{
|
||||
{5306.06,2037,707.778,4.81711},
|
||||
{5344.15,2007.17,707.778,3.15905},
|
||||
{5337.83,2010.06,707.778,3.22886},
|
||||
{5343.29,1999.38,707.778,2.9147},
|
||||
{5340.84,1992.46,707.778,2.75762},
|
||||
{5325.07,1977.6,707.778,2.07694},
|
||||
{5336.6,2017.28,707.778,3.47321},
|
||||
{5313.82,1978.15,707.778,1.74533},
|
||||
{5280.63,2012.16,707.778,6.05629},
|
||||
{5322.96,2040.29,707.778,4.34587},
|
||||
};
|
||||
|
||||
static Position RiflemanSpawnPos[ENCOUNTER_WAVE_RIFLEMAN] =
|
||||
{
|
||||
{5343.47,2015.95,707.778,3.49066},
|
||||
{5337.86,2003.4,707.778,2.98451},
|
||||
{5319.16,1974,707.778,1.91986},
|
||||
{5299.25,2036,707.778,5.02655},
|
||||
{5295.64,1973.76,707.778,1.18682},
|
||||
{5282.9,2019.6,707.778,5.88176},
|
||||
};
|
||||
|
||||
struct instance_halls_of_reflection : public ScriptedInstance
|
||||
{
|
||||
instance_halls_of_reflection(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
|
||||
instance_halls_of_reflection(Map* pMap) : ScriptedInstance(pMap) {};
|
||||
|
||||
uint64 uiFalric;
|
||||
uint64 uiMarwyn;
|
||||
uint64 uiLichKing;
|
||||
uint64 uiLichKingEvent;
|
||||
uint64 uiJainaPart1;
|
||||
uint64 uiSylvanasPart1;
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
uint64 uiFrostmourne;
|
||||
uint64 uiFrostmourneAltar;
|
||||
uint64 uiArthasDoor;
|
||||
uint64 uiFrontDoor;
|
||||
|
||||
uint32 uiEncounter[MAX_ENCOUNTER];
|
||||
uint32 uiTeamInInstance;
|
||||
uint32 uiWaveCount;
|
||||
bool bIntroDone;
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
events.Reset();
|
||||
|
||||
uiFalric = 0;
|
||||
uiMarwyn = 0;
|
||||
uiLichKing = 0;
|
||||
uiLichKingEvent = 0;
|
||||
uiJainaPart1 = 0;
|
||||
uiSylvanasPart1 = 0;
|
||||
|
||||
uiFrostmourne = 0;
|
||||
uiFrostmourneAltar = 0;
|
||||
uiArthasDoor = 0;
|
||||
uiFrontDoor = 0;
|
||||
uiTeamInInstance = 0;
|
||||
uiWaveCount = 0;
|
||||
bIntroDone = false;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
uiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
|
||||
void OnCreatureCreate(Creature* pCreature, bool add)
|
||||
{
|
||||
if (!add)
|
||||
return;
|
||||
|
||||
Map::PlayerList const &players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
if (Player* pPlayer = players.begin()->getSource())
|
||||
uiTeamInInstance = pPlayer->GetTeam();
|
||||
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case CREATURE_FALRIC:
|
||||
case NPC_FALRIC:
|
||||
uiFalric = pCreature->GetGUID();
|
||||
break;
|
||||
case CREATURE_MARWYN:
|
||||
case NPC_MARWYN:
|
||||
uiMarwyn = pCreature->GetGUID();
|
||||
break;
|
||||
case CREATURE_LICHKING:
|
||||
uiLichKing = pCreature->GetGUID();
|
||||
case NPC_LICH_KING_EVENT:
|
||||
uiLichKingEvent = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_JAINA_PART1:
|
||||
uiJainaPart1 = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_SYLVANAS_PART1:
|
||||
uiSylvanasPart1 = pCreature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo, bool add)
|
||||
{
|
||||
if (!add)
|
||||
return;
|
||||
|
||||
// TODO: init state depending on encounters
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case GO_FROSTMOURNE:
|
||||
uiFrostmourne = pGo->GetGUID();
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
|
||||
HandleGameObject(0, false, pGo);
|
||||
break;
|
||||
case GO_FROSTMOURNE_ALTAR:
|
||||
uiFrostmourneAltar = pGo->GetGUID();
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
|
||||
HandleGameObject(0, true, pGo);
|
||||
break;
|
||||
case GO_FRONT_DOOR:
|
||||
uiFrontDoor = pGo->GetGUID();
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
|
||||
HandleGameObject(0, true, pGo);
|
||||
break;
|
||||
case GO_ARTHAS_DOOR:
|
||||
uiArthasDoor = pGo->GetGUID();
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
|
||||
|
||||
if (uiEncounter[1] == DONE)
|
||||
HandleGameObject(0, true, pGo);
|
||||
else
|
||||
HandleGameObject(0, false, pGo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
if (type == DATA_WAVE_COUNT && data == SPECIAL)
|
||||
{
|
||||
bIntroDone = true;
|
||||
events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (uiWaveCount && data == NOT_STARTED)
|
||||
DoWipe();
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case DATA_FALRIC_EVENT:
|
||||
m_auiEncounter[0] = data;
|
||||
uiEncounter[0] = data;
|
||||
if (data == DONE)
|
||||
events.ScheduleEvent(EVENT_NEXT_WAVE, 60000);
|
||||
break;
|
||||
case DATA_MARWYN_EVENT:
|
||||
m_auiEncounter[1] = data;
|
||||
uiEncounter[1] = data;
|
||||
if (data == DONE)
|
||||
HandleGameObject(uiArthasDoor, true);
|
||||
break;
|
||||
case DATA_LICHKING_EVENT:
|
||||
m_auiEncounter[2] = data;
|
||||
uiEncounter[2] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -91,29 +242,35 @@ struct instance_halls_of_reflection : public ScriptedInstance
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_FALRIC_EVENT: return m_auiEncounter[0];
|
||||
case DATA_MARWYN_EVENT: return m_auiEncounter[1];
|
||||
case DATA_LICHKING_EVENT: return m_auiEncounter[2];
|
||||
case DATA_FALRIC_EVENT: return uiEncounter[0];
|
||||
case DATA_MARWYN_EVENT: return uiEncounter[1];
|
||||
case DATA_LICHKING_EVENT: return uiEncounter[2];
|
||||
case DATA_WAVE_COUNT: return uiWaveCount;
|
||||
case DATA_TEAM_IN_INSTANCE: return uiTeamInInstance;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
|
||||
uint64 GetData64(uint32 identifier)
|
||||
{
|
||||
switch(identifier)
|
||||
{
|
||||
case DATA_FALRIC: return uiFalric;
|
||||
case DATA_MARWYN: return uiMarwyn;
|
||||
case DATA_LICHKING: return uiLichKingEvent;
|
||||
case DATA_FROSTMOURNE: return uiFrostmourne;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "H R " << m_auiEncounter[0] << " " << m_auiEncounter[1] << m_auiEncounter[2];
|
||||
saveStream << "H R 1 " << uiEncounter[0] << " " << uiEncounter[1] << " " << uiEncounter[2];
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
@@ -130,25 +287,133 @@ struct instance_halls_of_reflection : public ScriptedInstance
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint16 version;
|
||||
uint16 data0, data1, data2;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
|
||||
loadStream >> dataHead1 >> dataHead2 >> version >> data0 >> data1 >> data2;
|
||||
|
||||
if (dataHead1 == 'H' && dataHead2 == 'R')
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
m_auiEncounter[1] = data1;
|
||||
m_auiEncounter[2] = data2;
|
||||
uiEncounter[0] = data0;
|
||||
uiEncounter[1] = data1;
|
||||
uiEncounter[2] = data2;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
if (uiEncounter[i] == IN_PROGRESS)
|
||||
uiEncounter[i] = NOT_STARTED;
|
||||
|
||||
} else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
if (uiEncounter[0] == DONE || uiEncounter[1] == DONE)
|
||||
bIntroDone = true;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
void AddWave()
|
||||
{
|
||||
DoUpdateWorldState(WORLD_STATE_HOR, 1);
|
||||
DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
|
||||
|
||||
switch(uiWaveCount)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if (Creature *pFalric = instance->GetCreature(uiFalric))
|
||||
SpawnWave(pFalric);
|
||||
break;
|
||||
case 5:
|
||||
if (GetData(DATA_FALRIC_EVENT) == DONE)
|
||||
events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
|
||||
else if (Creature *pFalric = instance->GetCreature(uiFalric))
|
||||
if (pFalric->AI())
|
||||
pFalric->AI()->DoAction(ACTION_ENTER_COMBAT);
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
if (Creature *pMarwyn = instance->GetCreature(uiMarwyn))
|
||||
SpawnWave(pMarwyn);
|
||||
break;
|
||||
case 10:
|
||||
if (GetData(DATA_MARWYN_EVENT) != DONE) // wave should not have been started if DONE. Check anyway to avoid bug exploit!
|
||||
if (Creature *pMarwyn = instance->GetCreature(uiMarwyn))
|
||||
if (pMarwyn->AI())
|
||||
pMarwyn->AI()->DoAction(ACTION_ENTER_COMBAT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe has been detected. Perform cleanup and reset.
|
||||
void DoWipe()
|
||||
{
|
||||
uiWaveCount = 0;
|
||||
events.Reset();
|
||||
DoUpdateWorldState(WORLD_STATE_HOR, 1);
|
||||
DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
|
||||
HandleGameObject(uiFrontDoor, true);
|
||||
|
||||
// TODO
|
||||
// in case of wipe, the event is normally restarted by jumping into the center of the room.
|
||||
// As I can't find a trigger area there, just respawn Jaina/Sylvanas so the event may be restarted.
|
||||
if (Creature* pJaina = instance->GetCreature(uiJainaPart1))
|
||||
pJaina->Respawn();
|
||||
if (Creature* pSylvanas = instance->GetCreature(uiSylvanasPart1))
|
||||
pSylvanas->Respawn();
|
||||
|
||||
if (Creature* pFalric = instance->GetCreature(uiFalric))
|
||||
pFalric->SetVisibility(VISIBILITY_OFF);
|
||||
if (Creature* pMarwyn = instance->GetCreature(uiMarwyn))
|
||||
pMarwyn->SetVisibility(VISIBILITY_OFF);
|
||||
}
|
||||
|
||||
// spawn a wave on behalf of the summoner.
|
||||
void SpawnWave(Creature *pSummoner)
|
||||
{
|
||||
uint32 index;
|
||||
|
||||
pSummoner->SetVisibility(VISIBILITY_ON);
|
||||
|
||||
// TODO: do composition at random. # of spawn also depends on uiWaveCount
|
||||
// As of now, it is just one of each.
|
||||
index = urand(0,ENCOUNTER_WAVE_MERCENARY-1);
|
||||
pSummoner->SummonCreature(NPC_WAVE_MERCENARY, MercenarySpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
||||
|
||||
index = urand(0,ENCOUNTER_WAVE_FOOTMAN-1);
|
||||
pSummoner->SummonCreature(NPC_WAVE_FOOTMAN, FootmenSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
||||
|
||||
index = urand(0,ENCOUNTER_WAVE_RIFLEMAN-1);
|
||||
pSummoner->SummonCreature(NPC_WAVE_RIFLEMAN, RiflemanSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
||||
|
||||
index = urand(0,ENCOUNTER_WAVE_PRIEST-1);
|
||||
pSummoner->SummonCreature(NPC_WAVE_PRIEST, PriestSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
||||
|
||||
index = urand(0,ENCOUNTER_WAVE_MAGE-1);
|
||||
pSummoner->SummonCreature(NPC_WAVE_MAGE, MageSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
if (!instance->HavePlayers())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
switch(uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_NEXT_WAVE:
|
||||
uiWaveCount++;
|
||||
AddWave();
|
||||
break;
|
||||
case EVENT_START_LICH_KING:
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InstanceData* GetInstanceData_instance_halls_of_reflection(Map* pMap)
|
||||
@@ -156,7 +421,7 @@ InstanceData* GetInstanceData_instance_halls_of_reflection(Map* pMap)
|
||||
return new instance_halls_of_reflection(pMap);
|
||||
}
|
||||
|
||||
void AddSC_halls_of_reflection()
|
||||
void AddSC_instance_halls_of_reflection()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
|
||||
Reference in New Issue
Block a user