From 48f588d37db88516a3d24a0cbe320df879dea972 Mon Sep 17 00:00:00 2001 From: avirar Date: Sat, 20 Jun 2026 08:35:03 +1000 Subject: [PATCH] Fix disenchant skill check causing bots to pass on usable loot (#2478) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Pull Request Description When a bot has the Enchanting skill but its level is insufficient to disenchant an item, the old code returned `ITEM_USAGE_NONE` immediately. This caused the bot to pass on loot rolls for items it could have used for other purposes (equip, quest turn-in, crafting reagents, guild tasks) because the function never reached those downstream checks. The fix combines the skill check and binding check into a single positive condition: the bot only returns `ITEM_USAGE_DISENCHANT` when it is both skilled enough and the binding allows it. Otherwise, execution falls through to the remaining item usage evaluations as intended. ## Feature Evaluation - Describe the **minimum logic** required to achieve the intended behavior. - Describe the **processing cost** when this logic executes across many bots. - **Minimum logic:** Replace two separate guards (one early-return `NONE`, one positive `DISENCHANT`) with a single combined `if` that returns `DISENCHANT` only when both conditions are met. No new branches — one fewer than before. - **Processing cost:** Identical. The same two comparisons execute once per disenchant-eligible item evaluation. No change to per-bot or per-tick cost. ## How to Test the Changes 1. Spawn a bot with Enchanting skill at a low level (e.g. 1/75). 2. Loot or roll on an armor/weapon item with `RequiredDisenchantSkill` higher than the bot's skill (e.g. a level 50 blue with required skill 225). 3. **Before:** The bot returns `ITEM_USAGE_NONE` and passes on the item, even if it could equip it or use it for a quest. 4. **After:** The bot correctly evaluates remaining usages (equip, quest, etc.) and rolls Need/Greed appropriately. ## Impact Assessment - Does this change increase per-bot/per-tick processing or risk scaling poorly with thousands of bots? - - [x] No, not at all - - [ ] Minimal impact (**explain below**) - - [ ] Moderate impact (**explain below**) Same number of comparisons, one fewer early-return path. - Does this change modify default bot behavior? - - [ ] No - - [x] Yes (**explain why**) Bots with insufficient enchanting skill will now correctly consider non-disenchant uses for items they previously passed on entirely. - Does this change add new decision branches or increase maintenance complexity? - - [x] No - - [ ] Yes (**explain below**) Reduces branches from two `if` statements to one. ## AI Assistance Was AI assistance used while working on this change? - - [ ] No - - [x] Yes (**explain below**) AI was used to refactor the two-condition guard into a single combined condition. The logic was reviewed and the behavioural difference (fall-through vs early return) was verified manually. ## Final Checklist - - [x] Stability is not compromised. - - [x] Performance impact is understood, tested, and acceptable. - - [x] Added logic complexity is justified and explained. - - [x] Any new bot dialogue lines are translated. - - [x] Documentation updated if needed (Conf comments, WiKi commands). ## Notes for Reviewers The root cause was that `return ITEM_USAGE_NONE` on the skill check short-circuited the entire `Calculate()` function, skipping all downstream item usage evaluations. The fix simply lets execution continue past the disenchant block when disenchanting isn't viable. Co-authored-by: avirar --- src/Ai/Base/Value/ItemUsageValue.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Ai/Base/Value/ItemUsageValue.cpp b/src/Ai/Base/Value/ItemUsageValue.cpp index a1f9688d2..f7b5196cd 100644 --- a/src/Ai/Base/Value/ItemUsageValue.cpp +++ b/src/Ai/Base/Value/ItemUsageValue.cpp @@ -109,12 +109,9 @@ ItemUsage ItemUsageValue::Calculate() // Retrieve the bot's Enchanting skill level uint32 enchantingSkill = bot->GetSkillValue(SKILL_ENCHANTING); - // Check if the bot has a high enough skill to disenchant this item - if (proto->RequiredDisenchantSkill > 0 && enchantingSkill < proto->RequiredDisenchantSkill) - return ITEM_USAGE_NONE; // Not skilled enough to disenchant - - // BoE (Bind on Equip) items should NOT be disenchanted unless they are already bound - if (proto->Bonding == BIND_WHEN_PICKED_UP || (proto->Bonding == BIND_WHEN_EQUIPPED && isSoulbound)) + // Only disenchant if skilled enough and binding allows it + if (enchantingSkill >= proto->RequiredDisenchantSkill && + (proto->Bonding == BIND_WHEN_PICKED_UP || (proto->Bonding == BIND_WHEN_EQUIPPED && isSoulbound))) return ITEM_USAGE_DISENCHANT; }