Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.runelite.client.config.ConfigInformation;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.ConfigSection;
import net.runelite.client.config.Range;
import net.runelite.client.plugins.microbot.autobankstander.processors.SkillType;
import net.runelite.client.plugins.microbot.autobankstander.skills.magic.MagicMethod;
import net.runelite.client.plugins.microbot.autobankstander.skills.magic.enchanting.BoltType;
Expand Down Expand Up @@ -99,4 +100,58 @@ default HerblorePotion finishedPotion() {
default boolean useAmuletOfChemistry() {
return false;
}

@ConfigItem(
keyName = "herbloreTurboMode",
name = "Herblore turbo mode",
description = "Rapid-click the entire grimy-herb inventory (cleaning only). Less human-like.",
hidden = true
)
default boolean herbloreTurboMode() {
return false;
}

@ConfigItem(
keyName = "herbloreTurboLimit",
name = "Herblore turbo limit",
description = "Auto-disable turbo after this many herbs cleaned (0 = no limit).",
hidden = true
)
@Range(min = 0, max = 10000)
default int herbloreTurboLimit() {
return 0;
}

@ConfigItem(
keyName = "herbloreSleepMin",
name = "Herblore sleep min (ms)",
description = "Lower bound for Gaussian inter-batch sleep during cleaning.",
hidden = true
)
@Range(min = 30, max = 1000)
default int herbloreSleepMin() {
return 60;
}

@ConfigItem(
keyName = "herbloreSleepMax",
name = "Herblore sleep max (ms)",
description = "Upper bound for Gaussian inter-batch sleep during cleaning.",
hidden = true
)
@Range(min = 100, max = 2000)
default int herbloreSleepMax() {
return 300;
}

@ConfigItem(
keyName = "herbloreSleepTarget",
name = "Herblore sleep target (ms)",
description = "Target (mean anchor) for Gaussian inter-batch sleep during cleaning.",
hidden = true
)
@Range(min = 50, max = 1500)
default int herbloreSleepTarget() {
return 150;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
)
@Slf4j
public class AutoBankStanderPlugin extends Plugin {
static final String version = "1.0.2";
static final String version = "1.0.3";

@Inject
private AutoBankStanderConfig config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,12 @@ private BankStandingProcessor createProcessor() {
configData.getCleanHerbMode(),
configData.getUnfinishedPotionMode(),
configData.getFinishedPotion(),
configData.isUseAmuletOfChemistry()
configData.isUseAmuletOfChemistry(),
configData.isHerbloreTurboMode(),
configData.getHerbloreTurboLimit(),
configData.getHerbloreSleepMin(),
configData.getHerbloreSleepMax(),
configData.getHerbloreSleepTarget()
);
case FLETCHING:
log.info("Entering fletching processor creation");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public class ConfigData {
private UnfinishedPotionMode unfinishedPotionMode = UnfinishedPotionMode.ANY_AND_ALL;
private HerblorePotion finishedPotion = HerblorePotion.ATTACK;
private boolean useAmuletOfChemistry = false;
private boolean herbloreTurboMode = false;
private int herbloreTurboLimit = 0;
private int herbloreSleepMin = 60;
private int herbloreSleepMax = 300;
private int herbloreSleepTarget = 150;

// Fletching settings
private FletchingMode fletchingMode = FletchingMode.DARTS;
Expand All @@ -56,6 +61,11 @@ public ConfigData(ConfigData other) {
this.unfinishedPotionMode = other.unfinishedPotionMode;
this.finishedPotion = other.finishedPotion;
this.useAmuletOfChemistry = other.useAmuletOfChemistry;
this.herbloreTurboMode = other.herbloreTurboMode;
this.herbloreTurboLimit = other.herbloreTurboLimit;
this.herbloreSleepMin = other.herbloreSleepMin;
this.herbloreSleepMax = other.herbloreSleepMax;
this.herbloreSleepTarget = other.herbloreSleepTarget;
this.fletchingMode = other.fletchingMode;
this.dartType = other.dartType;
this.fletchingBoltType = other.fletchingBoltType;
Expand Down Expand Up @@ -90,7 +100,22 @@ public ConfigData(ConfigData other) {

public boolean isUseAmuletOfChemistry() { return useAmuletOfChemistry; }
public void setUseAmuletOfChemistry(boolean useAmuletOfChemistry) { this.useAmuletOfChemistry = useAmuletOfChemistry; }


public boolean isHerbloreTurboMode() { return herbloreTurboMode; }
public void setHerbloreTurboMode(boolean herbloreTurboMode) { this.herbloreTurboMode = herbloreTurboMode; }

public int getHerbloreTurboLimit() { return herbloreTurboLimit; }
public void setHerbloreTurboLimit(int herbloreTurboLimit) { this.herbloreTurboLimit = herbloreTurboLimit; }

public int getHerbloreSleepMin() { return herbloreSleepMin; }
public void setHerbloreSleepMin(int herbloreSleepMin) { this.herbloreSleepMin = herbloreSleepMin; }

public int getHerbloreSleepMax() { return herbloreSleepMax; }
public void setHerbloreSleepMax(int herbloreSleepMax) { this.herbloreSleepMax = herbloreSleepMax; }

public int getHerbloreSleepTarget() { return herbloreSleepTarget; }
public void setHerbloreSleepTarget(int herbloreSleepTarget) { this.herbloreSleepTarget = herbloreSleepTarget; }

public FletchingMode getFletchingMode() { return fletchingMode; }
public void setFletchingMode(FletchingMode fletchingMode) { this.fletchingMode = fletchingMode; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

import net.runelite.api.Skill;
import net.runelite.api.gameval.ItemID;
Expand All @@ -15,7 +17,9 @@
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;
import net.runelite.client.plugins.microbot.util.inventory.Rs2ItemModel;
import net.runelite.client.plugins.microbot.util.inventory.InteractOrder;
import net.runelite.client.plugins.microbot.util.math.Rs2Random;
import net.runelite.client.plugins.microbot.util.player.Rs2Player;
import net.runelite.client.plugins.microbot.util.keyboard.Rs2Keyboard;
import net.runelite.client.plugins.microbot.util.dialogues.Rs2Dialogue;
Expand All @@ -33,23 +37,45 @@ public class HerbloreProcessor implements BankStandingProcessor {
private UnfinishedPotionMode unfinishedPotionMode;
private HerblorePotion finishedPotion;
private boolean useAmuletOfChemistry;


// cleaning tuning (from recovered HerbloreScript)
private final boolean turboModeEnabled;
private final int turboHerbLimit;
private final int sleepMin;
private final int sleepMax;
private final int sleepTarget;
private boolean turboActive;
private int turboHerbsCleanedCount = 0;
private final Random sleepRandom = new Random();

// processing state
private Herb currentHerb;
private Herb currentHerbForUnfinished;
private HerblorePotion currentPotion;
private boolean currentlyMakingPotions;
private int withdrawnAmount;
private boolean amuletBroken = false;
public HerbloreProcessor(Mode mode, CleanHerbMode cleanHerbMode, UnfinishedPotionMode unfinishedPotionMode,

public HerbloreProcessor(Mode mode, CleanHerbMode cleanHerbMode, UnfinishedPotionMode unfinishedPotionMode,
HerblorePotion finishedPotion, boolean useAmuletOfChemistry) {
this(mode, cleanHerbMode, unfinishedPotionMode, finishedPotion, useAmuletOfChemistry,
false, 0, 60, 300, 150);
}

public HerbloreProcessor(Mode mode, CleanHerbMode cleanHerbMode, UnfinishedPotionMode unfinishedPotionMode,
HerblorePotion finishedPotion, boolean useAmuletOfChemistry,
boolean turboMode, int turboHerbLimit,
int sleepMin, int sleepMax, int sleepTarget) {
this.mode = mode;
this.cleanHerbMode = cleanHerbMode;
this.unfinishedPotionMode = unfinishedPotionMode;
this.finishedPotion = finishedPotion;
this.useAmuletOfChemistry = useAmuletOfChemistry;
this.currentlyMakingPotions = false;
this.turboModeEnabled = turboMode;
this.turboHerbLimit = turboHerbLimit;
this.sleepMin = sleepMin;
this.sleepMax = sleepMax;
this.sleepTarget = sleepTarget;
this.turboActive = turboMode;
this.withdrawnAmount = 0;
}

Expand Down Expand Up @@ -152,17 +178,6 @@ public boolean performBanking() {

@Override
public boolean process() {
if (currentlyMakingPotions) {
// check if we need to stop making potions
if (!hasRequiredItems()) {
log.info("Finished making - no more ingredients");
currentlyMakingPotions = false;
return true; // return to banking
}
log.info("Still making potions - waiting for completion");
return true;
}

switch (mode) {
case CLEAN_HERBS:
return processCleanHerbs();
Expand Down Expand Up @@ -196,10 +211,6 @@ public boolean canContinueProcessing() {

@Override
public String getStatusMessage() {
if (currentlyMakingPotions) {
return "Making potions...";
}

switch (mode) {
case CLEAN_HERBS:
return "Cleaning herbs...";
Expand Down Expand Up @@ -332,14 +343,59 @@ private boolean bankForRegularPotion() {
}

private boolean processCleanHerbs() {
if (Rs2Inventory.hasItem("grimy")) {
log.info("Cleaning herbs using zigzag pattern");
Rs2Inventory.cleanHerbs(InteractOrder.ZIGZAG);
sleepUntil(() -> !Rs2Inventory.hasItem("grimy"), 5000);
if (turboActive && turboHerbLimit > 0 && turboHerbsCleanedCount >= turboHerbLimit) {
log.info("Turbo auto-disabled after {} herbs (limit {})", turboHerbsCleanedCount, turboHerbLimit);
turboActive = false;
}

if (!Rs2Inventory.hasItem("grimy")) {
log.info("No grimy herbs in inventory - returning to banking");
return true;
}
log.info("No grimy herbs in inventory - returning to banking");
return true; // return true to go back to banking for more herbs

if (turboActive) {
cleanHerbsTurbo();
} else {
cleanHerbsNormal();
}
return true;
}

private void cleanHerbsNormal() {
log.info("Cleaning herbs (normal, zigzag)");
Rs2Inventory.cleanHerbs(InteractOrder.ZIGZAG);
sleepUntil(() -> !Rs2Inventory.hasItem("grimy"), 5000);
sleep(gaussianSleep());
}

private void cleanHerbsTurbo() {
List<Rs2ItemModel> grimy = Rs2Inventory.items()
.filter(item -> item.getName() != null && item.getName().toLowerCase().contains("grimy"))
.collect(Collectors.toList());
if (grimy.isEmpty()) return;

log.info("Cleaning {} herbs (turbo)", grimy.size());
List<Rs2ItemModel> ordered = Rs2Inventory.calculateInteractOrder(grimy, InteractOrder.ZIGZAG);
for (Rs2ItemModel herb : ordered) {
if (herb == null || herb.getName() == null) continue;
if (!herb.getName().toLowerCase().contains("grimy")) continue;
Rs2Inventory.interact(herb, "Clean");
turboHerbsCleanedCount++;
sleep(Rs2Random.between(5, 15));
}
Rs2Inventory.waitForInventoryChanges(3000);
sleep(Rs2Random.between(50, 100));
}

private int gaussianSleep() {
double mean = (sleepMin + sleepMax + sleepTarget) / 3.0;
double std = Math.abs(sleepTarget - mean) / 3.0;
if (std <= 0) return sleepTarget;
int duration;
do {
duration = (int) Math.round(mean + sleepRandom.nextGaussian() * std);
} while (duration < sleepMin || duration > sleepMax);
return duration;
}

private boolean processUnfinishedPotions() {
Expand All @@ -352,7 +408,6 @@ private boolean processUnfinishedPotions() {
sleepUntil(() -> Rs2Dialogue.hasCombinationDialogue(), 3000);
Rs2Keyboard.keyPress('1');
}
currentlyMakingPotions = true;
log.info("Started making unfinished potions");
return true;
}
Expand Down Expand Up @@ -380,10 +435,9 @@ private boolean processSuperCombat() {
if (Rs2Inventory.combine(ItemID.TORSTOL, ItemID._4DOSE2ATTACK)) {
sleep(600, 800);
if (withdrawnAmount > 1) {
sleepUntil(() -> Rs2Dialogue.hasQuestion("How many do you wish to make?"), 3000);
sleepUntil(() -> Rs2Dialogue.hasCombinationDialogue(), 3000);
Rs2Keyboard.keyPress('1');
}
currentlyMakingPotions = true;
log.info("Started making super combat potions");
return true;
}
Expand All @@ -398,10 +452,9 @@ private boolean processRegularPotion() {
if (Rs2Inventory.combine(currentPotion.unfinished, currentPotion.secondary)) {
sleep(600, 800);
if (withdrawnAmount > 1) {
sleepUntil(() -> Rs2Dialogue.hasQuestion("How many do you wish to make?"), 3000);
sleepUntil(() -> Rs2Dialogue.hasCombinationDialogue(), 3000);
Rs2Keyboard.keyPress('1');
}
currentlyMakingPotions = true;
log.info("Started making {} potions", currentPotion.name());
return true;
}
Expand Down
Loading