Skip to content

[IN PROGRESS] Ultra Cleanup#88

Open
ArrowDev123 wants to merge 5 commits intoauqw:Skuafrom
ArrowDev123:ultra-cleanup
Open

[IN PROGRESS] Ultra Cleanup#88
ArrowDev123 wants to merge 5 commits intoauqw:Skuafrom
ArrowDev123:ultra-cleanup

Conversation

@ArrowDev123
Copy link

@ArrowDev123 ArrowDev123 commented Mar 6, 2026

Doing a pass on Ultras to try and make them as simple stupid as possible. Mostly they are already good!

Summary by Sourcery

Simplify and generalize ultra boss helper scripts by introducing shared gear utilities, configurable multi-tab options, and clearer role handling for taunter and DPS slots.

New Features:

  • Add a reusable CoreGearUtils module for selecting, equipping, and restoring best gear based on presets or custom meta priorities.
  • Support automatic multi-slot class compositions with per-slot overrides for both Ultra Nulgath and Champion Drakath encounters.
  • Introduce optional Scroll of Life Steal usage for non-taunter roles alongside existing Scroll of Enrage handling.

Enhancements:

  • Refine Ultra Nulgath and Champion Drakath scripts to use multi-tab configuration, clearer taunter role detection, and safer early-exit validation when setup is incomplete.
  • Leverage CoreGearUtils from Ultra scripts to automatically equip encounter-appropriate gear profiles instead of manual enhancement toggles.
  • Improve enhancement logic to cover additional class variants (e.g., Chrono ShadowHunter, Infinity Titan) and consolidate class-specific setups.

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 6, 2026

Reviewer's Guide

Refactors the Ultra Nulgath and Champion Drakath ultra scripts to use a shared gear optimization utility, add multi‑page configuration with class composition presets and overrides, and introduce life‑steal scroll support, while preserving the core fight logic and taunt behavior. Also adds a reusable CoreGearUtils helper and a life‑steal helper to CoreUltra.

Sequence diagram for UltraNulgath ScriptMain with gear snapshot, presets, and life steal

sequenceDiagram
    participant Bot as IScriptInterface
    participant Ultra as UltraNulgath
    participant Core as CoreEngine
    participant Bots as CoreBots
    participant Gear as CoreGearUtils
    participant UltraCore as CoreUltra

    Bot->>Ultra: ScriptMain(bot)
    Ultra->>Bots: OneTimeMessage(...)
    Ultra->>Bot: Config.Configure() [if not SkipOption]

    Ultra->>Bot: Read Main.DoEquipClasses
    Ultra->>Bot: Read ClassOverrides (a,b,c,d)
    Ultra->>Bot: Read CoreSettings.UseLifeSteal

    Ultra->>Gear: CaptureEquipment(Bot)
    Gear-->>Ultra: EquipmentSnapshot

    Ultra->>Core: Boot()
    Ultra->>Ultra: Prep()

    activate Ultra
    Ultra->>Bot: Get Main.DoEquipClasses
    alt comp selected
        Ultra->>Ultra: ApplyCompAndEquip(comp, overrides)
        Ultra->>UltraCore: EquipClassSync(classes, 4, nulgath_class.sync, true)
    end

    Ultra->>Bot: Get CoreSettings.EquipBestGear
    alt EquipBestGear true
        Ultra->>Gear: EquipBestGear(Bot, Bots, GearProfilePreset.Damage)
    end

    Ultra->>Bot: Get CoreSettings.DoEnh
    alt DoEnh true
        Ultra->>Ultra: DoEnhs() [apply enhancements]
    end

    Ultra->>UltraCore: UseAlchemyPotions(bestTonic, bestElixir)

    alt IsTaunter()
        Ultra->>UltraCore: GetScrollOfEnrage()
    else not taunter and UseLifeSteal
        Ultra->>UltraCore: GetScrollOfLifeSteal()
    end
    deactivate Ultra

    Ultra->>Ultra: Fight()

    loop fight loop
        Ultra->>Bot: Check Alive, quest progress
        alt IsTaunter()
            Ultra->>Bot: Attack(2) [Nulgath]
            Ultra->>Bot: UseSkill(5) [Scroll of Enrage until Focus]
        else non-taunter
            Ultra->>Bot: Attack(1 or 2)
            alt UseLifeSteal
                Ultra->>Bot: UseSkill(5) [Scroll of Life Steal]
            end
        end
    end

    Ultra-->>Bot: Fight exits

    Ultra->>Gear: RestoreEquipment(Bot, Bots, EquipmentSnapshot, true)
    Ultra->>Bots: SetOptions(false)
    Ultra-->>Bot: ScriptMain returns
