- Merge fix

This commit is contained in:
kadeshar
2026-03-13 22:41:25 +01:00
114 changed files with 73317 additions and 385 deletions
@@ -0,0 +1,5 @@
-- DB update 2026_03_06_00 -> 2026_03_07_00
-- Set Spawn Masks.
UPDATE `creature` SET `spawnMask` = `spawnMask` |2 WHERE (`id1` = 33059) AND (`guid` IN (136073, 136089, 136090));
UPDATE `creature` SET `spawnMask` = `spawnMask` |2 WHERE (`id1` = 33063) AND (`guid` IN (136246, 136249));
@@ -0,0 +1,6 @@
-- DB update 2026_03_07_00 -> 2026_03_07_01
-- Create new Guid.
DELETE FROM `creature` WHERE (`id1` = 33430) AND (`guid` IN (136607));
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES
(136607, 33430, 0, 0, 603, 0, 0, 3, 1, 0, 2221.8308, -14.313417, 423.59442, 3.60960, 604800, 5, 0, 195495, 0, 1, 0, 0, 0, '', NULL, 49345);
@@ -0,0 +1,5 @@
-- DB update 2026_03_07_01 -> 2026_03_07_02
-- Rime (49188/56822/59057) should only proc from Obliterate (SpellFamilyMask1 = 0x20000)
DELETE FROM `spell_proc` WHERE `SpellId` = -49188;
INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`)
VALUES (-49188, 0, 15, 0x00000000, 0x00020000, 0x00000000, 0, 0, 0x2, 0, 0, 0, 0, 0, 0, 0);
@@ -0,0 +1,3 @@
-- DB update 2026_03_07_02 -> 2026_03_07_03
UPDATE `spell_proc` SET `SpellFamilyMask0` = 4096, `ProcFlags` = 0, `Charges` = 0 WHERE `SpellId` = 36032;
UPDATE `spell_proc` SET `SpellFamilyMask0` = 0, `AttributesMask` = 8 WHERE `SpellId` = 44401;
@@ -0,0 +1,9 @@
-- DB update 2026_03_07_03 -> 2026_03_07_04
--
UPDATE `creature_template` SET `ScriptName` = 'npc_lor_themar_theron' WHERE (`entry` = 16802);
UPDATE `creature_template` SET `ScriptName` = 'npc_king_varian_wrynn' WHERE (`entry` = 29611);
UPDATE `creature_template` SET `ScriptName` = 'npc_tyrande_whisperwind' WHERE (`entry` = 7999);
UPDATE `creature_template` SET `ScriptName` = 'npc_king_magni_bronzebeard', `AIName` = '' WHERE (`entry` = 2784);
UPDATE `creature_template` SET `ScriptName` = 'npc_prophet_velen', `AIName` = '' WHERE (`entry` = 17468);
DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (2784,17468)) AND (`source_type` = 0);
@@ -0,0 +1,12 @@
-- DB update 2026_03_07_04 -> 2026_03_08_00
--
-- Remove misplaced "Yes, please!" option from menu 9586.
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 9586 AND `OptionID` = 1;
DELETE FROM `gossip_menu_option_locale` WHERE `MenuID` = 9586 AND `OptionID` = 1;
-- Show "Welcome, adventurer. You've come just in the nick..." if intro has not been completed yet
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 14) AND (`SourceGroup` = 9586) AND (`SourceEntry` IN (12939, 13470, 13471));
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(14, 9586, 13470, 0, 0, 13, 0, 7, 1, 0, 0, 0, 0, '', 'intro event must be completed'),
(14, 9586, 13471, 0, 0, 2, 0, 37888, 1, 0, 0, 0, 0, '', 'must have item Arcane Disruptor'),
(14, 9586, 13471, 0, 0, 13, 0, 7, 0, 0, 0, 0, 0, '', 'intro event must not be completed');
+252
View File
@@ -0,0 +1,252 @@
-- DB update 2026_03_08_00 -> 2026_03_08_01
ALTER TABLE `creature_classlevelstats` ADD `Strength` int NOT NULL DEFAULT '0' AFTER `damage_exp2`;
ALTER TABLE `creature_classlevelstats` ADD `Agility` int NOT NULL DEFAULT '0' AFTER `Strength`;
ALTER TABLE `creature_classlevelstats` ADD `Stamina` int NOT NULL DEFAULT '0' AFTER `Agility`;
ALTER TABLE `creature_classlevelstats` ADD `Intellect` int NOT NULL DEFAULT '0' AFTER `Stamina`;
ALTER TABLE `creature_classlevelstats` ADD `Spirit` int NOT NULL DEFAULT '0' AFTER `Intellect`;
UPDATE `creature_classlevelstats` SET `Strength` = 22, `Agility` = 7, `Stamina` = 22, `Intellect` = 20, `Spirit` = 20 WHERE `Level` = 1 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 23, `Agility` = 8, `Stamina` = 23, `Intellect` = 20, `Spirit` = 20 WHERE `Level` = 2 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 24, `Agility` = 8, `Stamina` = 24, `Intellect` = 20, `Spirit` = 21 WHERE `Level` = 3 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 25, `Agility` = 8, `Stamina` = 25, `Intellect` = 20, `Spirit` = 21 WHERE `Level` = 4 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 26, `Agility` = 8, `Stamina` = 25, `Intellect` = 20, `Spirit` = 21 WHERE `Level` = 5 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 27, `Agility` = 9, `Stamina` = 26, `Intellect` = 21, `Spirit` = 21 WHERE `Level` = 6 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 28, `Agility` = 9, `Stamina` = 27, `Intellect` = 21, `Spirit` = 22 WHERE `Level` = 7 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 29, `Agility` = 9, `Stamina` = 28, `Intellect` = 21, `Spirit` = 22 WHERE `Level` = 8 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 30, `Agility` = 9, `Stamina` = 29, `Intellect` = 21, `Spirit` = 22 WHERE `Level` = 9 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 31, `Agility` = 9, `Stamina` = 30, `Intellect` = 21, `Spirit` = 23 WHERE `Level` = 10 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 32, `Agility` = 10, `Stamina` = 34, `Intellect` = 21, `Spirit` = 23 WHERE `Level` = 11 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 33, `Agility` = 10, `Stamina` = 38, `Intellect` = 21, `Spirit` = 24 WHERE `Level` = 12 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 34, `Agility` = 11, `Stamina` = 42, `Intellect` = 21, `Spirit` = 25 WHERE `Level` = 13 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 35, `Agility` = 11, `Stamina` = 46, `Intellect` = 22, `Spirit` = 26 WHERE `Level` = 14 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 37, `Agility` = 12, `Stamina` = 51, `Intellect` = 22, `Spirit` = 27 WHERE `Level` = 15 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 38, `Agility` = 12, `Stamina` = 55, `Intellect` = 22, `Spirit` = 28 WHERE `Level` = 16 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 40, `Agility` = 12, `Stamina` = 59, `Intellect` = 22, `Spirit` = 29 WHERE `Level` = 17 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 42, `Agility` = 13, `Stamina` = 63, `Intellect` = 22, `Spirit` = 29 WHERE `Level` = 18 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 44, `Agility` = 13, `Stamina` = 67, `Intellect` = 22, `Spirit` = 31 WHERE `Level` = 19 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 45, `Agility` = 14, `Stamina` = 72, `Intellect` = 22, `Spirit` = 32 WHERE `Level` = 20 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 47, `Agility` = 14, `Stamina` = 76, `Intellect` = 23, `Spirit` = 32 WHERE `Level` = 21 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 49, `Agility` = 14, `Stamina` = 80, `Intellect` = 23, `Spirit` = 34 WHERE `Level` = 22 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 50, `Agility` = 15, `Stamina` = 84, `Intellect` = 23, `Spirit` = 34 WHERE `Level` = 23 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 52, `Agility` = 16, `Stamina` = 88, `Intellect` = 23, `Spirit` = 36 WHERE `Level` = 24 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 53, `Agility` = 16, `Stamina` = 94, `Intellect` = 23, `Spirit` = 37 WHERE `Level` = 25 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 55, `Agility` = 17, `Stamina` = 98, `Intellect` = 23, `Spirit` = 37 WHERE `Level` = 26 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 56, `Agility` = 17, `Stamina` = 102, `Intellect` = 23, `Spirit` = 39 WHERE `Level` = 27 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 58, `Agility` = 18, `Stamina` = 106, `Intellect` = 24, `Spirit` = 39 WHERE `Level` = 28 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 60, `Agility` = 18, `Stamina` = 110, `Intellect` = 24, `Spirit` = 41 WHERE `Level` = 29 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 61, `Agility` = 19, `Stamina` = 115, `Intellect` = 24, `Spirit` = 42 WHERE `Level` = 30 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 63, `Agility` = 19, `Stamina` = 120, `Intellect` = 24, `Spirit` = 42 WHERE `Level` = 31 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 64, `Agility` = 20, `Stamina` = 124, `Intellect` = 24, `Spirit` = 44 WHERE `Level` = 32 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 66, `Agility` = 20, `Stamina` = 128, `Intellect` = 24, `Spirit` = 44 WHERE `Level` = 33 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 67, `Agility` = 21, `Stamina` = 132, `Intellect` = 25, `Spirit` = 46 WHERE `Level` = 34 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 69, `Agility` = 21, `Stamina` = 138, `Intellect` = 25, `Spirit` = 47 WHERE `Level` = 35 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 70, `Agility` = 22, `Stamina` = 142, `Intellect` = 25, `Spirit` = 48 WHERE `Level` = 36 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 72, `Agility` = 22, `Stamina` = 146, `Intellect` = 25, `Spirit` = 49 WHERE `Level` = 37 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 74, `Agility` = 23, `Stamina` = 151, `Intellect` = 25, `Spirit` = 49 WHERE `Level` = 38 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 76, `Agility` = 23, `Stamina` = 155, `Intellect` = 26, `Spirit` = 51 WHERE `Level` = 39 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 78, `Agility` = 24, `Stamina` = 160, `Intellect` = 26, `Spirit` = 52 WHERE `Level` = 40 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 81, `Agility` = 25, `Stamina` = 165, `Intellect` = 26, `Spirit` = 53 WHERE `Level` = 41 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 86, `Agility` = 25, `Stamina` = 169, `Intellect` = 26, `Spirit` = 54 WHERE `Level` = 42 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 91, `Agility` = 26, `Stamina` = 128, `Intellect` = 26, `Spirit` = 55 WHERE `Level` = 43 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 97, `Agility` = 26, `Stamina` = 178, `Intellect` = 26, `Spirit` = 56 WHERE `Level` = 44 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 102, `Agility` = 27, `Stamina` = 184, `Intellect` = 27, `Spirit` = 58 WHERE `Level` = 45 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 104, `Agility` = 27, `Stamina` = 188, `Intellect` = 27, `Spirit` = 58 WHERE `Level` = 46 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 106, `Agility` = 28, `Stamina` = 193, `Intellect` = 27, `Spirit` = 60 WHERE `Level` = 47 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 108, `Agility` = 29, `Stamina` = 197, `Intellect` = 27, `Spirit` = 60 WHERE `Level` = 48 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 110, `Agility` = 29, `Stamina` = 202, `Intellect` = 28, `Spirit` = 62 WHERE `Level` = 49 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 113, `Agility` = 30, `Stamina` = 207, `Intellect` = 28, `Spirit` = 63 WHERE `Level` = 50 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 115, `Agility` = 30, `Stamina` = 212, `Intellect` = 28, `Spirit` = 64 WHERE `Level` = 51 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 117, `Agility` = 31, `Stamina` = 216, `Intellect` = 28, `Spirit` = 65 WHERE `Level` = 52 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 119, `Agility` = 32, `Stamina` = 221, `Intellect` = 28, `Spirit` = 66 WHERE `Level` = 53 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 122, `Agility` = 32, `Stamina` = 226, `Intellect` = 29, `Spirit` = 68 WHERE `Level` = 54 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 124, `Agility` = 33, `Stamina` = 231, `Intellect` = 29, `Spirit` = 69 WHERE `Level` = 55 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 127, `Agility` = 33, `Stamina` = 236, `Intellect` = 29, `Spirit` = 70 WHERE `Level` = 56 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 129, `Agility` = 34, `Stamina` = 241, `Intellect` = 29, `Spirit` = 71 WHERE `Level` = 57 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 131, `Agility` = 35, `Stamina` = 245, `Intellect` = 30, `Spirit` = 72 WHERE `Level` = 58 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 134, `Agility` = 35, `Stamina` = 250, `Intellect` = 30, `Spirit` = 73 WHERE `Level` = 59 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 136, `Agility` = 36, `Stamina` = 256, `Intellect` = 30, `Spirit` = 75 WHERE `Level` = 60 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 139, `Agility` = 38, `Stamina` = 261, `Intellect` = 30, `Spirit` = 78 WHERE `Level` = 61 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 141, `Agility` = 40, `Stamina` = 266, `Intellect` = 30, `Spirit` = 80 WHERE `Level` = 62 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 144, `Agility` = 42, `Stamina` = 270, `Intellect` = 31, `Spirit` = 84 WHERE `Level` = 63 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 146, `Agility` = 43, `Stamina` = 275, `Intellect` = 31, `Spirit` = 86 WHERE `Level` = 64 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 149, `Agility` = 45, `Stamina` = 281, `Intellect` = 31, `Spirit` = 88 WHERE `Level` = 65 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 151, `Agility` = 47, `Stamina` = 286, `Intellect` = 32, `Spirit` = 91 WHERE `Level` = 66 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 154, `Agility` = 49, `Stamina` = 291, `Intellect` = 32, `Spirit` = 93 WHERE `Level` = 67 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 156, `Agility` = 51, `Stamina` = 296, `Intellect` = 32, `Spirit` = 95 WHERE `Level` = 68 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 159, `Agility` = 53, `Stamina` = 301, `Intellect` = 32, `Spirit` = 96 WHERE `Level` = 69 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 162, `Agility` = 54, `Stamina` = 307, `Intellect` = 33, `Spirit` = 99 WHERE `Level` = 70 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 164, `Agility` = 58, `Stamina` = 312, `Intellect` = 33, `Spirit` = 102 WHERE `Level` = 71 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 167, `Agility` = 63, `Stamina` = 317, `Intellect` = 34, `Spirit` = 105 WHERE `Level` = 72 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 170, `Agility` = 68, `Stamina` = 322, `Intellect` = 34, `Spirit` = 108 WHERE `Level` = 73 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 187, `Agility` = 73, `Stamina` = 328, `Intellect` = 59, `Spirit` = 99 WHERE `Level` = 74 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 206, `Agility` = 78, `Stamina` = 334, `Intellect` = 61, `Spirit` = 101 WHERE `Level` = 75 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 226, `Agility` = 84, `Stamina` = 339, `Intellect` = 62, `Spirit` = 102 WHERE `Level` = 76 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 249, `Agility` = 91, `Stamina` = 344, `Intellect` = 62, `Spirit` = 104 WHERE `Level` = 77 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 274, `Agility` = 98, `Stamina` = 349, `Intellect` = 63, `Spirit` = 105 WHERE `Level` = 78 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 301, `Agility` = 105, `Stamina` = 355, `Intellect` = 63, `Spirit` = 107 WHERE `Level` = 79 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 331, `Agility` = 113, `Stamina` = 361, `Intellect` = 65, `Spirit` = 109 WHERE `Level` = 80 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 364, `Agility` = 122, `Stamina` = 366, `Intellect` = 66, `Spirit` = 110 WHERE `Level` = 81 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 401, `Agility` = 131, `Stamina` = 372, `Intellect` = 66, `Spirit` = 111 WHERE `Level` = 82 AND `Class` = 1;
UPDATE `creature_classlevelstats` SET `Strength` = 23, `Agility` = 8, `Stamina` = 23, `Intellect` = 21, `Spirit` = 22 WHERE `Level` = 3 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 24, `Agility` = 9, `Stamina` = 24, `Intellect` = 22, `Spirit` = 23 WHERE `Level` = 4 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 24, `Agility` = 9, `Stamina` = 25, `Intellect` = 22, `Spirit` = 24 WHERE `Level` = 5 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 25, `Agility` = 9, `Stamina` = 26, `Intellect` = 23, `Spirit` = 24 WHERE `Level` = 6 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 26, `Agility` = 9, `Stamina` = 26, `Intellect` = 24, `Spirit` = 25 WHERE `Level` = 7 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 27, `Agility` = 10, `Stamina` = 27, `Intellect` = 24, `Spirit` = 25 WHERE `Level` = 8 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 28, `Agility` = 10, `Stamina` = 28, `Intellect` = 25, `Spirit` = 26 WHERE `Level` = 9 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 29, `Agility` = 10, `Stamina` = 29, `Intellect` = 25, `Spirit` = 27 WHERE `Level` = 10 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 30, `Agility` = 10, `Stamina` = 32, `Intellect` = 26, `Spirit` = 28 WHERE `Level` = 11 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 31, `Agility` = 10, `Stamina` = 36, `Intellect` = 27, `Spirit` = 29 WHERE `Level` = 12 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 32, `Agility` = 11, `Stamina` = 40, `Intellect` = 28, `Spirit` = 30 WHERE `Level` = 13 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 33, `Agility` = 11, `Stamina` = 44, `Intellect` = 29, `Spirit` = 31 WHERE `Level` = 14 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 34, `Agility` = 12, `Stamina` = 48, `Intellect` = 31, `Spirit` = 32 WHERE `Level` = 15 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 36, `Agility` = 12, `Stamina` = 52, `Intellect` = 31, `Spirit` = 33 WHERE `Level` = 16 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 38, `Agility` = 12, `Stamina` = 55, `Intellect` = 32, `Spirit` = 34 WHERE `Level` = 17 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 39, `Agility` = 13, `Stamina` = 59, `Intellect` = 34, `Spirit` = 36 WHERE `Level` = 18 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 40, `Agility` = 13, `Stamina` = 63, `Intellect` = 34, `Spirit` = 37 WHERE `Level` = 19 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 42, `Agility` = 14, `Stamina` = 67, `Intellect` = 36, `Spirit` = 38 WHERE `Level` = 20 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 44, `Agility` = 14, `Stamina` = 71, `Intellect` = 37, `Spirit` = 39 WHERE `Level` = 21 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 46, `Agility` = 14, `Stamina` = 75, `Intellect` = 38, `Spirit` = 41 WHERE `Level` = 22 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 47, `Agility` = 15, `Stamina` = 79, `Intellect` = 39, `Spirit` = 42 WHERE `Level` = 23 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 49, `Agility` = 16, `Stamina` = 83, `Intellect` = 40, `Spirit` = 43 WHERE `Level` = 24 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 50, `Agility` = 16, `Stamina` = 87, `Intellect` = 42, `Spirit` = 44 WHERE `Level` = 25 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 52, `Agility` = 16, `Stamina` = 91, `Intellect` = 43, `Spirit` = 46 WHERE `Level` = 26 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 53, `Agility` = 17, `Stamina` = 95, `Intellect` = 43, `Spirit` = 47 WHERE `Level` = 27 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 55, `Agility` = 17, `Stamina` = 99, `Intellect` = 45, `Spirit` = 48 WHERE `Level` = 28 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 57, `Agility` = 18, `Stamina` = 103, `Intellect` = 46, `Spirit` = 49 WHERE `Level` = 29 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 57, `Agility` = 18, `Stamina` = 107, `Intellect` = 48, `Spirit` = 51 WHERE `Level` = 30 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 59, `Agility` = 19, `Stamina` = 111, `Intellect` = 49, `Spirit` = 52 WHERE `Level` = 31 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 60, `Agility` = 19, `Stamina` = 115, `Intellect` = 50, `Spirit` = 53 WHERE `Level` = 32 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 62, `Agility` = 20, `Stamina` = 119, `Intellect` = 51, `Spirit` = 54 WHERE `Level` = 33 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 63, `Agility` = 20, `Stamina` = 123, `Intellect` = 52, `Spirit` = 56 WHERE `Level` = 34 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 65, `Agility` = 21, `Stamina` = 127, `Intellect` = 54, `Spirit` = 57 WHERE `Level` = 35 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 66, `Agility` = 21, `Stamina` = 131, `Intellect` = 55, `Spirit` = 59 WHERE `Level` = 36 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 68, `Agility` = 21, `Stamina` = 135, `Intellect` = 56, `Spirit` = 60 WHERE `Level` = 37 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 70, `Agility` = 22, `Stamina` = 139, `Intellect` = 58, `Spirit` = 62 WHERE `Level` = 38 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 72, `Agility` = 22, `Stamina` = 143, `Intellect` = 59, `Spirit` = 63 WHERE `Level` = 39 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 74, `Agility` = 23, `Stamina` = 148, `Intellect` = 61, `Spirit` = 65 WHERE `Level` = 40 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 76, `Agility` = 23, `Stamina` = 152, `Intellect` = 62, `Spirit` = 66 WHERE `Level` = 41 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 81, `Agility` = 23, `Stamina` = 156, `Intellect` = 63, `Spirit` = 67 WHERE `Level` = 42 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 86, `Agility` = 24, `Stamina` = 160, `Intellect` = 65, `Spirit` = 69 WHERE `Level` = 43 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 93, `Agility` = 25, `Stamina` = 164, `Intellect` = 65, `Spirit` = 70 WHERE `Level` = 44 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 96, `Agility` = 25, `Stamina` = 169, `Intellect` = 67, `Spirit` = 72 WHERE `Level` = 45 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 98, `Agility` = 26, `Stamina` = 173, `Intellect` = 68, `Spirit` = 73 WHERE `Level` = 46 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 100, `Agility` = 26, `Stamina` = 177, `Intellect` = 70, `Spirit` = 75 WHERE `Level` = 47 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 102, `Agility` = 27, `Stamina` = 181, `Intellect` = 72, `Spirit` = 76 WHERE `Level` = 48 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 104, `Agility` = 27, `Stamina` = 186, `Intellect` = 73, `Spirit` = 78 WHERE `Level` = 49 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 107, `Agility` = 28, `Stamina` = 190, `Intellect` = 75, `Spirit` = 80 WHERE `Level` = 50 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 109, `Agility` = 29, `Stamina` = 194, `Intellect` = 76, `Spirit` = 81 WHERE `Level` = 51 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 111, `Agility` = 29, `Stamina` = 199, `Intellect` = 77, `Spirit` = 82 WHERE `Level` = 52 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 113, `Agility` = 30, `Stamina` = 203, `Intellect` = 79, `Spirit` = 84 WHERE `Level` = 53 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 115, `Agility` = 30, `Stamina` = 207, `Intellect` = 80, `Spirit` = 85 WHERE `Level` = 54 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 117, `Agility` = 31, `Stamina` = 212, `Intellect` = 82, `Spirit` = 88 WHERE `Level` = 55 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 120, `Agility` = 31, `Stamina` = 216, `Intellect` = 83, `Spirit` = 89 WHERE `Level` = 56 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 122, `Agility` = 32, `Stamina` = 221, `Intellect` = 84, `Spirit` = 90 WHERE `Level` = 57 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 124, `Agility` = 33, `Stamina` = 225, `Intellect` = 87, `Spirit` = 92 WHERE `Level` = 58 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 127, `Agility` = 33, `Stamina` = 230, `Intellect` = 88, `Spirit` = 94 WHERE `Level` = 59 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 129, `Agility` = 34, `Stamina` = 234, `Intellect` = 90, `Spirit` = 96 WHERE `Level` = 60 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 132, `Agility` = 35, `Stamina` = 239, `Intellect` = 105, `Spirit` = 99 WHERE `Level` = 61 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 133, `Agility` = 36, `Stamina` = 243, `Intellect` = 108, `Spirit` = 102 WHERE `Level` = 62 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 136, `Agility` = 37, `Stamina` = 248, `Intellect` = 112, `Spirit` = 105 WHERE `Level` = 63 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 138, `Agility` = 38, `Stamina` = 252, `Intellect` = 115, `Spirit` = 108 WHERE `Level` = 64 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 141, `Agility` = 39, `Stamina` = 257, `Intellect` = 119, `Spirit` = 110 WHERE `Level` = 65 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 143, `Agility` = 39, `Stamina` = 261, `Intellect` = 122, `Spirit` = 113 WHERE `Level` = 66 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 146, `Agility` = 41, `Stamina` = 266, `Intellect` = 124, `Spirit` = 115 WHERE `Level` = 67 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 148, `Agility` = 41, `Stamina` = 271, `Intellect` = 127, `Spirit` = 118 WHERE `Level` = 68 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 151, `Agility` = 42, `Stamina` = 275, `Intellect` = 130, `Spirit` = 120 WHERE `Level` = 69 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 153, `Agility` = 43, `Stamina` = 280, `Intellect` = 133, `Spirit` = 122 WHERE `Level` = 70 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 155, `Agility` = 47, `Stamina` = 285, `Intellect` = 134, `Spirit` = 125 WHERE `Level` = 71 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 158, `Agility` = 50, `Stamina` = 289, `Intellect` = 136, `Spirit` = 127 WHERE `Level` = 72 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 161, `Agility` = 54, `Stamina` = 294, `Intellect` = 138, `Spirit` = 130 WHERE `Level` = 73 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 177, `Agility` = 58, `Stamina` = 299, `Intellect` = 139, `Spirit` = 190 WHERE `Level` = 74 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 195, `Agility` = 63, `Stamina` = 304, `Intellect` = 141, `Spirit` = 194 WHERE `Level` = 75 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 214, `Agility` = 67, `Stamina` = 309, `Intellect` = 143, `Spirit` = 196 WHERE `Level` = 76 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 236, `Agility` = 72, `Stamina` = 314, `Intellect` = 144, `Spirit` = 200 WHERE `Level` = 77 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 260, `Agility` = 78, `Stamina` = 318, `Intellect` = 146, `Spirit` = 202 WHERE `Level` = 78 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 285, `Agility` = 84, `Stamina` = 323, `Intellect` = 148, `Spirit` = 206 WHERE `Level` = 79 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 314, `Agility` = 90, `Stamina` = 328, `Intellect` = 150, `Spirit` = 209 WHERE `Level` = 80 AND `Class` = 2;
UPDATE `creature_classlevelstats` SET `Strength` = 30, `Agility` = 33, `Stamina` = 29, `Intellect` = 21, `Spirit` = 0 WHERE `Level` = 9 AND `Class` = 4;
UPDATE `creature_classlevelstats` SET `Strength` = 331, `Agility` = 856, `Stamina` = 361, `Intellect` = 65, `Spirit` = 0 WHERE `Level` = 80 AND `Class` = 4;
UPDATE `creature_classlevelstats` SET `Strength` = 20, `Agility` = 20, `Stamina` = 20, `Intellect` = 25, `Spirit` = 23 WHERE `Level` = 1 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 22, `Agility` = 20, `Stamina` = 21, `Intellect` = 27, `Spirit` = 25 WHERE `Level` = 3 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 23, `Agility` = 21, `Stamina` = 21, `Intellect` = 29, `Spirit` = 26 WHERE `Level` = 4 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 23, `Agility` = 21, `Stamina` = 22, `Intellect` = 30, `Spirit` = 27 WHERE `Level` = 5 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 24, `Agility` = 21, `Stamina` = 22, `Intellect` = 31, `Spirit` = 28 WHERE `Level` = 6 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 25, `Agility` = 21, `Stamina` = 23, `Intellect` = 32, `Spirit` = 29 WHERE `Level` = 7 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 26, `Agility` = 21, `Stamina` = 23, `Intellect` = 33, `Spirit` = 30 WHERE `Level` = 8 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 27, `Agility` = 21, `Stamina` = 23, `Intellect` = 35, `Spirit` = 32 WHERE `Level` = 9 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 27, `Agility` = 22, `Stamina` = 24, `Intellect` = 36, `Spirit` = 33 WHERE `Level` = 10 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 28, `Agility` = 22, `Stamina` = 24, `Intellect` = 39, `Spirit` = 35 WHERE `Level` = 11 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 29, `Agility` = 22, `Stamina` = 26, `Intellect` = 44, `Spirit` = 38 WHERE `Level` = 12 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 30, `Agility` = 22, `Stamina` = 26, `Intellect` = 47, `Spirit` = 40 WHERE `Level` = 13 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 31, `Agility` = 22, `Stamina` = 28, `Intellect` = 56, `Spirit` = 45 WHERE `Level` = 14 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 32, `Agility` = 23, `Stamina` = 29, `Intellect` = 61, `Spirit` = 48 WHERE `Level` = 15 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 34, `Agility` = 23, `Stamina` = 30, `Intellect` = 64, `Spirit` = 50 WHERE `Level` = 16 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 36, `Agility` = 23, `Stamina` = 31, `Intellect` = 68, `Spirit` = 53 WHERE `Level` = 17 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 37, `Agility` = 23, `Stamina` = 32, `Intellect` = 72, `Spirit` = 55 WHERE `Level` = 18 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 38, `Agility` = 23, `Stamina` = 33, `Intellect` = 76, `Spirit` = 58 WHERE `Level` = 19 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 40, `Agility` = 24, `Stamina` = 35, `Intellect` = 81, `Spirit` = 61 WHERE `Level` = 20 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 42, `Agility` = 24, `Stamina` = 35, `Intellect` = 72, `Spirit` = 52 WHERE `Level` = 21 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 44, `Agility` = 24, `Stamina` = 37, `Intellect` = 89, `Spirit` = 67 WHERE `Level` = 22 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 45, `Agility` = 24, `Stamina` = 37, `Intellect` = 92, `Spirit` = 69 WHERE `Level` = 23 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 46, `Agility` = 25, `Stamina` = 39, `Intellect` = 97, `Spirit` = 73 WHERE `Level` = 24 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 47, `Agility` = 25, `Stamina` = 40, `Intellect` = 101, `Spirit` = 75 WHERE `Level` = 25 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 49, `Agility` = 25, `Stamina` = 41, `Intellect` = 105, `Spirit` = 78 WHERE `Level` = 26 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 50, `Agility` = 25, `Stamina` = 43, `Intellect` = 110, `Spirit` = 81 WHERE `Level` = 27 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 52, `Agility` = 25, `Stamina` = 43, `Intellect` = 121, `Spirit` = 86 WHERE `Level` = 28 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 54, `Agility` = 26, `Stamina` = 45, `Intellect` = 126, `Spirit` = 89 WHERE `Level` = 29 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 54, `Agility` = 26, `Stamina` = 46, `Intellect` = 131, `Spirit` = 92 WHERE `Level` = 30 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 56, `Agility` = 26, `Stamina` = 47, `Intellect` = 134, `Spirit` = 95 WHERE `Level` = 31 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 57, `Agility` = 26, `Stamina` = 49, `Intellect` = 139, `Spirit` = 98 WHERE `Level` = 32 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 59, `Agility` = 27, `Stamina` = 49, `Intellect` = 143, `Spirit` = 101 WHERE `Level` = 33 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 60, `Agility` = 27, `Stamina` = 51, `Intellect` = 147, `Spirit` = 104 WHERE `Level` = 34 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 62, `Agility` = 27, `Stamina` = 52, `Intellect` = 152, `Spirit` = 107 WHERE `Level` = 35 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 63, `Agility` = 28, `Stamina` = 53, `Intellect` = 156, `Spirit` = 110 WHERE `Level` = 36 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 64, `Agility` = 28, `Stamina` = 55, `Intellect` = 161, `Spirit` = 114 WHERE `Level` = 37 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 66, `Agility` = 28, `Stamina` = 55, `Intellect` = 165, `Spirit` = 116 WHERE `Level` = 38 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 68, `Agility` = 28, `Stamina` = 57, `Intellect` = 170, `Spirit` = 120 WHERE `Level` = 39 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 70, `Agility` = 29, `Stamina` = 59, `Intellect` = 174, `Spirit` = 123 WHERE `Level` = 40 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 72, `Agility` = 29, `Stamina` = 59, `Intellect` = 178, `Spirit` = 126 WHERE `Level` = 41 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 77, `Agility` = 29, `Stamina` = 61, `Intellect` = 190, `Spirit` = 131 WHERE `Level` = 42 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 81, `Agility` = 29, `Stamina` = 62, `Intellect` = 194, `Spirit` = 134 WHERE `Level` = 43 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 88, `Agility` = 30, `Stamina` = 63, `Intellect` = 199, `Spirit` = 138 WHERE `Level` = 44 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 91, `Agility` = 30, `Stamina` = 65, `Intellect` = 204, `Spirit` = 141 WHERE `Level` = 45 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 93, `Agility` = 30, `Stamina` = 66, `Intellect` = 208, `Spirit` = 144 WHERE `Level` = 46 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 95, `Agility` = 31, `Stamina` = 68, `Intellect` = 213, `Spirit` = 148 WHERE `Level` = 47 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 97, `Agility` = 31, `Stamina` = 68, `Intellect` = 218, `Spirit` = 151 WHERE `Level` = 48 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 99, `Agility` = 31, `Stamina` = 70, `Intellect` = 223, `Spirit` = 155 WHERE `Level` = 49 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 101, `Agility` = 32, `Stamina` = 72, `Intellect` = 228, `Spirit` = 158 WHERE `Level` = 50 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 103, `Agility` = 32, `Stamina` = 73, `Intellect` = 232, `Spirit` = 161 WHERE `Level` = 51 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 105, `Agility` = 32, `Stamina` = 74, `Intellect` = 237, `Spirit` = 165 WHERE `Level` = 52 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 107, `Agility` = 33, `Stamina` = 75, `Intellect` = 241, `Spirit` = 168 WHERE `Level` = 53 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 109, `Agility` = 33, `Stamina` = 77, `Intellect` = 247, `Spirit` = 172 WHERE `Level` = 54 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 111, `Agility` = 33, `Stamina` = 79, `Intellect` = 252, `Spirit` = 176 WHERE `Level` = 55 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 114, `Agility` = 34, `Stamina` = 80, `Intellect` = 265, `Spirit` = 181 WHERE `Level` = 56 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 116, `Agility` = 34, `Stamina` = 81, `Intellect` = 271, `Spirit` = 185 WHERE `Level` = 57 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 117, `Agility` = 34, `Stamina` = 82, `Intellect` = 275, `Spirit` = 188 WHERE `Level` = 58 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 120, `Agility` = 35, `Stamina` = 84, `Intellect` = 281, `Spirit` = 193 WHERE `Level` = 59 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 122, `Agility` = 35, `Stamina` = 86, `Intellect` = 286, `Spirit` = 196 WHERE `Level` = 60 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 125, `Agility` = 35, `Stamina` = 87, `Intellect` = 286, `Spirit` = 206 WHERE `Level` = 61 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 126, `Agility` = 35, `Stamina` = 89, `Intellect` = 286, `Spirit` = 212 WHERE `Level` = 62 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 129, `Agility` = 36, `Stamina` = 90, `Intellect` = 286, `Spirit` = 220 WHERE `Level` = 63 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 131, `Agility` = 36, `Stamina` = 92, `Intellect` = 287, `Spirit` = 226 WHERE `Level` = 64 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 134, `Agility` = 36, `Stamina` = 94, `Intellect` = 288, `Spirit` = 233 WHERE `Level` = 65 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 135, `Agility` = 37, `Stamina` = 94, `Intellect` = 297, `Spirit` = 239 WHERE `Level` = 66 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 138, `Agility` = 37, `Stamina` = 96, `Intellect` = 306, `Spirit` = 246 WHERE `Level` = 67 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 140, `Agility` = 37, `Stamina` = 97, `Intellect` = 312, `Spirit` = 251 WHERE `Level` = 68 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 143, `Agility` = 38, `Stamina` = 99, `Intellect` = 319, `Spirit` = 257 WHERE `Level` = 69 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 145, `Agility` = 38, `Stamina` = 101, `Intellect` = 327, `Spirit` = 263 WHERE `Level` = 70 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 147, `Agility` = 41, `Stamina` = 102, `Intellect` = 331, `Spirit` = 269 WHERE `Level` = 71 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 150, `Agility` = 44, `Stamina` = 104, `Intellect` = 335, `Spirit` = 275 WHERE `Level` = 72 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 153, `Agility` = 47, `Stamina` = 105, `Intellect` = 339, `Spirit` = 281 WHERE `Level` = 73 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 168, `Agility` = 51, `Stamina` = 107, `Intellect` = 343, `Spirit` = 333 WHERE `Level` = 74 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 185, `Agility` = 55, `Stamina` = 109, `Intellect` = 347, `Spirit` = 339 WHERE `Level` = 75 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 203, `Agility` = 59, `Stamina` = 110, `Intellect` = 351, `Spirit` = 344 WHERE `Level` = 76 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 224, `Agility` = 64, `Stamina` = 113, `Intellect` = 355, `Spirit` = 349 WHERE `Level` = 77 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 246, `Agility` = 68, `Stamina` = 114, `Intellect` = 360, `Spirit` = 355 WHERE `Level` = 78 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 270, `Agility` = 74, `Stamina` = 116, `Intellect` = 364, `Spirit` = 360 WHERE `Level` = 79 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 297, `Agility` = 79, `Stamina` = 118, `Intellect` = 369, `Spirit` = 367 WHERE `Level` = 80 AND `Class` = 8;
UPDATE `creature_classlevelstats` SET `Strength` = 327, `Agility` = 84, `Stamina` = 119, `Intellect` = 373, `Spirit` = 372 WHERE `Level` = 81 AND `Class` = 8;
@@ -0,0 +1,28 @@
-- DB update 2026_03_08_01 -> 2026_03_08_02
--
-- Update Lady Sinestra's `path_id` to GUID*10 for Lady Sinestras spawn (previously: 23283)
UPDATE `creature_addon` SET `path_id` = 287960 WHERE `guid` = 28796;
-- Assign lady Sinestra's waypoints `waypoint_data` to proper id
UPDATE `waypoint_data` SET `id` = 287960 WHERE `id` = 232830;
-- Add O'Reily waypoint data
DELETE FROM `waypoint_data` WHERE `id` = 232830;
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(232830, 1, -6750.71, -4729.29, 18.162, NULL, 0, 0, 0, 100, 5300507),
(232830, 2, -6745.54, -4730.11, 21.3666, NULL, 0, 0, 0, 100, 5300508),
(232830, 3, -6741.23, -4733.09, 22.9047, NULL, 0, 0, 0, 100, 5300509),
(232830, 4, -6739.45, -4735.04, 21.95, NULL, 0, 0, 0, 100, 5300510),
(232830, 5, -6734.35, -4739.1, 19.6258, NULL, 0, 0, 0, 100, 5300511),
(232830, 6, -6729.12, -4739.22, 19.6489, NULL, 0, 0, 0, 100, 5300511),
(232830, 7, -6723.62, -4735.62, 20.9465, NULL, 0, 0, 0, 100, 5300511),
(232830, 8, -6717.79, -4732.6, 21.8267, NULL, 0, 0, 0, 100, 5300512),
(232830, 9, -6710.5, -4729.87, 21.2642, NULL, 0, 0, 0, 100, 5300513),
(232830, 10, -6701.65, -4730.19, 22.8937, NULL, 0, 0, 0, 100, 5300513),
(232830, 11, -6706.7, -4728.98, 21.7531, NULL, 0, 0, 0, 100, 5300514),
(232830, 12, -6712.82, -4731.23, 22.3174, NULL, 0, 0, 0, 100, 5300515),
(232830, 13, -6719.86, -4734.66, 21.7555, NULL, 0, 0, 0, 100, 5300516),
(232830, 14, -6727.36, -4738.61, 19.9282, NULL, 0, 0, 0, 100, 5300517),
(232830, 15, -6737.15, -4738.2, 20.22, NULL, 0, 0, 0, 100, 5300518),
(232830, 16, -6742.15, -4734.1, 22.6405, NULL, 0, 0, 0, 100, 5300519),
(232830, 17, -6746.14, -4730.77, 21.0577, NULL, 0, 0, 0, 100, 5300520);
@@ -0,0 +1,3 @@
-- DB update 2026_03_08_02 -> 2026_03_08_03
-- Remove SPELL_ATTR0_CU_DONT_BREAK_STEALTH (0x40) from Piercing Howl
UPDATE `spell_custom_attr` SET `attributes` = `attributes` & ~(64) WHERE `spell_id` = 12323;
@@ -0,0 +1,68 @@
-- DB update 2026_03_08_03 -> 2026_03_08_04
-- Remove Not-Selectable flag (Earthen Stoneshaper)
UPDATE `creature_template` SET `unit_flags` = `unit_flags` &~33554432 WHERE (`entry` = 33620);
-- Remove SAI (Earthen Stoneshaper)
UPDATE `creature_template` SET `AIName` = '' WHERE (`entry` = 33620);
-- Delete GUID SAI (Earthen Stoneshaper, Kirin Tor Battle-Mage & Kirin Tor Mage).
DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-136525, -136526, -136537, -136524, -136271)) AND (`source_type` = 0);
-- Move waypoints in waypoint_data.
DELETE FROM `waypoints` WHERE `entry` IN (13627100, 13627101,33624);
DELETE FROM `waypoint_data` WHERE `id` IN (13627100, 13627101, 3362400);
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(13627100, 1, -856.854, -159.629, 458.894, NULL, 0, 0, 0, 100, 0),
(13627100, 2, -815.381, -160.206, 429.841, NULL, 0, 0, 0, 100, 0),
(13627100, 3, -812.063, -160.252, 429.841, NULL, 0, 0, 0, 100, 0),
(13627100, 4, -787.449, -186.878, 429.841, NULL, 0, 0, 0, 100, 0),
(13627100, 5, -764.428, -185.599, 429.841, NULL, 0, 0, 0, 100, 0),
(13627100, 6, -756.902, -183.903, 429.824, NULL, 0, 0, 0, 100, 0),
(13627100, 7, -743.469, -190.483, 429.841, NULL, 45000, 0, 0, 100, 0),
(13627100, 8, -735.021, -155.349, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 9, -733.845, -123.15, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 10, -735.325, -104.313, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 11, -726.365, -86.0322, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 12, -710.154, -81.27, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 13, -700.494, -81.3369, 429.402, NULL, 45000, 0, 0, 100, 0),
(13627100, 14, -723.062, -81.6906, 429.842, NULL, 0, 0, 0, 100, 0),
(13627100, 15, -735.383, -98.9337, 429.842, NULL, 0, 0, 0, 100, 0),
(13627100, 16, -736.991, -134.149, 429.841, NULL, 0, 0, 0, 100, 0),
(13627100, 17, -740.398, -157.068, 429.842, NULL, 0, 0, 0, 100, 0),
(13627100, 18, -746.407, -170.483, 429.842, NULL, 0, 0, 0, 100, 0),
(13627100, 19, -748.094, -175.932, 429.801, NULL, 0, 0, 0, 100, 0),
(13627100, 20, -776.031, -186.115, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 21, -795.367, -180.787, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 22, -803.027, -151.463, 429.84, NULL, 0, 0, 0, 100, 0),
(13627100, 23, -800.079, -131.901, 429.614, NULL, 0, 0, 0, 100, 0),
(13627100, 24, -798.208, -85.7146, 429.842, NULL, 0, 0, 0, 100, 0),
(13627100, 25, -796.247, -66.4749, 429.843, NULL, 0, 0, 0, 100, 0),
(13627100, 26, -803.578, -54.884, 429.843, NULL, 0, 0, 0, 100, 0),
(13627101, 1, -759.514, -46.609, 429.84, NULL, 0, 1, 0, 100, 0),
(13627101, 2, -709.315, -26.547, 429.84, NULL, 0, 1, 0, 100, 0),
(13627101, 3, -702.395, -11.965, 429.73, NULL, 0, 1, 0, 100, 0),
(13627101, 4, -679.813, -8.959, 426.88, NULL, 0, 1, 0, 100, 0),
(3362400, 1, -696.34, -85.89, 429.24, NULL, 0, 0, 0, 100, 0),
(3362400, 2, -676.52, -84.802, 426.89, NULL, 0, 0, 0, 100, 0);
-- Edit SAI (Goran Steelbreaker & Archmage Pentarus).
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE (`entry` IN (33622, 33624));
DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (33622,33624));
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`, `event_param6`, `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
(33622, 0, 0, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 13627100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Goran Steelbreaker - On Respawn - Start Path 13627100'),
(33622, 0, 1, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 232, 13627101, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Goran Steelbreaker - On Data Set 0 1 - Start Path 13627101'),
(33624, 0, 0, 0, 38, 0, 100, 512, 1, 1, 0, 0, 0, 0, 232, 3362400, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Archmage Pentarus - On Data Set 1 1 - Start Path 3362400'),
(33624, 0, 1, 2, 109, 0, 100, 0, 0, 3362400, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Archmage Pentarus - On Path 3362400 Finished - Say Line 1'),
(33624, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 45, 0, 2, 0, 0, 0, 0, 10, 136253, 33579, 0, 0, 0, 0, 0, 0, 'Archmage Pentarus - On Path 3362400 Finished - Set Data 0 2');
-- Set Creature Formations.
DELETE FROM `creature_formations` WHERE (`LeaderGUID` IN (136271, 136281));
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(136271, 136271, 0, 0, 515, 0, 0),
(136271, 136525, 3, 120, 515, 0, 0),
(136271, 136526, 3, 240, 515, 0, 0),
(136281, 136281, 0, 0, 515, 0, 0),
(136281, 136537, 5, 120, 515, 0, 0),
(136281, 136524, 5, 240, 515, 0, 0);
@@ -0,0 +1,4 @@
-- DB update 2026_03_08_04 -> 2026_03_09_00
-- Update .npc info help text for optional GUID support
UPDATE `command` SET `help` = 'Syntax: .npc info [#creature_guid]\r\n\r\nDisplay a list of details for the selected creature, or for the creature with the given GUID if no target is selected.\r\n\r\nWhen a creature is targeted or found in the current map, the list includes:\r\n- GUID, Faction, NPC flags, Entry ID, Model ID,\r\n- Level,\r\n- Health (current/maximum),\r\n- Field flags, dynamic flags, faction template,\r\n- Position information,\r\n- and the creature type, e.g. if the creature is a vendor.\r\n\r\nWhen only a GUID is given and the creature is not in the current map, DB-stored data is shown (spawn ID, entry, phase, position, map, etc.).'
WHERE `name` = 'npc info';
@@ -0,0 +1,5 @@
-- DB update 2026_03_09_00 -> 2026_03_09_01
DELETE FROM `spell_proc` WHERE `SpellId` IN (57529, 57531);
INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES
(57529, 0, 3, 0x61401035, 0x00001000, 0, 0, 0, 1, 0, 0x8, 0, 0, 0, 0, 0),
(57531, 0, 3, 0x61401035, 0x00001000, 0, 0, 0, 1, 0, 0x8, 0, 0, 0, 0, 0);
+415
View File
@@ -0,0 +1,415 @@
-- DB update 2026_03_09_01 -> 2026_03_09_02
-- DB update 2026_03_06_00 -> rev_1772756451514538300
-- chore(DB/Text): Add German (deDE) translations for acore_string
-- Command system
UPDATE `acore_string` SET `locale_deDE` = 'Befehl ''{}'' existiert nicht.' WHERE `entry` = 6;
UPDATE `acore_string` SET `locale_deDE` = 'Unterbefehl ''{}{}{}'' ist mehrdeutig:' WHERE `entry` = 7;
UPDATE `acore_string` SET `locale_deDE` = 'Mögliche Unterbefehle:' WHERE `entry` = 8;
UPDATE `acore_string` SET `locale_deDE` = 'Der Unterbefehl ''{}{}{}'' existiert nicht.' WHERE `entry` = 193;
UPDATE `acore_string` SET `locale_deDE` = 'Befehl ''{}'' ist mehrdeutig:' WHERE `entry` = 194;
UPDATE `acore_string` SET `locale_deDE` = '### VERWENDUNG: .{} ...' WHERE `entry` = 195;
UPDATE `acore_string` SET `locale_deDE` = 'Für ''{}'' sind keine detaillierten Verwendungsinformationen vorhanden.\nDies sollte bei Standard-AzerothCore-Befehlen nicht auftreten – bitte als Fehler melden.' WHERE `entry` = 196;
-- Account permissions
UPDATE `acore_string` SET `locale_deDE` = 'Falscher Parameter-ID: {}, existiert nicht.' WHERE `entry` = 63;
UPDATE `acore_string` SET `locale_deDE` = 'Falscher realmId-Parameter: {}' WHERE `entry` = 64;
UPDATE `acore_string` SET `locale_deDE` = 'Konto {} ({}) wurden Berechtigungen erteilt:' WHERE `entry` = 65;
UPDATE `acore_string` SET `locale_deDE` = 'Konto {} ({}) wurden Berechtigungen verweigert:' WHERE `entry` = 66;
UPDATE `acore_string` SET `locale_deDE` = 'Konto {} ({}) hat Berechtigungen durch Sicherheitsstufe {} geerbt:' WHERE `entry` = 67;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigungen:' WHERE `entry` = 68;
UPDATE `acore_string` SET `locale_deDE` = 'Verknüpfte Berechtigungen:' WHERE `entry` = 69;
UPDATE `acore_string` SET `locale_deDE` = 'Leere Liste' WHERE `entry` = 70;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} konnte nicht erteilt werden. Konto {} ({}) besitzt diese Berechtigung bereits.' WHERE `entry` = 72;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} konnte nicht erteilt werden. Konto {} ({}) hat diese Berechtigung in der Sperrliste.' WHERE `entry` = 73;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} wurde Konto {} ({}) erteilt.' WHERE `entry` = 74;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} konnte nicht gesperrt werden. Konto {} ({}) besitzt diese Berechtigung bereits.' WHERE `entry` = 75;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} konnte nicht gesperrt werden. Konto {} ({}) hat diese Berechtigung in der Sperrliste.' WHERE `entry` = 76;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} wurde Konto {} ({}) gesperrt.' WHERE `entry` = 77;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} wurde Konto {} ({}) entzogen.' WHERE `entry` = 78;
UPDATE `acore_string` SET `locale_deDE` = 'Berechtigung {} ({}) realmId {} konnte nicht entzogen werden. Konto {} ({}) besitzt diese Berechtigung nicht.' WHERE `entry` = 79;
UPDATE `acore_string` SET `locale_deDE` = 'Schlachtfeld-Siege in den letzten 7 Tagen\nAllianz: {}\nHorde: {}' WHERE `entry` = 80;
UPDATE `acore_string` SET `locale_deDE` = 'Das Speichern von Schlachtfeld-Punkteständen ist deaktiviert!' WHERE `entry` = 81;
-- Two-factor authentication
UPDATE `acore_string` SET `locale_deDE` = 'UNBEKANNTER_FEHLER' WHERE `entry` = 87;
UPDATE `acore_string` SET `locale_deDE` = 'Die Zwei-Faktor-Authentifizierungsbefehle sind nicht ordnungsgemäß eingerichtet.' WHERE `entry` = 88;
UPDATE `acore_string` SET `locale_deDE` = 'Die Zwei-Faktor-Authentifizierung ist für dieses Konto bereits aktiviert.' WHERE `entry` = 89;
UPDATE `acore_string` SET `locale_deDE` = 'Der angegebene Zwei-Faktor-Authentifizierungstoken ist ungültig.' WHERE `entry` = 90;
UPDATE `acore_string` SET `locale_deDE` = 'Um die Einrichtung abzuschließen, müsst Ihr das Gerät einrichten, das Ihr als zweiten Faktor verwenden werdet.\nEuer 2FA-Schlüssel: {}\nSobald Ihr Euer Gerät eingerichtet habt, bestätigt dies mit .account 2fa setup <token> und dem generierten Token.' WHERE `entry` = 91;
UPDATE `acore_string` SET `locale_deDE` = 'Die Zwei-Faktor-Authentifizierung wurde erfolgreich eingerichtet.' WHERE `entry` = 92;
UPDATE `acore_string` SET `locale_deDE` = 'Die Zwei-Faktor-Authentifizierung ist für dieses Konto nicht aktiviert.' WHERE `entry` = 93;
UPDATE `acore_string` SET `locale_deDE` = 'Um die Zwei-Faktor-Authentifizierung zu entfernen, gebt bitte einen aktuellen Token von Eurem Authentifizierungsgerät an.' WHERE `entry` = 94;
UPDATE `acore_string` SET `locale_deDE` = 'Die Zwei-Faktor-Authentifizierung wurde erfolgreich deaktiviert.' WHERE `entry` = 95;
UPDATE `acore_string` SET `locale_deDE` = 'Das angegebene Zwei-Faktor-Authentifizierungsgeheimnis ist zu lang.' WHERE `entry` = 188;
UPDATE `acore_string` SET `locale_deDE` = 'Das angegebene Zwei-Faktor-Authentifizierungsgeheimnis ist ungültig.' WHERE `entry` = 189;
UPDATE `acore_string` SET `locale_deDE` = 'Zwei-Faktor-Authentifizierung für ''{}'' mit dem angegebenen Geheimnis erfolgreich aktiviert.' WHERE `entry` = 190;
-- Guild and character name validation
UPDATE `acore_string` SET `locale_deDE` = 'Der Gildenname ''{}'' ist bereits vergeben.' WHERE `entry` = 96;
UPDATE `acore_string` SET `locale_deDE` = 'Gildenname ''{}'' wurde in ''{}'' geändert.' WHERE `entry` = 97;
UPDATE `acore_string` SET `locale_deDE` = '''{}'' existiert bereits als Charaktername, bitte einen anderen wählen.' WHERE `entry` = 98;
UPDATE `acore_string` SET `locale_deDE` = 'Spieler ''{}'' wurde zur Umbenennung in ''{}'' gezwungen.' WHERE `entry` = 99;
UPDATE `acore_string` SET `locale_deDE` = 'Dieser Name ist reserviert, bitte einen anderen wählen.' WHERE `entry` = 167;
UPDATE `acore_string` SET `locale_deDE` = 'Dieser Name ist anstößig, bitte einen anderen wählen.' WHERE `entry` = 187;
-- Gameobject
UPDATE `acore_string` SET `locale_deDE` = 'Ungültiger Spielobjekttyp, muss ein zerstörbares Gebäude sein.' WHERE `entry` = 176;
UPDATE `acore_string` SET `locale_deDE` = 'Spielobjekt {} (GUID: {}) hat {} Schaden genommen (aktuelle Gesundheit: {}).' WHERE `entry` = 177;
UPDATE `acore_string` SET `locale_deDE` = '| Kontoflags:' WHERE `entry` = 179;
UPDATE `acore_string` SET `locale_deDE` = 'Wiederherstellungs-ID: {} | Gegenstand: {} ({}) | Anzahl: {}' WHERE `entry` = 197;
UPDATE `acore_string` SET `locale_deDE` = 'Der Spieler hat keine wiederherstellbaren Gegenstände.' WHERE `entry` = 198;
UPDATE `acore_string` SET `locale_deDE` = 'Der Spieler hat keinen wiederherstellbaren Gegenstand mit ID {}.' WHERE `entry` = 199;
-- Spawn / go
UPDATE `acore_string` SET `locale_deDE` = 'Kann nicht zu Spawn {} wechseln, da nur {} vorhanden sind.' WHERE `entry` = 288;
-- Cheat commands
UPDATE `acore_string` SET `locale_deDE` = 'Cheat-Befehlsstatus:' WHERE `entry` = 357;
UPDATE `acore_string` SET `locale_deDE` = 'Gottmodus: {}.' WHERE `entry` = 358;
UPDATE `acore_string` SET `locale_deDE` = 'Zauberzeit: {}.' WHERE `entry` = 359;
UPDATE `acore_string` SET `locale_deDE` = 'Abklingzeit: {}.' WHERE `entry` = 360;
UPDATE `acore_string` SET `locale_deDE` = 'Energie: {}.' WHERE `entry` = 361;
UPDATE `acore_string` SET `locale_deDE` = 'Wasserlauf: {}.' WHERE `entry` = 362;
UPDATE `acore_string` SET `locale_deDE` = 'Spieler {} kann Euch nicht mehr zuflüstern.' WHERE `entry` = 363;
UPDATE `acore_string` SET `locale_deDE` = 'Taxiknoten: {}.' WHERE `entry` = 364;
UPDATE `acore_string` SET `locale_deDE` = '|cffffffff{}|r ausgerüstete Gegenstände für {} gelöscht.' WHERE `entry` = 365;
UPDATE `acore_string` SET `locale_deDE` = '|cffffffff{}|r Gegenstände in ausgerüsteten Taschen für {} gelöscht.' WHERE `entry` = 366;
UPDATE `acore_string` SET `locale_deDE` = '|cffffffff{}|r Gegenstände in der Bank für {} gelöscht.' WHERE `entry` = 367;
UPDATE `acore_string` SET `locale_deDE` = '|cffffffff{}|r Schlüssel im Schlüsselbund für {} gelöscht.' WHERE `entry` = 368;
UPDATE `acore_string` SET `locale_deDE` = '|cffffffff{}|r Währungen für {} gelöscht.' WHERE `entry` = 369;
UPDATE `acore_string` SET `locale_deDE` = '|cffffffff{}|r Gegenstände im Händler-Rückkauf für {} gelöscht.' WHERE `entry` = 370;
UPDATE `acore_string` SET `locale_deDE` = 'Alle Gegenstände für {} gelöscht:\n|cffffffff{}|r ausgerüstet\n|cffffffff{}|r in Taschen\n|cffffffff{}|r in der Bank\n|cffffffff{}|r im Schlüsselbund\n|cffffffff{}|r Währungstypen\n|cffffffff{}|r im Händler-Rückkauf' WHERE `entry` = 371;
UPDATE `acore_string` SET `locale_deDE` = 'Alle Gegenstände für {} gelöscht (inkl. Taschen):\n|cffffffff{}|r ausgerüstet\n|cffffffff{}|r in Taschen\n|cffffffff{}|r in der Bank\n|cffffffff{}|r im Schlüsselbund\n|cffffffff{}|r Währungstypen\n|cffffffff{}|r im Händler-Rückkauf\n|cffffffff{}|r normale Taschen\n|cffffffff{}|r Banktaschen' WHERE `entry` = 372;
UPDATE `acore_string` SET `locale_deDE` = 'Das Ziel besitzt die Aura {} nicht!' WHERE `entry` = 373;
UPDATE `acore_string` SET `locale_deDE` = 'Keine Stapelanzahl angegeben!' WHERE `entry` = 374;
UPDATE `acore_string` SET `locale_deDE` = 'Zauber {} kann keine Stapel haben!' WHERE `entry` = 375;
-- Quest management
UPDATE `acore_string` SET `locale_deDE` = 'Quest {} ({}) entfernt.' WHERE `entry` = 473;
UPDATE `acore_string` SET `locale_deDE` = 'Quest {} ({}) belohnt.' WHERE `entry` = 474;
UPDATE `acore_string` SET `locale_deDE` = 'Quest {} ({}) abgeschlossen.' WHERE `entry` = 475;
UPDATE `acore_string` SET `locale_deDE` = 'Quest {} ({}) ist bereits aktiv.' WHERE `entry` = 476;
-- Events / Do Action
UPDATE `acore_string` SET `locale_deDE` = 'Ereignis {} ({}) wurde gestartet.' WHERE `entry` = 600;
UPDATE `acore_string` SET `locale_deDE` = 'Ereignis {} ({}) wurde gestoppt.' WHERE `entry` = 601;
UPDATE `acore_string` SET `locale_deDE` = ' [belohnt]' WHERE `entry` = 602;
UPDATE `acore_string` SET `locale_deDE` = 'Aktion ausgeführt auf [GUID: {}, Eintrag: {}, Name: {}] Aktion: {}' WHERE `entry` = 603;
-- Battleground / Arena queue
UPDATE `acore_string` SET `locale_deDE` = 'Warteschlangenstatus für {} (Scharmützel {}) (Stufe: {} bis {})\nIn Warteschlange: {} (Mindestens {} weitere benötigt)' WHERE `entry` = 713;
UPDATE `acore_string` SET `locale_deDE` = '|cffff0000[Arena-Warteschlange]:|r {} (Scharmützel {}) -- [{}-{}] [{}/{}]|r' WHERE `entry` = 726;
-- NPC type indicators (GM info)
UPDATE `acore_string` SET `locale_deDE` = '* hat Klatsch ({})' WHERE `entry` = 820;
UPDATE `acore_string` SET `locale_deDE` = '* ist Questgeber ({})' WHERE `entry` = 821;
UPDATE `acore_string` SET `locale_deDE` = '* ist Klassentrainer ({})' WHERE `entry` = 822;
UPDATE `acore_string` SET `locale_deDE` = '* ist Berufslehrer ({})' WHERE `entry` = 823;
UPDATE `acore_string` SET `locale_deDE` = '* ist Munitionshändler ({})' WHERE `entry` = 824;
UPDATE `acore_string` SET `locale_deDE` = '* ist Lebensmittelhändler ({})' WHERE `entry` = 825;
UPDATE `acore_string` SET `locale_deDE` = '* ist Gifthändler ({})' WHERE `entry` = 826;
UPDATE `acore_string` SET `locale_deDE` = '* ist Reagenzienhändler ({})' WHERE `entry` = 827;
UPDATE `acore_string` SET `locale_deDE` = '* kann reparieren ({})' WHERE `entry` = 828;
UPDATE `acore_string` SET `locale_deDE` = '* ist Flugmeister ({})' WHERE `entry` = 829;
UPDATE `acore_string` SET `locale_deDE` = '* ist Geistheiler ({})' WHERE `entry` = 830;
UPDATE `acore_string` SET `locale_deDE` = '* ist Geistführer ({})' WHERE `entry` = 831;
UPDATE `acore_string` SET `locale_deDE` = '* ist Gastwirt ({})' WHERE `entry` = 832;
UPDATE `acore_string` SET `locale_deDE` = '* ist Banker ({})' WHERE `entry` = 833;
UPDATE `acore_string` SET `locale_deDE` = '* ist Petitionär ({})' WHERE `entry` = 834;
UPDATE `acore_string` SET `locale_deDE` = '* ist Wappenröckegestalter ({})' WHERE `entry` = 835;
UPDATE `acore_string` SET `locale_deDE` = '* ist Schlachtfeldmeister ({})' WHERE `entry` = 836;
UPDATE `acore_string` SET `locale_deDE` = '* ist Auktionator ({})' WHERE `entry` = 837;
UPDATE `acore_string` SET `locale_deDE` = '* ist Stallmeister ({})' WHERE `entry` = 838;
UPDATE `acore_string` SET `locale_deDE` = '* ist Gildenbanker ({})' WHERE `entry` = 839;
UPDATE `acore_string` SET `locale_deDE` = '* hat Zauberklick ({})' WHERE `entry` = 840;
UPDATE `acore_string` SET `locale_deDE` = '* ist Postkasten ({})' WHERE `entry` = 841;
UPDATE `acore_string` SET `locale_deDE` = '* ist Spielerfahrzeug ({})' WHERE `entry` = 842;
-- Arena team management
UPDATE `acore_string` SET `locale_deDE` = 'Arenateam [{}] nicht gefunden.' WHERE `entry` = 857;
UPDATE `acore_string` SET `locale_deDE` = 'Es gibt bereits ein Arenateam namens "{}".' WHERE `entry` = 858;
UPDATE `acore_string` SET `locale_deDE` = '{} ist bereits in einem Arenateam dieser Größe.' WHERE `entry` = 859;
UPDATE `acore_string` SET `locale_deDE` = 'Arenateam im Kampf.' WHERE `entry` = 860;
UPDATE `acore_string` SET `locale_deDE` = 'Arena mit dem Namen "{}" oder ähnlichem nicht gefunden.' WHERE `entry` = 861;
UPDATE `acore_string` SET `locale_deDE` = '[{}] ist kein Mitglied des Teams "{}".' WHERE `entry` = 862;
UPDATE `acore_string` SET `locale_deDE` = '[{}] ist bereits Kapitän des Teams "{}".' WHERE `entry` = 863;
UPDATE `acore_string` SET `locale_deDE` = 'Neues Arenateam erstellt [Name: "{}"][Id: {}][Typ: {}][Kapitän-GUID: {}].' WHERE `entry` = 864;
UPDATE `acore_string` SET `locale_deDE` = 'Arenateam "{}\"[Id: {}] aufgelöst.' WHERE `entry` = 865;
UPDATE `acore_string` SET `locale_deDE` = 'Arenateam [Id: {}] von "{}" in "{}" umbenannt.' WHERE `entry` = 866;
UPDATE `acore_string` SET `locale_deDE` = 'Arenateam "{}\"[Id: {}]: Kapitän von [{}] zu [{}] geändert.' WHERE `entry` = 867;
UPDATE `acore_string` SET `locale_deDE` = 'Arenateam: "{}\"[{}] - Bewertung: {} - Typ: {}x{}' WHERE `entry` = 868;
UPDATE `acore_string` SET `locale_deDE` = 'Name:"{}\"[guid:{}] - PR: {} - {}' WHERE `entry` = 869;
UPDATE `acore_string` SET `locale_deDE` = '|"{}\"[ID:{}]({}x{})|' WHERE `entry` = 870;
-- Email management (player-facing)
UPDATE `acore_string` SET `locale_deDE` = 'Die eingegebene E-Mail-Adresse stimmt nicht mit der Registrierungs-E-Mail überein, bitte Eingabe prüfen.' WHERE `entry` = 872;
UPDATE `acore_string` SET `locale_deDE` = 'Die neuen E-Mail-Adressen stimmen nicht überein.' WHERE `entry` = 873;
UPDATE `acore_string` SET `locale_deDE` = 'Die E-Mail-Adresse wurde geändert.' WHERE `entry` = 874;
UPDATE `acore_string` SET `locale_deDE` = 'Eure E-Mail-Adresse darf nicht länger als 255 Zeichen sein, E-Mail-Adresse nicht geändert!' WHERE `entry` = 875;
UPDATE `acore_string` SET `locale_deDE` = 'E-Mail-Adresse nicht geändert (unbekannter Fehler)!' WHERE `entry` = 876;
UPDATE `acore_string` SET `locale_deDE` = 'Änderung nicht nötig, neue E-Mail-Adresse ist identisch mit der alten.' WHERE `entry` = 877;
UPDATE `acore_string` SET `locale_deDE` = 'Eure E-Mail-Adresse ist: {}' WHERE `entry` = 878;
UPDATE `acore_string` SET `locale_deDE` = 'Sicherheitsstufe: {}' WHERE `entry` = 880;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr benötigt eine E-Mail-Adresse, um Euer Passwort zu ändern.' WHERE `entry` = 881;
-- Instance access requirements (player-facing)
UPDATE `acore_string` SET `locale_deDE` = 'Um einzutreten, müsst Ihr folgende Quest(s) abschließen:' WHERE `entry` = 882;
UPDATE `acore_string` SET `locale_deDE` = 'Um einzutreten, müsst Ihr folgende Erfolg(e) erzielen:' WHERE `entry` = 883;
UPDATE `acore_string` SET `locale_deDE` = 'Um einzutreten, müsst Ihr folgende(n) Gegenstand/Gegenstände in Eurem Inventar haben:' WHERE `entry` = 884;
UPDATE `acore_string` SET `locale_deDE` = '- Hinweis:' WHERE `entry` = 885;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr könnt nicht eintreten. Die Zugangsvoraussetzungen wurden nicht erfüllt.' WHERE `entry` = 886;
UPDATE `acore_string` SET `locale_deDE` = 'Um einzutreten, muss der durchschnittliche Gegenstandslevel Eurer Ausrüstung mindestens {} betragen. Euer aktueller durchschnittlicher Gegenstandslevel beträgt: {}.' WHERE `entry` = 887;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr müsst unter Stufe {} sein, um einzutreten.' WHERE `entry` = 888;
UPDATE `acore_string` SET `locale_deDE` = 'Um einzutreten, muss der Gruppenanführer ({}) folgende Quest(s) abgeschlossen haben:' WHERE `entry` = 889;
UPDATE `acore_string` SET `locale_deDE` = 'Um einzutreten, muss der Gruppenanführer ({}) folgende Erfolg(e) erzielt haben:' WHERE `entry` = 890;
UPDATE `acore_string` SET `locale_deDE` = 'Um einzutreten, muss der Gruppenanführer ({}) folgende(n) Gegenstand/Gegenstände in seinem/ihrem Inventar haben:' WHERE `entry` = 891;
-- Account creation
UPDATE `acore_string` SET `locale_deDE` = 'Ein Kontopasswort darf NICHT länger als 16 Zeichen sein (Client-Beschränkung). Konto NICHT erstellt.' WHERE `entry` = 1031;
-- Group management (GM)
UPDATE `acore_string` SET `locale_deDE` = '{} ist bereits in einer Gruppe!' WHERE `entry` = 1145;
UPDATE `acore_string` SET `locale_deDE` = '{} ist der Gruppe von {} beigetreten.' WHERE `entry` = 1146;
UPDATE `acore_string` SET `locale_deDE` = '{} ist in keiner Gruppe!' WHERE `entry` = 1147;
UPDATE `acore_string` SET `locale_deDE` = 'Die Gruppe ist voll!' WHERE `entry` = 1148;
UPDATE `acore_string` SET `locale_deDE` = 'Gruppentyp: {} mit {} Spielern.' WHERE `entry` = 1149;
UPDATE `acore_string` SET `locale_deDE` = 'Name: {} ({}),\n\n Zone: {}, Phase: {}, GUID: {}, Flags: {}, Rollen: {}' WHERE `entry` = 1150;
-- Config reload
UPDATE `acore_string` SET `locale_deDE` = 'Alle Konfigurationen wurden aus der/den Konfigurationsdatei(en) neu geladen.' WHERE `entry` = 1157;
-- Guild details (GM)
UPDATE `acore_string` SET `locale_deDE` = 'Zeige Gildendetails für {} (ID: {})' WHERE `entry` = 1177;
UPDATE `acore_string` SET `locale_deDE` = '| Gildenmeister: {} (GUID: {})' WHERE `entry` = 1178;
UPDATE `acore_string` SET `locale_deDE` = '| Erstellungsdatum der Gilde: {}' WHERE `entry` = 1179;
UPDATE `acore_string` SET `locale_deDE` = '| Gildenmitglieder: {}' WHERE `entry` = 1180;
UPDATE `acore_string` SET `locale_deDE` = '| Gildenbank: {} Gold' WHERE `entry` = 1181;
UPDATE `acore_string` SET `locale_deDE` = '| Gilden-MOTD: {}' WHERE `entry` = 1182;
UPDATE `acore_string` SET `locale_deDE` = '| Gildeninformationen: {}' WHERE `entry` = 1183;
UPDATE `acore_string` SET `locale_deDE` = '| Gildenränge:' WHERE `entry` = 1184;
-- Tickets (player-facing)
UPDATE `acore_string` SET `locale_deDE` = 'Euer Ticket wurde geschlossen.' WHERE `entry` = 1334;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr habt eine Ticketantwort erhalten.' WHERE `entry` = 1335;
-- Error messages
UPDATE `acore_string` SET `locale_deDE` = 'Entweder:' WHERE `entry` = 1500;
UPDATE `acore_string` SET `locale_deDE` = 'Oder: ' WHERE `entry` = 1501;
UPDATE `acore_string` SET `locale_deDE` = 'Wert ''{}'' ist für den Typ {} nicht gültig.' WHERE `entry` = 1502;
UPDATE `acore_string` SET `locale_deDE` = 'Ungültige UTF-8-Sequenzen in der Zeichenkette gefunden.' WHERE `entry` = 1503;
UPDATE `acore_string` SET `locale_deDE` = 'Der angegebene Link enthält ungültige Linkdaten.' WHERE `entry` = 1504;
UPDATE `acore_string` SET `locale_deDE` = 'Konto ''{}'' existiert nicht.' WHERE `entry` = 1505;
UPDATE `acore_string` SET `locale_deDE` = 'Konto-ID {} existiert nicht.' WHERE `entry` = 1506;
UPDATE `acore_string` SET `locale_deDE` = '{} existiert nicht.' WHERE `entry` = 1507;
UPDATE `acore_string` SET `locale_deDE` = 'Charakter ''{}'' existiert nicht.' WHERE `entry` = 1508;
UPDATE `acore_string` SET `locale_deDE` = '''{}'' ist kein gültiger Charaktername.' WHERE `entry` = 1509;
UPDATE `acore_string` SET `locale_deDE` = 'Erfolgs-ID {} existiert nicht.' WHERE `entry` = 1510;
UPDATE `acore_string` SET `locale_deDE` = 'Teleportort {} existiert nicht.' WHERE `entry` = 1511;
UPDATE `acore_string` SET `locale_deDE` = 'Teleportort ''{}'' existiert nicht.' WHERE `entry` = 1512;
UPDATE `acore_string` SET `locale_deDE` = 'Gegenstand-ID {} existiert nicht.' WHERE `entry` = 1513;
UPDATE `acore_string` SET `locale_deDE` = 'Zauber-ID {} existiert nicht.' WHERE `entry` = 1514;
UPDATE `acore_string` SET `locale_deDE` = 'Erwartet ''{}'', aber ''{}'' erhalten.' WHERE `entry` = 1515;
UPDATE `acore_string` SET `locale_deDE` = 'Quest-ID {} existiert nicht.' WHERE `entry` = 1516;
-- Ticket response
UPDATE `acore_string` SET `locale_deDE` = '|cff00ff00Ticketantwort|r: [{}]|r' WHERE `entry` = 2029;
UPDATE `acore_string` SET `locale_deDE` = '|cff00ff00Bearbeitet von|r:|cff00ccff {}|r' WHERE `entry` = 2030;
UPDATE `acore_string` SET `locale_deDE` = '|cff00ff00Antwort hinzugefügt|r:|cff00ccff [{}]|r' WHERE `entry` = 2031;
UPDATE `acore_string` SET `locale_deDE` = '|cff00ff00Antwort gelöscht von|r:|cff00ccff {}|r' WHERE `entry` = 2032;
-- GM diagnostic / debug strings
UPDATE `acore_string` SET `locale_deDE` = 'KIName: {} Skriptname: {}' WHERE `entry` = 5031;
UPDATE `acore_string` SET `locale_deDE` = 'Kein Schlachtfeld gefunden!' WHERE `entry` = 5032;
UPDATE `acore_string` SET `locale_deDE` = 'Keine Erfolgskriterien gefunden!' WHERE `entry` = 5033;
UPDATE `acore_string` SET `locale_deDE` = 'Kein offenes PvP gefunden!' WHERE `entry` = 5034;
UPDATE `acore_string` SET `locale_deDE` = 'Konsole' WHERE `entry` = 5039;
UPDATE `acore_string` SET `locale_deDE` = 'Charakter' WHERE `entry` = 5040;
UPDATE `acore_string` SET `locale_deDE` = 'Dauerhaft' WHERE `entry` = 5041;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr seid im Freien.' WHERE `entry` = 5042;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr seid in einem Innenbereich.' WHERE `entry` = 5043;
UPDATE `acore_string` SET `locale_deDE` = 'Keine VMAP-Daten für Gebietsinformationen verfügbar.' WHERE `entry` = 5044;
UPDATE `acore_string` SET `locale_deDE` = 'Karte: {} | ID: {} | perm: {} | erweitert: {} | diff: {} | canReset: {} | TTR: {}' WHERE `entry` = 5045;
UPDATE `acore_string` SET `locale_deDE` = 'Spielerbindungen: {}' WHERE `entry` = 5046;
UPDATE `acore_string` SET `locale_deDE` = 'Gruppenbindungen: {}' WHERE `entry` = 5047;
UPDATE `acore_string` SET `locale_deDE` = 'Kartenbindung aufgehoben: {} Instanz: {} perm: {} diff: {} canReset: {} TTR: {}' WHERE `entry` = 5048;
UPDATE `acore_string` SET `locale_deDE` = 'Aufgehobene Instanzen: {}' WHERE `entry` = 5049;
UPDATE `acore_string` SET `locale_deDE` = 'Geladene Instanzen: {}' WHERE `entry` = 5050;
UPDATE `acore_string` SET `locale_deDE` = 'Spieler in Instanzen: {}' WHERE `entry` = 5051;
UPDATE `acore_string` SET `locale_deDE` = 'Instanzspeicherungen: {}' WHERE `entry` = 5052;
UPDATE `acore_string` SET `locale_deDE` = 'Gebundene Spieler: {}' WHERE `entry` = 5053;
UPDATE `acore_string` SET `locale_deDE` = 'Gebundene Gruppen: {}' WHERE `entry` = 5054;
UPDATE `acore_string` SET `locale_deDE` = 'Die Karte ist kein Dungeon.' WHERE `entry` = 5055;
UPDATE `acore_string` SET `locale_deDE` = 'Die Karte hat keine Instanzdaten.' WHERE `entry` = 5056;
UPDATE `acore_string` SET `locale_deDE` = 'Boss-ID {} Status wurde auf {} ({}) gesetzt.' WHERE `entry` = 5057;
UPDATE `acore_string` SET `locale_deDE` = 'Boss-ID {} ({}) Status ist {} ({}).' WHERE `entry` = 5058;
UPDATE `acore_string` SET `locale_deDE` = 'Stummschaltungen für Konto: {}' WHERE `entry` = 5059;
UPDATE `acore_string` SET `locale_deDE` = 'Keine Stummschaltungen für Konto: {}' WHERE `entry` = 5060;
UPDATE `acore_string` SET `locale_deDE` = 'Stummschaltungsdatum: {} Dauer: {} Min. Grund: {} Gesetzt von: {}' WHERE `entry` = 5061;
UPDATE `acore_string` SET `locale_deDE` = 'Gecachte Daten für Charakter {} ({}) wurden geleert.' WHERE `entry` = 5064;
UPDATE `acore_string` SET `locale_deDE` = 'Gecachte Daten für Charakter {} ({}) wurden aktualisiert.' WHERE `entry` = 5065;
UPDATE `acore_string` SET `locale_deDE` = 'Cache für Charakter {} nicht gefunden.' WHERE `entry` = 5066;
UPDATE `acore_string` SET `locale_deDE` = 'Quest {} ({}) hinzugefügt.' WHERE `entry` = 5067;
UPDATE `acore_string` SET `locale_deDE` = 'Quest {} ({}) nicht im Questprotokoll gefunden.' WHERE `entry` = 5068;
UPDATE `acore_string` SET `locale_deDE` = 'Die Quest muss aktiv und abgeschlossen sein, bevor sie belohnt werden kann.' WHERE `entry` = 5069;
UPDATE `acore_string` SET `locale_deDE` = 'Der Befehl ist durch die Konfiguration deaktiviert.' WHERE `entry` = 5070;
UPDATE `acore_string` SET `locale_deDE` = 'Der angegebene Erweiterungskosten-Eintrag existiert nicht.' WHERE `entry` = 5071;
-- Honor / arena refund (player-facing)
UPDATE `acore_string` SET `locale_deDE` = 'Die Rückerstattung von {} ({}) würde das Ehrenpunkte-Limit überschreiten (Limit: {}, aktuelle Ehrenpunkte: {}, zu erstattende Ehrenpunkte: {}).' WHERE `entry` = 5072;
UPDATE `acore_string` SET `locale_deDE` = 'Die Rückerstattung von Gegenstand {} ist fehlgeschlagen, da dadurch das Ehrenpunkte-Limit überschritten würde.' WHERE `entry` = 5073;
UPDATE `acore_string` SET `locale_deDE` = 'Gegenstand {} ({}) wurde zurückerstattet und {} Ehrenpunkte wiederhergestellt.' WHERE `entry` = 5074;
UPDATE `acore_string` SET `locale_deDE` = 'Die Rückerstattung von {} ({}) würde das Arenapunkte-Limit überschreiten (Limit: {}, aktuelle Arenapunkte: {}, zu erstattende Arenapunkte: {}).' WHERE `entry` = 5075;
UPDATE `acore_string` SET `locale_deDE` = 'Die Rückerstattung von Gegenstand {} ist fehlgeschlagen, da dadurch das Arenapunkte-Limit überschritten würde.' WHERE `entry` = 5076;
UPDATE `acore_string` SET `locale_deDE` = 'Gegenstand {} ({}) wurde zurückerstattet und {} Arenapunkte wiederhergestellt.' WHERE `entry` = 5077;
UPDATE `acore_string` SET `locale_deDE` = 'Gegenstand nicht im Inventar des Charakters gefunden (einschließlich Bank).' WHERE `entry` = 5078;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr müsst mindestens Stufe {} sein, um automatische Rundfunknachrichten zu deaktivieren.' WHERE `entry` = 5079;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr erhaltet jetzt globale {}-Nachrichten.' WHERE `entry` = 5080;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr erhaltet keine globalen {}-Nachrichten mehr.' WHERE `entry` = 5081;
UPDATE `acore_string` SET `locale_deDE` = 'Charakter {} ({}) von Konto {} ({}) zu Konto {} ({}) verschoben.' WHERE `entry` = 5083;
UPDATE `acore_string` SET `locale_deDE` = 'Zauberausführung fehlgeschlagen! SpellCastResult: {} ({}).' WHERE `entry` = 5084;
UPDATE `acore_string` SET `locale_deDE` = 'Objekt {} (Eintrag: {} GUID: {}) neu erschaffen!' WHERE `entry` = 5085;
UPDATE `acore_string` SET `locale_deDE` = 'Keine Türen in Reichweite ({} Yards) gefunden.' WHERE `entry` = 5086;
UPDATE `acore_string` SET `locale_deDE` = 'Tür {} (Eintrag: {}) geöffnet!' WHERE `entry` = 5087;
UPDATE `acore_string` SET `locale_deDE` = 'Quest: {} ({})\nStatus: {}' WHERE `entry` = 5088;
UPDATE `acore_string` SET `locale_deDE` = 'Quest {} kann nicht angenommen werden. Gründe:' WHERE `entry` = 5089;
UPDATE `acore_string` SET `locale_deDE` = ' - Quest ist deaktiviert.' WHERE `entry` = 5090;
UPDATE `acore_string` SET `locale_deDE` = ' - Quest wurde bereits angenommen oder abgeschlossen.' WHERE `entry` = 5091;
UPDATE `acore_string` SET `locale_deDE` = ' - Klassenanforderung nicht erfüllt.' WHERE `entry` = 5092;
UPDATE `acore_string` SET `locale_deDE` = ' - Rassenanforderung nicht erfüllt.' WHERE `entry` = 5093;
UPDATE `acore_string` SET `locale_deDE` = ' - Spielerstufe zu niedrig (erforderlich: {}).' WHERE `entry` = 5094;
UPDATE `acore_string` SET `locale_deDE` = ' - Spielerstufe zu hoch (Maximum: {}).' WHERE `entry` = 5095;
UPDATE `acore_string` SET `locale_deDE` = ' - Fertigkeitsanforderung nicht erfüllt.' WHERE `entry` = 5096;
UPDATE `acore_string` SET `locale_deDE` = ' - Rufanforderung nicht erfüllt.' WHERE `entry` = 5097;
UPDATE `acore_string` SET `locale_deDE` = ' - Vorherige Quest in der Kette nicht abgeschlossen.' WHERE `entry` = 5098;
UPDATE `acore_string` SET `locale_deDE` = ' - Bereits eine zeitbegrenzte Quest aktiv.' WHERE `entry` = 5099;
UPDATE `acore_string` SET `locale_deDE` = ' - Konflikt mit exklusiver Gruppenquest.' WHERE `entry` = 5100;
UPDATE `acore_string` SET `locale_deDE` = ' - Nächste Quest in der Kette bereits begonnen.' WHERE `entry` = 5101;
UPDATE `acore_string` SET `locale_deDE` = ' - Vorherige Quest in der Kette noch aktiv.' WHERE `entry` = 5102;
UPDATE `acore_string` SET `locale_deDE` = ' - Brotkrumen-Quest-Konflikt.' WHERE `entry` = 5103;
UPDATE `acore_string` SET `locale_deDE` = ' - Tagesquest heute nicht verfügbar.' WHERE `entry` = 5104;
UPDATE `acore_string` SET `locale_deDE` = ' - Wochenquest diese Woche bereits abgeschlossen.' WHERE `entry` = 5105;
UPDATE `acore_string` SET `locale_deDE` = ' - Monatsquest diesen Monat bereits abgeschlossen.' WHERE `entry` = 5106;
UPDATE `acore_string` SET `locale_deDE` = ' - Saisonquest diese Saison bereits abgeschlossen.' WHERE `entry` = 5107;
UPDATE `acore_string` SET `locale_deDE` = ' - Bedingungsanforderungen nicht erfüllt:' WHERE `entry` = 5108;
UPDATE `acore_string` SET `locale_deDE` = ' - Questprotokoll ist voll.' WHERE `entry` = 5109;
UPDATE `acore_string` SET `locale_deDE` = ' - Bedingung nicht erfüllt: Typ {} Wert1: {} Wert2: {} Wert3: {}' WHERE `entry` = 5110;
-- GM Spectator
UPDATE `acore_string` SET `locale_deDE` = 'GM-Zuschauer ist AN' WHERE `entry` = 6617;
UPDATE `acore_string` SET `locale_deDE` = 'GM-Zuschauer ist AUS' WHERE `entry` = 6618;
-- LFG states
UPDATE `acore_string` SET `locale_deDE` = 'Spielername: {}, Status: {}, Dungeons: {} ({}),\n\n Rollen: {}, Kommentar: {}' WHERE `entry` = 9980;
UPDATE `acore_string` SET `locale_deDE` = 'LFG-Gruppe?: {}, Status: {}, Dungeon: {}' WHERE `entry` = 9981;
UPDATE `acore_string` SET `locale_deDE` = 'Nicht in einer Gruppe' WHERE `entry` = 9982;
UPDATE `acore_string` SET `locale_deDE` = 'Warteschlangen geleert' WHERE `entry` = 9983;
UPDATE `acore_string` SET `locale_deDE` = 'LFG-Optionen: {}' WHERE `entry` = 9984;
UPDATE `acore_string` SET `locale_deDE` = 'LFG-Optionen geändert' WHERE `entry` = 9985;
UPDATE `acore_string` SET `locale_deDE` = 'Keine' WHERE `entry` = 9986;
UPDATE `acore_string` SET `locale_deDE` = 'Rollenprüfung' WHERE `entry` = 9987;
UPDATE `acore_string` SET `locale_deDE` = 'In Warteschlange' WHERE `entry` = 9988;
UPDATE `acore_string` SET `locale_deDE` = 'Vorschlag' WHERE `entry` = 9989;
UPDATE `acore_string` SET `locale_deDE` = 'Abstimmung: Rauswurf' WHERE `entry` = 9990;
UPDATE `acore_string` SET `locale_deDE` = 'Im Dungeon' WHERE `entry` = 9991;
UPDATE `acore_string` SET `locale_deDE` = 'Dungeon beendet' WHERE `entry` = 9992;
UPDATE `acore_string` SET `locale_deDE` = 'Raid-Browser' WHERE `entry` = 9993;
UPDATE `acore_string` SET `locale_deDE` = 'Tank' WHERE `entry` = 9994;
UPDATE `acore_string` SET `locale_deDE` = 'Heiler' WHERE `entry` = 9995;
UPDATE `acore_string` SET `locale_deDE` = 'DPS' WHERE `entry` = 9996;
UPDATE `acore_string` SET `locale_deDE` = 'Gruppenanführer' WHERE `entry` = 9997;
UPDATE `acore_string` SET `locale_deDE` = 'Keine' WHERE `entry` = 9998;
UPDATE `acore_string` SET `locale_deDE` = 'Fehler' WHERE `entry` = 9999;
-- Halaa
UPDATE `acore_string` SET `locale_deDE` = 'Halaa ist schutzlos!' WHERE `entry` = 10074;
-- Server action announcements
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat {} rausgeworfen, Grund: {}' WHERE `entry` = 11002;
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat {} für {} stummgeschaltet, Grund: {}' WHERE `entry` = 11003;
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat Charakter {} für {} gesperrt, Grund: {}' WHERE `entry` = 11004;
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat Charakter {} dauerhaft gesperrt, Grund: {}' WHERE `entry` = 11005;
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat Konto {} für {} gesperrt, Grund: {}' WHERE `entry` = 11006;
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat Konto {} dauerhaft gesperrt, Grund: {}' WHERE `entry` = 11007;
UPDATE `acore_string` SET `locale_deDE` = 'Bewegungstyp: {}' WHERE `entry` = 11008;
UPDATE `acore_string` SET `locale_deDE` = 'Zusätzliche Flags: {}' WHERE `entry` = 11009;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr seid bereits an {} gebunden.' WHERE `entry` = 11014;
UPDATE `acore_string` SET `locale_deDE` = 'Dieser Kreatur ist keine aktive CreatureAI zugewiesen.' WHERE `entry` = 11015;
UPDATE `acore_string` SET `locale_deDE` = 'Bitte einen Spieler oder sein Haustier auswählen.' WHERE `entry` = 11016;
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat IP {} für {} gesperrt, Grund: {}' WHERE `entry` = 11017;
UPDATE `acore_string` SET `locale_deDE` = 'Server: {} hat IP {} dauerhaft gesperrt, Grund: {}' WHERE `entry` = 11018;
-- Module: Transmog / XP
UPDATE `acore_string` SET `locale_deDE` = 'Der Transmog-NPC zeigt nun verfügbare Erscheinungsbilder als Händlerinterface an (mit Vorschau).\nHINWEIS: Bei zu vielen Erscheinungsbildern werden einige aufgrund einer Client-Beschränkung nicht angezeigt. Deaktiviert in diesem Fall diese Option.' WHERE `entry` = 11117;
UPDATE `acore_string` SET `locale_deDE` = 'Der Transmog-NPC zeigt nun verfügbare Erscheinungsbilder als Klatschliste an.' WHERE `entry` = 11118;
UPDATE `acore_string` SET `locale_deDE` = 'Eure Erfahrungsrate wurde auf {} gesetzt.' WHERE `entry` = 11120;
UPDATE `acore_string` SET `locale_deDE` = 'Falscher Wert angegeben. Bitte einen Wert zwischen 0 und {} angeben.' WHERE `entry` = 11121;
UPDATE `acore_string` SET `locale_deDE` = 'Die auf Euch angewendete Rate beträgt {}.\nAktuelle Wochenend-XP-Konfiguration:\nAnnounce {}\nAlwaysEnabled {}\nQuestOnly {}\nMaxLevel {}\nxpAmount {}\nIndividualXPEnabled {}\nEnabled {}\nMaxAllowedRate {}' WHERE `entry` = 11122;
-- Wintergrasp
UPDATE `acore_string` SET `locale_deDE` = '{} wurde von {} gefangen.' WHERE `entry` = 12050;
UPDATE `acore_string` SET `locale_deDE` = '{} wird von {} angegriffen.' WHERE `entry` = 12051;
UPDATE `acore_string` SET `locale_deDE` = 'Belagerungswerkstatt des Zerbrochenen Tempels' WHERE `entry` = 12052;
UPDATE `acore_string` SET `locale_deDE` = 'Ostspark-Belagerungswerkstatt' WHERE `entry` = 12053;
UPDATE `acore_string` SET `locale_deDE` = 'Westspark-Belagerungswerkstatt' WHERE `entry` = 12054;
UPDATE `acore_string` SET `locale_deDE` = 'Belagerungswerkstatt des Gesunkenen Rings' WHERE `entry` = 12055;
UPDATE `acore_string` SET `locale_deDE` = 'Allianz' WHERE `entry` = 12057;
UPDATE `acore_string` SET `locale_deDE` = 'Die Schlacht um Wintersturm beginnt gleich!' WHERE `entry` = 12058;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr habt Rang 1 erreicht: Gefreiter' WHERE `entry` = 12059;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr habt Rang 2 erreicht: Leutnant' WHERE `entry` = 12060;
UPDATE `acore_string` SET `locale_deDE` = 'Der südöstliche Festungsturm' WHERE `entry` = 12061;
UPDATE `acore_string` SET `locale_deDE` = 'Der nordöstliche Festungsturm' WHERE `entry` = 12062;
UPDATE `acore_string` SET `locale_deDE` = 'Der südwestliche Festungsturm' WHERE `entry` = 12063;
UPDATE `acore_string` SET `locale_deDE` = 'Der nordwestliche Festungsturm' WHERE `entry` = 12064;
UPDATE `acore_string` SET `locale_deDE` = '{} wurde beschädigt!' WHERE `entry` = 12065;
UPDATE `acore_string` SET `locale_deDE` = '{} wurde zerstört!' WHERE `entry` = 12066;
UPDATE `acore_string` SET `locale_deDE` = 'Die Schlacht um Wintersturm beginnt!' WHERE `entry` = 12067;
UPDATE `acore_string` SET `locale_deDE` = '{} hat die Wintersturm-Festung erfolgreich verteidigt!' WHERE `entry` = 12068;
UPDATE `acore_string` SET `locale_deDE` = 'Der südliche Turm' WHERE `entry` = 12069;
UPDATE `acore_string` SET `locale_deDE` = 'Der östliche Turm' WHERE `entry` = 12070;
UPDATE `acore_string` SET `locale_deDE` = 'Der westliche Turm' WHERE `entry` = 12071;
UPDATE `acore_string` SET `locale_deDE` = 'Die Wintersturm-Festung wurde von {} erobert!' WHERE `entry` = 12072;
-- Wintergrasp NPC gossip (player-facing)
UPDATE `acore_string` SET `locale_deDE` = 'Bring mich zum Festungsfriedhof.' WHERE `entry` = 20070;
UPDATE `acore_string` SET `locale_deDE` = 'Bring mich zum Friedhof des Gesunkenen Rings.' WHERE `entry` = 20071;
UPDATE `acore_string` SET `locale_deDE` = 'Bring mich zum Friedhof des Zerbrochenen Tempels.' WHERE `entry` = 20072;
UPDATE `acore_string` SET `locale_deDE` = 'Bring mich zum Westspark-Friedhof.' WHERE `entry` = 20073;
UPDATE `acore_string` SET `locale_deDE` = 'Bring mich zum Ostspark-Friedhof.' WHERE `entry` = 20074;
UPDATE `acore_string` SET `locale_deDE` = 'Bring mich zurück zum Horden-Landungscamp.' WHERE `entry` = 20075;
UPDATE `acore_string` SET `locale_deDE` = 'Bring mich zurück zum Allianz-Landungscamp.' WHERE `entry` = 20076;
UPDATE `acore_string` SET `locale_deDE` = 'Für Wintersturm anmelden.' WHERE `entry` = 20077;
UPDATE `acore_string` SET `locale_deDE` = '|cffff0000[Wintersturm]:|r Kampf hat begonnen!|r' WHERE `entry` = 20078;
-- Quest tracking
UPDATE `acore_string` SET `locale_deDE` = 'Diese Spuren müssen Shango gehören.' WHERE `entry` = 28634;
UPDATE `acore_string` SET `locale_deDE` = 'Das sind nicht Shangos Spuren.' WHERE `entry` = 28635;
-- Miscellaneous player-facing
UPDATE `acore_string` SET `locale_deDE` = 'Sprechen ist erst nach mindestens {} Spielzeit erlaubt. Ihr könnt die Gruppen- und Gildenchats verwenden.' WHERE `entry` = 30000;
UPDATE `acore_string` SET `locale_deDE` = 'Sofortflug umschalten' WHERE `entry` = 30077;
UPDATE `acore_string` SET `locale_deDE` = 'Sofortflug AN' WHERE `entry` = 30078;
UPDATE `acore_string` SET `locale_deDE` = 'Sofortflug AUS' WHERE `entry` = 30079;
UPDATE `acore_string` SET `locale_deDE` = 'Die Datei ''opcode.txt'' fehlt im Server-Arbeitsverzeichnis.' WHERE `entry` = 30080;
UPDATE `acore_string` SET `locale_deDE` = '{} hat keinen Gegenstand mit itemID = {}, kann daher nicht entfernt werden.' WHERE `entry` = 30081;
UPDATE `acore_string` SET `locale_deDE` = '{} hat nicht so viele Gegenstände mit itemID = {}, daher wurden keine entfernt.' WHERE `entry` = 30082;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr könnt keine Quests teilen, während Ihr auf einem Schlachtfeld seid.' WHERE `entry` = 30083;
UPDATE `acore_string` SET `locale_deDE` = 'Ihr könnt keine Bereitschaftsprüfung starten, während Ihr auf einem Schlachtfeld seid.' WHERE `entry` = 30084;
UPDATE `acore_string` SET `locale_deDE` = 'Das Schlachtfeld-Debugging ist in der Konfiguration bereits aktiviert und kann nicht per Befehl ein-/ausgeschaltet werden.' WHERE `entry` = 30085;
UPDATE `acore_string` SET `locale_deDE` = 'Das Arena-Debugging ist in der Konfiguration bereits aktiviert und kann nicht per Befehl ein-/ausgeschaltet werden.' WHERE `entry` = 30086;
UPDATE `acore_string` SET `locale_deDE` = 'LFG ist für das Debugging auf 1-Spieler-Warteschlange gesetzt.' WHERE `entry` = 30096;
UPDATE `acore_string` SET `locale_deDE` = 'LFG ist auf normale Warteschlange gesetzt.' WHERE `entry` = 30097;
UPDATE `acore_string` SET `locale_deDE` = 'Das LFG-Debugging ist in der Konfiguration bereits aktiviert und kann nicht per Befehl ein-/ausgeschaltet werden.' WHERE `entry` = 30098;
-- Player info display (GM)
UPDATE `acore_string` SET `locale_deDE` = '¦ Spieler {} {} (GUID: {})' WHERE `entry` = 35400;
UPDATE `acore_string` SET `locale_deDE` = '¦ GM-Modus aktiv, Phase: -1' WHERE `entry` = 35401;
UPDATE `acore_string` SET `locale_deDE` = '├─ Gesperrt: (Typ: {}, Grund: {}, Zeit: {}, Von: {})' WHERE `entry` = 35402;
UPDATE `acore_string` SET `locale_deDE` = '├─ Stummgeschaltet: (Grund: {}, Zeit: {}, Von: {})' WHERE `entry` = 35403;
UPDATE `acore_string` SET `locale_deDE` = '¦ Konto: {} (ID: {}),\n\n GM-Stufe: {}' WHERE `entry` = 35404;
UPDATE `acore_string` SET `locale_deDE` = '¦ Letzter Login: {} (Fehlgeschlagene Logins: {})' WHERE `entry` = 35405;
UPDATE `acore_string` SET `locale_deDE` = '¦ Registrierungs-E-Mail: {} - E-Mail: {}' WHERE `entry` = 35406;
UPDATE `acore_string` SET `locale_deDE` = 'Kein Grund angegeben.' WHERE `entry` = 35407;
UPDATE `acore_string` SET `locale_deDE` = '<nicht autorisiert>' WHERE `entry` = 35408;
UPDATE `acore_string` SET `locale_deDE` = '¦ Karte: {}, Zone: {}, Bereich: {}' WHERE `entry` = 35409;
@@ -0,0 +1,26 @@
-- DB update 2026_03_09_02 -> 2026_03_10_00
-- Update gameobject 'Deadmines Doors and Levers' with sniffed values
-- updated spawns
DELETE FROM `gameobject` WHERE (`id` IN (16399, 17153, 17154, 16400, 101831, 101834, 101832, 101833, 13965, 16397)) AND (`guid` IN (26182, 26183, 26184, 26185, 26188, 26192, 26197, 26206, 30533, 30534));
INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES
(26182, 16399, 36, 0, 0, 1, 1, -168.513961791992187, -579.86077880859375, 19.31592750549316406, 3.124123096466064453, 0, 0, 0.99996185302734375, 0.008734640665352344, 7200, 255, 1, "", 48632, NULL),
(26183, 17153, 36, 0, 0, 1, 1, -262.7137451171875, -482.361083984375, 49.43531036376953125, 6.265733242034912109, 0, 0, -0.00872611999511718, 0.999961912631988525, 7200, 255, 1, "", 48632, NULL),
(26184, 17154, 36, 0, 0, 1, 1, -242.9652099609375, -578.56103515625, 51.13660430908203125, 3.124123096466064453, 0, 0, 0.99996185302734375, 0.008734640665352344, 7200, 255, 1, "", 48632, NULL),
(26185, 16400, 36, 0, 0, 1, 1, -290.29412841796875, -536.96026611328125, 49.43531036376953125, 1.553341388702392578, 0, 0, 0.700908660888671875, 0.713251054286956787, 7200, 255, 1, "", 48632, NULL),
(26188, 101831, 36, 0, 0, 1, 1, -188.1365966796875, -460.31341552734375, 54.5590667724609375, 1.727874636650085449, 0, 0, 0.760405540466308593, 0.649448513984680175, 7200, 255, 1, "", 48632, NULL),
(26192, 101834, 36, 0, 0, 1, 1, -165.404327392578125, -576.9241943359375, 19.30643844604492187, 3.298687219619750976, 0, 0, -0.99691677093505859, 0.078466430306434631, 7200, 255, 1, "", 48632, NULL),
(26197, 101832, 36, 0, 0, 1, 1, -287.28204345703125, -539.8768310546875, 49.43212127685546875, 1.727874636650085449, 0, 0, 0.760405540466308593, 0.649448513984680175, 7200, 255, 1, "", 48632, NULL),
(26206, 101833, 36, 0, 0, 1, 1, -96.9277496337890625, -670.5966796875, 7.40338134765625, 1.902408957481384277, 0, 0, 0.814115524291992187, 0.580702960491180419, 7200, 255, 1, "", 48632, NULL),
(30533, 13965, 36, 0, 0, 1, 1, -191.41455078125, -457.44580078125, 54.43914413452148437, 1.692966461181640625, 0, 0, 0.74895477294921875, 0.662621140480041503, 7200, 255, 1, "", 48632, NULL),
(30534, 16397, 36, 0, 0, 1, 1, -100.501541137695312, -668.7706298828125, 7.410491943359375, 1.815141916275024414, 0, 0, 0.788010597229003906, 0.615661680698394775, 7200, 255, 1, "", 48632, NULL);
-- update SAI
-- Levers
UPDATE `smart_scripts` SET `target_param2` = 16399 WHERE (`source_type` = 1 AND `entryorguid` = 101834 AND `event_type` = 70 AND `target_param1` = 26182);
UPDATE `smart_scripts` SET `target_param2` = 16400 WHERE (`source_type` = 1 AND `entryorguid` = 101832 AND `event_type` = 70 AND `target_param1` = 26185);
-- Sneed
UPDATE `smart_scripts` SET `target_param2` = 16400 WHERE (`source_type` = 0 AND `entryorguid` = 643 AND `event_type` = 6 AND `target_param1` = 26185);
-- Gilnid
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 1763 AND `id` = 2);
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`, `event_param6`, `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
(1763, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 14, 26182, 16399, 0, 0, 0, 0, 0, 0, 'Gilnid - On Just Died - Activate Gameobject');
@@ -0,0 +1,80 @@
-- DB update 2026_03_10_00 -> 2026_03_10_01
-- Match chances to pre-normalization values (2% -> 3%)
UPDATE `reference_loot_template` SET `Chance` = 3 WHERE `Entry` = 1200068 AND `Reference` = 1226870;
UPDATE `reference_loot_template` SET `Chance` = 1.5 WHERE `Entry` = 1200069 AND `Reference` = 1226870;
UPDATE `reference_loot_template` SET `Chance` = 1.5 WHERE `Entry` = 1200069 AND `Reference` = 1226971;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200070 AND `Reference` = 1226870;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200070 AND `Reference` = 1226971;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200070 AND `Reference` = 1227072;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200071 AND `Reference` = 1226971;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200071 AND `Reference` = 1227072;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200071 AND `Reference` = 1227173;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200072 AND `Reference` = 1227072;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200072 AND `Reference` = 1227173;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200072 AND `Reference` = 1227274;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200073 AND `Reference` = 1227173;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200073 AND `Reference` = 1227274;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200073 AND `Reference` = 1227375;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200074 AND `Reference` = 1227274;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200074 AND `Reference` = 1227375;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200074 AND `Reference` = 1227476;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200075 AND `Reference` = 1227375;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200075 AND `Reference` = 1227476;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200075 AND `Reference` = 1227577;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200076 AND `Reference` = 1227476;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200076 AND `Reference` = 1227577;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200076 AND `Reference` = 1227678;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200077 AND `Reference` = 1227577;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200077 AND `Reference` = 1227678;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200077 AND `Reference` = 1227779;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200078 AND `Reference` = 1227678;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200078 AND `Reference` = 1227779;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200078 AND `Reference` = 1227880;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200079 AND `Reference` = 1227779;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200079 AND `Reference` = 1227880;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200079 AND `Reference` = 1227981;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200080 AND `Reference` = 1227880;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200080 AND `Reference` = 1227981;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200080 AND `Reference` = 1228082;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200081 AND `Reference` = 1227981;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200081 AND `Reference` = 1228082;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200081 AND `Reference` = 1228183;
UPDATE `reference_loot_template` SET `Chance` = 3 WHERE `Entry` = 1200168 AND `Reference` = 1226870;
UPDATE `reference_loot_template` SET `Chance` = 1.5 WHERE `Entry` = 1200169 AND `Reference` = 1226870;
UPDATE `reference_loot_template` SET `Chance` = 1.5 WHERE `Entry` = 1200169 AND `Reference` = 1226971;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200170 AND `Reference` = 1226870;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200170 AND `Reference` = 1226971;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200170 AND `Reference` = 1227072;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200171 AND `Reference` = 1226971;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200171 AND `Reference` = 1227072;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200171 AND `Reference` = 1227173;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200172 AND `Reference` = 1227072;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200172 AND `Reference` = 1227173;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200172 AND `Reference` = 1227274;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200173 AND `Reference` = 1227173;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200173 AND `Reference` = 1227274;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200173 AND `Reference` = 1227375;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200174 AND `Reference` = 1227274;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200174 AND `Reference` = 1227375;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200174 AND `Reference` = 1227476;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200175 AND `Reference` = 1227375;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200175 AND `Reference` = 1227476;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200175 AND `Reference` = 1227577;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200176 AND `Reference` = 1227476;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200176 AND `Reference` = 1227577;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200176 AND `Reference` = 1227678;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200177 AND `Reference` = 1227577;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200177 AND `Reference` = 1227678;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200177 AND `Reference` = 1227779;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200178 AND `Reference` = 1227678;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200178 AND `Reference` = 1227779;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200178 AND `Reference` = 1227880;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200179 AND `Reference` = 1227779;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200179 AND `Reference` = 1227880;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200179 AND `Reference` = 1227981;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200180 AND `Reference` = 1227880;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200180 AND `Reference` = 1227981;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200180 AND `Reference` = 1228082;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200181 AND `Reference` = 1227981;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200181 AND `Reference` = 1228082;
UPDATE `reference_loot_template` SET `Chance` = 1 WHERE `Entry` = 1200181 AND `Reference` = 1228183;
@@ -0,0 +1,12 @@
-- DB update 2026_03_10_01 -> 2026_03_11_00
--
CREATE TABLE IF NOT EXISTS `spell_jump_distance` (
`ID` int unsigned NOT NULL COMMENT 'spell id',
`JumpDistance` float NOT NULL DEFAULT '0' COMMENT 'max hop distance in yards',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Per-spell chain jump distance override';
DELETE FROM `spell_jump_distance` WHERE `ID` IN (62131, 64390);
INSERT INTO `spell_jump_distance` (`ID`, `JumpDistance`) VALUES
(62131, 5.0),
(64390, 5.0);
@@ -0,0 +1,4 @@
-- DB update 2026_03_11_00 -> 2026_03_11_01
-- Restrict "on spellcast" procs to damage/heal only (SpellTypeMask=3)
-- Prevents proccing from utility spells like Open Lock (doors with keys)
UPDATE `spell_proc` SET `SpellTypeMask` = 3 WHERE `SpellId` IN (27521, 27774, 32837, 32980, 32981, 34584, 38334, 55381, 58442, 62114, 71585);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,77 @@
-- DB update 2026_03_11_02 -> 2026_03_12_00
-- .bf queue command and display strings
-- Syntax: .bf queue #battleid
-- Displays players in queue, invited, and actively in war for a given battlefield.
--
-- Output: 2 team headers + one line per player:
-- 1. Header (5120 or 5121) — args: battleId, timerSecs
-- 2. Team hdr (5122) x2 — args: teamName, queueCount, invitedCount, warCount
-- 3. Per-player (5123-5125) — queue: name | invited: name, secsLeft | war: name
-- ----------------------------------------------------------------
-- command table
-- ----------------------------------------------------------------
DELETE FROM `command` WHERE `name` = 'bf queue';
INSERT INTO `command` (`name`, `security`, `help`) VALUES
('bf queue', 2, 'Syntax: .bf queue #battleid\r\nDisplays all players currently in queue, invited, or actively in war for the specified battlefield.\r\n#battleid: the battle ID (e.g. 1 for Wintergrasp).');
-- ----------------------------------------------------------------
-- acore_string (entries 5120–5125)
-- ----------------------------------------------------------------
DELETE FROM `acore_string` WHERE `entry` BETWEEN 5120 AND 5125;
INSERT INTO `acore_string`
(`entry`, `content_default`,
`locale_koKR`, `locale_frFR`, `locale_deDE`,
`locale_zhCN`, `locale_zhTW`,
`locale_esES`, `locale_esMX`, `locale_ruRU`)
VALUES
-- 5120 : header – war in progress args: battleId, timerSecs
(5120,
'Battlefield [{}] | WAR IN PROGRESS | Timer: {}s',
'전장 [{}] | 전투 진행 중 | 타이머: {}초',
'Champ de bataille [{}] | GUERRE EN COURS | Minuterie : {}s',
'Schlachtfeld [{}] | KRIEG LÄUFT | Timer: {}s',
'战场 [{}] | 战斗进行中 | 计时器: {}秒',
'戰場 [{}] | 戰鬥進行中 | 計時器: {}秒',
'Campo de batalla [{}] | GUERRA EN CURSO | Temporizador: {}s',
'Campo de batalla [{}] | GUERRA EN CURSO | Temporizador: {}s',
'Поле боя [{}] | ВОЙНА ИДЁТ | Таймер: {}с'),
-- 5121 : header – waiting for battle args: battleId, timerSecs
(5121,
'Battlefield [{}] | Waiting for battle | Timer: {}s',
'전장 [{}] | 전투 대기 중 | 타이머: {}초',
'Champ de bataille [{}] | En attente de bataille | Minuterie : {}s',
'Schlachtfeld [{}] | Warten auf die Schlacht | Timer: {}s',
'战场 [{}] | 等待战斗 | 计时器: {}秒',
'戰場 [{}] | 等待戰鬥 | 計時器: {}秒',
'Campo de batalla [{}] | Esperando la batalla | Temporizador: {}s',
'Campo de batalla [{}] | Esperando la batalla | Temporizador: {}s',
'Поле боя [{}] | Ожидание битвы | Таймер: {}с'),
-- 5122 : team header args: teamName, queueCount, invitedCount, warCount
(5122,
'=== {} | Queue: {} | Invited: {} | War: {} ===',
'=== {} | 대기열: {} | 초대됨: {} | 전투 중: {} ===',
'=== {} | File : {} | Invités : {} | En guerre : {} ===',
'=== {} | Warteschlange: {} | Eingeladen: {} | Im Krieg: {} ===',
'=== {} | 队列: {} | 已邀请: {} | 战斗中: {} ===',
'=== {} | 佇列: {} | 已邀請: {} | 戰鬥中: {} ===',
'=== {} | Cola: {} | Invitados: {} | En guerra: {} ===',
'=== {} | Cola: {} | Invitados: {} | En guerra: {} ===',
'=== {} | Очередь: {} | Приглашённые: {} | В бою: {} ==='),
-- 5123 : player in queue args: playerName
(5123,
' [Q] {}',
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
-- 5124 : player invited args: playerName, secsLeft
(5124,
' [I] {} ({}s)',
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
-- 5125 : player in war args: playerName
(5125,
' [W] {}',
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -0,0 +1,5 @@
-- DB update 2026_03_12_00 -> 2026_03_13_00
--
DELETE FROM `spell_script_names` WHERE `spell_id` = -11426 AND `ScriptName` = 'spell_mage_ice_barrier_aura';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(-11426, 'spell_mage_ice_barrier_aura');
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,37 @@
-- DB update 2026_03_13_02 -> 2026_03_13_03
-- Update SAI.
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 28557;
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 28557);
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`, `event_param6`, `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
(28557, 0, 0, 1, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - On Reset - Set Event Phase 1'),
(28557, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - On Reset - Set Reactstate Passive'),
(28557, 0, 2, 0, 4, 1, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2855700, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - On Aggro - Run Script (Phase 1)'),
(28557, 0, 3, 0, 101, 1, 100, 1, 1, 3, 3000, 0, 0, 0, 80, 2855701, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - On 1 or More Players in Range - Run Script (Phase 1) (No Repeat)'),
(28557, 0, 4, 0, 102, 2, 100, 0, 1, 3, 30000, 30000, 30000, 0, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - On Less Than 1 Players in Range - Evade (Phase 2)'),
(28557, 0, 5, 0, 4, 1, 100, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - On Aggro - Set Reactstate Aggressive (Phase 1)');
-- Set Actionlist.
DELETE FROM `smart_scripts` WHERE (`source_type` = 9) AND (`entryorguid` IN (2855700, 2855701));
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`, `event_param6`, `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
(2855700, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Reactstate Passive'),
(2855700, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Orientation Invoker'),
(2855700, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 51604, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Cast \'Serverside - Stun Self\''),
(2855700, 9, 3, 0, 0, 0, 100, 0, 500, 500, 0, 0, 0, 0, 4, 14561, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Play Sound 14561'),
(2855700, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 431, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Emote State 431'),
(2855700, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Say Line 0'),
(2855700, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Event Phase 2'),
(2855701, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Reactstate Passive'),
(2855701, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 21, 5, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Orientation Closest Player'),
(2855701, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 51604, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Cast \'Serverside - Stun Self\''),
(2855701, 9, 3, 0, 0, 0, 100, 0, 500, 500, 0, 0, 0, 0, 4, 14561, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Play Sound 14561'),
(2855701, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 431, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Emote State 431'),
(2855701, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 21, 5, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Say Line 0'),
(2855701, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Peasant - Actionlist - Set Event Phase 2');
-- Set Conditions
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` IN (3, 6)) AND (`SourceEntry` = 28557) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 0) AND (`ConditionValue1` IN (3, 4)) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(22, 3, 28557, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'The event only occurs if the attacker is a player.'),
(22, 6, 28557, 0, 0, 31, 0, 3, 0, 0, 0, 0, 0, '', 'The event only occurs if the attacker is not a player.');
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,63 @@
-- DB update 2026_03_13_06 -> 2026_03_13_07
-- Update npc (ruRU) ; from WowHead Wotlk > TBC > Classic > Cata > Mop > Retail
-- If locale datas strictly equals AC enUS, or if locale datas strictly equals to Wowhead enUS, then we use AC fallback to enUS
-- Disclaimer : Datas of technical NPCs (Theoretically not visible to players) could be wrong, here we strictly align with WoWHead datas
-- Entries without any translation datas, on any version
-- AC datas : OLD Name : "Andrew Test Dummy 80 Hostile Low Damage", Name AC enUS : "QA Test Dummy 80 Hostile Low Damage" OLD Subname : "QA Punching Bag", Subname AC enUS : "QA Punching Bag" ; Reason : Match AC enUS datas
DELETE FROM `creature_template_locale` WHERE `locale` = 'ruRU' AND `entry` = 30888;
-- Update existing entries, from CLASSIC
-- AC datas : OLD Name : "", Name AC enUS : "DEBUG - Gossip Gryphon Master" ; Wowhead enUS : "DEBUG - Gossip Gryphon Master"
UPDATE `creature_template_locale` SET `Name` = 'DEBUG - укротитель грифонов, сплетни', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 2833;
-- AC datas : OLD Name : "", Name AC enUS : "Cap'n Copyright" ; Wowhead enUS : "Cap'n Copyright"
UPDATE `creature_template_locale` SET `Name` = 'Капитанские права', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 3152;
-- AC datas : OLD Name : "Наставница суккубов", Name AC enUS : "World Succubus Trainer" ; Wowhead enUS : "World Succubus Trainer"
UPDATE `creature_template_locale` SET `Name` = 'Дрессировщица суккубов', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 5014;
-- AC datas : OLD Name : "Наставница демонов Бездны", Name AC enUS : "World Voidwalker Trainer" ; Wowhead enUS : "World Voidwalker Trainer"
UPDATE `creature_template_locale` SET `Name` = 'Дрессировщица демонов Бездны', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 5016;
-- AC datas : OLD Name : "", Name AC enUS : "World Mount Vendor" ; Wowhead enUS : "World Mount Vendor"
UPDATE `creature_template_locale` SET `Name` = 'Мир - продавщица скакунов', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 7747;
-- AC datas : OLD Name : "", Name AC enUS : "World Gnome Engineering Trainer" ; Wowhead enUS : "World Gnome Engineering Trainer"
UPDATE `creature_template_locale` SET `Name` = 'Мир - гном - учитель - инженерное дело', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 8676;
-- AC datas : OLD Name : "Yor", Name AC enUS : "Yor <UNUSED>" ; Wowhead enUS : "Yor"
UPDATE `creature_template_locale` SET `Name` = 'Йор', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 10237;
-- Update existing entries, from CATA
-- AC datas : OLD Name : "", Name AC enUS : "Invis Horde Siege Engine - West 02" ; Wowhead enUS : "Invis Horde Siege Engine - West 02"
UPDATE `creature_template_locale` SET `Name` = 'Невидимая осадная машина Орды - запад 02', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 21236;
-- AC datas : OLD Name : "", Name AC enUS : "Invis Horde Siege Engine - East 02" ; Wowhead enUS : "Invis Horde Siege Engine - East 02"
UPDATE `creature_template_locale` SET `Name` = 'Невидимая осадная машина Орды - восток 02', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 21237;
-- AC datas : OLD Name : "", Name AC enUS : "Gnome Defender - 209" ; Wowhead enUS : "Gnome Defender - 209"
UPDATE `creature_template_locale` SET `Name` = 'Защитник гномов - 209', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 21426;
-- Update existing entries, from RETAIL
-- AC datas : OLD Subname : "Алхимик *модель отсутствует*", Subname AC enUS : "Alchemist <Needs Model>" ; Wowhead enUS : "Journeyman Alchemy Trainer"
UPDATE `creature_template_locale` SET `Title` = 'Учитель подмастерьев алхимиков', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 3070;
-- AC datas : OLD Subname : "Травник <модель отсутствует>", Subname AC enUS : "Herbalist <Needs Model>" ; Wowhead enUS : "Herbalism Trainer"
UPDATE `creature_template_locale` SET `Title` = 'Учитель травничества', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 3071;
-- AC datas : OLD Subname : "", Subname AC enUS : "No Clothes NPC" ; Wowhead enUS : "No Clothes NPC"
UPDATE `creature_template_locale` SET `Title` = 'Голый NPC', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 4045;
-- AC datas : OLD Name : "", Name AC enUS : "Test BattleMaster" ; Wowhead enUS : "Test BattleMaster"
UPDATE `creature_template_locale` SET `Name` = 'Тестовый военачальник', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 7314;
-- AC datas : OLD Subname : "", Subname AC enUS : "Designer Extraordinaire" ; Wowhead enUS : "Designer Extraordinaire"
UPDATE `creature_template_locale` SET `Title` = 'Выдающийся дизайнер', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 14885;
-- AC datas : OLD Subname : "", Subname AC enUS : "Designer Extraordinaire" ; Wowhead enUS : "Designer Extraordinaire"
UPDATE `creature_template_locale` SET `Title` = 'Выдающийся дизайнер', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 15123;
-- AC datas : OLD Name : "", Name AC enUS : "Vulculon UNUSED" ; Wowhead enUS : "Vulculon UNUSED"
UPDATE `creature_template_locale` SET `Name` = 'Вулкулон UNUSED', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 15210;
-- AC datas : OLD Name : "RC Blimp", Name AC enUS : "RC Blimp <PH>" ; Wowhead enUS : "RC Blimp"
UPDATE `creature_template_locale` SET `Name` = 'Радиоуправляемый дирижабль', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 15349;
-- AC datas : OLD Subname : "", Subname AC enUS : "Cheesy Test Alchemist" ; Wowhead enUS : "Alchemy Trainer"
UPDATE `creature_template_locale` SET `Title` = 'Учитель алхимии', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 16487;
-- AC datas : OLD Subname : "Учительница верховой езды", Subname AC enUS : "Horse Riding Trainer" ; Wowhead enUS : "Stable Master"
UPDATE `creature_template_locale` SET `Title` = 'Смотрительница стойл', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 19491;
-- AC datas : OLD Subname : "Учительница верховой езды", Subname AC enUS : "Horse Riding Trainer" ; Wowhead enUS : "Stable Master"
UPDATE `creature_template_locale` SET `Title` = 'Смотрительница стойл', `VerifiedBuild` = 0 WHERE `locale` = 'ruRU' AND `entry` = 19492;
-- List of entries using CLASSIC datas :
-- 2833,3152,5014,5016,7747,8676,10237
-- List of entries using CATA datas :
-- 21236,21237,21426
-- List of entries using RETAIL datas :
-- 3070,3071,4045,7314,14885,15123,15210,15349,16487,19491,19492
File diff suppressed because it is too large Load Diff
+51
View File
@@ -29,6 +29,16 @@ namespace Acore
template<typename... Args>
using FormatString = fmt::format_string<Args...>;
using FormatStringView = fmt::string_view;
using FormatArgs = fmt::format_args;
template<typename... Args>
constexpr auto MakeFormatArgs(Args&&... args)
{
return fmt::make_format_args(args...);
}
/// Default AC string format function.
template<typename... Args>
inline std::string StringFormat(FormatString<Args...> fmt, Args&&... args)
@@ -43,6 +53,47 @@ namespace Acore
}
}
/// Format directly to an output iterator.
template<typename OutputIt, typename... Args>
inline OutputIt StringFormatTo(OutputIt out, FormatString<Args...> fmt, Args&&... args)
{
try
{
return fmt::format_to(out, fmt, std::forward<Args>(args)...);
}
catch (std::exception const& e)
{
return fmt::format_to(out, "Wrong format occurred ({}). Fmt string: '{}'", e.what(), fmt.get());
}
}
/// Format with pre-built format args.
inline std::string StringVFormat(FormatStringView fmt, FormatArgs args)
{
try
{
return fmt::vformat(fmt, args);
}
catch (std::exception const& e)
{
return fmt::format("Wrong format occurred ({}). Fmt string: '{}'", e.what(), fmt);
}
}
/// Format with pre-built format args directly to an output iterator.
template<typename OutputIt>
inline OutputIt StringVFormatTo(OutputIt out, FormatStringView fmt, FormatArgs args)
{
try
{
return fmt::vformat_to(out, fmt, args);
}
catch (std::exception const& e)
{
return fmt::format_to(out, "Wrong format occurred ({}). Fmt string: '{}'", e.what(), fmt);
}
}
/// Returns true if the given char pointer is null.
inline bool IsFormatEmptyOrNull(char const* fmt)
{
@@ -27,6 +27,7 @@
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
#include <windows.h>
#include <iostream>
#else
#include "Chat.h"
#include "ChatCommand.h"
@@ -158,21 +159,48 @@ void CliThread()
std::string command;
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
wchar_t commandbuf[256];
DWORD charsRead = 0;
if (ReadConsoleW(hStdIn, commandbuf, sizeof(commandbuf) / sizeof(wchar_t) - 1, &charsRead, nullptr))
static bool checkedConsole = false;
static bool isRealConsole = false;
if (!checkedConsole)
{
if (charsRead > 0)
DWORD mode = 0;
isRealConsole = GetConsoleMode(hStdIn, &mode);
checkedConsole = true;
}
if (isRealConsole)
{
// ===== Real Windows Console =====
wchar_t commandbuf[256];
DWORD charsRead = 0;
if (ReadConsoleW(hStdIn, commandbuf,
sizeof(commandbuf) / sizeof(wchar_t) - 1,
&charsRead, nullptr))
{
commandbuf[charsRead] = L'\0';
if (!WStrToUtf8(commandbuf, charsRead, command))
if (charsRead > 0)
{
PrintCliPrefix();
continue;
commandbuf[charsRead] = L'\0';
if (!WStrToUtf8(commandbuf, charsRead, command))
{
PrintCliPrefix();
continue;
}
}
}
}
else
{
// ===== Redirected input (pipe) =====
if (!std::getline(std::cin, command))
{
World::StopNow(SHUTDOWN_EXIT_CODE);
break;
}
}
#else
char* command_str = readline(CLI_PREFIX);
::rl_bind_key('\t', ::rl_complete);
@@ -34,6 +34,7 @@
# CHARACTER DELETE
# CHARACTER CREATION
# CHARACTER
# ACHIEVEMENT
# SKILL
# STATS
# REPUTATION
@@ -2227,6 +2228,22 @@ SpellQueue.Window = 400
#
###################################################################################################
###################################################################################################
# ACHIEVEMENT
#
# Achievement.RealmFirstKillWindow
# Description: Time window (in seconds) for realm first kill achievements after the first
# completion. This setting controls whether multiple groups can earn the
# realm first kill achievement within a short time window.
# Default: 60 - (Allow additional groups to complete within 60 seconds/1 minute)
# 0 - (Strict mode, only the first group/player gets the achievement)
# 1+ - (Extended window, allow N seconds for additional completions)
Achievement.RealmFirstKillWindow = 60
#
###################################################################################################
###################################################################################################
# SKILL
#
+1 -1
View File
@@ -724,7 +724,7 @@ bool PetAI::CanAttack(Unit* target, SpellInfo const* spellInfo)
return me->GetCharmInfo()->IsCommandAttack();
// CC - mobs under crowd control can be attacked if owner commanded
if (target->HasBreakableByDamageCrowdControlAura() && (!spellInfo || !spellInfo->HasAttribute(SPELL_ATTR4_REACTIVE_DAMAGE_PROC)))
if (target->HasBreakableByDamageCrowdControlAura() && (!spellInfo || !spellInfo->HasAttribute(SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS)))
return me->GetCharmInfo()->IsCommandAttack();
// Returning - pets ignore attacks only if owner clicked follow
+11 -4
View File
@@ -29,8 +29,6 @@ class Unit;
class Creature;
class Player;
class SpellInfo;
enum SpellFinishReason : uint8;
typedef std::vector<AreaBoundary const*> CreatureBoundary;
#define TIME_INTERVAL_LOOK 5000
@@ -147,8 +145,17 @@ public:
// Called when spell hits a target
virtual void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spell*/) {}
// Called when a spell either finishes, interrupts or cancels a spell cast
virtual void OnSpellCastFinished(SpellInfo const* /*spell*/, SpellFinishReason /*reason*/) {}
// Called when the creature begins casting a spell (has cast time or is channeled)
virtual void OnSpellStart(SpellInfo const* /*spell*/) {}
// Called when the creature successfully executes a spell cast
virtual void OnSpellCast(SpellInfo const* /*spell*/) {}
// Called when a spell cast is interrupted or cancelled
virtual void OnSpellFailed(SpellInfo const* /*spell*/) {}
// Called when a channeled spell finishes its full duration
virtual void OnChannelFinished(SpellInfo const* /*spell*/) {}
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
virtual void AttackedBy(Unit* /*attacker*/) {}
@@ -269,6 +269,16 @@ void ScriptedAI::DoStopAttack()
me->AttackStop();
}
void ScriptedAI::DoRewardPlayersInArea()
{
me->GetMap()->DoForAllPlayers([&](Player* player)
{
if (player->GetFaction() != me->GetCreatureTemplate()->faction && !player->IsGameMaster())
if (player->GetAreaId() == me->GetAreaId())
player->KilledMonsterCredit(me->GetEntry());
});
}
void ScriptedAI::DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered)
{
if (!target || me->IsNonMeleeSpellCast(false))
@@ -756,9 +766,26 @@ void BossAI::UpdateAI(uint32 diff)
DoMeleeAttackIfReady();
}
void BossAI::OnSpellCastFinished(SpellInfo const* spellInfo, SpellFinishReason reason)
void BossAI::OnSpellCast(SpellInfo const* spellInfo)
{
ScriptedAI::OnSpellCast(spellInfo);
_CheckHealthAfterCast();
}
void BossAI::OnChannelFinished(SpellInfo const* spellInfo)
{
ScriptedAI::OnChannelFinished(spellInfo);
_CheckHealthAfterCast();
}
void BossAI::OnSpellFailed(SpellInfo const* spellInfo)
{
ScriptedAI::OnSpellFailed(spellInfo);
_CheckHealthAfterCast();
}
void BossAI::_CheckHealthAfterCast()
{
ScriptedAI::OnSpellCastFinished(spellInfo, reason);
// Check if any health check events are pending (i.e. waiting for the boss to stop casting.
if (_nextHealthCheck.IsPending() && me->IsInCombat())
{
@@ -306,6 +306,9 @@ struct ScriptedAI : public CreatureAI
//Stop attack of current victim
void DoStopAttack();
//Reward kill credit to all players from the oposing faction in the area (faction leaders)
void DoRewardPlayersInArea();
//Cast spell by spell info
void DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered = false);
@@ -490,7 +493,9 @@ public:
bool CanRespawn() override;
void OnSpellCastFinished(SpellInfo const* spell, SpellFinishReason reason) override;
void OnSpellCast(SpellInfo const* spell) override;
void OnChannelFinished(SpellInfo const* spell) override;
void OnSpellFailed(SpellInfo const* spell) override;
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override;
void JustSummoned(Creature* summon) override;
void SummonedCreatureDespawn(Creature* summon) override;
@@ -534,6 +539,7 @@ protected:
SummonList summons;
private:
void _CheckHealthAfterCast();
uint32 const _bossId;
std::list<HealthCheckEventData> _healthCheckEvents;
HealthCheckEventData _nextHealthCheck;
+3 -3
View File
@@ -1250,10 +1250,10 @@ bool SmartAI::IsMainSpellPrevented(SpellInfo const* spellInfo) const
return false;
}
void SmartAI::OnSpellCastFinished(SpellInfo const* spell, SpellFinishReason reason)
void SmartAI::OnSpellFailed(SpellInfo const* spell)
{
CreatureAI::OnSpellCastFinished(spell, reason);
if (reason == SPELL_FINISHED_CANCELED && _mainSpellId == spell->Id)
CreatureAI::OnSpellFailed(spell);
if (_mainSpellId == spell->Id)
if (_currentRangeMode && IsMainSpellPrevented(spell))
SetCurrentRangeMode(false);
}
+1 -1
View File
@@ -216,7 +216,7 @@ public:
bool IsMainSpellPrevented(SpellInfo const* spellInfo) const;
void OnSpellCastFinished(SpellInfo const* spell, SpellFinishReason reason) override;
void OnSpellFailed(SpellInfo const* spell) override;
private:
bool mIsCharmed;
@@ -28,6 +28,7 @@
#include "DBCEnums.h"
#include "DatabaseEnv.h"
#include "DisableMgr.h"
#include "Duration.h"
#include "GameEventMgr.h"
#include "GameTime.h"
#include "GridNotifiersImpl.h"
@@ -2592,11 +2593,18 @@ bool AchievementGlobalMgr::IsRealmCompleted(AchievementEntry const* achievement)
if (itr->second == SystemTimePoint::max())
return true;
// Allow completing the realm first kill for entire minute after first person did it
// Allow completing the realm first kill for configurable time window after first person did it
// it may allow more than one group to achieve it (highly unlikely)
// but apparently this is how blizz handles it as well
if (achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)
return (GameTime::GetSystemTime() - itr->second) > 1min;
{
Seconds windowSeconds = Seconds(sWorld->getIntConfig(CONFIG_ACHIEVEMENT_REALM_FIRST_KILL_WINDOW));
if (windowSeconds == 0s)
return true;
return (GameTime::GetSystemTime() - itr->second) > windowSeconds;
}
sScriptMgr->SetRealmCompleted(achievement);
+1 -1
View File
@@ -442,7 +442,7 @@ void Battlefield::PlayerAcceptInviteToWar(Player* player)
{
player->GetSession()->SendBfEntered(m_BattleId);
m_PlayersInWar[player->GetTeamId()].insert(player->GetGUID());
m_InvitedPlayers[player->GetTeamId()].erase(player->GetGUID());
m_InvitedPlayers[player->GetTeamId(true)].erase(player->GetGUID());
if (player->isAFK())
player->ToggleAFK();
@@ -361,6 +361,14 @@ public:
// Returns the maximum players allowed per team
uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayer; }
/// Returns the set of players waiting in the pre-battle queue (per team, read-only).
GuidUnorderedSet const& GetPlayersQueueSet(TeamId teamId) const { return m_PlayersInQueue[teamId]; }
/// Returns the map of players invited to join the active war, value is invite expiry
/// timestamp (per team, read-only).
PlayerTimerMap const& GetInvitedPlayersMap(TeamId teamId) const { return m_InvitedPlayers[teamId]; }
/// Returns the set of players actively fighting in the war (per team, read-only).
GuidUnorderedSet const& GetPlayersInWarSet(TeamId teamId) const { return m_PlayersInWar[teamId]; }
void DoPlaySoundToAll(uint32 SoundID);
void InvitePlayerToQueue(Player* player);
+14 -2
View File
@@ -22,6 +22,7 @@
#include "CreatureAI.h"
#include "CreatureAISelector.h"
#include "CreatureGroups.h"
#include "MoveSpline.h"
#include "DatabaseEnv.h"
#include "Formulas.h"
#include "GameEventMgr.h"
@@ -1093,8 +1094,7 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
UnitAI* oldAI = i_AI;
// Xinef: called in add to world
//Motion_Initialize();
Motion_Initialize();
i_AI = ai ? ai : FactorySelector::SelectAI(this);
delete oldAI;
@@ -1117,7 +1117,19 @@ void Creature::Motion_Initialize()
GetMotionMaster()->Initialize();
}
else if (m_formation->IsFormed())
{
// If the leader is already moving, start following immediately
// instead of waiting for the next waypoint signal.
if (Creature* leader = m_formation->GetLeader())
{
if (leader->IsAlive() && !leader->movespline->Finalized())
{
m_formation->LeaderStartedMoving();
return;
}
}
GetMotionMaster()->MoveIdle(); //wait the order of leader
}
else
GetMotionMaster()->Initialize();
}
@@ -303,6 +303,11 @@ struct CreatureBaseStats
uint32 AttackPower;
uint32 RangedAttackPower;
float BaseDamage[MAX_EXPANSIONS];
uint32 Strength;
uint32 Agility;
uint32 Stamina;
uint32 Intellect;
uint32 Spirit;
// Helpers
@@ -186,6 +186,7 @@ void CreatureGroup::RemoveMember(Creature* member)
{
if (m_leader == member)
{
RemoveFormationMovement();
m_leader = nullptr;
}
@@ -333,7 +334,7 @@ void CreatureGroup::FormationReset(bool dismiss, bool initMotionMaster)
if (initMotionMaster)
{
if (dismiss)
member->GetMotionMaster()->Initialize();
member->GetMotionMaster()->MovementExpiredOnSlot(MOTION_SLOT_IDLE, false);
else
member->GetMotionMaster()->MoveIdle();
@@ -344,16 +345,11 @@ void CreatureGroup::FormationReset(bool dismiss, bool initMotionMaster)
m_Formed = !dismiss;
}
void CreatureGroup::LeaderMoveTo(float x, float y, float z, uint32 move_type)
void CreatureGroup::LeaderStartedMoving()
{
//! To do: This should probably get its own movement generator or use WaypointMovementGenerator.
//! If the leader's path is known, member's path can be plotted as well using formation offsets.
if (!m_leader)
return;
float pathDist = m_leader->GetExactDist(x, y, z);
float pathAngle = std::atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
for (auto const& itr : m_members)
{
Creature* member = itr.first;
@@ -361,59 +357,39 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z, uint32 move_type)
if (member == m_leader || !member->IsAlive() || member->GetVictim() || !pFormationInfo.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER)))
continue;
// If member is stunned / rooted etc don't allow to move him
// Or if charmed/controlled
if (member->HasUnitState(UNIT_STATE_NOT_MOVE) || member->isPossessed() || member->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED))
continue;
// Xinef: this should be automatized, if turn angle is greater than PI/2 (90�) we should swap formation angle
float followAngle = pFormationInfo.follow_angle;
if (static_cast<float>(M_PI) - std::fabs(std::fabs(m_leader->GetOrientation() - pathAngle) - static_cast<float>(M_PI)) > static_cast<float>(M_PI)* 0.5f)
{
// pussywizard: in both cases should be 2*M_PI - follow_angle
// pussywizard: also, GetCurrentWaypointID() returns 0..n-1, while point_1 must be > 0, so +1
// pussywizard: db table waypoint_data shouldn't have point id 0 and shouldn't have any gaps for this to work!
// if (m_leader->GetCurrentWaypointID()+1 == pFormationInfo->point_1 || m_leader->GetCurrentWaypointID()+1 == itr->second->point_2)
followAngle = Position::NormalizeOrientation(pFormationInfo.follow_angle + static_cast<float>(M_PI)); //(2 * M_PI) - itr->second->follow_angle;
}
float const followAngle = pFormationInfo.follow_angle;
float const followDist = pFormationInfo.follow_dist;
float dx = x + std::cos(followAngle + pathAngle) * followDist;
float dy = y + std::sin(followAngle + pathAngle) * followDist;
float dz = z;
if (!member->HasUnitState(UNIT_STATE_FOLLOW_MOVE))
member->GetMotionMaster()->MoveFormation(m_leader, followDist, followAngle, pFormationInfo.point_1, pFormationInfo.point_2);
}
}
Acore::NormalizeMapCoord(dx);
Acore::NormalizeMapCoord(dy);
if (move_type < 2)
member->UpdateGroundPositionZ(dx, dy, dz);
bool CreatureGroup::CanLeaderStartMoving() const
{
for (auto const& itr : m_members)
{
if (itr.first && itr.first != m_leader && itr.first->IsAlive())
if (itr.first->IsEngaged() || itr.first->IsInEvadeMode())
return false;
}
// pussywizard: setting the same movementflags is not enough, spline decides whether leader walks/runs, so spline param is now passed as "run" parameter to this function
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
switch (move_type)
{
case WAYPOINT_MOVE_TYPE_WALK:
member->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
break;
case WAYPOINT_MOVE_TYPE_RUN:
member->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
break;
case WAYPOINT_MOVE_TYPE_LAND:
member->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
break;
}
return true;
}
// xinef: if we move members to position without taking care of sizes, we should compare distance without sizes
// xinef: change members speed basing on distance - if too far speed up, if too close slow down
UnitMoveType const mtype = Movement::SelectSpeedType(member->GetUnitMovementFlags());
float const speedRate = m_leader->GetSpeedRate(mtype) * member->GetExactDist(dx, dy, dz) / pathDist;
void CreatureGroup::RemoveFormationMovement()
{
for (auto const& itr : m_members)
{
Creature* member = itr.first;
if (!member || member == m_leader)
continue;
if (speedRate > 0.01f) // don't move if speed rate is too low
{
member->SetSpeedRate(mtype, speedRate);
member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
member->SetHomePosition(dx, dy, dz, pathAngle);
}
if (member->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) == FORMATION_MOTION_TYPE)
member->GetMotionMaster()->MovementExpiredOnSlot(MOTION_SLOT_IDLE, false);
}
}
@@ -108,7 +108,9 @@ public:
void RemoveMember(Creature* member);
void FormationReset(bool dismiss, bool initMotionMaster);
void LeaderMoveTo(float x, float y, float z, uint32 move_type);
void LeaderStartedMoving();
[[nodiscard]] bool CanLeaderStartMoving() const;
void RemoveFormationMovement();
void MemberEngagingTarget(Creature* member, Unit* target);
Unit* GetNewTargetForMember(Creature* member);
void MemberEvaded(Creature* member);
+36 -12
View File
@@ -16,6 +16,7 @@
*/
#include "Unit.h"
#include "AbstractFollower.h"
#include "AreaDefines.h"
#include "ArenaSpectator.h"
#include "Battlefield.h"
@@ -750,8 +751,7 @@ void Unit::DisableSpline()
void Unit::resetAttackTimer(WeaponAttackType type)
{
int32 time = int32(GetAttackTime(type) * m_modAttackSpeedPct[type]);
m_attackTimer[type] = std::min(m_attackTimer[type] + time, time);
m_attackTimer[type] = int32(GetAttackTime(type) * m_modAttackSpeedPct[type]);
}
bool Unit::IsWithinCombatRange(Unit const* obj, float dist2compare) const
@@ -978,7 +978,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
if (attacker && damagetype != DOT && spellProto->DmgClass == SPELL_DAMAGE_CLASS_MELEE && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_HOLY))
attacker->DealDamageShieldDamage(victim);
if (!spellProto->HasAttribute(SPELL_ATTR4_REACTIVE_DAMAGE_PROC))
if (!spellProto->HasAttribute(SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS))
victim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TAKE_DAMAGE, spellProto->Id);
}
else
@@ -2234,7 +2234,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit const* attacker, Unit const* victim, co
return uint32(std::ceil(std::max(damage * (1.0f - tmpvalue), 0.0f)));
}
float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMask, Unit const* victim)
float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo /*= nullptr*/)
{
float victimResistance = static_cast<float>(victim->GetResistance(schoolMask));
if (owner)
@@ -2252,7 +2252,8 @@ float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMa
}
victimResistance = std::max(victimResistance, 0.0f);
if (owner)
if (owner && (!spellInfo || !spellInfo->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL)))
victimResistance += std::max(static_cast<float>(victim->GetLevel() - owner->GetLevel()) * 5.0f, 0.0f);
float level = static_cast<float>(victim->GetLevel());
@@ -3555,9 +3556,8 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo
tmp += victim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellInfo->Dispel)) * 100;
}
// Players resistance for binary spells
if (spellInfo->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL) && (spellInfo->GetSchoolMask() & (SPELL_SCHOOL_MASK_NORMAL | SPELL_SCHOOL_MASK_HOLY)) == 0)
tmp += int32(Unit::GetEffectiveResistChance(this, spellInfo->GetSchoolMask(), victim) * 10000.0f); // 100 for spell calculations, and 100 for return value percentage
tmp += int32(Unit::GetEffectiveResistChance(this, spellInfo->GetSchoolMask(), victim, spellInfo) * 10000.0f);
}
// Roll chance
@@ -4210,7 +4210,7 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi
}
if (IsCreature() && IsAIEnabled)
ToCreature()->AI()->OnSpellCastFinished(spell->GetSpellInfo(), SPELL_FINISHED_CANCELED);
ToCreature()->AI()->OnSpellFailed(spell->GetSpellInfo());
}
}
@@ -5528,6 +5528,12 @@ void Unit::RemoveAreaAurasDueToLeaveWorld()
}
}
void Unit::RemoveAllFollowers()
{
while (!m_followingMe.empty())
(*m_followingMe.begin())->SetTarget(nullptr);
}
void Unit::RemoveAllAuras()
{
// this may be a dead loop if some events on aura remove will continiously apply aura on remove
@@ -8973,7 +8979,22 @@ float Unit::SpellDoneCritChance(Unit const* /*victim*/, SpellInfo const* spellPr
crit_chance = 0.0f;
// For other schools
else if (IsPlayer())
{
crit_chance = GetFloatValue(static_cast<uint16>(PLAYER_SPELL_CRIT_PERCENTAGE1) + GetFirstSchoolInMask(schoolMask));
// register aura mod, this is needed for Arcane Potency
if (Spell* spell = ToPlayer()->m_spellModTakingSpell)
{
Unit::AuraEffectList const& critAuras = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
for (AuraEffect const* aurEff : critAuras)
spell->m_appliedMods.insert(aurEff->GetBase());
Unit::AuraEffectList const& critSchoolAuras = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL);
for (AuraEffect const* aurEff : critSchoolAuras)
if (aurEff->GetMiscValue() & schoolMask)
spell->m_appliedMods.insert(aurEff->GetBase());
}
}
else
{
crit_chance = (float)m_baseSpellCritChance;
@@ -12706,6 +12727,8 @@ void Unit::RemoveFromWorld()
RemoveAreaAurasDueToLeaveWorld();
RemoveAllFollowers();
if (GetCharmerGUID())
{
LOG_FATAL("entities.unit", "Unit {} has charmer guid when removed from world", GetEntry());
@@ -14106,7 +14129,7 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura)
return true;
}
void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackType attackType, SpellInfo const* spellProto, Spell const* spell /*= nullptr*/)
void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackType attackType, SpellInfo const* /*spellProto*/, Spell const* /*spell*/ /*= nullptr*/)
{
// Prevent killing unit twice (and giving reward from kill twice)
if (!victim->GetHealth())
@@ -14220,20 +14243,21 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
}
// Do KILL and KILLED procs. KILL proc is called only for the unit who landed the killing blow (and its owner - for pets and totems) regardless of who tapped the victim
// Spell context is not passed to avoid the killing spell's triggered status from suppressing nested proc events
if (killer && (killer->IsPet() || killer->IsTotem()))
if (Unit* owner = killer->GetOwner())
{
Unit::ProcSkillsAndAuras(owner, victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
Unit::ProcSkillsAndAuras(owner, victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, nullptr, nullptr, -1, nullptr);
sScriptMgr->OnPlayerCreatureKilledByPet( killer->GetCharmerOrOwnerPlayerOrPlayerItself(), victim->ToCreature());
}
if (killer != victim)
{
Unit::ProcSkillsAndAuras(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
Unit::ProcSkillsAndAuras(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, nullptr, nullptr, -1, nullptr);
}
// Proc auras on death - must be before aura/combat remove
Unit::ProcSkillsAndAuras(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
Unit::ProcSkillsAndAuras(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, nullptr, nullptr, -1, nullptr);
// update get killing blow achievements, must be done before setDeathState to be able to require auras on target
// and before Spirit of Redemption as it also removes auras
+6 -6
View File
@@ -20,8 +20,6 @@
#include "EnumFlag.h"
#include "EventProcessor.h"
#include "FollowerRefMgr.h"
#include "FollowerReference.h"
#include "HostileRefMgr.h"
#include "ItemTemplate.h"
#include "MotionMaster.h"
@@ -74,6 +72,7 @@ class MotionTransport;
class Vehicle;
class TransportBase;
class SpellCastTargets;
class AbstractFollower;
typedef std::list<Unit*> UnitList;
typedef std::list< std::pair<Aura*, uint8> > DispelChargesList;
@@ -1191,7 +1190,7 @@ public:
int32 GetMechanicResistChance(SpellInfo const* spell);
[[nodiscard]] uint32 GetResistance(SpellSchoolMask mask) const;
[[nodiscard]] uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_RESISTANCES) + school); }
static float GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMask, Unit const* victim);
static float GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo = nullptr);
void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_RESISTANCES) + school, val); }
void UpdateResistanceBuffModsMod(SpellSchools school);
@@ -1882,9 +1881,10 @@ public:
[[nodiscard]] bool IsInDisallowedMountForm() const;
// Followers
void addFollower(FollowerReference* pRef) { m_FollowingRefMgr.insertFirst(pRef); }
void removeFollower(FollowerReference* /*pRef*/) { /* nothing to do yet */ }
void FollowerAdded(AbstractFollower* f) { m_followingMe.insert(f); }
void FollowerRemoved(AbstractFollower* f) { m_followingMe.erase(f); }
[[nodiscard]] virtual float GetFollowAngle() const { return static_cast<float>(M_PI / 2); }
void RemoveAllFollowers();
// Pets, guardians, minions...
[[nodiscard]] Guardian* GetGuardianPet() const;
@@ -2230,7 +2230,7 @@ private:
// Manage all Units that are threatened by us
HostileRefMgr m_HostileRefMgr;
FollowerRefMgr m_FollowingRefMgr;
std::unordered_set<AbstractFollower*> m_followingMe;
Unit* m_comboTarget;
int8 m_comboPoints;
+15 -18
View File
@@ -1961,21 +1961,23 @@ void GameEventMgr::SetHolidayEventTime(GameEventData& event)
bool singleDate = ((holiday->Date[0] >> 24) & 0x1F) == 31; // Events with fixed date within year have - 1
time_t curTime = GameTime::GetGameTime().count();
for (uint8 i = 0; i < MAX_HOLIDAY_DATES && holiday->Date[i]; ++i)
if (!singleDate)
{
time_t start = HolidayDateCalculator::FindStartTimeForStage(
holiday->Date, MAX_HOLIDAY_DATES, stageOffset, event.Length, curTime);
if (start)
event.Start = start;
return;
}
for (uint8 i = 0; i < MAX_HOLIDAY_DATES && holiday->Date[i]; ++i)
{
uint32 date = holiday->Date[i];
tm timeInfo;
if (singleDate)
{
timeInfo = Acore::Time::TimeBreakdown(curTime);
timeInfo.tm_year -= 1; // First try last year (event active through New Year)
}
else
{
timeInfo.tm_year = ((date >> 24) & 0x1F) + 100;
}
tm timeInfo = Acore::Time::TimeBreakdown(curTime);
timeInfo.tm_year -= 1; // First try last year (event active through New Year)
timeInfo.tm_mon = (date >> 20) & 0xF;
timeInfo.tm_mday = ((date >> 14) & 0x3F) + 1;
@@ -1986,12 +1988,12 @@ void GameEventMgr::SetHolidayEventTime(GameEventData& event)
// try to get next start time (skip past dates)
time_t startTime = mktime(&timeInfo);
if (curTime < startTime + event.Length * MINUTE)
if (curTime < startTime + stageOffset + event.Length * MINUTE)
{
event.Start = startTime + stageOffset;
break;
}
else if (singleDate)
else
{
tm tmCopy = Acore::Time::TimeBreakdown(curTime);
int year = tmCopy.tm_year; // This year
@@ -2000,11 +2002,6 @@ void GameEventMgr::SetHolidayEventTime(GameEventData& event)
event.Start = mktime(&tmCopy) + stageOffset;
break;
}
else
{
// date is due and not a singleDate event, try with next DBC date (dynamically calculated or overridden by game_event.start_time)
// if none is found we don't modify start date and use the one in game_event
}
}
}
@@ -580,3 +580,27 @@ std::vector<uint32_t> HolidayDateCalculator::GetDarkmoonFaireDates(int locationO
return dates;
}
time_t HolidayDateCalculator::FindStartTimeForStage(const uint32_t* packedDates, uint8_t numDates,
time_t stageOffset, uint32_t stageLengthMinutes, time_t curTime)
{
for (uint8_t i = 0; i < numDates && packedDates[i]; ++i)
{
uint32_t date = packedDates[i];
std::tm timeInfo = {};
timeInfo.tm_year = static_cast<int>(((date >> 24) & 0x1F)) + 100;
timeInfo.tm_mon = static_cast<int>((date >> 20) & 0xF);
timeInfo.tm_mday = static_cast<int>(((date >> 14) & 0x3F)) + 1;
timeInfo.tm_hour = static_cast<int>((date >> 6) & 0x1F);
timeInfo.tm_min = static_cast<int>(date & 0x3F);
timeInfo.tm_sec = 0;
timeInfo.tm_isdst = -1;
time_t startTime = mktime(&timeInfo);
if (curTime < startTime + stageOffset + static_cast<time_t>(stageLengthMinutes) * 60)
return startTime + stageOffset;
}
return 0;
}
@@ -100,6 +100,13 @@ public:
// Returns packed dates for all occurrences in the year range
static std::vector<uint32_t> GetDarkmoonFaireDates(int locationOffset, int startYear, int numYears, int dayOffset = 0);
// Find the correct stage start time from a list of packed holiday dates.
// For multi-stage holidays, stageOffset is the cumulative duration (in seconds) of all prior stages.
// stageLengthMinutes is the duration of the current stage in minutes.
// Returns the computed stage start time (startTime + stageOffset), or 0 if no valid date found.
static time_t FindStartTimeForStage(const uint32_t* packedDates, uint8_t numDates,
time_t stageOffset, uint32_t stageLengthMinutes, time_t curTime);
private:
// Julian Date conversions for lunar calculations
static double DateToJulianDay(int year, int month, double day);
+18 -1
View File
@@ -10431,6 +10431,11 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit
BaseMana = 0;
AttackPower = 0;
RangedAttackPower = 0;
Strength = 0;
Agility = 0;
Stamina = 0;
Intellect = 0;
Spirit = 0;
}
};
static const DefaultCreatureBaseStats defStats;
@@ -10441,7 +10446,7 @@ void ObjectMgr::LoadCreatureClassLevelStats()
{
uint32 oldMSTime = getMSTime();
QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2 FROM creature_classlevelstats");
QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2, Strength, Agility, Stamina, Intellect, Spirit FROM creature_classlevelstats");
if (!result)
{
@@ -10501,6 +10506,18 @@ void ObjectMgr::LoadCreatureClassLevelStats()
stats.AttackPower = fields[7].Get<uint32>();
stats.RangedAttackPower = fields[8].Get<uint32>();
stats.Strength = fields[12].Get<uint32>();
stats.Agility = fields[13].Get<uint32>();
stats.Stamina = fields[14].Get<uint32>();
stats.Intellect = fields[15].Get<uint32>();
stats.Spirit = fields[16].Get<uint32>();
if (!stats.Strength || !stats.Agility || !stats.Stamina || !stats.Intellect || !stats.Spirit)
{
// Once these attributes are implemented, this should probably be uncommented.
// LOG_WARN("server.loading", "Creature base attributes for class {}, level {} are missing!", Class, Level);
}
_creatureBaseStatsStore[MAKE_PAIR16(Level, Class)] = stats;
++count;
+6
View File
@@ -96,6 +96,12 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recv_data)
recv_data >> guid >> menuId >> gossipListId;
if (!_player->PlayerTalkClass->GetGossipMenu().GetItem(gossipListId))
{
recv_data.rfinish();
return;
}
if (_player->PlayerTalkClass->IsGossipOptionCoded(gossipListId))
recv_data >> code;
+9 -7
View File
@@ -530,14 +530,16 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
}
// auto-selection buff level base at target level (in spellInfo)
if (targets.GetUnitTarget())
{
SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(targets.GetUnitTarget()->GetLevel());
if (spellInfo->IsPositive())
if (Unit* target = targets.GetUnitTarget())
if (mover->IsFriendlyTo(target))
{
SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(target->GetLevel());
// if rank not found then function return nullptr but in explicit cast case original spell can be casted and later failed with appropriate error message
if (actualSpellInfo)
spellInfo = actualSpellInfo;
}
// if rank not found then function return nullptr but in explicit cast case original spell can be casted and later failed with appropriate error message
if (actualSpellInfo)
spellInfo = actualSpellInfo;
}
Spell* spell = new Spell(mover, spellInfo, triggerFlag, ObjectGuid::Empty, false);
+9 -1
View File
@@ -1194,7 +1194,15 @@ enum AcoreStrings
LANG_RESETALL_HONOR = 5118,
LANG_RESETALL_ARENA = 5119,
// Room for more strings 5120-9999
// Battlefield queue display (.bf queue)
LANG_BF_QUEUE_HDR_WAR = 5120,
LANG_BF_QUEUE_HDR_WAIT = 5121,
LANG_BF_QUEUE_TEAM_HDR = 5122,
LANG_BF_QUEUE_PLAYER_QUEUE = 5123,
LANG_BF_QUEUE_PLAYER_INVITED = 5124,
LANG_BF_QUEUE_PLAYER_WAR = 5125,
// Room for more strings 5126-9999
// Level requirement notifications
LANG_SAY_REQ = 6604,
@@ -15,15 +15,18 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FOLLOWERREFMANAGER
#define _FOLLOWERREFMANAGER
#include "AbstractFollower.h"
#include "Unit.h"
#include "RefMgr.h"
class Unit;
class TargetedMovementGeneratorBase;
class FollowerRefMgr : public RefMgr<Unit, TargetedMovementGeneratorBase>
void AbstractFollower::SetTarget(Unit* unit)
{
};
#endif
if (unit == _target)
return;
if (_target)
_target->FollowerRemoved(this);
_target = unit;
if (_target)
_target->FollowerAdded(this);
}
@@ -15,19 +15,22 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FOLLOWERREFERENCE_H
#define _FOLLOWERREFERENCE_H
#ifndef ACORE_ABSTRACTFOLLOWER_H
#define ACORE_ABSTRACTFOLLOWER_H
#include "Reference.h"
class TargetedMovementGeneratorBase;
class Unit;
class FollowerReference : public Reference<Unit, TargetedMovementGeneratorBase>
class AbstractFollower
{
protected:
void targetObjectBuildLink() override;
void targetObjectDestroyLink() override;
void sourceObjectDestroyLink() override;
public:
explicit AbstractFollower(Unit* target = nullptr) { SetTarget(target); }
virtual ~AbstractFollower() { SetTarget(nullptr); }
void SetTarget(Unit* unit);
[[nodiscard]] Unit* GetTarget() const { return _target; }
private:
Unit* _target = nullptr;
};
#endif
@@ -1,35 +0,0 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FollowerReference.h"
#include "TargetedMovementGenerator.h"
#include "Unit.h"
void FollowerReference::targetObjectBuildLink()
{
getTarget()->addFollower(this);
}
void FollowerReference::targetObjectDestroyLink()
{
getTarget()->removeFollower(this);
}
void FollowerReference::sourceObjectDestroyLink()
{
GetSource()->stopFollowing();
}
+12
View File
@@ -21,6 +21,7 @@
#include "CreatureAISelector.h"
#include "EscortMovementGenerator.h"
#include "FleeingMovementGenerator.h"
#include "FormationMovementGenerator.h"
#include "GameTime.h"
#include "HomeMovementGenerator.h"
#include "IdleMovementGenerator.h"
@@ -466,6 +467,17 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo
}
}
void MotionMaster::MoveFormation(Unit* leader, float dist, float angle, uint32 point1, uint32 point2)
{
if (!leader || leader == _owner || _owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
return;
if (!_owner->IsCreature())
return;
Mutate(new FormationMovementGenerator(leader, dist, angle, point1, point2), MOTION_SLOT_IDLE);
}
/**
* @brief The unit will move to a specific point. Doesn't work with UNIT_FLAG_DISABLE_MOVE
*
+3 -1
View File
@@ -55,7 +55,8 @@ enum MovementGeneratorType
ROTATE_MOTION_TYPE = 15,
EFFECT_MOTION_TYPE = 16,
ESCORT_MOTION_TYPE = 17, // xinef: EscortMovementGenerator.h
NULL_MOTION_TYPE = 18
FORMATION_MOTION_TYPE = 18, // FormationMovementGenerator.h
NULL_MOTION_TYPE = 19
};
enum MovementSlot
@@ -227,6 +228,7 @@ public:
void MoveTargetedHome(bool walk = false);
void MoveRandom(float wanderDistance = 0.0f);
void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE, bool inheritWalkState = true, bool inheritSpeed = true);
void MoveFormation(Unit* leader, float dist, float angle, uint32 point1, uint32 point2);
void MoveChase(Unit* target, std::optional<ChaseRange> dist = {}, std::optional<ChaseAngle> angle = {});
void MoveChase(Unit* target, float dist, float angle) { MoveChase(target, ChaseRange(dist), ChaseAngle(angle)); }
void MoveChase(Unit* target, float dist) { MoveChase(target, ChaseRange(dist)); }
@@ -0,0 +1,173 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FormationMovementGenerator.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "CreatureGroups.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
FormationMovementGenerator::FormationMovementGenerator(Unit* leader, float range, float angle, uint32 point1, uint32 point2)
: AbstractFollower(leader), _range(range), _angle(angle), _point1(point1), _point2(point2), _lastLeaderSplineID(0),
_hasPredictedDestination(false), _isMoving(false), _nextMoveTimer(0)
{
}
void FormationMovementGenerator::DoInitialize(Creature* owner)
{
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
owner->StopMoving();
return;
}
_nextMoveTimer.Reset(0);
}
void FormationMovementGenerator::DoFinalize(Creature* owner)
{
owner->ClearUnitState(UNIT_STATE_FOLLOW_MOVE);
}
void FormationMovementGenerator::DoReset(Creature* owner)
{
DoInitialize(owner);
}
bool FormationMovementGenerator::DoUpdate(Creature* owner, uint32 diff)
{
Unit* target = GetTarget();
if (!owner || !target)
return false;
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
owner->StopMoving();
_nextMoveTimer.Reset(0);
_hasPredictedDestination = false;
_isMoving = false;
return true;
}
if (target->movespline->Finalized() && target->movespline->GetId() == _lastLeaderSplineID && _hasPredictedDestination)
{
owner->StopMoving();
_nextMoveTimer.Reset(0);
_hasPredictedDestination = false;
_isMoving = false;
return true;
}
if (!owner->movespline->Finalized())
owner->SetHomePosition(owner->GetPosition());
if (!target->movespline->Finalized() && target->movespline->GetId() != _lastLeaderSplineID)
{
if (_point1 && target->IsCreature())
{
if (CreatureGroup* formation = target->ToCreature()->GetFormation())
{
if (Creature* leader = formation->GetLeader())
{
uint32 currentWaypoint = leader->GetCurrentWaypointID() + 1;
if (currentWaypoint == _point1 || currentWaypoint == _point2)
_angle = Position::NormalizeOrientation(float(2 * M_PI) - _angle);
}
}
}
LaunchMovement(owner, target);
_lastLeaderSplineID = target->movespline->GetId();
return true;
}
_nextMoveTimer.Update(diff);
if (_nextMoveTimer.Passed())
{
_nextMoveTimer.Reset(FORMATION_MOVEMENT_INTERVAL);
if (_lastLeaderPosition != target->GetPosition())
{
LaunchMovement(owner, target);
return true;
}
}
if (_isMoving && owner->movespline->Finalized())
{
_isMoving = false;
owner->SetFacingTo(target->GetOrientation());
MovementInform(owner);
}
return true;
}
void FormationMovementGenerator::LaunchMovement(Creature* owner, Unit* target)
{
float relativeAngle = 0.0f;
if (!target->movespline->Finalized())
{
G3D::Vector3 const leaderDestination = target->movespline->CurrentDestination();
relativeAngle = target->GetRelativeAngle(leaderDestination.x, leaderDestination.y);
}
Position dest = target->GetPosition();
float velocity = 0.0f;
if (!target->movespline->Finalized())
{
// Pick up leader's spline velocity
velocity = target->movespline->Velocity();
// Calculate travel distance to get a 1650ms result
float travelDist = velocity * 1.65f;
target->MovePositionToFirstCollision(dest, travelDist, relativeAngle);
target->MovePositionToFirstCollision(dest, _range, _angle + relativeAngle);
float distance = owner->GetExactDist(dest);
float velocityMod = std::min<float>(distance / travelDist, 1.5f);
velocity *= velocityMod;
_hasPredictedDestination = true;
}
else
{
target->MovePositionToFirstCollision(dest, _range, _angle + relativeAngle);
_hasPredictedDestination = false;
}
if (velocity == 0.0f)
velocity = target->GetSpeed(MOVE_WALK);
Movement::MoveSplineInit init(owner);
init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
init.SetVelocity(velocity);
init.Launch();
_lastLeaderPosition.Relocate(target->GetPosition());
_isMoving = true;
owner->AddUnitState(UNIT_STATE_FOLLOW_MOVE);
}
void FormationMovementGenerator::MovementInform(Creature* owner)
{
if (owner->AI())
owner->AI()->MovementInform(FORMATION_MOTION_TYPE, 0);
}
@@ -0,0 +1,58 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACORE_FORMATIONMOVEMENTGENERATOR_H
#define ACORE_FORMATIONMOVEMENTGENERATOR_H
#include "AbstractFollower.h"
#include "MovementGenerator.h"
#include "Position.h"
#include "Timer.h"
class Creature;
class FormationMovementGenerator : public MovementGeneratorMedium<Creature, FormationMovementGenerator>, public AbstractFollower
{
public:
explicit FormationMovementGenerator(Unit* leader, float range, float angle, uint32 point1, uint32 point2);
MovementGeneratorType GetMovementGeneratorType() { return FORMATION_MOTION_TYPE; }
void DoInitialize(Creature*);
void DoFinalize(Creature*);
void DoReset(Creature*);
bool DoUpdate(Creature*, uint32);
private:
void MovementInform(Creature* owner);
void LaunchMovement(Creature* owner, Unit* target);
static constexpr uint32 FORMATION_MOVEMENT_INTERVAL = 1200;
float const _range;
float _angle;
uint32 const _point1;
uint32 const _point2;
uint32 _lastLeaderSplineID;
bool _hasPredictedDestination;
bool _isMoving;
Position _lastLeaderPosition;
TimeTracker _nextMoveTimer;
};
#endif
@@ -67,8 +67,8 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
init.SetWalk(walk);
init.Launch();
if (creature->GetFormation() && creature->GetFormation()->GetLeader() == creature)
creature->GetFormation()->LeaderMoveTo(_currDestPosition.GetPositionX(), _currDestPosition.GetPositionY(), _currDestPosition.GetPositionZ(), 0);
if (creature->GetFormation() && creature->GetFormation()->GetLeader() == creature && creature->GetFormation()->CanLeaderStartMoving())
creature->GetFormation()->LeaderStartedMoving();
return;
}
@@ -242,8 +242,8 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
}
//Call for creature group update
if (creature->GetFormation() && creature->GetFormation()->GetLeader() == creature)
creature->GetFormation()->LeaderMoveTo(finalPoint.x, finalPoint.y, finalPoint.z, 0);
if (creature->GetFormation() && creature->GetFormation()->GetLeader() == creature && creature->GetFormation()->CanLeaderStartMoving())
creature->GetFormation()->LeaderStartedMoving();
if (sWorld->getBoolConfig(CONFIG_DONT_CACHE_RANDOM_MOVEMENT_PATHS))
_preComputedPaths.erase(pathIdx);
@@ -73,7 +73,7 @@ void ChaseMovementGenerator<T>::SetOffsetAndAngle(std::optional<ChaseRange> dist
template<class T>
void ChaseMovementGenerator<T>::SetNewTarget(Unit* target)
{
i_target.link(target, this);
SetTarget(target);
_lastTargetPosition.reset();
}
@@ -85,7 +85,7 @@ void ChaseMovementGenerator<T>::DistanceYourself(T* owner, float distance)
i_path = std::make_unique<PathGenerator>(owner);
float x, y, z;
i_target->GetNearPoint(owner, x, y, z, owner->GetBoundaryRadius(), distance, i_target->GetAngle(owner));
GetTarget()->GetNearPoint(owner, x, y, z, owner->GetBoundaryRadius(), distance, GetTarget()->GetAngle(owner));
if (DispatchSplineToPosition(owner, x, y, z, false, false, 0.f, false, false))
{
m_currentMode = CHASE_MODE_DISTANCING;
@@ -110,7 +110,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
// For pets, treat incomplete paths as failures to avoid clipping through geometry
// Players and Player-controlled units have more erratic movement, skip failure
if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer()) && !i_target.getTarget()->IsCharmedOwnedByPlayerOrPlayer())
if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer()) && !GetTarget()->IsCharmedOwnedByPlayerOrPlayer())
if (pathType & PATHFIND_INCOMPLETE)
pathFailed = true;
@@ -118,7 +118,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
{
if (cOwner)
{
cOwner->SetCannotReachTarget(i_target.getTarget()->GetGUID());
cOwner->SetCannotReachTarget(GetTarget()->GetGUID());
if (cOwner->IsPet() || cOwner->IsControlledByPlayer())
cOwner->AttackStop();
@@ -142,7 +142,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
Movement::MoveSplineInit init(owner);
init.MovebyPath(i_path->GetPath());
if (target)
init.SetFacing(i_target.getTarget());
init.SetFacing(GetTarget());
init.SetWalk(walk);
init.Launch();
@@ -152,7 +152,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
template<class T>
bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
{
if (!i_target.isValid() || !i_target->IsInWorld() || !owner->IsInMap(i_target.getTarget()))
if (!GetTarget() || !GetTarget()->IsInWorld() || !owner->IsInMap(GetTarget()))
return false;
if (!owner || !owner->IsAlive())
@@ -194,11 +194,11 @@ bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
bool forceDest =
//(cOwner && (cOwner->isWorldBoss() || cOwner->IsDungeonBoss())) || // force for all bosses, even not in instances
(i_target->IsPlayer() && i_target->ToPlayer()->IsGameMaster()) || // for .npc follow
(GetTarget()->IsPlayer() && GetTarget()->ToPlayer()->IsGameMaster()) || // for .npc follow
(owner->CanFly())
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
Unit* target = i_target.getTarget();
Unit* target = GetTarget();
bool mutualChase = IsMutualChase(owner, target);
bool const mutualTarget = target->GetVictim() == owner;
@@ -414,7 +414,7 @@ void ChaseMovementGenerator<T>::MovementInform(T* owner)
{
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
if (CreatureAI* AI = owner->ToCreature()->AI())
AI->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
AI->MovementInform(CHASE_MOTION_TYPE, GetTarget()->GetGUID().GetCounter());
break;
}
case CHASE_MODE_DISTANCING:
@@ -552,14 +552,14 @@ bool FollowMovementGenerator<T>::PositionOkay(Unit* target, bool isPlayerPet, bo
template<class T>
bool FollowMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
{
if (!i_target.isValid() || !i_target->IsInWorld() || !owner->IsInMap(i_target.getTarget()))
if (!GetTarget() || !GetTarget()->IsInWorld() || !owner->IsInMap(GetTarget()))
return false;
if (!owner || !owner->IsAlive())
return false;
Creature* cOwner = owner->ToCreature();
Unit* target = i_target.getTarget();
Unit* target = GetTarget();
// the owner might be unable to move (rooted or casting), or we have lost the target, pause movement
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || (cOwner && owner->ToCreature()->IsMovementPreventedByCasting()))
@@ -580,7 +580,7 @@ bool FollowMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
bool forceDest =
(followingMaster) || // allow pets following their master to cheat while generating paths
(i_target->IsPlayer() && i_target->ToPlayer()->IsGameMaster()) // for .npc follow
(GetTarget()->IsPlayer() && GetTarget()->ToPlayer()->IsGameMaster()) // for .npc follow
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
bool targetIsMoving = false;
@@ -717,7 +717,7 @@ void FollowMovementGenerator<T>::MovementInform(T* owner)
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
if (CreatureAI* AI = owner->ToCreature()->AI())
AI->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
AI->MovementInform(FOLLOW_MOTION_TYPE, GetTarget()->GetGUID().GetCounter());
}
//-----------------------------------------------//
@@ -18,22 +18,13 @@
#ifndef ACORE_TARGETEDMOVEMENTGENERATOR_H
#define ACORE_TARGETEDMOVEMENTGENERATOR_H
#include "FollowerReference.h"
#include "AbstractFollower.h"
#include "MovementGenerator.h"
#include "Optional.h"
#include "PathGenerator.h"
#include "Timer.h"
#include "Unit.h"
class TargetedMovementGeneratorBase
{
public:
TargetedMovementGeneratorBase(Unit* target) { i_target.link(target, this); }
void stopFollowing() { }
protected:
FollowerReference i_target;
};
enum ChaseMovementMode
{
CHASE_MODE_NORMAL, // chasing target
@@ -43,11 +34,11 @@ enum ChaseMovementMode
};
template<class T>
class ChaseMovementGenerator : public MovementGeneratorMedium<T, ChaseMovementGenerator<T>>, public TargetedMovementGeneratorBase
class ChaseMovementGenerator : public MovementGeneratorMedium<T, ChaseMovementGenerator<T>>, public AbstractFollower
{
public:
ChaseMovementGenerator(Unit* target, Optional<ChaseRange> range = {}, Optional<ChaseAngle> angle = {})
: TargetedMovementGeneratorBase(target), i_leashExtensionTimer(5000), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle), m_currentMode(CHASE_MODE_NORMAL) {}
: AbstractFollower(target), i_leashExtensionTimer(5000), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle), m_currentMode(CHASE_MODE_NORMAL) {}
~ChaseMovementGenerator() { }
MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; }
@@ -61,7 +52,7 @@ public:
bool PositionOkay(T* owner, Unit* target, Optional<float> maxDistance, Optional<ChaseAngle> angle);
void unitSpeedChanged() { _lastTargetPosition.reset(); }
Unit* GetTarget() const { return i_target.getTarget(); }
Unit* GetTarget() const { return AbstractFollower::GetTarget(); }
bool EnableWalking() const { return false; }
bool HasLostTarget(Unit* unit) const { return unit->GetVictim() != this->GetTarget(); }
@@ -87,11 +78,11 @@ private:
};
template<class T>
class FollowMovementGenerator : public MovementGeneratorMedium<T, FollowMovementGenerator<T>>, public TargetedMovementGeneratorBase
class FollowMovementGenerator : public MovementGeneratorMedium<T, FollowMovementGenerator<T>>, public AbstractFollower
{
public:
FollowMovementGenerator(Unit* target, float range, ChaseAngle angle, bool inheritWalkState, bool inheritSpeed)
: TargetedMovementGeneratorBase(target), i_path(nullptr), i_recheckPredictedDistanceTimer(0), i_recheckPredictedDistance(false), _range(range), _angle(angle), _inheritWalkState(inheritWalkState), _inheritSpeed(inheritSpeed) {}
: AbstractFollower(target), i_path(nullptr), i_recheckPredictedDistanceTimer(0), i_recheckPredictedDistance(false), _range(range), _angle(angle), _inheritWalkState(inheritWalkState), _inheritSpeed(inheritSpeed) {}
~FollowMovementGenerator() { }
MovementGeneratorType GetMovementGeneratorType() { return FOLLOW_MOTION_TYPE; }
@@ -102,7 +93,7 @@ public:
void DoReset(T*);
void MovementInform(T*);
Unit* GetTarget() const { return i_target.getTarget(); }
Unit* GetTarget() const { return AbstractFollower::GetTarget(); }
void unitSpeedChanged() { _lastTargetPosition.reset(); }
@@ -222,8 +222,8 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
init.Launch();
//Call for creature group update
if (creature->GetFormation() && creature->GetFormation()->GetLeader() == creature)
creature->GetFormation()->LeaderMoveTo(formationDest.x, formationDest.y, formationDest.z, node.move_type);
if (creature->GetFormation() && creature->GetFormation()->GetLeader() == creature && creature->GetFormation()->CanLeaderStartMoving())
creature->GetFormation()->LeaderStartedMoving();
return true;
}
@@ -166,6 +166,7 @@ namespace Movement
time_passed = 0;
vertical_acceleration = 0.f;
effect_start_time = 0;
velocity = args.velocity;
// Check if its a stop spline
if (args.flags.done)
@@ -190,7 +191,7 @@ namespace Movement
}
MoveSpline::MoveSpline() : m_Id(0), time_passed(0),
vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0),
vertical_acceleration(0.f), initialOrientation(0.f), velocity(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0),
onTransport(false)
{
splineflags.done = true;
@@ -64,6 +64,7 @@ namespace Movement
//float duration_mod_next;
float vertical_acceleration;
float initialOrientation;
float velocity;
int32 effect_start_time;
int32 point_Idx;
int32 point_Idx_offset;
@@ -85,6 +86,7 @@ namespace Movement
[[nodiscard]] int32 Duration() const { return spline.length(); }
[[nodiscard]] MySpline const& _Spline() const { return spline; }
[[nodiscard]] int32 _currentSplineIdx() const { return point_Idx; }
[[nodiscard]] float Velocity() const { return velocity; }
void _Finalize();
void _Interrupt() { splineflags.done = true; }
@@ -59,9 +59,7 @@ bool ScriptMgr::CanPacketSend(WorldSession* session, WorldPacket const& packet)
if (ScriptRegistry<ServerScript>::ScriptPointerList.empty())
return true;
WorldPacket copy(packet);
CALL_ENABLED_BOOLEAN_HOOKS(ServerScript, SERVERHOOK_CAN_PACKET_SEND, !script->CanPacketSend(session, copy));
CALL_ENABLED_BOOLEAN_HOOKS(ServerScript, SERVERHOOK_CAN_PACKET_SEND, !script->CanPacketSend(session, packet));
}
bool ScriptMgr::CanPacketReceive(WorldSession* session, WorldPacket const& packet)
@@ -69,9 +67,7 @@ bool ScriptMgr::CanPacketReceive(WorldSession* session, WorldPacket const& packe
if (ScriptRegistry<ServerScript>::ScriptPointerList.empty())
return true;
WorldPacket copy(packet);
CALL_ENABLED_BOOLEAN_HOOKS(ServerScript, SERVERHOOK_CAN_PACKET_RECEIVE, !script->CanPacketReceive(session, copy));
CALL_ENABLED_BOOLEAN_HOOKS(ServerScript, SERVERHOOK_CAN_PACKET_RECEIVE, !script->CanPacketReceive(session, packet));
}
ServerScript::ServerScript(const char* name, std::vector<uint16> enabledHooks)
@@ -53,23 +53,24 @@ public:
virtual void OnSocketClose(std::shared_ptr<WorldSocket> const& /*socket*/) { }
/**
* @brief This hook called when a packet is sent to a client. The packet object is a copy of the original packet, so reading and modifying it is safe.
* @brief This hook is called when a packet is sent to a client.
*
* @param session Contains information about the WorldSession
* @param packet Contains information about the WorldPacket
* @return True if you want to continue sending the packet, false if you want to disallow sending the packet
*/
[[nodiscard]] virtual bool CanPacketSend(WorldSession* /*session*/, WorldPacket& /*packet*/) { return true; }
[[nodiscard]] virtual bool CanPacketSend(WorldSession* /*session*/, WorldPacket const& /*packet*/) { return true; }
/**
* @brief Called when a (valid) packet is received by a client. The packet object is a copy of the original packet, so
* reading and modifying it is safe. Make sure to check WorldSession pointer before usage, it might be null in case of auth packets
* @brief Called when a (valid) packet is received by a client.
* Make sure to check WorldSession pointer before usage, it might be null in case of auth packets
*
* @param session Contains information about the WorldSession
* @param packet Contains information about the WorldPacket
* @return True if you want to continue receive the packet, false if you want to disallow receive the packet
* @return True if you want to continue receiving the packet, false if you want to disallow receiving the packet
*/
[[nodiscard]] virtual bool CanPacketReceive(WorldSession* /*session*/, WorldPacket& /*packet*/) { return true; }
[[nodiscard]] virtual bool CanPacketReceive(WorldSession* /*session*/, WorldPacket const& /*packet*/) { return true; }
virtual void OnPacketReceived(WorldSession* /*session*/, WorldPacket const& /*packet*/) { }
};
+1
View File
@@ -87,6 +87,7 @@ void ScriptMgr::Initialize()
ScriptRegistry<ArenaScript>::InitEnabledHooksIfNeeded(ARENAHOOK_END);
ScriptRegistry<ArenaTeamScript>::InitEnabledHooksIfNeeded(ARENATEAMHOOK_END);
ScriptRegistry<AuctionHouseScript>::InitEnabledHooksIfNeeded(AUCTIONHOUSEHOOK_END);
ScriptRegistry<BattlefieldScript>::InitEnabledHooksIfNeeded(BATTLEFIELDHOOK_END);
ScriptRegistry<BGScript>::InitEnabledHooksIfNeeded(ALLBATTLEGROUNDHOOK_END);
ScriptRegistry<CommandSC>::InitEnabledHooksIfNeeded(ALLCOMMANDHOOK_END);
ScriptRegistry<DatabaseScript>::InitEnabledHooksIfNeeded(DATABASEHOOK_END);
@@ -1105,14 +1105,12 @@ bool AuraEffect::IsAffectedOnSpell(SpellInfo const* spell) const
{
if (!spell)
return false;
// Check family name
if (spell->SpellFamilyName != m_spellInfo->SpellFamilyName)
// Check family name and EffectClassMask
if (!spell->IsAffected(m_spellInfo->SpellFamilyName, m_spellInfo->Effects[m_effIndex].SpellClassMask))
return false;
// Check EffectClassMask
if (m_spellInfo->Effects[m_effIndex].SpellClassMask & spell->SpellFamilyFlags)
return true;
return false;
return true;
}
bool AuraEffect::HasSpellClassMask() const
@@ -1348,28 +1348,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
}
switch (GetId())
{
case 12536: // Clearcasting
case 12043: // Presence of Mind
// Arcane Potency
if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, 2120, 0))
{
uint32 spellId = 0;
switch (aurEff->GetId())
{
case 31571:
spellId = 57529;
break;
case 31572:
spellId = 57531;
break;
default:
LOG_ERROR("spells.aura", "Aura::HandleAuraSpecificMods: Unknown rank of Arcane Potency ({}) found", aurEff->GetId());
}
if (spellId)
caster->CastSpell(caster, spellId, true);
}
break;
case 44544: // Fingers of Frost
{
// See if we already have the indicator aura. If not, create one.
+3 -3
View File
@@ -64,9 +64,9 @@ public:
uint8 GetSlot() const { return _slot; }
uint8 GetFlags() const { return _flags; }
uint8 GetEffectMask() const { return _flags & (AFLAG_EFF_INDEX_0 | AFLAG_EFF_INDEX_1 | AFLAG_EFF_INDEX_2); }
bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return _flags & (1 << effect); }
bool IsPositive() const { return _flags & AFLAG_POSITIVE; }
bool IsSelfcasted() const { return _flags & AFLAG_CASTER; }
bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return (_flags & (1 << effect)) != 0; }
bool IsPositive() const { return (_flags & AFLAG_POSITIVE) != 0; }
bool IsSelfcasted() const { return (_flags & AFLAG_CASTER) != 0; }
uint8 GetEffectsToApply() const { return _effectsToApply; }
void SetRemoveMode(AuraRemoveMode mode) { _removeMode = mode; }
+23 -14
View File
@@ -1862,7 +1862,7 @@ float tangent(float x)
//if (x <= -std::numeric_limits<float>::max()) return -std::numeric_limits<float>::max();
if (x < 100000.0f && x > -100000.0f) return x;
if (x >= 100000.0f) return 100000.0f;
if (x <= 100000.0f) return -100000.0f;
if (x <= -100000.0f) return -100000.0f;
return 0.0f;
}
@@ -2126,6 +2126,10 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
break;
}
// per-spell override from spell_jump_distance table
if (m_spellInfo->JumpDistance > 0.0f)
jumpRadius = m_spellInfo->JumpDistance;
// chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
bool isBouncingFar = (m_spellInfo->HasAttribute(SPELL_ATTR4_BOUNCY_CHAIN_MISSILES)
|| m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE
@@ -3255,7 +3259,7 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask)
Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
_duration = aur ? aur->GetDuration() : -1;
}
triggeredAur->SetDuration(_duration);
triggeredAur->SetDuration(std::max(triggeredAur->GetDuration(), _duration));
}
}
}
@@ -3629,6 +3633,12 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
m_caster->SetCurrentCastedSpell(this);
SendSpellStart();
// Call CreatureAI hook OnSpellStart for spells with cast time or channeled spells
if (m_casttime > 0 || m_spellInfo->IsChanneled())
if (Creature* caster = m_caster->ToCreature())
if (caster->IsAIEnabled)
caster->AI()->OnSpellStart(GetSpellInfo());
// set target for proper facing
if ((m_casttime || m_spellInfo->IsChanneled()) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_SET_FACING))
{
@@ -4016,7 +4026,7 @@ void Spell::_cast(bool skipCheck)
break;
}
Unit::ProcSkillsAndAuras(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, hitMask, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, hitMask, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
m_triggeredByAuraSpell.effectIndex, this, nullptr, nullptr, PROC_SPELL_PHASE_CAST);
}
@@ -4052,11 +4062,10 @@ void Spell::_cast(bool skipCheck)
SetExecutedCurrently(false);
// Call CreatureAI hook OnSpellCastFinished
if (m_originalCaster)
if (Creature* caster = m_originalCaster->ToCreature())
if (caster->IsAIEnabled)
caster->AI()->OnSpellCastFinished(GetSpellInfo(), SPELL_FINISHED_SUCCESSFUL_CAST);
// Call CreatureAI hook on successful cast
if (Creature* caster = m_caster->ToCreature())
if (caster->IsAIEnabled)
caster->AI()->OnSpellCast(GetSpellInfo());
}
void Spell::handle_immediate()
@@ -4416,7 +4425,7 @@ void Spell::update(uint32 difftime)
// We call the hook here instead of in Spell::finish because we only want to call it for completed channeling. Everything else is handled by interrupts
if (Creature* creatureCaster = m_caster->ToCreature())
if (creatureCaster->IsAIEnabled)
creatureCaster->AI()->OnSpellCastFinished(m_spellInfo, SPELL_FINISHED_CHANNELING_COMPLETE);
creatureCaster->AI()->OnChannelFinished(m_spellInfo);
}
// Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
// Xinef: Added this strange check because of diffrent update routines for players / creatures
@@ -4478,8 +4487,8 @@ void Spell::finish(bool ok)
// Xinef: Reset cooldown event in case of fail cast
if (m_spellInfo->IsCooldownStartedOnEvent())
m_caster->ToPlayer()->SendCooldownEvent(m_spellInfo, 0, 0, false);
}
return;
}
@@ -6878,9 +6887,9 @@ SpellCastResult Spell::CheckCasterAuras(bool preventionOnly) const
// Barkskin should skip sleep effects, sap and fears
if (m_spellInfo->Id == 22812)
mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
// Hand of Freedom, can be used while sapped
// Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
if (m_spellInfo->Id == 1044)
mask |= 1 << MECHANIC_SAPPED;
mask |= (1 << MECHANIC_SAPPED) | (1 << MECHANIC_FEAR);
Unit::AuraEffectList const& stunAuras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_STUN);
for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
{
@@ -6943,9 +6952,9 @@ SpellCastResult Spell::CheckCasterAuras(bool preventionOnly) const
// Barkskin should skip sleep effects, sap and fears
if (m_spellInfo->Id == 22812)
mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
// Hand of Freedom, can be used while sapped
// Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
if (m_spellInfo->Id == 1044)
mask |= 1 << MECHANIC_SAPPED;
mask |= (1 << MECHANIC_SAPPED) | (1 << MECHANIC_FEAR);
if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
return SPELL_FAILED_STUNNED;
-7
View File
@@ -93,13 +93,6 @@ enum SpellRangeFlag
SPELL_RANGE_RANGED = 2, //hunter range and ranged weapon
};
enum SpellFinishReason : uint8
{
SPELL_FINISHED_SUCCESSFUL_CAST = 0, // spell has sucessfully launched
SPELL_FINISHED_CANCELED = 1, // spell has been canceled (interrupts)
SPELL_FINISHED_CHANNELING_COMPLETE = 2 // spell channeling has been finished
};
struct SpellDestination
{
SpellDestination();
+16 -12
View File
@@ -861,6 +861,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry)
_isSpellValid = true;
_isCritCapable = false;
_requireCooldownInfo = false;
JumpDistance = 0.0f;
}
SpellInfo::~SpellInfo()
@@ -1285,6 +1286,20 @@ bool SpellInfo::IsAutoRepeatRangedSpell() const
return AttributesEx2 & SPELL_ATTR2_AUTO_REPEAT;
}
bool SpellInfo::IsAffected(uint32 familyName, flag96 const& familyFlags) const
{
if (!familyName)
return true;
if (familyName != SpellFamilyName)
return false;
if (familyFlags && !(familyFlags & SpellFamilyFlags))
return false;
return true;
}
bool SpellInfo::IsAffectedBySpellMods() const
{
return !(AttributesEx3 & SPELL_ATTR3_IGNORE_CASTER_MODIFIERS);
@@ -1300,23 +1315,12 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const
SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId);
if (!affectSpell)
{
return false;
}
if (!sScriptMgr->OnIsAffectedBySpellModCheck(affectSpell, this, mod))
{
return true;
}
// False if affect_spell == nullptr or spellFamily not equal
if (affectSpell->SpellFamilyName != SpellFamilyName)
return false;
if (mod->mask && !(mod->mask & SpellFamilyFlags))
return false;
return true;
return IsAffected(affectSpell->SpellFamilyName, mod->mask);
}
bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const
+3
View File
@@ -401,6 +401,7 @@ public:
bool _isSpellValid;
bool _isCritCapable;
bool _requireCooldownInfo;
float JumpDistance;
SpellInfo(SpellEntry const* spellEntry);
~SpellInfo();
@@ -466,6 +467,8 @@ public:
bool IsRangedWeaponSpell() const;
bool IsAutoRepeatRangedSpell() const;
[[nodiscard]] bool IsAffected(uint32 familyName, flag96 const& familyFlags) const;
bool IsAffectedBySpellMods() const;
bool IsAffectedBySpellMod(SpellModifier const* mod) const;
@@ -652,6 +652,19 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
});
// Explosive Trap Effect
ApplySpellFix({
13812, // Explosive Trap Effect (Rank 1)
14314, // Explosive Trap Effect (Rank 2)
14315, // Explosive Trap Effect (Rank 3)
27026, // Explosive Trap Effect (Rank 4)
49064, // Explosive Trap Effect (Rank 5)
49065 // Explosive Trap Effect (Rank 6)
}, [](SpellInfo* spellInfo)
{
spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
});
// Kill Command
// Kill Command, Overpower
ApplySpellFix({ 34027, 37529 }, [](SpellInfo* spellInfo)
@@ -1050,7 +1063,7 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({ 44461, 55361, 55362 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_TARGET_PROCS;
spellInfo->AttributesEx4 |= SPELL_ATTR4_REACTIVE_DAMAGE_PROC;
spellInfo->AttributesEx4 |= SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS;
});
// Evocation
@@ -1486,7 +1499,7 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
});
// Activate Sunblade Protecto
// Activate Sunblade Protector
ApplySpellFix({ 46475, 46476 }, [](SpellInfo* spellInfo)
{
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(14); // 60yd
@@ -1533,14 +1546,21 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT;
});
// Parasitic Shadowfiend
// Illidan Stormrage - Parasitic Shadowfiend
ApplySpellFix({ 41914 }, [](SpellInfo* spellInfo)
{
spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF;
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
});
// Teleport Maiev
// Illidan Stormrage - Demon Fire
ApplySpellFix({ 40030 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
spellInfo->AttributesEx4 &= ~SPELL_ATTR4_NO_CAST_LOG;
});
// Illidan Stormrage - Teleport Maiev
ApplySpellFix({ 41221 }, [](SpellInfo* spellInfo)
{
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 0-50000yd
+40 -10
View File
@@ -823,17 +823,10 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE
// check spell family name/flags (if set) for spells
if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK)
{
if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo())
{
if (procEntry.SpellFamilyName && procEntry.SpellFamilyName != eventSpellInfo->SpellFamilyName)
if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask))
return false;
if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventSpellInfo->SpellFamilyFlags))
return false;
}
}
// check spell type mask (if set)
if (eventInfo.GetTypeMask() & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))
{
@@ -1970,7 +1963,8 @@ void SpellMgr::LoadSpellProcs()
if (!spellInfo->Effects[i].IsAura())
continue;
if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER)
if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER
|| spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL)
{
found = true;
break;
@@ -2963,6 +2957,42 @@ void SpellMgr::LoadSpellSpecificAndAuraState()
LOG_INFO("server.loading", " ");
}
void SpellMgr::LoadSpellJumpDistances()
{
uint32 oldMSTime = getMSTime();
QueryResult result = WorldDatabase.Query("SELECT ID, JumpDistance FROM spell_jump_distance");
if (!result)
{
LOG_WARN("server.loading", ">> Loaded 0 spell jump distances. DB table `spell_jump_distance` is empty.");
LOG_INFO("server.loading", " ");
return;
}
uint32 count = 0;
do
{
Field const* fields = result->Fetch();
uint32 const spellId = fields[0].Get<uint32>();
float const jumpDistance = fields[1].Get<float>();
SpellInfo* spellInfo = _GetSpellInfo(spellId);
if (!spellInfo)
{
LOG_ERROR("sql.sql", "Table `spell_jump_distance` has wrong spell (spell_id: {}), ignored.", spellId);
continue;
}
spellInfo->JumpDistance = jumpDistance;
++count;
} while (result->NextRow());
LOG_INFO("server.loading", ">> Loaded {} spell jump distances in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
}
void SpellMgr::LoadSpellInfoCustomAttributes()
{
uint32 const oldMSTime = getMSTime();
@@ -3230,7 +3260,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
continue;
[[fallthrough]]; /// @todo: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
default:
if (!(spellInfo->Effects[j].CalcValue() &&
if (!(spellInfo->Effects[j].CalcValue() ||
((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) &&
!spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))))
continue;
+1
View File
@@ -778,6 +778,7 @@ public:
void LoadSpellInfoCustomAttributes();
void LoadSpellInfoCorrections();
void LoadSpellSpecificAndAuraState();
void LoadSpellJumpDistances();
private:
SpellDifficultySearcherMap mSpellDifficultySearcherMap;
+3
View File
@@ -434,6 +434,9 @@ void World::SetInitialWorldSettings()
LOG_INFO("server.loading", "Loading SpellInfo Custom Attributes...");
sSpellMgr->LoadSpellInfoCustomAttributes();
LOG_INFO("server.loading", "Loading Spell Jump Distances...");
sSpellMgr->LoadSpellJumpDistances();
LOG_INFO("server.loading", "Loading Player Totem models...");
sObjectMgr->LoadPlayerTotemModels();
+3
View File
@@ -674,4 +674,7 @@ void WorldConfig::BuildConfigCache()
SetConfigValue<uint32>(CONFIG_SCOURGEINVASION_COUNTER_THIRD, "ScourgeInvasion.CounterThird", 150);
SetConfigValue<std::string>(CONFIG_NEW_CHAR_STRING, "PlayerStart.String", "");
// Achievement
SetConfigValue<uint32>(CONFIG_ACHIEVEMENT_REALM_FIRST_KILL_WINDOW, "Achievement.RealmFirstKillWindow", 60);
}
+1
View File
@@ -489,6 +489,7 @@ enum ServerConfigs
RATE_MISS_CHANCE_MULTIPLIER_TARGET_PLAYER,
CONFIG_NEW_CHAR_STRING,
CONFIG_VALIDATE_SKILL_LEARNED_BY_SPELLS,
CONFIG_ACHIEVEMENT_REALM_FIRST_KILL_WINDOW,
MAX_NUM_SERVER_CONFIGS
};
+62 -1
View File
@@ -19,6 +19,9 @@
#include "Chat.h"
#include "CommandScript.h"
#include "Language.h"
#include "GameTime.h"
#include "ObjectAccessor.h"
#include "Player.h"
using namespace Acore::ChatCommands;
@@ -35,7 +38,8 @@ public:
{ "stop", HandleBattlefieldEnd, SEC_ADMINISTRATOR, Console::Yes },
{ "switch", HandleBattlefieldSwitch, SEC_ADMINISTRATOR, Console::Yes },
{ "timer", HandleBattlefieldTimer, SEC_ADMINISTRATOR, Console::Yes },
{ "enable", HandleBattlefieldEnable, SEC_ADMINISTRATOR, Console::Yes }
{ "enable", HandleBattlefieldEnable, SEC_ADMINISTRATOR, Console::Yes },
{ "queue", HandleBattlefieldQueue, SEC_GAMEMASTER, Console::Yes }
};
static ChatCommandTable commandTable =
{
@@ -167,6 +171,63 @@ public:
return true;
}
static bool HandleBattlefieldQueue(ChatHandler* handler, uint32 battleId)
{
Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId);
if (!bf)
{
handler->SendErrorMessage(LANG_BF_NOT_FOUND, battleId);
return false;
}
handler->PSendSysMessage(bf->IsWarTime() ? LANG_BF_QUEUE_HDR_WAR : LANG_BF_QUEUE_HDR_WAIT,
battleId, bf->GetTimer() / IN_MILLISECONDS);
static char const* teamNames[PVP_TEAMS_COUNT] = { "Alliance", "Horde" };
std::string offlineSuffix = handler->GetAcoreString(LANG_OFFLINE);
auto nameOf = [offlineSuffix](ObjectGuid guid) -> std::string
{
if (Player* p = ObjectAccessor::FindPlayer(guid))
return p->GetName();
return std::to_string(guid.GetCounter()) + offlineSuffix;
};
for (uint8 i = 0; i < PVP_TEAMS_COUNT; ++i)
{
TeamId team = TeamId(i);
GuidUnorderedSet const& inQueue = bf->GetPlayersQueueSet(team);
PlayerTimerMap const& invited = bf->GetInvitedPlayersMap(team);
GuidUnorderedSet const& inWar = bf->GetPlayersInWarSet(team);
handler->PSendSysMessage(LANG_BF_QUEUE_TEAM_HDR,
teamNames[i],
static_cast<uint32>(inQueue.size()),
static_cast<uint32>(invited.size()),
static_cast<uint32>(inWar.size()));
for (ObjectGuid const& guid : inQueue)
handler->PSendSysMessage(LANG_BF_QUEUE_PLAYER_QUEUE, nameOf(guid));
SystemTimePoint now = GameTime::GetSystemTime();
for (auto const& [guid, expiry] : invited)
{
SystemTimePoint expiryPoint = std::chrono::system_clock::from_time_t(expiry);
int32 secsLeft = std::max(int32(0), static_cast<int32>(
std::chrono::duration_cast<Seconds>(expiryPoint - now).count()));
handler->PSendSysMessage(LANG_BF_QUEUE_PLAYER_INVITED, nameOf(guid), secsLeft);
}
for (ObjectGuid const& guid : inWar)
handler->PSendSysMessage(LANG_BF_QUEUE_PLAYER_WAR, nameOf(guid));
}
return true;
}
};
void AddSC_bf_commandscript()
+49 -2
View File
@@ -620,16 +620,38 @@ public:
return true;
}
static bool HandleNpcInfoCommand(ChatHandler* handler)
static bool HandleNpcInfoCommand(ChatHandler* handler, Optional<CreatureSpawnId> spawnIdArg)
{
Creature* target = handler->getSelectedCreature();
ObjectGuid::LowType lowGuid = 0;
if (!target)
if (spawnIdArg)
lowGuid = *spawnIdArg;
if (!target && lowGuid)
target = handler->GetCreatureFromPlayerMapByDbGuid(lowGuid);
if (target)
return HandleNpcInfoCommandShowCreature(handler, target);
if (!lowGuid)
{
handler->SendErrorMessage(LANG_SELECT_CREATURE);
return false;
}
CreatureData const* cData = sObjectMgr->GetCreatureData(lowGuid);
if (!cData)
cData = sObjectMgr->LoadCreatureDataFromDB(lowGuid);
if (cData)
return HandleNpcInfoCommandShowFromDB(handler, lowGuid, cData);
handler->SendErrorMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowGuid);
return false;
}
static bool HandleNpcInfoCommandShowCreature(ChatHandler* handler, Creature* target)
{
CreatureTemplate const* cInfo = target->GetCreatureTemplate();
uint32 faction = target->GetFaction();
uint32 npcflags = target->GetNpcFlags();
@@ -695,6 +717,31 @@ public:
return true;
}
static bool HandleNpcInfoCommandShowFromDB(ChatHandler* handler, ObjectGuid::LowType lowGuid, CreatureData const* cData)
{
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(cData->id1);
if (!cInfo)
{
handler->SendErrorMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowGuid);
return false;
}
handler->PSendSysMessage("(Not in world - showing DB data)");
uint32 scriptId = cData->ScriptId ? cData->ScriptId : cInfo->ScriptID;
handler->PSendSysMessage(LANG_NPCINFO_CHAR, lowGuid, ObjectGuid::Create<HighGuid::Unit>(cData->id1, lowGuid).ToString(), cData->id1,
cData->id2, cData->id3, cData->displayid, cData->displayid, cInfo->faction,
cData->npcflag);
handler->PSendSysMessage(LANG_NPCINFO_PHASEMASK, cData->phaseMask);
handler->PSendSysMessage(LANG_NPCINFO_POSITION, cData->posX, cData->posY, cData->posZ);
handler->PSendSysMessage("Map: {} Spawn time: {}s", cData->mapid,
cData->spawntimesecs);
handler->PSendSysMessage(LANG_NPCINFO_EQUIPMENT, cData->equipmentId, cData->equipmentId);
handler->PSendSysMessage(LANG_NPCINFO_AIINFO, cInfo->AIName,
sObjectMgr->GetScriptName(scriptId));
return true;
}
static bool HandleNpcGuidCommand(ChatHandler* handler)
{
Creature* target = handler->getSelectedCreature();
@@ -40,6 +40,8 @@ enum GameObjects
GO_DOOR_LEVER_2 = 101833,
GO_DOOR_LEVER_3 = 101834,
GO_CANNON = 16398,
GO_FOUNDRY_DOOR = 16399,
GO_MAST_ROOM_DOOR = 16400,
};
template <class AI, class T>
@@ -46,6 +46,8 @@ public:
case GO_DOOR_LEVER_2:
case GO_DOOR_LEVER_3:
case GO_CANNON:
case GO_FOUNDRY_DOOR:
case GO_MAST_ROOM_DOOR:
gameobject->AllowSaveToDB(true);
break;
case GO_FACTORY_DOOR:
@@ -57,9 +59,8 @@ public:
case GO_IRON_CLAD_DOOR:
gameobject->AllowSaveToDB(true);
if (GetStoredGameObjectState(gameobject->GetSpawnId()) == GO_STATE_ACTIVE)
{
gameobject->DespawnOrUnsummon();
}
break;
}
}
@@ -153,7 +153,7 @@ void AddSC_elwynn_forest();
void AddSC_eversong_woods();
void AddSC_ghostlands();
void AddSC_hinterlands();
//void AddSC_ironforge();
void AddSC_ironforge();
void AddSC_isle_of_queldanas();
void AddSC_redridge_mountains();
void AddSC_silverpine_forest();
@@ -305,7 +305,7 @@ void AddEasternKingdomsScripts()
AddSC_eversong_woods();
AddSC_ghostlands();
AddSC_hinterlands();
// AddSC_ironforge();
AddSC_ironforge();
AddSC_isle_of_queldanas();
AddSC_redridge_mountains();
AddSC_silverpine_forest();
@@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CreatureScript.h"
#include "ScriptedCreature.h"
@@ -215,8 +216,29 @@ private:
float _facing;
};
// 16802 - Lor'themar Theron
/// @todo add abilities/timers
struct npc_lor_themar_theron : public ScriptedAI
{
npc_lor_themar_theron(Creature* creature) : ScriptedAI(creature) { }
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
void AddSC_eversong_woods()
{
RegisterCreatureAI(npc_partygoer_pather);
RegisterCreatureAI(npc_partygoer);
RegisterCreatureAI(npc_lor_themar_theron);
}
@@ -0,0 +1,73 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CreatureScript.h"
#include "ScriptedCreature.h"
// 2784 - King Magni Bronzebeard
enum KingMagniBronzebeard
{
SOUND_AGGRO = 5896,
SPELL_AVATAR = 19135,
SPELL_KNOCK_AWAY = 20686,
SPELL_STORM_BOLT = 20685
};
struct npc_king_magni_bronzebeard : public ScriptedAI
{
npc_king_magni_bronzebeard(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
me->PlayDirectSound(SOUND_AGGRO);
ScheduleTimedEvent(5s, 7s, [&]
{
DoCastSelf(SPELL_AVATAR);
}, 25s, 30s);
ScheduleTimedEvent(8s, 10s, [&]
{
DoCastVictim(SPELL_KNOCK_AWAY);
}, 20s, 30s);
ScheduleTimedEvent(12s, 15s, [&]
{
DoCastRandomTarget(SPELL_STORM_BOLT);
}, 15s, 20s);
}
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff,
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
}
};
void AddSC_ironforge()
{
RegisterCreatureAI(npc_king_magni_bronzebeard);
}
@@ -464,13 +464,26 @@ enum KingVarianWrynn : uint32
// Deathknight Starting Zone End
QUEST_WHERE_KINGS_WALK = 13188,
};
class npc_king_varian_wrynn : public CreatureScript
// 29611 - King Varian Wryn
/// @todo add abilities/timers
struct npc_king_varian_wrynn : public ScriptedAI
{
public:
npc_king_varian_wrynn() : CreatureScript("npc_king_varian_wrynn") { }
npc_king_varian_wrynn(Creature* creature) : ScriptedAI(creature) { }
bool OnQuestReward(Player* player, Creature* /*creature*/, Quest const* quest, uint32 /*item*/) override
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
bool OnQuestReward(Player* player, Creature* /*creature*/, Quest const* quest, uint32 /*item*/)
{
if (quest->GetQuestId() == QUEST_WHERE_KINGS_WALK)
@@ -486,5 +499,6 @@ void AddSC_stormwind_city()
new npc_tyrion_spybot();
new npc_lord_gregor_lescovar();
new npc_marzon_silent_blade();
new npc_king_varian_wrynn();
RegisterCreatureAI(npc_king_varian_wrynn);
}
@@ -118,6 +118,11 @@ public:
_events.ScheduleEvent(EVENT_MULTI_SHOT, 10s);
}
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void SetGUID(ObjectGuid const& guid, int32 type) override
{
if (type == GUID_EVENT_INVOKER)
@@ -1402,7 +1402,10 @@ enum chromie
ITEM_ARCANE_DISRUPTOR = 37888,
QUEST_DISPELLING_ILLUSIONS = 13149,
QUEST_A_ROYAL_ESCORT = 13151,
SPELL_SUMMON_ARCANE_DISRUPTOR = 49591
SPELL_SUMMON_ARCANE_DISRUPTOR = 49591,
GOSSIP_MENU_START = 9586,
GOSSIP_MENU_ACTION_MENU_SKIP = 11277,
GOSSIP_MENU_ACTION_INTERFERE = 9595
};
class npc_cos_chromie_start : public CreatureScript
@@ -1410,55 +1413,55 @@ class npc_cos_chromie_start : public CreatureScript
public:
npc_cos_chromie_start() : CreatureScript("npc_cos_chromie_start") { }
bool OnQuestAccept(Player*, Creature* creature, const Quest* pQuest)
bool OnQuestAccept(Player* /*player*/, Creature* creature, const Quest* quest) override
{
if (pQuest->GetQuestId() == QUEST_DISPELLING_ILLUSIONS)
{
if (InstanceScript* pInstance = creature->GetInstanceScript())
{
pInstance->SetData(DATA_SHOW_CRATES, 1);
}
}
if (quest->GetQuestId() == QUEST_DISPELLING_ILLUSIONS)
if (InstanceScript* instance = creature->GetInstanceScript())
instance->SetData(DATA_SHOW_CRATES, 1);
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 /*action*/)
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 /*action*/) override
{
// final menu id, show crates if hidden and add item if missing
if (player->PlayerTalkClass->GetGossipMenu().GetMenuId() == 9595)
switch (player->PlayerTalkClass->GetGossipMenu().GetMenuId())
{
if (InstanceScript* pInstance = creature->GetInstanceScript())
case GOSSIP_MENU_START:
{
if (pInstance->GetData(DATA_ARTHAS_EVENT) == COS_PROGRESS_NOT_STARTED)
{
pInstance->SetData(DATA_SHOW_CRATES, 1);
}
}
if (InstanceScript* instance = creature->GetInstanceScript())
if (instance->GetData(DATA_ARTHAS_EVENT) == COS_PROGRESS_NOT_STARTED)
instance->SetData(DATA_SHOW_CRATES, 1);
if (!player->HasItemCount(ITEM_ARCANE_DISRUPTOR))
{
creature->CastSpell(player, SPELL_SUMMON_ARCANE_DISRUPTOR);
break;
}
}
// Skip Event
else if (player->PlayerTalkClass->GetGossipMenu().GetMenuId() == 11277)
{
if (InstanceScript* pInstance = creature->GetInstanceScript())
case GOSSIP_MENU_ACTION_INTERFERE:
{
if (pInstance->GetData(DATA_ARTHAS_EVENT) == COS_PROGRESS_NOT_STARTED)
if (!player->HasItemCount(ITEM_ARCANE_DISRUPTOR))
creature->CastSpell(player, SPELL_SUMMON_ARCANE_DISRUPTOR);
break;
}
// Since 3.3.3: "Players may now skip the initial introduction dialog to this dungeon once they have completed it at least once."
case GOSSIP_MENU_ACTION_MENU_SKIP:
{
if (InstanceScript* instance = creature->GetInstanceScript())
{
pInstance->SetData(DATA_ARTHAS_EVENT, COS_PROGRESS_FINISHED_INTRO);
if (Creature* arthas = ObjectAccessor::GetCreature(*creature, pInstance->GetGuidData(DATA_ARTHAS)))
if (instance->GetData(DATA_ARTHAS_EVENT) == COS_PROGRESS_NOT_STARTED)
{
arthas->AI()->Reset();
instance->SetData(DATA_ARTHAS_EVENT, COS_PROGRESS_FINISHED_INTRO);
if (Creature* arthas = ObjectAccessor::GetCreature(*creature, instance->GetGuidData(DATA_ARTHAS)))
arthas->AI()->Reset();
}
player->NearTeleportTo(LeaderIntroPos2.GetPositionX(), LeaderIntroPos2.GetPositionY(), LeaderIntroPos2.GetPositionZ(), LeaderIntroPos2.GetOrientation());
}
player->NearTeleportTo(LeaderIntroPos2.GetPositionX(), LeaderIntroPos2.GetPositionY(), LeaderIntroPos2.GetPositionZ(), LeaderIntroPos2.GetOrientation());
break;
}
default:
break;
}
// return false to display last windows
return false;
}
};
@@ -1483,7 +1486,7 @@ public:
if (!creature->GetInstanceScript() || creature->GetInstanceScript()->GetData(DATA_ARTHAS_EVENT) != COS_PROGRESS_CRATES_FOUND)
return true;
// We can start event:)
// "Well, you're not going to sign recruitment papers or anything, but you are going to fight alongside him. ..."
if (player->PlayerTalkClass->GetGossipMenu().GetMenuId() == 9612)
creature->GetInstanceScript()->SetData(DATA_ARTHAS_EVENT, COS_PROGRESS_START_INTRO);
@@ -34,6 +34,8 @@ enum Data
DATA_START_WAVES,
DATA_SHOW_INFINITE_TIMER,
DATA_ARTHAS_REPOSITION,
DATA_INTRO_EVENT_FINISHED,
};
enum Data64
@@ -188,6 +188,8 @@ public:
return _encounterState;
case DATA_GUARDIANTIME_EVENT:
return _guardianTimer;
case DATA_INTRO_EVENT_FINISHED:
return _encounterState >= COS_PROGRESS_FINISHED_INTRO ? 1 : 0;
}
return 0;
}
@@ -88,6 +88,7 @@ void AddSC_orgrimmar();
void AddSC_silithus();
void AddSC_stonetalon_mountains();
void AddSC_tanaris();
void AddSC_teldrassil();
void AddSC_the_barrens();
void AddSC_thousand_needles();
void AddSC_thunder_bluff();
@@ -170,6 +171,7 @@ void AddKalimdorScripts()
AddSC_silithus();
AddSC_stonetalon_mountains();
AddSC_tanaris();
AddSC_teldrassil();
AddSC_the_barrens();
AddSC_thousand_needles();
AddSC_thunder_bluff();
@@ -559,6 +559,31 @@ public:
}
};
// 7999 - Tyrande Whisperwind
/// @todo add abilities/timers
struct npc_prophet_velen : public ScriptedAI
{
npc_prophet_velen(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
me->setActive(true);
}
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
void AddSC_azuremyst_isle()
{
new npc_draenei_survivor();
@@ -569,4 +594,5 @@ void AddSC_azuremyst_isle()
new npc_stillpine_capitive();
new go_bristlelimb_cage();
RegisterSpellScript(spell_inoculate_nestlewood_owlkin);
RegisterCreatureAI(npc_prophet_velen);
}
@@ -234,6 +234,11 @@ public:
void JustEngagedWith(Unit* /*who*/) override { }
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void DoAction(int32 action) override
{
if (action == ACTION_START_TALKING)
@@ -0,0 +1,44 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CreatureScript.h"
#include "ScriptedCreature.h"
// 7999 - Tyrande Whisperwind
/// @todo add abilities/timers
struct npc_tyrande_whisperwind : public ScriptedAI
{
npc_tyrande_whisperwind(Creature* creature) : ScriptedAI(creature) { }
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
void AddSC_teldrassil()
{
RegisterCreatureAI(npc_tyrande_whisperwind);
}
@@ -19,10 +19,6 @@
#include "Player.h"
#include "ScriptedCreature.h"
/*#####
# Support for Quest 925: Cairne's Hoofprint
######*/
// NPC 3057: Cairne Bloodhoof <High Chieftain>
enum CairneBloodhoof
{
@@ -34,7 +30,7 @@ enum CairneBloodhoof
SPELL_CAIRNES_HOOFPRINT = 23123
};
// @todo verify abilities/timers
/// @todo verify abilities/timers
class npc_cairne_bloodhoof : public CreatureScript
{
public:
@@ -61,12 +57,15 @@ public:
}
}
void JustDied(Unit* /*killer*/) override
{
DoRewardPlayersInArea();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
if (_berserkerChargeTimer <= diff)
{
@@ -121,23 +121,30 @@ enum Misc
POINT_CHANNEL_STEELBREAKER = 1
};
static uint8 CountAliveBosses(InstanceScript* instance)
{
uint8 count = 0;
if (!instance)
return count;
for (uint8 i = 0; i < 3; ++i)
if (Creature* boss = instance->GetCreature(DATA_STEELBREAKER + i))
if (boss->IsAlive())
++count;
return count;
}
bool IsEncounterComplete(InstanceScript* pInstance, Creature* me)
{
if (!pInstance || !me)
return false;
for (uint8 i = 0; i < 3; ++i)
{
if (Creature* boss = pInstance->GetCreature(DATA_STEELBREAKER + i))
{
if (boss->IsAlive())
return false;
continue;
}
else
if (!pInstance->GetCreature(DATA_STEELBREAKER + i))
return false;
}
return true;
return CountAliveBosses(pInstance) == 0;
}
void RespawnAssemblyOfIron(InstanceScript* pInstance, Creature* me)
@@ -550,6 +557,7 @@ struct boss_stormcaller_brundir : public ScriptedAI
void Reset() override
{
SetInvincibility(false);
me->SetLootMode(0);
RespawnAssemblyOfIron(pInstance, me);
@@ -667,6 +675,26 @@ struct boss_stormcaller_brundir : public ScriptedAI
me->CastSpell(me, SPELL_LIGHTNING_CHANNEL_PRE, true);
}
void OnSpellCast(SpellInfo const* spellInfo) override
{
// When Overload begins, prevent Brundir from dying unless he is the last boss alive
if (spellInfo->Id == SPELL_OVERLOAD && CountAliveBosses(pInstance) > 1)
SetInvincibility(true);
}
void OnChannelFinished(SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_OVERLOAD)
SetInvincibility(false);
}
void OnSpellFailed(SpellInfo const* spellInfo) override
{
// Also lift invincibility if the channel is somehow interrupted
if (spellInfo->Id == SPELL_OVERLOAD)
SetInvincibility(false);
}
void UpdateAI(uint32 diff) override
{
if (!me->IsInCombat() && me->GetReactState() == REACT_AGGRESSIVE)

Some files were not shown because too many files have changed in this diff Show More