mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
3
data/sql/updates/db_world/2023_07_15_00.sql
Normal file
3
data/sql/updates/db_world/2023_07_15_00.sql
Normal file
@@ -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));
|
||||
8
data/sql/updates/db_world/2023_07_15_01.sql
Normal file
8
data/sql/updates/db_world/2023_07_15_01.sql
Normal file
@@ -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\'');
|
||||
5
data/sql/updates/db_world/2023_07_15_02.sql
Normal file
5
data/sql/updates/db_world/2023_07_15_02.sql
Normal file
@@ -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);
|
||||
43
data/sql/updates/db_world/2023_07_15_03.sql
Normal file
43
data/sql/updates/db_world/2023_07_15_03.sql
Normal file
@@ -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)');
|
||||
26
data/sql/updates/db_world/2023_07_15_04.sql
Normal file
26
data/sql/updates/db_world/2023_07_15_04.sql
Normal file
@@ -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));
|
||||
5
data/sql/updates/db_world/2023_07_16_00.sql
Normal file
5
data/sql/updates/db_world/2023_07_16_00.sql
Normal file
@@ -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);
|
||||
25
data/sql/updates/db_world/2023_07_16_01.sql
Normal file
25
data/sql/updates/db_world/2023_07_16_01.sql
Normal file
@@ -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');
|
||||
2
data/sql/updates/db_world/2023_07_16_02.sql
Normal file
2
data/sql/updates/db_world/2023_07_16_02.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- DB update 2023_07_16_01 -> 2023_07_16_02
|
||||
UPDATE `quest_template_addon` SET `RequiredSkillPoints` = 70 WHERE (`ID` = 1582);
|
||||
4
data/sql/updates/db_world/2023_07_16_03.sql
Normal file
4
data/sql/updates/db_world/2023_07_16_03.sql
Normal file
@@ -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);
|
||||
|
||||
10
data/sql/updates/db_world/2023_07_17_00.sql
Normal file
10
data/sql/updates/db_world/2023_07_17_00.sql
Normal file
@@ -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
|
||||
3
data/sql/updates/db_world/2023_07_17_01.sql
Normal file
3
data/sql/updates/db_world/2023_07_17_01.sql
Normal file
@@ -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;
|
||||
3
data/sql/updates/db_world/2023_07_18_00.sql
Normal file
3
data/sql/updates/db_world/2023_07_18_00.sql
Normal file
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -306,7 +306,8 @@ typedef std::unordered_map<uint32, SpellProcEntry> 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
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
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>();
|
||||
}
|
||||
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<std::string>();
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
@@ -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<boss_curatorAI>(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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<Creature*> 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);
|
||||
}
|
||||
|
||||
@@ -15,44 +15,38 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* 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<npc_kilrekAI>(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<npc_demon_chainAI>(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<npc_fiendish_portalAI>(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<npc_fiendish_impAI>(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<boss_terestianAI>(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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user