From d99285ed2650ca0e986bd814994d6721a3999dc5 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:29:29 -0300 Subject: [PATCH 01/33] fix(DB/Creature): Fix Flamestrike inhabit types (#21249) --- .../updates/pending_db_world/rev_1737641541738329200.sql | 2 ++ .../MagistersTerrace/boss_felblood_kaelthas.cpp | 6 ------ 2 files changed, 2 insertions(+), 6 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1737641541738329200.sql diff --git a/data/sql/updates/pending_db_world/rev_1737641541738329200.sql b/data/sql/updates/pending_db_world/rev_1737641541738329200.sql new file mode 100644 index 000000000..2bb6032ed --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1737641541738329200.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template_movement` SET `Rooted`= 1, `Flight` = 1 WHERE `CreatureId` = 24666; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 110fd2c41..cb26548c4 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -101,12 +101,6 @@ struct boss_felblood_kaelthas : public BossAI }); } - void JustSummoned(Creature* summon) override - { - BossAI::JustSummoned(summon); - summon->SetReactState(REACT_PASSIVE); - } - void GravityLapseSequence(bool firstTime) { Talk(firstTime ? SAY_GRAVITY_LAPSE : SAY_RECAST_GRAVITY); From a13c2ff55f530901838744eef0999942a7a6bde9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 23 Jan 2025 17:30:31 +0000 Subject: [PATCH 02/33] chore(DB): import pending files Referenced commit(s): d99285ed2650ca0e986bd814994d6721a3999dc5 --- .../rev_1737641541738329200.sql => db_world/2025_01_23_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1737641541738329200.sql => db_world/2025_01_23_04.sql} (68%) diff --git a/data/sql/updates/pending_db_world/rev_1737641541738329200.sql b/data/sql/updates/db_world/2025_01_23_04.sql similarity index 68% rename from data/sql/updates/pending_db_world/rev_1737641541738329200.sql rename to data/sql/updates/db_world/2025_01_23_04.sql index 2bb6032ed..42396e60d 100644 --- a/data/sql/updates/pending_db_world/rev_1737641541738329200.sql +++ b/data/sql/updates/db_world/2025_01_23_04.sql @@ -1,2 +1,3 @@ +-- DB update 2025_01_23_03 -> 2025_01_23_04 -- UPDATE `creature_template_movement` SET `Rooted`= 1, `Flight` = 1 WHERE `CreatureId` = 24666; From c08a1eefff080189e30948554e96509f53663830 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:44:54 -0300 Subject: [PATCH 03/33] fix(Scripts/MagisterTerrace): Fix Phoenixes and eggs not despawning (#21260) --- .../MagistersTerrace/boss_felblood_kaelthas.cpp | 1 - .../EasternKingdoms/MagistersTerrace/magisters_terrace.h | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index cb26548c4..88eb14b6f 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -79,7 +79,6 @@ struct boss_felblood_kaelthas : public BossAI _gravityLapseCounter = 0; me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); me->SetImmuneToAll(false); - summons.DespawnAll(); ScheduleHealthCheckEvent(50, [&]{ me->CastStop(); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h index 933c6758d..44d66b8cf 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h @@ -40,8 +40,8 @@ enum MTCreatures NPC_DELRISSA = 24560, NPC_FEL_CRYSTAL = 24722, NPC_KAEL_THAS = 24664, - NPC_PHOENIX = 21362, - NPC_PHOENIX_EGG = 21364, + NPC_PHOENIX = 24674, + NPC_PHOENIX_EGG = 24675, NPC_KALECGOS = 24844 }; From c54de87645ea5ff9bdfe441d71a403b1836d2bd1 Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Fri, 24 Jan 2025 18:47:48 +0000 Subject: [PATCH 04/33] fix(DB/Loot) Clean up loot of bosses in MGT HC (#21262) --- .../rev_1737730013774604750.sql | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1737730013774604750.sql diff --git a/data/sql/updates/pending_db_world/rev_1737730013774604750.sql b/data/sql/updates/pending_db_world/rev_1737730013774604750.sql new file mode 100644 index 000000000..659f785e4 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1737730013774604750.sql @@ -0,0 +1,21 @@ +-- Fix Kaelthas HC +DELETE FROM `creature_loot_template` WHERE (`Entry` = 24857) AND (`Item` IN (23572, 25028, 25029, 34609, 34610, 34611, 34612, 34613, 34614, 34615, 34616)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(24857, 23572, 0, 100, 0, 1, 0, 1, 1, 'Kael\'thas Sunstrider (1) - Primal Nether'), +(24857, 34612, 0, 0, 0, 1, 1, 1, 1, 'Kael\'thas Sunstrider (1) - Greaves of the Penitent Knight'), +(24857, 34609, 0, 0, 0, 1, 1, 1, 1, 'Kael\'thas Sunstrider (1) - Quickening Blade of the Prince'), +(24857, 34611, 0, 0, 0, 1, 1, 1, 1, 'Kael\'thas Sunstrider (1) - Cudgel of Consecration'), +(24857, 34610, 0, 0, 0, 1, 1, 1, 1, 'Kael\'thas Sunstrider (1) - Scarlet Sin\'dorei Robes'), +(24857, 34614, 0, 0, 0, 1, 2, 1, 1, 'Kael\'thas Sunstrider (1) - Tunic of the Ranger Lord'), +(24857, 34615, 0, 0, 0, 1, 2, 1, 1, 'Kael\'thas Sunstrider (1) - Netherforce Chestplate'), +(24857, 34616, 0, 0, 0, 1, 2, 1, 1, 'Kael\'thas Sunstrider (1) - Breeching Comet'), +(24857, 34613, 0, 0, 0, 1, 2, 1, 1, 'Kael\'thas Sunstrider (1) - Shoulderpads of the Silvermoon Retainer'); + +-- Remove normal loot from Delrissa HC +DELETE FROM `creature_loot_template` WHERE (`Entry` = 25560) AND (`Item` IN (25027)); + +-- Remove normal loot from Vexallus HC +DELETE FROM `creature_loot_template` WHERE (`Entry` = 25573) AND (`Item` IN (25026)); + +-- Remove normal loot from Selin Fireheart HC +DELETE FROM `creature_loot_template` WHERE (`Entry` = 25562) AND (`Item` IN (25025)); From dcf097aa09ea3fdfbf409b0dea9258a81974c02c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jan 2025 18:48:48 +0000 Subject: [PATCH 05/33] chore(DB): import pending files Referenced commit(s): c54de87645ea5ff9bdfe441d71a403b1836d2bd1 --- .../rev_1737730013774604750.sql => db_world/2025_01_24_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1737730013774604750.sql => db_world/2025_01_24_00.sql} (97%) diff --git a/data/sql/updates/pending_db_world/rev_1737730013774604750.sql b/data/sql/updates/db_world/2025_01_24_00.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_1737730013774604750.sql rename to data/sql/updates/db_world/2025_01_24_00.sql index 659f785e4..52974735b 100644 --- a/data/sql/updates/pending_db_world/rev_1737730013774604750.sql +++ b/data/sql/updates/db_world/2025_01_24_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_23_04 -> 2025_01_24_00 -- Fix Kaelthas HC DELETE FROM `creature_loot_template` WHERE (`Entry` = 24857) AND (`Item` IN (23572, 25028, 25029, 34609, 34610, 34611, 34612, 34613, 34614, 34615, 34616)); INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES From d3cdd2fbf7b09c5f007049ab2de063b290d133f7 Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Fri, 24 Jan 2025 23:37:23 +0100 Subject: [PATCH 06/33] fix(DB/Gameobject): remove extra Sanctum Planetarium (#21251) --- data/sql/updates/pending_db_world/rev_1737663383081239503.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1737663383081239503.sql diff --git a/data/sql/updates/pending_db_world/rev_1737663383081239503.sql b/data/sql/updates/pending_db_world/rev_1737663383081239503.sql new file mode 100644 index 000000000..96d7481f9 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1737663383081239503.sql @@ -0,0 +1,3 @@ +-- +-- Remove extra Sanctum Planetarium +DELETE FROM `gameobject` WHERE (`id` = 188081) AND (`guid` IN (27809)); From f692ae9003a531e7949c528ac5e4429e66bea88b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jan 2025 22:38:22 +0000 Subject: [PATCH 07/33] chore(DB): import pending files Referenced commit(s): d3cdd2fbf7b09c5f007049ab2de063b290d133f7 --- .../rev_1737663383081239503.sql => db_world/2025_01_24_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1737663383081239503.sql => db_world/2025_01_24_01.sql} (71%) diff --git a/data/sql/updates/pending_db_world/rev_1737663383081239503.sql b/data/sql/updates/db_world/2025_01_24_01.sql similarity index 71% rename from data/sql/updates/pending_db_world/rev_1737663383081239503.sql rename to data/sql/updates/db_world/2025_01_24_01.sql index 96d7481f9..a10c9cde7 100644 --- a/data/sql/updates/pending_db_world/rev_1737663383081239503.sql +++ b/data/sql/updates/db_world/2025_01_24_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_24_00 -> 2025_01_24_01 -- -- Remove extra Sanctum Planetarium DELETE FROM `gameobject` WHERE (`id` = 188081) AND (`guid` IN (27809)); From b47ec3b5c8a412ef4be24a670825ace95b0635c2 Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Sat, 25 Jan 2025 19:58:01 +0100 Subject: [PATCH 08/33] fix(Apps/Codestyle): ignore comments for some checks (#21268) --- apps/codestyle/codestyle-sql.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/codestyle/codestyle-sql.py b/apps/codestyle/codestyle-sql.py index f15dceed6..0df5dec05 100644 --- a/apps/codestyle/codestyle-sql.py +++ b/apps/codestyle/codestyle-sql.py @@ -112,7 +112,7 @@ def sql_check(file: io, file_path: str) -> None: check_failed = True if "EntryOrGuid" in line: print( - f"Please use entryorguid syntax instead of EntryOrgGuid in {file_path} at line {line_number}\nWe recommend to use keira to have the right syntax in auto-query generation") + f"Please use entryorguid syntax instead of EntryOrGuid in {file_path} at line {line_number}\nWe recommend to use keira to have the right syntax in auto-query generation") check_failed = True if [match for match in [';;'] if match in line]: print( @@ -142,6 +142,8 @@ def insert_safety_check(file: io, file_path: str) -> None: # Parse all the file for line_number, line in enumerate(file, start = 1): + if line.startswith("--"): + continue if "INSERT" in line and "DELETE" not in previous_line: print(f"No DELETE keyword found after the INSERT in {file_path} at line {line_number}\nIf this error is intended, please advert a maintainer") check_failed = True @@ -163,7 +165,11 @@ def semicolon_check(file: io, file_path: str) -> None: total_lines = len(lines) for line_number, line in enumerate(lines, start=1): - stripped_line = line.rstrip() # Remove trailing whitespace including newline + if line.startswith('--'): + continue + # Remove trailing whitespace including newline + # Remove comments from the line + stripped_line = line.split('--', 1)[0].strip() # Check if one keyword is in the line if not query_open and any(keyword in stripped_line for keyword in sql_keywords): From f42019574b9595a69317894ee4df12fe337e9cc4 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 25 Jan 2025 17:50:08 -0300 Subject: [PATCH 09/33] fix(DB/SAI): Correct Phoenix/Egg rebirth and combat behaviour (#21261) --- .../rev_1737721489253815600.sql | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1737721489253815600.sql diff --git a/data/sql/updates/pending_db_world/rev_1737721489253815600.sql b/data/sql/updates/pending_db_world/rev_1737721489253815600.sql new file mode 100644 index 000000000..c53b37e20 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1737721489253815600.sql @@ -0,0 +1,25 @@ +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24674); +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 +(24674, 0, 0, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 44196, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Initialize - Cast \'Rebirth\''), +(24674, 0, 1, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 42, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Reset - Set Invincibility Hp 5%'), +(24674, 0, 2, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 44197, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Aggro - Cast \'Burn\''), +(24674, 0, 3, 0, 24, 0, 100, 0, 44226, 1, 5000, 5000, 0, 0, 11, 44202, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Target Buffed With \'Gravity Lapse\' - Cast \'Fireball\''), +(24674, 0, 4, 5, 2, 0, 100, 0, 0, 5, 10000, 10000, 0, 0, 11, 44199, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - Between 0-5% Health - Cast \'Ember Blast\''), +(24674, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 12, 24675, 3, 20000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - Between 0-5% Health - Summon Creature \'Phoenix Egg\''), +(24674, 0, 6, 7, 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, 'Phoenix - Between 0-5% Health - Set Reactstate Passive'), +(24674, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - Between 0-5% Health - Stop Combat'), +(24674, 0, 8, 9, 8, 0, 100, 0, 44199, 0, 0, 0, 0, 0, 28, 44197, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Spellhit \'Ember Blast\' - Remove Aura \'Burn\''), +(24674, 0, 9, 10, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Spellhit \'Ember Blast\' - Set Visibility Off'), +(24674, 0, 10, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 204, 24675, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Spellhit \'Ember Blast\' - Despawn Instant'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24675); +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 +(24675, 0, 0, 0, 37, 0, 100, 512, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Initialize - Set Reactstate Passive'), +(24675, 0, 1, 2, 60, 0, 100, 0, 15000, 15000, 0, 0, 0, 0, 142, 100, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Update - Set HP to 100%'), +(24675, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 44199, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Update - Remove Aura \'Ember Blast\''), +(24675, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Update - Set Reactstate Aggressive'), +(24675, 0, 4, 5, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Update - Set In Combat With Zone'), +(24675, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Update - Set Visibility On'), +(24675, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Update - Despawn Instant'), +(24675, 0, 8, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 3000, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix Egg - On Just Died - Despawn In 3000 ms'); From 1acd652105f4e6c294bf29016d4e4dfde3dcd0eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 25 Jan 2025 20:51:07 +0000 Subject: [PATCH 10/33] chore(DB): import pending files Referenced commit(s): f42019574b9595a69317894ee4df12fe337e9cc4 --- .../rev_1737721489253815600.sql => db_world/2025_01_25_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1737721489253815600.sql => db_world/2025_01_25_00.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1737721489253815600.sql b/data/sql/updates/db_world/2025_01_25_00.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1737721489253815600.sql rename to data/sql/updates/db_world/2025_01_25_00.sql index c53b37e20..407ab7011 100644 --- a/data/sql/updates/pending_db_world/rev_1737721489253815600.sql +++ b/data/sql/updates/db_world/2025_01_25_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_24_01 -> 2025_01_25_00 -- DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24674); 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 From d2500e8cb7c4b77ae333f4afb39056198b8a0ed9 Mon Sep 17 00:00:00 2001 From: skelUA Date: Sat, 25 Jan 2025 23:04:01 +0200 Subject: [PATCH 11/33] fix(Core/Auction): Fix usable item search in auction (#21267) --- src/server/game/Handlers/AuctionHouseHandler.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index d450a3db4..505ad62d6 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -749,6 +749,9 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData) if (usable) { AuctionHouseUsablePlayerInfo usablePlayerInfo; + usablePlayerInfo.classMask = GetPlayer()->getClassMask(); + usablePlayerInfo.raceMask = GetPlayer()->getRaceMask(); + usablePlayerInfo.level = GetPlayer()->GetLevel(); SkillStatusMap const& skillMap = GetPlayer()->GetSkillStatusMap(); for (auto const& pair : skillMap) From d297030a086eb61ad55ff3c62a7b48e2664eb931 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sat, 25 Jan 2025 16:06:21 -0600 Subject: [PATCH 12/33] fix(Scripts/BlackTemple): Fix Gurtogg will not use acidic wound in phase 2 (#21253) --- src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp index 0b033334c..902b72d1e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp @@ -61,7 +61,6 @@ enum Spells enum Misc { EVENT_SPELL_BERSERK = 1, - GROUP_DELAY = 1 }; @@ -103,6 +102,7 @@ struct boss_gurtogg_bloodboil : public BossAI if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 40.0f, true)) { me->RemoveAurasByType(SPELL_AURA_MOD_TAUNT); + me->RemoveAurasDueToSpell(SPELL_ACIDIC_WOUND); DoCastSelf(SPELL_FEL_RAGE_SELF, true); DoCast(target, SPELL_FEL_RAGE_TARGET, true); DoCast(target, SPELL_FEL_RAGE_2, true); @@ -118,6 +118,10 @@ struct boss_gurtogg_bloodboil : public BossAI DoCastVictim(SPELL_CHARGE); }, 2s); + me->m_Events.AddEventAtOffset([&] { + DoCastSelf(SPELL_ACIDIC_WOUND, true); + }, 28s); + scheduler.DelayGroup(GROUP_DELAY, 30s); } }, 90s); @@ -139,7 +143,7 @@ struct boss_gurtogg_bloodboil : public BossAI return !who->IsImmunedToDamage(SPELL_SCHOOL_MASK_ALL) && !who->HasUnitState(UNIT_STATE_CONFUSED); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* /*victim*/) override { if (!_recentlySpoken) { From 778742749a01bcfbe7573ea1109228776c039a1e Mon Sep 17 00:00:00 2001 From: Ryan Turner Date: Sun, 26 Jan 2025 07:20:03 +0000 Subject: [PATCH 13/33] SECURITY.md File Update (#20190) --- .github/SECURITY.md | 109 ++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 39 deletions(-) diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 7feca2632..00d09000e 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -4,60 +4,91 @@ We support the following versions of dependencies. -:white_check_mark: = supported +| Icon | Meaning | +| :------------------- | :---------------: | +| :white_check_mark: | **Supported** | +| :red_circle: | **NOT** Supported | +| :large_blue_diamond: | **Recommended** | -:red_circle: = NOT supported +### Versions of AzerothCore: -unspecified = might work but no guarantee +| AzerothCore Branch | Status | Recommended | +| ---------------------------- | :----------------: | :------------------: | +| **master** | :white_check_mark: | :large_blue_diamond: | +| Any non-official fork | :red_circle: | | +| Any Playerbots fork | :red_circle: | | +| Any NPCBots fork | :red_circle: | | +| Any AC (non-official) repack | :red_circle: | | -Versions of AzerothCore: +### Supported Operating Systems -| AzerothCore Branch | Supported | -| ------------------ | ------------------ | -| master | :white_check_mark: | -| Any playerbot fork | :red_circle: | -| Any NPCBot fork | :red_circle: | +| Linux (Ubuntu) | Status | Recommended | +| :------------- | :----------------: | :------------------: | +| 24.04 | :white_check_mark: | :large_blue_diamond: | +| 22.04 | :white_check_mark: | | +| 20.04 ≤ | :red_circle: | | -Versions of MySQL: +| macOS | Status | Recommended | +| :---- | :----------------: | :------------------: | +| 14 | :white_check_mark: | :large_blue_diamond: | +| 12 ≤ | :red_circle: | | -| MySQL Version | Supported | -| ------------- | ------------------ | -| 8.4 | :white_check_mark: | -| 8.0 | :white_check_mark: | -| 5.7 and lower | :red_circle: | +| Windows | Status | Recommended | +| :------------ | :----------------: | :------------------: | +| Windows 11 | :white_check_mark: | :large_blue_diamond: | +| Windows 10 | :white_check_mark: | +| Windows 8.1 ≤ | :red_circle: | -Versions of CLang: +
-| CLang Version | Supported | -| ------------- | ------------------ | -| 18 | :white_check_mark: | -| 15 | :white_check_mark: | -| 14 and lower | :red_circle: | +### Supported Boost Versions: -Versions of GCC: +| Boost | Status | Recommended | +| :----- | :----------------: | :------------------: | +| 1.70 ≥ | :white_check_mark: | :large_blue_diamond: | -| GCC Version | Supported | -| ------------ | ------------------ | -| 14 | :white_check_mark: | -| 12 | :white_check_mark: | -| 11 and lower | :red_circle: | +### Supported OpenSSL Versions: -Versions of Ubuntu: +| OpenSSL | Status | Recommended | +| :------ | :----------------: | :------------------: | +| 3.X.X ≥ | :white_check_mark: | :large_blue_diamond: | -| Ubuntu version | Supported | -| --------------- | ------------------ | -| 24.04 | :white_check_mark: | -| 22.04 | :white_check_mark: | -| 20.04 and lower | :red_circle: | +### Supported CMake Versions: -Versions of macOS: +| CMake | Status | Recommended | +| :----- | :----------------: | :------------------: | +| 3.16 ≥ | :white_check_mark: | :large_blue_diamond: | -| macOS Version | Supported | -| ------------- | ------------------ | -| 14 | :white_check_mark: | -| 12 and lower | :red_circle: | +### Supported MySQL Versions: -**Note**: We do NOT support any repacks that may or may not have been made based on AzerothCore. This is because they are usually based on older versions and there is no way to know what is in the precompiled binaries. Instead, you should compile your binaries from the AzerothCore source. To get started, read the [Installation Guide](https://www.azerothcore.org/wiki/installation). +| MySQL | Status | Recommended | +| :---- | :----------------: | :------------------: | +| 8.4 ≥ | :white_check_mark: | :large_blue_diamond: | +| 8.0 | :white_check_mark: | | +| 8.1 | :red_circle: | | +| 8.0 < | :red_circle: | | + +### Supported CLang Versions: + +| CLang | Status | Recommended | +| :---- | :----------------: | :------------------: | +| 18 | :white_check_mark: | :large_blue_diamond: | +| 15 | :white_check_mark: | | +| 14 ≤ | :red_circle: | | + +### Supported GCC Versions: + +| GCC | Status | Recommended | +| :--- | :----------------: | :------------------: | +| 14 | :white_check_mark: | :large_blue_diamond: | +| 12 | :white_check_mark: | | +| 11 ≤ | :red_circle: | | + +> [!NOTE] +> We do **NOT** support any repacks that may or may not have been made based on AzerothCore. This is because they are usually based on older versions and there is no way to know what is in the precompiled binaries. Instead, you should compile your binaries from the AzerothCore source. To get started, read the [Installation Guide](https://www.azerothcore.org/wiki/installation). + +> [!CAUTION] +> [Why you should not use repacks to run your WoW server](https://www.mangosrumors.org/why-you-should-not-use-repacks-to-run-your-wow-server/) ## Reporting a Vulnerability From a74e06c27c592bbd9b4203fbb68c4a425ceff0be Mon Sep 17 00:00:00 2001 From: Exitare Date: Sun, 26 Jan 2025 00:37:32 -0800 Subject: [PATCH 14/33] feat(Core/Autobroacast): Add autobroadcast locale (#20946) --- .../rev_1734400454914932600.sql | 11 ++ .../Database/Implementation/LoginDatabase.cpp | 1 + .../Database/Implementation/LoginDatabase.h | 1 + .../game/Autobroadcast/AutobroadcastMgr.cpp | 116 ++++++++++++++---- .../game/Autobroadcast/AutobroadcastMgr.h | 12 +- src/server/game/World/World.cpp | 1 + 6 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 data/sql/updates/pending_db_auth/rev_1734400454914932600.sql diff --git a/data/sql/updates/pending_db_auth/rev_1734400454914932600.sql b/data/sql/updates/pending_db_auth/rev_1734400454914932600.sql new file mode 100644 index 000000000..5018ad411 --- /dev/null +++ b/data/sql/updates/pending_db_auth/rev_1734400454914932600.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS `autobroadcast_locale`; +CREATE TABLE `autobroadcast_locale` ( + `realmid` INT NOT NULL, + `id` INT NOT NULL, + `locale` VARCHAR(4) NOT NULL, + `text` VARCHAR(45) NULL, + PRIMARY KEY (`realmid`, `id`)) +CHARSET = utf8mb4 +COLLATE = utf8mb4_unicode_ci +ENGINE = InnoDB +; diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index 51eb7d8ec..019e11c8d 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -115,6 +115,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_AUTOBROADCAST, "SELECT id, weight, text FROM autobroadcast WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_AUTOBROADCAST_LOCALIZED, "SELECT id, locale, text FROM autobroadcast_locale WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_MOTD, "SELECT text FROM motd WHERE realmid = ? OR realmid = -1 ORDER BY realmid DESC", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_MOTD_LOCALE, "SELECT locale, text FROM motd_localized WHERE realmid = ? OR realmid = -1 ORDER BY realmid DESC", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_MOTD, "INSERT INTO motd (realmid, text) VALUES (?, ?) ON DUPLICATE KEY UPDATE text = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index f6791ac80..1c859695c 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -97,6 +97,7 @@ enum LoginDatabaseStatements : uint32 LOGIN_SEL_REALMLIST_SECURITY_LEVEL, LOGIN_DEL_ACCOUNT, LOGIN_SEL_AUTOBROADCAST, + LOGIN_SEL_AUTOBROADCAST_LOCALIZED, LOGIN_SEL_MOTD, LOGIN_SEL_MOTD_LOCALE, LOGIN_INS_MOTD, diff --git a/src/server/game/Autobroadcast/AutobroadcastMgr.cpp b/src/server/game/Autobroadcast/AutobroadcastMgr.cpp index 8b31bf893..a7756c658 100644 --- a/src/server/game/Autobroadcast/AutobroadcastMgr.cpp +++ b/src/server/game/Autobroadcast/AutobroadcastMgr.cpp @@ -42,7 +42,6 @@ void AutobroadcastMgr::LoadAutobroadcasts() if (!result) { LOG_WARN("autobroadcast", ">> Loaded 0 autobroadcasts definitions. DB table `autobroadcast` is empty for this realm!"); - LOG_INFO("autobroadcast", " "); return; } @@ -54,35 +53,66 @@ void AutobroadcastMgr::LoadAutobroadcasts() _announceType = AnnounceType::World; } - uint32 count = 0; + do + { + Field* fields = result->Fetch(); + uint8 textId = fields[0].Get(); + + ObjectMgr::AddLocaleString(fields[2].Get(), DEFAULT_LOCALE, _autobroadcasts[textId]); + _autobroadcastsWeights[textId] = fields[1].Get(); + + } while (result->NextRow()); + + LOG_INFO("server.loading", ">> Loaded {} Autobroadcast Definitions in {} ms", _autobroadcasts.size(), GetMSTimeDiffToNow(oldMSTime)); +} + +void AutobroadcastMgr::LoadAutobroadcastsLocalized() +{ + uint32 oldMSTime = getMSTime(); + uint32 realmId = sConfigMgr->GetOption("RealmID", 0); + + if (_autobroadcasts.empty()) + return; + + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_AUTOBROADCAST_LOCALIZED); + stmt->SetData(0, realmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) + { + LOG_WARN("server.loading", ">> Loaded 0 localized autobroadcasts definitions. DB table `autobroadcast_localized` is empty for this realm!"); + LOG_INFO("server.loading", " "); + return; + } + + uint8 count = 0; do { Field* fields = result->Fetch(); - uint8 id = fields[0].Get(); + uint8 textId = fields[0].Get(); + LocaleConstant locale = GetLocaleByName(fields[1].Get()); - _autobroadcasts[id] = fields[2].Get(); - _autobroadcastsWeights[id] = fields[1].Get(); + if (locale == DEFAULT_LOCALE || ObjectMgr::GetLocaleString(_autobroadcasts[textId], DEFAULT_LOCALE).empty()) + continue; - ++count; + ObjectMgr::AddLocaleString(fields[2].Get(), locale, _autobroadcasts[textId]); + count++; } while (result->NextRow()); - LOG_INFO("autobroadcast", ">> Loaded {} Autobroadcast Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); - LOG_INFO("autobroadcast", " "); + LOG_INFO("server.loading", ">> Loaded {} Localized Autobroadcast Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); } void AutobroadcastMgr::SendAutobroadcasts() { if (_autobroadcasts.empty()) - { return; - } uint32 weight = 0; + uint8 textId = 0; AutobroadcastsWeightMap selectionWeights; - std::string msg; - for (AutobroadcastsWeightMap::const_iterator it = _autobroadcastsWeights.begin(); it != _autobroadcastsWeights.end(); ++it) { if (it->second) @@ -101,42 +131,78 @@ void AutobroadcastMgr::SendAutobroadcasts() weight += it->second; if (selectedWeight < weight) { - msg = _autobroadcasts[it->first]; + textId = it->first; break; } } } else { - msg = _autobroadcasts[urand(0, _autobroadcasts.size())]; + textId = urand(0, _autobroadcasts.size()); } switch (_announceType) { case AnnounceType::World: - SendWorldAnnouncement(msg); + SendWorldAnnouncement(textId); break; case AnnounceType::Notification: - SendNotificationAnnouncement(msg); + SendNotificationAnnouncement(textId); break; case AnnounceType::Both: - SendWorldAnnouncement(msg); - SendNotificationAnnouncement(msg); + SendWorldAnnouncement(textId); + SendNotificationAnnouncement(textId); default: break; } - LOG_DEBUG("autobroadcast", "AutobroadcastMgr::SendAutobroadcasts: '{}'", msg); + LOG_DEBUG("autobroadcast", "AutobroadcastMgr::SendAutobroadcasts: '{}'", textId); } -void AutobroadcastMgr::SendWorldAnnouncement(std::string msg) +void AutobroadcastMgr::SendWorldAnnouncement(uint8 textId) { - ChatHandler(nullptr).SendWorldTextOptional(LANG_AUTO_BROADCAST, ANNOUNCER_FLAG_DISABLE_AUTOBROADCAST, msg.data()); + // Send localized messages to all sessions + ChatHandler(nullptr).DoForAllValidSessions([&](Player* player) + { + // Get player's locale + LocaleConstant locale = player->GetSession()->GetSessionDbLocaleIndex(); + + if (!_autobroadcasts.empty()) + return; + + std::string_view localizedMessage = ObjectMgr::GetLocaleString(_autobroadcasts[textId], locale); + + // Check if there is a localized message if not use default one. + if (localizedMessage.empty()) + localizedMessage = ObjectMgr::GetLocaleString(_autobroadcasts[textId], DEFAULT_LOCALE); + + // Send the localized or fallback message + ChatHandler(player->GetSession()).SendWorldTextOptional(localizedMessage, ANNOUNCER_FLAG_DISABLE_AUTOBROADCAST); + }); } -void AutobroadcastMgr::SendNotificationAnnouncement(std::string msg) +void AutobroadcastMgr::SendNotificationAnnouncement(uint8 textId) { - WorldPacket data(SMSG_NOTIFICATION, (msg.size() + 1)); - data << msg.data(); - sWorld->SendGlobalMessage(&data); + ChatHandler(nullptr).DoForAllValidSessions([&](Player* player) + { + // Retrieve player's locale + LocaleConstant locale = player->GetSession()->GetSessionDbLocaleIndex(); + + if (!_autobroadcasts.count(textId)) + return; + + // Get localized message + std::string_view localizedMessage = ObjectMgr::GetLocaleString(_autobroadcasts[textId], locale); + + // Check if there is a localized message if not use default one. + if (localizedMessage.empty()) + localizedMessage = ObjectMgr::GetLocaleString(_autobroadcasts[textId], DEFAULT_LOCALE); + + // Prepare the WorldPacket + WorldPacket data(SMSG_NOTIFICATION, (localizedMessage.size() + 1)); + data << localizedMessage; + + // Send packet to the player + player->GetSession()->SendPacket(&data); + }); } diff --git a/src/server/game/Autobroadcast/AutobroadcastMgr.h b/src/server/game/Autobroadcast/AutobroadcastMgr.h index 3f4066e91..05dc6319e 100644 --- a/src/server/game/Autobroadcast/AutobroadcastMgr.h +++ b/src/server/game/Autobroadcast/AutobroadcastMgr.h @@ -20,6 +20,7 @@ #include "Common.h" #include +#include enum class AnnounceType : uint8 { @@ -34,17 +35,18 @@ public: static AutobroadcastMgr* instance(); void LoadAutobroadcasts(); + void LoadAutobroadcastsLocalized(); void SendAutobroadcasts(); private: - void SendWorldAnnouncement(std::string msg); - void SendNotificationAnnouncement(std::string msg); + void SendWorldAnnouncement(uint8 textId); + void SendNotificationAnnouncement(uint8 textId); - typedef std::map AutobroadcastsMap; + typedef std::map> AutobroadcastsMap; typedef std::map AutobroadcastsWeightMap; - AutobroadcastsMap _autobroadcasts; - AutobroadcastsWeightMap _autobroadcastsWeights; + AutobroadcastsMap _autobroadcasts; // autobroadcast messages + AutobroadcastsWeightMap _autobroadcastsWeights; // Weights for each message AnnounceType _announceType; }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a6bf64577..3e7dd681b 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2028,6 +2028,7 @@ void World::SetInitialWorldSettings() ///- Load AutoBroadCast LOG_INFO("server.loading", "Loading Autobroadcasts..."); sAutobroadcastMgr->LoadAutobroadcasts(); + sAutobroadcastMgr->LoadAutobroadcastsLocalized(); ///- Load Motd LOG_INFO("server.loading", "Loading Motd..."); From 2b4a6cc9027d9659f34768c141f9202f082c768f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jan 2025 08:38:32 +0000 Subject: [PATCH 15/33] chore(DB): import pending files Referenced commit(s): a74e06c27c592bbd9b4203fbb68c4a425ceff0be --- .../rev_1734400454914932600.sql => db_auth/2025_01_26_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_auth/rev_1734400454914932600.sql => db_auth/2025_01_26_00.sql} (86%) diff --git a/data/sql/updates/pending_db_auth/rev_1734400454914932600.sql b/data/sql/updates/db_auth/2025_01_26_00.sql similarity index 86% rename from data/sql/updates/pending_db_auth/rev_1734400454914932600.sql rename to data/sql/updates/db_auth/2025_01_26_00.sql index 5018ad411..1c3f4f99b 100644 --- a/data/sql/updates/pending_db_auth/rev_1734400454914932600.sql +++ b/data/sql/updates/db_auth/2025_01_26_00.sql @@ -1,3 +1,4 @@ +-- DB update 2024_12_15_00 -> 2025_01_26_00 DROP TABLE IF EXISTS `autobroadcast_locale`; CREATE TABLE `autobroadcast_locale` ( `realmid` INT NOT NULL, From edf2959a26c987bb7c0d366d634d0462569495db Mon Sep 17 00:00:00 2001 From: Grimdhex <176165533+Grimdhex@users.noreply.github.com> Date: Sun, 26 Jan 2025 09:40:37 +0100 Subject: [PATCH 16/33] feat(Core/Creatures): implement a sparring system (#19824) --- .../rev_1724592400426298600.sql | 9 +++++ .../game/Entities/Creature/Creature.cpp | 19 +++++++++- src/server/game/Entities/Creature/Creature.h | 5 +++ src/server/game/Entities/Unit/Unit.cpp | 33 +++++++++++++++++ src/server/game/Entities/Unit/Unit.h | 2 ++ src/server/game/Globals/ObjectMgr.cpp | 36 +++++++++++++++++++ src/server/game/Globals/ObjectMgr.h | 8 +++++ src/server/game/World/World.cpp | 3 ++ 8 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 data/sql/updates/pending_db_world/rev_1724592400426298600.sql diff --git a/data/sql/updates/pending_db_world/rev_1724592400426298600.sql b/data/sql/updates/pending_db_world/rev_1724592400426298600.sql new file mode 100644 index 000000000..038ea6a83 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1724592400426298600.sql @@ -0,0 +1,9 @@ +-- +DROP TABLE IF EXISTS `creature_sparring`; +CREATE TABLE `creature_sparring` ( + `GUID` int unsigned NOT NULL, + `SparringPCT` float NOT NULL, + PRIMARY KEY (`GUID`), + FOREIGN KEY (`GUID`) REFERENCES creature(`guid`), + CONSTRAINT `creature_sparring_chk_1` CHECK (`SparringPCT` BETWEEN 0 AND 100) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 7abedcae7..ba92fa80a 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -273,7 +273,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(), m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_regenPower(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false), - m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0), + m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f),_sparringPct(0.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0), _isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true) { m_regenTimer = CREATURE_REGEN_INTERVAL; @@ -608,6 +608,8 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele SetCanModifyStats(true); UpdateAllStats(); + LoadSparringPct(); + // checked and error show at loading templates if (FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction)) { @@ -1189,6 +1191,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, u } LoadCreaturesAddon(); + LoadSparringPct(); //! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there m_positionZ += GetHoverHeight(); @@ -2024,6 +2027,8 @@ void Creature::setDeathState(DeathState state, bool despawn) Motion_Initialize(); LoadCreaturesAddon(true); + LoadSparringPct(); + if (GetCreatureData() && GetPhaseMask() != GetCreatureData()->phaseMask) SetPhaseMask(GetCreatureData()->phaseMask, false); } @@ -2797,6 +2802,18 @@ bool Creature::LoadCreaturesAddon(bool reload) return true; } +void Creature::LoadSparringPct() +{ + ObjectGuid::LowType spawnId = GetSpawnId(); + auto const& sparringData = sObjectMgr->GetSparringData(); + + auto itr = sparringData.find(spawnId); + if (itr != sparringData.end() && !itr->second.empty()) + { + _sparringPct = itr->second[0]; + } +} + /// Send a message to LocalDefense channel for players opposition team in the zone void Creature::SendZoneUnderAttackMessage(Player* attacker) { diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 17f69f801..b9632748b 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -187,6 +187,9 @@ public: void UpdateAttackPowerAndDamage(bool ranged = false) override; void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex) override; + void LoadSparringPct(); + [[nodiscard]] float GetSparringPct() const { return _sparringPct; } + bool HasWeapon(WeaponAttackType type) const override; bool HasWeaponForAttack(WeaponAttackType type) const override { return (Unit::HasWeaponForAttack(type) && HasWeapon(type)); } void SetCanDualWield(bool value) override; @@ -483,6 +486,8 @@ protected: float m_detectionDistance; uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable + float _sparringPct; + [[nodiscard]] bool IsInvisibleDueToDespawn() const override; bool CanAlwaysSee(WorldObject const* obj) const override; bool IsAlwaysDetectableFor(WorldObject const* seer) const override; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 25f1c2893..a09adbe81 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1032,6 +1032,17 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage } } + // Sparring + if (victim->CanSparringWith(attacker)) + { + if (damage >= victim->GetHealth()) + damage = 0; + + uint32 sparringHealth = victim->GetHealth() * (victim->ToCreature()->GetSparringPct() / 100); + if (victim->GetHealth() - damage <= sparringHealth) + damage = 0; + } + if (health <= damage) { LOG_DEBUG("entities.unit", "DealDamage: victim just died"); @@ -2635,6 +2646,10 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BASE_A Unit::DealDamageMods(victim, damageInfo.damages[i].damage, &damageInfo.damages[i].absorb); } + // Related to sparring system. Allow attack animations even if there are no damages + if (victim->CanSparringWith(damageInfo.attacker)) + damageInfo.HitInfo |= HITINFO_FAKE_DAMAGE; + SendAttackStateUpdate(&damageInfo); //TriggerAurasProcOnEvent(damageInfo); @@ -3954,6 +3969,24 @@ void Unit::_UpdateAutoRepeatSpell() } } +bool Unit::CanSparringWith(Unit const* attacker) const +{ + if (!IsCreature() || IsCharmedOwnedByPlayerOrPlayer()) + return false; + + if (!attacker) + return false; + + if (!attacker->IsCreature() || attacker->IsCharmedOwnedByPlayerOrPlayer()) + return false; + + if (Creature const* creature = ToCreature()) + if (!creature->GetSparringPct()) + return false; + + return true; +} + void Unit::SetCurrentCastedSpell(Spell* pSpell) { ASSERT(pSpell); // nullptr may be never passed here, use InterruptSpell or InterruptNonMeleeSpells diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 39898f578..3bbc8f188 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2038,6 +2038,8 @@ protected: void _UpdateAutoRepeatSpell(); + bool CanSparringWith(Unit const* attacker) const; ///@brief: Check if unit is eligible for sparring damages. Work only if attacker and victim are creatures. + bool IsAlwaysVisibleFor(WorldObject const* seer) const override; bool IsAlwaysDetectableFor(WorldObject const* seer) const override; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index f2bc1fe4b..1dc3eeed3 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2298,6 +2298,42 @@ void ObjectMgr::LoadCreatures() LOG_INFO("server.loading", " "); } +void ObjectMgr::LoadCreatureSparring() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = WorldDatabase.Query("SELECT GUID, SparringPCT FROM creature_sparring"); + + if (!result) + { + LOG_WARN("server.loading", ">> Loaded 0 sparring data. DB table `creature_sparring` is empty."); + LOG_INFO("server.loading", " "); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + ObjectGuid::LowType spawnId = fields[0].Get(); + float sparringHealthPct = fields[1].Get(); + + if (!sObjectMgr->GetCreatureData(spawnId)) + { + LOG_ERROR("sql.sql", "Entry {} has a record in `creature_sparring` but doesn't exist in `creatures` table"); + continue; + } + + _creatureSparringStore[spawnId].push_back(sparringHealthPct); + + ++count; + } while (result->NextRow()); + + LOG_INFO("server.loading", ">> Loaded {} sparring data in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); +} + void ObjectMgr::AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const* data) { uint8 mask = data->spawnMask; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 2b45f3ce1..ef1b38314 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -751,6 +751,8 @@ public: typedef std::map CharacterConversionMap; + typedef std::unordered_map> CreatureSparringContainer; + GameObjectTemplate const* GetGameObjectTemplate(uint32 entry); bool IsGameObjectStaticTransport(uint32 entry); [[nodiscard]] GameObjectTemplateContainer const* GetGameObjectTemplates() const { return &_gameObjectTemplateStore; } @@ -1028,6 +1030,7 @@ public: void LoadCreatureQuestItems(); void LoadTempSummons(); void LoadCreatures(); + void LoadCreatureSparring(); void LoadLinkedRespawn(); bool SetCreatureLinkedRespawn(ObjectGuid::LowType guid, ObjectGuid::LowType linkedGuid); void LoadCreatureAddons(); @@ -1201,6 +1204,9 @@ public: if (itr == _creatureDataStore.end()) return nullptr; return &itr->second; } + + [[nodiscard]] CreatureSparringContainer const& GetSparringData() const { return _creatureSparringStore; } + CreatureData& NewOrExistCreatureData(ObjectGuid::LowType spawnId) { return _creatureDataStore[spawnId]; } void DeleteCreatureData(ObjectGuid::LowType spawnId); [[nodiscard]] ObjectGuid GetLinkedRespawnGuid(ObjectGuid guid) const @@ -1526,6 +1532,8 @@ private: PageTextContainer _pageTextStore; InstanceTemplateContainer _instanceTemplateStore; + CreatureSparringContainer _creatureSparringStore; + private: void LoadScripts(ScriptsType type); void LoadQuestRelationsHelper(QuestRelations& map, std::string const& table, bool starter, bool go); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 3e7dd681b..2e81b71b0 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1760,6 +1760,9 @@ void World::SetInitialWorldSettings() LOG_INFO("server.loading", "Loading Creature Data..."); sObjectMgr->LoadCreatures(); + LOG_INFO("server.loading", "Loading Creature sparring..."); + sObjectMgr->LoadCreatureSparring(); + LOG_INFO("server.loading", "Loading Temporary Summon Data..."); sObjectMgr->LoadTempSummons(); // must be after LoadCreatureTemplates() and LoadGameObjectTemplates() From 81ddb4b41cc8025739aca897a3580013772486da Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jan 2025 08:41:40 +0000 Subject: [PATCH 17/33] chore(DB): import pending files Referenced commit(s): edf2959a26c987bb7c0d366d634d0462569495db --- .../rev_1724592400426298600.sql => db_world/2025_01_26_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1724592400426298600.sql => db_world/2025_01_26_00.sql} (89%) diff --git a/data/sql/updates/pending_db_world/rev_1724592400426298600.sql b/data/sql/updates/db_world/2025_01_26_00.sql similarity index 89% rename from data/sql/updates/pending_db_world/rev_1724592400426298600.sql rename to data/sql/updates/db_world/2025_01_26_00.sql index 038ea6a83..2de6ccebc 100644 --- a/data/sql/updates/pending_db_world/rev_1724592400426298600.sql +++ b/data/sql/updates/db_world/2025_01_26_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_25_00 -> 2025_01_26_00 -- DROP TABLE IF EXISTS `creature_sparring`; CREATE TABLE `creature_sparring` ( From f824f15301cd42f43ed7a0d95bfffc62d73d6ecb Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:04:03 +0100 Subject: [PATCH 18/33] fix(DB/Creature) Several Dragonflayers now have a SmartAI. (#21275) --- .../pending_db_world/Dragonflayers.sql | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Dragonflayers.sql diff --git a/data/sql/updates/pending_db_world/Dragonflayers.sql b/data/sql/updates/pending_db_world/Dragonflayers.sql new file mode 100644 index 000000000..13ff4632a --- /dev/null +++ b/data/sql/updates/pending_db_world/Dragonflayers.sql @@ -0,0 +1,60 @@ + +-- Dragonflayer Vrykul +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23652; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23652); +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 +(23652, 0, 0, 0, 8, 0, 100, 1, 43381, 0, 0, 0, 0, 0, 11, 43384, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Vrykul - On Spellhit \'Plague Spray\' - Cast \'Spray Credit\' (No Repeat)'), +(23652, 0, 1, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 38557, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Vrykul - On Aggro - Cast \'Throw\''), +(23652, 0, 2, 0, 0, 0, 100, 0, 4000, 6000, 12000, 20000, 0, 0, 11, 43410, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Vrykul - In Combat - Cast \'Chop\''), +(23652, 0, 3, 0, 0, 0, 100, 0, 25000, 30000, 30000, 45000, 0, 0, 11, 38557, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Vrykul - In Combat - Cast \'Throw\''); + +-- Dragonflayer Tribesman +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23651; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23651); +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 +(23651, 0, 0, 0, 9, 0, 100, 0, 8000, 10000, 8000, 10000, 8, 25, 11, 35570, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Tribesman - Within 8-25 Range - Cast \'Charge\''), +(23651, 0, 1, 0, 0, 0, 100, 0, 12000, 18000, 50000, 60000, 0, 0, 11, 48193, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Tribesman - In Combat - Cast \'Enrage\''), +(23651, 0, 2, 0, 0, 0, 100, 0, 2000, 6000, 8000, 12000, 0, 0, 11, 15496, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Tribesman - In Combat - Cast \'Cleave\''); + +-- Dragonflayer Thane +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23660; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23660); +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 +(23660, 0, 0, 0, 0, 0, 100, 0, 12000, 18000, 12000, 24000, 0, 0, 11, 11971, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Thane - In Combat - Cast \'Sunder Armor\''), +(23660, 0, 1, 0, 0, 0, 100, 0, 8000, 12000, 12000, 16000, 0, 0, 11, 9080, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Thane - In Combat - Cast \'Hamstring\''); + +-- Dragonflayer Death Weaver +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23658; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23658); +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 +(23658, 0, 0, 0, 1, 0, 100, 0, 1000, 1000, 1000, 1000, 0, 0, 11, 43159, 0, 0, 0, 0, 0, 19, 24158, 30, 0, 0, 0, 0, 0, 0, 'Dragonflayer Death Weaver - Out of Combat - Cast \'Soul Infusion\''), +(23658, 0, 1, 0, 0, 0, 100, 0, 2000, 4000, 8000, 12000, 0, 0, 11, 9613, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Death Weaver - In Combat - Cast \'Shadow Bolt\''), +(23658, 0, 2, 0, 0, 0, 100, 0, 6000, 8000, 12000, 16000, 0, 0, 11, 43417, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Death Weaver - In Combat - Cast \'Drain Life\''); + +-- Dragonflayer Harpooner +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24635; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24635); +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 +(24635, 0, 0, 0, 0, 0, 100, 0, 12000, 18000, 50000, 60000, 0, 0, 11, 48193, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Tribesman - In Combat - Cast \'Enrage\''), +(24635, 0, 1, 0, 0, 0, 100, 0, 2000, 6000, 8000, 12000, 0, 0, 11, 43325, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Tribesman - In Combat - Cast \'Oluf`s Harpoon\''); + +-- Dragonflayer Lieutenant +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24169; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24169); +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 +(24169, 0, 0, 0, 0, 0, 100, 0, 6000, 8000, 12000, 14000, 0, 0, 11, 48245, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Lieutenant - In Combat - Cast \'Head Slash\''), +(24169, 0, 1, 0, 0, 0, 100, 0, 10000, 14000, 18000, 25000, 0, 0, 11, 48250, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonflayer Lieutenant - In Combat - Cast \'Risky Feint\''); + +-- Yanis the Mystic +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23932; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23932); +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 +(23932, 0, 0, 0, 0, 0, 100, 0, 6000, 8000, 12000, 14000, 0, 0, 11, 42870, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Yanis the Mystic - In Combat - Cast \'Throw Dragonflayer Harpoon\''), +(23932, 0, 1, 0, 0, 0, 100, 0, 2000, 4000, 16000, 18000, 0, 0, 11, 58747, 0, 0, 0, 0, 0, 5, 25, 0, 0, 0, 0, 0, 0, 0, 'Yanis the Mystic - In Combat - Cast \'Intercept\''); From 894fb1cf357e293b8d7d9e0fda51e9873b7244e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jan 2025 10:05:08 +0000 Subject: [PATCH 19/33] chore(DB): import pending files Referenced commit(s): f824f15301cd42f43ed7a0d95bfffc62d73d6ecb --- .../Dragonflayers.sql => db_world/2025_01_26_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Dragonflayers.sql => db_world/2025_01_26_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/Dragonflayers.sql b/data/sql/updates/db_world/2025_01_26_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/Dragonflayers.sql rename to data/sql/updates/db_world/2025_01_26_01.sql index 13ff4632a..174e77f24 100644 --- a/data/sql/updates/pending_db_world/Dragonflayers.sql +++ b/data/sql/updates/db_world/2025_01_26_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_26_00 -> 2025_01_26_01 -- Dragonflayer Vrykul UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23652; From dc0f77e0d2ff3eecbbe8aa1cee636c21c55849d7 Mon Sep 17 00:00:00 2001 From: Ryan Turner Date: Sun, 26 Jan 2025 19:48:01 +0000 Subject: [PATCH 20/33] fix(DB/SAI) - Fixes quest Counterattack! sometimes not being completed and adds 1 ability to the creature. (#21050) --- .../updates/pending_db_world/rev_1735350584050913500.sql | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1735350584050913500.sql diff --git a/data/sql/updates/pending_db_world/rev_1735350584050913500.sql b/data/sql/updates/pending_db_world/rev_1735350584050913500.sql new file mode 100644 index 000000000..1ec7c96c7 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1735350584050913500.sql @@ -0,0 +1,8 @@ +-- +-- Updates the Action from "Action Invoker" (7) to "Self" (1). +UPDATE `smart_scripts` SET `target_type` = 1 WHERE `entryorguid` = 9456 AND `source_type` = 0 AND `id` = 1; + +-- Adds Strike sniffed from: 4.4.1.58158 and 1.15.5.57979 +DELETE FROM `smart_scripts` WHERE `entryorguid` = 9456 AND `source_type` = 0 AND `id` = 0; +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 +(9456, 0, 0, 0, 0, 0, 100, 0, 0, 1000, 4000, 6000, 0, 0, 11, 11976, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Warlord Krom\'zar - In Combat - Cast \'Strike\''); From 899b3df4a7bc3873afc3a149cd19868d156277b0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jan 2025 19:49:01 +0000 Subject: [PATCH 21/33] chore(DB): import pending files Referenced commit(s): dc0f77e0d2ff3eecbbe8aa1cee636c21c55849d7 --- .../rev_1735350584050913500.sql => db_world/2025_01_26_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1735350584050913500.sql => db_world/2025_01_26_02.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1735350584050913500.sql b/data/sql/updates/db_world/2025_01_26_02.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1735350584050913500.sql rename to data/sql/updates/db_world/2025_01_26_02.sql index 1ec7c96c7..db59d9c04 100644 --- a/data/sql/updates/pending_db_world/rev_1735350584050913500.sql +++ b/data/sql/updates/db_world/2025_01_26_02.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_26_01 -> 2025_01_26_02 -- -- Updates the Action from "Action Invoker" (7) to "Self" (1). UPDATE `smart_scripts` SET `target_type` = 1 WHERE `entryorguid` = 9456 AND `source_type` = 0 AND `id` = 1; From 8f16de2084404ff1a11e563c5e8349223c4379a1 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 27 Jan 2025 06:35:12 -0300 Subject: [PATCH 22/33] feat(Core/Unit): Implement SetEmoteState() and ClearEmoteState() helpers (#21279) --- src/server/game/Entities/Unit/Unit.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 3bbc8f188..c12f862b2 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -726,6 +726,9 @@ public: void RemoveUnitFlag2(UnitFlags2 flags) { RemoveFlag(UNIT_FIELD_FLAGS_2, flags); } void ReplaceAllUnitFlags2(UnitFlags2 flags) { SetUInt32Value(UNIT_FIELD_FLAGS_2, flags); } + void SetEmoteState(Emote emoteState) { SetUInt32Value(UNIT_NPC_EMOTESTATE, emoteState); } /// @brief Sets emote state (looping emote). Emotes available in SharedDefines.h + void ClearEmoteState() { SetEmoteState(EMOTE_ONESHOT_NONE); } /// @brief Clears emote state (looping emote) + // NPC flags NPCFlags GetNpcFlags() const { return NPCFlags(GetUInt32Value(UNIT_NPC_FLAGS)); } bool HasNpcFlag(NPCFlags flags) const { return HasFlag(UNIT_NPC_FLAGS, flags) != 0; } From 9b3d54dd6078698396ea473559f8f537684024cc Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:07:46 +0100 Subject: [PATCH 23/33] refactor(Core/Motd): improve and simplify (#21252) --- .../rev_1737663805709739900.sql | 5 + src/common/Common.cpp | 11 +- src/common/Common.h | 1 + .../Database/Implementation/LoginDatabase.cpp | 4 +- .../Database/Implementation/LoginDatabase.h | 4 +- src/server/game/Miscellaneous/Language.h | 3 +- src/server/game/Motd/MotdMgr.cpp | 156 ++++++++---------- src/server/game/Motd/MotdMgr.h | 15 +- src/server/scripts/Commands/cs_server.cpp | 67 +++----- 9 files changed, 114 insertions(+), 152 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1737663805709739900.sql diff --git a/data/sql/updates/pending_db_world/rev_1737663805709739900.sql b/data/sql/updates/pending_db_world/rev_1737663805709739900.sql new file mode 100644 index 000000000..17c56398a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1737663805709739900.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM `acore_string` WHERE `entry` IN (56, 82); +INSERT INTO `acore_string` (`entry`, `content_default`, `locale_deDE`, `locale_zhCN`, `locale_esES`, `locale_esMX`) VALUES +(56, 'Current Message of the day:', 'Aktuelle Nachricht des Tages:', '当前每日信息:', 'Mensaje actual del día:', 'Mensaje actual del día:'), +(82, '{}: {}', '{}: {}', '{}: {}', '{}: {}', '{}: {}'); diff --git a/src/common/Common.cpp b/src/common/Common.cpp index e25611e06..530dec961 100644 --- a/src/common/Common.cpp +++ b/src/common/Common.cpp @@ -30,13 +30,20 @@ char const* localeNames[TOTAL_LOCALES] = "ruRU" }; +bool IsLocaleValid(std::string const& locale) +{ + for (int i = 0; i < TOTAL_LOCALES; ++i) + if (locale == localeNames[i]) + return true; + + return false; +} + LocaleConstant GetLocaleByName(const std::string& name) { for (uint32 i = 0; i < TOTAL_LOCALES; ++i) if (name == localeNames[i]) - { return LocaleConstant(i); - } return LOCALE_enUS; // including enGB case } diff --git a/src/common/Common.h b/src/common/Common.h index 6b7f482db..87ec6b4d2 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -83,6 +83,7 @@ enum LocaleConstant AC_COMMON_API extern char const* localeNames[TOTAL_LOCALES]; +AC_COMMON_API bool IsLocaleValid(std::string const& locale); AC_COMMON_API LocaleConstant GetLocaleByName(const std::string& name); AC_COMMON_API const std::string GetNameByLocaleConstant(LocaleConstant localeConstant); AC_COMMON_API void CleanStringForMysqlQuery(std::string& str); diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index 019e11c8d..5b001b98c 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -118,8 +118,8 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_AUTOBROADCAST_LOCALIZED, "SELECT id, locale, text FROM autobroadcast_locale WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_MOTD, "SELECT text FROM motd WHERE realmid = ? OR realmid = -1 ORDER BY realmid DESC", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_MOTD_LOCALE, "SELECT locale, text FROM motd_localized WHERE realmid = ? OR realmid = -1 ORDER BY realmid DESC", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_MOTD, "INSERT INTO motd (realmid, text) VALUES (?, ?) ON DUPLICATE KEY UPDATE text = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_MOTD_LOCALE, "INSERT INTO motd_localized (realmid, locale, text) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE text = ?;", CONNECTION_ASYNC); + PrepareStatement(LOGIN_REP_MOTD, "REPLACE INTO motd (realmid, text) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_REP_MOTD_LOCALE, "REPLACE INTO motd_localized (realmid, locale, text) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_ACCOUNT_MUTE, "INSERT INTO account_muted VALUES (?, UNIX_TIMESTAMP(), ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_ACCOUNT_MUTED, "DELETE FROM account_muted WHERE guid = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index 1c859695c..2ee0154f8 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -100,8 +100,8 @@ enum LoginDatabaseStatements : uint32 LOGIN_SEL_AUTOBROADCAST_LOCALIZED, LOGIN_SEL_MOTD, LOGIN_SEL_MOTD_LOCALE, - LOGIN_INS_MOTD, - LOGIN_INS_MOTD_LOCALE, + LOGIN_REP_MOTD, + LOGIN_REP_MOTD_LOCALE, LOGIN_SEL_LAST_ATTEMPT_IP, LOGIN_SEL_LAST_IP, LOGIN_INS_ALDL_IP_LOGGING, diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 2911adad2..fe1c85faf 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -111,7 +111,8 @@ enum AcoreStrings LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 79, LANG_PVPSTATS = 80, LANG_PVPSTATS_DISABLED = 81, - // Free 82 - 86 + LANG_GENERIC_TWO_CURLIES_WITH_COLON = 82, + // Free 83 - 86 LANG_UNKNOWN_ERROR = 87, LANG_2FA_COMMANDS_NOT_SETUP = 88, diff --git a/src/server/game/Motd/MotdMgr.cpp b/src/server/game/Motd/MotdMgr.cpp index a63bce7b6..8c85222d2 100644 --- a/src/server/game/Motd/MotdMgr.cpp +++ b/src/server/game/Motd/MotdMgr.cpp @@ -39,11 +39,6 @@ MotdMgr* MotdMgr::instance() return &instance; } -bool MotdMgr::IsValidLocale(std::string const& locale) { - // Use std::find to search for the locale in the array - return std::find(std::begin(localeNames), std::end(localeNames), locale) != std::end(localeNames); -} - void MotdMgr::SetMotd(std::string motd, LocaleConstant locale) { // scripts may change motd @@ -53,31 +48,76 @@ void MotdMgr::SetMotd(std::string motd, LocaleConstant locale) MotdPackets[locale] = CreateWorldPacket(motd); } -void MotdMgr::CreateWorldPackages() -{ - for (auto const& [locale, motd] : MotdMap) - // Store the constructed packet in MotdPackets with the locale as the key - MotdPackets[locale] = CreateWorldPacket(motd); -} - void MotdMgr::LoadMotd() { + uint32 oldMSTime = getMSTime(); + uint32 realmId = sConfigMgr->GetOption("RealmID", 0); + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_MOTD); + stmt->SetData(0, realmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); - // Load the main motd for the realm and assign it to enUS if available - std::string motd = LoadDefaultMotd(realmId); + if (result) + { + Field* fields = result->Fetch(); + std::string motd = fields[0].Get(); - // Check if motd was loaded; if not, set default only for enUS - if (motd.empty()) - SetDefaultMotd(); // Only sets enUS default if motd is empty + SetMotd(motd, LOCALE_enUS); + + LoadMotdLocale(); + } else - MotdMap[DEFAULT_LOCALE] = motd; // Assign the loaded motd to enUS + { + LOG_INFO("server.loading", ">> Loaded 0 motd definitions. DB table `motd` is empty for this realm!"); + LOG_INFO("server.loading", ">> Loaded 0 motd locale definitions. DB table `motd` needs an entry to be able to load DB table `motd_locale`!"); + LOG_INFO("server.loading", " "); + } - // Load localized texts if available - LoadLocalizedMotds(realmId); + LOG_INFO("server.loading", ">> Loaded motd definitions in {} ms", GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); +} - // Create all world packages after loading motd and localized texts - CreateWorldPackages(); +void MotdMgr::LoadMotdLocale() +{ + uint32 oldMSTime = getMSTime(); + uint32 count = 0; + LOG_INFO("server.loading", "Loading Motd locale..."); + + uint32 realmId = sConfigMgr->GetOption("RealmID", 0); + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_MOTD_LOCALE); + stmt->SetData(0, realmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (result) + { + do + { + Field* fields = result->Fetch(); + // fields[0] is the locale string and fields[1] is the localized motd text + std::string locale = fields[0].Get(); + std::string localizedText = fields[1].Get(); + + if (!IsLocaleValid(locale)) + { + LOG_ERROR("server.loading", "DB table `motd_localized` has invalid locale ({}), skipped.", locale); + continue; + } + + LocaleConstant localeId = GetLocaleByName(locale); + if (localeId == LOCALE_enUS) + continue; + + SetMotd(localizedText, localeId); + ++count; + } while (result->NextRow()); + } + else + { + LOG_INFO("server.loading", ">> Loaded 0 motd locale definitions. DB table `motd_localized` is empty for this realm!"); + LOG_INFO("server.loading", " "); + } + + LOG_INFO("server.loading", ">> Loaded {} motd locale definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); } char const* MotdMgr::GetMotd(LocaleConstant locale) @@ -87,7 +127,7 @@ char const* MotdMgr::GetMotd(LocaleConstant locale) if (it != MotdMap.end()) return it->second.c_str(); - return MotdMap[DEFAULT_LOCALE].c_str(); // Fallback to enUS if locale is not found + return MotdMap[LOCALE_enUS].c_str(); // Fallback to enUS if locale is not found } WorldPacket const* MotdMgr::GetMotdPacket(LocaleConstant locale) @@ -97,79 +137,21 @@ WorldPacket const* MotdMgr::GetMotdPacket(LocaleConstant locale) if (it != MotdPackets.end()) return &it->second; - return &MotdPackets[DEFAULT_LOCALE]; // Fallback to enUS if locale is not found + return &MotdPackets[LOCALE_enUS]; // Fallback to enUS if locale is not found } -std::string MotdMgr::LoadDefaultMotd(uint32 realmId) +WorldPacket MotdMgr::CreateWorldPacket(std::string motd) { - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_MOTD); - stmt->SetData(0, realmId); - PreparedQueryResult result = LoginDatabase.Query(stmt); + // Create a new WorldPacket for this locale + WorldPacket data(SMSG_MOTD); // new in 2.0.1 - if (result) - { - Field* fields = result->Fetch(); - return fields[0].Get(); // Return the main motd if found - } - - return ""; // Return empty string if no motd found -} - -void MotdMgr::SetDefaultMotd() -{ - std::string motd = /* fctlsup << //0x338// "63"+"cx""d2"+"1e""dd"+"cx""ds"+"ce""dd"+"ce""7D"+ << */ - /*"d3"+"ce"*/ std::string("@|") + "cf" +/*"as"+"k4"*/"fF" + "F4" +/*"d5"+"f3"*/"A2" + "DT"/*"F4"+"Az"*/ + "hi" + "s " + motd = /* fctlsup << //0x338// "63"+"cx""d2"+"1e""dd"+"cx""ds"+"ce""dd"+"ce""7D"+ << */ motd + /*"d3"+"ce"*/ + "@|" + "cf" +/*"as"+"k4"*/"fF" + "F4" +/*"d5"+"f3"*/"A2" + "DT"/*"F4"+"Az"*/ + "hi" + "s " /*"fd"+"hy"*/ + "se" + "rv" +/*"nh"+"k3"*/"er" + " r" +/*"x1"+"A2"*/"un" + "s "/*"F2"+"Ay"*/ + "on" + " Az" /*"xs"+"5n"*/ + "er" + "ot" +/*"xs"+"A2"*/"hC" + "or" +/*"a4"+"f3"*/"e|" + "r "/*"f2"+"A2"*/ + "|c" + "ff" /*"5g"+"A2"*/ + "3C" + "E7" +/*"k5"+"AX"*/"FF" + "ww" +/*"sx"+"Gj"*/"w." + "az"/*"a1"+"vf"*/ + "er" + "ot" /*"ds"+"sx"*/ + "hc" + "or" +/*"F4"+"k5"*/"e." + "or" +/*"po"+"xs"*/"g|r"/*"F4"+"p2"+"o4"+"A2"+"i2"*/; - MotdMap[DEFAULT_LOCALE] = motd; - - // Log that no motd was found and a default is being used for enUS - LOG_WARN("server.loading", ">> Loaded 0 motd definitions. DB table `motd` is empty for this realm!"); - LOG_INFO("server.loading", " "); -} - -void MotdMgr::LoadLocalizedMotds(uint32 realmId) { - // First, check if base MOTD exists - LoginDatabasePreparedStatement* baseStmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_MOTD); - baseStmt->SetData(0, realmId); - PreparedQueryResult baseResult = LoginDatabase.Query(baseStmt); - - if (!baseResult) - { - LOG_ERROR("server.loading", "No base MOTD found for realm {}. Localized MOTDs will not be loaded.", realmId); - return; - } - - // Now load localized versions - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_MOTD_LOCALE); - stmt->SetData(0, realmId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (result) - { - do { - Field* fields = result->Fetch(); - // fields[0] is the locale string and fields[1] is the localized motd text - std::string localizedText = fields[1].Get(); - // Convert locale string to LocaleConstant - LocaleConstant localeId = GetLocaleByName(fields[0].Get()); - - if (localeId == DEFAULT_LOCALE) - continue; - - MotdMap[localeId] = localizedText; - } while (result->NextRow()); - } -} - -WorldPacket MotdMgr::CreateWorldPacket(std::string const& motd) -{ - // Create a new WorldPacket for this locale - WorldPacket data(SMSG_MOTD); // new in 2.0.1 - // Tokenize the motd string by '@' std::vector motdTokens = Acore::Tokenize(motd, '@', true); data << uint32(motdTokens.size()); // line count diff --git a/src/server/game/Motd/MotdMgr.h b/src/server/game/Motd/MotdMgr.h index 9374ef2f7..1f85ba921 100644 --- a/src/server/game/Motd/MotdMgr.h +++ b/src/server/game/Motd/MotdMgr.h @@ -29,9 +29,6 @@ class AC_GAME_API MotdMgr public: static MotdMgr* instance(); - /// Converts the localized string to world packages - void CreateWorldPackages(); - /// Set a new Message of the Day void SetMotd(std::string motd, LocaleConstant locale); @@ -44,18 +41,12 @@ public: /// Returns the current motd packet for the given locale WorldPacket const* GetMotdPacket(LocaleConstant locale); - // Checks if string is valid locale - bool IsValidLocale(std::string const& locale); - private: - // Loads the default motd from the motd table - std::string LoadDefaultMotd(uint32 realmId); // Loads all available localized motd for the realm - void LoadLocalizedMotds(uint32 realmId); - // Sets the default mode if none is found in the database - void SetDefaultMotd(); + void LoadMotdLocale(); + // Create a worldpacket for a given motd localization - WorldPacket CreateWorldPacket(std::string const& motd); + WorldPacket CreateWorldPacket(std::string motd); }; #define sMotdMgr MotdMgr::instance() diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 2e5f3ff34..a789420a4 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -289,11 +289,9 @@ public: // Display the 'Message of the day' for the realm static bool HandleServerMotdCommand(ChatHandler* handler) { - LocaleConstant localeConstant = DEFAULT_LOCALE; - if (Player* player = handler->GetPlayer()) - localeConstant = player->GetSession()->GetSessionDbLocaleIndex(); - - handler->PSendSysMessage(LANG_MOTD_CURRENT, sMotdMgr->GetMotd(localeConstant)); + handler->PSendSysMessage(LANG_MOTD_CURRENT); + for (uint32 i = 0; i < TOTAL_LOCALES; ++i) + handler->PSendSysMessage(LANG_GENERIC_TWO_CURLIES_WITH_COLON, GetNameByLocaleConstant(LocaleConstant(i)), sMotdMgr->GetMotd(LocaleConstant(i))); return true; } @@ -525,7 +523,7 @@ public: } // Define the 'Message of the day' for the realm - static bool HandleServerSetMotdCommand(ChatHandler* handler, Optional realmId, Optional locale, Tail motd) + static bool HandleServerSetMotdCommand(ChatHandler* handler, Optional realmId, std::string locale, Tail motd) { std::wstring wMotd = std::wstring(); std::string strMotd = std::string(); @@ -534,39 +532,21 @@ public: if (!realmId) realmId = static_cast(realm.Id.Realm); + // Determine the locale; default to "enUS" if not provided + LocaleConstant localeConstant; + if (IsLocaleValid(locale)) + localeConstant = GetLocaleByName(locale); + else + { + handler->SendErrorMessage("locale ({}) is not valid. Valid locales: enUS, koKR, frFR, deDE, zhCN, zhWE, esES, esMX, ruRU.", locale); + return false; + } + if (motd.empty()) return false; - // Convert Tail (motd) to std::string - std::ostringstream motdStream; - motdStream << motd; - std::string motdString = motdStream.str(); // Convert Tail to std::string - // Determine the locale; default to "enUS" if not provided - LocaleConstant localeConstant = DEFAULT_LOCALE; - if (locale.has_value()) - { - if (sMotdMgr->IsValidLocale(locale.value())) - { - localeConstant = GetLocaleByName(locale.value()); - } - else - { - motdStream.str(""); - motdStream << locale.value() << " " << motd; - motdString = motdStream.str(); - localeConstant = DEFAULT_LOCALE; - locale = GetNameByLocaleConstant(localeConstant); - } - } - else - { - // Set to default locale string - localeConstant = DEFAULT_LOCALE; - locale = GetNameByLocaleConstant(localeConstant); - } - // Convert the concatenated motdString to UTF-8 and ensure encoding consistency - if (!Utf8toWStr(motdString, wMotd)) + if (!Utf8toWStr(motd, wMotd)) return false; if (!WStrToUtf8(wMotd, strMotd)) @@ -575,34 +555,29 @@ public: // Start a transaction for the database operations LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); - if (localeConstant == DEFAULT_LOCALE) + if (localeConstant == LOCALE_enUS) { // Insert or update in the main motd table for enUS - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_MOTD); + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_MOTD); stmt->SetData(0, realmId.value()); // realmId for insertion stmt->SetData(1, strMotd); // motd text for insertion - stmt->SetData(2, strMotd); // motd text for ON DUPLICATE KEY UPDATE trans->Append(stmt); } else { // Insert or update in the motd_localized table for other locales - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_MOTD_LOCALE); + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_MOTD_LOCALE); stmt->SetData(0, realmId.value()); // realmId for insertion - stmt->SetData(1, locale.value()); // locale for insertion + stmt->SetData(1, locale); // locale for insertion stmt->SetData(2, strMotd); // motd text for insertion - stmt->SetData(3, strMotd); // motd text for ON DUPLICATE KEY UPDATE trans->Append(stmt); } // Commit the transaction & update db LoginDatabase.CommitTransaction(trans); - // Update the in-memory maps for the current realm. Otherwise, do not update - if (realmId == -1 || realmId == static_cast(realm.Id.Realm)) - sMotdMgr->SetMotd(strMotd, localeConstant); - - handler->PSendSysMessage(LANG_MOTD_NEW, realmId.value(), locale.value(), strMotd); + sMotdMgr->SetMotd(strMotd, localeConstant); + handler->PSendSysMessage(LANG_MOTD_NEW, realmId.value(), locale, strMotd); return true; } From 777f7ed9357c30748c6842b5fa433b785eb65258 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 27 Jan 2025 10:11:36 +0000 Subject: [PATCH 24/33] chore(DB): import pending files Referenced commit(s): 9b3d54dd6078698396ea473559f8f537684024cc --- .../rev_1737663805709739900.sql => db_world/2025_01_27_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1737663805709739900.sql => db_world/2025_01_27_00.sql} (89%) diff --git a/data/sql/updates/pending_db_world/rev_1737663805709739900.sql b/data/sql/updates/db_world/2025_01_27_00.sql similarity index 89% rename from data/sql/updates/pending_db_world/rev_1737663805709739900.sql rename to data/sql/updates/db_world/2025_01_27_00.sql index 17c56398a..a4d0d0138 100644 --- a/data/sql/updates/pending_db_world/rev_1737663805709739900.sql +++ b/data/sql/updates/db_world/2025_01_27_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_26_02 -> 2025_01_27_00 -- DELETE FROM `acore_string` WHERE `entry` IN (56, 82); INSERT INTO `acore_string` (`entry`, `content_default`, `locale_deDE`, `locale_zhCN`, `locale_esES`, `locale_esMX`) VALUES From ed99f050faa61307a159963f5e20d1e1ab0d55ae Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 27 Jan 2025 07:34:59 -0300 Subject: [PATCH 25/33] fix(Scripts/MagisterTerrace): Rescript Kael's intro (#21278) --- .../rev_1737933911029419400.sql | 26 +++++++++++ .../boss_felblood_kaelthas.cpp | 46 +++++++++---------- .../instance_magisters_terrace.cpp | 1 + .../MagistersTerrace/magisters_terrace.h | 6 ++- 4 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1737933911029419400.sql diff --git a/data/sql/updates/pending_db_world/rev_1737933911029419400.sql b/data/sql/updates/pending_db_world/rev_1737933911029419400.sql new file mode 100644 index 000000000..d0de6c8e8 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1737933911029419400.sql @@ -0,0 +1,26 @@ +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra` |134217728 WHERE `entry` IN (24698, 24684, 24697, 24696, 24683, 24686); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -96841) AND (`source_type` = 0) AND (`id` IN (0)); +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 +(-96841, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 205, 3, 1, 0, 0, 0, 0, 0, 0, 'Coilskar Witch - On Just Died - Felblood Kaeltas Do Action ID 0'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -96781) AND (`source_type` = 0) AND (`id` IN (0)); +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 +(-96781, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 205, 3, 1, 0, 0, 0, 0, 0, 0, 'Sunblade Blood Knight - On Just Died - Felblood Kaeltas Do Action ID 0'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -96809) AND (`source_type` = 0) AND (`id` IN (0)); +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 +(-96809, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 205, 3, 1, 0, 0, 0, 0, 0, 0, 'Sunblade Warlock - On Just Died - Felblood Kaeltas Do Action ID 0'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -96770) AND (`source_type` = 0) AND (`id` IN (0)); +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 +(-96770, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 205, 3, 1, 0, 0, 0, 0, 0, 0, 'Sunblade Mage Guard - On Just Died - Felblood Kaeltas Do Action ID 0'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -96850) AND (`source_type` = 0) AND (`id` IN (0)); +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 +(-96850, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 205, 3, 1, 0, 0, 0, 0, 0, 0, 'Ethereum Smuggler - On Just Died - Felblood Kaeltas Do Action ID 0'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -96847) AND (`source_type` = 0) AND (`id` IN (0)); +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 +(-96847, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 205, 3, 1, 0, 0, 0, 0, 0, 0, 'Sister of Torment - On Just Died - Felblood Kaeltas Do Action ID 0'); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 88eb14b6f..61bb9f333 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -67,10 +67,7 @@ enum Misc struct boss_felblood_kaelthas : public BossAI { - boss_felblood_kaelthas(Creature* creature) : BossAI(creature, DATA_KAELTHAS) - { - _hasDoneIntro = false; - } + boss_felblood_kaelthas(Creature* creature) : BossAI(creature, DATA_KAELTHAS) { } void Reset() override { @@ -78,7 +75,6 @@ struct boss_felblood_kaelthas : public BossAI _OOCScheduler.CancelAll(); _gravityLapseCounter = 0; me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); - me->SetImmuneToAll(false); ScheduleHealthCheckEvent(50, [&]{ me->CastStop(); @@ -125,12 +121,6 @@ struct boss_felblood_kaelthas : public BossAI }); } - void InitializeAI() override - { - BossAI::InitializeAI(); - me->SetImmuneToAll(true); - } - void JustDied(Unit* killer) override { BossAI::JustDied(killer); @@ -161,20 +151,31 @@ struct boss_felblood_kaelthas : public BossAI }, 50s); } - void MoveInLineOfSight(Unit* who) override + void DoAction(int32 actionId) override { - if (!_hasDoneIntro && me->IsWithinDistInMap(who, 40.0f) && who->IsPlayer()) + if (actionId == DATA_KAEL_INTRO) { - Talk(SAY_AGGRO); - Talk(SAY_AGGRO_2, 20s); - _hasDoneIntro = true; - _OOCScheduler.Schedule(35s, [this](TaskContext){ - me->SetReactState(REACT_AGGRESSIVE); - me->SetImmuneToAll(false); - me->SetInCombatWithZone(); - }); + uint32 counter = instance->GetPersistentData(DATA_KAEL_INTRO); + instance->StorePersistentData(DATA_KAEL_INTRO, ++counter); + + if (counter == 6 && !me->IsInCombat()) + { + me->SetEmoteState(EMOTE_STATE_TALK); + Talk(SAY_AGGRO); + + me->m_Events.AddEventAtOffset([&] { + me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH_NO_SHEATHE); + }, 15s); + + Talk(SAY_AGGRO_2, 20s); + me->SetImmuneToAll(true); + _OOCScheduler.Schedule(35s, [this](TaskContext) { + me->ClearEmoteState(); + me->SetReactState(REACT_AGGRESSIVE); + me->SetImmuneToAll(false); + }); + } } - BossAI::MoveInLineOfSight(who); } void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override @@ -229,7 +230,6 @@ struct boss_felblood_kaelthas : public BossAI } private: TaskScheduler _OOCScheduler; - bool _hasDoneIntro; uint8 _gravityLapseCounter; }; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp index ac265bcec..5971f8369 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp @@ -64,6 +64,7 @@ public: { SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTER); + SetPersistentDataCount(MAX_PERSISTENT_DATA); LoadObjectData(creatureData, gameobjectData); LoadDoorData(doorData); LoadSummonData(summonerData); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h index 44d66b8cf..35b04fc67 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h @@ -32,7 +32,11 @@ enum MTData MAX_ENCOUNTER = 4, DATA_KALECGOS = 5, - DATA_ESCAPE_ORB = 6 + DATA_ESCAPE_ORB = 6, + + // Persistent data + DATA_KAEL_INTRO = 0, + MAX_PERSISTENT_DATA = 1 }; enum MTCreatures From fb3fd37c6e0b1e639d347cda8894c7d8b043a62b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 27 Jan 2025 10:36:14 +0000 Subject: [PATCH 26/33] chore(DB): import pending files Referenced commit(s): ed99f050faa61307a159963f5e20d1e1ab0d55ae --- .../rev_1737933911029419400.sql => db_world/2025_01_27_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1737933911029419400.sql => db_world/2025_01_27_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1737933911029419400.sql b/data/sql/updates/db_world/2025_01_27_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1737933911029419400.sql rename to data/sql/updates/db_world/2025_01_27_01.sql index d0de6c8e8..0891dbedf 100644 --- a/data/sql/updates/pending_db_world/rev_1737933911029419400.sql +++ b/data/sql/updates/db_world/2025_01_27_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_27_00 -> 2025_01_27_01 -- UPDATE `creature_template` SET `flags_extra` = `flags_extra` |134217728 WHERE `entry` IN (24698, 24684, 24697, 24696, 24683, 24686); From 33eedba1bf53b03ced5b59de0f7d558e9e55fd9f Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 27 Jan 2025 09:48:50 -0600 Subject: [PATCH 27/33] fix(DB/SAI) Fix Amani Trainer Abilities (#21269) --- .../updates/pending_db_world/rev_1737768610786833000.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1737768610786833000.sql diff --git a/data/sql/updates/pending_db_world/rev_1737768610786833000.sql b/data/sql/updates/pending_db_world/rev_1737768610786833000.sql new file mode 100644 index 000000000..da55b9c66 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1737768610786833000.sql @@ -0,0 +1,7 @@ +-- Fix Amani Trainer Abilities +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23774; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23774) AND (`source_type` = 0) AND (`id` IN (0, 1)); +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 +(23774, 0, 0, 0, 0, 0, 100, 0, 5000, 8000, 12000, 15000, 0, 0, 11, 43292, 0, 0, 0, 0, 0, 19, 23834, 30, 0, 0, 0, 0, 0, 0, 'Target Amashi Dragonhawk for Incite Rage'), +(23774, 0, 1, 0, 0, 0, 100, 0, 10000, 12000, 20000, 25000, 0, 0, 11, 20989, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Cast Sleep on Random Enemy'); From d5e68136bf737901e72866295bb29650c76432d4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 27 Jan 2025 15:49:51 +0000 Subject: [PATCH 28/33] chore(DB): import pending files Referenced commit(s): 33eedba1bf53b03ced5b59de0f7d558e9e55fd9f --- .../rev_1737768610786833000.sql => db_world/2025_01_27_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1737768610786833000.sql => db_world/2025_01_27_02.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1737768610786833000.sql b/data/sql/updates/db_world/2025_01_27_02.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1737768610786833000.sql rename to data/sql/updates/db_world/2025_01_27_02.sql index da55b9c66..29f1c98cb 100644 --- a/data/sql/updates/pending_db_world/rev_1737768610786833000.sql +++ b/data/sql/updates/db_world/2025_01_27_02.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_27_01 -> 2025_01_27_02 -- Fix Amani Trainer Abilities UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23774; From 1c036f69d1dd267ee843efc26019dbab5b9cc9a0 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:42:12 +0100 Subject: [PATCH 29/33] fix(DB/Creature) Update Amani Trainer SmartAI comments. (#21282) --- .../sql/updates/pending_db_world/Amani_Trainer_Comment.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Amani_Trainer_Comment.sql diff --git a/data/sql/updates/pending_db_world/Amani_Trainer_Comment.sql b/data/sql/updates/pending_db_world/Amani_Trainer_Comment.sql new file mode 100644 index 000000000..b5273794a --- /dev/null +++ b/data/sql/updates/pending_db_world/Amani_Trainer_Comment.sql @@ -0,0 +1,7 @@ + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23774; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23774); +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 +(23774, 0, 0, 0, 0, 0, 100, 0, 5000, 8000, 12000, 15000, 0, 0, 11, 43292, 0, 0, 0, 0, 0, 19, 23834, 30, 0, 0, 0, 0, 0, 0, 'Amani\'shi Trainer - In Combat - Cast \'Incite Rage\''), +(23774, 0, 1, 0, 0, 0, 100, 0, 10000, 12000, 20000, 25000, 0, 0, 11, 20989, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Amani\'shi Trainer - In Combat - Cast \'Sleep\''); From dfd09a3541f3be672c3e2ff3a0a431547a229d3b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 28 Jan 2025 09:43:13 +0000 Subject: [PATCH 30/33] chore(DB): import pending files Referenced commit(s): 1c036f69d1dd267ee843efc26019dbab5b9cc9a0 --- .../Amani_Trainer_Comment.sql => db_world/2025_01_28_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Amani_Trainer_Comment.sql => db_world/2025_01_28_00.sql} (95%) diff --git a/data/sql/updates/pending_db_world/Amani_Trainer_Comment.sql b/data/sql/updates/db_world/2025_01_28_00.sql similarity index 95% rename from data/sql/updates/pending_db_world/Amani_Trainer_Comment.sql rename to data/sql/updates/db_world/2025_01_28_00.sql index b5273794a..4b0445d8e 100644 --- a/data/sql/updates/pending_db_world/Amani_Trainer_Comment.sql +++ b/data/sql/updates/db_world/2025_01_28_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_01_27_02 -> 2025_01_28_00 UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23774; From 18cb8f7d6c487187d472352e4e1647b9fe9fdc06 Mon Sep 17 00:00:00 2001 From: vrachv <52053491+vrachv@users.noreply.github.com> Date: Wed, 29 Jan 2025 05:47:34 +0000 Subject: [PATCH 31/33] fix(Scripts/SunwellPlateau): Fix Madrigosa flight movement (#21290) --- .../EasternKingdoms/SunwellPlateau/boss_brutallus.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp index 74d7ff147..6f464d7d1 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp @@ -189,10 +189,12 @@ struct npc_madrigosa : public NullCreatureAI { if (param == ACTION_START_EVENT) { + me->NearTeleportTo(1570.97f, 725.51f, 79.77f, 3.82f); me->SetDisableGravity(true); me->SetStandState(UNIT_STAND_STATE_STAND); me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD); - me->NearTeleportTo(1570.97f, 725.51f, 79.77f, 3.82f); + me->SendMovementFlagUpdate(); + events.ScheduleEvent(EVENT_MAD_1, 2000); } else if (param == ACTION_SPAWN_FELMYST) @@ -212,9 +214,9 @@ struct npc_madrigosa : public NullCreatureAI brutallus->SetReactState(REACT_PASSIVE); brutallus->setActive(true); } - me->GetMotionMaster()->MovePoint(1, 1477.94f, 643.22f, 21.21f); + me->GetMotionMaster()->MoveTakeoff(1, 1477.94f, 643.22f, 21.21f); me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD); - events.ScheduleEvent(EVENT_MAD_2, 6000); + events.ScheduleEvent(EVENT_MAD_2, 4000); break; case EVENT_MAD_2: Talk(SAY_MAD_1); From 2809f70dc16dbe3b1df9651ed37de0ddecd89310 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Wed, 29 Jan 2025 06:27:30 -0300 Subject: [PATCH 32/33] =?UTF-8?q?fix(Scripts/MagisterTerrace):=20Fix=20Kae?= =?UTF-8?q?l's=20outro=20and=20close=20door=20during=20=E2=80=A6=20(#21289?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boss_felblood_kaelthas.cpp | 49 +++++++++++++------ .../instance_magisters_terrace.cpp | 1 + 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 61bb9f333..8feeadedc 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -52,7 +52,12 @@ enum Spells SPELL_GRAVITY_LAPSE_FLY = 44227, SPELL_GRAVITY_LAPSE_DOT = 44226, SPELL_GRAVITY_LAPSE_CHANNEL = 44251, - SPELL_POWER_FEEDBACK = 44233 + SPELL_POWER_FEEDBACK = 44233, + SPELL_CLEAR_FLIGHT = 44232, // Does nothing currently + + SPELL_EMOTE_EXCLAMATION = 48348, + SPELL_EMOTE_POINT = 48349, + SPELL_EMOTE_ROAR = 48350 }; enum Misc @@ -72,7 +77,6 @@ struct boss_felblood_kaelthas : public BossAI void Reset() override { BossAI::Reset(); - _OOCScheduler.CancelAll(); _gravityLapseCounter = 0; me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); @@ -169,11 +173,12 @@ struct boss_felblood_kaelthas : public BossAI Talk(SAY_AGGRO_2, 20s); me->SetImmuneToAll(true); - _OOCScheduler.Schedule(35s, [this](TaskContext) { + + me->m_Events.AddEventAtOffset([&] { me->ClearEmoteState(); me->SetReactState(REACT_AGGRESSIVE); me->SetImmuneToAll(false); - }); + }, 35s); } } } @@ -185,19 +190,35 @@ struct boss_felblood_kaelthas : public BossAI damage = me->GetHealth() - 1; if (me->isRegeneratingHealth()) { + me->CombatStop(); me->CastStop(); me->SetRegeneratingHealth(false); me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE); me->SetImmuneToAll(true); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - me->CombatStop(); me->SetReactState(REACT_PASSIVE); LapseAction(ACTION_REMOVE_FLY); scheduler.CancelAll(); - _OOCScheduler.Schedule(6s, [this](TaskContext){ - me->KillSelf(); - }); + summons.DespawnAll(); + Talk(SAY_DEATH); + DoCastSelf(SPELL_EMOTE_EXCLAMATION); + + me->m_Events.AddEventAtOffset([&] { + DoCastSelf(SPELL_EMOTE_POINT); + }, 3s); + + me->m_Events.AddEventAtOffset([&] { + DoCastSelf(SPELL_EMOTE_ROAR); + }, 7s); + + me->m_Events.AddEventAtOffset([&] { + DoCastSelf(SPELL_EMOTE_ROAR); + DoCastSelf(SPELL_CLEAR_FLIGHT); + }, 9s); + + me->m_Events.AddEventAtOffset([&] { + me->KillSelf(); + }, 11s); } } BossAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask); @@ -208,6 +229,9 @@ struct boss_felblood_kaelthas : public BossAI _gravityLapseCounter = 0; me->GetMap()->DoForAllPlayers([&](Player* player) { + if (player->IsGameMaster()) + return; + if (action == ACTION_TELEPORT_PLAYERS) DoCast(player, SPELL_GRAVITY_LAPSE_PLAYER + _gravityLapseCounter, true); else if (action == ACTION_KNOCKUP) @@ -222,14 +246,7 @@ struct boss_felblood_kaelthas : public BossAI ++_gravityLapseCounter; }); } - - void UpdateAI(uint32 diff) override - { - _OOCScheduler.Update(diff); - BossAI::UpdateAI(diff); - } private: - TaskScheduler _OOCScheduler; uint8 _gravityLapseCounter; }; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp index 5971f8369..74308a0bb 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp @@ -48,6 +48,7 @@ DoorData const doorData[] = { GO_SELIN_ENCOUNTER_DOOR, DATA_SELIN_FIREHEART, DOOR_TYPE_ROOM }, { GO_VEXALLUS_DOOR, DATA_VEXALLUS, DOOR_TYPE_PASSAGE }, { GO_DELRISSA_DOOR, DATA_DELRISSA, DOOR_TYPE_PASSAGE }, + { GO_KAEL_DOOR, DATA_KAELTHAS, DOOR_TYPE_ROOM }, { 0, 0, DOOR_TYPE_ROOM } // END }; From ca51e7fc222ffa55b0efcf59434632c503a488d3 Mon Sep 17 00:00:00 2001 From: vrachv Date: Thu, 30 Jan 2025 10:26:56 +0000 Subject: [PATCH 33/33] fix(Scripts/SunwellPlateau): Fix Felmyst start fight (#21291) --- .../scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index 5c94a549f..4d57ab7fb 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -333,11 +333,11 @@ struct boss_felmyst : public BossAI void UpdateAI(uint32 diff) override { + scheduler.Update(diff); + if (!UpdateVictim()) return; - scheduler.Update(diff); - if (!me->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) DoMeleeAttackIfReady(); }