Loading

Class diagram for new CoreGearUtils gear optimization utility

classDiagram
    direction LR

    class CoreGearUtils {
        <<static>>
        +EquipBestGear(preset GearProfilePreset)
        +EquipBestGear(bot IScriptInterface, core CoreBots, preset GearProfilePreset)
        +EquipBestGear(profileOrMetaOrder string)
        +EquipBestGear(bot IScriptInterface, core CoreBots, profileOrMetaOrder string)
        +CaptureEquipment() EquipmentSnapshot
        +CaptureEquipment(bot IScriptInterface) EquipmentSnapshot
        +RestoreEquipment(snapshot EquipmentSnapshot, loadBank bool)
        +RestoreEquipment(bot IScriptInterface, core CoreBots, snapshot EquipmentSnapshot, loadBank bool)
    }

    class GearProfilePreset {
        <<enum>>
        Damage
        Gold
        Exp
        ClassPoints
        Reputation
        Chaos
        Undead
        Elemental
        Dragonkin
        Human
        Orc
    }

    class EquipmentSnapshot {
        +EquipmentSnapshot(bySlot Dictionary~string,string~, orderedItems string[])
        +BySlot Dictionary~string,string~
        +OrderedItems string[]
    }

    class GearPlan {
        <<internal>>
        -GearPlan(primaryMeta string, secondaryMeta string, metaPriority string[])
        -PrimaryMeta string
        -SecondaryMeta string
        -MetaPriority string[]
    }

    class BoostCandidate {
        <<internal>>
        -BoostCandidate(item InventoryItem, slot string, primary double, secondary double)
        -Item InventoryItem
        -Slot string
        -Primary double
        -Secondary double
    }

    class CoreBots {
        +Unbank(itemName string) void
        +EquipBestItemsForMeta(metaBySlot Dictionary~string,string[]~) void
        +GetBoostFloat(item InventoryItem, meta string) double
        +Instance CoreBots
    }

    class IScriptInterface {
        +Instance IScriptInterface
        +Inventory Inventory
        +Bank Bank
        +Player Player
        +Log(message string) void
    }

    class InventoryItem {
    }

    CoreGearUtils ..> GearProfilePreset : uses
    CoreGearUtils ..> EquipmentSnapshot : creates
    CoreGearUtils ..> CoreBots : uses
    CoreGearUtils ..> IScriptInterface : uses
    CoreGearUtils ..> GearPlan : builds
    CoreGearUtils ..> BoostCandidate : evaluates
    BoostCandidate --> InventoryItem : wraps
    EquipmentSnapshot o--> "1" Dictionary~string,string~ : BySlot
    EquipmentSnapshot o--> "*" string : OrderedItems
    CoreBots ..> InventoryItem : boosts
    IScriptInterface ..> InventoryItem : owns
Loading

Class diagram for updated UltraNulgath and ChampionDrakath scripts with presets and life steal

