From baf67c36f254ee80137ae3b0f4f1855d05f1617d Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Tue, 23 Dec 2025 21:39:34 -0600 Subject: [PATCH 01/34] Closes #1612 Closes #1612 --- etc/databases/world/updates/updates.sql | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 62d6951c8..94e5795ee 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13716,6 +13716,37 @@ begin not atomic insert into applied_updates values ('171220251'); end if; + -- 23/12/2025 1 + if (select count(*) from applied_updates where id='231220251') = 0 then + -- Fix Engineering items. + UPDATE `item_template` SET `display_id` = '7435' WHERE (`entry` = '4358'); + UPDATE `item_template` SET `display_id` = '7435' WHERE (`entry` = '4378'); + UPDATE `item_template` SET `display_id` = '7435' WHERE (`entry` = '10507'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4358'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4378'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4367'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4398'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4370'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4406'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4375'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4376'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4381'); + UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4388'); + + -- Bandages. + UPDATE `item_template` SET `spellid_1` = '746', `spellcharges_1` = '-1', `spellcooldown_1` = '60000', `spellcategory_1` = '150', `spellcategorycooldown_1` = '60000' WHERE (`entry` = '1251'); + UPDATE `item_template` SET `spellid_1` = '1159', `spellcharges_1` = '-1', `spellcooldown_1` = '60000', `spellcategory_1` = '150', `spellcategorycooldown_1` = '60000' WHERE (`entry` = '2581'); + + -- Burning War Axe. + UPDATE `item_template` SET `spellid_1` = '7711', `spellcharges_1` = '-1' WHERE (`entry` = '2299'); + + insert into applied_updates values ('231220251'); + end if; + + + + + end $ delimiter ; From ab096919dd589dccd80059061a91107213743c57 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Tue, 23 Dec 2025 22:58:28 -0600 Subject: [PATCH 02/34] Closes #1607 Closes #1607 --- etc/databases/world/updates/updates.sql | 56 ++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 94e5795ee..ccd656d64 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13740,13 +13740,59 @@ begin not atomic -- Burning War Axe. UPDATE `item_template` SET `spellid_1` = '7711', `spellcharges_1` = '-1' WHERE (`entry` = '2299'); - insert into applied_updates values ('231220251'); - end if; - - - + -- Thundersnout. + UPDATE `creature_template` SET `detection_range` = '20' WHERE (`entry` = '5055'); + UPDATE `creature_template` SET `unit_class` = '2' WHERE (`entry` = '5055'); + UPDATE `creature_template` SET `health_multiplier` = '0.231', `mana_multiplier` = '0.859' WHERE (`entry` = '5055'); + UPDATE `creature_template` SET `damage_multiplier` = '1' WHERE (`entry` = '5055'); + -- New creature spell lists. + REPLACE INTO `creature_spells` (`entry`, `name`, `spellId_1`, `probability_1`, `castTarget_1`, `targetParam1_1`, `targetParam2_1`, `castFlags_1`, `delayInitialMin_1`, `delayInitialMax_1`, `delayRepeatMin_1`, `delayRepeatMax_1`, `scriptId_1`, `spellId_2`, `probability_2`, `castTarget_2`, `targetParam1_2`, `targetParam2_2`, `castFlags_2`, `delayInitialMin_2`, `delayInitialMax_2`, `delayRepeatMin_2`, `delayRepeatMax_2`, `scriptId_2`, `spellId_3`, `probability_3`, `castTarget_3`, `targetParam1_3`, `targetParam2_3`, `castFlags_3`, `delayInitialMin_3`, `delayInitialMax_3`, `delayRepeatMin_3`, `delayRepeatMax_3`, `scriptId_3`, `spellId_4`, `probability_4`, `castTarget_4`, `targetParam1_4`, `targetParam2_4`, `castFlags_4`, `delayInitialMin_4`, `delayInitialMax_4`, `delayRepeatMin_4`, `delayRepeatMax_4`, `scriptId_4`, `spellId_5`, `probability_5`, `castTarget_5`, `targetParam1_5`, `targetParam2_5`, `castFlags_5`, `delayInitialMin_5`, `delayInitialMax_5`, `delayRepeatMin_5`, `delayRepeatMax_5`, `scriptId_5`, `spellId_6`, `probability_6`, `castTarget_6`, `targetParam1_6`, `targetParam2_6`, `castFlags_6`, `delayInitialMin_6`, `delayInitialMax_6`, `delayRepeatMin_6`, `delayRepeatMax_6`, `scriptId_6`, `spellId_7`, `probability_7`, `castTarget_7`, `targetParam1_7`, `targetParam2_7`, `castFlags_7`, `delayInitialMin_7`, `delayInitialMax_7`, `delayRepeatMin_7`, `delayRepeatMax_7`, `scriptId_7`, `spellId_8`, `probability_8`, `castTarget_8`, `targetParam1_8`, `targetParam2_8`, `castFlags_8`, `delayInitialMin_8`, `delayInitialMax_8`, `delayRepeatMin_8`, `delayRepeatMax_8`, `scriptId_8`) VALUES (5055, 'Deviate Lasher', 6255, 80, 1, 0, 0, 0, 5, 10, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '18684'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '18685'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '18686'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '18681'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '18680'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '33980'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '33981'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '38126'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '38132'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '38127'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '48752'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '45721'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '85912'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '85918'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '85916'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87111'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '85989'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87112'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '85994'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '85995'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '85996'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '86325'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '86415'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '86105'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87098'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87101'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87102'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87103'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87106'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87110'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87119'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87120'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87135'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87137'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87136'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87148'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87152'); + UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87151'); + + -- Deviate Crocolisks are now non-elite. + UPDATE `creature_template` SET `rank` = '1' WHERE (`entry` = '5053'); + insert into applied_updates values ('231220251'); + end if; end $ delimiter ; From c1b80900fe5d79742b50c2c1605becfe67343fc4 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Wed, 24 Dec 2025 20:09:12 -0600 Subject: [PATCH 03/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index ccd656d64..b8ae784ec 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13733,18 +13733,18 @@ begin not atomic UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4381'); UPDATE `item_template` SET `subclass` = '0' WHERE (`entry` = '4388'); - -- Bandages. - UPDATE `item_template` SET `spellid_1` = '746', `spellcharges_1` = '-1', `spellcooldown_1` = '60000', `spellcategory_1` = '150', `spellcategorycooldown_1` = '60000' WHERE (`entry` = '1251'); - UPDATE `item_template` SET `spellid_1` = '1159', `spellcharges_1` = '-1', `spellcooldown_1` = '60000', `spellcategory_1` = '150', `spellcategorycooldown_1` = '60000' WHERE (`entry` = '2581'); - -- Burning War Axe. UPDATE `item_template` SET `spellid_1` = '7711', `spellcharges_1` = '-1' WHERE (`entry` = '2299'); -- Thundersnout. + UPDATE `creature_template` SET `rank` = '1' WHERE (`entry` = '5055'); + UPDATE `creature_template` SET `damage_multiplier` = '1.7', `health_multiplier` = '2.5', `armor_multiplier` = '1' WHERE (`entry` = '5055'); UPDATE `creature_template` SET `detection_range` = '20' WHERE (`entry` = '5055'); - UPDATE `creature_template` SET `unit_class` = '2' WHERE (`entry` = '5055'); - UPDATE `creature_template` SET `health_multiplier` = '0.231', `mana_multiplier` = '0.859' WHERE (`entry` = '5055'); - UPDATE `creature_template` SET `damage_multiplier` = '1' WHERE (`entry` = '5055'); + + -- Deviate Crocolisks are now non-elite. + UPDATE `creature_template` SET `rank` = '1' WHERE (`entry` = '5053'); + UPDATE `creature_template` SET `damage_multiplier` = '1.7', `health_multiplier` = '2.5', `armor_multiplier` = '1' WHERE (`entry` = '5053'); + UPDATE `creature_template` SET `detection_range` = '20' WHERE (`entry` = '5053'); -- New creature spell lists. REPLACE INTO `creature_spells` (`entry`, `name`, `spellId_1`, `probability_1`, `castTarget_1`, `targetParam1_1`, `targetParam2_1`, `castFlags_1`, `delayInitialMin_1`, `delayInitialMax_1`, `delayRepeatMin_1`, `delayRepeatMax_1`, `scriptId_1`, `spellId_2`, `probability_2`, `castTarget_2`, `targetParam1_2`, `targetParam2_2`, `castFlags_2`, `delayInitialMin_2`, `delayInitialMax_2`, `delayRepeatMin_2`, `delayRepeatMax_2`, `scriptId_2`, `spellId_3`, `probability_3`, `castTarget_3`, `targetParam1_3`, `targetParam2_3`, `castFlags_3`, `delayInitialMin_3`, `delayInitialMax_3`, `delayRepeatMin_3`, `delayRepeatMax_3`, `scriptId_3`, `spellId_4`, `probability_4`, `castTarget_4`, `targetParam1_4`, `targetParam2_4`, `castFlags_4`, `delayInitialMin_4`, `delayInitialMax_4`, `delayRepeatMin_4`, `delayRepeatMax_4`, `scriptId_4`, `spellId_5`, `probability_5`, `castTarget_5`, `targetParam1_5`, `targetParam2_5`, `castFlags_5`, `delayInitialMin_5`, `delayInitialMax_5`, `delayRepeatMin_5`, `delayRepeatMax_5`, `scriptId_5`, `spellId_6`, `probability_6`, `castTarget_6`, `targetParam1_6`, `targetParam2_6`, `castFlags_6`, `delayInitialMin_6`, `delayInitialMax_6`, `delayRepeatMin_6`, `delayRepeatMax_6`, `scriptId_6`, `spellId_7`, `probability_7`, `castTarget_7`, `targetParam1_7`, `targetParam2_7`, `castFlags_7`, `delayInitialMin_7`, `delayInitialMax_7`, `delayRepeatMin_7`, `delayRepeatMax_7`, `scriptId_7`, `spellId_8`, `probability_8`, `castTarget_8`, `targetParam1_8`, `targetParam2_8`, `castFlags_8`, `delayInitialMin_8`, `delayInitialMax_8`, `delayRepeatMin_8`, `delayRepeatMax_8`, `scriptId_8`) VALUES (5055, 'Deviate Lasher', 6255, 80, 1, 0, 0, 0, 5, 10, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); @@ -13788,9 +13788,6 @@ begin not atomic UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87152'); UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87151'); - -- Deviate Crocolisks are now non-elite. - UPDATE `creature_template` SET `rank` = '1' WHERE (`entry` = '5053'); - insert into applied_updates values ('231220251'); end if; From 605c10c76ad291e23c913160f5951e12b50ccf58 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Wed, 24 Dec 2025 20:11:40 -0600 Subject: [PATCH 04/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index b8ae784ec..60b2a3c4b 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13745,6 +13745,7 @@ begin not atomic UPDATE `creature_template` SET `rank` = '1' WHERE (`entry` = '5053'); UPDATE `creature_template` SET `damage_multiplier` = '1.7', `health_multiplier` = '2.5', `armor_multiplier` = '1' WHERE (`entry` = '5053'); UPDATE `creature_template` SET `detection_range` = '20' WHERE (`entry` = '5053'); + UPDATE `creature_template` SET `level_max` = '20' WHERE (`entry` = '5053'); -- New creature spell lists. REPLACE INTO `creature_spells` (`entry`, `name`, `spellId_1`, `probability_1`, `castTarget_1`, `targetParam1_1`, `targetParam2_1`, `castFlags_1`, `delayInitialMin_1`, `delayInitialMax_1`, `delayRepeatMin_1`, `delayRepeatMax_1`, `scriptId_1`, `spellId_2`, `probability_2`, `castTarget_2`, `targetParam1_2`, `targetParam2_2`, `castFlags_2`, `delayInitialMin_2`, `delayInitialMax_2`, `delayRepeatMin_2`, `delayRepeatMax_2`, `scriptId_2`, `spellId_3`, `probability_3`, `castTarget_3`, `targetParam1_3`, `targetParam2_3`, `castFlags_3`, `delayInitialMin_3`, `delayInitialMax_3`, `delayRepeatMin_3`, `delayRepeatMax_3`, `scriptId_3`, `spellId_4`, `probability_4`, `castTarget_4`, `targetParam1_4`, `targetParam2_4`, `castFlags_4`, `delayInitialMin_4`, `delayInitialMax_4`, `delayRepeatMin_4`, `delayRepeatMax_4`, `scriptId_4`, `spellId_5`, `probability_5`, `castTarget_5`, `targetParam1_5`, `targetParam2_5`, `castFlags_5`, `delayInitialMin_5`, `delayInitialMax_5`, `delayRepeatMin_5`, `delayRepeatMax_5`, `scriptId_5`, `spellId_6`, `probability_6`, `castTarget_6`, `targetParam1_6`, `targetParam2_6`, `castFlags_6`, `delayInitialMin_6`, `delayInitialMax_6`, `delayRepeatMin_6`, `delayRepeatMax_6`, `scriptId_6`, `spellId_7`, `probability_7`, `castTarget_7`, `targetParam1_7`, `targetParam2_7`, `castFlags_7`, `delayInitialMin_7`, `delayInitialMax_7`, `delayRepeatMin_7`, `delayRepeatMax_7`, `scriptId_7`, `spellId_8`, `probability_8`, `castTarget_8`, `targetParam1_8`, `targetParam2_8`, `castFlags_8`, `delayInitialMin_8`, `delayInitialMax_8`, `delayRepeatMin_8`, `delayRepeatMax_8`, `scriptId_8`) VALUES (5055, 'Deviate Lasher', 6255, 80, 1, 0, 0, 0, 5, 10, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); From d558d30ef75922edaa7feecc8dc457b9731b26ca Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Fri, 26 Dec 2025 19:31:42 -0600 Subject: [PATCH 05/34] Closes #1614 Closes #1614 --- etc/databases/world/updates/updates.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 60b2a3c4b..53d62a7eb 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13788,6 +13788,9 @@ begin not atomic UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87148'); UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87152'); UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87151'); + + -- https://github.com/The-Alpha-Project/alpha-core/issues/1614 + UPDATE `areatrigger_teleport` SET `target_position_x` = '7200', `target_position_y` = '-838', `target_position_z` = '-2' WHERE (`id` = '259'); insert into applied_updates values ('231220251'); end if; From 9750214abfb0c3435851414f144ffbd416f003d7 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Fri, 26 Dec 2025 19:35:36 -0600 Subject: [PATCH 06/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 53d62a7eb..7ec614d23 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13790,7 +13790,7 @@ begin not atomic UPDATE `spawns_creatures` SET `ignored` = '1' WHERE (`spawn_id` = '87151'); -- https://github.com/The-Alpha-Project/alpha-core/issues/1614 - UPDATE `areatrigger_teleport` SET `target_position_x` = '7200', `target_position_y` = '-838', `target_position_z` = '-2' WHERE (`id` = '259'); + UPDATE `areatrigger_teleport` SET `target_position_x` = '7200', `target_position_y` = '-838', `target_position_z` = '-2', `target_orientation` = '1.69' WHERE (`id` = '259'); insert into applied_updates values ('231220251'); end if; From 2173c593f91dbf03283a9ba7e58ea11ed80ea20b Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Fri, 26 Dec 2025 21:56:39 -0600 Subject: [PATCH 07/34] Closes #1615 --- etc/databases/world/updates/updates.sql | 35 +++++++++++++++++++ .../objects/units/player/PlayerManager.py | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 7ec614d23..8d07c84ac 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13792,6 +13792,41 @@ begin not atomic -- https://github.com/The-Alpha-Project/alpha-core/issues/1614 UPDATE `areatrigger_teleport` SET `target_position_x` = '7200', `target_position_y` = '-838', `target_position_z` = '-2', `target_orientation` = '1.69' WHERE (`id` = '259'); + -- https://github.com/The-Alpha-Project/alpha-core/issues/1615 + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7329.976', `position_y` = '-926.581', `position_z` = '26.886', `ignored` = '0' WHERE (`spawn_id` = '33285'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7330.661', `position_y` = '-956.526', `position_z` = '21.355', `ignored` = '0' WHERE (`spawn_id` = '33286'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7361.977', `position_y` = '-956.526', `position_z` = '15.8', `ignored` = '0' WHERE (`spawn_id` = '33287'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7360.347', `position_y` = '-924.597', `position_z` = '10.244', `ignored` = '0' WHERE (`spawn_id` = '33288'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7331.168', `position_y` = '-969.052', `position_z` = '1.274', `ignored` = '0' WHERE (`spawn_id` = '33289'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7345.075', `position_y` = '-956.467', `position_z` = '-2.549', `ignored` = '0' WHERE (`spawn_id` = '33290'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7335.171', `position_y` = '-994.75', `position_z` = '4.594', `ignored` = '0' WHERE (`spawn_id` = '33291'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7337.593', `position_y` = '-1014.914', `position_z` = '5.07', `ignored` = '0' WHERE (`spawn_id` = '33292'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7324.585', `position_y` = '-1006.85', `position_z` = '7.31', `ignored` = '0' WHERE (`spawn_id` = '33293'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7307.925', `position_y` = '-998.504', `position_z` = '10.407', `ignored` = '0' WHERE (`spawn_id` = '33294'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7291.623', `position_y` = '-1003.646', `position_z` = '13.72', `ignored` = '0' WHERE (`spawn_id` = '33295'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7264.027', `position_y` = '-985.447', `position_z` = '14.062', `ignored` = '0' WHERE (`spawn_id` = '33296'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7242.308', `position_y` = '-986.236', `position_z` = '12.419', `ignored` = '0' WHERE (`spawn_id` = '33297'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7215.997', `position_y` = '-1001.37', `position_z` = '8.272', `ignored` = '0' WHERE (`spawn_id` = '33298'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7218.884', `position_y` = '-1023.406', `position_z` = '5.734', `ignored` = '0' WHERE (`spawn_id` = '33299'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7186.713', `position_y` = '-1018.934', `position_z` = '6.373', `ignored` = '0' WHERE (`spawn_id` = '33300'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7172.797', `position_y` = '-976.058', `position_z` = '7.43', `ignored` = '0' WHERE (`spawn_id` = '33302'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7220.33', `position_y` = '-1024.405', `position_z` = '5.534', `ignored` = '0' WHERE (`spawn_id` = '33303'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7181.906', `position_y` = '-966.99', `position_z` = '8.068', `ignored` = '0' WHERE (`spawn_id` = '33304'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7198.093', `position_y` = '-952.203', `position_z` = '13.206', `ignored` = '0' WHERE (`spawn_id` = '33305'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7210.375', `position_y` = '-933.342', `position_z` = '19.135', `ignored` = '0' WHERE (`spawn_id` = '33306'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7215.71', `position_y` = '-903.382', `position_z` = '13.826', `ignored` = '0' WHERE (`spawn_id` = '33307'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7234.793', `position_y` = '-876.929', `position_z` = '5.612', `ignored` = '0' WHERE (`spawn_id` = '33308'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7226.869', `position_y` = '-847.338', `position_z` = '1.036', `ignored` = '0' WHERE (`spawn_id` = '33309'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7238.033', `position_y` = '-830.053', `position_z` = '-0.934', `ignored` = '0' WHERE (`spawn_id` = '33310'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7261.411', `position_y` = '-822.074', `position_z` = '-6.646', `ignored` = '0' WHERE (`spawn_id` = '33311'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7228.346', `position_y` = '-817.803', `position_z` = '-2.083', `ignored` = '0' WHERE (`spawn_id` = '33312'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7200.409', `position_y` = '-832.39', `position_z` = '-3.295', `ignored` = '0' WHERE (`spawn_id` = '38665'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7197.827', `position_y` = '-809.274', `position_z` = '-5.784', `ignored` = '0' WHERE (`spawn_id` = '38666'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7234.529', `position_y` = '-853.076', `position_z` = '1.142', `ignored` = '0' WHERE (`spawn_id` = '38808'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7225.653', `position_y` = '-869.667', `position_z` = '3.192', `ignored` = '0' WHERE (`spawn_id` = '38974'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7162.353', `position_y` = '-987.953', `position_z` = '5.219', `ignored` = '0' WHERE (`spawn_id` = '38976'); + UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7154.26', `position_y` = '-976.811', `position_z` = '5.219', `ignored` = '0' WHERE (`spawn_id` = '38977'); + insert into applied_updates values ('231220251'); end if; diff --git a/game/world/managers/objects/units/player/PlayerManager.py b/game/world/managers/objects/units/player/PlayerManager.py index 96850f584..4682d41f3 100644 --- a/game/world/managers/objects/units/player/PlayerManager.py +++ b/game/world/managers/objects/units/player/PlayerManager.py @@ -540,7 +540,7 @@ def trigger_teleport(self): pending_teleport.destination_location.z, pending_teleport.destination_location.o, self.pitch, - MoveFlags.MOVEFLAG_NONE + MoveFlags.MOVEFLAG_NONE if not self.collision_cheat else MoveFlags.MOVEFLAG_DONTCOLLIDE ) self.enqueue_packet(PacketWriter.get_packet(OpCode.MSG_MOVE_TELEPORT_ACK, data)) From e791f740db8be38033b424a79e826c10d547c49c Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Fri, 26 Dec 2025 23:38:24 -0600 Subject: [PATCH 08/34] Closes #1616 --- etc/databases/world/updates/updates.sql | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 8d07c84ac..15f4a91d6 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13791,6 +13791,8 @@ begin not atomic -- https://github.com/The-Alpha-Project/alpha-core/issues/1614 UPDATE `areatrigger_teleport` SET `target_position_x` = '7200', `target_position_y` = '-838', `target_position_z` = '-2', `target_orientation` = '1.69' WHERE (`id` = '259'); + UPDATE `worldports` SET `x` = '7200', `y` = '-838', `z` = '-2', `o` = '4.60' WHERE (`entry` = '116'); + UPDATE `worldports` SET `x` = '7200', `y` = '-838', `z` = '-2', `o` = '4.60' WHERE (`entry` = '115'); -- https://github.com/The-Alpha-Project/alpha-core/issues/1615 UPDATE `spawns_creatures` SET `spawn_entry2` = '4803', `position_x` = '7329.976', `position_y` = '-926.581', `position_z` = '26.886', `ignored` = '0' WHERE (`spawn_id` = '33285'); @@ -13827,6 +13829,50 @@ begin not atomic UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7162.353', `position_y` = '-987.953', `position_z` = '5.219', `ignored` = '0' WHERE (`spawn_id` = '38976'); UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7154.26', `position_y` = '-976.811', `position_z` = '5.219', `ignored` = '0' WHERE (`spawn_id` = '38977'); + -- Sapphire of Aku'Mai. + UPDATE `gameobject_template` SET `displayId` = '219' WHERE (`entry` = '178186'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7170.637', `spawn_positionY` = '-835.637', `spawn_positionZ` = '-4.33', `ignored` = '0' WHERE (`spawn_id` = '47700'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7207.226', `spawn_positionY` = '-820.836', `spawn_positionZ` = '-4.359', `ignored` = '0' WHERE (`spawn_id` = '47701'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7194.21', `spawn_positionY` = '-822.588', `spawn_positionZ` = '-2.327', `ignored` = '0' WHERE (`spawn_id` = '47702'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7240.419', `spawn_positionY` = '-801.943', `spawn_positionZ` = '-0.804', `ignored` = '0' WHERE (`spawn_id` = '47703'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7242.694', `spawn_positionY` = '-796.015', `spawn_positionZ` = '-0.703', `ignored` = '0' WHERE (`spawn_id` = '12597'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7218.879', `spawn_positionY` = '-856.85', `spawn_positionZ` = '1.475', `ignored` = '0' WHERE (`spawn_id` = '12680'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7230.974', `spawn_positionY` = '-889.777', `spawn_positionZ` = '8.922', `ignored` = '0' WHERE (`spawn_id` = '12737'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7207.672', `spawn_positionY` = '-922.717', `spawn_positionZ` = '19.06', `ignored` = '0' WHERE (`spawn_id` = '12971'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7188.083', `spawn_positionY` = '-969.881', `spawn_positionZ` = '9.085', `ignored` = '0' WHERE (`spawn_id` = '12974'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7143.786', `spawn_positionY` = '-1009.911', `spawn_positionZ` = '1.745', `ignored` = '0' WHERE (`spawn_id` = '12975'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7150.199', `spawn_positionY` = '-978.224', `spawn_positionZ` = '1.997', `ignored` = '0' WHERE (`spawn_id` = '12976'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7134.333', `spawn_positionY` = '-972.33', `spawn_positionZ` = '1.834', `ignored` = '0' WHERE (`spawn_id` = '47704'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7172.979', `spawn_positionY` = '-1008.211', `spawn_positionZ` = '8.581', `ignored` = '0' WHERE (`spawn_id` = '47705'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7215.15', `spawn_positionY` = '-1031.327', `spawn_positionZ` = '5.573', `ignored` = '0' WHERE (`spawn_id` = '47706'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7204.904', `spawn_positionY` = '-990.651', `spawn_positionZ` = '12.862', `ignored` = '0' WHERE (`spawn_id` = '48527'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7258.449', `spawn_positionY` = '-992.256', `spawn_positionZ` = '15.103', `ignored` = '0' WHERE (`spawn_id` = '66114'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7290.677', `spawn_positionY` = '-987.456', `spawn_positionZ` = '12.206', `ignored` = '0' WHERE (`spawn_id` = '66117'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7323.686', `spawn_positionY` = '-1011.742', `spawn_positionZ` = '8.448', `ignored` = '0' WHERE (`spawn_id` = '12607'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7353.294', `spawn_positionY` = '-1004.24', `spawn_positionZ` = '4.619', `ignored` = '0' WHERE (`spawn_id` = '12608'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7344.894', `spawn_positionY` = '-979.081', `spawn_positionZ` = '5.518', `ignored` = '0' WHERE (`spawn_id` = '12633'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7339.358', `spawn_positionY` = '-936.26', `spawn_positionZ` = '-5.943', `ignored` = '0' WHERE (`spawn_id` = '12970'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7361.472', `spawn_positionY` = '-946.255', `spawn_positionZ` = '-2.422', `ignored` = '0' WHERE (`spawn_id` = '12973'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7232.584', `spawn_positionY` = '-1088.886', `spawn_positionZ` = '-2.906', `ignored` = '0' WHERE (`spawn_id` = '12977'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7236.339', `spawn_positionY` = '-1071.187', `spawn_positionZ` = '-1.655', `ignored` = '0' WHERE (`spawn_id` = '47708'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7231.96', `spawn_positionY` = '-1029.418', `spawn_positionZ` = '5.442', `ignored` = '0' WHERE (`spawn_id` = '47709'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7202.164', `spawn_positionY` = '-1047.757', `spawn_positionZ` = '0.243', `ignored` = '0' WHERE (`spawn_id` = '47710'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7206.83', `spawn_positionY` = '-1054.763', `spawn_positionZ` = '3.452', `ignored` = '0' WHERE (`spawn_id` = '47711'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7187.108', `spawn_positionY` = '-1056.761', `spawn_positionZ` = '3.699', `ignored` = '0' WHERE (`spawn_id` = '55103'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7221.238', `spawn_positionY` = '-873.562', `spawn_positionZ` = '4.657', `ignored` = '0' WHERE (`spawn_id` = '55104'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7228.259', `spawn_positionY` = '-806.796', `spawn_positionZ` = '-2.275', `ignored` = '0' WHERE (`spawn_id` = '55105'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7269.82', `spawn_positionY` = '-816.293', `spawn_positionZ` = '-6.59', `ignored` = '0' WHERE (`spawn_id` = '55106'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7254.73', `spawn_positionY` = '-829.8', `spawn_positionZ` = '-1.72', `ignored` = '0' WHERE (`spawn_id` = '55191'); + + -- Bruiseweed. + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7232.22', `spawn_positionY` = '-912.841', `spawn_positionZ` = '15.0677' WHERE (`spawn_id` = '68490'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7227', `spawn_positionY` = '-813.303', `spawn_positionZ` = '-2.444' WHERE (`spawn_id` = '68497'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7293.99', `spawn_positionY` = '-1007.82', `spawn_positionZ` = '14.1899' WHERE (`spawn_id` = '68491'); + + -- Clamps. + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7190.36', `spawn_positionY` = '-801.884', `spawn_positionZ` = '-6.08355' WHERE (`spawn_id` = '48046'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7168.23', `spawn_positionY` = '-770.48', `spawn_positionZ` = '-5.91007' WHERE (`spawn_id` = '48047'); + insert into applied_updates values ('231220251'); end if; From 38182ebd3cdf3cbefcdeac62c0dd1ee2b306029e Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Fri, 26 Dec 2025 23:41:39 -0600 Subject: [PATCH 09/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 15f4a91d6..64695a730 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13866,7 +13866,7 @@ begin not atomic -- Bruiseweed. UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7232.22', `spawn_positionY` = '-912.841', `spawn_positionZ` = '15.0677' WHERE (`spawn_id` = '68490'); - UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7227', `spawn_positionY` = '-813.303', `spawn_positionZ` = '-2.444' WHERE (`spawn_id` = '68497'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7227', `spawn_positionY` = '-813.303', `spawn_positionZ` = '-2.444' WHERE (`spawn_id` = '24253'); UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7293.99', `spawn_positionY` = '-1007.82', `spawn_positionZ` = '14.1899' WHERE (`spawn_id` = '68491'); -- Clamps. From 03e7566562d9746b1cd95f96a1a73dff4327ebfc Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 27 Dec 2025 10:47:27 -0600 Subject: [PATCH 10/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 64695a730..c3e13bbbe 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13869,7 +13869,7 @@ begin not atomic UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7227', `spawn_positionY` = '-813.303', `spawn_positionZ` = '-2.444' WHERE (`spawn_id` = '24253'); UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7293.99', `spawn_positionY` = '-1007.82', `spawn_positionZ` = '14.1899' WHERE (`spawn_id` = '68491'); - -- Clamps. + -- Clams. UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7190.36', `spawn_positionY` = '-801.884', `spawn_positionZ` = '-6.08355' WHERE (`spawn_id` = '48046'); UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7168.23', `spawn_positionY` = '-770.48', `spawn_positionZ` = '-5.91007' WHERE (`spawn_id` = '48047'); From 0b122e910bc540441426367b0007e8b507675eef Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 27 Dec 2025 19:16:35 -0600 Subject: [PATCH 11/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 64695a730..02699fede 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13830,7 +13830,9 @@ begin not atomic UPDATE `spawns_creatures` SET `spawn_entry2` = '4802', `position_x` = '7154.26', `position_y` = '-976.811', `position_z` = '5.219', `ignored` = '0' WHERE (`spawn_id` = '38977'); -- Sapphire of Aku'Mai. + UPDATE `gameobject_template` SET `displayId` = '219' WHERE (`entry` = '178184'); UPDATE `gameobject_template` SET `displayId` = '219' WHERE (`entry` = '178186'); + UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7170.637', `spawn_positionY` = '-835.637', `spawn_positionZ` = '-4.33', `ignored` = '0' WHERE (`spawn_id` = '47700'); UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7207.226', `spawn_positionY` = '-820.836', `spawn_positionZ` = '-4.359', `ignored` = '0' WHERE (`spawn_id` = '47701'); UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7194.21', `spawn_positionY` = '-822.588', `spawn_positionZ` = '-2.327', `ignored` = '0' WHERE (`spawn_id` = '47702'); From 7b984071589711bc8d64620b27cc4e9cb84466b6 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 27 Dec 2025 19:22:12 -0600 Subject: [PATCH 12/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index f2945689d..5c654708a 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13875,6 +13875,15 @@ begin not atomic UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7190.36', `spawn_positionY` = '-801.884', `spawn_positionZ` = '-6.08355' WHERE (`spawn_id` = '48046'); UPDATE `spawns_gameobjects` SET `spawn_positionX` = '7168.23', `spawn_positionY` = '-770.48', `spawn_positionZ` = '-5.91007' WHERE (`spawn_id` = '48047'); + -- Fallenroot Satyr. + UPDATE `spawns_creatures` SET `position_x` = '7213.932', `position_y` = '-832.024', `position_z` = '-2.712', `ignored` = '0' WHERE (`spawn_id` = '33166'); + UPDATE `spawns_creatures` SET `position_x` = '7227.299', `position_y` = '-861.059', `position_z` = '1.865', `ignored` = '0' WHERE (`spawn_id` = '33167'); + UPDATE `spawns_creatures` SET `position_x` = '7225.854', `position_y` = '-912.134', `position_z` = '15.323', `ignored` = '0' WHERE (`spawn_id` = '33168'); + UPDATE `spawns_creatures` SET `position_x` = '7172.837', `position_y` = '-1001.29', `position_z` = '9.511', `ignored` = '0' WHERE (`spawn_id` = '33169'); + UPDATE `spawns_creatures` SET `position_x` = '7198.722', `position_y` = '-1010.773', `position_z` = '7.385', `ignored` = '0' WHERE (`spawn_id` = '33170'); + UPDATE `spawns_creatures` SET `position_x` = '7282.656', `position_y` = '-991.871', `position_z` = '13.75', `ignored` = '0' WHERE (`spawn_id` = '33171'); + UPDATE `spawns_creatures` SET `position_x` = '7340.932', `position_y` = '-1004.148', `position_z` = '3.857', `ignored` = '0' WHERE (`spawn_id` = '33172'); + insert into applied_updates values ('231220251'); end if; From 09f6ae3bf01bf585270194c1b6ea61341d93cce9 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 27 Dec 2025 23:01:48 -0600 Subject: [PATCH 13/34] Address inconsistencies between spell tooltips and the actual effect points calculation. - Spells which are linked to a skill should use skill level and not caster level. - Roll effect points only once. --- .../managers/objects/spell/CastingSpell.py | 64 ++----------------- .../managers/objects/spell/SpellEffect.py | 16 ++++- 2 files changed, 19 insertions(+), 61 deletions(-) diff --git a/game/world/managers/objects/spell/CastingSpell.py b/game/world/managers/objects/spell/CastingSpell.py index 3b700f779..76803a884 100644 --- a/game/world/managers/objects/spell/CastingSpell.py +++ b/game/world/managers/objects/spell/CastingSpell.py @@ -483,66 +483,12 @@ def requires_combo_points(self): def requires_aura_state(self): return self.spell_entry.CasterAuraState != 0 - ''' - TODO: Figure out this for proper spell min max damage calculation. - void __fastcall Spell_C_GetMinMaxPoints(int effectIndex, int a2, int *min, int *max, unsigned int level, int isPet) - { - signed int SpellLevel; // edi - int v10; // eax - double v11; // st7 - char v13; // c0 - double v14; // st7 - int v15; // ecx - int v16; // ecx - int v17; // edi - double v18; // [esp+0h] [ebp-18h] - int dieSides; // [esp+14h] [ebp-4h] - int maxBonus; // [esp+28h] [ebp+10h] - float maxBonusa; // [esp+28h] [ebp+10h] - int minBonus; // [esp+2Ch] [ebp+14h] - - *min = 0; - *max = 0; - if ( effectIndex ) - { - SpellLevel = level; - dieSides = *(_DWORD *)(effectIndex + 4 * a2 + 224); - if ( !level ) - SpellLevel = Spell_C_GetSpellLevel(*(_DWORD *)effectIndex, isPet); - v10 = *(_DWORD *)(effectIndex + 88); - maxBonus = SpellLevel; - if ( v10 > 0 ) - { - SpellLevel -= v10; - maxBonus = SpellLevel; - } - if ( SpellLevel < 0 ) - { - SpellLevel = 0; - maxBonus = 0; - } - v11 = (double)maxBonus * *(float *)(effectIndex + 4 * a2 + 260); - maxBonusa = v11; - minBonus = (__int64)v11; - _floor(maxBonusa); - v18 = maxBonusa; - if ( v13 ) - v14 = _floor(v18); - else - v14 = _ceil(v18); - v15 = SpellLevel * *(_DWORD *)(effectIndex + 4 * a2 + 248) + *(_DWORD *)(effectIndex + 4 * a2 + 236); - *min = v15; - *min = *(_DWORD *)(effectIndex + 4 * a2 + 272) + minBonus + v15; - v16 = dieSides * *(_DWORD *)(effectIndex + 4 * a2 + 236); - *max = v16; - v17 = v16 + *(_DWORD *)(effectIndex + 4 * a2 + 248) * dieSides * SpellLevel; - *max = v17; - *max = *(_DWORD *)(effectIndex + 4 * a2 + 272) + (__int64)v14 + v17; - } - } - ''' def calculate_effective_level(self): - level = self.spell_caster.level + skill = 0 + if self.spell_caster.is_player(): + skill = self.spell_caster.skill_manager.get_skill_value_for_spell_id(self.spell_entry.ID) + + level = self.spell_caster.level if not skill else int(skill / 5) if level > self.spell_entry.MaxLevel > 0: level = self.spell_entry.MaxLevel elif level < self.spell_entry.BaseLevel: diff --git a/game/world/managers/objects/spell/SpellEffect.py b/game/world/managers/objects/spell/SpellEffect.py index dc4eb3d5d..0d8fd6398 100644 --- a/game/world/managers/objects/spell/SpellEffect.py +++ b/game/world/managers/objects/spell/SpellEffect.py @@ -33,6 +33,7 @@ class SpellEffect: caster_effective_level: int effect_index: int + effect_points: int = 0 targets: EffectTargets radius_entry: SpellRadius @@ -50,6 +51,7 @@ def __init__(self, casting_spell, index): self.load_effect(casting_spell.spell_entry, index) self.caster_effective_level = casting_spell.caster_effective_level + self.effect_points = self.get_effect_points() self.targets = EffectTargets(casting_spell, self) self.radius_entry = DbcDatabaseManager.spell_radius_get_by_id(self.radius_index) if self.radius_index else None self.casting_spell = casting_spell @@ -158,8 +160,18 @@ def is_periodic(self): return self.aura_period != 0 def get_effect_points(self) -> int: - rolled_points = random.randint(1, self.die_sides + self.dice_per_level) if self.die_sides != 0 else 0 - return self.base_points + int(self.real_points_per_level * self.caster_effective_level) + rolled_points + if self.effect_points: + return self.effect_points + + # Calculate min and max dice roll values. + min_roll = 1 if self.die_sides != 0 else 0 + max_roll = self.die_sides + self.dice_per_level if self.die_sides != 0 else 0 + + # Roll. + rolled_points = random.randint(min_roll, max_roll) if self.die_sides != 0 else 0 + self.effect_points = self.base_points + int(self.real_points_per_level * self.caster_effective_level) + rolled_points + + return self.effect_points def get_effect_simple_points(self) -> int: return self.base_points + self.base_dice From e85fc757ee4df663d0249da1f29d741e2ebc0cf1 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 27 Dec 2025 23:15:21 -0600 Subject: [PATCH 14/34] Update QuestManager.py --- .../managers/objects/units/player/quest/QuestManager.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/game/world/managers/objects/units/player/quest/QuestManager.py b/game/world/managers/objects/units/player/quest/QuestManager.py index c657a52e8..a3464912c 100644 --- a/game/world/managers/objects/units/player/quest/QuestManager.py +++ b/game/world/managers/objects/units/player/quest/QuestManager.py @@ -821,7 +821,8 @@ def handle_accept_quest(self, quest_id, quest_giver_guid, shared=False, quest_gi self.send_cant_take_quest_response(QuestFailedReasons.QUEST_ALREADY_ON) return - if quest_id in self.completed_quests: + # Only one timed quest can be active. + if self.has_timed_quest(): self.send_cant_take_quest_response(QuestFailedReasons.QUEST_ONLY_ONE_TIMED) return @@ -1281,6 +1282,12 @@ def item_needed_by_quests(self, item_entry): return True return False + def has_timed_quest(self): + for active_quest in list(self.active_quests.values()): + if QuestHelpers.is_timed_quest(active_quest.quest): + return True + return False + def update(self, elapsed): self.last_timer_update += elapsed From 429f180090494565762c423466921d4f24c20c7c Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sun, 28 Dec 2025 00:24:19 -0600 Subject: [PATCH 15/34] SPELL_AURA_MOD_BLOCK_PERCENT Differentiate between shields and bucklers. --- .../objects/spell/aura/AuraEffectHandler.py | 22 ++++++++++++++----- .../managers/objects/units/UnitManager.py | 6 +++++ .../objects/units/player/PlayerManager.py | 21 +++++++++++++++--- .../objects/units/player/StatManager.py | 19 +++++++++++++++- 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/game/world/managers/objects/spell/aura/AuraEffectHandler.py b/game/world/managers/objects/spell/aura/AuraEffectHandler.py index cd7537568..9c7baad59 100644 --- a/game/world/managers/objects/spell/aura/AuraEffectHandler.py +++ b/game/world/managers/objects/spell/aura/AuraEffectHandler.py @@ -5,7 +5,8 @@ from game.world.managers.objects.units.player.StatManager import UnitStats from game.world.managers.objects.spell import ExtendedSpellData from utils.Logger import Logger -from utils.constants.ItemCodes import InventoryError +from utils.constants import ItemCodes +from utils.constants.ItemCodes import InventoryError, ItemSubClasses from utils.constants.MiscCodes import UnitDynamicTypes, ProcFlags from utils.constants.PetCodes import PetSlot from utils.constants.SpellCodes import ShapeshiftForms, AuraTypes, SpellSchoolMask, SpellImmunity @@ -774,16 +775,27 @@ def handle_mod_dodge_chance(aura, effect_target, remove): effect_target.stat_manager.apply_aura_stat_bonus(aura.index, UnitStats.DODGE_CHANCE, amount_percent, percentual=False) - # TODO: Need to have separate blocking stats depending on item subclass. - # e.g. 'Increases your chance to block with a Shield (not a Buckler) by 2%.' @staticmethod def handle_mod_block_chance(aura, effect_target, remove): if remove: effect_target.stat_manager.remove_aura_stat_bonus(aura.index, percentual=False) return + + item_subclass = aura.spell_effect.casting_spell.spell_entry.EquippedItemSubclass + shield_present = item_subclass & (1 << ItemSubClasses.ITEM_SUBCLASS_SHIELD) + buckler_present = item_subclass & (1 << ItemSubClasses.ITEM_SUBCLASS_BUCKLER) + + if shield_present and buckler_present: + stat_type = UnitStats.BLOCK_SHIELD | UnitStats.BLOCK_BUCKLER + elif shield_present: + stat_type = UnitStats.BLOCK_SHIELD + elif buckler_present: + stat_type = UnitStats.BLOCK_BUCKLER + else: + return + amount_percent = aura.get_effect_points() / 100 - effect_target.stat_manager.apply_aura_stat_bonus(aura.index, UnitStats.BLOCK_CHANCE, - amount_percent, percentual=False) + effect_target.stat_manager.apply_aura_stat_bonus(aura.index, stat_type, amount_percent, percentual=False) @staticmethod def handle_mod_threat(aura, effect_target, remove): diff --git a/game/world/managers/objects/units/UnitManager.py b/game/world/managers/objects/units/UnitManager.py index 1dfbf7cee..d06b6069c 100644 --- a/game/world/managers/objects/units/UnitManager.py +++ b/game/world/managers/objects/units/UnitManager.py @@ -1021,6 +1021,12 @@ def can_block(self, attacker_location=None, in_combat=False): return self.has_block_passive and not self.spell_manager.is_casting() and \ not self.unit_state & UnitStates.STUNNED + def has_shield(self): + return False + + def has_buckler(self): + return False + def can_parry(self, attacker_location=None, in_combat=False): if not in_combat: return self.has_parry_passive diff --git a/game/world/managers/objects/units/player/PlayerManager.py b/game/world/managers/objects/units/player/PlayerManager.py index 4682d41f3..6defdcf57 100644 --- a/game/world/managers/objects/units/player/PlayerManager.py +++ b/game/world/managers/objects/units/player/PlayerManager.py @@ -36,7 +36,7 @@ from utils.GuidUtils import GuidUtils from utils.Logger import Logger from utils.constants.DuelCodes import * -from utils.constants.ItemCodes import InventoryTypes +from utils.constants.ItemCodes import InventoryTypes, ItemSubClasses from utils.constants.MiscCodes import ChatFlags, LootTypes, LiquidTypes, MountResults, DismountResults, LockTypes from utils.constants.MiscCodes import ObjectTypeFlags, ObjectTypeIds, PlayerFlags, WhoPartyStatus, HighGuid, \ AttackTypes, MoveFlags @@ -1381,8 +1381,23 @@ def can_block(self, attacker_location=None, in_combat=False): if attacker_location and not self.location.has_in_arc(attacker_location): return False # players can't block from behind. - return self.inventory.has_offhand() and \ - self.inventory.get_offhand().item_template.inventory_type == InventoryTypes.SHIELD + return self.has_shield() or self.has_buckler() + + # override + def has_shield(self): + if not self.inventory.has_offhand(): + return False + item_template = self.inventory.get_offhand().item_template + return (item_template.inventory_type == InventoryTypes.SHIELD + and item_template.subclass == ItemSubClasses.ITEM_SUBCLASS_SHIELD) + + # override + def has_buckler(self): + if not self.inventory.has_offhand(): + return False + item_template = self.inventory.get_offhand().item_template + return (item_template.inventory_type == InventoryTypes.SHIELD + and item_template.subclass == ItemSubClasses.ITEM_SUBCLASS_BUCKLER) # override def can_parry(self, attacker_location=None, in_combat=False): diff --git a/game/world/managers/objects/units/player/StatManager.py b/game/world/managers/objects/units/player/StatManager.py index 2811d8725..131674f59 100644 --- a/game/world/managers/objects/units/player/StatManager.py +++ b/game/world/managers/objects/units/player/StatManager.py @@ -51,6 +51,8 @@ class UnitStats(IntFlag): PARRY_CHANCE = auto() DODGE_CHANCE = auto() BLOCK_CHANCE = auto() + BLOCK_SHIELD = auto() + BLOCK_BUCKLER = auto() # Note: Block value did not exist in 0.5.3 PROC_CHANCE = auto() @@ -868,7 +870,16 @@ def get_attack_result_against_self(self, attacker, attack_type, rating_difference_block = self._get_combat_rating_difference(attacker.level, combat_rating, use_block=self.unit_mgr.can_block(in_combat=True)) - block_chance = self.get_total_stat(UnitStats.BLOCK_CHANCE, accept_float=True) + rating_difference_block * 0.0004 + block_chance = self.get_total_stat(UnitStats.BLOCK_CHANCE, accept_float=True) + + # Shield/Buckler bonuses. + if self.unit_mgr.has_shield(): + block_chance += self.get_total_stat(UnitStats.BLOCK_SHIELD, accept_float=True) + elif self.unit_mgr.has_buckler(): + block_chance += self.get_total_stat(UnitStats.BLOCK_BUCKLER, accept_float=True) + + block_chance += rating_difference_block * 0.0004 + can_block = not (invalid_result_mask & HitInfo.BLOCK) and self.unit_mgr.can_block(attacker.location, in_combat=True) if can_block and random.random() < block_chance: return hit_info | HitInfo.BLOCK @@ -1245,6 +1256,12 @@ def send_block_percentage(self): # Percentual bonuses are stored as 100% = 1, client expects 100% = 100 value = self.get_total_stat(UnitStats.BLOCK_CHANCE, accept_float=True) * 100 + # Shield/Buckler bonuses. + if self.unit_mgr.has_shield(): + value += self.get_total_stat(UnitStats.BLOCK_SHIELD, accept_float=True) * 100 + elif self.unit_mgr.has_buckler(): + value += self.get_total_stat(UnitStats.BLOCK_BUCKLER, accept_float=True) * 100 + # Penalty against player of same level with max skill. value += self._get_combat_rating_difference(use_block=True) * 0.04 From 533c0d5ee152f81c1ad60108f0bb59a3aec9e57d Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 00:55:10 -0600 Subject: [PATCH 16/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 5c654708a..89512c442 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13884,6 +13884,11 @@ begin not atomic UPDATE `spawns_creatures` SET `position_x` = '7282.656', `position_y` = '-991.871', `position_z` = '13.75', `ignored` = '0' WHERE (`spawn_id` = '33171'); UPDATE `spawns_creatures` SET `position_x` = '7340.932', `position_y` = '-1004.148', `position_z` = '3.857', `ignored` = '0' WHERE (`spawn_id` = '33172'); + -- Whaldak Spider Trainer placement. + UPDATE `spawns_creatures` SET `position_x` = '-4833.676', `position_y` = '-2706.077', `orientation` = '3.731' WHERE (`spawn_id` = '400071'); + -- Olthran Craghelm placement. + UPDATE `spawns_creatures` SET `position_x` = '-5037.026', `position_y` = '-1149.393', `position_z` = '530.177', `orientation` = '0.340' WHERE (`spawn_id` = '92'); + insert into applied_updates values ('231220251'); end if; From 4e51a3e78f4f06e794a03763d2fc108ce0562a14 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:04:22 -0600 Subject: [PATCH 17/34] Update SpellEffect.py --- game/world/managers/objects/spell/SpellEffect.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/game/world/managers/objects/spell/SpellEffect.py b/game/world/managers/objects/spell/SpellEffect.py index 0d8fd6398..58dd182c2 100644 --- a/game/world/managers/objects/spell/SpellEffect.py +++ b/game/world/managers/objects/spell/SpellEffect.py @@ -169,9 +169,7 @@ def get_effect_points(self) -> int: # Roll. rolled_points = random.randint(min_roll, max_roll) if self.die_sides != 0 else 0 - self.effect_points = self.base_points + int(self.real_points_per_level * self.caster_effective_level) + rolled_points - - return self.effect_points + return self.base_points + int(self.real_points_per_level * self.caster_effective_level) + rolled_points def get_effect_simple_points(self) -> int: return self.base_points + self.base_dice From bd7a286b7378a56936d52da7f2256452aa92b208 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:11:36 -0600 Subject: [PATCH 18/34] Update Definitions.py --- game/world/opcode_handling/Definitions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/game/world/opcode_handling/Definitions.py b/game/world/opcode_handling/Definitions.py index 78325e230..140fc1171 100644 --- a/game/world/opcode_handling/Definitions.py +++ b/game/world/opcode_handling/Definitions.py @@ -386,6 +386,7 @@ OpCode.CMSG_FORCE_MOVE_ROOT_ACK: MovementHandler.handle_movement_status, OpCode.CMSG_FORCE_MOVE_UNROOT_ACK: MovementHandler.handle_movement_status, OpCode.CMSG_FORCE_SPEED_CHANGE_ACK: MovementHandler.handle_movement_status, + OpCode.CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: MovementHandler.handle_movement_status, # Ignored packets (Use NullHandler) OpCode.CMSG_TUTORIAL_CLEAR: NullHandler.handle, From 2a815186988a39bf6530a90cc3e9ab38b63e8ed2 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:21:15 -0600 Subject: [PATCH 19/34] Fix creatures not stopping upon root. --- game/world/managers/objects/units/UnitManager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/game/world/managers/objects/units/UnitManager.py b/game/world/managers/objects/units/UnitManager.py index d06b6069c..5c895ee4c 100644 --- a/game/world/managers/objects/units/UnitManager.py +++ b/game/world/managers/objects/units/UnitManager.py @@ -1249,11 +1249,6 @@ def set_stealthed(self, active=True, index=-1) -> bool: def set_rooted(self, active=True, index=-1) -> bool: is_rooted = self.set_move_flag(MoveFlags.MOVEFLAG_ROOTED, active, index) is_rooted |= self.set_unit_state(UnitStates.ROOTED, active, index) - - if is_rooted: - # Stop movement if needed. - self.movement_manager.stop() - return is_rooted def set_stunned(self, active=True, index=-1) -> bool: @@ -1343,6 +1338,10 @@ def set_move_flag(self, move_flag, active=True, index=-1) -> bool: else: self.movement_flags &= ~move_flag + # Force movement stop if rooted or immobilized. + if flag_changed and is_active and move_flag in {MoveFlags.MOVEFLAG_ROOTED, MoveFlags.MOVEFLAG_IMMOBILIZED}: + self.movement_manager.stop(force=True) + # Only broadcast swimming, rooted, walking or immobilized. if flag_changed and move_flag in {MoveFlags.MOVEFLAG_SWIMMING, MoveFlags.MOVEFLAG_ROOTED, MoveFlags.MOVEFLAG_IMMOBILIZED, MoveFlags.MOVEFLAG_WALK}: From 6b8b2cb03f77f1be1b4ff869ec2a5b3d624abac7 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:44:38 -0600 Subject: [PATCH 20/34] Fix Yell not reaching anyone beyond VIEW_DISTANCE. --- game/world/managers/maps/Cell.py | 46 ++++++++++++++++--------- game/world/managers/maps/GridManager.py | 17 +++++---- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/game/world/managers/maps/Cell.py b/game/world/managers/maps/Cell.py index 1c78550b6..878ef352c 100644 --- a/game/world/managers/maps/Cell.py +++ b/game/world/managers/maps/Cell.py @@ -180,26 +180,38 @@ def send_all(self, packet, source, include_source=False, exclude=None, use_ignor camera.broadcast_packet(packet, exclude=players_reached) def send_all_in_range(self, packet, range_, source, include_source=True, exclude=None, use_ignore=False): + # If range is non-positive, send to all players without filtering. if range_ <= 0: self.send_all(packet, source, exclude) - else: - players_reached = set() - for guid, player_mgr in list(self.players.items()): - if not player_mgr.online or not player_mgr.location.distance(source.location) <= range_: - continue - if not include_source and player_mgr.guid == source.guid: - continue - if use_ignore and player_mgr.friends_manager.has_ignore(source.guid): - continue - # Never send messages to a player that does not know the source object. - if not player_mgr.guid == source.guid and source.guid not in player_mgr.known_objects: - continue - players_reached.add(player_mgr.guid) - player_mgr.enqueue_packet(packet) + return - # If this cell has cameras, route packets. - for camera in FarSightManager.get_cell_cameras(self): - camera.broadcast_packet(packet, exclude=players_reached) + players_reached = set() + for guid, player_mgr in list(self.players.items()): + # Skip offline players. + if not player_mgr.online: + continue + # Check distance. + distance = player_mgr.location.distance(source.location) + if distance > range_: + continue + # Optionally exclude source. + if not include_source and player_mgr.guid == source.guid: + continue + # Skip players that have ignored the source. + if use_ignore and player_mgr.friends_manager.has_ignore(source.guid): + continue + # Ensure the player knows about the source object. + if guid != source.guid and source.guid not in player_mgr.known_objects: + continue + + # Add to reached players. + players_reached.add(guid) + # Send packet. + player_mgr.enqueue_packet(packet) + + # Route packets via cameras if applicable. + for camera in FarSightManager.get_cell_cameras(self): + camera.broadcast_packet(packet, exclude=players_reached) def can_deactivate(self): return not self.has_players() and not self.has_cameras() diff --git a/game/world/managers/maps/GridManager.py b/game/world/managers/maps/GridManager.py index 41f2ce14e..18db5d70a 100644 --- a/game/world/managers/maps/GridManager.py +++ b/game/world/managers/maps/GridManager.py @@ -197,15 +197,16 @@ def _update_players_surroundings(self, cell_key, exclude_cells=None, world_objec return affected_cells - def _get_surrounding_cells_by_cell(self, cell=None, cell_x=0, cell_y=0, map_id=0, instance_id=0): + def _get_surrounding_cells_by_cell(self, cell=None, cell_x=0, cell_y=0, map_id=0, instance_id=0, range_=0): if cell: cell_x = cell.cell_x cell_y = cell.cell_y map_id = cell.map_id instance_id = cell.instance_id + view_distance = VIEW_DISTANCE if not range_ else range_ # Calculate how many cells to include in each direction given the view distance, at least 1. - max_cells_radius = max(1, int(VIEW_DISTANCE // CELL_SIZE)) + max_cells_radius = max(1, int(view_distance // CELL_SIZE)) surrounding_cells = set() for dx in range(-max_cells_radius, max_cells_radius + 1): @@ -222,13 +223,15 @@ def _get_surrounding_cells_by_cell(self, cell=None, cell_x=0, cell_y=0, map_id=0 return surrounding_cells - def _get_surrounding_cells_by_object(self, world_object): + def _get_surrounding_cells_by_object(self, world_object, range_=0): pos = world_object.location - return self._get_surrounding_cells_by_location(pos.x, pos.y, world_object.map_id, world_object.instance_id) + return self._get_surrounding_cells_by_location( + pos.x, pos.y, world_object.map_id, world_object.instance_id, range_=range_) - def _get_surrounding_cells_by_location(self, x, y, map_, instance_id): + def _get_surrounding_cells_by_location(self, x, y, map_, instance_id, range_=0): cell_x, cell_y = CellUtils.generate_coord_data(x, y) - return self._get_surrounding_cells_by_cell(cell_x=cell_x, cell_y=cell_y, map_id=map_, instance_id=instance_id) + return self._get_surrounding_cells_by_cell(cell_x=cell_x, cell_y=cell_y, map_id=map_, + instance_id=instance_id, range_=range_) def send_surrounding(self, packet, world_object, include_self=True, exclude=None, use_ignore=False): if world_object.current_cell: @@ -244,7 +247,7 @@ def send_surrounding_in_range(self, packet, world_object, range_, include_self=T Logger.warning(f'{world_object.get_name()} Cannot send surrounding in range without current cell.') return - for cell in self._get_surrounding_cells_by_object(world_object): + for cell in self._get_surrounding_cells_by_object(world_object, range_=range_): cell.send_all_in_range(packet, range_, world_object, include_self, exclude, use_ignore) def get_surrounding_objects(self, world_object, object_types): From 20c91411b71be7d696f060c27937b93479abd8e2 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:52:39 -0600 Subject: [PATCH 21/34] Update Cell.py --- game/world/managers/maps/Cell.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/game/world/managers/maps/Cell.py b/game/world/managers/maps/Cell.py index 878ef352c..d141d807e 100644 --- a/game/world/managers/maps/Cell.py +++ b/game/world/managers/maps/Cell.py @@ -2,6 +2,8 @@ from game.world.managers.objects.farsight.FarSightManager import FarSightManager from threading import RLock +from utils.ConfigManager import config + class Cell: def __init__(self, cell_x=0, cell_y=0, map_id=0, instance_id=0, key=''): @@ -185,6 +187,9 @@ def send_all_in_range(self, packet, range_, source, include_source=True, exclude self.send_all(packet, source, exclude) return + is_yell = int(range_) == int(config.World.Chat.ChatRange.yell_range) + is_say = int(range_) == int(config.World.Chat.ChatRange.say_range) + players_reached = set() for guid, player_mgr in list(self.players.items()): # Skip offline players. @@ -200,9 +205,10 @@ def send_all_in_range(self, packet, range_, source, include_source=True, exclude # Skip players that have ignored the source. if use_ignore and player_mgr.friends_manager.has_ignore(source.guid): continue - # Ensure the player knows about the source object. - if guid != source.guid and source.guid not in player_mgr.known_objects: - continue + # Ensure the player knows about the source object if this is not a chat message. + if not is_say and not is_yell: + if guid != source.guid and source.guid not in player_mgr.known_objects: + continue # Add to reached players. players_reached.add(guid) From 44736395a906f656cbdefca5d36d38d5aeb21400 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 18:55:05 -0600 Subject: [PATCH 22/34] Hammerhead Sharks --- etc/databases/world/updates/updates.sql | 21 +++++++++++++++++++ .../objects/units/creature/CreatureManager.py | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 89512c442..0cd7088a9 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13889,6 +13889,27 @@ begin not atomic -- Olthran Craghelm placement. UPDATE `spawns_creatures` SET `position_x` = '-5037.026', `position_y` = '-1149.393', `position_z` = '530.177', `orientation` = '0.340' WHERE (`spawn_id` = '92'); + -- Hammerhead Sharks - Theramore. + UPDATE `creature_template` SET `display_id1` = '2851', `display_id2` = '0', `display_id3` = '0' WHERE (`entry` = '5185'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400474', '5185', '0', '0', '0', '1', '-3937.427', '-4650.228', '-6.616', '0.317', '300', '300', '0', '100', '0', '2', '0', '0', '0'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400475', '5185', '0', '0', '0', '1', '-4026.160', '-4566.016', '-11.210', '3.257', '300', '300', '0', '100', '0', '2', '0', '0', '0'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400476', '5185', '0', '0', '0', '1', '-3871.077', '-4715.082', '-11.359', '2.328', '300', '300', '0', '100', '0', '2', '0', '0', '0'); + + DELETE FROM creature_movement WHERE id = 400476; + INSERT INTO creature_movement (id, point, position_x, position_y, position_z, orientation, waittime, wander_distance, script_id) VALUES + (400476, 0, -3871.08, -4715.08, -11.359, 0, 0, 0, 0), + (400476, 1, -3937.43, -4650.23, -6.616, 0, 0, 0, 0); + + DELETE FROM creature_movement WHERE id = 400474; + INSERT INTO creature_movement (id, point, position_x, position_y, position_z, orientation, waittime, wander_distance, script_id) VALUES + (400474, 0, -3937.43, -4650.23, -6.616, 0, 0, 0, 0), + (400474, 1, -4019.872, -4570.601, -10.032, 0, 0, 0, 0); + + DELETE FROM creature_movement WHERE id = 400475; + INSERT INTO creature_movement (id, point, position_x, position_y, position_z, orientation, waittime, wander_distance, script_id) VALUES + (400475, 0, -4026.16, -4566.02, -11.21, 0, 0, 0, 0), + (400475, 1, -3852.411, -4695.709, -8.891, 0, 0, 0, 0); + insert into applied_updates values ('231220251'); end if; diff --git a/game/world/managers/objects/units/creature/CreatureManager.py b/game/world/managers/objects/units/creature/CreatureManager.py index 273c96225..c93d442ff 100644 --- a/game/world/managers/objects/units/creature/CreatureManager.py +++ b/game/world/managers/objects/units/creature/CreatureManager.py @@ -304,6 +304,7 @@ def finish_loading(self): self.apply_default_auras() # Movement. + self.set_move_flag(MoveFlags.MOVEFLAG_SWIMMING, active=self.static_flags & CreatureStaticFlags.AQUATIC != 0) self.set_move_flag(MoveFlags.MOVEFLAG_WALK, active=not self.should_always_run_ooc()) self.movement_manager.initialize_or_reset() @@ -948,6 +949,9 @@ def _update_swimming_state(self): if not self.can_swim(): return + if not self.get_map().is_active_cell_for_location(self.location): + return + is_under_water = self.is_under_water() if is_under_water and not self.movement_flags & MoveFlags.MOVEFLAG_SWIMMING: From 56c970b26c59ff435146e6bfe4cfbcca35f81e7f Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 19:51:35 -0600 Subject: [PATCH 23/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 66 ++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 0cd7088a9..249148c32 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13890,7 +13890,7 @@ begin not atomic UPDATE `spawns_creatures` SET `position_x` = '-5037.026', `position_y` = '-1149.393', `position_z` = '530.177', `orientation` = '0.340' WHERE (`spawn_id` = '92'); -- Hammerhead Sharks - Theramore. - UPDATE `creature_template` SET `display_id1` = '2851', `display_id2` = '0', `display_id3` = '0' WHERE (`entry` = '5185'); + UPDATE `creature_template` SET `display_id1` = '2851', `display_id2` = '0', `display_id3` = '0', `level_min` = '10', `level_max` = '30' WHERE (`entry` = '5185'); INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400474', '5185', '0', '0', '0', '1', '-3937.427', '-4650.228', '-6.616', '0.317', '300', '300', '0', '100', '0', '2', '0', '0', '0'); INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400475', '5185', '0', '0', '0', '1', '-4026.160', '-4566.016', '-11.210', '3.257', '300', '300', '0', '100', '0', '2', '0', '0', '0'); INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400476', '5185', '0', '0', '0', '1', '-3871.077', '-4715.082', '-11.359', '2.328', '300', '300', '0', '100', '0', '2', '0', '0', '0'); @@ -13910,6 +13910,70 @@ begin not atomic (400475, 0, -4026.16, -4566.02, -11.21, 0, 0, 0, 0), (400475, 1, -3852.411, -4695.709, -8.891, 0, 0, 0, 0); + -- Hammerhead Sharks - Wetlands. + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400477', '5185', '0', '0', '0', '0', '-3619.912', '-667.062', '-5.495', '2.847', '300', '300', '0', '100', '0', '0', '0', '0', '0'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400478', '5185', '0', '0', '0', '0', '-3860.069', '-970.231', '-9.424', '1.893', '300', '300', '0', '100', '0', '0', '0', '0', '0'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400479', '5185', '0', '0', '0', '0', '-3086.198', '-878.560', '-8.186', '6.281', '300', '300', '0', '100', '0', '0', '0', '0', '0'); + + DELETE FROM creature_movement WHERE id = 400477; + INSERT INTO creature_movement (id, point, position_x, position_y, position_z, orientation, waittime, wander_distance, script_id) VALUES + (400477, 0, -3619.912, -667.062, -6.0, 0, 0, 0, 0), + (400477, 1, -3679.512, -654.877, -5.768, 0, 0, 0, 0), + (400477, 2, -3754.543, -660.885, -6.968, 0, 0, 0, 0), + (400477, 3, -3840.858, -725.926, -4.462, 0, 0, 0, 0), + (400477, 4, -3895.266, -798.169, -3.192, 0, 0, 0, 0), + (400477, 5, -3888.073, -871.998, -4.459, 0, 0, 0, 0), + (400477, 6, -3886.798, -925.889, -5.656, 0, 0, 0, 0), + (400477, 7, -3926.045, -899.105, -3.271, 0, 0, 0, 0), + (400477, 8, -3944.383, -846.207, -7.741, 0, 0, 0, 0), + (400477, 9, -3916.853, -764.062, -6.979, 0, 0, 0, 0), + (400477, 10, -3789.159, -667.851, -6.656, 0, 0, 0, 0), + (400477, 11, -3643.234, -665.627, -3.28, 0, 0, 0, 0); + + DELETE FROM creature_movement WHERE id = 400479; + INSERT INTO creature_movement (id, point, position_x, position_y, position_z, orientation, waittime, wander_distance, script_id) VALUES + (400479, 0, -3086.198, -878.56, -8.186, 0, 0, 0, 0), + (400479, 1, -2994.042, -890.377, -5.982, 0, 0, 0, 0), + (400479, 2, -2949.162, -914.763, -5.667, 0, 0, 0, 0), + (400479, 3, -2911.086, -967.312, -5.657, 0, 0, 0, 0), + (400479, 4, -2860.667, -1015.364, -7.212, 0, 0, 0, 0), + (400479, 5, -2763.598, -1087.138, -4.957, 0, 0, 0, 0), + (400479, 6, -2757.104, -1009.766, -6.123, 0, 0, 0, 0), + (400479, 7, -2805.729, -952.217, -6.572, 0, 0, 0, 0), + (400479, 8, -2943.019, -953.778, -2.742, 0, 0, 0, 0), + (400479, 9, -2977.853, -888.88, -3.793, 0, 0, 0, 0), + (400479, 10, -3063.256, -876.323, -6.928, 0, 0, 0, 0); + + DELETE FROM creature_movement WHERE id = 400478; + INSERT INTO creature_movement (id, point, position_x, position_y, position_z, orientation, waittime, wander_distance, script_id) VALUES + (400478, 0, -3860.07, -970.231, -9.424, 0, 0, 0, 0), + (400478, 1, -3847.447, -1041.32, -6.086, 0, 0, 0, 0), + (400478, 2, -3818.298, -1131.86, -5.075, 0, 0, 0, 0), + (400478, 3, -3765.189, -1227.954, -3.878, 0, 0, 0, 0), + (400478, 4, -3670.321, -1173.761, -6.452, 0, 0, 0, 0), + (400478, 5, -3577.506, -1101.181, -6.452, 0, 0, 0, 0), + (400478, 6, -3535.464, -1039.792, -6.452, 0, 0, 0, 0), + (400478, 7, -3601.396, -975.107, -6.452, 0, 0, 0, 0), + (400478, 8, -3580.904, -907.404, -6.452, 0, 0, 0, 0), + (400478, 9, -3553.939, -839.087, -6.452, 0, 0, 0, 0), + (400478, 10, -3589.421, -832.031, -6.452, 0, 0, 0, 0), + (400478, 11, -3623.885, -909.151, -6.452, 0, 0, 0, 0), + (400478, 12, -3665.608, -962.974, -6.452, 0, 0, 0, 0), + (400478, 13, -3740.933, -964.078, -6.452, 0, 0, 0, 0), + (400478, 14, -3818.444, -943.057, -6.452, 0, 0, 0, 0), + (400478, 15, -3874.734, -902.968, -6.452, 0, 0, 0, 0), + (400478, 16, -3893.729, -846.193, -6.452, 0, 0, 0, 0), + (400478, 17, -3884.289, -777.849, -6.452, 0, 0, 0, 0), + (400478, 18, -3836.793, -736.491, -6.452, 0, 0, 0, 0), + (400478, 19, -3857.304, -679.108, -6.452, 0, 0, 0, 0), + (400478, 20, -3943.348, -631.051, -6.452, 0, 0, 0, 0), + (400478, 21, -4076.014, -691.217, -6.452, 0, 0, 0, 0), + (400478, 22, -4120.404, -774.243, -6.452, 0, 0, 0, 0), + (400478, 23, -4071.049, -793.069, -6.452, 0, 0, 0, 0), + (400478, 24, -3991.929, -826.605, -6.452, 0, 0, 0, 0), + (400478, 25, -3904.568, -865.126, -6.452, 0, 0, 0, 0), + (400478, 26, -3851.88, -948.064, -6.452, 0, 0, 0, 0); + insert into applied_updates values ('231220251'); end if; From e5a9b10d58a5b4b45d65991d9390f1e55e6f98e9 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 19:52:49 -0600 Subject: [PATCH 24/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 249148c32..ce942bda6 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13911,9 +13911,9 @@ begin not atomic (400475, 1, -3852.411, -4695.709, -8.891, 0, 0, 0, 0); -- Hammerhead Sharks - Wetlands. - INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400477', '5185', '0', '0', '0', '0', '-3619.912', '-667.062', '-5.495', '2.847', '300', '300', '0', '100', '0', '0', '0', '0', '0'); - INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400478', '5185', '0', '0', '0', '0', '-3860.069', '-970.231', '-9.424', '1.893', '300', '300', '0', '100', '0', '0', '0', '0', '0'); - INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400479', '5185', '0', '0', '0', '0', '-3086.198', '-878.560', '-8.186', '6.281', '300', '300', '0', '100', '0', '0', '0', '0', '0'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400477', '5185', '0', '0', '0', '0', '-3619.912', '-667.062', '-5.495', '2.847', '300', '300', '0', '100', '0', '2', '0', '0', '0'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400478', '5185', '0', '0', '0', '0', '-3860.069', '-970.231', '-9.424', '1.893', '300', '300', '0', '100', '0', '2', '0', '0', '0'); + INSERT INTO `spawns_creatures` (`spawn_id`, `spawn_entry1`, `spawn_entry2`, `spawn_entry3`, `spawn_entry4`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `wander_distance`, `health_percent`, `mana_percent`, `movement_type`, `spawn_flags`, `visibility_mod`, `ignored`) VALUES ('400479', '5185', '0', '0', '0', '0', '-3086.198', '-878.560', '-8.186', '6.281', '300', '300', '0', '100', '0', '2', '0', '0', '0'); DELETE FROM creature_movement WHERE id = 400477; INSERT INTO creature_movement (id, point, position_x, position_y, position_z, orientation, waittime, wander_distance, script_id) VALUES From 3a4b9fe20ef180d7740898a4510ad1c23d92a887 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 20:29:44 -0600 Subject: [PATCH 25/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index ce942bda6..7b43e9efd 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13974,6 +13974,9 @@ begin not atomic (400478, 25, -3904.568, -865.126, -6.452, 0, 0, 0, 0), (400478, 26, -3851.88, -948.064, -6.452, 0, 0, 0, 0); + -- Wharfmaster Lozgil. + UPDATE `spawns_creatures` SET `position_x` = '-14303.7', `position_y` = '527.608', `position_z` = '8.83', `orientation` = '4.86', `ignored` = '0', `map` = '0' WHERE (`spawn_id` = '184'); + insert into applied_updates values ('231220251'); end if; From 5fa9a5ef3bb786036e7856af738fe492182a8056 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 21:23:38 -0600 Subject: [PATCH 26/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 7b43e9efd..98f322b92 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13977,6 +13977,9 @@ begin not atomic -- Wharfmaster Lozgil. UPDATE `spawns_creatures` SET `position_x` = '-14303.7', `position_y` = '527.608', `position_z` = '8.83', `orientation` = '4.86', `ignored` = '0', `map` = '0' WHERE (`spawn_id` = '184'); + -- Frostmaw. + UPDATE `creature_template` SET `display_id1` = '934' WHERE (`entry` = '4504'); + insert into applied_updates values ('231220251'); end if; From b2e090bda47188a7ea193d184f45c03016b4b7ae Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Mon, 29 Dec 2025 22:17:15 -0600 Subject: [PATCH 27/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 98f322b92..7132a482b 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13979,6 +13979,9 @@ begin not atomic -- Frostmaw. UPDATE `creature_template` SET `display_id1` = '934' WHERE (`entry` = '4504'); + DELETE FROM `event_scripts` WHERE `id`=727; + INSERT INTO `event_scripts` (`id`, `delay`, `priority`, `command`, `datalong`, `datalong2`, `datalong3`, `datalong4`, `target_param1`, `target_param2`, `target_type`, `data_flags`, `dataint`, `dataint2`, `dataint3`, `dataint4`, `x`, `y`, `z`, `o`, `condition_id`, `comments`) VALUES + (727, 0, 0, 10, 4504, 0, 1, 0, 0, 0, 0, 0, 8, 0, -1, 7, 234.227, -239.227, 141.325, 2.84489, 0, 'Frostmaw: Summon Creature Frostmaw'); insert into applied_updates values ('231220251'); end if; From 70dbf7c46afdba707977174c2990461c7bc6e93a Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Wed, 31 Dec 2025 23:58:12 -0600 Subject: [PATCH 28/34] Update SpellManager.py --- game/world/managers/objects/spell/SpellManager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/game/world/managers/objects/spell/SpellManager.py b/game/world/managers/objects/spell/SpellManager.py index f1ed8679f..45c4f1bd0 100644 --- a/game/world/managers/objects/spell/SpellManager.py +++ b/game/world/managers/objects/spell/SpellManager.py @@ -1836,6 +1836,9 @@ def send_cast_result(self, casting_spell, error, misc_data=-1): # Only players receive cast results. if is_player: if error == SpellCheckCastResult.SPELL_NO_ERROR: + # TODO: Client displays spell failed with items casts like 'Fresh Carcass' or 'Etched Phial' + # when given the spell id, might be sending spell start or go packet with wrong structure. + spell_id = spell_id if not casting_spell.source_item else 0 data = pack(' Date: Thu, 1 Jan 2026 20:32:11 -0600 Subject: [PATCH 29/34] Revert "Update SpellManager.py" This reverts commit 70dbf7c46afdba707977174c2990461c7bc6e93a. --- game/world/managers/objects/spell/SpellManager.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/game/world/managers/objects/spell/SpellManager.py b/game/world/managers/objects/spell/SpellManager.py index 45c4f1bd0..f1ed8679f 100644 --- a/game/world/managers/objects/spell/SpellManager.py +++ b/game/world/managers/objects/spell/SpellManager.py @@ -1836,9 +1836,6 @@ def send_cast_result(self, casting_spell, error, misc_data=-1): # Only players receive cast results. if is_player: if error == SpellCheckCastResult.SPELL_NO_ERROR: - # TODO: Client displays spell failed with items casts like 'Fresh Carcass' or 'Etched Phial' - # when given the spell id, might be sending spell start or go packet with wrong structure. - spell_id = spell_id if not casting_spell.source_item else 0 data = pack(' Date: Sat, 3 Jan 2026 22:20:16 -0600 Subject: [PATCH 30/34] Update SpellManager.py --- .../managers/objects/spell/SpellManager.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/game/world/managers/objects/spell/SpellManager.py b/game/world/managers/objects/spell/SpellManager.py index f1ed8679f..55d278d9f 100644 --- a/game/world/managers/objects/spell/SpellManager.py +++ b/game/world/managers/objects/spell/SpellManager.py @@ -835,14 +835,15 @@ def send_cast_start(self, casting_spell): if not self.caster.is_unit(by_mask=True): return # Non-unit casters should not broadcast their casts. - is_player = self.caster.is_player() + source_guid = self.caster.guid + if casting_spell.source_item: + source_guid = casting_spell.source_item.guid - source_guid = casting_spell.initial_target.guid if casting_spell.initial_target_is_item() else self.caster.guid cast_flags = casting_spell.cast_flags # Validate if this spell crashes the client. # Force SpellCastFlags.CAST_FLAG_PROC, which hides the start cast. - if not is_player and not ExtendedSpellData.UnitSpellsValidator.spell_has_valid_cast(casting_spell): + if not self.caster.is_player() and not ExtendedSpellData.UnitSpellsValidator.spell_has_valid_cast(casting_spell): Logger.warning(f'Hiding spell {casting_spell.spell_entry.Name_enUS} start cast due invalid cast.') cast_flags |= SpellCastFlags.CAST_FLAG_PROC @@ -866,7 +867,7 @@ def send_cast_start(self, casting_spell): # Spell start. data = pack(signature, *data) packet = PacketWriter.get_packet(OpCode.SMSG_SPELL_START, data) - self.caster.get_map().send_surrounding(packet, self.caster, include_self=is_player) + self.caster.get_map().send_surrounding(packet, self.caster, include_self=self.caster.is_player()) def handle_channel_start(self, casting_spell): if not casting_spell.is_channeled(): @@ -960,13 +961,14 @@ def send_spell_resist_result(self, casting_spell, damage_info): self.caster.get_map().send_surrounding(packet, self.caster, include_self=is_player) def send_spell_go(self, casting_spell): - # The client expects the source to only be set for unit casters. - caster_unit = casting_spell.initial_target.guid if casting_spell.initial_target_is_item() \ - else self.caster.guid + source_guid = self.caster.guid + if casting_spell.source_item: + source_guid = casting_spell.source_item.guid + caster_guid = self.caster.guid if self.caster.is_unit(by_mask=True) else 0 # Exclude proc flag from GO - proc casts are visible in 0.5.5 screenshots. - data = [caster_unit, caster_guid, casting_spell.spell_entry.ID, + data = [source_guid, caster_guid, casting_spell.spell_entry.ID, casting_spell.cast_flags & ~SpellCastFlags.CAST_FLAG_PROC] signature = '<2QIHB' # caster, source, ID, flags .. (targets, ammo info). From b9e49203821cf179d37511fe8290eca6bd52374b Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 3 Jan 2026 22:20:18 -0600 Subject: [PATCH 31/34] Update AuraManager.py --- game/world/managers/objects/spell/aura/AuraManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/world/managers/objects/spell/aura/AuraManager.py b/game/world/managers/objects/spell/aura/AuraManager.py index b5cfc2b41..e6ebaf971 100644 --- a/game/world/managers/objects/spell/aura/AuraManager.py +++ b/game/world/managers/objects/spell/aura/AuraManager.py @@ -157,7 +157,7 @@ def check_aura_interrupts(self, moved=False, turned=False, changed_stand_state=F # An interrupt for sitting does not exist. # Food/drink spells do claim that the player must remain seated. - # In later versions an aurainterrupt exists for this purpose. + # In later versions an aura interrupt exists for this purpose. if aura.source_spell.is_refreshment_spell() and changed_stand_state and \ self.unit_mgr.stand_state != StandState.UNIT_SITTING: self.remove_aura(aura) From 1094f97c2c69cd94a833d75ddf23c54f30468082 Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 3 Jan 2026 22:34:20 -0600 Subject: [PATCH 32/34] Update SpellManager.py --- game/world/managers/objects/spell/SpellManager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/game/world/managers/objects/spell/SpellManager.py b/game/world/managers/objects/spell/SpellManager.py index 55d278d9f..fc07952a7 100644 --- a/game/world/managers/objects/spell/SpellManager.py +++ b/game/world/managers/objects/spell/SpellManager.py @@ -1,4 +1,3 @@ -import math import time from random import randint from struct import pack From e1edc18b82c2a6d9c47b323de773d532648d6faf Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 3 Jan 2026 23:11:25 -0600 Subject: [PATCH 33/34] Update updates.sql --- etc/databases/world/updates/updates.sql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etc/databases/world/updates/updates.sql b/etc/databases/world/updates/updates.sql index 7132a482b..af6b3cc95 100644 --- a/etc/databases/world/updates/updates.sql +++ b/etc/databases/world/updates/updates.sql @@ -13983,6 +13983,11 @@ begin not atomic INSERT INTO `event_scripts` (`id`, `delay`, `priority`, `command`, `datalong`, `datalong2`, `datalong3`, `datalong4`, `target_param1`, `target_param2`, `target_type`, `data_flags`, `dataint`, `dataint2`, `dataint3`, `dataint4`, `x`, `y`, `z`, `o`, `condition_id`, `comments`) VALUES (727, 0, 0, 10, 4504, 0, 1, 0, 0, 0, 0, 0, 8, 0, -1, 7, 234.227, -239.227, 141.325, 2.84489, 0, 'Frostmaw: Summon Creature Frostmaw'); + -- Fresh Carcass - Player cast flag. + UPDATE `item_template` SET `flags` = '64' WHERE (`entry` = '5810'); + -- Etched Phial - Player cast flag. + UPDATE `item_template` SET `flags` = '2112' WHERE (`entry` = '5867'); + insert into applied_updates values ('231220251'); end if; From cd9c5626f4e8121a135061ddb16ece5d83d57a0b Mon Sep 17 00:00:00 2001 From: devw4r <108442943+devw4r@users.noreply.github.com> Date: Sat, 3 Jan 2026 23:32:38 -0600 Subject: [PATCH 34/34] Update SpellManager.py --- game/world/managers/objects/spell/SpellManager.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/game/world/managers/objects/spell/SpellManager.py b/game/world/managers/objects/spell/SpellManager.py index fc07952a7..18c78f0fb 100644 --- a/game/world/managers/objects/spell/SpellManager.py +++ b/game/world/managers/objects/spell/SpellManager.py @@ -419,6 +419,13 @@ def perform_spell_cast(self, casting_spell: CastingSpell, validate=True): self.send_cast_result(casting_spell, SpellCheckCastResult.SPELL_NO_ERROR) self.send_spell_go(casting_spell) + # Spells that use the KneelLoop animation causes the client to get stuck in this animation until relog. + # Send a KneelEnd animation to resolve this issue. e.g. spell 6717 'Place Lion Carcass' + if casting_spell.spell_visual_entry and casting_spell.spell_visual_entry.CastKit == 380: # KneelLoop. + data = pack(f'QI', self.caster.guid, 444) + packet = PacketWriter.get_packet(OpCode.SMSG_PLAY_SPELL_VISUAL, data) + self.caster.enqueue_packet(packet) + if casting_spell.requires_combo_points(): # Combo points will be reset by consume_resources_for_cast. casting_spell.spent_combo_points = self.caster.combo_points