diff --git a/data/sql/updates/db_world/2023_07_15_00.sql b/data/sql/updates/db_world/2023_07_15_00.sql new file mode 100644 index 000000000..34189bd95 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_15_00.sql @@ -0,0 +1,3 @@ +-- DB update 2023_07_12_00 -> 2023_07_15_00 +-- +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (22038, 22482) AND (`source_type` = 0) AND (`id` IN (12)); diff --git a/data/sql/updates/db_world/2023_07_15_01.sql b/data/sql/updates/db_world/2023_07_15_01.sql new file mode 100644 index 000000000..0e2994843 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_15_01.sql @@ -0,0 +1,8 @@ +-- DB update 2023_07_15_00 -> 2023_07_15_01 +-- +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23168; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23168); +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`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(23168, 0, 0, 0, 0, 0, 100, 0, 5000, 9000, 10000, 12000, 0, 11, 10966, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Or\'kaos the Insane - In Combat - Cast \'Uppercut\''), +(23168, 0, 1, 0, 0, 0, 100, 0, 3000, 5000, 6000, 10000, 0, 11, 15496, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Or\'kaos the Insane - In Combat - Cast \'Cleave\' '), +(23168, 0, 2, 0, 0, 0, 100, 0, 7000, 9000, 6000, 10000, 0, 11, 17547, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Or\'kaos the Insane - In Combat - Cast \'Mortal Strike\''); diff --git a/data/sql/updates/db_world/2023_07_15_02.sql b/data/sql/updates/db_world/2023_07_15_02.sql new file mode 100644 index 000000000..faec06eab --- /dev/null +++ b/data/sql/updates/db_world/2023_07_15_02.sql @@ -0,0 +1,5 @@ +-- DB update 2023_07_15_01 -> 2023_07_15_02 +-- +DELETE FROM `spell_proc_event` WHERE `entry` IN (38319); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `procPhase`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(38319,0,0,0,0,0,0,0,0,0,0,50000); diff --git a/data/sql/updates/db_world/2023_07_15_03.sql b/data/sql/updates/db_world/2023_07_15_03.sql new file mode 100644 index 000000000..8085bed37 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_15_03.sql @@ -0,0 +1,43 @@ +-- DB update 2023_07_15_02 -> 2023_07_15_03 +-- +DELETE FROM `reference_loot_template` WHERE `Entry` IN (526791, 526792); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(526791, 21929, 0, 0, 0, 1, 1, 1, 1, 'Flame Spessarite'), +(526791, 23077, 0, 0, 0, 1, 1, 1, 1, 'Blood Garnet'), +(526791, 23107, 0, 0, 0, 1, 1, 1, 1, 'Shadow Draenite'), +(526791, 23112, 0, 0, 0, 1, 1, 1, 1, 'Golden Draenite'), +(526791, 23079, 0, 0, 0, 1, 1, 1, 1, 'Deep Peridot'), +(526791, 23117, 0, 0, 0, 1, 1, 1, 1, 'Azure Moonstone'), +(526792, 23436, 0, 0, 0, 1, 1, 1, 1, 'Living Ruby'), +(526792, 23437, 0, 0, 0, 1, 1, 1, 1, 'Talasite'), +(526792, 23438, 0, 0, 0, 1, 1, 1, 1, 'Star of Eluna'), +(526792, 23439, 0, 0, 0, 1, 1, 1, 1, 'Noble Topaz'), +(526792, 23441, 0, 0, 0, 1, 1, 1, 1, 'Dawnstone'), +(526792, 23440, 0, 0, 0, 1, 1, 1, 1, 'Nightseye'); + +DELETE FROM `item_loot_template` WHERE `Entry` IN (25419, 25422, 25423, 25424) AND (`Item` IN (21929, 23077, 23079, 23107, 23112, 23117, 23436, 23437, 23438, 23439, 23440, 23441, 0, 1, 2, 3, 4, 5)); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(25424, 0, 526791, 100, 0, 1, 0, 1, 1, 'Gem-Stuffed Envelope - Uncommon TBC Gems (ReferenceTable)'), +(25424, 1, 526791, 55, 0, 1, 1, 1, 1, 'Gem-Stuffed Envelope - Uncommon TBC Gems (ReferenceTable)'), +(25424, 2, 526791, 55, 0, 1, 2, 1, 1, 'Gem-Stuffed Envelope - Uncommon TBC Gems (ReferenceTable)'), +(25424, 3, 526792, 4, 0, 1, 0, 1, 1, 'Gem-Stuffed Envelope - Rare Gems TBC (ReferenceTable)'), +(25424, 4, 526792, 4, 0, 1, 1, 1, 1, 'Gem-Stuffed Envelope - Rare Gems TBC (ReferenceTable)'), +(25424, 5, 526792, 4, 0, 1, 2, 1, 1, 'Gem-Stuffed Envelope - Rare Gems TBC (ReferenceTable)'), +(25419, 0, 526791, 100, 0, 1, 0, 1, 1, 'Unmarked Bag of Gems - Uncommon TBC Gems (ReferenceTable)'), +(25419, 1, 526791, 55, 0, 1, 1, 1, 1, 'Unmarked Bag of Gems - Uncommon TBC Gems (ReferenceTable)'), +(25419, 2, 526791, 55, 0, 1, 2, 1, 1, 'Unmarked Bag of Gems - Uncommon TBC Gems (ReferenceTable)'), +(25419, 3, 526792, 4, 0, 1, 0, 1, 1, 'Unmarked Bag of Gems - Rare TBC Gems (ReferenceTable)'), +(25419, 4, 526792, 4, 0, 1, 1, 1, 1, 'Unmarked Bag of Gems - Rare TBC Gems (ReferenceTable)'), +(25419, 5, 526792, 4, 0, 1, 2, 1, 1, 'Unmarked Bag of Gems - Rare TBC Gems (ReferenceTable)'), +(25422, 0, 526791, 100, 0, 1, 0, 1, 1, 'Bulging Sack of Gems - Uncommon TBC Gems (ReferenceTable)'), +(25422, 1, 526791, 67, 0, 1, 1, 1, 1, 'Bulging Sack of Gems - Uncommon TBC Gems (ReferenceTable)'), +(25422, 2, 526791, 67, 0, 1, 2, 1, 1, 'Bulging Sack of Gems - Uncommon TBC Gems (ReferenceTable)'), +(25422, 3, 526792, 22, 0, 1, 0, 1, 1, 'Bulging Sack of Gems - Rare TBC Gems (ReferenceTable)'), +(25422, 4, 526792, 22, 0, 1, 1, 1, 1, 'Bulging Sack of Gems - Rare TBC Gems (ReferenceTable)'), +(25422, 5, 526792, 22, 0, 1, 2, 1, 1, 'Bulging Sack of Gems - Rare TBC Gems (ReferenceTable)'), +(25423, 0, 526791, 100, 0, 1, 0, 1, 1, 'Bag of Premium Gems - Uncommon TBC Gems (ReferenceTable)'), +(25423, 1, 526791, 70, 0, 1, 1, 1, 1, 'Bag of Premium Gems - Uncommon TBC Gems (ReferenceTable)'), +(25423, 2, 526791, 70, 0, 1, 2, 1, 1, 'Bag of Premium Gems - Uncommon TBC Gems (ReferenceTable)'), +(25423, 3, 526792, 100, 0, 1, 0, 1, 1, 'Bag of Premium Gems - Rare TBC Gems (ReferenceTable)'), +(25423, 4, 526792, 25, 0, 1, 1, 1, 1, 'Bag of Premium Gems - Rare TBC Gems (ReferenceTable)'), +(25423, 5, 526792, 25, 0, 1, 2, 1, 1, 'Bag of Premium Gems - Rare TBC Gems (ReferenceTable)'); diff --git a/data/sql/updates/db_world/2023_07_15_04.sql b/data/sql/updates/db_world/2023_07_15_04.sql new file mode 100644 index 000000000..6a9b2a321 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_15_04.sql @@ -0,0 +1,26 @@ +-- DB update 2023_07_15_03 -> 2023_07_15_04 +-- +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_anzu_spirit' WHERE (`entry` IN (23134, 23135, 23136)); + +DELETE FROM `creature_template_addon` WHERE (`entry` IN (23134, 23135, 23136)); +INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES +(23134, '40250'), +(23135, '40250'), +(23136, '40250'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23136) AND (`source_type` = 0); + +DELETE FROM `creature_text` WHERE `CreatureID` IN (23134, 23135, 23136); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23134, 0, 0, '%s returns to stone.', 16, 0, 100, 0, 0, 0, 20980, 0, 'Hawk Spirit'), +(23135, 0, 0, '%s returns to stone.', 16, 0, 100, 0, 0, 0, 20980, 0, 'Falcon Spirit'), +(23136, 0, 0, '%s returns to stone.', 16, 0, 100, 0, 0, 0, 20980, 0, 'Eagle Spirit'); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceEntry` IN (40240, 40237, 40241)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 3, 40240, 0, 0, 31, 0, 3, 23035, 0, 0, 0, 0, '', 'Spite of the Eagle (40240) only targets Anzu (23035)'), +(13, 1, 40237, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Protection of the Hawk (40237) only targets Players'), +(13, 1, 40241, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Speed of the Falcon (40241) only targets Players'); + +-- Hack: Add PLAYER_CONTROLLED to allow for players to heal them. Flag 64 is sniffed, though +UPDATE `creature_template` SET `unit_flags` = `unit_flags`|64|8 WHERE (`entry` IN (23134, 23135, 23136)); diff --git a/data/sql/updates/db_world/2023_07_16_00.sql b/data/sql/updates/db_world/2023_07_16_00.sql new file mode 100644 index 000000000..479603e6a --- /dev/null +++ b/data/sql/updates/db_world/2023_07_16_00.sql @@ -0,0 +1,5 @@ +-- DB update 2023_07_15_04 -> 2023_07_16_00 +-- +DELETE FROM `spell_proc_event` WHERE `entry` IN (46662); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `procPhase`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(46662,0,0,0,0,0,0,0,0,0,0,25000); diff --git a/data/sql/updates/db_world/2023_07_16_01.sql b/data/sql/updates/db_world/2023_07_16_01.sql new file mode 100644 index 000000000..4b3573b06 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_16_01.sql @@ -0,0 +1,25 @@ +-- DB update 2023_07_16_00 -> 2023_07_16_01 +-- +DELETE FROM `item_loot_template` WHERE (`Entry` = 31800); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(31800, 22829, 0, 97, 0, 1, 3, 1, 2, 'Outcast\'s Cache - Super Healing Potion'), +(31800, 27498, 0, 0, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Agility V'), +(31800, 27499, 0, 0, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Intellect V'), +(31800, 27500, 0, 0, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Protection V'), +(31800, 27501, 0, 0, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Spirit V'), +(31800, 27502, 0, 0, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Stamina V'), +(31800, 27503, 0, 0, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Strength V'), +(31800, 28491, 0, 3, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Windwalker\'s Footwraps'), +(31800, 28492, 0, 2, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Talonite\'s Boots'), +(31800, 28493, 0, 2, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Dreadhawk\'s Schynbald'), +(31800, 28494, 0, 2, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Ravenguard\'s Greaves'), +(31800, 28495, 0, 0, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Windwalker\'s Sash'), +(31800, 28496, 0, 0, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Talonite\'s Belt'), +(31800, 28497, 0, 0, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Dreadhawk\'s Girdle'), +(31800, 28498, 0, 0, 0, 1, 2, 1, 1, 'Outcast\'s Cache - Ravenguard\'s Baldric'), +(31800, 33457, 0, 2, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Agility VI'), +(31800, 33458, 0, 2, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Intellect VI'), +(31800, 33459, 0, 2, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Protection VI'), +(31800, 33460, 0, 2, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Spirit VI'), +(31800, 33461, 0, 2, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Stamina VI'), +(31800, 33462, 0, 2, 0, 1, 1, 1, 1, 'Outcast\'s Cache - Scroll of Strenght VI'); diff --git a/data/sql/updates/db_world/2023_07_16_02.sql b/data/sql/updates/db_world/2023_07_16_02.sql new file mode 100644 index 000000000..2ad4dc85e --- /dev/null +++ b/data/sql/updates/db_world/2023_07_16_02.sql @@ -0,0 +1,2 @@ +-- DB update 2023_07_16_01 -> 2023_07_16_02 +UPDATE `quest_template_addon` SET `RequiredSkillPoints` = 70 WHERE (`ID` = 1582); diff --git a/data/sql/updates/db_world/2023_07_16_03.sql b/data/sql/updates/db_world/2023_07_16_03.sql new file mode 100644 index 000000000..97adc03fc --- /dev/null +++ b/data/sql/updates/db_world/2023_07_16_03.sql @@ -0,0 +1,4 @@ +-- DB update 2023_07_16_02 -> 2023_07_16_03 +-- +UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask` | 8388608, `flags_extra` = 1073741824 WHERE `entry` in (19389, 21350); + diff --git a/data/sql/updates/db_world/2023_07_17_00.sql b/data/sql/updates/db_world/2023_07_17_00.sql new file mode 100644 index 000000000..977a581b6 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_17_00.sql @@ -0,0 +1,10 @@ +-- DB update 2023_07_16_03 -> 2023_07_17_00 +-- adding the aura and making him stand as well as adding stand state for other npcs present +DELETE FROM `creature_template_addon` WHERE `entry` IN (8387, 8388, 8389, 8394); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(8387, 0, 0, 0, 0, 26, 0, ''), -- first mate +(8388, 0, 0, 0, 0, 26, 0, ''), -- cook +(8389, 0, 0, 0, 0, 26, 0, ''), -- engineer +(8394, 0, 0, 0, 0, 26, 0, '12508'); -- roland geardabbler + +UPDATE `creature_template` SET `unit_class` = 8 WHERE `entry` = 8394; -- changing class from 2 to 8 diff --git a/data/sql/updates/db_world/2023_07_17_01.sql b/data/sql/updates/db_world/2023_07_17_01.sql new file mode 100644 index 000000000..11031bed3 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_17_01.sql @@ -0,0 +1,3 @@ +-- DB update 2023_07_17_00 -> 2023_07_17_01 +-- +UPDATE `spell_enchant_proc_data` SET `attributeMask` = 0x2 WHERE `entry` = 2675; diff --git a/data/sql/updates/db_world/2023_07_18_00.sql b/data/sql/updates/db_world/2023_07_18_00.sql new file mode 100644 index 000000000..17b998b98 --- /dev/null +++ b/data/sql/updates/db_world/2023_07_18_00.sql @@ -0,0 +1,3 @@ +-- DB update 2023_07_17_01 -> 2023_07_18_00 +-- +UPDATE `creature_template` SET `skinloot` = 0 WHERE `entry` IN (2966, 2961, 2955); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b26be3114..48c12596c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7226,6 +7226,9 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 continue; } + if (entry && (entry->attributeMask & ENCHANT_PROC_ATTR_WHITE_HIT) && (procVictim & SPELL_PROC_FLAG_MASK)) + continue; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pEnchant->spellid[s]); if (!spellInfo) { @@ -7274,10 +7277,8 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 item->SetEnchantmentCharges(EnchantmentSlot(e_slot), charges); } - if (spellInfo->IsPositive()) - CastSpell(this, spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); - else - CastSpell(target, spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); + Unit* unitTarget = spellInfo->IsPositive() ? this : target; + CastSpell(unitTarget, spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); } } } @@ -9023,20 +9024,6 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) { pet->CombatStop(); - if (returnreagent) - { - switch (pet->GetEntry()) - { - //warlock pets except imp are removed(?) when logging out - case 1860: - case 1863: - case 417: - case 17252: - mode = PET_SAVE_NOT_IN_SLOT; - break; - } - } - // only if current pet in slot pet->SavePetToDB(mode); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index ce45a5589..c580e69f1 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4933,20 +4933,18 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if (!unitTarget) return; - if (m_caster->GetTypeId() == TYPEID_PLAYER) - { - sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true); - } - - // charge changes fall time - if( m_caster->GetTypeId() == TYPEID_PLAYER ) - m_caster->ToPlayer()->SetFallInformation(GameTime::GetGameTime().count(), m_caster->GetPositionZ()); - ObjectGuid targetGUID = ObjectGuid::Empty; - if (!m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) && !m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER && - m_caster->GetTarget() == unitTarget->GetGUID()) + Player* player = m_caster->ToPlayer(); + if (player) { - targetGUID = unitTarget->GetGUID(); + sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true); + // charge changes fall time + player->SetFallInformation(GameTime::GetGameTime().count(), m_caster->GetPositionZ()); + + if (!m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) && !m_spellInfo->IsPositive() && m_caster->GetTarget() == unitTarget->GetGUID()) + { + targetGUID = unitTarget->GetGUID(); + } } float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE; @@ -4955,20 +4953,15 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) { Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetCombatReach(), unitTarget->GetRelativeAngle(m_caster)); m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID); - - if (m_caster->GetTypeId() == TYPEID_PLAYER) - { - sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); - } } else { m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID); + } - if (m_caster->GetTypeId() == TYPEID_PLAYER) - { - sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); - } + if (player) + { + sScriptMgr->AnticheatSetUnderACKmount(player); } } @@ -5144,13 +5137,10 @@ void Spell::EffectSendTaxi(SpellEffIndex effIndex) if (!unitTarget) return; - Player* player = unitTarget->ToPlayer(); - if (!player) + if (Player* player = unitTarget->ToPlayer()) { - return; + player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id); } - - player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id); } void Spell::EffectPullTowards(SpellEffIndex effIndex) @@ -5732,13 +5722,10 @@ void Spell::EffectKillCreditPersonal(SpellEffIndex effIndex) if (!unitTarget) return; - Player* player = unitTarget->GetCharmerOrOwnerPlayerOrPlayerItself(); - if (!player) + if (Player* player = unitTarget->GetCharmerOrOwnerPlayerOrPlayerItself()) { - return; + player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue); } - - player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue); } void Spell::EffectKillCredit(SpellEffIndex effIndex) @@ -5774,13 +5761,10 @@ void Spell::EffectQuestFail(SpellEffIndex effIndex) if (!unitTarget) return; - Player* player = unitTarget->ToPlayer(); - if (!player) + if (Player* player = unitTarget->ToPlayer()) { - return; + player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue); } - - player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue); } void Spell::EffectQuestStart(SpellEffIndex effIndex) @@ -6190,13 +6174,10 @@ void Spell::EffectSpecCount(SpellEffIndex /*effIndex*/) if (!unitTarget) return; - Player* player = unitTarget->ToPlayer(); - if (!player) + if (Player* player = unitTarget->ToPlayer()) { - return; + player->UpdateSpecCount(damage); } - - player->UpdateSpecCount(damage); } void Spell::EffectActivateSpec(SpellEffIndex /*effIndex*/) @@ -6207,13 +6188,10 @@ void Spell::EffectActivateSpec(SpellEffIndex /*effIndex*/) if (!unitTarget) return; - Player* player = unitTarget->ToPlayer(); - if (!player) + if (Player* player = unitTarget->ToPlayer()) { - return; + player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1 } - - player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1 } void Spell::EffectPlaySound(SpellEffIndex effIndex) diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 80eae7fc2..3a9700b6d 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -306,7 +306,8 @@ typedef std::unordered_map SpellProcMap; enum EnchantProcAttributes { - ENCHANT_PROC_ATTR_EXCLUSIVE = 0x1 // Only one instance of that effect can be active + ENCHANT_PROC_ATTR_EXCLUSIVE = 0x1, // Only one instance of that effect can be active + ENCHANT_PROC_ATTR_WHITE_HIT = 0x2 // Enchant shall only proc off white hits (not abilities) }; struct SpellEnchantProcEntry diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 2aa03c875..228d052a2 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -128,12 +128,15 @@ public: dbPortOutput = Acore::StringFormat("Realm Id: %u not found in `realmlist` table. Please check your setup", realm.Id.Realm); } - handler->PSendSysMessage("%s", GitRevision::GetFullVersion()); + HandleServerInfoCommand(handler); + handler->PSendSysMessage("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); handler->PSendSysMessage("Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); - handler->PSendSysMessage("Using MySQL version: %u", MySQL::GetLibraryVersion()); handler->PSendSysMessage("Using CMake version: %s", GitRevision::GetCMakeVersion()); + handler->PSendSysMessage("Using MySQL version: %u", MySQL::GetLibraryVersion()); + handler->PSendSysMessage("Found MySQL Executable: %s", GitRevision::GetMySQLExecutable()); + handler->PSendSysMessage("Compiled on: %s", GitRevision::GetHostOSVersion()); handler->PSendSysMessage("Worldserver listening connections on port %" PRIu16, worldPort); @@ -210,13 +213,36 @@ public: availableLocales += " "; } - handler->PSendSysMessage("Using %s DBC Locale as default. All available DBC locales: %s", localeNames[defaultLocale], availableLocales.c_str()); + handler->PSendSysMessage("Default DBC locale: %s.\nAll available DBC locales: %s", localeNames[defaultLocale], availableLocales.c_str()); handler->PSendSysMessage("Using World DB: %s", sWorld->GetDBVersion()); #ifdef MOD_PLAYERBOTS handler->PSendSysMessage("Using Playerbots DB Revision: %s", sWorld->GetPlayerbotsDBRevision()); #endif + std::string lldb = "No updates found!"; + if (QueryResult resL = LoginDatabase.Query("SELECT name FROM updates ORDER BY name DESC LIMIT 1")) + { + Field* fields = resL->Fetch(); + lldb = fields[0].Get(); + } + std::string lcdb = "No updates found!"; + if (QueryResult resC = CharacterDatabase.Query("SELECT name FROM updates ORDER BY name DESC LIMIT 1")) + { + Field* fields = resC->Fetch(); + lcdb = fields[0].Get(); + } + std::string lwdb = "No updates found!"; + if (QueryResult resW = WorldDatabase.Query("SELECT name FROM updates ORDER BY name DESC LIMIT 1")) + { + Field* fields = resW->Fetch(); + lwdb = fields[0].Get(); + } + + handler->PSendSysMessage("Latest LoginDatabase update: %s", lldb.c_str()); + handler->PSendSysMessage("Latest CharacterDatabase update: %s", lcdb.c_str()); + handler->PSendSysMessage("Latest WorldDatabase update: %s", lwdb.c_str()); + handler->PSendSysMessage("LoginDatabase queue size: %zu", LoginDatabase.QueueSize()); handler->PSendSysMessage("CharacterDatabase queue size: %zu", CharacterDatabase.QueueSize()); handler->PSendSysMessage("WorldDatabase queue size: %zu", WorldDatabase.QueueSize()); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp index 6ab065280..dfc07e012 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp @@ -19,15 +19,18 @@ #include "ScriptedCreature.h" #include "karazhan.h" -enum Curator +enum Text { SAY_AGGRO = 0, SAY_SUMMON = 1, SAY_EVOCATE = 2, SAY_ENRAGE = 3, SAY_KILL = 4, - SAY_DEATH = 5, + SAY_DEATH = 5 +}; +enum Spells +{ SPELL_HATEFUL_BOLT = 30383, SPELL_EVOCATION = 30254, SPELL_ARCANE_INFUSION = 30403, @@ -36,140 +39,112 @@ enum Curator SPELL_SUMMON_ASTRAL_FLARE1 = 30236, SPELL_SUMMON_ASTRAL_FLARE2 = 30239, SPELL_SUMMON_ASTRAL_FLARE3 = 30240, - SPELL_SUMMON_ASTRAL_FLARE4 = 30241, - - EVENT_KILL_TALK = 1, - EVENT_SPELL_HATEFUL_BOLT = 2, - EVENT_SPELL_EVOCATION = 3, - EVENT_SPELL_ASTRAL_FLARE = 4, - EVENT_SPELL_BERSERK = 5, - EVENT_CHECK_HEALTH = 6 + SPELL_SUMMON_ASTRAL_FLARE4 = 30241 }; -class boss_curator : public CreatureScript +struct boss_curator : public BossAI { -public: - boss_curator() : CreatureScript("boss_curator") { } + boss_curator(Creature* creature) : BossAI(creature, DATA_CURATOR) { } - struct boss_curatorAI : public BossAI + void Reset() override { - boss_curatorAI(Creature* creature) : BossAI(creature, DATA_CURATOR) { } + BossAI::Reset(); + me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_MANA_LEECH, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_POWER_BURN, true); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_POWER_BURN, true); + ScheduleHealthCheckEvent(15, [&] { + DoCastSelf(SPELL_ARCANE_INFUSION, true); + Talk(SAY_ENRAGE); + }); + } - void Reset() override - { - BossAI::Reset(); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, true); - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_MANA_LEECH, true); - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_POWER_BURN, true); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_POWER_BURN, true); - } - - void KilledUnit(Unit* /*victim*/) override - { - if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) - { - Talk(SAY_KILL); - events.ScheduleEvent(EVENT_KILL_TALK, 5000); - } - } - - void JustDied(Unit* killer) override - { - BossAI::JustDied(killer); - Talk(SAY_DEATH); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - Talk(SAY_AGGRO); - - events.ScheduleEvent(EVENT_SPELL_HATEFUL_BOLT, 10000); - events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 6000); - events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); - DoZoneInCombat(); - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - if (Unit* target = summon->SelectNearbyTarget(nullptr, 40.0f)) - { - summon->AI()->AttackStart(target); - summon->AddThreat(target, 1000.0f); - } - - summon->SetInCombatWithZone(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(16)) - { - events.CancelEvent(EVENT_SPELL_ASTRAL_FLARE); - me->CastSpell(me, SPELL_ARCANE_INFUSION, true); - Talk(SAY_ENRAGE); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); - break; - case EVENT_SPELL_BERSERK: - Talk(SAY_ENRAGE); - me->InterruptNonMeleeSpells(true); - me->CastSpell(me, SPELL_ASTRAL_DECONSTRUCTION, true); - break; - case EVENT_SPELL_HATEFUL_BOLT: - if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, urand(1, 2), 40.0f)) - me->CastSpell(target, SPELL_HATEFUL_BOLT, false); - events.ScheduleEvent(EVENT_SPELL_HATEFUL_BOLT, urand(5000, 7500) * (events.GetNextEventTime(EVENT_SPELL_BERSERK) == 0 ? 1 : 2)); - break; - case EVENT_SPELL_ASTRAL_FLARE: - { - me->CastSpell(me, RAND(SPELL_SUMMON_ASTRAL_FLARE1, SPELL_SUMMON_ASTRAL_FLARE2, SPELL_SUMMON_ASTRAL_FLARE3, SPELL_SUMMON_ASTRAL_FLARE4), false); - int32 mana = CalculatePct(me->GetMaxPower(POWER_MANA), 10); - me->ModifyPower(POWER_MANA, -mana); - if (me->GetPowerPct(POWER_MANA) < 10.0f) - { - Talk(SAY_EVOCATE); - me->CastSpell(me, SPELL_EVOCATION, false); - - events.DelayEvents(20000); - events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 20000); - } - else - { - if (roll_chance_i(50)) - Talk(SAY_SUMMON); - - events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 10000); - } - - break; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override + void KilledUnit(Unit* victim) override { - return GetKarazhanAI(creature); + if (victim->GetTypeId() == TYPEID_PLAYER) + { + Talk(SAY_KILL); + } + } + + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(SAY_DEATH); + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + DoZoneInCombat(); + scheduler.Schedule(10min, [this](TaskContext /*context*/) + { + Talk(SAY_ENRAGE); + me->InterruptNonMeleeSpells(true); + DoCastSelf(SPELL_ASTRAL_DECONSTRUCTION, true); + }).Schedule(10s, [this](TaskContext context) + { + if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, 45.0f, true, false)) + { + DoCast(target, SPELL_HATEFUL_BOLT); + } + else + { + DoCastVictim(SPELL_HATEFUL_BOLT); + } + context.Repeat(7s, 15s); + }).Schedule(6s, [this](TaskContext context) + { + if (me->HealthAbovePct(15)) + { + if (roll_chance_i(50)) + { + Talk(SAY_SUMMON); + } + DoCastSelf(RAND(SPELL_SUMMON_ASTRAL_FLARE1, SPELL_SUMMON_ASTRAL_FLARE2, SPELL_SUMMON_ASTRAL_FLARE3, SPELL_SUMMON_ASTRAL_FLARE4)); + int32 mana = CalculatePct(me->GetMaxPower(POWER_MANA), 10); + me->ModifyPower(POWER_MANA, -mana); + if (me->GetPowerPct(POWER_MANA) < 10.0f) + { + Talk(SAY_EVOCATE); + DoCastSelf(SPELL_EVOCATION); + scheduler.DelayAll(20s); + context.Repeat(20s); + } + else + { + context.Repeat(10s); + } + } + }); + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + if (Unit* target = summon->SelectNearbyTarget(nullptr, 40.0f)) + { + summon->AI()->AttackStart(target); + summon->AddThreat(target, 1000.0f); + } + summon->SetInCombatWithZone(); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + DoMeleeAttackIfReady(); } }; void AddSC_boss_curator() { - new boss_curator(); + RegisterKarazhanCreatureAI(boss_curator); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp index fd8978d22..82ccd7030 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp @@ -19,48 +19,61 @@ #include "ScriptedCreature.h" #include "karazhan.h" -enum MaidenOfVirtue +enum Text { - SAY_AGGRO = 0, - SAY_SLAY = 1, - SAY_REPENTANCE = 2, - SAY_DEATH = 3, + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_REPENTANCE = 2, + SAY_DEATH = 3 +}; - SPELL_REPENTANCE = 29511, - SPELL_HOLY_FIRE = 29522, - SPELL_HOLY_WRATH = 32445, - SPELL_HOLY_GROUND = 29523, - SPELL_BERSERK = 26662, - - EVENT_SPELL_REPENTANCE = 1, - EVENT_SPELL_HOLY_FIRE = 2, - EVENT_SPELL_HOLY_WRATH = 3, - EVENT_SPELL_ENRAGE = 4, - EVENT_KILL_TALK = 5 +enum Spells +{ + SPELL_REPENTANCE = 29511, + SPELL_HOLY_FIRE = 29522, + SPELL_HOLY_WRATH = 32445, + SPELL_HOLY_GROUND = 29523, + SPELL_BERSERK = 26662 }; struct boss_maiden_of_virtue : public BossAI { boss_maiden_of_virtue(Creature* creature) : BossAI(creature, DATA_MAIDEN) { } + void Reset() override + { + BossAI::Reset(); + } + void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); Talk(SAY_AGGRO); - DoCastAOE(SPELL_HOLY_GROUND, true); - events.ScheduleEvent(EVENT_SPELL_REPENTANCE, 25s); - events.ScheduleEvent(EVENT_SPELL_HOLY_FIRE, 8s); - events.ScheduleEvent(EVENT_SPELL_HOLY_WRATH, 15s); - events.ScheduleEvent(EVENT_SPELL_ENRAGE, 10min); + scheduler.Schedule(25s, [this](TaskContext context) + { + DoCastAOE(SPELL_REPENTANCE, true); + Talk(SAY_REPENTANCE); + context.Repeat(25s, 35s); + }).Schedule(8s, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_HOLY_FIRE, 0, 50.0f); + context.Repeat(8s, 18s); + }).Schedule(15s, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_HOLY_WRATH, 0, 80.0f); + context.Repeat(20s, 25s); + }).Schedule(10min, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_BERSERK, true); + }); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) + if (victim->GetTypeId() == TYPEID_PLAYER) { Talk(SAY_SLAY); - events.ScheduleEvent(EVENT_KILL_TALK, 5s); } } @@ -75,30 +88,10 @@ struct boss_maiden_of_virtue : public BossAI if (!UpdateVictim()) return; - events.Update(diff); + scheduler.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_REPENTANCE: - DoCastAOE(SPELL_REPENTANCE, true); - Talk(SAY_REPENTANCE); - events.Repeat(25s, 35s); - break; - case EVENT_SPELL_HOLY_FIRE: - DoCastRandomTarget(SPELL_HOLY_FIRE, 0, 50.0f); - events.Repeat(8s, 18s); - break; - case EVENT_SPELL_HOLY_WRATH: - DoCastRandomTarget(SPELL_HOLY_WRATH, 0, 80.0f); - events.Repeat(20s, 25s); - break; - case EVENT_SPELL_ENRAGE: - DoCastSelf(SPELL_BERSERK, true); - break; - } - DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp index a3c6184b5..708d27836 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp @@ -41,7 +41,7 @@ enum Spells SPELL_FRENZY = 37023, SPELL_DUAL_WIELD = 29651, SPELL_BERSERK = 26662, - SPELL_VANISH_TELEPORT = 29431, + SPELL_VANISH_TELEPORT = 29431 }; enum Misc @@ -52,9 +52,8 @@ enum Misc EVENT_SPELL_GARROTE = 4, EVENT_SPELL_BLIND = 5, EVENT_SPELL_GOUGE = 6, - EVENT_CHECK_HEALTH = 7, - EVENT_SPELL_ENRAGE = 8, - EVENT_KILL_TALK = 9, + EVENT_SPELL_ENRAGE = 7, + EVENT_KILL_TALK = 8, ACTIVE_GUEST_COUNT = 4, MAX_GUEST_COUNT = 6 @@ -65,17 +64,13 @@ const Position GuestsPosition[4] = {-10987.38f, -1883.38f, 81.73f, 1.50f}, {-10989.60f, -1881.27f, 81.73f, 0.73f}, {-10978.81f, -1884.08f, 81.73f, 1.50f}, - {-10976.38f, -1882.59f, 81.73f, 2.31f}, + {-10976.38f, -1882.59f, 81.73f, 2.31f} }; const uint32 GuestEntries[6] = { - 17007, - 19872, - 19873, - 19874, - 19875, - 19876, + 17007, 19872, 19873, + 19874, 19875, 19876 }; struct boss_moroes : public BossAI @@ -109,11 +104,13 @@ struct boss_moroes : public BossAI uint8 rand2 = RAND(0x08, 0x10, 0x20); _activeGuests &= ~(rand1 | rand2); } - for (uint8 i = 0; i < MAX_GUEST_COUNT; ++i) + { if ((1 << i) & _activeGuests) + { me->SummonCreature(GuestEntries[i], GuestsPosition[summons.size()], TEMPSUMMON_MANUAL_DESPAWN); - + } + } _events2.Reset(); _events2.ScheduleEvent(EVENT_GUEST_TALK, 10s); } @@ -128,24 +125,32 @@ struct boss_moroes : public BossAI { BossAI::JustEngagedWith(who); Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_SPELL_VANISH, 30s); events.ScheduleEvent(EVENT_SPELL_BLIND, 20s); events.ScheduleEvent(EVENT_SPELL_GOUGE, 13s); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 5s); events.ScheduleEvent(EVENT_SPELL_ENRAGE, 10min); - _events2.Reset(); me->CallForHelp(20.0f); DoZoneInCombat(); } - void KilledUnit(Unit* /*victim*/) override + void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override + { + if (HealthBelowPct(30)) + { + DoCastSelf(SPELL_FRENZY, true); + } + } + + void KilledUnit(Unit* victim) override { if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) { - Talk(SAY_KILL); - events.ScheduleEvent(EVENT_KILL_TALK, 5s); + if (victim->GetTypeId() == TYPEID_PLAYER) + { + Talk(SAY_KILL); + events.ScheduleEvent(EVENT_KILL_TALK, 5s); + } } } @@ -160,9 +165,12 @@ struct boss_moroes : public BossAI { std::list guestList; for (SummonList::const_iterator i = summons.begin(); i != summons.end(); ++i) + { if (Creature* summon = ObjectAccessor::GetCreature(*me, *i)) + { guestList.push_back(summon); - + } + } return Acore::Containers::SelectRandomContainerElement(guestList); } @@ -171,15 +179,17 @@ struct boss_moroes : public BossAI _events2.Update(diff); switch (_events2.ExecuteEvent()) { - case EVENT_GUEST_TALK: - if (Creature* guest = GetRandomGuest()) - guest->AI()->Talk(SAY_GUEST); - _events2.Repeat(5s); - break; - case EVENT_GUEST_TALK2: - Talk(SAY_OUT_OF_COMBAT); - _events2.Repeat(1min, 2min); - break; + case EVENT_GUEST_TALK: + if (Creature* guest = GetRandomGuest()) + { + guest->AI()->Talk(SAY_GUEST); + } + _events2.Repeat(5s); + break; + case EVENT_GUEST_TALK2: + Talk(SAY_OUT_OF_COMBAT); + _events2.Repeat(1min, 2min); + break; } if (!UpdateVictim()) @@ -191,14 +201,6 @@ struct boss_moroes : public BossAI switch (events.ExecuteEvent()) { - case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(31)) - { - DoCastSelf(SPELL_FRENZY, true); - break; - } - events.Repeat(1s); - break; case EVENT_SPELL_ENRAGE: DoCastSelf(SPELL_BERSERK, true); break; @@ -227,9 +229,7 @@ struct boss_moroes : public BossAI events.SetPhase(0); break; } - - // Xinef: not in vanish - if (events.GetPhaseMask() == 0) + if (events.GetPhaseMask() == 0) // Xinef: not in vanish DoMeleeAttackIfReady(); } @@ -238,41 +238,30 @@ struct boss_moroes : public BossAI uint8 _activeGuests; }; -class spell_moroes_vanish : public SpellScriptLoader +class spell_moroes_vanish : public SpellScript { -public: - spell_moroes_vanish() : SpellScriptLoader("spell_moroes_vanish") { } + PrepareSpellScript(spell_moroes_vanish); - class spell_moroes_vanish_SpellScript : public SpellScript + void HandleDummy(SpellEffIndex effIndex) { - PrepareSpellScript(spell_moroes_vanish_SpellScript); - - void HandleDummy(SpellEffIndex effIndex) + PreventHitDefaultEffect(effIndex); + if (Unit* target = GetHitUnit()) { - PreventHitDefaultEffect(effIndex); - if (Unit* target = GetHitUnit()) - { - Position pos = target->GetFirstCollisionPosition(5.0f, M_PI); - GetCaster()->CastSpell(target, SPELL_GARROTE_DUMMY, true); - GetCaster()->RemoveAurasDueToSpell(SPELL_VANISH); - GetCaster()->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation()); - } + Position pos = target->GetFirstCollisionPosition(5.0f, M_PI); + GetCaster()->CastSpell(target, SPELL_GARROTE_DUMMY, true); + GetCaster()->RemoveAurasDueToSpell(SPELL_VANISH); + GetCaster()->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation()); } + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_moroes_vanish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_moroes_vanish_SpellScript(); + OnEffectHitTarget += SpellEffectFn(spell_moroes_vanish::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; void AddSC_boss_moroes() { RegisterKarazhanCreatureAI(boss_moroes); - new spell_moroes_vanish(); + RegisterSpellScript(spell_moroes_vanish); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp index f85e4301b..b81b7cd8b 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp @@ -15,44 +15,38 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Terestian_Illhoof -SD%Complete: 95 -SDComment: Complete! Needs adjustments to use spell though. -SDCategory: Karazhan -EndScriptData */ - #include "PassiveAI.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellInfo.h" #include "karazhan.h" -enum TerestianIllhoof +enum Text { - SAY_SLAY = 1, - SAY_DEATH = 2, - SAY_AGGRO = 3, - SAY_SACRIFICE = 4, - SAY_SUMMON = 5 + SAY_SLAY = 0, + SAY_DEATH = 1, + SAY_AGGRO = 2, + SAY_SACRIFICE = 3, + SAY_SUMMON = 4 }; enum Spells { - SPELL_SUMMON_DEMONCHAINS = 30120, // Summons demonic chains that maintain the ritual of sacrifice. - SPELL_DEMON_CHAINS = 30206, // Instant - Visual Effect - SPELL_ENRAGE = 23537, // Increases the caster's attack speed by 50% and the Physical damage it deals by 219 to 281 for 10 min. - SPELL_SHADOW_BOLT = 30055, // Hurls a bolt of dark magic at an enemy, inflicting Shadow damage. - SPELL_SACRIFICE = 30115, // Teleports and adds the debuff - SPELL_BERSERK = 32965, // Increases attack speed by 75%. Periodically casts Shadow Bolt Volley. - SPELL_SUMMON_FIENDISIMP = 30184, // Summons a Fiendish Imp. - SPELL_SUMMON_IMP = 30066, // Summons Kil'rek + SPELL_SUMMON_DEMONCHAINS = 30120, + SPELL_DEMON_CHAINS = 30206, + SPELL_ENRAGE = 23537, + SPELL_SHADOW_BOLT = 30055, + SPELL_SACRIFICE = 30115, + SPELL_BERSERK = 32965, + SPELL_SUMMON_FIENDISIMP = 30184, + SPELL_SUMMON_IMP = 30066, - SPELL_FIENDISH_PORTAL = 30171, // Opens portal and summons Fiendish Portal, 2 sec cast - SPELL_FIENDISH_PORTAL_1 = 30179, // Opens portal and summons Fiendish Portal, instant cast + SPELL_FIENDISH_PORTAL = 30171, + SPELL_FIENDISH_PORTAL_1 = 30179, - SPELL_FIREBOLT = 30050, // Blasts a target for 150 Fire damage. - SPELL_BROKEN_PACT = 30065, // All damage taken increased by 25%. - SPELL_AMPLIFY_FLAMES = 30053, // Increases the Fire damage taken by an enemy by 500 for 25 sec. + SPELL_FIREBOLT = 30050, + SPELL_BROKEN_PACT = 30065, + SPELL_AMPLIFY_FLAMES = 30053 }; enum Creatures @@ -62,390 +56,306 @@ enum Creatures NPC_PORTAL = 17265 }; -class npc_kilrek : public CreatureScript +struct npc_kilrek : public ScriptedAI { -public: - npc_kilrek() : CreatureScript("npc_kilrek") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_kilrek(Creature* creature) : ScriptedAI(creature) { - return GetKarazhanAI(creature); + instance = creature->GetInstanceScript(); } - struct npc_kilrekAI : public ScriptedAI + void Reset() override { - npc_kilrekAI(Creature* creature) : ScriptedAI(creature) + _scheduler.CancelAll(); + TerestianGUID.Clear(); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _scheduler.Schedule(2s, [this](TaskContext context) { - instance = creature->GetInstanceScript(); - } + me->InterruptNonMeleeSpells(false); + DoCastVictim(SPELL_AMPLIFY_FLAMES); + context.Repeat(10s, 20s); + }); + } - InstanceScript* instance; - - ObjectGuid TerestianGUID; - - uint32 AmplifyTimer; - - void Reset() override + void JustDied(Unit* /*killer*/) override + { + ObjectGuid TerestianGuid = instance->GetGuidData(DATA_TERESTIAN); + if (TerestianGuid) { - TerestianGUID.Clear(); - AmplifyTimer = 2000; - } - - void JustEngagedWith(Unit* /*who*/) override - { - } - - void JustDied(Unit* /*killer*/) override - { - ObjectGuid TerestianGuid = instance->GetGuidData(DATA_TERESTIAN); - if (TerestianGuid) + Unit* Terestian = ObjectAccessor::GetUnit(*me, TerestianGuid); + if (Terestian && Terestian->IsAlive()) { - Unit* Terestian = ObjectAccessor::GetUnit(*me, TerestianGuid); - if (Terestian && Terestian->IsAlive()) - DoCast(Terestian, SPELL_BROKEN_PACT, true); + DoCast(Terestian, SPELL_BROKEN_PACT, true); } } - - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (AmplifyTimer <= diff) - { - me->InterruptNonMeleeSpells(false); - DoCastVictim(SPELL_AMPLIFY_FLAMES); - - AmplifyTimer = urand(10000, 20000); - } - else - AmplifyTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -class npc_demon_chain : public CreatureScript -{ -public: - npc_demon_chain() : CreatureScript("npc_demon_chain") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetKarazhanAI(creature); + me->DespawnOrUnsummon(15000); } - struct npc_demon_chainAI : public ScriptedAI + void UpdateAI(uint32 diff) override { - npc_demon_chainAI(Creature* creature) : ScriptedAI(creature) { } + if (!UpdateVictim()) + return; - ObjectGuid SacrificeGUID; + _scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void Reset() override + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; + InstanceScript* instance; + ObjectGuid TerestianGUID; +}; + +struct npc_demon_chain : public ScriptedAI +{ + npc_demon_chain(Creature* creature) : ScriptedAI(creature) { } + + void Reset() override + { + sacrificeGUID.Clear(); + } + + void IsSummonedBy(WorldObject* summoner) override + { + sacrificeGUID = summoner->GetGUID(); + DoCastSelf(SPELL_DEMON_CHAINS, true); + } + + void JustEngagedWith(Unit* /*who*/) override { } + void AttackStart(Unit* /*who*/) override { } + void MoveInLineOfSight(Unit* /*who*/) override { } + + void JustDied(Unit* /*killer*/) override + { + if (sacrificeGUID) { - SacrificeGUID.Clear(); - } - - void JustEngagedWith(Unit* /*who*/) override { } - void AttackStart(Unit* /*who*/) override { } - void MoveInLineOfSight(Unit* /*who*/) override { } - - void JustDied(Unit* /*killer*/) override - { - if (SacrificeGUID) + Unit* Sacrifice = ObjectAccessor::GetUnit(*me, sacrificeGUID); + if (Sacrifice) { - Unit* Sacrifice = ObjectAccessor::GetUnit(*me, SacrificeGUID); - if (Sacrifice) - Sacrifice->RemoveAurasDueToSpell(SPELL_SACRIFICE); + Sacrifice->RemoveAurasDueToSpell(SPELL_SACRIFICE); } } - }; -}; - -class npc_fiendish_portal : public CreatureScript -{ -public: - npc_fiendish_portal() : CreatureScript("npc_fiendish_portal") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetKarazhanAI(creature); } - struct npc_fiendish_portalAI : public PassiveAI - { - npc_fiendish_portalAI(Creature* creature) : PassiveAI(creature), summons(me) { } - - SummonList summons; - - void Reset() override - { - DespawnAllImp(); - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - DoZoneInCombat(summon); - } - - void DespawnAllImp() - { - summons.DespawnAll(); - } - }; +private: + ObjectGuid sacrificeGUID; }; -class npc_fiendish_imp : public CreatureScript +struct npc_fiendish_portal : public PassiveAI { -public: - npc_fiendish_imp() : CreatureScript("npc_fiendish_imp") { } + npc_fiendish_portal(Creature* creature) : PassiveAI(creature), summons(me) {} - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetKarazhanAI(creature); + DespawnAllImp(); } - struct npc_fiendish_impAI : public ScriptedAI + void JustSummoned(Creature* summon) override { - npc_fiendish_impAI(Creature* creature) : ScriptedAI(creature) { } + summons.Summon(summon); + DoZoneInCombat(summon); + } - uint32 FireboltTimer; + void DespawnAllImp() + { + summons.DespawnAll(); + } - void Reset() override +private: + SummonList summons; +}; + +struct npc_fiendish_imp : public ScriptedAI +{ + npc_fiendish_imp(Creature* creature) : ScriptedAI(creature) {} + + void Reset() override + { + _scheduler.CancelAll(); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _scheduler.Schedule(2s, [this](TaskContext context) { - FireboltTimer = 2000; - } + DoCastVictim(SPELL_FIREBOLT); + context.Repeat(2200ms); + }); + } - void JustEngagedWith(Unit* /*who*/) override { } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override + _scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; +}; + +struct boss_terestian_illhoof : public BossAI +{ + boss_terestian_illhoof(Creature* creature) : BossAI(creature, DATA_TERESTIAN) + { + scheduler.SetValidator([this] { - //Return since we have no target - if (!UpdateVictim()) - return; + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } - if (FireboltTimer <= diff) + void Reset() override + { + _Reset(); + SummonKilrek(); + portalsCount = 0; + berserk = false; + for (uint8 i = 0; i < 2; ++i) + { + if (portalGUID[i]) { - DoCastVictim(SPELL_FIREBOLT); - FireboltTimer = 2200; - } - else - FireboltTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -class boss_terestian_illhoof : public CreatureScript -{ -public: - boss_terestian_illhoof() : CreatureScript("boss_terestian_illhoof") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetKarazhanAI(creature); - } - - struct boss_terestianAI : public ScriptedAI - { - boss_terestianAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - ObjectGuid PortalGUID[2]; - uint8 PortalsCount; - - uint32 SacrificeTimer; - uint32 ShadowboltTimer; - uint32 SummonTimer; - uint32 BerserkTimer; - uint32 SummonKilrekTimer; - - bool SummonedPortals; - bool Berserk; - - void Reset() override - { - for (uint8 i = 0; i < 2; ++i) - { - if (PortalGUID[i]) + if (Creature* pPortal = ObjectAccessor::GetCreature(*me, portalGUID[i])) { - if (Creature* pPortal = ObjectAccessor::GetCreature(*me, PortalGUID[i])) - { - CAST_AI(npc_fiendish_portal::npc_fiendish_portalAI, pPortal->AI())->DespawnAllImp(); - pPortal->DespawnOrUnsummon(); - } - - PortalGUID[i].Clear(); + pPortal->AI()->Reset(); + pPortal->DespawnOrUnsummon(); } + portalGUID[i].Clear(); } - - PortalsCount = 0; - SacrificeTimer = 30000; - ShadowboltTimer = 5000; - SummonTimer = 10000; - BerserkTimer = 600000; - SummonKilrekTimer = 0; - - SummonedPortals = false; - Berserk = false; - - instance->SetData(DATA_TERESTIAN, NOT_STARTED); - - me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT); - - if (Minion* Kilrek = me->GetFirstMinion()) - { - if (!Kilrek->IsAlive()) - { - Kilrek->UnSummon(); - DoCast(me, SPELL_SUMMON_IMP, true); - } - } - else - DoCast(me, SPELL_SUMMON_IMP, true); } + } - void JustEngagedWith(Unit* /*who*/) override + void SummonKilrek() + { + me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT); + DoCastSelf(SPELL_SUMMON_IMP); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_BROKEN_PACT) { - Talk(SAY_AGGRO); - DoZoneInCombat(); + scheduler.Schedule(45s, [this](TaskContext /*context*/) { + SummonKilrek(); + }); } + } - void JustSummoned(Creature* summoned) override + void JustEngagedWith(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + DoZoneInCombat(); + scheduler.Schedule(30s, [this](TaskContext context) { - if (summoned->GetEntry() == NPC_PORTAL) + if (Unit * target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, false)) { - PortalGUID[PortalsCount] = summoned->GetGUID(); - ++PortalsCount; - - if (summoned->GetUInt32Value(UNIT_CREATED_BY_SPELL) == SPELL_FIENDISH_PORTAL_1) + DoCast(target, SPELL_SACRIFICE, true); + target->CastSpell(target, SPELL_SUMMON_DEMONCHAINS, true); + Talk(SAY_SACRIFICE); + context.Repeat(30s); + } + }).Schedule(5s, [this](TaskContext context) + { + DoCastVictim(SPELL_SHADOW_BOLT); + context.Repeat(10s); + }).Schedule(10s, [this](TaskContext context) + { + if (!portalGUID[0]) + { + DoCastVictim(SPELL_FIENDISH_PORTAL); + } + if (!portalGUID[1]) + { + DoCastVictim(SPELL_FIENDISH_PORTAL_1); + } + if (portalGUID[0] && portalGUID[1]) + { + if (Creature* pPortal = ObjectAccessor::GetCreature(*me, portalGUID[urand(0, 1)])) { - Talk(SAY_SUMMON); - SummonedPortals = true; + pPortal->CastSpell(me->GetVictim(), SPELL_SUMMON_FIENDISIMP); } + context.Repeat(5s); + } + }).Schedule(10min, [this](TaskContext /*context*/) + { + if (!berserk) + { + DoCastSelf(SPELL_BERSERK); + berserk = true; + } + }); + } + + void JustSummoned(Creature* summoned) override + { + if (summoned->GetEntry() == NPC_PORTAL) + { + portalGUID[portalsCount] = summoned->GetGUID(); + ++portalsCount; + if (summoned->GetUInt32Value(UNIT_CREATED_BY_SPELL) == SPELL_FIENDISH_PORTAL_1) + { + Talk(SAY_SUMMON); } } + } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) { Talk(SAY_SLAY); } + } - void JustDied(Unit* /*killer*/) override + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + for (uint8 i = 0; i < 2; ++i) { - for (uint8 i = 0; i < 2; ++i) + if (portalGUID[i]) { - if (PortalGUID[i]) + if (Creature* pPortal = ObjectAccessor::GetCreature((*me), portalGUID[i])) { - if (Creature* pPortal = ObjectAccessor::GetCreature((*me), PortalGUID[i])) - pPortal->DespawnOrUnsummon(); - - PortalGUID[i].Clear(); + pPortal->AI()->Reset(); + pPortal->DespawnOrUnsummon(); } + portalGUID[i].Clear(); } - - Talk(SAY_DEATH); - instance->SetData(DATA_TERESTIAN, DONE); } + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (Minion* Kilrek = me->GetFirstMinion()) - { - if (!Kilrek->IsAlive()) - { - Kilrek->UnSummon(); - SummonKilrekTimer = 45000; - } - } + scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (SummonKilrekTimer <= diff) - { - DoCast(me, SPELL_SUMMON_IMP, true); - me->RemoveAura(SPELL_BROKEN_PACT); - } - else - SummonKilrekTimer -= diff; + DoMeleeAttackIfReady(); + } - if (SacrificeTimer <= diff) - { - Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true); - if (target && target->IsAlive()) - { - DoCast(target, SPELL_SACRIFICE, true); - DoCast(target, SPELL_SUMMON_DEMONCHAINS, true); - - if (Creature* Chains = me->FindNearestCreature(NPC_DEMONCHAINS, 5000)) - { - CAST_AI(npc_demon_chain::npc_demon_chainAI, Chains->AI())->SacrificeGUID = target->GetGUID(); - Chains->CastSpell(Chains, SPELL_DEMON_CHAINS, true); - - Talk(SAY_SACRIFICE); - SacrificeTimer = 30000; - } - } - } - else - SacrificeTimer -= diff; - - if (ShadowboltTimer <= diff) - { - DoCast(SelectTarget(SelectTargetMethod::MaxThreat, 0), SPELL_SHADOW_BOLT); - ShadowboltTimer = 10000; - } - else - ShadowboltTimer -= diff; - - if (SummonTimer <= diff) - { - if (!PortalGUID[0]) - DoCastVictim(SPELL_FIENDISH_PORTAL, false); - - if (!PortalGUID[1]) - DoCastVictim(SPELL_FIENDISH_PORTAL_1, false); - - if (PortalGUID[0] && PortalGUID[1]) - { - if (Creature* pPortal = ObjectAccessor::GetCreature(*me, PortalGUID[urand(0, 1)])) - pPortal->CastSpell(me->GetVictim(), SPELL_SUMMON_FIENDISIMP, false); - SummonTimer = 5000; - } - } - else - SummonTimer -= diff; - - if (!Berserk) - { - if (BerserkTimer <= diff) - { - DoCast(me, SPELL_BERSERK); - Berserk = true; - } - else - BerserkTimer -= diff; - } - - DoMeleeAttackIfReady(); - } - }; +private: + bool berserk; + ObjectGuid portalGUID[2]; + uint8 portalsCount; }; void AddSC_boss_terestian_illhoof() { - new boss_terestian_illhoof(); - new npc_fiendish_imp(); - new npc_fiendish_portal(); - new npc_kilrek(); - new npc_demon_chain(); + RegisterKarazhanCreatureAI(boss_terestian_illhoof); + RegisterKarazhanCreatureAI(npc_fiendish_imp); + RegisterKarazhanCreatureAI(npc_fiendish_portal); + RegisterKarazhanCreatureAI(npc_kilrek); + RegisterKarazhanCreatureAI(npc_demon_chain); } diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp index 3008e7188..df615ef0d 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp @@ -620,28 +620,28 @@ struct npc_eye_tentacle : public ScriptedAI void Reset() override { + DoZoneInCombat(); _scheduler.Schedule(500ms, [this](TaskContext /*task*/) - { - DoCastAOE(SPELL_GROUND_RUPTURE); - }) - .Schedule(5min, [this](TaskContext /*task*/) - { - me->DespawnOrUnsummon(); - }) - .Schedule(1s, 5s, [this](TaskContext context) - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, NotInStomachSelector())) - { - DoCast(target, SPELL_MIND_FLAY); - } - - context.Repeat(10s, 15s); - }); + { + DoCastAOE(SPELL_GROUND_RUPTURE); + }) + .Schedule(5min, [this](TaskContext /*task*/) + { + me->DespawnOrUnsummon(); + }); } void JustEngagedWith(Unit* /*who*/) override { - DoZoneInCombat(); + _scheduler.Schedule(1s, 5s, [this](TaskContext context) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, NotInStomachSelector())) + { + DoCast(target, SPELL_MIND_FLAY); + } + + context.Repeat(10s, 15s); + }); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp index 5b854ecf6..c13ec226e 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" +#include "Unit.h" #include "sethekk_halls.h" enum Text @@ -38,7 +39,26 @@ enum Spells enum Npc { - NPC_BROOD_OF_ANZU = 23132 + NPC_BROOD_OF_ANZU = 23132, + NPC_HAWK_SPIRIT = 23134, + NPC_FALCON_SPIRIT = 23135, + NPC_EAGLE_SPIRIT = 23136 +}; + +enum Spirits +{ + SPELL_HAWK = 40237, + SPELL_FALCON = 40241, + SPELL_EAGLE = 40240, + + SPELL_DURATION = 40250, + + SPELL_FREEZE_ANIM = 16245, + SPELL_STONEFORM = 40308, + + SAY_STONED = 0, + + MAX_DRUID_SPELLS = 27 }; struct boss_anzu : public BossAI @@ -54,15 +74,25 @@ struct boss_anzu : public BossAI }); } + const Position AnzuSpiritPos[3] = + { + {-96.4816f, 304.236f, 26.5135f, 5.23599f}, // Hawk Spirit + {-72.3434f, 290.861f, 26.4851f, 3.29867f}, // Falcon Spirit + {-99.5906f, 276.661f, 26.8467f, 0.750492f}, // Eagle Spirit + }; + uint32 talkTimer; void SummonedCreatureDies(Creature* summon, Unit*) override { - summons.Despawn(summon); - summons.RemoveNotExisting(); - if (summons.empty()) + if (summon->GetEntry() == NPC_BROOD_OF_ANZU) { - me->RemoveAurasDueToSpell(SPELL_BANISH_SELF); + summons.Despawn(summon); + summons.RemoveNotExisting(); + if (summons.empty()) + { + me->RemoveAurasDueToSpell(SPELL_BANISH_SELF); + } } } @@ -78,6 +108,7 @@ struct boss_anzu : public BossAI void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); + SummonSpirits(); scheduler.Schedule(14s, [this](TaskContext context) { DoCastSelf(SPELL_PARALYZING_SCREECH); @@ -112,6 +143,13 @@ struct boss_anzu : public BossAI } } + void SummonSpirits() + { + me->SummonCreature(NPC_HAWK_SPIRIT, AnzuSpiritPos[0], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_FALCON_SPIRIT, AnzuSpiritPos[1], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_EAGLE_SPIRIT, AnzuSpiritPos[2], TEMPSUMMON_MANUAL_DESPAWN); + } + void UpdateAI(uint32 diff) override { if (talkTimer) @@ -119,6 +157,7 @@ struct boss_anzu : public BossAI talkTimer += diff; if (talkTimer >= 1000 && talkTimer < 10000) { + me->SetImmuneToAll(true); Talk(SAY_ANZU_INTRO1); talkTimer = 10000; } @@ -128,6 +167,7 @@ struct boss_anzu : public BossAI me->RemoveAurasDueToSpell(SPELL_SHADOWFORM); Talk(SAY_ANZU_INTRO2); talkTimer = 0; + me->SetInCombatWithZone(); } } @@ -142,7 +182,62 @@ struct boss_anzu : public BossAI } }; +struct npc_anzu_spirit : public ScriptedAI +{ + npc_anzu_spirit(Creature* creature) : ScriptedAI(creature) { } + + void IsSummonedBy(WorldObject* /*summoner*/) override + { + _scheduler.Schedule(1ms, [this](TaskContext task) + { + // Check for Druid HoTs every 2400ms + if (me->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 64, 0)) + { + me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM); + me->RemoveAurasDueToSpell(SPELL_STONEFORM); + + switch (me->GetEntry()) + { + case NPC_HAWK_SPIRIT: + DoCastSelf(SPELL_HAWK); + break; + case NPC_FALCON_SPIRIT: + DoCastSelf(SPELL_FALCON); + break; + case NPC_EAGLE_SPIRIT: + DoCastSelf(SPELL_EAGLE); + break; + default: + break; + } + } + else if (!me->HasAura(SPELL_STONEFORM)) + { + Talk(SAY_STONED); + DoCastSelf(SPELL_FREEZE_ANIM, true); + DoCastSelf(SPELL_STONEFORM, true); + } + + task.Repeat(2400ms); + }); + } + + void Reset() override + { + _scheduler.CancelAll(); + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } + +private: + TaskScheduler _scheduler; +}; + void AddSC_boss_anzu() { RegisterSethekkHallsCreatureAI(boss_anzu); + RegisterSethekkHallsCreatureAI(npc_anzu_spirit); } 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 b6eb11830..97b9627c8 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp @@ -201,6 +201,8 @@ struct npc_voidtraveler : public ScriptedAI void Reset() override { + me->SetReactState(REACT_PASSIVE); + if (TempSummon* summon = me->ToTempSummon()) { if (Unit* vorpil = summon->GetSummonerUnit())