classDiagram
    direction LR

    class UltraNulgath {
        +DontPreconfigure bool
        +OptionsStorage string
        +MultiOptions string[]
        -a string
        -b string
        -c string
        -d string
        -overrideA string
        -overrideB string
        -overrideC string
        -overrideD string
        -UseLifeSteal bool
        +Main List~IOption~
        +CoreSettings List~IOption~
        +ClassOverrides List~IOption~
        +ScriptMain(bot IScriptInterface) void
        -IsTaunter() bool
        -Prep() void
        -ApplyCompAndEquip(comp NulgathComp, aOverride string, bOverride string, cOverride string, dOverride string) void
        -Fight() void
        -DoEnhs() void
    }

    class NulgathComp {
        <<enum>>
        Unselected
        Fast
        F2PFast
        Common
        Balanced
    }

    class ChampionDrakath {
        +DontPreconfigure bool
        +OptionsStorage string
        +MultiOptions string[]
        -a string
        -b string
        -c string
        -d string
        -overrideA string
        -overrideB string
        -overrideC string
        -overrideD string
        -UseLifeSteal bool
        -previousHP int
        -hpThresholds int[]
        +Main List~IOption~
        +CoreSettings List~IOption~
        +ClassOverrides List~IOption~
        +ScriptMain(bot IScriptInterface) void
        -IsTaunter() bool
        -Prep() void
        -ApplyCompAndEquip(comp DrakathComp, aOverride string, bOverride string, cOverride string, dOverride string) void
        -Fight() void
        -DoEnhs() void
    }

    class DrakathComp {
        <<enum>>
        Unselected
        Safe
        Fast
        Cheapest
    }

    class HowManyTaunts {
        <<enum>>
        One
        Two
        Three
        Four
    }

    class CoreUltra {
        +GetScrollOfEnrage() void
        +GetScrollOfLifeSteal(minStock int, restockTo int) void
        +UseAlchemyPotions(tonic string, elixir string) void
        +EquipClassSync(classes string[][], slots int, syncFile string, allowDuplicates bool) void
        +WaitForArmy(minCount int, syncFile string) void
        +ResolveSyncPath(fileName string) string
        +ClearSyncFile(path string) void
        +CheckArmyProgressBool(checkFunc Func~bool~, syncPath string) bool
    }

    class CoreGearUtils {
        +EquipBestGear(bot IScriptInterface, core CoreBots, preset GearProfilePreset) void
        +CaptureEquipment(bot IScriptInterface) EquipmentSnapshot
        +RestoreEquipment(bot IScriptInterface, core CoreBots, snapshot EquipmentSnapshot, loadBank bool) void
    }

    class GearProfilePreset {
        <<enum>>
    }

    class CoreBots {
        +Logger(tag string, message string) void
        +EnsureAccept(id int) void
        +EnsureComplete(id int) void
        +AddDrop(name string) void
        +Jump(cell string, pad string) void
        +Join(map string) void
        +SetOptions(isActive bool) void
    }

    class CoreEngine {
        +Boot() void
        +Join(map string) void
        +ChooseBestCell(target string) void
        +EnableSkills() void
        +DisableSkills() void
        +EquipEnrage() void
    }

    UltraNulgath ..> NulgathComp : uses
    UltraNulgath ..> CoreUltra : collaborates
    UltraNulgath ..> CoreGearUtils : snapshot_and_best_gear
    UltraNulgath ..> GearProfilePreset : selects
    UltraNulgath ..> CoreBots : uses
    UltraNulgath ..> CoreEngine : uses

    ChampionDrakath ..> DrakathComp : uses
    ChampionDrakath ..> HowManyTaunts : uses
    ChampionDrakath ..> CoreUltra : collaborates
    ChampionDrakath ..> CoreGearUtils : snapshot_and_best_gear
    ChampionDrakath ..> GearProfilePreset : selects
    ChampionDrakath ..> CoreBots : uses
    ChampionDrakath ..> CoreEngine : uses

    CoreUltra ..> CoreBots : uses
    CoreGearUtils ..> EquipmentSnapshot : returns
Loading

File-Level Changes

Change Details Files
Ultra Nulgath script now uses multi-tab options, shared gear utilities, class comp presets/overrides, and life-steal support while keeping existing taunt/DPS logic.
  • Replaces single Options list with three option groups (Main, CoreSettings, ClassOverrides) and adds MultiOptions wiring.
  • Adds class composition enum defaults, per-slot overrides, and helper to apply/equip compositions across 4 clients.
  • Introduces EquipmentSnapshot capture/restore around the run and switches to CoreGearUtils for best-gear equip.
  • Refactors taunter detection into IsTaunter and uses it consistently in fight logic.
  • Adds UseLifeSteal flag and corresponding Scroll of Life Steal usage for non-taunters while taunters still use Scroll of Enrage.
  • Updates enhancement logic to handle Chrono ShadowHunter and Infinity Titan in addition to existing classes.
  • Reorders control flow in ScriptMain/Prep/Fight but preserves core combat targeting and taunt rotation behavior.
