Skip to content

Comments

Add fortis gem stall#1472

Merged
chsami merged 4 commits intochsami:developmentfrom
heap-overfl0w:add-fortis-gem-stall
Sep 4, 2025
Merged

Add fortis gem stall#1472
chsami merged 4 commits intochsami:developmentfrom
heap-overfl0w:add-fortis-gem-stall

Conversation

@heap-overfl0w
Copy link
Contributor

  • Added support for Fortis Gem Stall to Thieving script

…quirements satisfied to do so.

Fixed a deprecated API call with Simon Templeton by using Rs2NpcModel instead.
Handled issue where the banking branch tried to withdraw “gems” even when none were required for things like Unstrung symbols and Tiaras.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 4, 2025

Walkthrough

This PR updates multiple plugins and enums:

  • Agility PyramidCourse: switches Rs2Inventory.useItemOnNpc second argument to Rs2NpcModel and expands waterskin handling with Humidify logic.
  • Crafting JewelryScript: replaces null gem check with Gem.NONE.
  • Jewelry enum: adds TIARA and UNSTRUNG_SYMBOL entries.
  • Magic AIOMagic: adds SPINFLAX activity and integrates new SpinFlaxScript; MagicActivity enum updated accordingly; introduces injected SpinFlaxScript lifecycle.
  • Adds SpinFlaxScript with banking/casting flow for Spin Flax.
  • Thieving: removes a debug log; adds FORTIS_GEM_STALL spot, updates ThievingSpotMapper constructor/mapping, and implements FortisGemStallThievingSpot.

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/crafting/jewelry/JewelryScript.java (1)

426-428: Fix precedence bug in hasFinishedCrafting (can bank too early).

As written, the ternary applies to (hasItem && hasNoGem) instead of guarding the whole right side. This can return true even when no crafted jewelry is present.

Apply:

