Conversation
heap-overfl0w
commented
Sep 4, 2025
- 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.
WalkthroughThis PR updates multiple plugins and enums:
Possibly related PRs
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
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 valuesIf
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 onthievingSpotto 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 robustnessIf 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 @OverRideEnsures 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.
📒 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 correctlyLooks 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 goodSPINFLAX 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 consistentInjection and startup switch integrate SpinFlaxScript cleanly; shutdown path is covered.
Also applies to: 114-140
| 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; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
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.
| 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.
| 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), |
There was a problem hiding this comment.
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.
| 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.
| overlayManager.remove(aioMagicOverlay); | ||
| } |
There was a problem hiding this comment.
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.
| 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.
| import net.runelite.api.Skill; | ||
| import net.runelite.api.gameval.ItemID; | ||
| import net.runelite.client.plugins.microbot.Microbot; |
There was a problem hiding this comment.
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.
| 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.
| 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()); |
There was a problem hiding this comment.
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.
| 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.