aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/Management/VMapFactory.cpp92
-rw-r--r--src/server/collision/Management/VMapFactory.h3
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp2
-rw-r--r--src/server/game/Conditions/ConditionMgr.h5
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp2
-rw-r--r--src/server/game/Conditions/DisableMgr.h4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp14
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp7
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/World/World.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp102
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp129
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp297
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/zulaman.h48
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp476
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h9
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp143
-rw-r--r--src/server/worldserver/worldserver.conf.dist9
18 files changed, 832 insertions, 518 deletions
diff --git a/src/server/collision/Management/VMapFactory.cpp b/src/server/collision/Management/VMapFactory.cpp
index 428ef320f5d..4d3719cf288 100644
--- a/src/server/collision/Management/VMapFactory.cpp
+++ b/src/server/collision/Management/VMapFactory.cpp
@@ -16,99 +16,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/types.h>
#include "VMapFactory.h"
#include "VMapManager2.h"
-#include "G3D/Table.h"
-
-using namespace G3D;
namespace VMAP
{
- void chompAndTrim(std::string& str)
- {
- while (str.length() >0)
- {
- char lc = str[str.length()-1];
- if (lc == '\r' || lc == '\n' || lc == ' ' || lc == '"' || lc == '\'')
- {
- str = str.substr(0, str.length()-1);
- }
- else
- {
- break;
- }
- }
- while (str.length() >0)
- {
- char lc = str[0];
- if (lc == ' ' || lc == '"' || lc == '\'')
- {
- str = str.substr(1, str.length()-1);
- }
- else
- {
- break;
- }
- }
- }
-
- IVMapManager* gVMapManager = 0;
- Table<unsigned int, bool>* iIgnoreSpellIds=0;
-
- //===============================================
- // result false, if no more id are found
-
- bool getNextId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId)
- {
- bool result = false;
- unsigned int i;
- for (i=pStartPos;i<pString.size(); ++i)
- {
- if (pString[i] == ',')
- {
- break;
- }
- }
- if (i>pStartPos)
- {
- std::string idString = pString.substr(pStartPos, i-pStartPos);
- pStartPos = i+1;
- chompAndTrim(idString);
- pId = atoi(idString.c_str());
- result = true;
- }
- return(result);
- }
-
- //===============================================
- /**
- parameter: String of map ids. Delimiter = ","
- */
-
- void VMapFactory::preventSpellsFromBeingTestedForLoS(const char* pSpellIdString)
- {
- if (!iIgnoreSpellIds)
- iIgnoreSpellIds = new Table<unsigned int, bool>();
- if (pSpellIdString != NULL)
- {
- unsigned int pos =0;
- unsigned int id;
- std::string confString(pSpellIdString);
- chompAndTrim(confString);
- while (getNextId(confString, pos, id))
- {
- iIgnoreSpellIds->set(id, true);
- }
- }
- }
-
- //===============================================
-
- bool VMapFactory::checkSpellForLoS(unsigned int pSpellId)
- {
- return(!iIgnoreSpellIds->containsKey(pSpellId));
- }
+ IVMapManager* gVMapManager = NULL;
//===============================================
// just return the instance
@@ -123,9 +36,6 @@ namespace VMAP
// delete all internal data structures
void VMapFactory::clear()
{
- delete iIgnoreSpellIds;
- iIgnoreSpellIds = NULL;
-
delete gVMapManager;
gVMapManager = NULL;
}
diff --git a/src/server/collision/Management/VMapFactory.h b/src/server/collision/Management/VMapFactory.h
index 05fdc193c74..1545a8f6977 100644
--- a/src/server/collision/Management/VMapFactory.h
+++ b/src/server/collision/Management/VMapFactory.h
@@ -34,9 +34,6 @@ namespace VMAP
public:
static IVMapManager* createOrGetVMapManager();
static void clear();
-
- static void preventSpellsFromBeingTestedForLoS(const char* pSpellIdString);
- static bool checkSpellForLoS(unsigned int pSpellId);
};
}
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 88d20307d86..1ef035d8f87 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -489,6 +489,7 @@ uint32 Condition::GetMaxAvailableConditionTargets()
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:
case CONDITION_SOURCE_TYPE_NPC_VENDOR:
+ case CONDITION_SOURCE_TYPE_SPELL_PROC:
return 2;
default:
return 1;
@@ -1427,6 +1428,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
break;
}
case CONDITION_SOURCE_TYPE_SPELL:
+ case CONDITION_SOURCE_TYPE_SPELL_PROC:
{
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry);
if (!spellProto)
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 8826c7cc484..cd3cf7bbbd8 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -128,8 +128,9 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21,
CONDITION_SOURCE_TYPE_SMART_EVENT = 22,
CONDITION_SOURCE_TYPE_NPC_VENDOR = 23,
- CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 24,
- CONDITION_SOURCE_TYPE_MAX = 25 // MAX
+ CONDITION_SOURCE_TYPE_SPELL_PROC = 24,
+ CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 25,
+ CONDITION_SOURCE_TYPE_MAX = 26 // MAX
};
enum ComparisionType
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index 8cd36827ab9..fefb51323c4 100644
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -310,6 +310,8 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
}
else if (spellFlags & SPELL_DISABLE_DEPRECATED_SPELL) // call not from spellcast
return true;
+ else if (flags & SPELL_DISABLE_LOS)
+ return spellFlags & SPELL_DISABLE_LOS;
break;
}
diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h
index e84f3347df8..89761931048 100644
--- a/src/server/game/Conditions/DisableMgr.h
+++ b/src/server/game/Conditions/DisableMgr.h
@@ -42,8 +42,10 @@ enum SpellDisableTypes
SPELL_DISABLE_DEPRECATED_SPELL = 0x8,
SPELL_DISABLE_MAP = 0x10,
SPELL_DISABLE_AREA = 0x20,
+ SPELL_DISABLE_LOS = 0x40,
MAX_SPELL_DISABLE_TYPE = ( SPELL_DISABLE_PLAYER | SPELL_DISABLE_CREATURE | SPELL_DISABLE_PET |
- SPELL_DISABLE_DEPRECATED_SPELL | SPELL_DISABLE_MAP | SPELL_DISABLE_AREA)
+ SPELL_DISABLE_DEPRECATED_SPELL | SPELL_DISABLE_MAP | SPELL_DISABLE_AREA |
+ SPELL_DISABLE_LOS)
};
enum VmapDisableTypes
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index c2d98a412b7..155ce911a65 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -11459,7 +11459,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
if (GetTypeId() == TYPEID_UNIT)
{
Unit* pOwner = GetCharmerOrOwner();
- if (isPet() && !isInCombat() && pOwner) // Must check for owner or crash on "Tame Beast"
+ if ((isPet() || isGuardian()) && !isInCombat() && pOwner) // Must check for owner or crash on "Tame Beast"
{
// For every yard over 5, increase speed by 0.01
// to help prevent pet from lagging behind and despawning
@@ -13518,6 +13518,12 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
}
}
+ Unit* actor = isVictim ? target : this;
+ Unit* actionTarget = !isVictim ? target : this;
+
+ DamageInfo damageInfo = DamageInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE);
+ ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, NULL, &damageInfo, NULL /*HealInfo*/);
+
ProcTriggeredList procTriggered;
// Fill procTriggered list
for (AuraApplicationMap::const_iterator itr = GetAppliedAuras().begin(); itr!= GetAppliedAuras().end(); ++itr)
@@ -13541,6 +13547,12 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (!IsTriggeredAtSpellProcEvent(target, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, active, triggerData.spellProcEvent))
continue;
+ // do checks using conditions table
+ ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id);
+ ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
+ if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
+ continue;
+
// Triggered spells not triggering additional spells
bool triggered = !(spellProto->AttributesEx3 & SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ?
(procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 77059b794ff..764ec68bbcc 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1702,8 +1702,13 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI
if (!sSpellMgr->CanSpellTriggerProcOnEvent(*procEntry, eventInfo))
return false;
+ // do checks using conditions table
+ ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetSpellInfo()->Id);
+ ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
+ if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
+ return false;
+
// TODO:
- // - do checks using conditions table for eventInfo->GetActor() and eventInfo->GetActionTarget()
// - add DoCheckProc() AuraScript hook
// to allow additional requirements for procs
// this is needed because this is the last moment in which you can prevent aura charge drop on proc
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 6f29caeeee4..abfda74d555 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4944,7 +4944,7 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_NOT_INFRONT;
if (m_caster->GetEntry() != WORLD_TRIGGER) // Ignore LOS for gameobjects casts (wrongly casted by a trigger)
- if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
+ if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOSInMap(target))
return SPELL_FAILED_LINE_OF_SIGHT;
}
}
@@ -4955,7 +4955,7 @@ SpellCastResult Spell::CheckCast(bool strict)
float x, y, z;
m_targets.GetDstPos()->GetPosition(x, y, z);
- if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOS(x, y, z))
+ if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z))
return SPELL_FAILED_LINE_OF_SIGHT;
}
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 39ff431161f..d291d1d2fe9 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1164,15 +1164,13 @@ void World::LoadConfigSettings(bool reload)
bool enableLOS = ConfigMgr::GetBoolDefault("vmap.enableLOS", true);
bool enableHeight = ConfigMgr::GetBoolDefault("vmap.enableHeight", true);
bool enablePetLOS = ConfigMgr::GetBoolDefault("vmap.petLOS", true);
- std::string ignoreSpellIds = ConfigMgr::GetStringDefault("vmap.ignoreSpellIds", "");
if (!enableHeight)
sLog->outError(LOG_FILTER_SERVER_LOADING, "VMap height checking disabled! Creatures movements and other various things WILL be broken! Expect no support.");
VMAP::VMapFactory::createOrGetVMapManager()->setEnableLineOfSightCalc(enableLOS);
VMAP::VMapFactory::createOrGetVMapManager()->setEnableHeightCalc(enableHeight);
- VMAP::VMapFactory::preventSpellsFromBeingTestedForLoS(ignoreSpellIds.c_str());
- sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap support included. LineOfSight:%i, getHeight:%i, indoorCheck:%i PetLOS:%i", enableLOS, enableHeight, enableIndoor, enablePetLOS);
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap support included. LineOfSight: %i, getHeight: %i, indoorCheck: %i PetLOS: %i", enableLOS, enableHeight, enableIndoor, enablePetLOS);
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap data directory is: %svmaps", m_dataPath.c_str());
m_int_configs[CONFIG_MAX_WHO] = ConfigMgr::GetIntDefault("MaxWhoListReturns", 49);
diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
index 091c9fd1f91..15c7a10a125 100644
--- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
+++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
@@ -33,12 +33,10 @@ enum Spells
SPELL_WING_FLAP = 12882,
SPELL_PIERCE_ARMOR = 6016,
SPELL_DISARM = 8379,
-
SPELL_KIRTONOS_TRANSFORM = 16467,
-
SPELL_SHADOW_BOLT = 17228,
SPELL_CURSE_OF_TONGUES = 12889,
- SPELL_DONINATE_MIND = 14515
+ SPELL_DOMINATE_MIND = 14515
};
enum Events
@@ -55,37 +53,15 @@ enum Events
EVENT_DISARM = 10,
EVENT_SHADOW_BOLT = 11,
EVENT_CURSE_OF_TONGUES = 12,
- EVENT_DONINATE_MIND = 13,
+ EVENT_DOMINATE_MIND = 13,
EVENT_KIRTONOS_TRANSFORM = 14
};
-enum Points
-{
- MAX_KIRTONOS_WAYPOINTS_INTRO = 14,
- POINT_KIRTONOS_LAND = 14
-};
-
enum Misc
{
- WEAPON_KIRTONOS_STAFF = 11365
-};
-
-Position const kirtonosIntroWaypoint[MAX_KIRTONOS_WAYPOINTS_INTRO] =
-{
- {316.7087f, 71.26834f, 104.5843f, 0.0f},
- {321.1605f, 72.80973f, 104.6676f, 0.0f},
- {332.3713f, 77.98991f, 105.8621f, 0.0f},
- {333.3254f, 86.60159f, 106.6399f, 0.0f},
- {334.1263f, 101.6836f, 106.8343f, 0.0f},
- {331.0458f, 114.5935f, 106.3621f, 0.0f},
- {329.5439f, 126.7019f, 106.1399f, 0.0f},
- {335.2471f, 136.5460f, 105.7232f, 0.0f},
- {343.2100f, 139.9459f, 107.6399f, 0.0f},
- {364.3288f, 140.9012f, 109.9454f, 0.0f},
- {362.6760f, 115.6384f, 110.3065f, 0.0f},
- {341.7896f, 91.94390f, 107.1676f, 0.0f},
- {313.4945f, 93.45945f, 104.0565f, 0.0f},
- {306.3839f, 93.61675f, 104.0565f, 0.0f},
+ WEAPON_KIRTONOS_STAFF = 11365,
+ POINT_KIRTONOS_LAND = 13,
+ KIRTONOS_PATH = 105061
};
class boss_kirtonos_the_herald : public CreatureScript
@@ -113,7 +89,7 @@ class boss_kirtonos_the_herald : public CreatureScript
events.ScheduleEvent(EVENT_DISARM, urand(22000, 22000));
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(42000, 42000));
events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, urand(53000, 53000));
- events.ScheduleEvent(EVENT_DONINATE_MIND, urand(34000, 48000));
+ events.ScheduleEvent(EVENT_DOMINATE_MIND, urand(34000, 48000));
events.ScheduleEvent(EVENT_KIRTONOS_TRANSFORM, urand(20000, 20000));
_EnterCombat();
}
@@ -142,12 +118,7 @@ class boss_kirtonos_the_herald : public CreatureScript
me->DespawnOrUnsummon(5000);
}
- void DamageTaken(Unit* /*killer*/, uint32 &damage)
- {
-
- }
-
- void IsSummonedBy(Unit* summoner)
+ void IsSummonedBy(Unit* /*summoner*/)
{
me->SetDisableGravity(true);
me->SetReactState(REACT_PASSIVE);
@@ -163,12 +134,13 @@ class boss_kirtonos_the_herald : public CreatureScript
BossAI::JustSummoned(summon);
}
- void MovementInform(uint32 movementType, uint32 pointId)
+ void MovementInform(uint32 type, uint32 id)
{
- if (movementType != POINT_MOTION_TYPE)
- return;
-
- _currentPoint = pointId + 1;
+ if (type == WAYPOINT_MOTION_TYPE && id == POINT_KIRTONOS_LAND)
+ {
+ _introTimer = 1500;
+ _introEvent = INTRO_2;
+ }
}
void UpdateAI(uint32 const diff)
@@ -180,13 +152,8 @@ class boss_kirtonos_the_herald : public CreatureScript
switch (_introEvent)
{
case INTRO_1:
- if (_currentPoint < POINT_KIRTONOS_LAND)
- me->GetMotionMaster()->MovePoint(_currentPoint, kirtonosIntroWaypoint[_currentPoint]);
- else
- {
- _introTimer = 1000;
- _introEvent = INTRO_2;
- }
+ me->GetMotionMaster()->MovePath(KIRTONOS_PATH,false);
+ _introEvent = 0;
break;
case INTRO_2:
me->SetWalk(true);
@@ -204,6 +171,7 @@ class boss_kirtonos_the_herald : public CreatureScript
case INTRO_4:
if (GameObject* brazier = me->GetMap()->GetGameObject(instance->GetData64(GO_BRAZIER_OF_THE_HERALD)))
brazier->SetGoState(GO_STATE_READY);
+ me->SetWalk(true);
me->SetDisableGravity(false);
DoCast(me, SPELL_KIRTONOS_TRANSFORM);
_introTimer = 1000;
@@ -227,7 +195,7 @@ class boss_kirtonos_the_herald : public CreatureScript
_introTimer -= diff;
}
- if (!UpdateVictim())
+ if (!UpdateVictim())
return;
events.Update(diff);
@@ -241,31 +209,31 @@ class boss_kirtonos_the_herald : public CreatureScript
{
case EVENT_SWOOP:
DoCast(me, SPELL_SWOOP);
- events.ScheduleEvent(EVENT_SWOOP, urand(15000, 15000));
+ events.ScheduleEvent(EVENT_SWOOP, 15000);
break;
case EVENT_WING_FLAP:
DoCast(me, SPELL_WING_FLAP);
- events.ScheduleEvent(EVENT_WING_FLAP, urand(13000, 13000));
+ events.ScheduleEvent(EVENT_WING_FLAP, 13000);
break;
case EVENT_PIERCE_ARMOR:
DoCastVictim(SPELL_PIERCE_ARMOR, true);
- events.ScheduleEvent(EVENT_PIERCE_ARMOR, urand(12000, 12000));
+ events.ScheduleEvent(EVENT_PIERCE_ARMOR, 12000);
break;
case EVENT_DISARM:
DoCastVictim(SPELL_DISARM, true);
- events.ScheduleEvent(EVENT_DISARM, urand(11000, 11000));
+ events.ScheduleEvent(EVENT_DISARM, 11000);
break;
case EVENT_SHADOW_BOLT:
DoCastVictim(SPELL_SHADOW_BOLT, true);
- events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(42000, 42000));
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 42000);
break;
case EVENT_CURSE_OF_TONGUES:
DoCastVictim(SPELL_CURSE_OF_TONGUES, true);
- events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, urand(35000, 35000));
+ events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, 35000);
break;
- case EVENT_DONINATE_MIND:
- DoCastVictim(SPELL_DONINATE_MIND, true);
- events.ScheduleEvent(EVENT_DONINATE_MIND, urand(44000, 48000));
+ case EVENT_DOMINATE_MIND:
+ DoCastVictim(SPELL_DOMINATE_MIND, true);
+ events.ScheduleEvent(EVENT_DOMINATE_MIND, urand(44000, 48000));
break;
case EVENT_KIRTONOS_TRANSFORM:
if (me->HasAura(SPELL_KIRTONOS_TRANSFORM))
@@ -312,16 +280,16 @@ enum Brazier_Of_The_Herald
class go_brazier_of_the_herald : public GameObjectScript
{
-public:
- go_brazier_of_the_herald() : GameObjectScript("go_brazier_of_the_herald") { }
+ public:
+ go_brazier_of_the_herald() : GameObjectScript("go_brazier_of_the_herald") { }
- bool OnGossipHello(Player* player, GameObject* go)
- {
- go->UseDoorOrButton();
- go->PlayDirectSound(SOUND_SCREECH,0);
- player->SummonCreature(NPC_KIRTONOS, 315.028f, 70.53845f, 102.1496f, 0.3859715f, TEMPSUMMON_DEAD_DESPAWN, 900000);
- return true;
- }
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ go->UseDoorOrButton();
+ go->PlayDirectSound(SOUND_SCREECH, 0);
+ player->SummonCreature(NPC_KIRTONOS, 315.028f, 70.53845f, 102.1496f, 0.3859715f, TEMPSUMMON_DEAD_DESPAWN, 900000);
+ return true;
+ }
};
void AddSC_boss_kirtonos_the_herald()
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
index 372811b8a8c..80f38dbd7cf 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
@@ -29,13 +29,14 @@ EndScriptData */
#include "Player.h"
#include "TemporarySummon.h"
-#define MAX_ENCOUNTER 6
-#define RAND_VENDOR 2
+enum Misc
+{
+ MAX_ENCOUNTER = 7,
+ RAND_VENDOR = 2,
+ WORLDSTATE_SHOW_TIMER = 3104,
+ WORLDSTATE_TIME_TO_SACRIFICE = 3106
+};
-//187021 //Harkor's Satchel
-//186648 //Tanzar's Trunk
-//186672 //Ashli's Bag
-//186667 //Kraz's Package
// Chests spawn at bear/eagle/dragonhawk/lynx bosses
// The loots depend on how many bosses have been killed, but not the entries of the chests
// But we cannot add loots to gameobject, so we have to use the fixed loot_template
@@ -51,9 +52,10 @@ static SHostageInfo HostageInfo[] =
{23999, 187021, 400, 1414, 74.36f, 3.3f}, // eagle
{24001, 186672, -35, 1134, 18.71f, 1.9f}, // dragonhawk
{24024, 186667, 413, 1117, 6.32f, 3.1f} // lynx
-
};
+Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f};
+
class instance_zulaman : public InstanceMapScript
{
public:
@@ -70,9 +72,11 @@ class instance_zulaman : public InstanceMapScript
uint64 TanzarsTrunkGUID;
uint64 AshlisBagGUID;
uint64 KrazsPackageGUID;
+ uint64 StrangeGongGUID;
uint64 HexLordGateGUID;
uint64 ZulJinGateGUID;
+ uint64 MassiveGateGUID;
uint64 AkilzonDoorGUID;
uint64 ZulJinDoorGUID;
uint64 HalazziDoorGUID;
@@ -93,20 +97,24 @@ class instance_zulaman : public InstanceMapScript
TanzarsTrunkGUID = 0;
AshlisBagGUID = 0;
KrazsPackageGUID = 0;
-
+ StrangeGongGUID = 0;
HexLordGateGUID = 0;
ZulJinGateGUID = 0;
+ MassiveGateGUID = 0;
AkilzonDoorGUID = 0;
HalazziDoorGUID = 0;
ZulJinDoorGUID = 0;
QuestTimer = 0;
- QuestMinute = 21;
+ QuestMinute = 0;
BossKilled = 0;
ChestLooted = 0;
for (uint8 i = 0; i < RAND_VENDOR; ++i)
RandVendor[i] = NOT_STARTED;
+
+ m_auiEncounter[DATA_GONGEVENT] = NOT_STARTED;
+ instance->SummonCreature(NPC_HARRISON_JONES, HarrisonJonesLoc);
}
bool IsEncounterInProgress() const
@@ -122,11 +130,11 @@ class instance_zulaman : public InstanceMapScript
{
switch (creature->GetEntry())
{
- case 23578://janalai
- case 23863://zuljin
- case 24239://hexlord
- case 23577://halazzi
- case 23576://nalorakk
+ case NPC_JANALAI:
+ case NPC_ZULJIN:
+ case NPC_HEXLORD:
+ case NPC_HALAZZI:
+ case NPC_NALORAKK:
default: break;
}
}
@@ -135,18 +143,19 @@ class instance_zulaman : public InstanceMapScript
{
switch (go->GetEntry())
{
- case 186303: HalazziDoorGUID = go->GetGUID(); break;
- case 186304: ZulJinGateGUID = go->GetGUID(); break;
- case 186305: HexLordGateGUID = go->GetGUID(); break;
- case 186858: AkilzonDoorGUID = go->GetGUID(); break;
- case 186859: ZulJinDoorGUID = go->GetGUID(); break;
-
- case 187021: HarkorsSatchelGUID = go->GetGUID(); break;
- case 186648: TanzarsTrunkGUID = go->GetGUID(); break;
- case 186672: AshlisBagGUID = go->GetGUID(); break;
- case 186667: KrazsPackageGUID = go->GetGUID(); break;
+ case GO_DOOR_HALAZZI: HalazziDoorGUID = go->GetGUID(); break;
+ case GO_GATE_ZULJIN: ZulJinGateGUID = go->GetGUID(); break;
+ case GO_GATE_HEXLORD: HexLordGateGUID = go->GetGUID(); break;
+ case GO_MASSIVE_GATE: MassiveGateGUID = go->GetGUID(); break;
+ case GO_DOOR_AKILZON: AkilzonDoorGUID = go->GetGUID(); break;
+ case GO_DOOR_ZULJIN: ZulJinDoorGUID = go->GetGUID(); break;
+
+ case GO_HARKORS_SATCHEL: HarkorsSatchelGUID = go->GetGUID(); break;
+ case GO_TANZARS_TRUNK: TanzarsTrunkGUID = go->GetGUID(); break;
+ case GO_ASHLIS_BAG: AshlisBagGUID = go->GetGUID(); break;
+ case GO_KRAZS_PACKAGE: KrazsPackageGUID = go->GetGUID(); break;
+ case GO_STRANGE_GONG: StrangeGongGUID = go->GetGUID(); break;
default: break;
-
}
CheckInstanceStatus();
}
@@ -173,10 +182,13 @@ class instance_zulaman : public InstanceMapScript
void CheckInstanceStatus()
{
- if (BossKilled >= 4)
+ if (m_auiEncounter[DATA_GONGEVENT] == DONE)
+ HandleGameObject(MassiveGateGUID, true);
+
+ if (BossKilled >= DATA_HALAZZIEVENT)
HandleGameObject(HexLordGateGUID, true);
- if (BossKilled >= 5)
+ if (BossKilled >= DATA_HEXLORDEVENT)
HandleGameObject(ZulJinGateGUID, true);
}
@@ -214,49 +226,57 @@ class instance_zulaman : public InstanceMapScript
{
switch (type)
{
+ case DATA_GONGEVENT:
+ m_auiEncounter[DATA_GONGEVENT] = data;
+ if (data == SPECIAL)
+ SaveToDB();
+ if (data == DONE)
+ QuestMinute = 21;
+ break;
case DATA_NALORAKKEVENT:
- m_auiEncounter[0] = data;
+ m_auiEncounter[DATA_NALORAKKEVENT] = data;
if (data == DONE)
{
if (QuestMinute)
{
QuestMinute += 15;
- DoUpdateWorldState(3106, QuestMinute);
+ DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
}
SummonHostage(0);
}
break;
case DATA_AKILZONEVENT:
- m_auiEncounter[1] = data;
+ m_auiEncounter[DATA_AKILZONEVENT] = data;
HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS);
if (data == DONE)
{
if (QuestMinute)
{
QuestMinute += 10;
- DoUpdateWorldState(3106, QuestMinute);
+ DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
}
SummonHostage(1);
}
break;
case DATA_JANALAIEVENT:
- m_auiEncounter[2] = data;
- if (data == DONE) SummonHostage(2);
+ m_auiEncounter[DATA_JANALAIEVENT] = data;
+ if (data == DONE)
+ SummonHostage(2);
break;
case DATA_HALAZZIEVENT:
- m_auiEncounter[3] = data;
+ m_auiEncounter[DATA_HALAZZIEVENT] = data;
HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS);
if (data == DONE) SummonHostage(3);
break;
case DATA_HEXLORDEVENT:
- m_auiEncounter[4] = data;
+ m_auiEncounter[DATA_HEXLORDEVENT] = data;
if (data == IN_PROGRESS)
HandleGameObject(HexLordGateGUID, false);
else if (data == NOT_STARTED)
CheckInstanceStatus();
break;
case DATA_ZULJINEVENT:
- m_auiEncounter[5] = data;
+ m_auiEncounter[DATA_ZULJINEVENT] = data;
HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS);
break;
case DATA_CHESTLOOTED:
@@ -274,10 +294,10 @@ class instance_zulaman : public InstanceMapScript
if (data == DONE)
{
++BossKilled;
- if (QuestMinute && BossKilled >= 4)
+ if (QuestMinute && BossKilled >= DATA_HALAZZIEVENT)
{
QuestMinute = 0;
- DoUpdateWorldState(3104, 0);
+ DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0);
}
CheckInstanceStatus();
SaveToDB();
@@ -288,12 +308,13 @@ class instance_zulaman : public InstanceMapScript
{
switch (type)
{
- case DATA_NALORAKKEVENT: return m_auiEncounter[0];
- case DATA_AKILZONEVENT: return m_auiEncounter[1];
- case DATA_JANALAIEVENT: return m_auiEncounter[2];
- case DATA_HALAZZIEVENT: return m_auiEncounter[3];
- case DATA_HEXLORDEVENT: return m_auiEncounter[4];
- case DATA_ZULJINEVENT: return m_auiEncounter[5];
+ case DATA_GONGEVENT: return m_auiEncounter[DATA_GONGEVENT];
+ case DATA_NALORAKKEVENT: return m_auiEncounter[DATA_NALORAKKEVENT];
+ case DATA_AKILZONEVENT: return m_auiEncounter[DATA_AKILZONEVENT];
+ case DATA_JANALAIEVENT: return m_auiEncounter[DATA_JANALAIEVENT];
+ case DATA_HALAZZIEVENT: return m_auiEncounter[DATA_HALAZZIEVENT];
+ case DATA_HEXLORDEVENT: return m_auiEncounter[DATA_HEXLORDEVENT];
+ case DATA_ZULJINEVENT: return m_auiEncounter[DATA_ZULJINEVENT];
case DATA_CHESTLOOTED: return ChestLooted;
case TYPE_RAND_VENDOR_1: return RandVendor[0];
case TYPE_RAND_VENDOR_2: return RandVendor[1];
@@ -312,13 +333,27 @@ class instance_zulaman : public InstanceMapScript
QuestTimer += 60000;
if (QuestMinute)
{
- DoUpdateWorldState(3104, 1);
- DoUpdateWorldState(3106, QuestMinute);
- } else DoUpdateWorldState(3104, 0);
+ DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1);
+ DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
+ } else DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0);
}
QuestTimer -= diff;
}
}
+
+ uint64 GetData64(uint32 type) const
+ {
+ switch (type)
+ {
+ case GO_STRANGE_GONG:
+ return StrangeGongGUID;
+ case GO_MASSIVE_GATE:
+ return MassiveGateGUID;
+ }
+
+ return 0;
+ }
+
};
InstanceScript* GetInstanceScript(InstanceMap* map) const
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
index 660f144c2dd..d140c349a4b 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
@@ -33,6 +33,7 @@ EndContentData */
#include "zulaman.h"
#include "Player.h"
#include "SpellInfo.h"
+#include "SpellScript.h"
/*######
## npc_forest_frog
@@ -199,9 +200,303 @@ class npc_zulaman_hostage : public CreatureScript
}
};
+/*######
+## npc_harrison_jones
+######*/
+
+enum Says
+{
+ SAY_HARRISON_0 = 0,
+ SAY_HARRISON_1 = 1,
+ SAY_HARRISON_2 = 0,
+ SAY_HARRISON_3 = 1
+};
+
+enum Spells
+{
+ SPELL_BANGING_THE_GONG = 45225,
+ SPELL_STEALTH = 34189,
+ SPELL_COSMETIC_SPEAR_THROW = 43647
+};
+
+enum Events
+{
+ GONG_EVENT_1 = 1,
+ GONG_EVENT_2 = 2,
+ GONG_EVENT_3 = 3,
+ GONG_EVENT_4 = 4,
+ GONG_EVENT_5 = 5,
+ GONG_EVENT_6 = 6,
+ GONG_EVENT_7 = 7,
+ GONG_EVENT_8 = 8,
+ GONG_EVENT_9 = 9,
+ GONG_EVENT_10 = 10,
+ GONG_EVENT_11 = 11,
+ GONG_EVENT_12 = 12
+};
+
+enum Waypoints
+{
+ HARRISON_MOVE_1 = 860440,
+ HARRISON_MOVE_2 = 860441,
+ HARRISON_MOVE_3 = 860442
+};
+
+enum DisplayIds
+{
+ MODEL_HARRISON_JONES_0 = 22340,
+ MODEL_HARRISON_JONES_1 = 22354,
+ MODEL_HARRISON_JONES_2 = 22347
+};
+
+enum EntryIds
+{
+ NPC_HARRISON_JONES_1 = 24375,
+ NPC_HARRISON_JONES_2 = 24365,
+ NPC_AMANISHI_GUARDIAN = 23597,
+};
+
+enum Weapons
+{
+ WEAPON_MACE = 5301,
+ WEAPON_SPEAR = 13631
+};
+
+Position const AmanishiGuardianLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f};
+
+class npc_harrison_jones : public CreatureScript
+{
+ public:
+
+ npc_harrison_jones()
+ : CreatureScript("npc_harrison_jones")
+ {
+ }
+
+ struct npc_harrison_jonesAI : public ScriptedAI
+ {
+ npc_harrison_jonesAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ InstanceScript* instance;
+
+ uint8 _gongEvent;
+ uint32 _gongTimer;
+ uint64 uiTargetGUID;
+
+ void Reset()
+ {
+ _gongEvent = 0;
+ _gongTimer = 0;
+ uiTargetGUID = 0;
+ }
+
+ void EnterCombat(Unit* /*who*/) {}
+
+ void sGossipSelect(Player* player, uint32 sender, uint32 action)
+ {
+ if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ me->SetInFront(player);
+ me->SendMovementFlagUpdate(true);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Talk(SAY_HARRISON_0);
+ instance->SetData(DATA_GONGEVENT, IN_PROGRESS);
+ _gongEvent = GONG_EVENT_1;
+ _gongTimer = 4000;
+ }
+ }
+
+ void SpellHit(Unit*, const SpellInfo* spell)
+ {
+ if (spell->Id == SPELL_COSMETIC_SPEAR_THROW)
+ {
+ me->RemoveAllAuras();
+ me->SetEntry(NPC_HARRISON_JONES_2);
+ me->SetDisplayId(MODEL_HARRISON_JONES_2);
+ me->SetTarget(0);
+ me->SetByteValue(UNIT_FIELD_BYTES_1,0,UNIT_STAND_STATE_DEAD);
+ me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+ if (instance)
+ instance->SetData(DATA_GONGEVENT, DONE);
+ }
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (_gongEvent)
+ {
+ if (_gongTimer <= diff)
+ {
+ switch (_gongEvent)
+ {
+ case GONG_EVENT_1:
+ me->GetMotionMaster()->MovePath(HARRISON_MOVE_1,false);
+ _gongTimer = 12000;
+ _gongEvent = GONG_EVENT_2;
+ break;
+ case GONG_EVENT_2:
+ me->SetFacingTo(6.235659f);
+ Talk(SAY_HARRISON_1);
+ DoCast(me, SPELL_BANGING_THE_GONG);
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_MACE));
+ me->SetSheath(SHEATH_STATE_MELEE);
+ _gongTimer = 4000;
+ _gongEvent = GONG_EVENT_3;
+ break;
+ case GONG_EVENT_3:
+ if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG)))
+ gong->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_NOT_SELECTABLE);
+ _gongTimer = 105000;
+ _gongEvent = GONG_EVENT_4;
+ break;
+ case GONG_EVENT_4:
+ me->RemoveAura(SPELL_BANGING_THE_GONG);
+ if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG)))
+ gong->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_NOT_SELECTABLE);
+
+ // trigger or gong will need to be scripted to set SPECIAL if enough players click gong.
+ // This is temp workaround.
+ if (instance)
+ instance->SetData(DATA_GONGEVENT, SPECIAL); // to be removed.
+
+ if (instance->GetData(DATA_GONGEVENT) == SPECIAL)
+ {
+ // Players are Now Saved to instance at SPECIAL (Player should be notified?)
+ me->GetMotionMaster()->MovePath(HARRISON_MOVE_2,false);
+ _gongTimer = 5000;
+ _gongEvent = 5;
+ }
+ else
+ {
+ _gongTimer = 1000;
+ _gongEvent = 10;
+ }
+ break;
+ case GONG_EVENT_5:
+ me->SetEntry(NPC_HARRISON_JONES_1);
+ me->SetDisplayId(MODEL_HARRISON_JONES_1);
+ Talk(SAY_HARRISON_2);
+ _gongTimer = 14000;
+ _gongEvent = 6;
+ break;
+ case GONG_EVENT_6:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
+ Talk(SAY_HARRISON_3);
+ _gongTimer = 7000;
+ _gongEvent = 7;
+ break;
+ case GONG_EVENT_7:
+ if (!uiTargetGUID)
+ {
+ std::list<Creature*> targetList;
+ GetCreatureListWithEntryInGrid(targetList, me, NPC_AMANISHI_GUARDIAN, 26.0f);
+ if (!targetList.empty())
+ {
+ for (std::list<Creature*>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
+ {
+ if (Creature* ptarget = *itr)
+ {
+ if (ptarget->GetPositionX() > 120)
+ {
+ ptarget->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_SPEAR));
+ ptarget->AI()->SetData(0,1);
+ }
+ }
+ }
+ }
+ }
+
+ if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_MASSIVE_GATE)))
+ gate->SetGoState(GO_STATE_ACTIVE);
+ _gongTimer = 1000;
+ _gongEvent = 8;
+ case GONG_EVENT_8:
+ DoCast(me, SPELL_STEALTH);
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(0));
+ me->GetMotionMaster()->MovePath(HARRISON_MOVE_3,false);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ _gongTimer = 100;
+ _gongEvent = 9;
+ case GONG_EVENT_9:
+ // If player in 10.0f range
+ // Send setdata to SAI for previous target
+ // SAI BELOW
+ // move 23597, guid 86194 to be deleted
+ // path 138.2242 Y: 1586.994 Z: 43.5488
+ // path 131.8407 Y: 1590.247 Z: 43.61384
+ // Reach end of path turnto 2.024582 cast Spell ID: 43647 on self hits 24365 update UNIT_VIRTUAL_ITEM_SLOT_ID: 33979
+ // wait 2 sec say text 0
+ // Set below after complete above
+ _gongTimer = 0;
+ _gongEvent = 0;
+ break;
+ case GONG_EVENT_10:
+ me->GetMotionMaster()->MovePoint(0, 120.687f, 1674.0f, 42.0217f);
+ _gongTimer = 12000;
+ _gongEvent = 11;
+ break;
+ case GONG_EVENT_11:
+ me->SetFacingTo(1.59044f);
+ _gongTimer = 6000;
+ _gongEvent = 12;
+ break;
+ case GONG_EVENT_12:
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ if (instance)
+ instance->SetData(DATA_GONGEVENT, NOT_STARTED);
+ _gongTimer = 0;
+ _gongEvent = 0;
+ break;
+ }
+ }
+ else
+ _gongTimer -= diff;
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_harrison_jonesAI(creature);
+ }
+};
+
+class spell_banging_the_gong : public SpellScriptLoader
+{
+ public:
+ spell_banging_the_gong() : SpellScriptLoader("spell_banging_the_gong") { }
+
+ class spell_banging_the_gong_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_banging_the_gong_SpellScript);
+
+ void Activate(SpellEffIndex index)
+ {
+ PreventHitDefaultEffect(index);
+ GetHitGObj()->SendCustomAnim(0);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_banging_the_gong_SpellScript::Activate, EFFECT_1, SPELL_EFFECT_ACTIVATE_OBJECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_banging_the_gong_SpellScript();
+ }
+};
+
+
void AddSC_zulaman()
{
new npc_forest_frog();
new npc_zulaman_hostage();
+ new npc_harrison_jones();
+ new spell_banging_the_gong();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
index 7227dfaedf4..c3386f8c996 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
@@ -19,15 +19,43 @@
#ifndef DEF_ZULAMAN_H
#define DEF_ZULAMAN_H
-#define DATA_NALORAKKEVENT 1
-#define DATA_AKILZONEVENT 2
-#define DATA_JANALAIEVENT 3
-#define DATA_HALAZZIEVENT 4
-#define DATA_HEXLORDEVENT 5
-#define DATA_ZULJINEVENT 6
-#define DATA_CHESTLOOTED 7
-#define TYPE_RAND_VENDOR_1 8
-#define TYPE_RAND_VENDOR_2 9
+enum DataTypes
+{
+ DATA_GONGEVENT = 0,
+ DATA_NALORAKKEVENT = 1,
+ DATA_AKILZONEVENT = 2,
+ DATA_JANALAIEVENT = 3,
+ DATA_HALAZZIEVENT = 4,
+ DATA_HEXLORDEVENT = 5,
+ DATA_ZULJINEVENT = 6,
+ DATA_CHESTLOOTED = 7,
+ TYPE_RAND_VENDOR_1 = 8,
+ TYPE_RAND_VENDOR_2 = 9
+};
-#endif
+enum CreatureIds
+{
+ NPC_HARRISON_JONES = 24358,
+ NPC_JANALAI = 23578,
+ NPC_ZULJIN = 23863,
+ NPC_HEXLORD = 24239,
+ NPC_HALAZZI = 23577,
+ NPC_NALORAKK = 23576
+};
+
+enum GameobjectIds
+{
+ GO_DOOR_HALAZZI = 186303,
+ GO_GATE_ZULJIN = 186304,
+ GO_GATE_HEXLORD = 186305,
+ GO_MASSIVE_GATE = 186728,
+ GO_DOOR_AKILZON = 186858,
+ GO_DOOR_ZULJIN = 186859,
+ GO_HARKORS_SATCHEL = 187021,
+ GO_TANZARS_TRUNK = 186648,
+ GO_ASHLIS_BAG = 186672,
+ GO_KRAZS_PACKAGE = 186667,
+ GO_STRANGE_GONG = 187359
+};
+#endif
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
index 6d33efb4515..e99128fbbf9 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
@@ -16,229 +16,245 @@
*/
#include "ScriptMgr.h"
+#include "SpellScript.h"
#include "ScriptedCreature.h"
#include "drak_tharon_keep.h"
-enum Spells
+enum Misc
{
- SPELL_ARCANE_BLAST = 49198,
- H_SPELL_ARCANE_BLAST = 59909,
- SPELL_ARCANE_FIELD = 47346,
- SPELL_BLIZZARD = 49034,
- H_SPELL_BLIZZARD = 59854,
- SPELL_FROSTBOLT = 49037,
- H_SPELL_FROSTBOLT = 59855,
- SPELL_WRATH_OF_MISERY = 50089,
- H_SPELL_WRATH_OF_MISERY = 59856,
- SPELL_SUMMON_MINIONS = 59910 //Summons an army of Fetid Troll Corpses to assist the caster.
+ ACTION_RESET_CRYSTALS,
+ ACTION_ACTIVATE_CRYSTAL,
+ ACTION_DEACTIVATE,
+ EVENT_ATTACK,
+ EVENT_SUMMON_MINIONS,
+ DATA_NOVOS_ACHIEV
};
-//not in db
-enum Yells
+enum Creatures
{
- SAY_AGGRO = 0,
- SAY_KILL = 1,
- SAY_DEATH = 2,
- SAY_NECRO_ADD = 3,
- SAY_REUBBLE = 4
+ NPC_CRYSTAL_CHANNEL_TARGET = 26712,
+ NPC_FETID_TROLL_CORPSE = 27597,
+ NPC_RISEN_SHADOWCASTER = 27600,
+ NPC_HULKING_CORPSE = 27597
};
-enum Creatures
+enum Spells
{
- CREATURE_RISEN_SHADOWCASTER = 27600,
- CREATURE_FETID_TROLL_CORPSE = 27598,
- CREATURE_HULKING_CORPSE = 27597,
- CREATURE_CRYSTAL_HANDLER = 26627
+ SPELL_BEAM_CHANNEL = 52106,
+ SPELL_ARCANE_FIELD = 47346,
+
+ SPELL_SUMMON_RISEN_SHADOWCASTER = 49105,
+ SPELL_SUMMON_FETID_TROLL_CORPSE = 49103,
+ SPELL_SUMMON_HULKING_CORPSE = 49104,
+ SPELL_SUMMON_CRYSTAL_HANDLER = 49179,
+
+ SPELL_ARCANE_BLAST = 49198,
+ SPELL_BLIZZARD = 49034,
+ SPELL_FROSTBOLT = 49037,
+ SPELL_WRATH_OF_MISERY = 50089,
+ SPELL_SUMMON_MINIONS = 59910
};
-enum CombatPhase
+struct SummonerInfo
{
- IDLE,
- PHASE_1,
- PHASE_2
+ uint32 data, spell, timer;
};
-#define ACTION_MINION_REACHED 1
-#define DATA_OH_NOVOS 2
+const SummonerInfo summoners[] =
+{
+ { DATA_NOVOS_SUMMONER_1, SPELL_SUMMON_RISEN_SHADOWCASTER, 15000 },
+ { DATA_NOVOS_SUMMONER_2, SPELL_SUMMON_FETID_TROLL_CORPSE, 5000 },
+ { DATA_NOVOS_SUMMONER_3, SPELL_SUMMON_HULKING_CORPSE, 30000 },
+ { DATA_NOVOS_SUMMONER_4, SPELL_SUMMON_CRYSTAL_HANDLER, 30000 }
+};
-static Position AddSpawnPoint = { -379.20f, -816.76f, 59.70f, 0.0f };
-static Position CrystalHandlerSpawnPoint = { -326.626343f, -709.956604f, 27.813314f, 0.0f };
-static Position AddDestinyPoint = { -379.314545f, -772.577637f, 28.58837f, 0.0f };
+#define MAX_Y_COORD_OH_NOVOS -771.95f
class boss_novos : public CreatureScript
{
public:
boss_novos() : CreatureScript("boss_novos") { }
- struct boss_novosAI : public Scripted_NoMovementAI
+ struct boss_novosAI : public BossAI
{
- boss_novosAI(Creature* creature) : Scripted_NoMovementAI(creature), lSummons(me)
+ boss_novosAI(Creature* creature) : BossAI(creature, DATA_NOVOS_EVENT) {}
+
+ void Reset()
{
- instance = creature->GetInstanceScript();
+ events.Reset();
+ summons.DespawnAll();
+ instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
+
+ _ohNovos = true;
+ _crystalHandlerCount = 0;
+ SetCrystalsStatus(false);
+ SetSummonerStatus(false);
+ SetBubbled(false);
}
- uint32 uiTimer;
- uint32 uiCrystalHandlerTimer;
- uint8 crystalHandlerAmount;
+ void EnterCombat(Unit* /* victim */)
+ {
+ me->setActive(true);
+ DoZoneInCombat();
+ instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
- bool ohNovos;
+ SetCrystalsStatus(true);
+ SetSummonerStatus(true);
+ SetBubbled(true);
+ }
- SummonList lSummons;
+ void AttackStart(Unit* target)
+ {
+ if (!target)
+ return;
- std::list<uint64> luiCrystals;
+ if (me->Attack(target, true))
+ DoStartNoMovement(target);
+ }
- CombatPhase Phase;
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim() || _bubbled)
+ return;
- InstanceScript* instance;
+ events.Update(diff);
- void Reset()
- {
- Phase = IDLE;
- luiCrystals.clear();
- ohNovos = true;
- me->CastStop();
- lSummons.DespawnAll();
- crystalHandlerAmount = 0;
-
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
- if (instance)
- {
- instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
- for (uint8 n = 0; n < 4; ++n)
- luiCrystals.push_back(instance->GetData64(DATA_NOVOS_CRYSTAL_1 + n));
- for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
- {
- if (GameObject* temp = instance->instance->GetGameObject(*itr))
- temp->SetGoState(GO_STATE_READY);
- }
- }
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- void EnterCombat(Unit* /*who*/)
- {
- Talk(SAY_AGGRO);
- Phase = PHASE_1;
- uiCrystalHandlerTimer = 30*IN_MILLISECONDS;
- uiTimer = 1*IN_MILLISECONDS;
- DoCast(SPELL_ARCANE_FIELD);
- if (instance)
+ if (uint32 eventId = events.ExecuteEvent())
{
- for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
+ switch (eventId)
{
- if (GameObject* temp = instance->instance->GetGameObject(*itr))
- temp->SetGoState(GO_STATE_ACTIVE);
+ case EVENT_SUMMON_MINIONS:
+ DoCast(SPELL_SUMMON_MINIONS);
+ events.ScheduleEvent(EVENT_SUMMON_MINIONS, 15000);
+ break;
+ case EVENT_ATTACK:
+ if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(victim, RAND(SPELL_ARCANE_BLAST, SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_WRATH_OF_MISERY));
+ events.ScheduleEvent(EVENT_ATTACK, 3000);
+ break;
+ default:
+ break;
}
- instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
}
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void UpdateAI(const uint32 diff)
+ void DoAction(int32 const action)
{
- switch (Phase)
- {
- case PHASE_1:
- if (uiTimer <= diff)
- {
- Creature* summon = me->SummonCreature(RAND(CREATURE_FETID_TROLL_CORPSE, CREATURE_HULKING_CORPSE, CREATURE_RISEN_SHADOWCASTER), AddSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS);
- summon->GetMotionMaster()->MovePoint(0, AddDestinyPoint);
- //If spell is casted stops casting arcane field so no spell casting
- //DoCast(me, SPELL_SUMMON_MINIONS);
- uiTimer = 3*IN_MILLISECONDS;
- } else uiTimer -= diff;
- if (crystalHandlerAmount < 4)
- {
- if (uiCrystalHandlerTimer <= diff)
- {
- Talk(SAY_NECRO_ADD);
- Creature* pCrystalHandler = me->SummonCreature(CREATURE_CRYSTAL_HANDLER, CrystalHandlerSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS);
- pCrystalHandler->GetMotionMaster()->MovePoint(0, AddDestinyPoint);
- uiCrystalHandlerTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else uiCrystalHandlerTimer -= diff;
- }
- break;
- case PHASE_2:
- if (uiTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, DUNGEON_MODE(RAND(SPELL_ARCANE_BLAST, SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_WRATH_OF_MISERY),
- RAND(H_SPELL_ARCANE_BLAST, H_SPELL_BLIZZARD, H_SPELL_FROSTBOLT, H_SPELL_WRATH_OF_MISERY)));
- uiTimer = urand(1*IN_MILLISECONDS, 3*IN_MILLISECONDS);
- } else uiTimer -= diff;
- break;
- default:
- break;
- }
+ if (action == ACTION_CRYSTAL_HANDLER_DIED)
+ CrystalHandlerDied();
}
- void JustDied(Unit* /*killer*/)
+
+ void MoveInLineOfSight(Unit* who)
{
- Talk(SAY_DEATH);
- if (instance)
- instance->SetData(DATA_NOVOS_EVENT, DONE);
- lSummons.DespawnAll();
+ BossAI::MoveInLineOfSight(who);
+
+ if (!_ohNovos || !who || who->GetTypeId() != TYPEID_UNIT || who->GetPositionY() > MAX_Y_COORD_OH_NOVOS)
+ return;
+
+ uint32 entry = who->GetEntry();
+ if (entry == NPC_HULKING_CORPSE || entry == NPC_RISEN_SHADOWCASTER || entry == NPC_FETID_TROLL_CORPSE)
+ _ohNovos = false;
}
- void KilledUnit(Unit* victim)
+ uint32 GetData(uint32 type) const
{
- if (victim == me)
- return;
- Talk(SAY_KILL);
+ return type == DATA_NOVOS_ACHIEV && _ohNovos ? 1 : 0;
}
void JustSummoned(Creature* summon)
{
- if (summon->GetEntry() == CREATURE_CRYSTAL_HANDLER)
- crystalHandlerAmount++;
-
- lSummons.Summon(summon);
+ summons.Summon(summon);
}
- void DoAction(int32 const action)
+ private:
+ void SetBubbled(bool state)
{
- if (action == ACTION_MINION_REACHED)
- ohNovos = false;
+ _bubbled = state;
+ if (!state)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ me->CastStop();
+ }
+ else
+ {
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ DoCast(SPELL_ARCANE_FIELD);
+ }
}
- uint32 GetData(uint32 type) const
+ void SetSummonerStatus(bool active)
{
- if (type == DATA_OH_NOVOS)
- return ohNovos ? 1 : 0;
+ for (uint8 i = 0; i < 4; i++)
+ if (uint64 guid = instance->GetData64(summoners[i].data))
+ if (Creature* crystalChannelTarget = instance->instance->GetCreature(guid))
+ {
+ if (active)
+ crystalChannelTarget->AI()->SetData(summoners[i].spell, summoners[i].timer);
+ else
+ crystalChannelTarget->AI()->Reset();
+ }
+ }
- return 0;
+ void SetCrystalsStatus(bool active)
+ {
+ for (uint8 i = 0; i < 4; i++)
+ if (uint64 guid = instance->GetData64(DATA_NOVOS_CRYSTAL_1 + i))
+ if (GameObject* crystal = instance->instance->GetGameObject(guid))
+ SetCrystalStatus(crystal, active);
}
- void RemoveCrystal()
+ void SetCrystalStatus(GameObject* crystal, bool active)
{
- if (!luiCrystals.empty())
- {
- if (instance)
- if (GameObject* temp = instance->instance->GetGameObject(luiCrystals.back()))
- temp->SetGoState(GO_STATE_READY);
- luiCrystals.pop_back();
- }
- if (luiCrystals.empty())
+ if (!crystal)
+ return;
+
+ crystal->SetGoState(active ? GO_STATE_ACTIVE : GO_STATE_READY);
+ if (Creature* crystalChannelTarget = crystal->FindNearestCreature(NPC_CRYSTAL_CHANNEL_TARGET, 5.0f))
{
- me->CastStop();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Phase = PHASE_2;
- uiTimer = 1*IN_MILLISECONDS;
+ if (active)
+ crystalChannelTarget->AI()->DoCastAOE(SPELL_BEAM_CHANNEL);
+ else if (crystalChannelTarget->HasUnitState(UNIT_STATE_CASTING))
+ crystalChannelTarget->CastStop();
}
}
- Unit* GetRandomTarget()
+ void CrystalHandlerDied()
{
- return SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
+ for (uint8 i = 0; i < 4; i++)
+ if (uint64 guid = instance->GetData64(DATA_NOVOS_CRYSTAL_1 + i))
+ if (GameObject* crystal = instance->instance->GetGameObject(guid))
+ if (crystal->GetGoState() == GO_STATE_ACTIVE)
+ {
+ SetCrystalStatus(crystal, false);
+ break;
+ }
+
+ if (++_crystalHandlerCount >= 4)
+ {
+ SetSummonerStatus(false);
+ SetBubbled(false);
+ events.ScheduleEvent(EVENT_ATTACK, 3000);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_SUMMON_MINIONS, 15000);
+ }
+ else if (uint64 guid = instance->GetData64(DATA_NOVOS_SUMMONER_4))
+ if (Creature* crystalChannelTarget = instance->instance->GetCreature(guid))
+ crystalChannelTarget->AI()->SetData(SPELL_SUMMON_CRYSTAL_HANDLER, 15000);
}
+
+ uint8 _crystalHandlerCount;
+ bool _ohNovos;
+ bool _bubbled;
};
CreatureAI* GetAI(Creature* creature) const
@@ -247,126 +263,116 @@ public:
}
};
-enum CrystalHandlerSpells
-{
- SPELL_FLASH_OF_DARKNESS = 49668,
- H_SPELL_FLASH_OF_DARKNESS = 59004
-};
-
-class mob_crystal_handler : public CreatureScript
+class npc_crystal_channel_target : public CreatureScript
{
public:
- mob_crystal_handler() : CreatureScript("mob_crystal_handler") { }
+ npc_crystal_channel_target() : CreatureScript("npc_crystal_channel_target") {}
- struct mob_crystal_handlerAI : public ScriptedAI
+ struct npc_crystal_channel_targetAI : public ScriptedAI
{
- mob_crystal_handlerAI(Creature* creature) : ScriptedAI(creature)
+ npc_crystal_channel_targetAI(Creature* creature) : ScriptedAI(creature) {}
+
+ void Reset()
{
- instance = creature->GetInstanceScript();
+ _spell = 0;
+ _timer = 0;
+ _temp = 0;
}
- uint32 uiFlashOfDarknessTimer;
-
- InstanceScript* instance;
-
- void Reset()
+ void UpdateAI(const uint32 diff)
{
- uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
+ if (_spell)
+ {
+ if (_temp <= diff)
+ {
+ DoCast(_spell);
+ _temp = _timer;
+ }
+ else
+ _temp -= diff;
+ }
}
- void JustDied(Unit* /*killer*/)
+ void SetData(uint32 id, uint32 value)
{
- if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
- CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->RemoveCrystal();
+ _spell = id;
+ _timer = value;
+ _temp = value;
}
- void UpdateAI(const uint32 diff)
+ void JustSummoned(Creature* summon)
{
- if (!UpdateVictim())
- return;
+ if (InstanceScript* instance = me->GetInstanceScript())
+ if (uint64 guid = instance->GetData64(DATA_NOVOS))
+ if (Creature* novos = Creature::GetCreature(*me, guid))
+ novos->AI()->JustSummoned(summon);
- if (uiFlashOfDarknessTimer <= diff)
- {
- DoCast(me->getVictim(), DUNGEON_MODE(SPELL_FLASH_OF_DARKNESS, H_SPELL_FLASH_OF_DARKNESS));
- uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
- } else uiFlashOfDarknessTimer -= diff;
+ if (summon)
+ summon->GetMotionMaster()->MovePath(summon->GetEntry() * 100, false);
- DoMeleeAttackIfReady();
+ if (_spell == SPELL_SUMMON_CRYSTAL_HANDLER)
+ Reset();
}
- void MovementInform(uint32 type, uint32 id)
- {
- if (type != POINT_MOTION_TYPE || id != 0)
- return;
- if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
- if (Unit* target = CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->GetRandomTarget())
- AttackStart(target);
- }
+ private:
+ uint32 _spell;
+ uint32 _timer;
+ uint32 _temp;
};
CreatureAI* GetAI(Creature* creature) const
{
- return new mob_crystal_handlerAI(creature);
+ return new npc_crystal_channel_targetAI(creature);
}
};
-class mob_novos_minion : public CreatureScript
+class achievement_oh_novos : public AchievementCriteriaScript
{
public:
- mob_novos_minion() : CreatureScript("mob_novos_minion") { }
+ achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") {}
- struct mob_novos_minionAI : public ScriptedAI
+ bool OnCheck(Player* /*player*/, Unit* target)
{
- mob_novos_minionAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
+ return target && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(DATA_NOVOS_ACHIEV);
+ }
+};
- InstanceScript* instance;
+enum SummonMinions
+{
+ SPELL_COPY_OF_SUMMON_MINIONS = 59933
+};
- void MovementInform(uint32 type, uint32 id)
- {
- if (type != POINT_MOTION_TYPE || id !=0)
- return;
- if (Creature* Novos = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
- {
- Novos->AI()->DoAction(ACTION_MINION_REACHED);
- if (Unit* target = CAST_AI(boss_novos::boss_novosAI, Novos->AI())->GetRandomTarget())
- AttackStart(target);
- }
- }
- };
+class spell_summon_minions : public SpellScriptLoader
+{
+public:
+ spell_summon_minions() : SpellScriptLoader("spell_summon_minions") { }
- CreatureAI* GetAI(Creature* creature) const
+ class spell_summon_minions_SpellScript : public SpellScript
{
- return new mob_novos_minionAI(creature);
- }
-};
+ PrepareSpellScript(spell_summon_minions_SpellScript);
-class achievement_oh_novos : public AchievementCriteriaScript
-{
- public:
- achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos")
+ void HandleScript(SpellEffIndex /*effIndex*/)
{
+ GetCaster()->CastSpell((Unit*)NULL, SPELL_COPY_OF_SUMMON_MINIONS, true);
+ GetCaster()->CastSpell((Unit*)NULL, SPELL_COPY_OF_SUMMON_MINIONS, true);
}
- bool OnCheck(Player* /*player*/, Unit* target)
+ void Register()
{
- if (!target)
- return false;
-
- if (Creature* Novos = target->ToCreature())
- if (Novos->AI()->GetData(DATA_OH_NOVOS))
- return true;
-
- return false;
+ OnEffectHitTarget += SpellEffectFn(spell_summon_minions_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_summon_minions_SpellScript();
+ }
};
void AddSC_boss_novos()
{
new boss_novos();
- new mob_crystal_handler();
- new mob_novos_minion();
+ new npc_crystal_channel_target();
+ new spell_summon_minions();
new achievement_oh_novos();
}
diff --git a/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h b/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h
index dc8428f9104..e17cba4bccd 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h
+++ b/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h
@@ -31,9 +31,16 @@ enum Data64
DATA_NOVOS,
DATA_DRED,
DATA_THARON_JA,
+
DATA_NOVOS_CRYSTAL_1,
DATA_NOVOS_CRYSTAL_2,
DATA_NOVOS_CRYSTAL_3,
- DATA_NOVOS_CRYSTAL_4
+ DATA_NOVOS_CRYSTAL_4,
+ DATA_NOVOS_SUMMONER_1,
+ DATA_NOVOS_SUMMONER_2,
+ DATA_NOVOS_SUMMONER_3,
+ DATA_NOVOS_SUMMONER_4,
+
+ ACTION_CRYSTAL_HANDLER_DIED
};
#endif
diff --git a/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp b/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
index 52c5c9eab8e..28bea60fb87 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
@@ -16,6 +16,7 @@
*/
#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "InstanceScript.h"
#include "drak_tharon_keep.h"
@@ -30,17 +31,23 @@
enum Creatures
{
- NPC_TROLLGORE = 26630,
- NPC_NOVOS = 26631,
- NPC_KING_DRED = 27483,
- NPC_THARON_JA = 26632
+ NPC_TROLLGORE = 26630,
+ NPC_NOVOS = 26631,
+ NPC_KING_DRED = 27483,
+ NPC_THARON_JA = 26632,
+ NPC_CRYSTAL_CHANNEL_TARGET = 26712,
+ NPC_CRYSTAL_HANDLER = 26627
};
enum GameObjects
{
- GO_NOVOS_CRYSTAL_1 = 189299,
- GO_NOVOS_CRYSTAL_2 = 189300,
- GO_NOVOS_CRYSTAL_3 = 189301,
- GO_NOVOS_CRYSTAL_4 = 189302
+ GO_NOVOS_CRYSTAL_1 = 189299,
+ GO_NOVOS_CRYSTAL_2 = 189300,
+ GO_NOVOS_CRYSTAL_3 = 189301,
+ GO_NOVOS_CRYSTAL_4 = 189302
+};
+enum Achievements
+{
+ ACM_CRITERIA_OH_NOVOS = 7361
};
class instance_drak_tharon : public InstanceMapScript
@@ -52,17 +59,22 @@ public:
{
instance_drak_tharon_InstanceScript(Map* map) : InstanceScript(map) {}
- uint8 uiDredAchievCounter;
+ uint8 dredAchievCounter;
- uint64 uiTrollgore;
- uint64 uiNovos;
- uint64 uiDred;
- uint64 uiTharonJa;
+ uint64 trollgoreGUID;
+ uint64 novosGUID;
+ uint64 dredGUID;
+ uint64 tharonJaGUID;
- uint64 uiNovosCrystal1;
- uint64 uiNovosCrystal2;
- uint64 uiNovosCrystal3;
- uint64 uiNovosCrystal4;
+ uint64 novosCrystalGUID1;
+ uint64 novosCrystalGUID2;
+ uint64 novosCrystalGUID3;
+ uint64 novosCrystalGUID4;
+
+ uint64 novosSummonerGUID1;
+ uint64 novosSummonerGUID2;
+ uint64 novosSummonerGUID3;
+ uint64 novosSummonerGUID4;
uint16 m_auiEncounter[MAX_ENCOUNTER];
@@ -71,15 +83,23 @@ public:
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
- uiTrollgore = 0;
- uiNovos = 0;
- uiDred = 0;
- uiTharonJa = 0;
- uiNovosCrystal1 = 0;
- uiNovosCrystal2 = 0;
- uiNovosCrystal3 = 0;
- uiNovosCrystal4 = 0;
- uiDredAchievCounter = 0;
+
+ dredAchievCounter = 0;
+
+ trollgoreGUID = 0;
+ novosGUID = 0;
+ dredGUID = 0;
+ tharonJaGUID = 0;
+
+ novosCrystalGUID1 = 0;
+ novosCrystalGUID2 = 0;
+ novosCrystalGUID3 = 0;
+ novosCrystalGUID4 = 0;
+
+ novosSummonerGUID1 = 0;
+ novosSummonerGUID2 = 0;
+ novosSummonerGUID3 = 0;
+ novosSummonerGUID4 = 0;
}
bool IsEncounterInProgress() const
@@ -96,16 +116,20 @@ public:
switch (go->GetEntry())
{
case GO_NOVOS_CRYSTAL_1:
- uiNovosCrystal1 = go->GetGUID();
+ novosCrystalGUID1 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
case GO_NOVOS_CRYSTAL_2:
- uiNovosCrystal2 = go->GetGUID();
+ novosCrystalGUID2 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
case GO_NOVOS_CRYSTAL_3:
- uiNovosCrystal3 = go->GetGUID();
+ novosCrystalGUID3 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
case GO_NOVOS_CRYSTAL_4:
- uiNovosCrystal4 = go->GetGUID();
+ novosCrystalGUID4 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
}
}
@@ -115,32 +139,55 @@ public:
switch (creature->GetEntry())
{
case NPC_TROLLGORE:
- uiTrollgore = creature->GetGUID();
+ trollgoreGUID = creature->GetGUID();
break;
case NPC_NOVOS:
- uiNovos = creature->GetGUID();
+ novosGUID = creature->GetGUID();
break;
case NPC_KING_DRED:
- uiDred = creature->GetGUID();
+ dredGUID = creature->GetGUID();
break;
case NPC_THARON_JA:
- uiTharonJa = creature->GetGUID();
+ tharonJaGUID = creature->GetGUID();
+ break;
+ case NPC_CRYSTAL_CHANNEL_TARGET:
+ InitializeNovosSummoner(creature);
break;
}
}
+ void InitializeNovosSummoner(Creature* creature)
+ {
+ float x = creature->GetPositionX();
+ float y = creature->GetPositionY();
+ float z = creature->GetPositionZ();
+
+ if (x < -374.0f && x > -379.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
+ novosSummonerGUID1 = creature->GetGUID();
+ else if (x < -379.0f && x > -385.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
+ novosSummonerGUID2 = creature->GetGUID();
+ else if (x < -374.0f && x > -385.0f && y > -827.0f && y < -820.0f && z < 60.0f && z > 58.0f)
+ novosSummonerGUID3 = creature->GetGUID();
+ else if (x < -338.0f && x > -344.0f && y > -727.0f && y < 721.0f && z < 30.0f && z > 26.0f)
+ novosSummonerGUID4 = creature->GetGUID();
+ }
+
uint64 GetData64(uint32 identifier) const
{
switch (identifier)
{
- case DATA_TROLLGORE: return uiTrollgore;
- case DATA_NOVOS: return uiNovos;
- case DATA_DRED: return uiDred;
- case DATA_THARON_JA: return uiTharonJa;
- case DATA_NOVOS_CRYSTAL_1: return uiNovosCrystal1;
- case DATA_NOVOS_CRYSTAL_2: return uiNovosCrystal2;
- case DATA_NOVOS_CRYSTAL_3: return uiNovosCrystal3;
- case DATA_NOVOS_CRYSTAL_4: return uiNovosCrystal4;
+ case DATA_TROLLGORE: return trollgoreGUID;
+ case DATA_NOVOS: return novosGUID;
+ case DATA_DRED: return dredGUID;
+ case DATA_THARON_JA: return tharonJaGUID;
+ case DATA_NOVOS_CRYSTAL_1: return novosCrystalGUID1;
+ case DATA_NOVOS_CRYSTAL_2: return novosCrystalGUID2;
+ case DATA_NOVOS_CRYSTAL_3: return novosCrystalGUID3;
+ case DATA_NOVOS_CRYSTAL_4: return novosCrystalGUID4;
+ case DATA_NOVOS_SUMMONER_1: return novosSummonerGUID1;
+ case DATA_NOVOS_SUMMONER_2: return novosSummonerGUID2;
+ case DATA_NOVOS_SUMMONER_3: return novosSummonerGUID3;
+ case DATA_NOVOS_SUMMONER_4: return novosSummonerGUID4;
}
return 0;
@@ -164,7 +211,7 @@ public:
break;
case DATA_KING_DRED_ACHIEV:
- uiDredAchievCounter = data;
+ dredAchievCounter = data;
break;
}
@@ -182,7 +229,7 @@ public:
case DATA_NOVOS_EVENT: return m_auiEncounter[1];
case DATA_DRED_EVENT: return m_auiEncounter[2];
case DATA_THARON_JA_EVENT: return m_auiEncounter[3];
- case DATA_KING_DRED_ACHIEV: return uiDredAchievCounter;
+ case DATA_KING_DRED_ACHIEV: return dredAchievCounter;
}
return 0;
}
@@ -199,6 +246,14 @@ public:
return saveStream.str();
}
+ void OnUnitDeath(Unit* unit)
+ {
+ if (unit->GetEntry() == NPC_CRYSTAL_HANDLER)
+ if (novosGUID)
+ if (Creature* novos = instance->GetCreature(novosGUID))
+ novos->AI()->DoAction(ACTION_CRYSTAL_HANDLER_DIED);
+ }
+
void Load(const char* in)
{
if (!in)
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 8b8e45432c8..05c756c757c 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -281,15 +281,6 @@ vmap.enableLOS = 1
vmap.enableHeight = 1
#
-# vmap.ignoreSpellIds
-# Description: These spells are ignored for LoS calculation.
-# List of ids with delimiter ','.
-# Example: "7720,1337"
-# Default: "7720"
-
-vmap.ignoreSpellIds = "7720"
-
-#
# vmap.petLOS
# Description: Check line of sight for pets, to avoid them attacking through walls.
# Default: 1 - (Enabled, each pet attack will be checked for line of sight)