-        return Rs2Inventory.hasItem(plugin.getJewelry().getItemID()) 
-                && hasNoGem ? !hasCraftingItem : !hasCraftingItem && !hasCutGem;
+        return Rs2Inventory.hasItem(plugin.getJewelry().getItemID())
+                && (hasNoGem ? !hasCraftingItem : (!hasCraftingItem && !hasCutGem));
🧹 Nitpick comments (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/constants/ThievingSpotMapper.java (1)

18-20: Verify DI wiring; Map.of will NPE on null values

If fortisGemStallThievingSpot (or any other field) isn’t injected, Map.of(...) will throw a NullPointerException during map construction. Please confirm DI provides this bean in all plugin contexts. Optionally switch on thievingSpot to avoid per-call allocations and to fail fast on unknown values.

Also applies to: 29-29

runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/model/FortisGemStallThievingSpot.java (1)

16-18: Anchor plane and stall ID robustness

If the stall sits on a different plane or swaps IDs when depleted, lookups can fail. Anchor on the player’s current plane and allow multiple IDs.

-    private static final WorldPoint SAFESPOT = new WorldPoint(1671, 3101, 0);
-    private static final int STALL_ID = 51935;
+    private static final WorldPoint SAFESPOT = new WorldPoint(1671, 3101, 0);
+    // Include other object IDs if the stall changes state
+    private static final java.util.Set<Integer> STALL_IDS = java.util.Set.of(51935);
@@
-        final GameObject stall = Rs2GameObject.getGameObject(STALL_ID, SAFESPOT, 2);
+        final WorldPoint anchor =
+            new WorldPoint(SAFESPOT.getX(), SAFESPOT.getY(), Rs2Player.getWorldLocation().getPlane());
+        final GameObject stall =
+            Rs2GameObject.getGameObject(obj -> STALL_IDS.contains(obj.getId()), anchor, 2);

If you prefer imports, add:

import java.util.Set;

Also applies to: 33-36

runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/AIOMagicPlugin.java (1)

142-146: Annotate shutDown with @OverRide

Ensures signature mismatch is caught at compile time.

-    protected void shutDown() {
+    @Override
+    protected void shutDown() {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 19fa74d and c3d1adf.

📒 Files selected for processing (10)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/courses/PyramidCourse.java (3 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/crafting/jewelry/JewelryScript.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/crafting/jewelry/enums/Jewelry.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/AIOMagicPlugin.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/enums/MagicActivity.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/scripts/SpinFlaxScript.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/StallThievingScript.java (0 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/constants/ThievingSpot.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/constants/ThievingSpotMapper.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/model/FortisGemStallThievingSpot.java (1 hunks)
💤 Files with no reviewable changes (1)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/StallThievingScript.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-25T15:51:39.272Z
Learnt from: runsonmypc
PR: chsami/Microbot#1417
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/AgilityScript.java:13-13
Timestamp: 2025-08-25T15:51:39.272Z
Learning: Both net.runelite.api.ItemID and net.runelite.api.gameval.ItemID are valid import paths in the RuneLite codebase. The microbot plugins consistently use net.runelite.api.ItemID as their established pattern.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/courses/PyramidCourse.java
🧬 Code graph analysis (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/model/FortisGemStallThievingSpot.java (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/Global.java (1)
  • Global (10-171)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java (1)
  • Rs2GameObject (36-2002)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java (1)
  • Rs2Player (67-2070)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/scripts/SpinFlaxScript.java (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2Inventory.java (1)
  • Rs2Inventory (60-2244)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/magic/Rs2Magic.java (1)
  • Rs2Magic (44-608)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java (1)
  • Rs2Player (67-2070)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/courses/PyramidCourse.java (4)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/magic/Rs2Magic.java (1)
  • Rs2Magic (44-608)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2Inventory.java (1)
  • Rs2Inventory (60-2244)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/Global.java (1)
  • Global (10-171)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java (1)
  • Rs2Player (67-2070)
🔇 Additional comments (6)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/thieving/stalls/constants/ThievingSpot.java (1)

7-8: Enum constant added correctly

Looks good. No issues spotted with the new enum value.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/courses/PyramidCourse.java (2)

19-21: Imports for Rs2NpcModel/Rs2Magic/MagicAction look correct.

Consistent with the updated APIs and usage below.


1163-1167: Switch to Rs2NpcModel matches the non-deprecated overload.

Correctly avoids the deprecated NPC overload.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/crafting/jewelry/JewelryScript.java (1)

128-131: Correct guard: use Gem.NONE instead of null.

Prevents withdrawing cut gems for Gem.NONE cases (e.g., tiara/symbol). Looks good.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/enums/MagicActivity.java (1)

11-12: Enum addition looks good

SPINFLAX is correctly added and comma usage is fine.

runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/AIOMagicPlugin.java (1)

62-75: SPINFLAX wiring is consistent

Injection and startup switch integrate SpinFlaxScript cleanly; shutdown path is covered.

Also applies to: 114-140

Comment on lines 1205 to 1232
private boolean handleEmptyWaterskins() {
if (Rs2Inventory.contains(ItemID.WATERSKIN0)) {
log.debug("Found empty waterskin(s), dropping them");
Rs2Inventory.drop(ItemID.WATERSKIN0);
Global.sleep(300, 500);
final boolean hasEmpty = Rs2Inventory.contains(ItemID.WATERSKIN0);
if (!hasEmpty) return false;

final boolean hasFilled = Rs2Inventory.contains(
ItemID.WATERSKIN1, ItemID.WATERSKIN2, ItemID.WATERSKIN3, ItemID.WATERSKIN4
);

if (!hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
log.debug("All waterskins are empty; casting Humidify");
if (Rs2Magic.cast(MagicAction.HUMIDIFY)) {
Global.sleepUntil(Rs2Player::isAnimating, 1500);
Global.sleepUntil(() -> !Rs2Player.isAnimating() && !Rs2Inventory.contains(ItemID.WATERSKIN0), 3500);
Global.sleep(200, 400);
}
return true;
}
return false;

if (hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
log.debug("Have filled waterskin(s); not casting Humidify because not all Waterskins are empty");
return false;
}

log.debug("Cannot cast Humidify; dropping empty waterskin(s)");
Rs2Inventory.drop(ItemID.WATERSKIN0);
Global.sleep(300, 500);
return true;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Guard Humidify cast failures to avoid crashes or stalls.

Two risks:

  • Rs2Magic.cast may throw (e.g., unconfigured MagicAction widget), crashing the plugin.
  • If cast() returns false, the method still returns true, causing repeated no-op loops.

Wrap the cast with try/catch and add a fallback to drop empties when casting fails.

Apply this diff:

-        if (!hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
-            log.debug("All waterskins are empty; casting Humidify");
-            if (Rs2Magic.cast(MagicAction.HUMIDIFY)) {
-                Global.sleepUntil(Rs2Player::isAnimating, 1500);
-                Global.sleepUntil(() -> !Rs2Player.isAnimating() && !Rs2Inventory.contains(ItemID.WATERSKIN0), 3500);
-                Global.sleep(200, 400);
-            }
-            return true;
-        }
+        if (!hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
+            log.debug("All waterskins are empty; casting Humidify");
+            try {
+                if (Rs2Magic.cast(MagicAction.HUMIDIFY)) {
+                    Global.sleepUntil(Rs2Player::isAnimating, 1500);
+                    Global.sleepUntil(() -> !Rs2Player.isAnimating() && !Rs2Inventory.contains(ItemID.WATERSKIN0), 3500);
+                    Global.sleep(200, 400);
+                } else {
+                    log.warn("Humidify cast returned false; dropping empty waterskin(s) as fallback");
+                    Rs2Inventory.drop(ItemID.WATERSKIN0);
+                    Global.sleep(300, 500);
+                }
+            } catch (RuntimeException e) {
+                log.warn("Humidify cast threw; dropping empty waterskin(s) as fallback", e);
+                Rs2Inventory.drop(ItemID.WATERSKIN0);
+                Global.sleep(300, 500);
+            }
+            return true;
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private boolean handleEmptyWaterskins() {
if (Rs2Inventory.contains(ItemID.WATERSKIN0)) {
log.debug("Found empty waterskin(s), dropping them");
Rs2Inventory.drop(ItemID.WATERSKIN0);
Global.sleep(300, 500);
final boolean hasEmpty = Rs2Inventory.contains(ItemID.WATERSKIN0);
if (!hasEmpty) return false;
final boolean hasFilled = Rs2Inventory.contains(
ItemID.WATERSKIN1, ItemID.WATERSKIN2, ItemID.WATERSKIN3, ItemID.WATERSKIN4
);
if (!hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
log.debug("All waterskins are empty; casting Humidify");
if (Rs2Magic.cast(MagicAction.HUMIDIFY)) {
Global.sleepUntil(Rs2Player::isAnimating, 1500);
Global.sleepUntil(() -> !Rs2Player.isAnimating() && !Rs2Inventory.contains(ItemID.WATERSKIN0), 3500);
Global.sleep(200, 400);
}
return true;
}
return false;
if (hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
log.debug("Have filled waterskin(s); not casting Humidify because not all Waterskins are empty");
return false;
}
log.debug("Cannot cast Humidify; dropping empty waterskin(s)");
Rs2Inventory.drop(ItemID.WATERSKIN0);
Global.sleep(300, 500);
return true;
}
private boolean handleEmptyWaterskins() {
final boolean hasEmpty = Rs2Inventory.contains(ItemID.WATERSKIN0);
if (!hasEmpty) return false;
final boolean hasFilled = Rs2Inventory.contains(
ItemID.WATERSKIN1, ItemID.WATERSKIN2, ItemID.WATERSKIN3, ItemID.WATERSKIN4
);
if (!hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
log.debug("All waterskins are empty; casting Humidify");
try {
if (Rs2Magic.cast(MagicAction.HUMIDIFY)) {
Global.sleepUntil(Rs2Player::isAnimating, 1500);
Global.sleepUntil(() -> !Rs2Player.isAnimating() && !Rs2Inventory.contains(ItemID.WATERSKIN0), 3500);
Global.sleep(200, 400);
} else {
log.warn("Humidify cast returned false; dropping empty waterskin(s) as fallback");
Rs2Inventory.drop(ItemID.WATERSKIN0);
Global.sleep(300, 500);
}
} catch (RuntimeException e) {
log.warn("Humidify cast threw; dropping empty waterskin(s) as fallback", e);
Rs2Inventory.drop(ItemID.WATERSKIN0);
Global.sleep(300, 500);
}
return true;
}
if (hasFilled && Rs2Magic.canCast(MagicAction.HUMIDIFY)) {
log.debug("Have filled waterskin(s); not casting Humidify because not all Waterskins are empty");
return false;
}
log.debug("Cannot cast Humidify; dropping empty waterskin(s)");
Rs2Inventory.drop(ItemID.WATERSKIN0);
Global.sleep(300, 500);
return true;
}
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/courses/PyramidCourse.java
around lines 1205-1232, wrap the Rs2Magic.cast(MagicAction.HUMIDIFY) call in a
try/catch and handle a false return: if cast throws or returns false, log the
failure, fall back to dropping empty waterskins (call
Rs2Inventory.drop(ItemID.WATERSKIN0) and a short sleep) and return true to
indicate the empties were handled; keep the existing successful-cast behavior
(sleep until animating/finished) and the early-return when there are filled
waterskins.

Comment on lines +18 to +19
TIARA("tiara", ItemID.TIARA, Gem.NONE, ItemID.TIARA_MOULD, JewelryType.SILVER, null, 23),
UNSTRUNG_SYMBOL("holy symbol", ItemID.UNSTRUNG_SYMBOL, Gem.NONE, ItemID.HOLY_MOULD, JewelryType.SILVER, null, 16),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Widget label mismatch: use “unstrung symbol” for crafting UI.

The furnace widget lists “Unstrung symbol”. Using “holy symbol” will likely fail Rs2Widget.clickWidget(itemName).

Apply:

-    UNSTRUNG_SYMBOL("holy symbol", ItemID.UNSTRUNG_SYMBOL, Gem.NONE, ItemID.HOLY_MOULD, JewelryType.SILVER, null, 16),
+    UNSTRUNG_SYMBOL("unstrung symbol", ItemID.UNSTRUNG_SYMBOL, Gem.NONE, ItemID.HOLY_MOULD, JewelryType.SILVER, null, 16),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TIARA("tiara", ItemID.TIARA, Gem.NONE, ItemID.TIARA_MOULD, JewelryType.SILVER, null, 23),
UNSTRUNG_SYMBOL("holy symbol", ItemID.UNSTRUNG_SYMBOL, Gem.NONE, ItemID.HOLY_MOULD, JewelryType.SILVER, null, 16),
TIARA("tiara", ItemID.TIARA, Gem.NONE, ItemID.TIARA_MOULD, JewelryType.SILVER, null, 23),
UNSTRUNG_SYMBOL("unstrung symbol", ItemID.UNSTRUNG_SYMBOL, Gem.NONE, ItemID.HOLY_MOULD, JewelryType.SILVER, null, 16),
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/crafting/jewelry/enums/Jewelry.java
around lines 18-19, the enum entry uses the display name "holy symbol" which
doesn't match the furnace widget label and will break
Rs2Widget.clickWidget(itemName); change the display string to "unstrung symbol"
(matching the crafting UI label) for the UNSTRUNG_SYMBOL enum entry so clicks
target the correct widget.

Comment on lines +151 to +152
overlayManager.remove(aioMagicOverlay);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid NPE on shutdown when OverlayManager is null

Null-check before removal to prevent a shutdown crash.

Apply this diff:

-        overlayManager.remove(aioMagicOverlay);
+        if (overlayManager != null) {
+            overlayManager.remove(aioMagicOverlay);
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
overlayManager.remove(aioMagicOverlay);
}
if (overlayManager != null) {
overlayManager.remove(aioMagicOverlay);
}
}
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/AIOMagicPlugin.java
around lines 151-152, the call overlayManager.remove(aioMagicOverlay) can throw
an NPE if overlayManager is null during shutdown; add a null-check to ensure
overlayManager is not null (and optionally aioMagicOverlay is not null) before
calling remove, e.g. wrap the removal in an if (overlayManager != null) {
overlayManager.remove(aioMagicOverlay); } to avoid the crash.

Comment on lines +3 to +5
import net.runelite.api.Skill;
import net.runelite.api.gameval.ItemID;
import net.runelite.client.plugins.microbot.Microbot;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect ItemID import (compile error)

The package should be net.runelite.api.ItemID.

-import net.runelite.api.gameval.ItemID;
+import net.runelite.api.ItemID;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import net.runelite.api.Skill;
import net.runelite.api.gameval.ItemID;
import net.runelite.client.plugins.microbot.Microbot;
import net.runelite.api.Skill;
import net.runelite.api.ItemID;
import net.runelite.client.plugins.microbot.Microbot;
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/scripts/SpinFlaxScript.java
around lines 3 to 5, the import for ItemID is incorrect
(net.runelite.api.gameval.ItemID) causing a compile error; replace that import
with net.runelite.api.ItemID and remove the wrong one so the correct ItemID
class from net.runelite.api is used.

Comment on lines +66 to +74
Rs2Bank.depositAll(ItemID.BOW_STRING);
Rs2Inventory.waitForInventoryChanges(1200);

boolean hasAstralInv = Rs2Inventory.hasItem(Runes.ASTRAL.getItemId());
boolean hasNatureInv = Rs2Inventory.hasItem(Runes.NATURE.getItemId());
boolean hasAirInv = Rs2Inventory.hasItem(Runes.AIR.getItemId());

boolean hasAstralBank = Rs2Bank.hasItem(Runes.ASTRAL.getItemId());
boolean hasNatureBank = Rs2Bank.hasItem(Runes.NATURE.getItemId());
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Banking loop can soft-lock when carrying flax

If a cast fails and you return to bank with flax in inventory, the empty-slot check will never pass. Deposit flax before the slot check.

                         Rs2Bank.depositAll(ItemID.BOW_STRING);
                         Rs2Inventory.waitForInventoryChanges(1200);
+                        // Ensure we don't get stuck with flax in inventory
+                        if (Rs2Inventory.hasItem(ItemID.FLAX)) {
+                            Rs2Bank.depositAll(ItemID.FLAX);
+                            Rs2Inventory.waitForInventoryChanges(1200);
+                        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Rs2Bank.depositAll(ItemID.BOW_STRING);
Rs2Inventory.waitForInventoryChanges(1200);
boolean hasAstralInv = Rs2Inventory.hasItem(Runes.ASTRAL.getItemId());
boolean hasNatureInv = Rs2Inventory.hasItem(Runes.NATURE.getItemId());
boolean hasAirInv = Rs2Inventory.hasItem(Runes.AIR.getItemId());
boolean hasAstralBank = Rs2Bank.hasItem(Runes.ASTRAL.getItemId());
boolean hasNatureBank = Rs2Bank.hasItem(Runes.NATURE.getItemId());
Rs2Bank.depositAll(ItemID.BOW_STRING);
Rs2Inventory.waitForInventoryChanges(1200);
// Ensure we don't get stuck with flax in inventory
if (Rs2Inventory.hasItem(ItemID.FLAX)) {
Rs2Bank.depositAll(ItemID.FLAX);
Rs2Inventory.waitForInventoryChanges(1200);
}
boolean hasAstralInv = Rs2Inventory.hasItem(Runes.ASTRAL.getItemId());
boolean hasNatureInv = Rs2Inventory.hasItem(Runes.NATURE.getItemId());
boolean hasAirInv = Rs2Inventory.hasItem(Runes.AIR.getItemId());
boolean hasAstralBank = Rs2Bank.hasItem(Runes.ASTRAL.getItemId());
boolean hasNatureBank = Rs2Bank.hasItem(Runes.NATURE.getItemId());
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/magic/aiomagic/scripts/SpinFlaxScript.java
around lines 66-74, the banking loop can soft-lock if the player returns to bank
still carrying flax because the later empty-slot check never passes; modify the
sequence so you deposit any flax (bow strings or raw flax) before performing the
empty-slot/inventory checks, i.e., call deposit for flax items first, wait for
inventory change, then evaluate hasAstral/hasNature/hasAir and bank item
presence.

@chsami chsami merged commit 34a3af7 into chsami:development Sep 4, 2025
1 check passed
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.

2 participants