Ultras/UltraNulgath.cs
Champion Drakath script is updated to use class presets/overrides, shared gear utilities, life-steal support, and modernized taunter configuration while keeping the phase-based taunt logic intact.
  • Renames OptionsStorage and introduces MultiOptions with three option pages (Main, CoreSettings, ClassOverrides).
  • Adds DrakathComp enum and ApplyCompAndEquip to define Safe/Fast/Cheapest class compositions with inventory-aware fallbacks and overrides.
  • Removes SoloTaunt in favor of HowManyTaunts and validates that all enabled taunter slots have overrides when not using presets.
  • Captures and restores equipment using CoreGearUtils, and routes best-gear selection through CoreGearUtils with a Chaos profile.
  • Moves DoEnh, EquipBestGear, and potion/scroll setup into Prep, adding Scroll of Life Steal for non-taunters.
  • Injects non-taunter life-steal usage into Fight loop and adds comments clarifying Scroll of Enrage/Life Steal responsibilities.
  • Minor logging/option key updates (new OptionsStorage name, namespaced config keys).
Ultras/ChampionDrakath.cs
CoreUltra gains a helper to restock and equip Scroll of Life Steal for reuse by ultra scripts.
  • Adds GetScrollOfLifeSteal method that unbanks, restocks from a specific shop if below a minimum stock, and equips the consumable.
  • Leaves existing GetScrollOfEnrage and taunt helpers unchanged.
Ultras/CoreUltra.cs
Introduces CoreGearUtils utility to centralize gear optimization and equipment snapshot/restore logic for scripts.
  • Adds GearProfilePreset enum to represent common gearing goals (damage, gold, exp, cp, rep, and several race-specific presets).
  • Implements EquipBestGear overloads that either take a preset or a meta-order string and build a GearPlan with primary/secondary metas and priority list.
  • Adds CaptureEquipment and RestoreEquipment to snapshot currently equipped items by logical slot and re-equip them later (with optional bank loading).
  • Implements meta token normalization and mapping from user strings or presets into internal boost metas.
  • Uses CoreBots.EquipBestItemsForMeta for baseline equip, then searches inventory+bank for the best stacking pair of items for primary+secondary boosts by slot and equips them.
  • Defines internal helpers for category-to-slot mapping, bank loading, and a small BoostCandidate/GearPlan/EquipmentSnapshot data model.
CoreGearUtils.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • The taunter/composition handling patterns in UltraNulgath and ChampionDrakath (MultiOptions, overrides, ApplyCompAndEquip, IsTaunter, life-steal vs enrage behavior) are very similar; consider extracting shared helpers (e.g., a small CoreUltraRoles utility) to reduce duplication and keep the logic consistent across ultras.
  • In ChampionDrakath.IsTaunter you are using currentClass.Contains(a/b/c/d) with default overrides that can be substrings (e.g., "Chrono Shadow"), and the comparison is case‑sensitive; consider switching to an ordinal case-insensitive equality or well-defined prefix pattern to avoid accidental matches or misses when class names differ only by case or contain overlapping substrings.
  • CoreGearUtils.RestoreEquipment always restores in a fixed slot order and then additional items; if a user had multiple cosmetics of the same slot equipped, you may want to document or adjust the ordering logic (e.g., preserve original equip order or prioritize class/weapon) to better match player expectations for what "equipment snapshot" means.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The taunter/composition handling patterns in UltraNulgath and ChampionDrakath (MultiOptions, overrides, ApplyCompAndEquip, IsTaunter, life-steal vs enrage behavior) are very similar; consider extracting shared helpers (e.g., a small `CoreUltraRoles` utility) to reduce duplication and keep the logic consistent across ultras.
