diff options
38 files changed, 1252 insertions, 876 deletions
diff --git a/sql/updates/world/2013_08_26_02_world_db_errors.sql b/sql/updates/world/2013_08_26_02_world_db_errors.sql new file mode 100644 index 00000000000..17c1d54d5a6 --- /dev/null +++ b/sql/updates/world/2013_08_26_02_world_db_errors.sql @@ -0,0 +1,3 @@ +DELETE FROM `creature_equip_template` WHERE `entry` =9543; +INSERT INTO `creature_equip_template` (`entry`, `id`, `itemEntry1`, `itemEntry2`, `itemEntry3`) VALUES +(9543, 1, 5280, 0, 0); diff --git a/sql/updates/world/2013_08_26_03_world_auchindoun.sql b/sql/updates/world/2013_08_26_03_world_auchindoun.sql new file mode 100644 index 00000000000..cf726fa41c5 --- /dev/null +++ b/sql/updates/world/2013_08_26_03_world_auchindoun.sql @@ -0,0 +1,12 @@ +UPDATE `instance_template` SET `script`='instance_auchenai_crypts' WHERE `map`=558; +UPDATE `instance_template` SET `script`='instance_mana_tombs' WHERE `map`=557; + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (33923, 38796, 33666, 38795, 39365); +INSERT INTO `spell_script_names`(`spell_id`, `ScriptName`) VALUES +(33923, 'spell_murmur_sonic_boom'), +(38796, 'spell_murmur_sonic_boom'), +(33666, 'spell_murmur_sonic_boom_effect'), +(38795, 'spell_murmur_sonic_boom_effect'), +(39365, 'spell_murmur_thundering_storm'); + +DELETE FROM `creature_ai_scripts` WHERE `id`=1879605; diff --git a/sql/updates/world/2013_08_26_04_world_sai.sql b/sql/updates/world/2013_08_26_04_world_sai.sql new file mode 100644 index 00000000000..ead2cb8099a --- /dev/null +++ b/sql/updates/world/2013_08_26_04_world_sai.sql @@ -0,0 +1,53 @@ +-- It Rolls Downhill (12673) +/* +-- Blight Geist +-- Emote ID: OneShotSpellCast (51) +-- Emote ID: OneShotAttack1H (36) -- WP 6174.282, -2017.246, 245.1156 +*/ +SET @TARGET := 52247; -- Target Crystal +SET @CHARM := 52252; -- Charm Blight Geist +SET @CHARM_P := 52244; -- Charm Periodic +SET @EVIL_S := 61456; -- Evil Teleport +SET @GEIST := 28750; -- Blight Geist +SET @HARVEST := 52245; -- Harvest Blight Crystal +SET @CREDIT := 52248; -- Kill Credit - Blighted Geist +SET @BLIGHT1 := 190716; -- Crystallized Blight +SET @BLIGHT2 := 190939; -- Crystallized Blight +SET @BLIGHT3 := 190940; -- Crystallized Blight +SET @RADIATION := 52243; -- Orange Radiation, Small + +DELETE FROM `creature_text` WHERE `entry`=@GEIST; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(@GEIST, 0, 1, 'Mphmm rmphhimm rrhumghph?', 12, 0, 100, 1, 0, 0, 'Blight Geist'), +(@GEIST, 0, 2, 'Mhrrumph rummrhum phurr!', 12, 0, 100, 1, 0, 0, 'Blight Geist'); + +DELETE FROM `creature_template_addon` WHERE `entry`=28750; +INSERT INTO `creature_template_addon` (`entry`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES +(28750,0,0,1,0, ''); + +UPDATE `creature_template` SET `AIName`='SmartAI',`spell1`=@HARVEST WHERE `entry`=@GEIST; +DELETE FROM `smart_scripts` WHERE `entryorguid`IN (@GEIST,@GEIST*100) AND `source_type`IN (0,9); +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@GEIST,0,0,1,8,0,100,0,@HARVEST,0,0,0,69,0,0,0,0,0,0,13,@BLIGHT1,5,30,0.0,0.0,0.0,0.0,'On Spellhit - Move to pos - Blight1'), +(@GEIST,0,1,0,61,0,100,0,0,0,0,0,80,@GEIST*100,2,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'On Spellhit - Move to pos - Blight1'), +-- +(@GEIST,0,2,3,8,0,100,0,@HARVEST,0,0,0,69,0,0,0,0,0,0,13,@BLIGHT2,5,30,0.0,0.0,0.0,0.0,'On Spellhit - Move to pos - Blight1'), +(@GEIST,0,3,0,61,0,100,0,0,0,0,0,80,@GEIST*100,2,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'On Spellhit Move to pos - Blight2'), +-- +(@GEIST,0,4,5,8,0,100,0,@HARVEST,0,0,0,69,0,0,0,0,0,0,13,@BLIGHT3,5,30,0.0,0.0,0.0,0.0,'On Spellhit - Move to pos - Blight1'), +(@GEIST,0,5,0,61,0,100,0,0,0,0,0,80,@GEIST*100,2,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'On Spellhit Move to pos - Blight3'), +-- +(@GEIST*100,9,0,0,0,0,100,0,4000,4000,4000,4000,11,@TARGET,2,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,' - On Scrip - '), +(@GEIST*100,9,1,0,0,0,100,0,4000,4000,4000,4000,11,@EVIL_S,2,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,' - On Scrip - '), +(@GEIST*100,9,2,0,0,0,100,1,2000,2000,2000,2000,11,@CREDIT,0,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,' - On Scrip - '), +(@GEIST*100,9,3,0,0,0,100,0,1000,1000,1000,1000,69,0,0,0,0,0,0,1,0,0,0,6174.282, -2017.246, 245.1156,0.0,'On move inform 0 Cast credit'), +(@GEIST*100,9,4,0,0,0,100,0,0,0,0,0,41,10000,0,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'On link - Despawn - Self'), +-- +(@GEIST,0,6,0,8,0,100,0,@CHARM_P,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'On Spellhit - Say Random'), +(@GEIST,0,7,0,8,0,100,0,@CHARM,0,0,0,11,@RADIATION,2,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'On Spellhit - Say Random'); +-- +DELETE FROM `conditions` WHERE `SourceEntry`=@GEIST; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 1, @GEIST, 1, 0, 30, 1, @BLIGHT1, 1, 0, 1, 0, 0, '', 'Execute SAI 0 only if GObject is in range'), +(22, 3, @GEIST, 1, 0, 30, 1, @BLIGHT2, 1, 0, 1, 0, 0, '', 'Execute SAI 2 only if GObject is in range'), +(22, 4, @GEIST, 1, 0, 30, 1, @BLIGHT3, 1, 0, 1, 0, 0, '', 'Execute SAI 6 only if GObject is in range'); diff --git a/sql/updates/world/2013_08_26_05_world_comments.sql b/sql/updates/world/2013_08_26_05_world_comments.sql new file mode 100644 index 00000000000..21836922062 --- /dev/null +++ b/sql/updates/world/2013_08_26_05_world_comments.sql @@ -0,0 +1,13 @@ +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Spellhit - Go to PoS GO' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=0 AND `link`=1; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Link - Start Action Script' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=1 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Spellhit - Go to PoS GO' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=2 AND `link`=3; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Link - Start Action Script' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=3 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Spellhit - Go to PoS GO' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=4 AND `link`=5; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Link - Start Action Script' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=5 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Spellhit - Say Random' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=6 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Spellhit - Add Aura Self' WHERE `entryorguid`=28750 AND `source_type`=0 AND `id`=7 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Script - Cast Spell Target' WHERE `entryorguid`=2875000 AND `source_type`=9 AND `id`=0 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Script - Cast Spell Evil Teleport' WHERE `entryorguid`=2875000 AND `source_type`=9 AND `id`=1 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Script - Cast Credit' WHERE `entryorguid`=2875000 AND `source_type`=9 AND `id`=2 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Script - Go to Teleport Pad' WHERE `entryorguid`=2875000 AND `source_type`=9 AND `id`=3 AND `link`=0; +UPDATE `smart_scripts` SET `comment`='Blight Geist - On Script - Despawn' WHERE `entryorguid`=2875000 AND `source_type`=9 AND `id`=4 AND `link`=0; diff --git a/sql/updates/world/2013_08_26_06_world_loot.sql b/sql/updates/world/2013_08_26_06_world_loot.sql new file mode 100644 index 00000000000..bb4fdb4f41a --- /dev/null +++ b/sql/updates/world/2013_08_26_06_world_loot.sql @@ -0,0 +1,6 @@ +UPDATE `reference_loot_template` SET `groupid`=2 WHERE `entry`=25019; -- Grand Warlock Nethekurse (Heroic) +UPDATE `reference_loot_template` SET `groupid`=2 WHERE `entry`=25020; -- Warbringer O'mrogg (Heroic) + +UPDATE `creature_loot_template` SET `groupid`=2 WHERE `entry`=16809 AND `item`=25020; +UPDATE `creature_loot_template` SET `groupid`=2 WHERE `entry`=16807 AND `item`=25019; + diff --git a/sql/updates/world/2013_08_26_07_world_sai.sql b/sql/updates/world/2013_08_26_07_world_sai.sql new file mode 100644 index 00000000000..5ea76436405 --- /dev/null +++ b/sql/updates/world/2013_08_26_07_world_sai.sql @@ -0,0 +1,45 @@ +-- Zero Tolerance (12686) & Hazardous Materials, these are a 2 in 1 quest +SET @DARMUK := 28793; -- Darmuk +SET @SERVANT := 28802; -- Servant of Drakuru +SET @HAND := 28805; -- Hand of Drakuru + +/* +Reference to GO text +-- Scourge Disguise Failing! Run for cover! +-- Scourge Disguise Failing! Find a safe place! +-- Scourge Disguise Failing! Hide quickly! +*/ +-- Darmuk +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@DARMUK; +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@DARMUK; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@DARMUK,0,0,0,0,0,100,0,7000,13000,12000,17000,11,54386,0,0,0,0,0,1,0,0,0,0,0,0,0,'Darmuk - IC - Cast Darmuk''s Vigilance'), +(@DARMUK,0,1,0,4,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Darmuk - On Aggro - Say1'); + +DELETE FROM `creature_text` WHERE `entry`=@DARMUK; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(@DARMUK, 0, 1, 'Your disguise doesn''t fool me, fleshling! Your defeat will please Drakuru!', 12, 0, 100, 1, 0, 0, 'Darmuk'); + +-- Servant of Drakuru +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@SERVANT; +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@SERVANT; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@SERVANT,0,0,0,0,0,100,0,4000,4800,12000,14000,11,50361,0,0,0,0,0,2,0,0,0,0,0,0,0,'Servant of Drakuru - IC - Cast Rot Armor'), +(@SERVANT,0,1,0,29,0,100,1,0,0,0,0,36,@HAND,0,0,0,0,0,1,0,0,0,0,0,0,0,' Servant of Drakuru - On charm - Update entry Self'); + +-- Hand of Drakuru +UPDATE `creature_model_info` SET `bounding_radius`=1.24,`combat_reach`=4 WHERE `modelid`=26924; +UPDATE `creature_template` SET `AIName`='SmartAI',`spell1`=52400,`spell2`=52401,`spell3`=52402, `minlevel`=75, `maxlevel`=75, `npcflag`=264, `mindmg`=194, `maxdmg`=283, `exp`=2, `attackpower`=432, `minrangedmg`=441, `maxrangedmg`=661 WHERE `entry`=@HAND; +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@HAND; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@HAND,0,0,0,16,0,100,1,52390,1,2000,2000,36,@SERVANT,0,0,0,0,0,1,0,0,0,0,0,0,0,' Hand of Drakuru - On aura remove - Update entry'); + +-- Gameobject, relating to Hazardous Materials. +SET @OGUID = 9246; +DELETE FROM `gameobject` WHERE `id`=190720; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(@OGUID+0, 190720, 571, 1, 1, 6242.536, -1959.009, 417.684, 0.4712385, 0, 0, 0, 1, 120, 255, 1), -- Harvested Blight Crystal (Area: 0) +(@OGUID+1, 190720, 571, 1, 1, 6255.469, -1972.384, 417.7136, 0.3316107, 0, 0, 0, 1, 120, 255, 1), -- Harvested Blight Crystal (Area: Reliquary of Pain) +(@OGUID+2, 190720, 571, 1, 1, 6245.086, -2010.295, 417.5486, 4.450591, 0, 0, 0, 1, 120, 255, 1), -- Harvested Blight Crystal (Area: Reliquary of Pain) +(@OGUID+3, 190720, 571, 1, 1, 6208.02, -2098.342, 417.5984, 0.6981314, 0, 0, 0, 1, 120, 255, 1), -- Harvested Blight Crystal (Area: Reliquary of Pain) +(@OGUID+4, 190720, 571, 1, 1, 6182.603, -2088.755, 417.549, 2.530723, 0, 0, 0, 1, 120, 255, 1); -- Harvested Blight Crystal (Area: Reliquary of Pain) diff --git a/sql/updates/world/2013_08_27_00_world_sai.sql b/sql/updates/world/2013_08_27_00_world_sai.sql new file mode 100644 index 00000000000..4b0d78c6885 --- /dev/null +++ b/sql/updates/world/2013_08_27_00_world_sai.sql @@ -0,0 +1,27 @@ +-- Sabotage (12676) +SET @ENTRY := 28780; -- Explosive Charges Bunny +SET @GOB := 190731; -- Scourgewagon +SET @DETONATE := 52322; -- Detonate Charges +SET @EX1 := 52325; -- Explode Scourgewagon:Roller +SET @EX2 := 52329; -- Explode Scourgewagon:Frame +SET @EX3 := 52330; -- Explode Scourgewagon:Grill +SET @EX4 := 52332; -- Explode Scourgewagon:Wheel +SET @CREDIT := 52346; -- Credit + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=@DETONATE; +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(@DETONATE,@EX1,1,'Explode Scourgewagon'), +(@DETONATE,@EX2,1,'Explode Scourgewagon'), +(@DETONATE,@EX3,1,'Explode Scourgewagon'), +(@DETONATE,@EX4,1,'Explode Scourgewagon'); + +-- Explosive Charges Bunny +SET @SOURCETYPE :=0; +UPDATE `creature_template` SET `AIName`='SmartAI',`flags_extra`=`flags_extra`|128 WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY*100 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,@SOURCETYPE,0,0,54,0,100,0,0,0,0,0,80,@ENTRY*100,2,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'Explosive Charges Bunny - On just summoned - Run script'), +-- +(@ENTRY*100,9,0,0,0,0,100,0,2000,2000,2000,2000,11,@DETONATE,0,0,0,0,0,1,0,0,0,0.0,0.0,0.0,0.0,'Explosive Charges Bunny - On Timed Script - Cast detonate'), +(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,11,@CREDIT,0,0,0,0,0,7,0,0,0,0.0,0.0,0.0,0.0,'Explosive Charges Bunny - On Timed Script - Cast credit '); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index b4e18b66a69..41dae740e59 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2231,6 +2231,7 @@ SmartScriptHolder SmartScript::CreateEvent(SMART_EVENT e, uint32 event_flags, ui script.event.raw.param4 = event_param4; script.event.event_phase_mask = phaseMask; script.event.event_flags = event_flags; + script.event.event_chance = 100; script.action.type = action; script.action.raw.param1 = action_param1; diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 09d29750c57..28e42939287 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -973,11 +973,10 @@ bool Guardian::UpdateStats(Stats stat) float mod = 0.75f; if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH)) { - switch (stat) - { - case STAT_STAMINA: mod = 0.3f; break; // Default Owner's Stamina scale - case STAT_STRENGTH: mod = 0.7f; break; // Default Owner's Strength scale - } + if (stat == STAT_STAMINA) + mod = 0.3f; // Default Owner's Stamina scale + else + mod = 0.7f; // Default Owner's Strength scale // Check just if owner has Ravenous Dead since it's effect is not an aura AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index aca351c4c6a..fde3c0ddfae 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13296,13 +13296,13 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const { if (!isVictim) { - uint32 WeaponSpeed = GetAttackTime(attType); - chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto); + uint32 weaponSpeed = GetAttackTime(attType); + chance = GetPPMProcChance(weaponSpeed, spellProcEvent->ppmRate, spellProto); } - else + else if (victim) { - uint32 WeaponSpeed = victim->GetAttackTime(attType); - chance = victim->GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto); + uint32 weaponSpeed = victim->GetAttackTime(attType); + chance = victim->GetPPMProcChance(weaponSpeed, spellProcEvent->ppmRate, spellProto); } } // Apply chance modifer aura diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 86a6a906df5..e95779c1f20 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6622,17 +6622,20 @@ void ObjectMgr::LoadPetNumber() std::string ObjectMgr::GeneratePetName(uint32 entry) { - StringVector & list0 = _petHalfName0[entry]; - StringVector & list1 = _petHalfName1[entry]; + StringVector& list0 = _petHalfName0[entry]; + StringVector& list1 = _petHalfName1[entry]; if (list0.empty() || list1.empty()) { CreatureTemplate const* cinfo = GetCreatureTemplate(entry); - const char* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale()); - if (!petname) - return cinfo->Name; + if (!cinfo) + return std::string(); - return std::string(petname); + char const* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale()); + if (petname) + return std::string(petname); + else + return cinfo->Name; } return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1)); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 56330c503de..65d9ee4f5ba 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2114,6 +2114,10 @@ void Map::AddObjectToRemoveList(WorldObject* obj) void Map::AddObjectToSwitchList(WorldObject* obj, bool on) { ASSERT(obj->GetMapId() == GetId() && obj->GetInstanceId() == GetInstanceId()); + // i_objectsToSwitch is iterated only in Map::RemoveAllObjectsInRemoveList() and it uses + // the contained objects only if GetTypeId() == TYPEID_UNIT , so we can return in all other cases + if (obj->GetTypeId() != TYPEID_UNIT) + return; std::map<WorldObject*, bool>::iterator itr = i_objectsToSwitch.find(obj); if (itr == i_objectsToSwitch.end()) diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 3c1ec5db0a8..437638da16d 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -536,20 +536,31 @@ void AddSC_zuldrak(); void AddSC_crystalsong_forest(); void AddSC_isle_of_conquest(); -//outland -void AddSC_boss_exarch_maladaar(); //Auchindoun Auchenai Crypts +// Outland + +// Auchindoun - Auchenai Crypts void AddSC_boss_shirrak_the_dead_watcher(); -void AddSC_boss_nexusprince_shaffar(); //Auchindoun Mana Tombs +void AddSC_boss_exarch_maladaar(); +void AddSC_instance_auchenai_crypts(); + +// Auchindoun - Mana Tombs void AddSC_boss_pandemonius(); -void AddSC_boss_darkweaver_syth(); //Auchindoun Sekketh Halls +void AddSC_boss_nexusprince_shaffar(); +void AddSC_instance_mana_tombs(); + +// Auchindoun - Sekketh Halls +void AddSC_boss_darkweaver_syth(); void AddSC_boss_talon_king_ikiss(); void AddSC_boss_anzu(); void AddSC_instance_sethekk_halls(); -void AddSC_instance_shadow_labyrinth(); //Auchindoun Shadow Labyrinth + +// Auchindoun - Shadow Labyrinth void AddSC_boss_ambassador_hellmaw(); void AddSC_boss_blackheart_the_inciter(); void AddSC_boss_grandmaster_vorpil(); void AddSC_boss_murmur(); +void AddSC_instance_shadow_labyrinth(); + void AddSC_black_temple(); //Black Temple void AddSC_boss_illidan(); void AddSC_boss_shade_of_akama(); @@ -1054,19 +1065,29 @@ void AddKalimdorScripts() void AddOutlandScripts() { #ifdef SCRIPTS - AddSC_boss_exarch_maladaar(); //Auchindoun Auchenai Crypts + // Auchindoun - Auchenai Crypts AddSC_boss_shirrak_the_dead_watcher(); - AddSC_boss_nexusprince_shaffar(); //Auchindoun Mana Tombs + AddSC_boss_exarch_maladaar(); + AddSC_instance_auchenai_crypts(); + + // Auchindoun - Mana Tombs AddSC_boss_pandemonius(); - AddSC_boss_darkweaver_syth(); //Auchindoun Sekketh Halls + AddSC_boss_nexusprince_shaffar(); + AddSC_instance_mana_tombs(); + + // Auchindoun - Sekketh Halls + AddSC_boss_darkweaver_syth(); AddSC_boss_talon_king_ikiss(); AddSC_boss_anzu(); AddSC_instance_sethekk_halls(); - AddSC_instance_shadow_labyrinth(); //Auchindoun Shadow Labyrinth + + // Auchindoun - Shadow Labyrinth AddSC_boss_ambassador_hellmaw(); AddSC_boss_blackheart_the_inciter(); AddSC_boss_grandmaster_vorpil(); AddSC_boss_murmur(); + AddSC_instance_shadow_labyrinth(); + AddSC_black_temple(); //Black Temple AddSC_boss_illidan(); AddSC_boss_shade_of_akama(); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 3272498662b..65ddb3a8d05 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -29,10 +29,16 @@ #include "SpellInfo.h" #include "SpellScript.h" #include "GossipDef.h" -#include "CreatureAI.h" +#include "CreatureAIImpl.h" #include "Player.h" #include "WorldPacket.h" +namespace +{ + typedef std::set<ScriptObject*> ExampleScriptContainer; + ExampleScriptContainer ExampleScripts; +} + // This is the global static registry of scripts. template<class TScript> class ScriptRegistry @@ -104,6 +110,9 @@ class ScriptRegistry if (script->GetName().find("example") == std::string::npos && script->GetName().find("Smart") == std::string::npos) TC_LOG_ERROR(LOG_FILTER_SQL, "Script named '%s' does not have a script name assigned in database.", script->GetName().c_str()); + + // These scripts don't get stored anywhere so throw them into this to avoid leaking memory + ExampleScripts.insert(script); } } else @@ -160,7 +169,11 @@ class ScriptRegistry if (!V) \ return R; - +struct TSpellSummary +{ + uint8 Targets; // set of enum SelectTarget + uint8 Effects; // set of enum SelectEffect +} *SpellSummary; ScriptMgr::ScriptMgr() : _scriptCount(0), _scheduledScripts(0) @@ -220,6 +233,13 @@ void ScriptMgr::Unload() SCR_CLEAR(UnitScript); #undef SCR_CLEAR + + for (ExampleScriptContainer::iterator itr = ExampleScripts.begin(); itr != ExampleScripts.end(); ++itr) + delete *itr; + ExampleScripts.clear(); + + delete[] SpellSummary; + delete[] UnitAI::AISpellInfo; } void ScriptMgr::LoadDatabase() @@ -227,14 +247,10 @@ void ScriptMgr::LoadDatabase() sScriptSystemMgr->LoadScriptWaypoints(); } -struct TSpellSummary -{ - uint8 Targets; // set of enum SelectTarget - uint8 Effects; // set of enum SelectEffect -} *SpellSummary; - void ScriptMgr::FillSpellSummary() { + UnitAI::FillAISpellInfo(); + SpellSummary = new TSpellSummary[sSpellMgr->GetSpellInfoStoreSize()]; SpellInfo const* pTempSpell; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index b34b935e975..721a171917e 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -27,7 +27,6 @@ #include "Chat.h" #include "Spell.h" #include "BattlegroundMgr.h" -#include "CreatureAI.h" #include "MapManager.h" #include "BattlefieldWG.h" #include "BattlefieldMgr.h" @@ -3079,8 +3078,6 @@ void SpellMgr::LoadSpellInfoCustomAttributes() spellInfo->_InitializeExplicitTargetMask(); } - CreatureAI::FillAISpellInfo(); - TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded SpellInfo custom attributes in %u ms", GetMSTimeDiffToNow(oldMSTime)); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index 2abfcead826..8f292f2d008 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -364,24 +364,22 @@ public: me->GetRandomNearPosition(pos, 60); else { - std::vector<InfernalPoint*>::iterator itr = positions.begin()+rand()%positions.size(); - point = *itr; - positions.erase(itr); - pos.Relocate(point->x, point->y, INFERNAL_Z); + point = Trinity::Containers::SelectRandomContainerElement(positions); + pos.Relocate(point->x, point->y, INFERNAL_Z, frand(0.0f, float(M_PI * 2))); } - Creature* Infernal = me->SummonCreature(NETHERSPITE_INFERNAL, pos, TEMPSUMMON_TIMED_DESPAWN, 180000); + Creature* infernal = me->SummonCreature(NETHERSPITE_INFERNAL, pos, TEMPSUMMON_TIMED_DESPAWN, 180000); - if (Infernal) + if (infernal) { - Infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE); - Infernal->setFaction(me->getFaction()); + infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE); + infernal->setFaction(me->getFaction()); if (point) - CAST_AI(netherspite_infernal::netherspite_infernalAI, Infernal->AI())->point=point; - CAST_AI(netherspite_infernal::netherspite_infernalAI, Infernal->AI())->malchezaar=me->GetGUID(); + CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->point=point; + CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->malchezaar=me->GetGUID(); - infernals.push_back(Infernal->GetGUID()); - DoCast(Infernal, SPELL_INFERNAL_RELAY); + infernals.push_back(infernal->GetGUID()); + DoCast(infernal, SPELL_INFERNAL_RELAY); } Talk(SAY_SUMMON); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index a9f92521ef8..f438a117a5f 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -1001,6 +1001,8 @@ public: void Reset() OVERRIDE { + dummy_dragonAI::Reset(); + m_uiShadowBreathTimer = 20000; m_uiShadowFissureTimer = 5000; m_uiHatchEggTimer = 30000; @@ -1090,6 +1092,8 @@ public: void Reset() OVERRIDE { + dummy_dragonAI::Reset(); + m_uiShadowBreathTimer = 20000; m_uiShadowFissureTimer = 5000; m_uiAcolyteShadronTimer = 60000; @@ -1194,6 +1198,8 @@ public: void Reset() OVERRIDE { + dummy_dragonAI::Reset(); + m_uiShadowBreathTimer = 20000; m_uiShadowFissureTimer = 5000; m_uiAcolyteVesperonTimer = 60000; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index 557d6768790..bbd700b7edd 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -493,7 +493,7 @@ class npc_green_dragon_combat_trigger : public CreatureScript struct npc_green_dragon_combat_triggerAI : public BossAI { - npc_green_dragon_combat_triggerAI(Creature* creature) : BossAI(creature, DATA_VALITHRIA_DREAMWALKER) + npc_green_dragon_combat_triggerAI(Creature* creature) : BossAI(creature, DATA_VALITHRIA_DREAMWALKER), _evadeCheck(false) { } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp index 4ece79b0f7f..bbb3d666b32 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp @@ -112,6 +112,7 @@ public: Charge_Timer = 5000; StoneStrike_Timer = 10000; Dalronn_isDead = false; + Response_Timer = 0; Check_Timer = 5000; Enraged = false; @@ -280,6 +281,7 @@ public: Summon_Timer = 10000; Check_Timer = 5000; Skarvald_isDead = false; + Response_Timer = 0; AggroYell_Timer = 0; ghost = me->GetEntry() == NPC_DALRONN_GHOST; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp index a54a1b6bec7..f592a4b2bb2 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp @@ -159,6 +159,7 @@ public: void Reset() OVERRIDE { + m_bIsWalking = false; m_bIsPause = false; m_bIsActiveWithBJORN = false; m_bIsActiveWithHALDOR = false; diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h new file mode 100644 index 00000000000..21e82a1702d --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef AUCHENAI_CRYPTS_H_ +#define AUCHENAI_CRYPTS_H_ + +#define ACScriptName "instance_auchenai_crypts" + +uint32 const EncounterCount = 2; + +enum DataTypes +{ + // Encounter States/Boss GUIDs + DATA_SHIRRAK_THE_DEAD_WATCHER = 0, + DATA_EXARCH_MALADAAR = 1 +}; + +enum CreatureIds +{ +}; + +enum GameObjectIds +{ +}; + +template<class AI> +AI* GetAuchenaiCryptsAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, ACScriptName); +} + +#endif // AUCHENAI_CRYPTS_H_ diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp new file mode 100644 index 00000000000..56279f20e4c --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "auchenai_crypts.h" + +class instance_auchenai_crypts : public InstanceMapScript +{ + public: + instance_auchenai_crypts() : InstanceMapScript(ACScriptName, 558) { } + + struct instance_auchenai_crypts_InstanceMapScript : public InstanceScript + { + instance_auchenai_crypts_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + } + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_auchenai_crypts_InstanceMapScript(map); + } +}; + +void AddSC_instance_auchenai_crypts() +{ + new instance_auchenai_crypts(); +} diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp b/src/server/scripts/Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp new file mode 100644 index 00000000000..77a5841cb39 --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "mana_tombs.h" + +class instance_mana_tombs : public InstanceMapScript +{ + public: + instance_mana_tombs() : InstanceMapScript(MTScriptName, 557) { } + + struct instance_mana_tombs_InstanceMapScript : public InstanceScript + { + instance_mana_tombs_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + } + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_mana_tombs_InstanceMapScript(map); + } +}; + +void AddSC_instance_mana_tombs() +{ + new instance_mana_tombs(); +} diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/mana_tombs.h b/src/server/scripts/Outland/Auchindoun/ManaTombs/mana_tombs.h new file mode 100644 index 00000000000..9199ef1945b --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/mana_tombs.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MANA_TOMBS_H_ +#define MANA_TOMBS_H_ + +#define MTScriptName "instance_mana_tombs" + +uint32 const EncounterCount = 4; + +enum DataTypes +{ + // Encounter States/Boss GUIDs + DATA_PANDEMONIUS = 0, + DATA_TAVAROK = 1, + DATA_NEXUSPRINCE_SHAFFAR = 2, + DATA_YOR = 3 +}; + +enum CreatureIds +{ +}; + +enum GameObjectIds +{ +}; + +template<class AI> +AI* GetManaTombsAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, MTScriptName); +} + +#endif // MANA_TOMBS_H_ diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp index ade6c13aafe..af8a4390d96 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp @@ -71,20 +71,22 @@ class boss_anzu : public CreatureScript void Reset() OVERRIDE { + //_Reset(); + events.Reset(); _under33Percent = false; _under66Percent = false; } void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); events.ScheduleEvent(EVENT_PARALYZING_SCREECH, 14000); events.ScheduleEvent(EVENT_CYCLONE_OF_FEATHERS, 5000); } void JustDied(Unit* /*killer*/) OVERRIDE { - if (instance) - instance->SetData(DATA_ANZU, DONE); + _JustDied(); } void DamageTaken(Unit* /*killer*/, uint32 &damage) OVERRIDE @@ -153,12 +155,11 @@ class boss_anzu : public CreatureScript private: bool _under33Percent; bool _under66Percent; - }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new boss_anzuAI(creature); + return GetSethekkHallsAI<boss_anzuAI>(creature); } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp index 782db325496..be3a109b9f0 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp @@ -75,6 +75,7 @@ public: void Reset() OVERRIDE { + _Reset(); summon90 = false; summon50 = false; summon10 = false; @@ -82,6 +83,7 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); events.ScheduleEvent(EVENT_FLAME_SHOCK, 2000); events.ScheduleEvent(EVENT_ARCANE_SHOCK, 4000); events.ScheduleEvent(EVENT_FROST_SHOCK, 6000); @@ -93,18 +95,14 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { + _JustDied(); Talk(SAY_DEATH); - - if (instance) - instance->SetData(DATA_DARKWEAVER_SYTH, DONE); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* who) OVERRIDE { - if (rand()%2) - return; - - Talk(SAY_SLAY); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void JustSummoned(Creature* summoned) OVERRIDE @@ -196,7 +194,7 @@ public: CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new boss_darkweaver_sythAI(creature); + return GetSethekkHallsAI<boss_darkweaver_sythAI>(creature); } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp index 9d3aa623011..022ac3e9e4d 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp @@ -62,6 +62,7 @@ public: void Reset() OVERRIDE { + _Reset(); ArcaneVolley_Timer = 5000; Sheep_Timer = 8000; Blink_Timer = 35000; @@ -72,7 +73,6 @@ public: } void MoveInLineOfSight(Unit* who) OVERRIDE - { if (!me->GetVictim() && me->CanCreatureAttack(who)) { @@ -96,20 +96,20 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); Talk(SAY_AGGRO); } void JustDied(Unit* /*killer*/) OVERRIDE { + _JustDied(); Talk(SAY_DEATH); - - if (instance) - instance->SetData(DATA_TALON_KING_IKISS, DONE); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* who) OVERRIDE { - Talk(SAY_SLAY); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void UpdateAI(uint32 diff) OVERRIDE @@ -202,7 +202,7 @@ public: CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new boss_talon_king_ikissAI(creature); + return GetSethekkHallsAI<boss_talon_king_ikissAI>(creature); } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp index f380914506e..08cefb83c96 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,125 +15,100 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance - Sethekk Halls -SD%Complete: 50 -SDComment: Instance Data for Sethekk Halls instance -SDCategory: Auchindoun, Sethekk Halls -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" #include "sethekk_halls.h" -class instance_sethekk_halls : public InstanceMapScript +DoorData const doorData[] = { -public: - instance_sethekk_halls() : InstanceMapScript("instance_sethekk_halls", 556) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE - { - return new instance_sethekk_halls_InstanceMapScript(map); - } - - struct instance_sethekk_halls_InstanceMapScript : public InstanceScript - { - instance_sethekk_halls_InstanceMapScript(Map* map) : InstanceScript(map) - { - SetBossNumber(EncounterCount); - } + { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; - void Initialize() OVERRIDE - { - SetBossState(DATA_ANZU, NOT_STARTED); - iIkissDoorGUID = 0; - } +class instance_sethekk_halls : public InstanceMapScript +{ + public: + instance_sethekk_halls() : InstanceMapScript(SHScriptName, 556) { } - void OnCreatureCreate(Creature* creature) OVERRIDE + struct instance_sethekk_halls_InstanceMapScript : public InstanceScript { - if (creature->GetEntry() == NPC_ANZU) + instance_sethekk_halls_InstanceMapScript(Map* map) : InstanceScript(map) { - if (GetBossState(DATA_ANZU) == DONE) - creature->DisappearAndDie(); - else - SetBossState(DATA_ANZU, IN_PROGRESS); + SetBossNumber(EncounterCount); + LoadDoorData(doorData); } - } - void OnGameObjectCreate(GameObject* go) OVERRIDE - { - if (go->GetEntry() == GO_IKISS_DOOR) - iIkissDoorGUID = go->GetGUID(); - } - - bool SetBossState(uint32 type, EncounterState state) OVERRIDE - { - if (!InstanceScript::SetBossState(type, state)) - return false; + void OnCreatureCreate(Creature* creature) OVERRIDE + { + if (creature->GetEntry() == NPC_ANZU) + { + if (GetBossState(DATA_ANZU) == DONE) + creature->DisappearAndDie(); + else + SetBossState(DATA_ANZU, IN_PROGRESS); + } + } - switch (type) + void OnGameObjectCreate(GameObject* go) OVERRIDE { - case DATA_DARKWEAVER_SYTH: - break; - case DATA_TALON_KING_IKISS: - if (state == DONE) - DoUseDoorOrButton(iIkissDoorGUID, DAY*IN_MILLISECONDS); - break; - case DATA_ANZU: - break; - default: - break; + if (go->GetEntry() == GO_IKISS_DOOR) + AddDoor(go, true); } - return true; - } + void OnGameObjectRemove(GameObject* go) OVERRIDE + { + if (go->GetEntry() == GO_IKISS_DOOR) + AddDoor(go, false); + } - std::string GetSaveData() OVERRIDE - { - OUT_SAVE_INST_DATA; + std::string GetSaveData() OVERRIDE + { + OUT_SAVE_INST_DATA; - std::ostringstream saveStream; - saveStream << "S H " << GetBossSaveData(); + std::ostringstream saveStream; + saveStream << "S H " << GetBossSaveData(); - OUT_SAVE_INST_DATA_COMPLETE; - return saveStream.str(); - } + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } - void Load(const char* str) OVERRIDE - { - if (!str) + void Load(char const* str) OVERRIDE { - OUT_LOAD_INST_DATA_FAIL; - return; - } + if (!str) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - OUT_LOAD_INST_DATA(str); + OUT_LOAD_INST_DATA(str); - char dataHead1, dataHead2; + char dataHead1, dataHead2; - std::istringstream loadStream(str); - loadStream >> dataHead1 >> dataHead2; + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; - if (dataHead1 == 'S' && dataHead2 == 'H') - { - for (uint32 i = 0; i < EncounterCount; ++i) + if (dataHead1 == 'S' && dataHead2 == 'H') { - uint32 tmpState; - loadStream >> tmpState; - if (tmpState == IN_PROGRESS || tmpState > SPECIAL) - tmpState = NOT_STARTED; - SetBossState(i, EncounterState(tmpState)); + for (uint32 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + SetBossState(i, EncounterState(tmpState)); + } } + else + OUT_LOAD_INST_DATA_FAIL; + + OUT_LOAD_INST_DATA_COMPLETE; } - else - OUT_LOAD_INST_DATA_FAIL; + }; - OUT_LOAD_INST_DATA_COMPLETE; + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_sethekk_halls_InstanceMapScript(map); } - - protected: - uint64 iIkissDoorGUID; - }; }; void AddSC_instance_sethekk_halls() diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h index 86789e9982f..58b8d4d157c 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h @@ -15,13 +15,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEF_SETHEKK_HALLS_H -#define DEF_SETHEKK_HALLS_H +#ifndef SETHEKK_HALLS_H_ +#define SETHEKK_HALLS_H_ + +#define SHScriptName "instance_sethekk_halls" uint32 const EncounterCount = 3; enum DataTypes { + // Encounter States/Boss GUIDs DATA_DARKWEAVER_SYTH = 0, DATA_TALON_KING_IKISS = 1, DATA_ANZU = 2 @@ -38,4 +41,10 @@ enum GameObjectIds GO_IKISS_DOOR = 177203 }; -#endif +template<class AI> +AI* GetSethekkHallsAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, SHScriptName); +} + +#endif // SETHEKK_HALLS_H_ diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp index ffadfccecfe..1fa589af3a1 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp @@ -45,165 +45,146 @@ enum Spells SPELL_ENRAGE = 34970 }; -class boss_ambassador_hellmaw : public CreatureScript +enum Events { -public: - boss_ambassador_hellmaw() : CreatureScript("boss_ambassador_hellmaw") { } - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_ambassador_hellmawAI(creature); - } - - struct boss_ambassador_hellmawAI : public npc_escortAI - { - boss_ambassador_hellmawAI(Creature* creature) : npc_escortAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; + EVENT_CORROSIVE_ACID = 1, + EVENT_FEAR, + EVENT_BERSERK +}; - uint32 EventCheck_Timer; - uint32 CorrosiveAcid_Timer; - uint32 Fear_Timer; - uint32 Enrage_Timer; - bool Intro; - bool IsBanished; - bool Enraged; +class boss_ambassador_hellmaw : public CreatureScript +{ + public: + boss_ambassador_hellmaw() : CreatureScript("boss_ambassador_hellmaw") { } - void Reset() OVERRIDE + struct boss_ambassador_hellmawAI : public npc_escortAI { - EventCheck_Timer = 5000; - CorrosiveAcid_Timer = urand(5000, 10000); - Fear_Timer = urand(25000, 30000); - Enrage_Timer = 180000; - Intro = false; - IsBanished = true; - Enraged = false; - - if (instance && me->IsAlive()) + boss_ambassador_hellmawAI(Creature* creature) : npc_escortAI(creature) { - if (instance->GetData(TYPE_OVERSEER) != DONE) - DoCast(me, SPELL_BANISH, true); + _instance = creature->GetInstanceScript(); + _intro = false; } - } - void JustReachedHome() OVERRIDE - { - if (instance) - instance->SetData(TYPE_HELLMAW, FAIL); - } + void Reset() OVERRIDE + { + if (!me->IsAlive()) + return; - void MoveInLineOfSight(Unit* who) OVERRIDE + _events.Reset(); + _instance->SetBossState(DATA_AMBASSADOR_HELLMAW, NOT_STARTED); - { - if (me->HasAura(SPELL_BANISH)) - return; + _events.ScheduleEvent(EVENT_CORROSIVE_ACID, urand(5000, 10000)); + _events.ScheduleEvent(EVENT_FEAR, urand(25000, 30000)); + if (IsHeroic()) + _events.ScheduleEvent(EVENT_BERSERK, 180000); - npc_escortAI::MoveInLineOfSight(who); - } + DoAction(ACTION_AMBASSADOR_HELLMAW_BANISH); + } - void WaypointReached(uint32 /*waypointId*/) OVERRIDE - { - } + void MoveInLineOfSight(Unit* who) OVERRIDE + { + if (me->HasAura(SPELL_BANISH)) + return; - void DoIntro() - { - if (me->HasAura(SPELL_BANISH)) - me->RemoveAurasDueToSpell(SPELL_BANISH); + npc_escortAI::MoveInLineOfSight(who); + } - IsBanished = false; - Intro = true; + void WaypointReached(uint32 /*waypointId*/) OVERRIDE + { + } - if (instance) + void DoAction(int32 actionId) { - if (instance->GetData(TYPE_HELLMAW) != FAIL) + if (actionId == ACTION_AMBASSADOR_HELLMAW_INTRO) + DoIntro(); + else if (actionId == ACTION_AMBASSADOR_HELLMAW_BANISH) { - Talk(SAY_INTRO); - Start(true, false, 0, NULL, false, true); + if (_instance->GetData(DATA_FEL_OVERSEER) && me->HasAura(SPELL_BANISH)) + DoCast(me, SPELL_BANISH, true); // this will not work, because he is immune to banish } - - instance->SetData(TYPE_HELLMAW, IN_PROGRESS); } - } - void EnterCombat(Unit* /*who*/) OVERRIDE - { - Talk(SAY_AGGRO); - } + void DoIntro() + { + if (_intro) + return; - void KilledUnit(Unit* /*victim*/) OVERRIDE - { - Talk(SAY_SLAY); - } + _intro = true; - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); + if (me->HasAura(SPELL_BANISH)) + me->RemoveAurasDueToSpell(SPELL_BANISH); - if (instance) - instance->SetData(TYPE_HELLMAW, DONE); - } + Talk(SAY_INTRO); + Start(true, false, 0, NULL, false, true); + } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!Intro && !HasEscortState(STATE_ESCORT_ESCORTING)) + void EnterCombat(Unit* /*who*/) OVERRIDE { - if (EventCheck_Timer <= diff) - { - if (instance) - { - if (instance->GetData(TYPE_OVERSEER) == DONE) - { - DoIntro(); - return; - } - } - EventCheck_Timer = 5000; - return; - } - else - { - EventCheck_Timer -= diff; - return; - } + _instance->SetBossState(DATA_AMBASSADOR_HELLMAW, IN_PROGRESS); + Talk(SAY_AGGRO); } - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - - if (me->HasAura(SPELL_BANISH, 0)) + void KilledUnit(Unit* who) OVERRIDE { - EnterEvadeMode(); - return; + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } - if (CorrosiveAcid_Timer <= diff) + void JustDied(Unit* /*killer*/) OVERRIDE { - DoCastVictim(SPELL_CORROSIVE_ACID); - CorrosiveAcid_Timer = urand(15000, 25000); - } else CorrosiveAcid_Timer -= diff; + _instance->SetBossState(DATA_AMBASSADOR_HELLMAW, DONE); + Talk(SAY_DEATH); + } - if (Fear_Timer <= diff) + void UpdateEscortAI(uint32 const diff) OVERRIDE { - DoCast(me, SPELL_FEAR); - Fear_Timer = urand(20000, 35000); - } else Fear_Timer -= diff; + if (!UpdateVictim()) + return; - if (IsHeroic()) - { - if (!Enraged && Enrage_Timer <= diff) + if (me->HasAura(SPELL_BANISH)) + { + EnterEvadeMode(); + return; + } + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) { - DoCast(me, SPELL_ENRAGE); - Enraged = true; - } else Enrage_Timer -= diff; + switch (eventId) + { + case EVENT_CORROSIVE_ACID: + DoCastVictim(SPELL_CORROSIVE_ACID); + _events.ScheduleEvent(EVENT_CORROSIVE_ACID, urand(15000, 25000)); + break; + case EVENT_FEAR: + DoCastAOE(SPELL_FEAR); + _events.ScheduleEvent(EVENT_FEAR, urand(20000, 35000)); + break; + case EVENT_BERSERK: + DoCast(me, SPELL_ENRAGE, true); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); } - } - }; + private: + InstanceScript* _instance; + EventMap _events; + bool _intro; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<boss_ambassador_hellmawAI>(creature); + } }; void AddSC_boss_ambassador_hellmaw() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp index 573acfce5c2..ec3465a0bfc 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp @@ -50,112 +50,97 @@ enum BlackheartTheInciter enum Events { - EVENT_INCITE_CHAOS_WAIT = 1, - EVENT_INCITE_CHAOS = 2, - EVENT_CHARGE_ATTACK = 3, - EVENT_WAR_STOMP = 4 + EVENT_INCITE_CHAOS = 1, + EVENT_CHARGE_ATTACK = 2, + EVENT_WAR_STOMP = 3 }; class boss_blackheart_the_inciter : public CreatureScript { -public: - boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { } + public: + boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { } - struct boss_blackheart_the_inciterAI : public BossAI - { - boss_blackheart_the_inciterAI(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT) { } - - void Reset() OVERRIDE + struct boss_blackheart_the_inciterAI : public BossAI { - InciteChaos = false; - - if (instance) - instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, NOT_STARTED); - } + boss_blackheart_the_inciterAI(Creature* creature) : BossAI(creature, DATA_BLACKHEART_THE_INCITER) { } - void KilledUnit(Unit* /*victim*/) OVERRIDE - { - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); + void Reset() OVERRIDE + { + _Reset(); + } - if (instance) - instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, DONE); - } + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000); + events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000); + events.ScheduleEvent(EVENT_WAR_STOMP, 15000); - void EnterCombat(Unit* /*who*/) OVERRIDE - { - events.ScheduleEvent(EVENT_INCITE_CHAOS_WAIT, 15000); - events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000); - events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000); - events.ScheduleEvent(EVENT_WAR_STOMP, 15000); + Talk(SAY_AGGRO); + } - Talk(SAY_AGGRO); + void KilledUnit(Unit* who) OVERRIDE + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - if (instance) - instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, IN_PROGRESS); - } + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + Talk(SAY_DEATH); + } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_INCITE_CHAOS_WAIT: - InciteChaos = false; - events.ScheduleEvent(EVENT_INCITE_CHAOS_WAIT, 15000); - break; - case EVENT_INCITE_CHAOS: + switch (eventId) { - DoCast(me, SPELL_INCITE_CHAOS); - - std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); - for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + case EVENT_INCITE_CHAOS: { - Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (target && target->GetTypeId() == TYPEID_PLAYER) - me->CastSpell(target, SPELL_INCITE_CHAOS_B, true); + DoCast(me, SPELL_INCITE_CHAOS); + + std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); + for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + if (Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) + if (target->GetTypeId() == TYPEID_PLAYER) + me->CastSpell(target, SPELL_INCITE_CHAOS_B, true); + } + + DoResetThreat(); + events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000); + break; } - - DoResetThreat(); - InciteChaos = true; - events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000); - break; + case EVENT_CHARGE_ATTACK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_CHARGE); + events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000)); + break; + case EVENT_WAR_STOMP: + DoCast(me, SPELL_WAR_STOMP); + events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000)); + break; } - case EVENT_CHARGE_ATTACK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_CHARGE); - events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000)); - break; - case EVENT_WAR_STOMP: - DoCast(me, SPELL_WAR_STOMP); - events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000)); - break; } - } - DoMeleeAttackIfReady(); - } - private: - bool InciteChaos; - }; + DoMeleeAttackIfReady(); + } + }; - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_blackheart_the_inciterAI(creature); - } + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<boss_blackheart_the_inciterAI>(creature); + } }; void AddSC_boss_blackheart_the_inciter() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp index 088913b13d2..44ef5e8e42c 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp @@ -43,16 +43,23 @@ enum GrandmasterVorpil SPELL_BANISH = 38791, NPC_VOID_TRAVELER = 19226, + SPELL_SUMMON_VOID_TRAVELER_A = 33582, + SPELL_SUMMON_VOID_TRAVELER_B = 33583, + SPELL_SUMMON_VOID_TRAVELER_C = 33584, + SPELL_SUMMON_VOID_TRAVELER_D = 33585, + SPELL_SUMMON_VOID_TRAVELER_E = 33586, + SPELL_SACRIFICE = 33587, SPELL_SHADOW_NOVA = 33846, SPELL_EMPOWERING_SHADOWS = 33783, H_SPELL_EMPOWERING_SHADOWS = 39364, NPC_VOID_PORTAL = 19224, + SPELL_SUMMON_PORTAL = 33566, SPELL_VOID_PORTAL_VISUAL = 33569 }; -float VorpilPosition[3] = {-252.8820f, -264.3030f, 17.1f}; +Position const VorpilPosition = { -252.8820f, -264.3030f, 17.1f, 0.0f }; float VoidPortalCoords[5][3] = { @@ -71,254 +78,202 @@ enum Events EVENT_SUMMON_TRAVELER = 4 }; -class npc_voidtraveler : public CreatureScript +class boss_grandmaster_vorpil : public CreatureScript { -public: - npc_voidtraveler() : CreatureScript("npc_voidtraveler") { } + public: + boss_grandmaster_vorpil() : CreatureScript("boss_grandmaster_vorpil") { } - struct npc_voidtravelerAI : public ScriptedAI - { - npc_voidtravelerAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 VorpilGUID; - uint32 move; - bool sacrificed; - - void Reset() OVERRIDE + struct boss_grandmaster_vorpilAI : public BossAI { - VorpilGUID = 0; - move = 0; - sacrificed = false; - } - - void EnterCombat(Unit* /*who*/)OVERRIDE {} + boss_grandmaster_vorpilAI(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL) + { + _intro = false; + } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!VorpilGUID) + void Reset() OVERRIDE { - me->Kill(me); - return; + _Reset(); + _helpYell = false; } - if (move <= diff) + + void SummonPortals() { - Creature* Vorpil = Unit::GetCreature(*me, VorpilGUID); - if (!Vorpil) - { - VorpilGUID = 0; - return; - } + for (uint8 i = 0; i < 5; ++i) + if (Creature* portal = me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 3000000)) + portal->CastSpell(portal, SPELL_VOID_PORTAL_VISUAL, true); - if (sacrificed) - { - me->AddAura(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS, H_SPELL_EMPOWERING_SHADOWS), Vorpil); - Vorpil->ModifyHealth(int32(Vorpil->CountPctFromMaxHealth(4))); - DoCast(me, SPELL_SHADOW_NOVA, true); - me->Kill(me); - return; - } - me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0); - if (me->IsWithinDist(Vorpil, 3)) - { - DoCast(me, SPELL_SACRIFICE, false); - sacrificed = true; - move = 500; - return; - } - if (!Vorpil->IsInCombat() || Vorpil->isDead()) + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); + } + + void spawnVoidTraveler() + { + uint8 pos = urand(0, 4); + me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + if (!_helpYell) { - me->Kill(me); - return; + Talk(SAY_HELP); + _helpYell = true; } - move = 1000; - } else move -= diff; - } - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_voidtravelerAI(creature); - } -}; - -class boss_grandmaster_vorpil : public CreatureScript -{ -public: - boss_grandmaster_vorpil() : CreatureScript("boss_grandmaster_vorpil") { } - - struct boss_grandmaster_vorpilAI : public BossAI - { - boss_grandmaster_vorpilAI(Creature* creature) : BossAI(creature, DATA_GRANDMASTERVORPIL) - { - Intro = false; - } + } - void Reset() OVERRIDE - { - HelpYell = false; - sumportals = false; - destroyPortals(); + void KilledUnit(Unit* who) OVERRIDE + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - if (instance) - instance->SetData(DATA_GRANDMASTERVORPILEVENT, NOT_STARTED); - } + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + Talk(SAY_DEATH); + } - void summonPortals() - { - if (!sumportals) + void EnterCombat(Unit* /*who*/) OVERRIDE { - for (uint8 i = 0; i < 5; ++i) - { - Creature* Portal = NULL; - Portal = me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 3000000); - if (Portal) - { - PortalsGuid[i] = Portal->GetGUID(); - Portal->CastSpell(Portal, SPELL_VOID_PORTAL_VISUAL, false); - } - } - sumportals = true; - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); + _EnterCombat(); + events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(7000, 14000)); + if (IsHeroic()) + events.ScheduleEvent(EVENT_BANISH, 17000); + events.ScheduleEvent(EVENT_DRAW_SHADOWS, 45000); + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 90000); + + Talk(SAY_AGGRO); + SummonPortals(); } - } - void destroyPortals() - { - if (sumportals) + void MoveInLineOfSight(Unit* who) OVERRIDE { - for (uint8 i = 0; i < 5; ++i) + BossAI::MoveInLineOfSight(who); + + if (!_intro && me->IsWithinLOSInMap(who) && me->IsWithinDistInMap(who, 100) && me->IsValidAttackTarget(who)) { - Unit* Portal = Unit::GetUnit(*me, PortalsGuid[i]); - if (Portal && Portal->IsAlive()) - Portal->DealDamage(Portal, Portal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - PortalsGuid[i] = 0; + Talk(SAY_INTRO); + _intro = true; } - sumportals = false; } - } - void spawnVoidTraveler() - { - int pos = urand(0, 4); - me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - if (!HelpYell) + void UpdateAI(uint32 diff) OVERRIDE { - Talk(SAY_HELP); - HelpYell = true; - } - } + if (!UpdateVictim()) + return; - void JustSummoned(Creature* summoned) OVERRIDE - { - if (summoned && summoned->GetEntry() == NPC_VOID_TRAVELER) - CAST_AI(npc_voidtraveler::npc_voidtravelerAI, summoned->AI())->VorpilGUID = me->GetGUID(); - } + events.Update(diff); - void KilledUnit(Unit* /*victim*/) OVERRIDE - { - Talk(SAY_SLAY); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); - destroyPortals(); + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SHADOWBOLT_VOLLEY: + DoCast(me, SPELL_SHADOWBOLT_VOLLEY); + events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(15000, 30000)); + break; + case EVENT_BANISH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, false)) + DoCast(target, SPELL_BANISH); + events.ScheduleEvent(EVENT_BANISH, 16000); + break; + case EVENT_DRAW_SHADOWS: + { + Map* map = me->GetMap(); + Map::PlayerList const &PlayerList = map->GetPlayers(); + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player* i_pl = i->GetSource()) + if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH)) + i_pl->TeleportTo(me->GetMapId(), VorpilPosition.GetPositionX(), VorpilPosition.GetPositionY(), VorpilPosition.GetPositionZ(), VorpilPosition.GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT); + + me->SetPosition(VorpilPosition); + DoCast(me, SPELL_DRAW_SHADOWS, true); + DoCast(me, SPELL_RAIN_OF_FIRE); + events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000); + events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30000); + break; + } + case EVENT_SUMMON_TRAVELER: + spawnVoidTraveler(); + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10000); + // enrage at 20% + if (HealthBelowPct(20)) + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); + break; + } + } - if (instance) - instance->SetData(DATA_GRANDMASTERVORPILEVENT, DONE); - } + DoMeleeAttackIfReady(); + } + + private: + bool _intro; + bool _helpYell; + }; - void EnterCombat(Unit* /*who*/) OVERRIDE + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(7000, 14000)); - if (IsHeroic()) - events.ScheduleEvent(EVENT_BANISH, 17000); - events.ScheduleEvent(EVENT_DRAW_SHADOWS, 45000); - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 90000); - - Talk(SAY_AGGRO); - summonPortals(); - - if (instance) - instance->SetData(DATA_GRANDMASTERVORPILEVENT, IN_PROGRESS); - _EnterCombat(); + return GetShadowLabyrinthAI<boss_grandmaster_vorpilAI>(creature); } +}; - void MoveInLineOfSight(Unit* who) OVERRIDE +class npc_voidtraveler : public CreatureScript +{ + public: + npc_voidtraveler() : CreatureScript("npc_voidtraveler") { } + struct npc_voidtravelerAI : public ScriptedAI { - ScriptedAI::MoveInLineOfSight(who); - - if (!Intro && me->IsWithinLOSInMap(who)&& me->IsWithinDistInMap(who, 100) && me->IsValidAttackTarget(who)) + npc_voidtravelerAI(Creature* creature) : ScriptedAI(creature) { - Talk(SAY_INTRO); - Intro = true; + _instance = creature->GetInstanceScript(); } - } - - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; - events.Update(diff); + void Reset() OVERRIDE + { + _moveTimer = 0; + _sacrificed = false; + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + void EnterCombat(Unit* /*who*/) OVERRIDE { } - while (uint32 eventId = events.ExecuteEvent()) + void UpdateAI(uint32 diff) OVERRIDE { - switch (eventId) + if (_moveTimer <= diff) { - case EVENT_SHADOWBOLT_VOLLEY: - DoCast(me, SPELL_SHADOWBOLT_VOLLEY); - events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(15000, 30000)); - break; - case EVENT_BANISH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30, false)) - DoCast(target, SPELL_BANISH); - events.ScheduleEvent(EVENT_BANISH, 16000); - break; - case EVENT_DRAW_SHADOWS: - { - Map* map = me->GetMap(); - Map::PlayerList const &PlayerList = map->GetPlayers(); - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* i_pl = i->GetSource()) - if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH)) - i_pl->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT); - - me->SetPosition(VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f); - DoCast(me, SPELL_DRAW_SHADOWS, true); - DoCast(me, SPELL_RAIN_OF_FIRE); - events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000); - events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30000); - break; - } - case EVENT_SUMMON_TRAVELER: - spawnVoidTraveler(); - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10000); - //enrage at 20% - if (HealthBelowPct(20)) - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); - break; + Creature* Vorpil = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_GRANDMASTER_VORPIL)); + if (!Vorpil) + return; + + if (_sacrificed) + { + DoCastAOE(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS, H_SPELL_EMPOWERING_SHADOWS), true); + DoCast(me, SPELL_SHADOW_NOVA, true); + me->Kill(me); + return; + } + me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0); + if (me->IsWithinDist(Vorpil, 3)) + { + DoCast(me, SPELL_SACRIFICE, false); + _sacrificed = true; + _moveTimer = 500; + return; + } + _moveTimer = 1000; } + else + _moveTimer -= diff; } - DoMeleeAttackIfReady(); - } private: - bool Intro, HelpYell; - bool sumportals; - uint64 PortalsGuid[5]; - + InstanceScript* _instance; + uint32 _moveTimer; + bool _sacrificed; + }; - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_grandmaster_vorpilAI(creature); - } + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<npc_voidtravelerAI>(creature); + } }; void AddSC_boss_grandmaster_vorpil() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp index 99078b3b15d..5e2e26b578a 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp @@ -25,8 +25,8 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "shadow_labyrinth.h" -#include "SpellInfo.h" enum Murmur { @@ -54,149 +54,234 @@ enum Events class boss_murmur : public CreatureScript { -public: - boss_murmur() : CreatureScript("boss_murmur") { } + public: + boss_murmur() : CreatureScript("boss_murmur") { } - struct boss_murmurAI : public BossAI - { - boss_murmurAI(Creature* creature) : BossAI(creature, DATA_MURMUREVENT) + struct boss_murmurAI : public BossAI { - SetCombatMovement(false); - } - - void Reset() OVERRIDE - { - events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); - events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(8000, 20000)); - events.ScheduleEvent(EVENT_RESONANCE, 5000); - events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000)); - if (IsHeroic()) + boss_murmurAI(Creature* creature) : BossAI(creature, DATA_MURMUR) { - events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); - events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000); + SetCombatMovement(false); } - //database should have `RegenHealth`=0 to prevent regen - uint32 hp = me->CountPctFromMaxHealth(40); - if (hp) me->SetHealth(hp); - me->ResetPlayerDamageReq(); - } + void Reset() OVERRIDE + { + _Reset(); + events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); + events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(8000, 20000)); + events.ScheduleEvent(EVENT_RESONANCE, 5000); + events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000)); + if (IsHeroic()) + { + events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); + events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000); + } - void SonicBoomEffect() - { - ThreatContainer::StorageType const &t_list = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + // database should have `RegenHealth`=0 to prevent regen + uint32 hp = me->CountPctFromMaxHealth(40); + if (hp) + me->SetHealth(hp); + me->ResetPlayerDamageReq(); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE { - Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (target && target->GetTypeId() == TYPEID_PLAYER) - { - //Not do anything without aura, spell can be resisted! - if (target->HasAura(SPELL_SONIC_BOOM_CAST) && me->IsWithinDistInMap(target, 34.0f)) - { - //This will be wrong calculation. Also, comments suggest it must deal damage - target->SetHealth(target->CountPctFromMaxHealth(20)); - } - } + _EnterCombat(); } - } - void EnterCombat(Unit* /*who*/) OVERRIDE {} + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } - // Sonic Boom instant damage (needs core fix instead of this) - void SpellHitTarget(Unit* target, const SpellInfo* spell) OVERRIDE - { - if (target && target->IsAlive() && spell && spell->Id == uint32(SPELL_SONIC_BOOM_EFFECT)) - me->DealDamage(target, (target->GetHealth()*90)/100, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NATURE, spell); - } + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) OVERRIDE - { - //Return since we have no target or casting - if (!UpdateVictim() || me->IsNonMeleeSpellCasted(false)) - return; + events.Update(diff); - events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_SONIC_BOOM: - Talk(EMOTE_SONIC_BOOM); - DoCast(me, SPELL_SONIC_BOOM_CAST); - DoCast(me, SPELL_SONIC_BOOM_EFFECT, true); - SonicBoomEffect(); - events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); - events.ScheduleEvent(EVENT_RESONANCE, 1500); - break; - case EVENT_MURMURS_TOUCH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true)) - DoCast(target, SPELL_MURMURS_TOUCH); - events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(25000, 35000)); - break; - case EVENT_RESONANCE: - if (!(me->IsWithinMeleeRange(me->GetVictim()))) - { - DoCast(me, SPELL_RESONANCE); - events.ScheduleEvent(EVENT_RESONANCE, 5000); - } - break; - case EVENT_MAGNETIC_PULL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive()) + switch (eventId) + { + case EVENT_SONIC_BOOM: + Talk(EMOTE_SONIC_BOOM); + DoCast(me, SPELL_SONIC_BOOM_CAST); + events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); + events.ScheduleEvent(EVENT_RESONANCE, 1500); + break; + case EVENT_MURMURS_TOUCH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true)) + DoCast(target, SPELL_MURMURS_TOUCH); + events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(25000, 35000)); + break; + case EVENT_RESONANCE: + if (!(me->IsWithinMeleeRange(me->GetVictim()))) + { + DoCast(me, SPELL_RESONANCE); + events.ScheduleEvent(EVENT_RESONANCE, 5000); + } + break; + case EVENT_MAGNETIC_PULL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { DoCast(target, SPELL_MAGNETIC_PULL); - events.ScheduleEvent(EVENT_MAGNETIC_PULL, 15000+rand()%15000); + events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000)); break; } - events.ScheduleEvent(EVENT_MAGNETIC_PULL, 500); - break; - case EVENT_THUNDERING_STORM: - { - ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) - if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid())) - if (target->IsAlive() && !me->IsWithinDist(target, 35, false)) - DoCast(target, SPELL_THUNDERING_STORM, true); - events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); - break; - } - case EVENT_SONIC_SHOCK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20, false)) - if (target->IsAlive()) + events.ScheduleEvent(EVENT_MAGNETIC_PULL, 500); + break; + case EVENT_THUNDERING_STORM: + DoCastAOE(SPELL_THUNDERING_STORM, true); + events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); + break; + case EVENT_SONIC_SHOCK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, false)) DoCast(target, SPELL_SONIC_SHOCK); - events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000+rand()%10000); - break; + events.ScheduleEvent(EVENT_SONIC_SHOCK, urand(10000, 20000)); + break; + } + } + + // Select nearest most aggro target if top aggro too far + if (!me->isAttackReady()) + return; + + if (!me->IsWithinMeleeRange(me->GetVictim())) + { + ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); + for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) + if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid())) + if (me->IsWithinMeleeRange(target)) + { + me->TauntApply(target); + break; + } } + + DoMeleeAttackIfReady(); } + }; - // Select nearest most aggro target if top aggro too far - if (!me->isAttackReady()) - return; + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<boss_murmurAI>(creature); + } +}; - if (!me->IsWithinMeleeRange(me->GetVictim())) +// 33923, 38796 - Sonic Boom +class spell_murmur_sonic_boom : public SpellScriptLoader +{ + public: + spell_murmur_sonic_boom() : SpellScriptLoader("spell_murmur_sonic_boom") { } + + class spell_murmur_sonic_boom_SpellScript : public SpellScript + { + PrepareSpellScript(spell_murmur_sonic_boom_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE { - ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) - if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid())) - if (target->IsAlive() && me->IsWithinMeleeRange(target)) - { - me->TauntApply(target); - break; - } + if (!sSpellMgr->GetSpellInfo(SPELL_SONIC_BOOM_EFFECT)) + return false; + return true; + } + + void HandleEffect(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell((Unit*)NULL, SPELL_SONIC_BOOM_EFFECT, true); } - DoMeleeAttackIfReady(); + void Register() OVERRIDE + { + OnEffectHit += SpellEffectFn(spell_murmur_sonic_boom_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_murmur_sonic_boom_SpellScript(); } - }; +}; + +// 33666, 38795 - Sonic Boom Effect +class spell_murmur_sonic_boom_effect : public SpellScriptLoader +{ + public: + spell_murmur_sonic_boom_effect() : SpellScriptLoader("spell_murmur_sonic_boom_effect") { } + + class spell_murmur_sonic_boom_effect_SpellScript : public SpellScript + { + PrepareSpellScript(spell_murmur_sonic_boom_effect_SpellScript); + + void CalcDamage() + { + if (Unit* target = GetHitUnit()) + SetHitDamage(target->CountPctFromMaxHealth(80)); /// @todo: find correct value + } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_murmurAI(creature); - } + void Register() OVERRIDE + { + OnHit += SpellHitFn(spell_murmur_sonic_boom_effect_SpellScript::CalcDamage); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_murmur_sonic_boom_effect_SpellScript(); + } +}; + +class ThunderingStormCheck +{ + public: + ThunderingStormCheck(WorldObject* source) : _source(source) { } + + bool operator()(WorldObject* obj) + { + float distSq = _source->GetExactDist2dSq(obj); + return distSq < (25.0f * 25.0f) || distSq > (100.0f * 100.0f); + } + + private: + WorldObject const* _source; + float _dist; +}; + +// 39365 - Thundering Storm +class spell_murmur_thundering_storm : public SpellScriptLoader +{ + public: + spell_murmur_thundering_storm() : SpellScriptLoader("spell_murmur_thundering_storm") { } + + class spell_murmur_thundering_storm_SpellScript : public SpellScript + { + PrepareSpellScript(spell_murmur_thundering_storm_SpellScript); + + void FilterTarget(std::list<WorldObject*>& targets) + { + targets.remove_if(ThunderingStormCheck(GetCaster())); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_murmur_thundering_storm_SpellScript::FilterTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_murmur_thundering_storm_SpellScript(); + } }; void AddSC_boss_murmur() { new boss_murmur(); + new spell_murmur_sonic_boom(); + new spell_murmur_sonic_boom_effect(); + new spell_murmur_thundering_storm(); } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp index 9a507979d8d..a401a74273f 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,210 +15,178 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance_Shadow_Labyrinth -SD%Complete: 85 -SDComment: Some cleanup left along with save -SDCategory: Auchindoun, Shadow Labyrinth -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" +#include "ScriptedCreature.h" #include "shadow_labyrinth.h" -/* Shadow Labyrinth encounters: -1 - Ambassador Hellmaw event -2 - Blackheart the Inciter event -3 - Grandmaster Vorpil event -4 - Murmur event -*/ +DoorData const doorData[] = +{ + { GO_REFECTORY_DOOR, DATA_BLACKHEART_THE_INCITER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_SCREAMING_HALL_DOOR, DATA_GRANDMASTER_VORPIL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; class instance_shadow_labyrinth : public InstanceMapScript { -public: - instance_shadow_labyrinth() : InstanceMapScript("instance_shadow_labyrinth", 555) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE - { - return new instance_shadow_labyrinth_InstanceMapScript(map); - } - - struct instance_shadow_labyrinth_InstanceMapScript : public InstanceScript - { - instance_shadow_labyrinth_InstanceMapScript(Map* map) : InstanceScript(map) {} - - uint32 m_auiEncounter[EncounterCount]; - std::string str_data; - - uint64 m_uiRefectoryDoorGUID; - uint64 m_uiScreamingHallDoorGUID; - - uint64 m_uiGrandmasterVorpil; - uint32 m_uiFelOverseerCount; + public: + instance_shadow_labyrinth() : InstanceMapScript(SLScriptName, 555) { } - void Initialize() OVERRIDE + struct instance_shadow_labyrinth_InstanceMapScript : public InstanceScript { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiRefectoryDoorGUID = 0; - m_uiScreamingHallDoorGUID = 0; - - m_uiGrandmasterVorpil = 0; - m_uiFelOverseerCount = 0; - } + instance_shadow_labyrinth_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + LoadDoorData(doorData); - bool IsEncounterInProgress() const OVERRIDE - { - for (uint8 i = 0; i < EncounterCount; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; + AmbassadorHellmawGUID = 0; + GrandmasterVorpilGUID = 0; + FelOverseerCount = 0; + } - return false; - } + void OnCreatureCreate(Creature* creature) OVERRIDE + { + switch (creature->GetEntry()) + { + case NPC_AMBASSADOR_HELLMAW: + AmbassadorHellmawGUID = creature->GetGUID(); + break; + case NPC_GRANDMASTER_VORPIL: + GrandmasterVorpilGUID = creature->GetGUID(); + break; + case NPC_FEL_OVERSEER: + if (creature->IsAlive()) + { + ++FelOverseerCount; + if (Creature* hellmaw = instance->GetCreature(AmbassadorHellmawGUID)) + hellmaw->AI()->DoAction(ACTION_AMBASSADOR_HELLMAW_BANISH); + } + break; + default: + break; + } + } - void OnGameObjectCreate(GameObject* go) OVERRIDE - { - switch (go->GetEntry()) + void OnGameObjectCreate(GameObject* go) OVERRIDE { - case REFECTORY_DOOR: - m_uiRefectoryDoorGUID = go->GetGUID(); - if (m_auiEncounter[2] == DONE) - go->SetGoState(GO_STATE_ACTIVE); - break; - case SCREAMING_HALL_DOOR: - m_uiScreamingHallDoorGUID = go->GetGUID(); - if (m_auiEncounter[3] == DONE) - go->SetGoState(GO_STATE_ACTIVE); - break; + switch (go->GetEntry()) + { + case GO_REFECTORY_DOOR: + case GO_SCREAMING_HALL_DOOR: + AddDoor(go, true); + break; + default: + break; + } } - } - void OnCreatureCreate(Creature* creature) OVERRIDE - { - switch (creature->GetEntry()) + void OnGameObjectRemove(GameObject* go) OVERRIDE { - case 18732: - m_uiGrandmasterVorpil = creature->GetGUID(); - break; - case 18796: - if (creature->IsAlive()) - { - ++m_uiFelOverseerCount; - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Shadow Labyrinth: counting %u Fel Overseers.", m_uiFelOverseerCount); - } - break; + switch (go->GetEntry()) + { + case GO_REFECTORY_DOOR: + case GO_SCREAMING_HALL_DOOR: + AddDoor(go, false); + break; + default: + break; + } } - } - void SetData(uint32 type, uint32 uiData) OVERRIDE - { - switch (type) + void OnUnitDeath(Unit* unit) { - case TYPE_HELLMAW: - m_auiEncounter[0] = uiData; - break; + Creature* creature = unit->ToCreature(); + if (!creature) + return; - case TYPE_OVERSEER: - if (uiData != DONE) - { - TC_LOG_ERROR(LOG_FILTER_TSCR, "Shadow Labyrinth: TYPE_OVERSEER did not expect other data than DONE"); - return; - } - if (m_uiFelOverseerCount) - { - --m_uiFelOverseerCount; + if (creature->GetEntry() == NPC_FEL_OVERSEER) + { + if (FelOverseerCount) + --FelOverseerCount; - if (m_uiFelOverseerCount) - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Shadow Labyrinth: %u Fel Overseers left to kill.", m_uiFelOverseerCount); - else - { - m_auiEncounter[1] = DONE; - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Shadow Labyrinth: TYPE_OVERSEER == DONE"); - } - } - break; - - case DATA_BLACKHEARTTHEINCITEREVENT: - if (uiData == DONE) - DoUseDoorOrButton(m_uiRefectoryDoorGUID); - m_auiEncounter[2] = uiData; - break; - - case DATA_GRANDMASTERVORPILEVENT: - if (uiData == DONE) - DoUseDoorOrButton(m_uiScreamingHallDoorGUID); - m_auiEncounter[3] = uiData; - break; - - case DATA_MURMUREVENT: - m_auiEncounter[4] = uiData; - break; + if (!FelOverseerCount) + if (Creature* hellmaw = instance->GetCreature(AmbassadorHellmawGUID)) + hellmaw->AI()->DoAction(ACTION_AMBASSADOR_HELLMAW_INTRO); + } } - if (uiData == DONE) + uint32 GetData(uint32 type) const OVERRIDE { - if (type == TYPE_OVERSEER && m_uiFelOverseerCount != 0) - return; + switch (type) + { + case DATA_FEL_OVERSEER: + return !FelOverseerCount ? 1 : 0; + default: + break; + } + return 0; + } + uint64 GetData64(uint32 type) const OVERRIDE + { + switch (type) + { + case DATA_GRANDMASTER_VORPIL: + return GrandmasterVorpilGUID; + default: + break; + } + return 0; + } + + std::string GetSaveData() OVERRIDE + { OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' - << m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' << m_auiEncounter[4]; + saveStream << "S L " << GetBossSaveData(); - str_data = saveStream.str(); - - SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); } - } - uint32 GetData(uint32 type) const OVERRIDE - { - switch (type) + void Load(char const* str) OVERRIDE { - case TYPE_HELLMAW: return m_auiEncounter[0]; - case TYPE_OVERSEER: return m_auiEncounter[1]; - case DATA_GRANDMASTERVORPILEVENT: return m_auiEncounter[3]; - case DATA_MURMUREVENT: return m_auiEncounter[4]; - } - return false; - } + if (!str) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - uint64 GetData64(uint32 identifier) const OVERRIDE - { - if (identifier == DATA_GRANDMASTERVORPIL) - return m_uiGrandmasterVorpil; + OUT_LOAD_INST_DATA(str); - return 0; - } + char dataHead1, dataHead2; - std::string GetSaveData() OVERRIDE - { - return str_data; - } - - void Load(const char* in) OVERRIDE - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; - OUT_LOAD_INST_DATA(in); + if (dataHead1 == 'S' && dataHead2 == 'L') + { + for (uint32 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + SetBossState(i, EncounterState(tmpState)); + } + } + else + OUT_LOAD_INST_DATA_FAIL; - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4]; + OUT_LOAD_INST_DATA_COMPLETE; + } - for (uint8 i = 0; i < EncounterCount; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; + protected: + uint64 AmbassadorHellmawGUID; + uint64 GrandmasterVorpilGUID; + uint32 FelOverseerCount; + }; - OUT_LOAD_INST_DATA_COMPLETE; + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_shadow_labyrinth_InstanceMapScript(map); } - }; - }; void AddSC_instance_shadow_labyrinth() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h index 8fdb60b32a6..fd073903748 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,26 +15,49 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEF_SHADOW_LABYRINTH_H -#define DEF_SHADOW_LABYRINTH_H +#ifndef SHADOW_LABYRINTH_H_ +#define SHADOW_LABYRINTH_H_ -uint32 const EncounterCount = 5; +#define SLScriptName "instance_shadow_labyrinth" + +uint32 const EncounterCount = 4; enum DataTypes { - TYPE_HELLMAW = 1, - TYPE_OVERSEER = 2, - DATA_BLACKHEARTTHEINCITEREVENT = 3, - DATA_GRANDMASTERVORPILEVENT = 4, - DATA_MURMUREVENT = 5, - DATA_GRANDMASTERVORPIL = 6 + // Encounter States/Boss GUIDs + DATA_AMBASSADOR_HELLMAW = 0, + DATA_BLACKHEART_THE_INCITER = 1, + DATA_GRANDMASTER_VORPIL = 2, + DATA_MURMUR = 3, + + // Additional Data + DATA_FEL_OVERSEER = 4 +}; + +enum CreatureIds +{ + NPC_AMBASSADOR_HELLMAW = 18731, + NPC_GRANDMASTER_VORPIL = 18732, + NPC_FEL_OVERSEER = 18796 }; -enum Objects +enum GameObjectIds { - REFECTORY_DOOR = 183296, // door opened when blackheart the inciter dies - SCREAMING_HALL_DOOR = 183295 // door opened when grandmaster vorpil dies + GO_REFECTORY_DOOR = 183296, // door opened when blackheart the inciter dies + GO_SCREAMING_HALL_DOOR = 183295 // door opened when grandmaster vorpil dies }; -#endif +enum Misc +{ + ACTION_AMBASSADOR_HELLMAW_INTRO = 1, + ACTION_AMBASSADOR_HELLMAW_BANISH = 2, +}; + +template<class AI> +AI* GetShadowLabyrinthAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, SLScriptName); +} + +#endif // SHADOW_LABYRINTH_H_ diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 4dedc774bb8..279a846140c 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -478,6 +478,7 @@ public: { instance = creature->GetInstanceScript(); DoCast(me, SPELL_DUAL_WIELD, true); + AkamaGUID = 0; } void Reset() OVERRIDE; @@ -1081,7 +1082,7 @@ public: { case EVENT_SHADOW_BLAST: me->GetMotionMaster()->Clear(false); - if (!me->IsWithinDistInMap(me->GetVictim(), 50)||!me->IsWithinLOSInMap(me->GetVictim())) + if (me->GetVictim() && (!me->IsWithinDistInMap(me->GetVictim(), 50) || !me->IsWithinLOSInMap(me->GetVictim()))) me->GetMotionMaster()->MoveChase(me->GetVictim(), 30); else me->GetMotionMaster()->MoveIdle(); diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt index c828c6dfbcf..84cbbc3c30c 100644 --- a/src/server/scripts/Outland/CMakeLists.txt +++ b/src/server/scripts/Outland/CMakeLists.txt @@ -74,19 +74,23 @@ set(scripts_STAT_SRCS Outland/TempestKeep/arcatraz/arcatraz.cpp Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp + Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp + Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp - Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp + Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp + Outland/Auchindoun/ManaTombs/mana_tombs.h Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp + Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp Outland/Auchindoun/SethekkHalls/boss_anzu.cpp Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp Outland/Auchindoun/SethekkHalls/sethekk_halls.h - Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp + Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp + Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h - Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp Outland/boss_doomwalker.cpp Outland/zone_terokkar_forest.cpp Outland/zone_hellfire_peninsula.cpp diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index 4499cb98475..ff66dcb550c 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -151,6 +151,8 @@ public: Intro = false; JustCreated = true; creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); // set it only once on Creature create (no need do intro if wiped) + for (uint8 i = 0; i < 4; ++i) + ShieldGeneratorChannel[i] = 0; } InstanceScript* instance; @@ -201,17 +203,20 @@ public: JustCreated = false; } else CanAttack = true; - for (uint8 i = 0; i < 4; ++i) - if (Unit* remo = Unit::GetUnit(*me, ShieldGeneratorChannel[i])) - remo->setDeathState(JUST_DIED); + { + if (ShieldGeneratorChannel[i]) + { + if (Unit* remo = Unit::GetUnit(*me, ShieldGeneratorChannel[i])) + { + remo->setDeathState(JUST_DIED); + ShieldGeneratorChannel[i] = 0; + } + } + } if (instance) instance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED); - ShieldGeneratorChannel[0] = 0; - ShieldGeneratorChannel[1] = 0; - ShieldGeneratorChannel[2] = 0; - ShieldGeneratorChannel[3] = 0; me->SetCorpseDelay(1000*60*60); } |