Merge branch 'master' of github.com:TrinityCore/TrinityCore into mmaps

Conflicts:
	src/server/game/World/World.cpp
	src/server/worldserver/worldserver.conf.dist
This commit is contained in:
Vincent_Michael
2013-01-07 16:57:39 +01:00
26 changed files with 1006 additions and 538 deletions
@@ -0,0 +1,63 @@
-- Summon minions
DELETE FROM `spell_script_names` WHERE `spell_id`=59910;
INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUE
(59910,'spell_summon_minions');
-- Heroic spells
DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (49198,49034,49037,50089,49668,51363) OR `spellid0` IN (49198,49034,49037,50089,49668,51363);
INSERT INTO `spelldifficulty_dbc`(`id`,`spellid0`,`spellid1`) VALUES
(49198,49198,59909), -- Arcance Blast
(49034,49034,59854), -- Blizzard
(49037,49037,59855), -- Frostbolt
(50089,50089,59856), -- Wrath of Misery
(49668,49668,59004), -- Flash of Darkness
(51363,51363,59016); -- Shadow Bolt
-- Script assignment for summoners
UPDATE `creature_template` SET `ScriptName`='npc_crystal_channel_target',`AIName`='' WHERE `entry`=26712;
-- Spawn summoner for Crystal Handlers
SET @GUID = 40153;
DELETE FROM `creature` WHERE `guid`=@GUID;
INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `modelid`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `curhealth`) VALUE
(@GUID,26712,600,3,17188,-341.31,-724.4,28.57,3.78,3600,8982);
-- Check instance script for achievement Oh Novos
DELETE FROM `achievement_criteria_data` WHERE `criteria_id`=7361;
INSERT INTO `achievement_criteria_data`(`criteria_id`,`type`,`ScriptName`) VALUE
(7361,11,'achievement_oh_novos');
-- Waypoints for summoned adds
DELETE FROM `waypoint_data` WHERE `id` IN(2759700,2759800,2760000,2662700);
INSERT INTO `waypoint_data`(`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES
(2759700,1,-379.473,-810.974,59.7612),
(2759700,2,-379.449,-791.535,44.1756),
(2759700,3,-379.448,-790.328,44.1756),
(2759700,4,-379.426,-772.338,28.5884),
(2759700,5,-379.415,-763.518,28.5884),
(2760000,1,-376.571,-810.681,59.6673),
(2760000,2,-375.627,-791.874,44.1756),
(2760000,3,-375.629,-790.273,44.1434),
(2760000,4,-375.402,-771.145,28.5895),
(2760000,5,-375.337,-765.027,28.5895),
(2759800,1,-382.303,-810.815,59.7628),
(2759800,2,-382.324,-791.595,44.1756),
(2759800,3,-382.326,-790.331,44.1746),
(2759800,4,-383.037,-770.382,28.5884),
(2759800,5,-383.140,-765.399,28.5884),
(2662700,1,-346.977,-733.319,28.5838),
(2662700,2,-363.009,-765.202,28.5907),
(2662700,3,-378.269,-765.701,28.5893);
-- SAI for Crystal Handlers and Risen Shadowcasters
UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' WHERE `entry` IN (26627,27600);
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (26627,27600) AND `source_type`=0;
INSERT INTO `smart_scripts`(`entryorguid`,`event_type`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`target_type`,`comment`) VALUES
(26627,0,1000,1000,5000,5000,11,49668,2,'Crystal Handler - In fight - After 1s then every 5s - Cast Flash of Darkness - On victim'),
(27600,0,1000,1000,5000,5000,11,51363,2,'Risen Shadowcaster - In fight - After 1s then every 5s - Cast Shadow Bolt - On victim');
-- Conditions for beam spell
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=52106;
INSERT INTO `conditions`(`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`Comment`) VALUES
(13,1,52106,31,0,3,26712,0,'Beam Channel target has to be Crystal Channel Target'),
(13,1,52106,35,1,0, 18,1,'Beam Channel target must not be self');
@@ -0,0 +1,10 @@
-- Pathing for Harrison Jones Entry: 24358
SET @NPC := 86177;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`IN (@PATH,@PATH+1,@PATH+2);
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`delay`,`move_flag`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,131.8243,1644.853,42.0216,0,0,0,100,0),
(@PATH+1,1,121.897,1639.106,42.19081,0,0,0,100,0),
(@PATH+1,2,120.8522,1637.931,42.37172,0,0,0,100,0),
(@PATH+1,3,120.7898,1609.063,43.49005,0,0,0,100,0),
(@PATH+2,1,120.6967,1603.713,43.4503,0,0,0,100,0);
@@ -0,0 +1,10 @@
-- Cleanup creature_addon and creature_template_addon
-- we had 83 duplicate aura definitions in those
-- Glacier Penguin (51 rows)
DELETE FROM `creature_addon` WHERE `guid` IN (134996,134997,134998,134999,135000,135001,135002,135004,135005,135006,135007,135008,135009,135010,135011,135012,135013,135014,135015,135016,135017,135018,135025,135026,135027,135028,135029,135030,135031,135032,135033,135034,135035,135036,135037,135038,135039,135040,135041,53884,53885,53886,53887,53888,53889,53890,53891,53892,54042,54043,54044);
-- Plagued Dragonflayer Tribesman (21 rows)
DELETE FROM `creature_addon` WHERE `guid` IN (97517,97518,97519,97520,97521,97522,97523,97524,97526,97527,97528,97529,97530,97531,97532,97534,97535,97537,97538,97539,97541);
DELETE FROM `creature_addon` WHERE `guid` IN (
85036, -- Sir Marcus Barlowe
85038, -- Captain Joseph Holley
85053); -- Marshal Jacob Alerius
@@ -0,0 +1,4 @@
-- Add cpp script to Harrison Jones Entry: 24358
UPDATE `creature_template` SET `AIName`= '', `ScriptName`= 'npc_harrison_jones' WHERE `entry`=24358;
-- Remove cpp script from Strange Gong
UPDATE `gameobject_template` SET `AIName`= '', `ScriptName`= '' WHERE `entry`=187359;
@@ -0,0 +1,18 @@
-- Pathing for Kirtonos the Herald Entry: 10506
SET @PATH := 105061;
DELETE FROM `waypoint_data` WHERE `id`IN (@PATH,@PATH+1,@PATH+2);
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`delay`,`move_flag`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,316.7087,71.26834,104.5843,0,0,0,100,0),
(@PATH,2,321.1605,72.80973,104.6676,0,0,0,100,0),
(@PATH,3,332.3713,77.98991,105.8621,0,0,0,100,0),
(@PATH,4,333.3254,86.60159,106.6399,0,0,0,100,0),
(@PATH,5,334.1263,101.6836,106.8343,0,0,0,100,0),
(@PATH,6,331.0458,114.5935,106.3621,0,0,0,100,0),
(@PATH,7,329.5439,126.7019,106.1399,0,0,0,100,0),
(@PATH,8,335.2471,136.546,105.7232,0,0,0,100,0),
(@PATH,9,343.21,139.9459,107.6399,0,0,0,100,0),
(@PATH,10,364.3288,140.9012,109.9454,0,0,0,100,0),
(@PATH,11,362.676,115.6384,110.3065,0,0,0,100,0),
(@PATH,12,341.7896,91.9439,107.1676,0,0,0,100,0),
(@PATH,13,313.4945,93.45945,104.0565,0,0,0,100,0),
(@PATH,14,306.3839,93.61675,104.0565,0,0,0,100,0);
@@ -0,0 +1,12 @@
-- Small fix to pathing for Harrison Jones
UPDATE `waypoint_data` SET `position_y`=1642.853 WHERE `id`=861770 AND `point`=1;
-- Text for Amani'shi Guardian from sniff
DELETE FROM `creature_text` WHERE `entry` IN (23597);
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(23597,0,0, 'More intruders! Sound da alarm!',14,0,100,25,0,12104, 'Amani''shi Guardian - Gong Event Say');
-- Spell condition for Cosmetic - Spear Throw
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=43647;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13,1,43647,0,0,31,0,3,24358,0,0,0,0, '', 'Cosmetic - Spear Throw - Harrison Jones');
@@ -0,0 +1,3 @@
-- Some SAI Event flag fixes
UPDATE `smart_scripts` SET `event_flags`=`event_flags` &~2 WHERE `entryorguid` IN (594,2529,3631,3632,3633,3655,11777,11778,11781,11782,11785,11786,12239,12240,12241,14284,14285,16354,16355,24819,25471,25472,25473,29186,29190,29199,29200,29204,29219,29454,29455,29468,32501);
UPDATE `smart_scripts` SET `event_flags`=`event_flags` &~4 WHERE `entryorguid` IN (32501);
@@ -0,0 +1,34 @@
-- Spell condition for Cosmetic - Spear Throw
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=43647;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13,1,43647,0,0,31,0,3,24375,0,0,0,0, '', 'Cosmetic - Spear Throw - Harrison Jones');
-- Text for Harrison Jones from sniff
DELETE FROM `creature_text` WHERE `entry` IN (24358,24375);
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(24358,0,0, 'Suit yourself. At least five of you must assist me if we''re to get inside. Follow me....',14,0,100,1,0,0, 'Harrison Jones - Gong Event Say 0'),
(24358,1,0, 'According to my calculations, if enough of us bang the gong at once the seal on these doors will break and we can enter.',14,0,100,1,0,0, 'Harrison Jones - Gong Event Say 1'),
(24375,0,0, 'I''ve researched this site extensively and I won''t allow any dim-witted treasure hunters to swoop in and steal what belongs in a museum. I''ll lead this charge...',14,0,100,0,0,0, 'Harrison Jones - Gong Event Say 2'),
(24375,1,0, 'In fact, it would be best if you just stay here. You''d only get in my way....',14,0,100,0,0,0, 'Harrison Jones - Gong Event Say 3');
-- Add spell script for banging the gong
DELETE FROM `spell_script_names` WHERE `spell_id`=45226;
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(45226, 'spell_banging_the_gong');
-- Remove creature from db
DELETE FROM `creature` WHERE id=24358;
DELETE FROM `creature_addon` WHERE guid=86177;
UPDATE `creature_template` SET `equipment_id`=0 WHERE `entry`=24358;
-- Pathing for Harrison Jones Entry: 24358
SET @NPC := 86044;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`IN (861770,861771,861772);
DELETE FROM `waypoint_data` WHERE `id`IN (@PATH,@PATH+1,@PATH+2);
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`delay`,`move_flag`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,131.8243,1642.853,42.0216,0,0,0,100,0),
(@PATH+1,1,121.897,1639.106,42.19081,0,0,0,100,0),
(@PATH+1,2,120.8522,1637.931,42.37172,0,0,0,100,0),
(@PATH+1,3,120.7898,1609.063,43.49005,0,0,0,100,0),
(@PATH+2,1,120.6967,1603.713,43.4503,0,0,0,100,0);
@@ -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;
}
@@ -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);
};
}
@@ -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;
@@ -1403,6 +1404,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)
+2 -1
View File
@@ -128,7 +128,8 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21,
CONDITION_SOURCE_TYPE_SMART_EVENT = 22,
CONDITION_SOURCE_TYPE_NPC_VENDOR = 23,
CONDITION_SOURCE_TYPE_MAX = 24 // MAX
CONDITION_SOURCE_TYPE_SPELL_PROC = 24,
CONDITION_SOURCE_TYPE_MAX = 25 // MAX
};
enum ComparisionType
@@ -338,6 +338,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;
}
+3 -1
View File
@@ -43,8 +43,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
+13 -1
View File
@@ -12716,7 +12716,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
@@ -14448,6 +14448,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)
@@ -14471,6 +14477,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;
+6 -1
View File
@@ -1980,8 +1980,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
+2 -2
View File
@@ -4915,7 +4915,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;
}
}
@@ -4926,7 +4926,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;
}
+1 -3
View File
@@ -1139,15 +1139,13 @@ void World::LoadConfigSettings(bool reload)
bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true);
bool enableLOS = ConfigMgr::GetBoolDefault("vmap.enableLOS", true);
bool enableHeight = ConfigMgr::GetBoolDefault("vmap.enableHeight", 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", enableLOS, enableHeight, enableIndoor);
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap support included. LineOfSight: %i, getHeight: %i, indoorCheck: %i", enableLOS, enableHeight, enableIndoor);
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);
@@ -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()
@@ -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 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 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_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
@@ -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();
}
@@ -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
};
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
@@ -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.
};
//not in db
enum Yells
{
SAY_AGGRO = 0,
SAY_KILL = 1,
SAY_DEATH = 2,
SAY_NECRO_ADD = 3,
SAY_REUBBLE = 4
ACTION_RESET_CRYSTALS,
ACTION_ACTIVATE_CRYSTAL,
ACTION_DEACTIVATE,
EVENT_ATTACK,
EVENT_SUMMON_MINIONS,
DATA_NOVOS_ACHIEV
};
enum Creatures
{
CREATURE_RISEN_SHADOWCASTER = 27600,
CREATURE_FETID_TROLL_CORPSE = 27598,
CREATURE_HULKING_CORPSE = 27597,
CREATURE_CRYSTAL_HANDLER = 26627
NPC_CRYSTAL_CHANNEL_TARGET = 26712,
NPC_FETID_TROLL_CORPSE = 27597,
NPC_RISEN_SHADOWCASTER = 27600,
NPC_HULKING_CORPSE = 27597
};
enum CombatPhase
enum Spells
{
IDLE,
PHASE_1,
PHASE_2
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
};
#define ACTION_MINION_REACHED 1
#define DATA_OH_NOVOS 2
struct SummonerInfo
{
uint32 data, spell, timer;
};
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 };
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 }
};
#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)
{
instance = creature->GetInstanceScript();
}
uint32 uiTimer;
uint32 uiCrystalHandlerTimer;
uint8 crystalHandlerAmount;
bool ohNovos;
SummonList lSummons;
std::list<uint64> luiCrystals;
CombatPhase Phase;
InstanceScript* instance;
boss_novosAI(Creature* creature) : BossAI(creature, DATA_NOVOS_EVENT) {}
void Reset()
{
Phase = IDLE;
luiCrystals.clear();
ohNovos = true;
me->CastStop();
lSummons.DespawnAll();
crystalHandlerAmount = 0;
events.Reset();
summons.DespawnAll();
instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
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);
}
}
_ohNovos = true;
_crystalHandlerCount = 0;
SetCrystalsStatus(false);
SetSummonerStatus(false);
SetBubbled(false);
}
void EnterCombat(Unit* /*who*/)
void EnterCombat(Unit* /* victim */)
{
Talk(SAY_AGGRO);
Phase = PHASE_1;
uiCrystalHandlerTimer = 30*IN_MILLISECONDS;
uiTimer = 1*IN_MILLISECONDS;
DoCast(SPELL_ARCANE_FIELD);
if (instance)
{
for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
{
if (GameObject* temp = instance->instance->GetGameObject(*itr))
temp->SetGoState(GO_STATE_ACTIVE);
}
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);
me->setActive(true);
DoZoneInCombat();
instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
SetCrystalsStatus(true);
SetSummonerStatus(true);
SetBubbled(true);
}
void AttackStart(Unit* target)
{
if (!target)
return;
if (me->Attack(target, true))
DoStartNoMovement(target);
}
void UpdateAI(const uint32 diff)
{
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;
}
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_DEATH);
if (instance)
instance->SetData(DATA_NOVOS_EVENT, DONE);
lSummons.DespawnAll();
}
void KilledUnit(Unit* victim)
{
if (victim == me)
if (!UpdateVictim() || _bubbled)
return;
Talk(SAY_KILL);
}
void JustSummoned(Creature* summon)
{
if (summon->GetEntry() == CREATURE_CRYSTAL_HANDLER)
crystalHandlerAmount++;
events.Update(diff);
lSummons.Summon(summon);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
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;
}
}
}
void DoAction(int32 const action)
{
if (action == ACTION_MINION_REACHED)
ohNovos = false;
if (action == ACTION_CRYSTAL_HANDLER_DIED)
CrystalHandlerDied();
}
void MoveInLineOfSight(Unit* who)
{
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;
}
uint32 GetData(uint32 type) const
{
if (type == DATA_OH_NOVOS)
return ohNovos ? 1 : 0;
return 0;
return type == DATA_NOVOS_ACHIEV && _ohNovos ? 1 : 0;
}
void RemoveCrystal()
void JustSummoned(Creature* summon)
{
if (!luiCrystals.empty())
summons.Summon(summon);
}
private:
void SetBubbled(bool state)
{
_bubbled = state;
if (!state)
{
if (instance)
if (GameObject* temp = instance->instance->GetGameObject(luiCrystals.back()))
temp->SetGoState(GO_STATE_READY);
luiCrystals.pop_back();
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();
}
if (luiCrystals.empty())
else
{
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 (!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);
}
}
Unit* GetRandomTarget()
void SetSummonerStatus(bool active)
{
return SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
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();
}
}
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 SetCrystalStatus(GameObject* crystal, bool active)
{
if (!crystal)
return;
crystal->SetGoState(active ? GO_STATE_ACTIVE : GO_STATE_READY);
if (Creature* crystalChannelTarget = crystal->FindNearestCreature(NPC_CRYSTAL_CHANNEL_TARGET, 5.0f))
{
if (active)
crystalChannelTarget->AI()->DoCastAOE(SPELL_BEAM_CHANNEL);
else if (crystalChannelTarget->HasUnitState(UNIT_STATE_CASTING))
crystalChannelTarget->CastStop();
}
}
void CrystalHandlerDied()
{
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)
{
instance = creature->GetInstanceScript();
}
uint32 uiFlashOfDarknessTimer;
InstanceScript* instance;
npc_crystal_channel_targetAI(Creature* creature) : ScriptedAI(creature) {}
void Reset()
{
uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
}
void JustDied(Unit* /*killer*/)
{
if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->RemoveCrystal();
_spell = 0;
_timer = 0;
_temp = 0;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (uiFlashOfDarknessTimer <= diff)
if (_spell)
{
DoCast(me->getVictim(), DUNGEON_MODE(SPELL_FLASH_OF_DARKNESS, H_SPELL_FLASH_OF_DARKNESS));
uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
} else uiFlashOfDarknessTimer -= diff;
DoMeleeAttackIfReady();
}
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);
}
};
CreatureAI* GetAI(Creature* creature) const
{
return new mob_crystal_handlerAI(creature);
}
};
class mob_novos_minion : public CreatureScript
{
public:
mob_novos_minion() : CreatureScript("mob_novos_minion") { }
struct mob_novos_minionAI : public ScriptedAI
{
mob_novos_minionAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
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);
if (_temp <= diff)
{
DoCast(_spell);
_temp = _timer;
}
else
_temp -= diff;
}
}
void SetData(uint32 id, uint32 value)
{
_spell = id;
_timer = value;
_temp = value;
}
void JustSummoned(Creature* summon)
{
if (InstanceScript* instance = me->GetInstanceScript())
if (uint64 guid = instance->GetData64(DATA_NOVOS))
if (Creature* novos = Creature::GetCreature(*me, guid))
novos->AI()->JustSummoned(summon);
if (summon)
summon->GetMotionMaster()->MovePath(summon->GetEntry() * 100, false);
if (_spell == SPELL_SUMMON_CRYSTAL_HANDLER)
Reset();
}
private:
uint32 _spell;
uint32 _timer;
uint32 _temp;
};
CreatureAI* GetAI(Creature* creature) const
{
return new mob_novos_minionAI(creature);
return new npc_crystal_channel_targetAI(creature);
}
};
class achievement_oh_novos : public AchievementCriteriaScript
{
public:
achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos")
public:
achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") {}
bool OnCheck(Player* /*player*/, Unit* target)
{
return target && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(DATA_NOVOS_ACHIEV);
}
};
enum SummonMinions
{
SPELL_COPY_OF_SUMMON_MINIONS = 59933
};
class spell_summon_minions : public SpellScriptLoader
{
public:
spell_summon_minions() : SpellScriptLoader("spell_summon_minions") { }
class spell_summon_minions_SpellScript : public SpellScript
{
PrepareSpellScript(spell_summon_minions_SpellScript);
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();
}
@@ -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
@@ -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)
@@ -287,15 +287,6 @@ mmap.enablePathFinding = 1
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.enableIndoorCheck
# Description: VMap based indoor check to remove outdoor-only auras (mounts etc.).