Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2023-07-18 17:59:18 +08:00
23 changed files with 759 additions and 666 deletions

View 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));

View 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\'');

View 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);

View 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)');

View 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));

View 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);

View 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');

View 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);

View 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);

View 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

View 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;

View 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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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());

View File

@@ -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);
}

View File

@@ -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();
}
};

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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())