diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index e8f3efa170..bda51e9344 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -45,6 +45,7 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.*; import net.runelite.client.plugins.microbot.Microbot; +import net.runelite.client.plugins.microbot.inventorysetups.InventorySetup; import net.runelite.client.plugins.microbot.util.security.Login; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.RunnableExceptionLogger; @@ -1301,6 +1302,10 @@ Object stringToObject(String str, Type type) return gson.fromJson(str, parameterizedType); } } + if(type == InventorySetup.class) + { + return gson.fromJson(str, type); + } if (type instanceof Class) { Class clazz = (Class) type; @@ -1377,6 +1382,10 @@ String objectToString(Object object) { return gson.toJson(object, Set.class); } + if (object instanceof InventorySetup) + { + return gson.toJson(object, InventorySetup.class); + } if (object != null) { ConfigSerializer configSerializer = object.getClass().getAnnotation(ConfigSerializer.class); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java index 120b36ad71..c9e4766ac6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java @@ -26,17 +26,18 @@ package net.runelite.client.plugins.bosstimer; import com.google.common.collect.ImmutableMap; -import java.time.Duration; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalUnit; -import java.util.Map; import lombok.Getter; import net.runelite.api.ItemID; import net.runelite.api.NpcID; import net.runelite.client.util.RSTimeUnit; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalUnit; +import java.util.Map; + @Getter -enum Boss +public enum Boss { GENERAL_GRAARDOR(NpcID.GENERAL_GRAARDOR, 90, ChronoUnit.SECONDS, ItemID.PET_GENERAL_GRAARDOR), KRIL_TSUTSAROTH(NpcID.KRIL_TSUTSAROTH, 90, ChronoUnit.SECONDS, ItemID.PET_KRIL_TSUTSAROTH), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/RespawnTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/RespawnTimer.java index 1d9d077f25..21905863ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/RespawnTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/RespawnTimer.java @@ -24,12 +24,13 @@ */ package net.runelite.client.plugins.bosstimer; -import java.awt.image.BufferedImage; -import java.time.temporal.ChronoUnit; import net.runelite.client.plugins.Plugin; import net.runelite.client.ui.overlay.infobox.Timer; -class RespawnTimer extends Timer +import java.awt.image.BufferedImage; +import java.time.temporal.ChronoUnit; + +public class RespawnTimer extends Timer { private final Boss boss; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleConfig.java new file mode 100644 index 0000000000..73ca041698 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleConfig.java @@ -0,0 +1,185 @@ +package net.runelite.client.plugins.microbot.bossing.giantmole; + +import net.runelite.client.config.*; +import net.runelite.client.plugins.microbot.inventorysetups.InventorySetup; +import net.runelite.client.plugins.microbot.playerassist.enums.DefaultLooterStyle; +@ConfigInformation("

S-1D Giant Mole

\n" + + "

BETA PREVIEW 1

\n" + + "

1. Select your Giant Mole inventory setup.

\n" + + "

2. Include a teleport to Falador for banking.

\n" + + "

3. Start in Falador with either an empty inventory or your complete setup.

\n" + + "

4. Falador hard diary is required for the mole locator.

\n" + + "

5. Spec Weapon use QoL to select spec weapon.

\n" + + "

\n" + + "

FEEDBACK: If you encounter any bugs or need assistance, please message us on Discord.

\n" +) +@ConfigGroup("giantmole") +public interface GiantMoleConfig extends Config { + + @ConfigSection( + name = "lootSection", + description = "Looting settings", + position = 1 + ) + String lootSection = "looting"; + + @ConfigItem( + keyName = "useQuickPrayer", + name = "Use quick prayer", + description = "Use quick prayer", + position = 0 + ) + default boolean useQuickPrayer() { + return true; + } + + // config item for inventory setup + @ConfigItem( + keyName = "inventorySetup", + name = "Inventory Setup", + description = "Inventory Setup", + position = 1 + ) + default InventorySetup inventorySetup() { + return null; + } + + @ConfigItem( + keyName = "Loot items", + name = "Auto loot items", + description = "Enable/disable loot items", + position = 0, + section = lootSection + ) + default boolean toggleLootItems() { + return true; + } + + @ConfigItem( + name = "Loot Style", + keyName = "lootStyle", + position = 1, + description = "Choose Looting Style", + section = lootSection + ) + default DefaultLooterStyle looterStyle() { + return DefaultLooterStyle.MIXED; + } + + @ConfigItem( + name = "List of Items", + keyName = "listOfItemsToLoot", + position = 2, + description = "List of items to loot", + section = lootSection + ) + default String listOfItemsToLoot() { + return "bones,ashes"; + } + + @ConfigItem( + keyName = "Min Price of items to loot", + name = "Min. Price of items to loot", + description = "Min. Price of items to loot", + position = 10, + section = lootSection + ) + default int minPriceOfItemsToLoot() { + return 5000; + } + + @ConfigItem( + keyName = "Max Price of items to loot", + name = "Max. Price of items to loot", + description = "Max. Price of items to loot default is set to 10M", + position = 11, + section = lootSection + ) + default int maxPriceOfItemsToLoot() { + return 10000000; + } + // toggle scatter + + @ConfigItem( + keyName = "Loot arrows", + name = "Auto loot arrows", + description = "Enable/disable loot arrows", + position = 20, + section = lootSection + ) + default boolean toggleLootArrows() { + return false; + } + + // toggle loot runes + @ConfigItem( + keyName = "Loot runes", + name = "Loot runes", + description = "Enable/disable loot runes", + position = 30, + section = lootSection + ) + default boolean toggleLootRunes() { + return false; + } + + // toggle loot coins + @ConfigItem( + keyName = "Loot coins", + name = "Loot coins", + description = "Enable/disable loot coins", + position = 40, + section = lootSection + ) + default boolean toggleLootCoins() { + return false; + } + + // toggle loot untreadables + @ConfigItem( + keyName = "Loot untradables", + name = "Loot untradables", + description = "Enable/disable loot untradables", + position = 50, + section = lootSection + ) + default boolean toggleLootUntradables() { + return false; + } + + @ConfigItem( + keyName = "Bury Bones", + name = "Bury Bones", + description = "Picks up and Bury Bones", + position = 96, + section = lootSection + ) + default boolean toggleBuryBones() { + return false; + } + + // only loot my items + @ConfigItem( + keyName = "onlyLootMyItems", + name = "Only Loot My Items", + description = "Only loot items that are dropped for/by you", + position = 99, + section = lootSection + ) + default boolean toggleOnlyLootMyItems() { + return false; + } + + //Force loot regardless if we are in combat or not + @ConfigItem( + keyName = "forceLoot", + name = "Force Loot", + description = "Force loot regardless if we are in combat or not", + position = 100, + section = lootSection + ) + default boolean toggleForceLoot() { + return false; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleOverlay.java new file mode 100644 index 0000000000..9643437667 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleOverlay.java @@ -0,0 +1,62 @@ +package net.runelite.client.plugins.microbot.bossing.giantmole; + +import net.runelite.client.ui.overlay.OverlayPanel; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +import javax.inject.Inject; +import java.awt.*; + +public class GiantMoleOverlay extends OverlayPanel { + + @Inject + GiantMoleOverlay(GiantMolePlugin plugin) + { + super(plugin); + setPosition(OverlayPosition.TOP_LEFT); + setNaughty(); + } + @Override + public Dimension render(Graphics2D graphics) { + try { + panelComponent.setPreferredSize(new Dimension(350, 400)); + panelComponent.getChildren().add(TitleComponent.builder() + .text("\uD83E\uDD86 Giant Mole \uD83E\uDD86") + .color(Color.ORANGE) + .build()); + + panelComponent.getChildren().add(LineComponent.builder().build()); + + panelComponent.getChildren().add(LineComponent.builder() + .left("Giant Mole Location:") + .right(GiantMoleScript.getMoleLocation() == null ? GiantMoleScript.isMoleDead() ? "Unknown" : "Close" : GiantMoleScript.getMoleLocation().toString()) + .build()); + + panelComponent.getChildren().add(LineComponent.builder().build()); + +// panelComponent.getChildren().add(LineComponent.builder() +// .left("Walker target:") +// .right(ShortestPathPlugin.getPathfinder() == null ? "Unknown" : ShortestPathPlugin.getPathfinder().getTarget().toString()) +// .build()); + panelComponent.getChildren().add(LineComponent.builder() + .left("State:") + .right(GiantMoleScript.state.toString()) + .build()); + panelComponent.getChildren().add(LineComponent.builder() + .left("Is dead:") + .right(String.valueOf(GiantMoleScript.isMoleDead() + )) + .build()); + panelComponent.getChildren().add(LineComponent.builder() + .left("Version:") + .right(GiantMoleScript.VERSION) + .build()); + + + } catch(Exception ex) { + System.out.println(ex.getMessage()); + } + return super.render(graphics); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMolePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMolePlugin.java new file mode 100644 index 0000000000..9ded2c745a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMolePlugin.java @@ -0,0 +1,85 @@ +package net.runelite.client.plugins.microbot.bossing.giantmole; + +import com.google.inject.Provides; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ChatMessageType; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; + +import javax.inject.Inject; +import java.awt.*; + +@PluginDescriptor( + name = PluginDescriptor.See1Duck + "Giant Mole", + description = "Giant Mole plugin", + tags = {"Giant Mole", "microbot"}, + enabledByDefault = false +) +@Slf4j +public class GiantMolePlugin extends Plugin { + @Inject + private GiantMoleConfig config; + @Getter + @Setter + public static InfoBoxManager infoBoxManager; + + @Inject + private OverlayManager overlayManager; + @Inject + private GiantMoleOverlay giantMoleOverlay; + + @Inject + GiantMoleScript giantMoleScript; + @Provides + GiantMoleConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(GiantMoleConfig.class); + } + + + + @Override + protected void startUp() throws AWTException { + if (overlayManager != null) { + overlayManager.add(giantMoleOverlay); + } + giantMoleScript.run(config); + } + + protected void shutDown() { + giantMoleScript.shutdown(); + overlayManager.remove(giantMoleOverlay); + } + int ticks = 10; + @Subscribe + public void onGameTick(GameTick tick) + { + //System.out.println(getName().chars().mapToObj(i -> (char)(i + 3)).map(String::valueOf).collect(Collectors.joining())); + + if (ticks > 0) { + ticks--; + } else { + ticks = 10; + } + + } + + @Subscribe + public void onChatMessage(ChatMessage event) { + if(event.getType() != ChatMessageType.GAMEMESSAGE) { + return; + } + if(event.getMessage().contains("You look inside the mole hill and see")) { + GiantMoleScript.isWorldOccupied = !event.getMessage().contains("no adventurers inside the mole tunnels."); + GiantMoleScript.checkedIfWorldOccupied = true; + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleScript.java new file mode 100644 index 0000000000..b59ff32770 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/GiantMoleScript.java @@ -0,0 +1,670 @@ +package net.runelite.client.plugins.microbot.bossing.giantmole; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.NPC; +import net.runelite.api.ObjectID; +import net.runelite.api.Skill; +import net.runelite.api.TileObject; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.bosstimer.Boss; +import net.runelite.client.plugins.bosstimer.BossTimersPlugin; +import net.runelite.client.plugins.bosstimer.RespawnTimer; +import net.runelite.client.plugins.microbot.Microbot; +import net.runelite.client.plugins.microbot.Script; +import net.runelite.client.plugins.microbot.bossing.giantmole.enums.State; +import net.runelite.client.plugins.microbot.inventorysetups.InventorySetup; +import net.runelite.client.plugins.microbot.playerassist.enums.DefaultLooterStyle; +import net.runelite.client.plugins.microbot.qualityoflife.QoLPlugin; +import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.util.Global; +import net.runelite.client.plugins.microbot.util.Rs2InventorySetup; +import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; +import net.runelite.client.plugins.microbot.util.bank.enums.BankLocation; +import net.runelite.client.plugins.microbot.util.combat.Rs2Combat; +import net.runelite.client.plugins.microbot.util.gameobject.Rs2GameObject; +import net.runelite.client.plugins.microbot.util.grounditem.LootingParameters; +import net.runelite.client.plugins.microbot.util.grounditem.Rs2GroundItem; +import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory; +import net.runelite.client.plugins.microbot.util.inventory.Rs2Item; +import net.runelite.client.plugins.microbot.util.math.Rs2Random; +import net.runelite.client.plugins.microbot.util.misc.Rs2Food; +import net.runelite.client.plugins.microbot.util.misc.Rs2Potion; +import net.runelite.client.plugins.microbot.util.npc.Rs2Npc; +import net.runelite.client.plugins.microbot.util.player.Rs2Player; +import net.runelite.client.plugins.microbot.util.prayer.Rs2Prayer; +import net.runelite.client.plugins.microbot.util.security.Login; +import net.runelite.client.plugins.microbot.util.walker.Rs2Walker; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import static net.runelite.client.plugins.microbot.util.player.Rs2Player.isMember; + +@Slf4j +public class GiantMoleScript extends Script +{ + public static State state = State.IDLE; + + public static final String VERSION = "0.0.1"; + + // Region IDs + public static final List FAlADOR_REGIONS = List.of(11828, 12084); + public static final List MOLE_TUNNEL_REGIONS = List.of(6993, 6992); + + // Important WorldPoints + public static final WorldPoint FALADOR_PARK = new WorldPoint(2989, 3378, 0); + + public static boolean isWorldOccupied = true; + public static boolean checkedIfWorldOccupied = false; + + private GiantMoleConfig localConfig; + + /** + * Main runner method for the Giant Mole script. + */ + public boolean run(GiantMoleConfig config) + { + localConfig = config; + Microbot.enableAutoRunOn = true; + Microbot.useStaminaPotsIfNeeded = true; + Microbot.runEnergyThreshold = 5000; + isWorldOccupied = true; + checkedIfWorldOccupied = false; + + mainScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> + { + try + { + if (!Microbot.isLoggedIn()) return; + if (!super.run()) return; + + long startTime = System.currentTimeMillis(); + + // Make sure BossTimersPlugin is running for mole kill timers + if (!Microbot.isPluginEnabled(BossTimersPlugin.class)) + { + Plugin bossingInfo = Microbot.getPluginManager().getPlugins().stream() + .filter(x -> x.getClass().getName().equals(BossTimersPlugin.class.getName())) + .findFirst() + .orElse(null); + Microbot.startPlugin(bossingInfo); + } + + updateState(config); + handlePotions(); + handleFood(); + + switch (state) + { + case IDLE: + handlePrayer(config); + if (isInFalador()) + { + if (!checkedIfWorldOccupied) + { + checkWorldOccupied(); + } + } + else if (isInMoleTunnel()) + { + handleLooting(config); + } + break; + + case HOPPING: + hopWorlds(); + break; + + case ENTERING_MOLE_LAIR: + goInsideMoleHill(); + break; + + case COMBAT: + handlePrayer(config); + attackMole(); + break; + + case HUNTING: + handlePrayer(config); + walkToMole(); + break; + + case BANKING: + handlePrayer(config); + handleBanking(config); + break; + + case WALKING_TO_MOLE_HOLE: + Rs2Walker.walkTo(FALADOR_PARK, 5); + break; + } + + long endTime = System.currentTimeMillis(); + long totalTime = endTime - startTime; + // Optionally log totalTime if you want to measure loop duration + } + catch (Exception ex) + { + System.out.println(ex.getMessage()); + } + }, 0, 600, TimeUnit.MILLISECONDS); + + return true; + } + + @Override + public void shutdown() + { + super.shutdown(); + } + + /** + * Updates the script's state based on current conditions. + */ + public void updateState(GiantMoleConfig config) + { + if (needBanking(config)) + { + state = State.BANKING; + return; + } + + if (isInMoleTunnel()) + { + if (isMoleDead()) + { + state = State.IDLE; + } + else if (isMoleNearby()) + { + state = State.COMBAT; + } + else + { + state = State.HUNTING; + } + } + + if (isInFalador()) + { + if (Rs2Player.getWorldLocation().distanceTo2D(FALADOR_PARK) > 10) + { + state = State.WALKING_TO_MOLE_HOLE; + return; + } + + if (checkedIfWorldOccupied && isWorldOccupied) + { + state = State.HOPPING; + return; + } + + if (checkedIfWorldOccupied) + { + state = State.ENTERING_MOLE_LAIR; + } + else + { + state = State.IDLE; + } + } + } + + /** + * Checks if current region is Falador. + */ + public boolean isInFalador() + { + return FAlADOR_REGIONS.contains(Rs2Player.getWorldLocation().getRegionID()); + } + + /** + * Checks if player is in the Giant Mole tunnel region. + */ + public static boolean isInMoleTunnel() + { + return MOLE_TUNNEL_REGIONS.contains(Rs2Player.getWorldLocation().getRegionID()); + } + + /** + * Hops to a random world (member/free based on current account). + */ + public void hopWorlds() + { + int randomWorld = Login.getRandomWorld(isMember()); + Microbot.hopToWorld(randomWorld); + checkedIfWorldOccupied = false; + state = State.IDLE; + } + + /** + * Retrieves the Mole Hill tile object by ID. + */ + public TileObject getMoleHill() + { + return Rs2GameObject.getTileObject(ObjectID.MOLE_HILL); + } + + /** + * Uses "Look-inside" on the Mole Hill to check occupancy. + */ + public void checkWorldOccupied() + { + TileObject moleHill = getMoleHill(); + if (moleHill != null) + { + Rs2GameObject.interact(moleHill, "Look-inside"); + Global.sleepUntilTrue(() -> checkedIfWorldOccupied, 200, 7000); + } + } + + /** + * Enters the mole lair by digging on the Mole Hill with a spade. + */ + public void goInsideMoleHill() + { + TileObject moleHill = getMoleHill(); + if (moleHill != null) + { + if (Rs2Walker.walkTo(moleHill.getWorldLocation(), 0)) + { + Rs2Item spade = Rs2Inventory.get("Spade"); + Rs2Inventory.interact(spade, "Dig"); + } + } + } + + /** + * Returns the current world point of the mole if in the tunnel (hint arrow). + */ + public static WorldPoint getMoleLocation() + { + if (isInMoleTunnel()) + { + return Microbot.getClient().getHintArrowPoint(); + } + return null; + } + + /** + * Checks if the mole is within immediate range (i.e. no hint arrow or not needed). + */ + public static boolean isMoleNearby() + { + // If there's no hint arrow, we treat it as "nearby" or not tracked. + return getMoleLocation() == null; + } + + /** + * Checks if the Mole is currently considered 'dead' by the BossTimers plugin (respawn timer). + */ + public static boolean isMoleDead() + { + return Microbot.getInfoBoxManager().getInfoBoxes().stream() + .anyMatch(t -> t instanceof RespawnTimer && ((RespawnTimer) t).getBoss() == Boss.GIANT_MOLE); + } + + /** + * Returns the NPC representing the Giant Mole (via hint arrow). + */ + public NPC getMole() + { + return Microbot.getClient().getHintArrowNpc(); + } + + /** + * Walks toward the hinted Giant Mole location. + */ + public void walkToMole() + { + WorldPoint moleLocation = getMoleLocation(); + if (moleLocation != null) + { + if (!Rs2Walker.disableTeleports) + { + Rs2Walker.disableTeleports = true; + } + + if (ShortestPathPlugin.getPathfinder() != null) + { + if (ShortestPathPlugin.getPathfinder().getTarget().distanceTo2D(moleLocation) > 1) + { + log.info("Current target: " + ShortestPathPlugin.getPathfinder().getTarget()); + log.info("New target: " + moleLocation); + Rs2Walker.setTarget(moleLocation); + } + } + else + { + Microbot.getClientThread().runOnSeperateThread(() -> + { + Rs2Walker.walkTo(moleLocation); + return null; + }); + } + } + } + + /** + * Attacks the Giant Mole if not already in combat. + */ + public void attackMole() + { + NPC mole = getMole(); + if (mole != null && !Rs2Combat.inCombat()) + { + // Mole's "dig" animation is 3314; if it's mid-dig or dead, skip + if (mole.getAnimation() == 3314 || isMoleDead()) + { + return; + } + + // If pathfinder is active, exit it before attacking + if (ShortestPathPlugin.getPathfinder() != null) + { + ShortestPathPlugin.exit(); + sleep(600, 800); + } + + Rs2Npc.interact(mole, "Attack"); + sleep(600, 800); + } + } + + /** + * Toggles quick prayers when in combat, if enabled by config. + */ + public void handlePrayer(GiantMoleConfig config) + { + if (!config.useQuickPrayer()) + { + return; + } + + boolean underAttack = !Rs2Npc.getNpcsForPlayer().isEmpty() || Rs2Combat.inCombat(); + Rs2Prayer.toggleQuickPrayer(!isInFalador() && underAttack); + } + + // Handles food consumption + public void handleFood() + { + boolean usingQoLFood = Microbot.getConfigManager().getConfiguration("QoL", "autoEatFood", Boolean.class); + if (!(Microbot.isPluginEnabled(QoLPlugin.class) && usingQoLFood)) + { + Rs2Player.eatAt(Rs2Random.randomGaussian(50, 10)); + } + } + + /** + * Handles prayer/combat potion usage if the QoL plugin isn't auto-drinking. + */ + public void handlePotions() + { + boolean usingQoLPrayer = Microbot.getConfigManager().getConfiguration("QoL", "autoDrinkPrayerPot", Boolean.class); + + if (!(Microbot.isPluginEnabled(QoLPlugin.class) && usingQoLPrayer)) + { + Rs2Player.drinkPrayerPotionAt(Rs2Random.randomGaussian(20, 10)); + } + + // Covers overload-like potions for RANGED, ATTACK, STRENGTH, DEFENCE, MAGIC + Rs2Player.drinkCombatPotionAt(Skill.RANGED); + Rs2Player.drinkCombatPotionAt(Skill.ATTACK); + Rs2Player.drinkCombatPotionAt(Skill.STRENGTH); + Rs2Player.drinkCombatPotionAt(Skill.DEFENCE); + Rs2Player.drinkCombatPotionAt(Skill.MAGIC); + } + + /** + * Handles banking logic at Falador East, loading inventory setups, etc. + */ + public boolean handleBanking(GiantMoleConfig config) + { + Rs2Walker.disableTeleports = false; + if (Rs2Bank.walkToBankAndUseBank(BankLocation.FALADOR_EAST)) + { + Rs2InventorySetup setup = new Rs2InventorySetup(config.inventorySetup(), mainScheduledFuture); + if (setup.loadEquipment() && setup.loadInventory()) + { + Rs2Bank.closeBank(); + state = State.WALKING_TO_MOLE_HOLE; + } + } + return false; + } + + /** + * Returns true if the player needs to bank (e.g., missing potions, full inventory). + */ + public static boolean needBanking(GiantMoleConfig config) + { + InventorySetup inventorySetup = config.inventorySetup(); + + // If no setup is selected, assume no banking is needed + if (inventorySetup == null) + { + return false; + } + + // (1) If inventory is full, we need to bank + if (Rs2Inventory.isFull()) + { + return true; + } + + // (2) For each potion type, check if setup requires it and if we have it + if (needsPotion(inventorySetup, Rs2Potion.getPrayerPotionsVariants())) return true; + if (needsPotion(inventorySetup, Rs2Potion.getRangePotionsVariants())) return true; + if (needsPotion(inventorySetup, Rs2Potion.getCombatPotionsVariants())) return true; + if (needsPotion(inventorySetup, Rs2Potion.getMagicPotionsVariants())) return true; + if (needsPotion(inventorySetup, Collections.singletonList(Rs2Potion.getStaminaPotion()))) return true; + return needsPotion(inventorySetup, Rs2Potion.getRestoreEnergyPotionsVariants()); + } + + /** + * Checks if the given setup requires any variant of a specific potion but the player does not have it. + */ + private static boolean needsPotion(InventorySetup setup, List potionVariants) + { + // If the setup doesn't contain any of these variants, no need to bank for them + if (!setupHasPotion(setup, potionVariants)) + { + return false; + } + // The setup does require it; if we don't have it, we need to bank + return !Rs2Inventory.hasItem(potionVariants); + } + + /** + * Checks if the given setup has any item matching any of the given potion variants. + */ + private static boolean setupHasPotion(InventorySetup setup, List potionVariants) + { + return setup.getInventory().stream().anyMatch(item -> + { + if (item.getName() == null) + { + return false; + } + // Strip off any "(x doses)" part + String itemBaseName = item.getName().split("\\(")[0].trim().toLowerCase(Locale.ENGLISH); + + // Check if that base name matches any potion variant + return potionVariants.stream().anyMatch(variant -> + { + String variantLower = variant.toLowerCase(Locale.ENGLISH); + return variantLower.contains(itemBaseName); + }); + }); + } + + // check if we need food + private static boolean needsFood(InventorySetup setup) + { + // if setup doesn't have any food, no need to bank for it + if (!setupHasFood(setup)) + { + return false; + } + // setup does require food; if we don't have it, we need to bank + return Rs2Inventory.getInventoryFood().isEmpty(); + } + + // check if setup has any food + private static boolean setupHasFood(InventorySetup setup) + { + return setup.getInventory().stream().anyMatch(item -> + { + if (item.getName() == null) + { + return false; + } + // get id of the item + int itemId = item.getId(); + return + Rs2Food.getIds().contains(itemId); + }); + } + + + + /** + * Central method to handle all looting logic. + */ + private void handleLooting(GiantMoleConfig config) + { + // Loot “by name” first + if (config.looterStyle() == DefaultLooterStyle.MIXED || config.looterStyle() == DefaultLooterStyle.ITEM_LIST) + { + lootItemsOnName(config); + } + + // Loot by value + if (config.looterStyle() == DefaultLooterStyle.MIXED || config.looterStyle() == DefaultLooterStyle.GE_PRICE_RANGE) + { + lootItemsByValue(config); + } + + // Loot arrows + lootArrows(config); + + // Loot bones + lootBones(config); + + // Loot runes + lootRunes(config); + + // Loot coins + lootCoins(config); + + // Loot untradables + lootUntradeableItems(config); + } + + private void lootArrows(GiantMoleConfig config) + { + if (config.toggleLootArrows()) + { + LootingParameters arrowParams = new LootingParameters( + 10, 1, 10, 0, false, config.toggleOnlyLootMyItems(), "arrow" + ); + if (Rs2GroundItem.lootItemsBasedOnNames(arrowParams)) + { + Microbot.pauseAllScripts = false; + } + } + } + + private void lootBones(GiantMoleConfig config) + { + if (config.toggleBuryBones()) + { + LootingParameters bonesParams = new LootingParameters( + 10, 1, 1, 0, false, config.toggleOnlyLootMyItems(), "bones" + ); + if (Rs2GroundItem.lootItemsBasedOnNames(bonesParams)) + { + Microbot.pauseAllScripts = false; + } + } + } + + private void lootRunes(GiantMoleConfig config) + { + if (config.toggleLootRunes()) + { + LootingParameters runesParams = new LootingParameters( + 10, 1, 1, 0, false, config.toggleOnlyLootMyItems(), " rune" + ); + if (Rs2GroundItem.lootItemsBasedOnNames(runesParams)) + { + Microbot.pauseAllScripts = false; + } + } + } + + private void lootCoins(GiantMoleConfig config) + { + if (config.toggleLootCoins()) + { + LootingParameters coinsParams = new LootingParameters( + 10, 1, 1, 0, false, config.toggleOnlyLootMyItems(), "coins" + ); + if (Rs2GroundItem.lootCoins(coinsParams)) + { + Microbot.pauseAllScripts = false; + } + } + } + + private void lootUntradeableItems(GiantMoleConfig config) + { + if (config.toggleLootUntradables()) + { + LootingParameters untradeableItemsParams = new LootingParameters( + 10, 1, 1, 0, false, config.toggleOnlyLootMyItems(), "untradeable" + ); + if (Rs2GroundItem.lootUntradables(untradeableItemsParams)) + { + Microbot.pauseAllScripts = false; + } + } + } + + private void lootItemsByValue(GiantMoleConfig config) + { + LootingParameters valueParams = new LootingParameters( + config.minPriceOfItemsToLoot(), + config.maxPriceOfItemsToLoot(), + 10, + 1, + 0, + false, + config.toggleOnlyLootMyItems() + ); + if (Rs2GroundItem.lootItemBasedOnValue(valueParams)) + { + Microbot.pauseAllScripts = false; + } + } + + private void lootItemsOnName(GiantMoleConfig config) + { + LootingParameters valueParams = new LootingParameters( + 10, + 1, + 1, + 0, + false, + config.toggleOnlyLootMyItems(), + config.listOfItemsToLoot().trim().split(",") + ); + if (Rs2GroundItem.lootItemsBasedOnNames(valueParams)) + { + Microbot.pauseAllScripts = false; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/enums/State.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/enums/State.java new file mode 100644 index 0000000000..18c35a30db --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/bossing/giantmole/enums/State.java @@ -0,0 +1,11 @@ +package net.runelite.client.plugins.microbot.bossing.giantmole.enums; + +public enum State { + IDLE, + COMBAT, + HUNTING, + BANKING, + HOPPING, + ENTERING_MOLE_LAIR, + WALKING_TO_MOLE_HOLE +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeOverlay.java index 4d7a9de055..ea0b20c1c7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeOverlay.java @@ -2,6 +2,7 @@ import net.runelite.client.ui.overlay.OverlayPanel; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.TitleComponent; import javax.inject.Inject; @@ -24,6 +25,10 @@ public Dimension render(Graphics2D graphics) { .color(Color.GREEN) .build()); + panelComponent.getChildren().add(LineComponent.builder() + .left("Version: " + GabulhasGlassMakeScript.version) + .build()); + } catch(Exception ex) { System.out.println(ex.getMessage()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeScript.java index b231c0d524..012f3da632 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeScript.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/gabplugs/glassmake/GabulhasGlassMakeScript.java @@ -1,28 +1,16 @@ package net.runelite.client.plugins.microbot.gabplugs.glassmake; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.GameObject; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.widgets.Widget; import net.runelite.client.Notifier; -import net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig; import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.Script; -import net.runelite.client.plugins.microbot.globval.enums.InterfaceTab; import net.runelite.client.plugins.microbot.util.antiban.Rs2Antiban; +import net.runelite.client.plugins.microbot.util.antiban.Rs2AntibanSettings; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; -import net.runelite.client.plugins.microbot.util.gameobject.Rs2GameObject; import net.runelite.client.plugins.microbot.util.grounditem.Rs2GroundItem; import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory; import net.runelite.client.plugins.microbot.util.magic.Rs2Magic; -import net.runelite.client.plugins.microbot.util.magic.Rs2Spells; import net.runelite.client.plugins.microbot.util.math.Rs2Random; -import net.runelite.client.plugins.microbot.util.misc.Rs2UiHelper; -import net.runelite.client.plugins.microbot.util.npc.Rs2Npc; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; -import net.runelite.client.plugins.microbot.util.tabs.Rs2Tab; -import net.runelite.client.plugins.microbot.util.walker.Rs2Walker; -import net.runelite.client.plugins.microbot.util.widget.Rs2Widget; import net.runelite.client.plugins.skillcalculator.skills.MagicAction; import javax.inject.Inject; @@ -30,18 +18,21 @@ import static net.runelite.client.plugins.microbot.gabplugs.glassmake.GabulhasGlassMakeInfo.botStatus; import static net.runelite.client.plugins.microbot.gabplugs.glassmake.GabulhasGlassMakeInfo.states; -import static net.runelite.client.plugins.microbot.util.Global.sleep; -import static net.runelite.client.plugins.microbot.util.Global.sleepUntil; @Slf4j public class GabulhasGlassMakeScript extends Script { - public static double version = 1.0; + public static String version = "1.0.1"; @Inject private Notifier notifier; private GabulhasGlassMakeInfo.items currentItem; + private boolean oneTimeSpellBookCheck = false; + public boolean run(GabulhasGlassMakeConfig config) { + oneTimeSpellBookCheck = false; + Rs2Antiban.antibanSetupTemplates.applyUniversalAntibanSetup(); + Rs2AntibanSettings.actionCooldownChance = 0.2; currentItem= config.ITEM(); Microbot.enableAutoRunOn = false; mainScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { @@ -72,12 +63,13 @@ public boolean run(GabulhasGlassMakeConfig config) { } catch (Exception ex) { System.out.println(ex.getMessage()); } - }, 0, 1000, TimeUnit.MILLISECONDS); + }, 0, 600, TimeUnit.MILLISECONDS); return true; } @Override public void shutdown() { + Rs2Antiban.resetAntibanSettings(); super.shutdown(); } @@ -137,26 +129,19 @@ private void banking() { } private void glassblowing(){ - Rs2Tab.switchToMagicTab(); - sleep(60, 100); superglassmake(); sleep(60, 100); sleepUntil(()-> Rs2Inventory.contains("Molten Glass"), 100); } private void superglassmake() { - sleepUntil(() -> { - Rs2Tab.switchToMagicTab(); - sleep(50, 150); - return Rs2Tab.getCurrentTab() == InterfaceTab.MAGIC; - }); - Widget superglass = Rs2Widget.findWidget(MagicAction.SUPERGLASS_MAKE.getName()); - if (superglass.getSpriteId() == 1972) { - Microbot.click(superglass.getBounds()); - } else { - superglass = Rs2Widget.findWidget("Superglass Make", false); - System.out.println(superglass); - Microbot.click(superglass.getBounds()); + if(!oneTimeSpellBookCheck) { + Rs2Magic.oneTimeSpellBookCheck(); + oneTimeSpellBookCheck = true; + } + if (Rs2Magic.quickCast(MagicAction.SUPERGLASS_MAKE)) { + Rs2Bank.preHover(); + sleep(600*2, 600*4); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistConfig.java index bb1d0dcf0b..7c76ec6d76 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistConfig.java @@ -382,6 +382,18 @@ default boolean toggleForceLoot() { return false; } + //toggle High Alch profitable items + @ConfigItem( + keyName = "highAlchProfitable", + name = "High Alch Profitable", + description = "High Alch Profitable items", + position = 101, + section = lootSection + ) + default boolean toggleHighAlchProfitable() { + return false; + } + //set center tile manually @ConfigItem( keyName = "Center Tile", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistPlugin.java index 786a462921..696e4998b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/PlayerAssistPlugin.java @@ -76,6 +76,7 @@ public class PlayerAssistPlugin extends Plugin { private final AttackStyleScript attackStyleScript = new AttackStyleScript(); private final BankerScript bankerScript = new BankerScript(); private final PrayerScript prayerScript = new PrayerScript(); + private final HighAlchScript highAlchScript = new HighAlchScript(); @Inject private PlayerAssistConfig config; @Inject @@ -119,6 +120,7 @@ protected void startUp() throws AWTException { attackStyleScript.run(config); bankerScript.run(config); prayerScript.run(config); + highAlchScript.run(config); Microbot.getSpecialAttackConfigs() .setSpecialAttack(true); } @@ -138,6 +140,7 @@ protected void shutDown() { attackStyleScript.shutdown(); bankerScript.shutdown(); prayerScript.shutdown(); + highAlchScript.shutdown(); resetLocation(); overlayManager.remove(playerAssistOverlay); overlayManager.remove(playerAssistInfoOverlay); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/bank/BankerScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/bank/BankerScript.java index 01165ce63b..9d55bcc76e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/bank/BankerScript.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/bank/BankerScript.java @@ -63,10 +63,11 @@ public boolean run(PlayerAssistConfig config) { mainScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { try { if (Microbot.isLoggedIn() && config.bank() && needsBanking()) { - handleBanking(); + if(handleBanking()){ + PlayerAssistPlugin.setState(State.IDLE); + } } else if (!needsBanking() && config.centerLocation().distanceTo(Rs2Player.getWorldLocation()) > config.attackRadius()) { PlayerAssistPlugin.setState(State.WALKING); - Microbot.pauseAllScripts = false; Rs2Walker.walkTo(config.centerLocation()); } } catch (Exception ex) { @@ -77,7 +78,7 @@ public boolean run(PlayerAssistConfig config) { } public boolean needsBanking() { - return isUpkeepItemDepleted(config) || Rs2Inventory.getEmptySlots() <= config.minFreeSlots(); + return (isUpkeepItemDepleted(config) && config.bank()) || (Rs2Inventory.getEmptySlots() <= config.minFreeSlots() && config.bank()); } public boolean withdrawUpkeepItems(PlayerAssistConfig config) { @@ -142,7 +143,6 @@ public boolean goToBank() { public boolean handleBanking() { PlayerAssistPlugin.setState(State.BANKING); - Microbot.pauseAllScripts = true; Rs2Prayer.disableAllPrayers(); if (Rs2Bank.walkToBankAndUseBank()) { depositAllExcept(config); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/combat/HighAlchScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/combat/HighAlchScript.java new file mode 100644 index 0000000000..b7cd6914ec --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/combat/HighAlchScript.java @@ -0,0 +1,34 @@ +package net.runelite.client.plugins.microbot.playerassist.combat; + +import net.runelite.client.plugins.microbot.Microbot; +import net.runelite.client.plugins.microbot.Script; +import net.runelite.client.plugins.microbot.playerassist.PlayerAssistConfig; +import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory; +import net.runelite.client.plugins.microbot.util.inventory.Rs2Item; +import net.runelite.client.plugins.microbot.util.magic.Rs2Magic; +import net.runelite.client.plugins.skillcalculator.skills.MagicAction; + +import java.util.concurrent.TimeUnit; + +public class HighAlchScript extends Script { +public boolean run(PlayerAssistConfig config) { + mainScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { + try { + if (!Microbot.isLoggedIn() || !super.run() || !config.toggleHighAlchProfitable()) return; + Rs2Item item = Rs2Inventory.get(Rs2Item::isHaProfitable); + if (item != null && Rs2Magic.canCast(MagicAction.HIGH_LEVEL_ALCHEMY)) { + Rs2Magic.alch(item); + } + + } catch(Exception ex) { + System.out.println(ex.getMessage()); + } + }, 0, 600, TimeUnit.MILLISECONDS); + return true; +} + + + public void shutdown() { + super.shutdown(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/combat/PrayerScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/combat/PrayerScript.java index 68d25a09bf..6848aa562c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/combat/PrayerScript.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/playerassist/combat/PrayerScript.java @@ -5,6 +5,7 @@ import net.runelite.client.plugins.microbot.Script; import net.runelite.client.plugins.microbot.playerassist.PlayerAssistConfig; import net.runelite.client.plugins.microbot.playerassist.enums.PrayerStyle; +import net.runelite.client.plugins.microbot.util.combat.Rs2Combat; import net.runelite.client.plugins.microbot.util.npc.Rs2Npc; import net.runelite.client.plugins.microbot.util.npc.Rs2NpcManager; import net.runelite.client.plugins.microbot.util.prayer.Rs2Prayer; @@ -34,9 +35,8 @@ public boolean run(PlayerAssistConfig config) { private void handlePrayer(PlayerAssistConfig config) { if (!Microbot.isLoggedIn() || !config.togglePrayer()) return; if (config.prayerStyle() != PrayerStyle.CONTINUOUS && config.prayerStyle() != PrayerStyle.ALWAYS_ON) return; - log.info("Prayer style: " + config.prayerStyle().getName()); if (config.prayerStyle() == PrayerStyle.CONTINUOUS) { - boolean underAttack = !Rs2Npc.getNpcsForPlayer().isEmpty(); + boolean underAttack = !Rs2Npc.getNpcsForPlayer().isEmpty() || Rs2Combat.inCombat(); Rs2Prayer.toggleQuickPrayer(underAttack); } else { if (super.run()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLConfig.java index 9272dccce8..1018dadf63 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLConfig.java @@ -2,6 +2,7 @@ import net.runelite.client.config.*; import net.runelite.client.plugins.microbot.fletching.enums.FletchingItem; +import net.runelite.client.plugins.microbot.inventorysetups.InventorySetup; import net.runelite.client.plugins.microbot.qualityoflife.enums.WintertodtActions; import net.runelite.client.plugins.microbot.util.misc.SpecialAttackWeaponEnum; @@ -64,15 +65,23 @@ public interface QoLConfig extends Config { @ConfigSection( name = "Wintertodt", description = "Wintertodt settings", - position = 7 + position = 70 ) String wintertodtSection = "wintertodtSection"; + // Guardian of the rift section + @ConfigSection( + name = "Guardian of the Rift", + description = "Guardian of the Rift settings", + position = 71 + ) + String guardianOfTheRiftSection = "guardianOfTheRiftSection"; + // Fletching section @ConfigSection( name = "Fletching", description = "Fletching settings", - position = 8 + position = 80 ) String fletchingSection = "fletchingSection"; @@ -80,10 +89,18 @@ public interface QoLConfig extends Config { @ConfigSection( name = "Firemaking", description = "Firemaking settings", - position = 9 + position = 81 ) String firemakingSection = "firemakingSection"; + // Runecrafting section + @ConfigSection( + name = "Runecrafting", + description = "Runecrafting settings", + position = 82 + ) + String runecraftingSection = "runecraftingSection"; + // boolean to render Max Hit Overlay @ConfigItem( keyName = "renderMaxHitOverlay", @@ -132,15 +149,27 @@ default boolean useDoLastAnvil() { return true; } - // boolean for DoLast action on Workbench + // boolean for Smart Workbench @ConfigItem( - keyName = "useDoLastWorkbench", - name = "Use Do-Last Workbench", - description = "Use Do-Last Workbench", - position = 3, - section = doLastSection + keyName = "smartWorkbench", + name = "Smart Workbench", + description = "Fills empty pouches and continues crafting Guardian essence", + position = 1, + section = guardianOfTheRiftSection ) - default boolean useDoLastWorkbench() { + default boolean smartWorkbench() { + return true; + } + + // boolean for Smart Mine + @ConfigItem( + keyName = "smartGotrMine", + name = "Smart Mine", + description = "Fills empty pouches and continues and continues mining huge remains", + position = 2, + section = guardianOfTheRiftSection + ) + default boolean smartGotrMine() { return true; } @@ -357,8 +386,8 @@ default boolean displaySetup1() { position = 2, section = inventorySection ) - default String Setup1() { - return ""; + default InventorySetup Setup1(){ + return null; } // boolean to display Setup 2 @@ -381,8 +410,8 @@ default boolean displaySetup2() { position = 4, section = inventorySection ) - default String Setup2() { - return ""; + default InventorySetup Setup2(){ + return null; } // boolean to display Setup 3 @@ -405,8 +434,8 @@ default boolean displaySetup3() { position = 6, section = inventorySection ) - default String Setup3() { - return ""; + default InventorySetup Setup3(){ + return null; } // boolean to display Setup 4 @@ -429,8 +458,8 @@ default boolean displaySetup4() { position = 8, section = inventorySection ) - default String Setup4() { - return ""; + default InventorySetup Setup4(){ + return null; } // Boolean to use auto drop @@ -710,5 +739,17 @@ default boolean quickFiremakeLogs() { return false; } + // boolean to Smart Runecraft + @ConfigItem( + keyName = "smartRunecraft", + name = "Smart Runecraft", + description = "Fills empty pouches and continues crafting runes", + position = 0, + section = runecraftingSection + ) + default boolean smartRunecraft() { + return true; + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLPlugin.java index 7fb3c422cf..6b44a9875a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLPlugin.java @@ -3,9 +3,7 @@ import com.google.inject.Provides; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.ChatMessageType; -import net.runelite.api.GameState; -import net.runelite.api.MenuEntry; +import net.runelite.api.*; import net.runelite.api.events.*; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; @@ -16,6 +14,7 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.config.ConfigPlugin; import net.runelite.client.plugins.microbot.Microbot; +import net.runelite.client.plugins.microbot.inventorysetups.InventorySetup; import net.runelite.client.plugins.microbot.qualityoflife.enums.WintertodtActions; import net.runelite.client.plugins.microbot.qualityoflife.managers.FiremakingManager; import net.runelite.client.plugins.microbot.qualityoflife.managers.FletchingManager; @@ -26,6 +25,8 @@ import net.runelite.client.plugins.microbot.util.antiban.FieldUtil; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; import net.runelite.client.plugins.microbot.util.camera.Rs2Camera; +import net.runelite.client.plugins.microbot.util.gameobject.Rs2GameObject; +import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory; import net.runelite.client.plugins.microbot.util.menu.NewMenuEntry; import net.runelite.client.plugins.microbot.util.widget.Rs2Widget; import net.runelite.client.ui.ColorScheme; @@ -67,7 +68,7 @@ public class QoLPlugin extends Plugin { private static final int YAW_INDEX = 1; private static final BufferedImage SWITCHER_ON_IMG = getImageFromConfigResource("switcher_on"); private static final BufferedImage STAR_ON_IMG = getImageFromConfigResource("star_on"); - public static String loadoutToLoad = ""; + public static InventorySetup loadoutToLoad = null; private static GameState lastGameState = GameState.UNKNOWN; private final int[] deltaCamera = new int[3]; private final int[] previousCamera = new int[3]; @@ -157,7 +158,7 @@ protected void startUp() throws AWTException { } if (config.autoStamina()) { Microbot.useStaminaPotsIfNeeded = true; - Microbot.runEnergyThreshold = config.staminaThreshold() * 100; + Microbot.runEnergyThreshold = config.staminaThreshold() * 1000; } autoRunScript.run(config); specialAttackScript.run(config); @@ -291,6 +292,41 @@ private void onMenuOptionClicked(MenuOptionClicked event) { updateLastWinthertodtAction(WintertodtActions.NONE); updateWintertodtInterupted(false); } + + } + if (config.smartWorkbench() && event.getMenuOption().contains("Smart Work-at") && event.getMenuEntry().getIdentifier() == ObjectID.WORKBENCH_43754) { + if(Rs2Inventory.anyPouchEmpty() && Rs2Inventory.hasItem(ItemID.GUARDIAN_ESSENCE)) { + event.consume(); + Microbot.getClientThread().runOnSeperateThread(() -> { + Rs2Inventory.fillPouches(); + Rs2GameObject.interact(ObjectID.WORKBENCH_43754); + return null; + }); + + } + } + if (config.smartGotrMine() && event.getMenuOption().contains("Smart Mine") && event.getMenuEntry().getIdentifier() == ObjectID.HUGE_GUARDIAN_REMAINS) { + if(Rs2Inventory.anyPouchEmpty() && Rs2Inventory.hasItem(ItemID.GUARDIAN_ESSENCE)) { + event.consume(); + Microbot.getClientThread().runOnSeperateThread(() -> { + Rs2Inventory.fillPouches(); + Rs2GameObject.interact(ObjectID.HUGE_GUARDIAN_REMAINS); + return null; + }); + + } + } + if (config.smartRunecraft() && event.getMenuOption().contains("Smart Craft-rune") && event.getMenuTarget().contains("Altar")) { + if(Rs2Inventory.anyPouchFull()) { + Microbot.getClientThread().runOnSeperateThread(() -> { + Rs2Inventory.waitForInventoryChanges(50000); + Rs2Inventory.emptyPouches(); + Rs2Inventory.waitForInventoryChanges(3000); + Rs2GameObject.interact("Altar"); + return null; + }); + + } } } @@ -346,7 +382,7 @@ private void onMenuEntryAdded(MenuEntryAdded event) { String option = event.getOption(); String target = event.getTarget(); MenuEntry menuEntry = event.getMenuEntry(); - boolean bankChestCheck = "Bank".equals(option) || ("Use".equals(option) && target.contains("Bank chest")); + boolean bankChestCheck = "Bank".equals(option) || ("Use".equals(option) && target.toLowerCase().contains("bank chest")); if (config.rightClickCameraTracking() && menuEntry.getNpc() != null && menuEntry.getNpc().getId() > 0) { addMenuEntry(event, "Track", target, this::customTrackOnClicked); @@ -377,8 +413,14 @@ private void onMenuEntryAdded(MenuEntryAdded event) { addMenuEntry(event, "Do-Last", target, this::customAnvilOnClicked); } - if (config.useDoLastWorkbench() && "Work-at".equals(option)) { - menuEntry.onClick(this::customWorkbenchOnClicked); + if (config.smartWorkbench() && menuEntry.getOption().contains("Work-at") && menuEntry.getIdentifier() == ObjectID.WORKBENCH_43754) { + menuEntry.setOption("Smart Work-at"); + } + if (config.smartGotrMine() && menuEntry.getOption().contains("Mine") && menuEntry.getIdentifier() == ObjectID.HUGE_GUARDIAN_REMAINS) { + menuEntry.setOption("Smart Mine"); + } + if (config.smartRunecraft() && menuEntry.getOption().contains("Craft-rune") && menuEntry.getTarget().contains("Altar")) { + menuEntry.setOption("Smart Craft-rune"); } if (config.displayInventorySetups() && bankChestCheck && event.getItemId() == -1) { @@ -388,16 +430,16 @@ private void onMenuEntryAdded(MenuEntryAdded event) { private void addLoadoutMenuEntries(MenuEntryAdded event, String target) { if (config.displaySetup1()) { - addLoadoutMenuEntry(event, "Equip: " + config.Setup1() + "", target, e -> customLoadoutOnClicked(e, config.Setup1())); + addLoadoutMenuEntry(event, "Equip: " + config.Setup1().getName() + "", target, e -> customLoadoutOnClicked(e, config.Setup1())); } if (config.displaySetup2()) { - addLoadoutMenuEntry(event, "Equip: " + config.Setup2() + "", target, e -> customLoadoutOnClicked(e, config.Setup2())); + addLoadoutMenuEntry(event, "Equip: " + config.Setup2().getName() + "", target, e -> customLoadoutOnClicked(e, config.Setup2())); } if (config.displaySetup3()) { - addLoadoutMenuEntry(event, "Equip: " + config.Setup3() + "", target, e -> customLoadoutOnClicked(e, config.Setup3())); + addLoadoutMenuEntry(event, "Equip: " + config.Setup3().getName() + "", target, e -> customLoadoutOnClicked(e, config.Setup3())); } if (config.displaySetup4()) { - addLoadoutMenuEntry(event, "Equip: " + config.Setup4() + "", target, e -> customLoadoutOnClicked(e, config.Setup4())); + addLoadoutMenuEntry(event, "Equip: " + config.Setup4().getName() + "", target, e -> customLoadoutOnClicked(e, config.Setup4())); } } @@ -428,6 +470,10 @@ public void onConfigChanged(ConfigChanged ev) { if (ev.getKey().equals("autoStamina")) { Microbot.useStaminaPotsIfNeeded = config.autoStamina(); } + + if (ev.getKey().equals("staminaThreshold")) { + Microbot.runEnergyThreshold = config.staminaThreshold() * 100; + } } @Subscribe @@ -440,9 +486,9 @@ public void onBeforeRender(BeforeRender render) { // TODO: These OnClick methods should be moved to a separate class to reduce the size and make this class more manageable - private void customLoadoutOnClicked(MenuEntry event, String loadoutName) { + private void customLoadoutOnClicked(MenuEntry event, InventorySetup loadout) { recordActions = false; - loadoutToLoad = loadoutName; + loadoutToLoad = loadout; executeLoadoutActions = true; } @@ -487,13 +533,13 @@ private void customAnvilOnClicked(MenuEntry event) { private void customWorkbenchOnClicked(MenuEntry event) { Microbot.log("Workbench"); - executeWorkbenchActions = true; + } private void recordNewActions(MenuEntry event) { recordActions = true; String option = event.getOption(); - if (BANK_OPTION.equals(option) || "Use".equals(option) && event.getTarget().contains("Bank chest")){ + if (BANK_OPTION.equals(option) || "Use".equals(option) && event.getTarget().toLowerCase().contains("bank chest")){ bankMenuEntries.clear(); } else if (SMELT_OPTION.equals(option)) { furnaceMenuEntries.clear(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLScript.java index d4ab64f095..ee4014e4e2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLScript.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/QoLScript.java @@ -56,7 +56,7 @@ public boolean run(QoLConfig config) { handleWorkbenchActions(); } - if (QoLPlugin.executeLoadoutActions && !QoLPlugin.loadoutToLoad.isEmpty()) { + if (QoLPlugin.executeLoadoutActions && QoLPlugin.loadoutToLoad != null) { handleInventorySetup(); } @@ -89,7 +89,7 @@ private void handleInventorySetup() { if (!openBank()) { Microbot.log("Bank did not open"); QoLPlugin.executeLoadoutActions = false; - QoLPlugin.loadoutToLoad = ""; + QoLPlugin.loadoutToLoad = null; return; } @@ -103,10 +103,10 @@ private void handleInventorySetup() { inventorySetup.loadInventory(); } QoLPlugin.executeLoadoutActions = false; - QoLPlugin.loadoutToLoad = ""; + QoLPlugin.loadoutToLoad = null; } catch (Exception ignored) { QoLPlugin.executeLoadoutActions = false; - QoLPlugin.loadoutToLoad = ""; + QoLPlugin.loadoutToLoad = null; Microbot.pauseAllScripts = false; Microbot.log("Failed to load inventory setup"); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/managers/FiremakingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/managers/FiremakingManager.java index 62a8a1da89..20f4189dd6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/managers/FiremakingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/qualityoflife/managers/FiremakingManager.java @@ -27,12 +27,12 @@ public FiremakingManager(QoLConfig config) { @Subscribe private void onMenuEntryAdded(MenuEntryAdded event) { - if (!Microbot.isLoggedIn() && !config.quickFiremakeLogs()) return; + if (!Microbot.isLoggedIn()) return; String option = event.getOption(); int itemId = event.getItemId(); - if (itemId == ItemID.TINDERBOX && "Use".equals(option)) { + if (itemId == ItemID.TINDERBOX && "Use".equals(option) && config.quickFiremakeLogs()) { modifyMenuEntry(event, "Light Logs", "", this::lightLogsOnClick); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/runecrafting/arceuus/ArceuusRcScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/runecrafting/arceuus/ArceuusRcScript.java index 3b0eb96b27..ded920327a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/runecrafting/arceuus/ArceuusRcScript.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/runecrafting/arceuus/ArceuusRcScript.java @@ -90,7 +90,7 @@ public void goToDarkAltar() { public boolean shouldGoToRunestone() { return !Rs2Inventory.isFull() - && Rs2Player.getWorldLocation().distanceTo(DENSE_RUNESTONE) > 10 + && Rs2Player.getWorldLocation().distanceTo(DENSE_RUNESTONE) > 8 && darkAltarTripCount < 2 && !(Rs2Player.getWorldLocation().distanceTo(ARCEUUS_BLOOD_ALTAR) < 5 && Rs2Inventory.hasItem(ItemID.DARK_ESSENCE_BLOCK,ItemID.DARK_ESSENCE_FRAGMENTS)); @@ -150,14 +150,14 @@ public void useDarkAltar() { } public void mineEssence() { - GameObject runeStone = Rs2GameObject.findObject("Dense runestone", true,10,false,Rs2Player.getWorldLocation()); + GameObject runeStone = Rs2GameObject.findObject("Dense runestone", true,11,false,Rs2Player.getWorldLocation()); if (runeStone != null) { Rs2GameObject.interact(runeStone,"Chip"); Rs2Player.waitForAnimation(10000); } } public static boolean shouldMineEssence() { - GameObject runeStone = Rs2GameObject.findObject("Dense runestone", true,10,false,Rs2Player.getWorldLocation()); + GameObject runeStone = Rs2GameObject.findObject("Dense runestone", true,11,false,Rs2Player.getWorldLocation()); return !Rs2Inventory.hasItem(ItemID.DARK_ESSENCE_BLOCK) && !Rs2Inventory.isFull() && !Rs2Player.isAnimating() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/ui/MicrobotConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/ui/MicrobotConfigPanel.java index 6c43f52bb8..9aff6f0471 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/ui/MicrobotConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/ui/MicrobotConfigPanel.java @@ -38,6 +38,8 @@ import net.runelite.client.externalplugins.ExternalPluginManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.microbot.inventorysetups.InventorySetup; +import net.runelite.client.plugins.microbot.inventorysetups.MInventorySetupsPlugin; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.DynamicGridLayout; import net.runelite.client.ui.FontManager; @@ -342,6 +344,10 @@ else if (cid.getType() == Dimension.class) { item.add(createDimension(cd, cid), BorderLayout.EAST); } + else if (cid.getType() == InventorySetup.class) + { + item.add(createInventorySetupsComboBox(cd, cid), BorderLayout.EAST); + } else if (cid.getType() instanceof Class && ((Class) cid.getType()).isEnum()) { item.add(createComboBox(cd, cid), BorderLayout.EAST); @@ -597,6 +603,70 @@ private JPanel createDimension(ConfigDescriptor cd, ConfigItemDescriptor cid) return dimensionPanel; } + // --------------------------------------------------------------------------- +// If the type is InventorySetup.class, create a combo box that uses +// MInventorySetupsPlugin.getInventorySetups(), but stores the *entire* object +// in config as a JSON string. +// --------------------------------------------------------------------------- + private JComboBox createInventorySetupsComboBox(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + // Suppose MInventorySetupsPlugin.getInventorySetups() returns a List + List setups = MInventorySetupsPlugin.getInventorySetups(); + if (setups.isEmpty()) + { + // If there are no setups, return an empty combo box + return new JComboBox<>(); + } + JComboBox box = new JComboBox<>(new DefaultComboBoxModel<>(setups.toArray(new InventorySetup[0]))); + + + // Set the renderer to display the setup name + box.setRenderer(new DefaultListCellRenderer() + { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) + { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof InventorySetup) + { + InventorySetup setup = (InventorySetup) value; + setText(setup.getName()); + } + return this; + } + }); + + // 1) Retrieve dezerialized InventorySetup from config + InventorySetup dezerialized = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(),InventorySetup.class); + if (dezerialized == null) + { + dezerialized = setups.get(0); + } + for (InventorySetup setup : setups) + { + if (setup.getName().equals(dezerialized.getName())) + { + box.setSelectedItem(setup); + break; + } + } + + // 3) Listen for changes + box.addItemListener(e -> + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + InventorySetup chosen = (InventorySetup) box.getSelectedItem(); + if (chosen != null) + { + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), chosen); + } + } + }); + + return box; + } + private JComboBox> createComboBox(ConfigDescriptor cd, ConfigItemDescriptor cid) { Class type = (Class) cid.getType(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/Rs2InventorySetup.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/Rs2InventorySetup.java index 41f6162a65..aff58759ae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/Rs2InventorySetup.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/Rs2InventorySetup.java @@ -1,10 +1,10 @@ package net.runelite.client.plugins.microbot.util; import net.runelite.api.Varbits; +import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.inventorysetups.InventorySetup; import net.runelite.client.plugins.microbot.inventorysetups.InventorySetupsItem; import net.runelite.client.plugins.microbot.inventorysetups.MInventorySetupsPlugin; -import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; import net.runelite.client.plugins.microbot.util.equipment.Rs2Equipment; import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory; @@ -45,6 +45,22 @@ public Rs2InventorySetup(String name, ScheduledFuture mainScheduler) { } } + /** + * Constructor to initialize the Rs2InventorySetup with a specific setup and scheduler. + * The setup can now directly be fetched from the new config selector. + * + * @param setup The inventory setup to load. + * @param mainScheduler The scheduler to monitor for cancellation. + */ + public Rs2InventorySetup(InventorySetup setup, ScheduledFuture mainScheduler) { + inventorySetup = setup; + _mainScheduler = mainScheduler; + if (inventorySetup == null) { + Microbot.showMessage("Inventory load error!"); + Microbot.pauseAllScripts = true; + } + } + /** * Checks if the main scheduler has been cancelled. * diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/AntibanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/AntibanPlugin.java index d9e49706ce..ef4f55bcb9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/AntibanPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/AntibanPlugin.java @@ -150,6 +150,7 @@ public static void performActionBreak() { @Override protected void startUp() throws AWTException { + Rs2Antiban.setActivityIntensity(ActivityIntensity.EXTREME); final MasterPanel panel = injector.getInstance(MasterPanel.class); final BufferedImage icon = ImageUtil.loadImageResource(getClass(), "antiban.png"); navButton = NavigationButton.builder() @@ -301,7 +302,9 @@ private void updateAntibanSettings(Skill skill) { if (activity != null && Rs2AntibanSettings.dynamicActivity) { Rs2Antiban.setActivity(activity); - Microbot.log("Activity changed, new activity: " + activity); + if (Rs2AntibanSettings.devDebug) { + Microbot.log("Activity changed, new activity: " + activity); + } if (Rs2AntibanSettings.universalAntiban) { Rs2Antiban.actionCooldown(); Rs2Antiban.takeMicroBreakByChance(); @@ -310,7 +313,9 @@ private void updateAntibanSettings(Skill skill) { if (activityIntensity != null && Rs2AntibanSettings.dynamicIntensity) { Rs2Antiban.setActivityIntensity(activityIntensity); - Microbot.log("Activity changed, new activity intensity: " + activityIntensity); + if (Rs2AntibanSettings.devDebug) { + Microbot.log("Activity changed, new activity intensity: " + activityIntensity); + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/Rs2Antiban.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/Rs2Antiban.java index 5ae6470a9b..88239783d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/Rs2Antiban.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/Rs2Antiban.java @@ -551,7 +551,7 @@ public static void resetAntibanSettings() { Rs2AntibanSettings.reset(); Rs2Antiban.playStyle = null; Rs2Antiban.activity = null; - Rs2Antiban.activityIntensity = null; + Rs2Antiban.activityIntensity = ActivityIntensity.EXTREME; Rs2Antiban.category = null; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/enums/Category.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/enums/Category.java index 79f658d51b..a3d9a3d15d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/enums/Category.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/enums/Category.java @@ -146,7 +146,7 @@ public boolean isBusyInternal() { SKILLING_THIEVING("Skilling/Thieving") { @Override public boolean isBusyInternal() { - return !Rs2Player.isAnimating(); + return Rs2Player.isAnimating(); } }, SKILLING("Skilling") { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/ui/MousePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/ui/MousePanel.java index 01cc38dcbd..f3fce2f90d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/ui/MousePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/antiban/ui/MousePanel.java @@ -1,6 +1,8 @@ package net.runelite.client.plugins.microbot.util.antiban.ui; +import net.runelite.client.plugins.microbot.util.antiban.Rs2Antiban; import net.runelite.client.plugins.microbot.util.antiban.Rs2AntibanSettings; +import net.runelite.client.plugins.microbot.util.antiban.enums.ActivityIntensity; import net.runelite.client.ui.ColorScheme; import javax.swing.*; @@ -8,7 +10,8 @@ import static net.runelite.client.plugins.microbot.util.antiban.ui.UiHelper.setupSlider; -public class MousePanel extends JPanel { +public class MousePanel extends JPanel +{ private final JCheckBox useNaturalMouse = new JCheckBox("Use Natural Mouse"); private final JCheckBox simulateMistakes = new JCheckBox("Simulate Mistakes"); private final JCheckBox moveMouseOffScreen = new JCheckBox("Move Mouse Off Screen"); @@ -18,8 +21,12 @@ public class MousePanel extends JPanel { private final JSlider moveMouseRandomlyChance = new JSlider(0, 100, (int) (Rs2AntibanSettings.moveMouseRandomlyChance * 100)); private final JLabel moveMouseRandomlyChanceLabel = new JLabel("Random Mouse Movement (%): " + (int) (Rs2AntibanSettings.moveMouseRandomlyChance * 100)); - public MousePanel() { + // 1) Add new components for Activity Intensity + private final JLabel mouseSpeedLabel = new JLabel(); + private final JSlider mouseSpeedSlider = new JSlider(0, 4, 2); // default to index=2 (MODERATE) + public MousePanel() + { useNaturalMouse.setToolTipText("Simulate human-like mouse movements"); simulateMistakes.setToolTipText("Simulate mistakes in mouse movements"); moveMouseOffScreen.setToolTipText("Move the mouse off screen if activity cooldown is active"); @@ -27,53 +34,61 @@ public MousePanel() { moveMouseRandomly.setToolTipText("Move the mouse randomly when activity cooldown is active"); moveMouseRandomlyChance.setToolTipText("Chance to move the mouse randomly when activity cooldown is active"); - // Set the layout manager for the panel to GridBagLayout + // Configure the new mouseSpeedSlider + mouseSpeedSlider.setToolTipText("Controls the overall mouse speed/intensity"); + mouseSpeedSlider.setPaintTicks(true); + mouseSpeedSlider.setPaintLabels(true); + // This helper can be used if you'd like consistent look, or you can do it manually: + setupSlider(mouseSpeedSlider, 0, 4, 1); + setLayout(new GridBagLayout()); setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); setupSlider(moveMouseRandomlyChance, 20, 100, 10); - // Create a GridBagConstraints object to define the layout settings for each component GridBagConstraints gbc = new GridBagConstraints(); - gbc.insets = new Insets(5, 5, 5, 5); // Padding around components - gbc.anchor = GridBagConstraints.WEST; // Align components to the left - gbc.gridx = 0; // All components will be in column 0 - gbc.gridy = GridBagConstraints.RELATIVE; // Components will be placed in consecutive rows + gbc.insets = new Insets(5, 5, 5, 5); + gbc.anchor = GridBagConstraints.WEST; + gbc.gridx = 0; + gbc.gridy = GridBagConstraints.RELATIVE; // Add the "Use Natural Mouse" checkbox add(useNaturalMouse, gbc); - // Add a gap between "Use Natural Mouse" and the rest of the settings - gbc.insets = new Insets(20, 5, 5, 5); // Increase the top padding to create a larger gap - add(Box.createVerticalStrut(15), gbc); // Add a vertical gap of 15 pixels + // Add a gap + gbc.insets = new Insets(20, 5, 5, 5); + add(Box.createVerticalStrut(15), gbc); - // Add the "Simulate Mistakes" checkbox - gbc.insets = new Insets(5, 5, 5, 5); // Reset padding for normal spacing + gbc.insets = new Insets(5, 5, 5, 5); add(simulateMistakes, gbc); - // Add the "Move Mouse Off Screen" checkbox add(moveMouseOffScreen, gbc); - - // Add the "Move Mouse Off Screen (%)" label add(moveMouseOffScreenChanceLabel, gbc); gbc.fill = GridBagConstraints.HORIZONTAL; - // Add the "Move Mouse Off Screen (%)" slider add(moveMouseOffScreenChance, gbc); - // Add the "Move Mouse Randomly" checkbox + gbc.fill = GridBagConstraints.NONE; add(moveMouseRandomly, gbc); - // Add the "Random Mouse Movement" label + gbc.fill = GridBagConstraints.HORIZONTAL; add(moveMouseRandomlyChanceLabel, gbc); + add(moveMouseRandomlyChance, gbc); + + // 2) Add new label and slider for "Mouse Speed" (ActivityIntensity) + gbc.fill = GridBagConstraints.NONE; + add(mouseSpeedLabel, gbc); gbc.fill = GridBagConstraints.HORIZONTAL; - // Add the "Random Mouse Movement" slider - add(moveMouseRandomlyChance, gbc); + add(mouseSpeedSlider, gbc); setupActionListeners(); + + // Make sure the default values on the UI match the current settings + updateValues(); } - private void setupActionListeners() { + private void setupActionListeners() + { useNaturalMouse.addActionListener(e -> Rs2AntibanSettings.naturalMouse = useNaturalMouse.isSelected()); simulateMistakes.addActionListener(e -> Rs2AntibanSettings.simulateMistakes = simulateMistakes.isSelected()); moveMouseOffScreen.addActionListener(e -> Rs2AntibanSettings.moveMouseOffScreen = moveMouseOffScreen.isSelected()); @@ -86,10 +101,17 @@ private void setupActionListeners() { Rs2AntibanSettings.moveMouseRandomlyChance = moveMouseRandomlyChance.getValue() / 100.0; moveMouseRandomlyChanceLabel.setText("Random Mouse Movement (%): " + moveMouseRandomlyChance.getValue()); }); - } - public void updateValues() { + // 3) When mouseSpeedSlider changes, update the ActivityIntensity + mouseSpeedSlider.addChangeListener(e -> { + ActivityIntensity intensity = getActivityIntensityFromIndex(mouseSpeedSlider.getValue()); + Rs2Antiban.setActivityIntensity(intensity); + mouseSpeedLabel.setText("Mouse Speed: " + intensity.getName()); // or getName(), etc. + }); + } + public void updateValues() + { useNaturalMouse.setSelected(Rs2AntibanSettings.naturalMouse); simulateMistakes.setSelected(Rs2AntibanSettings.simulateMistakes); moveMouseOffScreen.setSelected(Rs2AntibanSettings.moveMouseOffScreen); @@ -97,5 +119,38 @@ public void updateValues() { moveMouseRandomly.setSelected(Rs2AntibanSettings.moveMouseRandomly); moveMouseRandomlyChance.setValue((int) (Rs2AntibanSettings.moveMouseRandomlyChance * 100)); moveMouseRandomlyChanceLabel.setText("Random Mouse Movement (%): " + moveMouseRandomlyChance.getValue()); + + // 4) Sync the ActivityIntensity slider + label with current settings + ActivityIntensity currentIntensity = Rs2Antiban.getActivityIntensity(); + mouseSpeedSlider.setValue(getIndexFromActivityIntensity(currentIntensity)); + mouseSpeedLabel.setText("Mouse Speed: " + currentIntensity.getName()); + } + + // Helper to convert ActivityIntensity -> slider index + private int getIndexFromActivityIntensity(ActivityIntensity intensity) + { + switch (intensity) + { + case VERY_LOW: return 0; + case LOW: return 1; + case MODERATE: return 2; + case HIGH: return 3; + case EXTREME: return 4; + default: return 2; + } + } + + // Helper to convert slider index -> ActivityIntensity + private ActivityIntensity getActivityIntensityFromIndex(int index) + { + switch (index) + { + case 0: return ActivityIntensity.VERY_LOW; + case 1: return ActivityIntensity.LOW; + case 2: return ActivityIntensity.MODERATE; + case 3: return ActivityIntensity.HIGH; + case 4: return ActivityIntensity.EXTREME; + default: return ActivityIntensity.MODERATE; + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2Item.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2Item.java index 6b9f847d7c..17da769972 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2Item.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2Item.java @@ -3,6 +3,7 @@ import lombok.Getter; import net.runelite.api.Item; import net.runelite.api.ItemComposition; +import net.runelite.api.ItemID; import net.runelite.api.ParamID; import net.runelite.client.plugins.microbot.Microbot; @@ -28,6 +29,8 @@ public class Rs2Item { boolean isNoted; @Getter boolean isTradeable; + @Getter + ItemComposition itemComposition; int[] wearableActionIndexes = new int[]{ ParamID.OC_ITEM_OP1, ParamID.OC_ITEM_OP2, @@ -50,6 +53,7 @@ public Rs2Item(Item item, ItemComposition itemComposition, int slot) { ? Microbot.getClientThread().runOnClientThread(() -> Microbot.getClient().getItemDefinition(this.id - 1)).isTradeable() : itemComposition.isTradeable(); this.inventoryActions = itemComposition.getInventoryActions(); + this.itemComposition = itemComposition; addEquipmentActions(itemComposition); } @@ -73,6 +77,17 @@ public int getPrice() { Microbot.getItemManager().getItemPrice(id) * quantity); } + public int getHaPrice() { + return itemComposition.getHaPrice(); + } + + public boolean isHaProfitable() { + int natureRunePrice = Microbot.getClientThread().runOnClientThread(() -> + Microbot.getItemManager().getItemPrice(ItemID.NATURE_RUNE)); + return (getHaPrice() - natureRunePrice) > getPrice() && isTradeable; + + } + @Override public int hashCode() { final int prime = 31; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/magic/Rs2Magic.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/magic/Rs2Magic.java index c21e944eca..23e901fbea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/magic/Rs2Magic.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/magic/Rs2Magic.java @@ -41,7 +41,7 @@ public class Rs2Magic { /** * Check if all the settings are correct before we start interacting with spellbook */ - private static boolean oneTimeSpellBookCheck() { + public static boolean oneTimeSpellBookCheck() { // We add a one time check to avoid performanec issues. Checking varbits is expensive if (firstInteractionWithSpellBook && !Rs2SpellBookSettings.setAllFiltersOn()) { return false; @@ -95,9 +95,9 @@ public static boolean quickCanCast(MagicAction magicSpell) { sleepUntil(() -> Rs2Tab.getCurrentTab() == InterfaceTab.MAGIC); } - Widget widget = Arrays.stream(Rs2Widget.getWidget(218, 3).getStaticChildren()).filter(x -> x.getSpriteId() == magicSpell.getSprite()).findFirst().orElse(null); + Widget widget = Rs2Widget.findWidget(magicSpell.getName()); + return widget.getSpriteId() == magicSpell.getSprite(); - return widget != null; } public static boolean quickCanCast(String spellName) { @@ -134,6 +134,18 @@ public static boolean cast(MagicAction magicSpell, String option, int identifier return true; } + public static boolean quickCast(MagicAction magicSpell) { + Microbot.status = "Casting " + magicSpell.getName(); + + if(quickCanCast(magicSpell)) { + Widget widget = Rs2Widget.findWidget(magicSpell.getName()); + Microbot.click(widget.getBounds()); + return true; + } + log("Unable to cast " + magicSpell.getName()); + return false; + } + public static void castOn(MagicAction magicSpell, Actor actor) { if (actor == null) return; cast(magicSpell); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/misc/Rs2Potion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/misc/Rs2Potion.java index 4beb8d7910..e4af2fc5f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/misc/Rs2Potion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/misc/Rs2Potion.java @@ -12,6 +12,14 @@ public static List getRangePotionsVariants() { return Arrays.asList("ranging potion", "bastion potion", "divine bastion potion"); } + public static List getCombatPotionsVariants() { + return Arrays.asList("combat potion", "super combat potion", "divine super combat potion"); + } + + public static List getMagicPotionsVariants() { + return Arrays.asList("magic potion", "divine magic potion", "battlemage potion", "divine battlemage potion"); + } + public static String getStaminaPotion() { return "Stamina potion"; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java index 26f24e5a5e..09e85f0599 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java @@ -835,6 +835,88 @@ public static boolean drinkPrayerPotionAt(int prayerPoints) { return false; } + public static boolean drinkCombatPotionAt(Skill skill) { + return drinkCombatPotionAt(skill, true); + } + + /** + * Drink combat potion for skill + * + * @param skill + * @return + */ + public static boolean drinkCombatPotionAt(Skill skill, boolean superCombat) { + if (Microbot.getClient().getBoostedSkillLevel(skill) - Microbot.getClient().getRealSkillLevel(skill) > 5) { + return false; + } + + if (superCombat && (skill == Skill.ATTACK || skill == Skill.STRENGTH || skill == Skill.DEFENCE)) { + if (usePotion(ItemID.SUPER_COMBAT_POTION1, ItemID.SUPER_COMBAT_POTION2, ItemID.SUPER_COMBAT_POTION3, ItemID.SUPER_COMBAT_POTION4)) { + return true; + } + if (usePotion(ItemID.DIVINE_SUPER_COMBAT_POTION1, ItemID.DIVINE_SUPER_COMBAT_POTION2, ItemID.DIVINE_SUPER_COMBAT_POTION3, ItemID.DIVINE_SUPER_COMBAT_POTION4)) { + return true; + } + } + + if (skill == Skill.ATTACK) { + if (usePotion(ItemID.ATTACK_POTION1, ItemID.ATTACK_POTION2, ItemID.ATTACK_POTION3, ItemID.ATTACK_POTION4)) { + return true; + } + if (usePotion(ItemID.SUPER_ATTACK1, ItemID.SUPER_ATTACK2, ItemID.SUPER_ATTACK3, ItemID.SUPER_ATTACK4)) { + return true; + } + } + + if (skill == Skill.STRENGTH) { + if (usePotion(ItemID.STRENGTH_POTION1, ItemID.STRENGTH_POTION2, ItemID.STRENGTH_POTION3, ItemID.STRENGTH_POTION4)) { + return true; + } + if (usePotion(ItemID.SUPER_STRENGTH1, ItemID.SUPER_STRENGTH2, ItemID.SUPER_STRENGTH3, ItemID.SUPER_STRENGTH4)) { + return true; + } + } + + if (skill == Skill.DEFENCE) { + if (usePotion(ItemID.DEFENCE_POTION1, ItemID.DEFENCE_POTION2, ItemID.DEFENCE_POTION3, ItemID.DEFENCE_POTION4)) { + return true; + } + if (usePotion(ItemID.SUPER_DEFENCE1, ItemID.SUPER_DEFENCE2, ItemID.SUPER_DEFENCE3, ItemID.SUPER_DEFENCE4)) { + return true; + } + } + + if (skill == Skill.RANGED) { + if (usePotion(ItemID.RANGING_POTION1, ItemID.RANGING_POTION2, ItemID.RANGING_POTION3, ItemID.RANGING_POTION4)) { + return true; + } + if (usePotion(ItemID.BASTION_POTION1, ItemID.BASTION_POTION2, ItemID.BASTION_POTION3, ItemID.BASTION_POTION4)) { + return true; + } + if (usePotion(ItemID.DIVINE_RANGING_POTION1, ItemID.DIVINE_RANGING_POTION2, ItemID.DIVINE_RANGING_POTION3, ItemID.DIVINE_RANGING_POTION4)) { + return true; + } + if (usePotion(ItemID.DIVINE_BASTION_POTION1, ItemID.DIVINE_BASTION_POTION2, ItemID.DIVINE_BASTION_POTION3, ItemID.DIVINE_BASTION_POTION4)) { + return true; + } + } + + if (skill == Skill.MAGIC) { + if (usePotion(ItemID.MAGIC_POTION1, ItemID.MAGIC_POTION2, ItemID.MAGIC_POTION3, ItemID.MAGIC_POTION4)) { + return true; + } + if (usePotion(ItemID.DIVINE_BATTLEMAGE_POTION1, ItemID.DIVINE_BATTLEMAGE_POTION2, ItemID.DIVINE_BATTLEMAGE_POTION3, ItemID.DIVINE_BATTLEMAGE_POTION4)) { + return true; + } + if (usePotion(ItemID.DIVINE_MAGIC_POTION1, ItemID.DIVINE_MAGIC_POTION2, ItemID.DIVINE_MAGIC_POTION3, ItemID.DIVINE_MAGIC_POTION4)) { + return true; + } + return usePotion(ItemID.BATTLEMAGE_POTION1, ItemID.BATTLEMAGE_POTION2, ItemID.BATTLEMAGE_POTION3, ItemID.BATTLEMAGE_POTION4); + } + + return false; + } + /** * Helper method to check for the presence of any item in the provided IDs and interact with it. * diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/settings/Rs2SpellBookSettings.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/settings/Rs2SpellBookSettings.java index 52c5017a67..c898829fe1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/settings/Rs2SpellBookSettings.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/settings/Rs2SpellBookSettings.java @@ -202,7 +202,6 @@ public static boolean toggleIconResizing(boolean toggle) { * @return */ public static boolean setAllFiltersOn() { - return Microbot.getClientThread().runOnClientThread(() -> { boolean success = toggleCombatSpells(true, false) && toggleTeleportSpells(true, false) && toggleUtilitySpells(true, false) && @@ -215,7 +214,6 @@ public static boolean setAllFiltersOn() { closeSpellBookFilter(); } return success; - }); } /**