- In ChampionDrakath.IsTaunter you are using `currentClass.Contains(a/b/c/d)` with default overrides that can be substrings (e.g., "Chrono Shadow"), and the comparison is case‑sensitive; consider switching to an ordinal case-insensitive equality or well-defined prefix pattern to avoid accidental matches or misses when class names differ only by case or contain overlapping substrings.
- CoreGearUtils.RestoreEquipment always restores in a fixed slot order and then additional items; if a user had multiple cosmetics of the same slot equipped, you may want to document or adjust the ordering logic (e.g., preserve original equip order or prioritize class/weapon) to better match player expectations for what "equipment snapshot" means.

## Individual Comments

### Comment 1
<location path="Ultras/UltraNulgath.cs" line_range="141-149" />
<code_context>
+        if (bot == null || core == null)
+            return;
+
+        try
+        {
+            TryLoadBank(bot);
</code_context>
<issue_to_address>
**issue (bug_risk):** Equipment snapshot restore does not revert enhancements, so DoEnhs permanently alters the player’s gear

Previously this used `Adv.GearStore(false, true)` before enhancing and `Adv.GearStore(true, true)` after, which reverted both items and their enhancements. The new snapshot restore only re-equips items and does not revert enhancements, so `DoEnhs()` now leaves permanent enhancement changes. If the goal is to fully restore the user’s gear, either keep the `GearStore` calls around `DoEnhs` or extend the snapshot/restore logic to capture and reapply enhancements too.
</issue_to_address>

### Comment 2
<location path="Ultras/ChampionDrakath.cs" line_range="252-253" />
<code_context>
+        if (Bot.Config!.Get<bool>("CoreSettings", "EquipBestGear"))
+            CoreGearUtils.EquipBestGear(Bot, C, GearProfilePreset.Chaos);
+
+        if (Bot.Config!.Get<bool>("CoreSettings", "DoEnh"))
             DoEnhs();

         Ultra.UseAlchemyPotions(
</code_context>
<issue_to_address>
**issue (bug_risk):** Enhancement changes are no longer reverted at the end of the run, unlike the previous GearStore-based behavior

Previously this logic wrapped enhancements with `Adv.GearStore(false, true)` / `Adv.GearStore(true, true)`, so any changes were reverted after the run. Now `DoEnhs()` is called directly and `CoreGearUtils.RestoreEquipment` only restores items, not their enhancements, so players keep the new enhancements permanently. If that’s unintended, we should either reintroduce the GearStore pattern around `DoEnhs()` or extend the snapshot/restore logic to include enhancement data.
</issue_to_address>

### Comment 3
<location path="CoreGearUtils.cs" line_range="137-146" />
<code_context>
+        if (bot == null || core == null)
+            return;
+
+        try
+        {
+            TryLoadBank(bot);
+
+            core.EquipBestItemsForMeta(
+                new Dictionary<string, string[]>
+                {
+                    { "Weapon", plan.MetaPriority },
+                    { "Armor", plan.MetaPriority },
+                    { "Helm", plan.MetaPriority },
+                    { "Cape", plan.MetaPriority },
+                    { "Pet", plan.MetaPriority },
+                }
+            );
+
+            EquipBestStackingPair(bot, core, plan.PrimaryMeta, plan.SecondaryMeta);
+        }
+        catch
+        {
+            bot.Log("Best gear equip failed. Continuing with current setup.");
+        }
+    }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Swallowing all exceptions in EquipBestGearInternal can hide real issues and make debugging harder

The blanket try/catch hides all errors and only logs a generic message, which will make regressions in calls like `EquipBestItemsForMeta` or `GetBoostFloat` very hard to diagnose. Please either log the actual exception details (at least `ex.Message` and some relevant context such as preset/meta info) or narrow the catch to the specific, expected failures (e.g., bank load issues) and let unexpected exceptions propagate.

Suggested implementation:

```csharp
    private static void EquipBestGearInternal(IScriptInterface bot, CoreBots core, GearPlan plan)
    {
        if (bot == null || core == null)
            return;

        try
        {
            TryLoadBank(bot);

            core.EquipBestItemsForMeta(
                new Dictionary<string, string[]>
                {
                    { "Weapon", plan.MetaPriority },
                    { "Armor", plan.MetaPriority },
                    { "Helm", plan.MetaPriority },
                    { "Cape", plan.MetaPriority },
                    { "Pet", plan.MetaPriority },
                }
            );

            EquipBestStackingPair(bot, core, plan.PrimaryMeta, plan.SecondaryMeta);
        }
        catch (System.Exception ex)
        {
            bot.Log(
                $"Best gear equip failed for plan '{plan?.Name ?? "unknown"}'. " +
                $"Primary meta: '{plan?.PrimaryMeta ?? "null"}', Secondary meta: '{plan?.SecondaryMeta ?? "null"}'."
            );
            bot.Log($"Exception while equipping best gear: {ex}");
        }

```

If `GearPlan` does not currently expose a `Name` property, either add one or adjust the log message to use whatever identifying information is available for the plan (e.g., preset enum, ID, or omit the plan name segment of the log).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +141 to +149
try
{
Core.Boot();
Prep();
Fight();
}
finally
{
CoreGearUtils.RestoreEquipment(Bot, C, equippedBefore);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Equipment snapshot restore does not revert enhancements, so DoEnhs permanently alters the player’s gear

Previously this used Adv.GearStore(false, true) before enhancing and Adv.GearStore(true, true) after, which reverted both items and their enhancements. The new snapshot restore only re-equips items and does not revert enhancements, so DoEnhs() now leaves permanent enhancement changes. If the goal is to fully restore the user’s gear, either keep the GearStore calls around DoEnhs or extend the snapshot/restore logic to capture and reapply enhancements too.

Comment on lines +252 to 253
if (Bot.Config!.Get<bool>("CoreSettings", "DoEnh"))
DoEnhs();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Enhancement changes are no longer reverted at the end of the run, unlike the previous GearStore-based behavior

Previously this logic wrapped enhancements with Adv.GearStore(false, true) / Adv.GearStore(true, true), so any changes were reverted after the run. Now DoEnhs() is called directly and CoreGearUtils.RestoreEquipment only restores items, not their enhancements, so players keep the new enhancements permanently. If that’s unintended, we should either reintroduce the GearStore pattern around DoEnhs() or extend the snapshot/restore logic to include enhancement data.

Comment on lines +137 to +146
try
{
TryLoadBank(bot);

core.EquipBestItemsForMeta(
new Dictionary<string, string[]>
{
{ "Weapon", plan.MetaPriority },
{ "Armor", plan.MetaPriority },
{ "Helm", plan.MetaPriority },
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Swallowing all exceptions in EquipBestGearInternal can hide real issues and make debugging harder

The blanket try/catch hides all errors and only logs a generic message, which will make regressions in calls like EquipBestItemsForMeta or GetBoostFloat very hard to diagnose. Please either log the actual exception details (at least ex.Message and some relevant context such as preset/meta info) or narrow the catch to the specific, expected failures (e.g., bank load issues) and let unexpected exceptions propagate.

Suggested implementation:

    private static void EquipBestGearInternal(IScriptInterface bot, CoreBots core, GearPlan plan)
    {
        if (bot == null || core == null)
            return;

        try
        {
            TryLoadBank(bot);

            core.EquipBestItemsForMeta(
                new Dictionary<string, string[]>
                {
                    { "Weapon", plan.MetaPriority },
                    { "Armor", plan.MetaPriority },
                    { "Helm", plan.MetaPriority },
                    { "Cape", plan.MetaPriority },
                    { "Pet", plan.MetaPriority },
                }
            );

            EquipBestStackingPair(bot, core, plan.PrimaryMeta, plan.SecondaryMeta);
        }
        catch (System.Exception ex)
        {
            bot.Log(
                $"Best gear equip failed for plan '{plan?.Name ?? "unknown"}'. " +
                $"Primary meta: '{plan?.PrimaryMeta ?? "null"}', Secondary meta: '{plan?.SecondaryMeta ?? "null"}'."
            );
            bot.Log($"Exception while equipping best gear: {ex}");
        }

If GearPlan does not currently expose a Name property, either add one or adjust the log message to use whatever identifying information is available for the plan (e.g., preset enum, ID, or omit the plan name segment of the log).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant