Compare commits

...

13 Commits

Author SHA1 Message Date
d6af3d5b46 Add quickprayer support for buff prayers 2022-01-23 03:06:18 +01:00
4166c7fdf8 Add autoalcher and motherlodeminer 2022-01-22 12:10:33 +01:00
2c015056fb Add releases 2022-01-22 12:09:59 +01:00
5c1991fb1a Fix weapon special usage 2022-01-22 12:09:39 +01:00
344ee6cb24 Re-add automatic start 2022-01-22 12:09:16 +01:00
c0ee06e38a Add last bank check, activities and improve idle check 2022-01-22 12:08:29 +01:00
5948f13f06 Add Motherlode Miner 2022-01-22 12:07:08 +01:00
32807711f0 Add Autoalcher 2022-01-22 12:06:50 +01:00
7bdb37e031 Update releases 2022-01-20 01:27:35 +01:00
2e9808c32c Add auto TP feature 2022-01-20 01:27:24 +01:00
9ec09e42d5 Add option for seaweed spore pickup 2022-01-20 01:27:04 +01:00
01a71ba399 Add bank task 2022-01-20 01:26:44 +01:00
08dde87681 Support OpenOSRS 4.19.0 2022-01-20 01:25:56 +01:00
43 changed files with 1367 additions and 74 deletions

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
version = "1.0.0"
project.extra["PluginName"] = "Chaos Auto Alcher" // This is the name that is used in the external plugin manager panel
project.extra["PluginDescription"] = "Gold! Always believe in your soul." // This is the description that is used in the external plugin manager panel
dependencies {
compileOnly(project(":util"))
}
tasks {
jar {
manifest {
attributes(mapOf(
"Plugin-Version" to project.version,
"Plugin-Id" to nameToId(project.extra["PluginName"] as String),
"Plugin-Provider" to project.extra["PluginProvider"],
"Plugin-Description" to project.extra["PluginDescription"],
"Plugin-Dependencies" to
arrayOf(
nameToId("Chaos Util"),
nameToId("iUtils")
).joinToString(),
"Plugin-License" to project.extra["PluginLicense"]
))
}
}
}

View File

@ -0,0 +1,178 @@
package io.reisub.openosrs.autoalcher;
import com.google.inject.Provides;
import io.reisub.openosrs.util.Calculations;
import io.reisub.openosrs.util.Util;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ItemID;
import net.runelite.api.Varbits;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.RunepouchRune;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.iutils.api.Spells;
import net.runelite.client.plugins.iutils.game.Game;
import net.runelite.client.plugins.iutils.game.InventoryItem;
import net.runelite.client.plugins.iutils.game.iWidget;
import net.runelite.client.plugins.iutils.iUtils;
import org.pf4j.Extension;
import javax.inject.Inject;
import java.awt.event.KeyEvent;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Extension
@PluginDependency(Util.class)
@PluginDependency(iUtils.class)
@PluginDescriptor(
name = "Chaos Auto Alcher",
description = "Gold! Always believe in your soul.",
enabledByDefault = false
)
@Slf4j
public class Autoalcher extends Plugin implements KeyListener {
@Inject
private Game game;
@Inject
private Config config;
@Inject
private Calculations calc;
@Inject
private KeyManager keyManager;
@Provides
Config provideConfig(ConfigManager configManager) {
return configManager.getConfig(Config.class);
}
private static final Varbits[] AMOUNT_VARBITS = {
Varbits.RUNE_POUCH_AMOUNT1, Varbits.RUNE_POUCH_AMOUNT2, Varbits.RUNE_POUCH_AMOUNT3
};
private static final Varbits[] RUNE_VARBITS = {
Varbits.RUNE_POUCH_RUNE1, Varbits.RUNE_POUCH_RUNE2, Varbits.RUNE_POUCH_RUNE3
};
private ScheduledExecutorService executor;
private boolean active;
private long last;
private String[] names;
@Override
protected void startUp() {
log.info("Starting Chaos Auto Alcher");
executor = Executors.newSingleThreadScheduledExecutor();
keyManager.registerKeyListener(this);
}
@Override
protected void shutDown() {
log.info("Stopping Chaos Auto Alcher");
executor.shutdownNow();
keyManager.unregisterKeyListener(this);
}
@Subscribe
private void onGameTick(GameTick event) {
if (!active || last + 5 > game.ticks()) return;
if (names == null) parseItems();
if (names == null || names.length == 0) return;
if (game.inventory().withNamePart(names).exists()
&& hasRunes()) {
executor.schedule(this::alch, calc.random(100, 200), TimeUnit.MILLISECONDS);
}
}
@Subscribe
private void onConfigChanged(ConfigChanged event) {
if (!event.getGroup().equals("chaosautoalcher")) return;
if (event.getKey().equals("alchItems")) {
parseItems();
}
}
private void alch() {
InventoryItem item = game.inventory().withNamePart(names).first();
iWidget spellWidget = game.widget(Spells.HIGH_LEVEL_ALCHEMY.getInfo());
if (item == null || spellWidget == null) return;
spellWidget.useOn(item);
last = game.ticks();
game.tick(3);
game.openInterface(3);
}
private void parseItems() {
names = config.alchItems().split(";");
for (int i = 0; i < names.length; i++) {
names[i] = names[i].trim();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (config.autoalchHotkey().matches(e)) {
active = !active;
if (active) {
game.utils.sendGameMessage("Enabled Auto Alcher");
} else {
game.utils.sendGameMessage("Disabled Auto Alcher");
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
private boolean hasRunes() {
int fireRunes = (int) game.inventory().withId(ItemID.FIRE_RUNE).count();
int natureRunes = (int) game.inventory().withId(ItemID.NATURE_RUNE).count();
if (game.inventory().withId(ItemID.RUNE_POUCH).exists()) {
for (int i = 0; i < AMOUNT_VARBITS.length; i++) {
int amount = game.client().getVar(AMOUNT_VARBITS[i]);
if (amount <= 0) continue;
RunepouchRune rune = RunepouchRune.getRune(game.client().getVar(RUNE_VARBITS[i]));
switch (rune) {
case NATURE:
natureRunes += amount;
break;
case FIRE:
fireRunes += amount;
break;
}
}
}
return fireRunes >= 5 && natureRunes >= 1;
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2018, Andrew EP | ElPinche256 <https://github.com/ElPinche256>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package io.reisub.openosrs.autoalcher;
import net.runelite.client.config.Button;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Keybind;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@ConfigGroup("chaosautoalcher")
public interface Config extends net.runelite.client.config.Config {
@ConfigItem(
keyName = "alchItems",
name = "Items",
description = "List of items to alch, separated by a semicolon. You can use a part of the name.",
position = 0
)
default String alchItems() { return "Rune arrow"; }
@ConfigItem(
keyName = "autoalchHotkey",
name = "Hotkey",
description = "Press this key to toggle auto alching.",
position = 2
)
default Keybind autoalchHotkey() {
return new Keybind(KeyEvent.VK_F9, InputEvent.CTRL_DOWN_MASK);
}
@ConfigItem(
keyName = "startButton",
name = "Start/Stop",
description = "Start the script",
position = 100
)
default Button startButton() {
return new Button();
}
}

View File

@ -93,14 +93,14 @@ public class Birdhouse extends CScript implements KeyListener {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Subscribe @Subscribe
private void onGameTick(GameTick event) { private void onGameTick(GameTick event) {
// if (isLoggedIn() if (isLoggedIn()
// && game.localPlayer().position().regionID() == 14908) { && game.localPlayer().position().regionID() == 14908) {
// if (!active && game.localPlayer().position().distanceTo(hillHousePosition) < 10 && game.inventory().withNamePart("logs").count() == 4) { if (!active && game.localPlayer().position().distanceTo(hillHousePosition) < 10 && game.inventory().withNamePart("logs").count() == 4) {
// execute(); execute();
// } else if (active && game.inventory().all().isEmpty() && !bank.isOpen() && game.localPlayer().position().distanceTo(islandPosition) < 10) { } else if (active && game.inventory().all().isEmpty() && !bank.isOpen() && game.localPlayer().position().distanceTo(islandPosition) < 10) {
// execute(); execute();
// } }
// } }
} }
public boolean hasRecentlyBeenEmptied(BirdhouseSpace space) { public boolean hasRecentlyBeenEmptied(BirdhouseSpace space) {

View File

@ -24,7 +24,7 @@
*/ */
object ProjectVersions { object ProjectVersions {
const val openosrsVersion = "4.17.0" const val openosrsVersion = "4.19.0"
const val apiVersion = "^1.0.0" const val apiVersion = "^1.0.0"
} }

View File

@ -27,6 +27,10 @@ package io.reisub.openosrs.consume;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.ConfigSection; import net.runelite.client.config.ConfigSection;
import net.runelite.client.config.Keybind;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@ConfigGroup("chaosconsume") @ConfigGroup("chaosconsume")
@ -223,7 +227,7 @@ public interface Config extends net.runelite.client.config.Config {
unhide = "drinkStrength" unhide = "drinkStrength"
) )
default int strengthLevel() { default int strengthLevel() {
return 100; return 1;
} }
@ConfigItem( @ConfigItem(
@ -260,7 +264,7 @@ public interface Config extends net.runelite.client.config.Config {
unhide = "drinkAttack" unhide = "drinkAttack"
) )
default int attackLevel() { default int attackLevel() {
return 100; return 1;
} }
@ConfigItem( @ConfigItem(
@ -297,7 +301,7 @@ public interface Config extends net.runelite.client.config.Config {
unhide = "drinkDefence" unhide = "drinkDefence"
) )
default int defenceLevel() { default int defenceLevel() {
return 100; return 1;
} }
@ConfigItem( @ConfigItem(
@ -334,7 +338,7 @@ public interface Config extends net.runelite.client.config.Config {
unhide = "drinkRanged" unhide = "drinkRanged"
) )
default int rangedLevel() { default int rangedLevel() {
return 100; return 1;
} }
@ConfigItem( @ConfigItem(
@ -371,7 +375,7 @@ public interface Config extends net.runelite.client.config.Config {
unhide = "drinkMagic" unhide = "drinkMagic"
) )
default int magicLevel() { default int magicLevel() {
return 100; return 1;
} }
@ConfigItem( @ConfigItem(
@ -426,5 +430,29 @@ public interface Config extends net.runelite.client.config.Config {
) )
default int specialCost() { return 100; } default int specialCost() { return 100; }
@ConfigItem(
keyName = "pkTeleport",
name = "PK teleport hotkey",
description = "Pressing the hotkey will toggle watching for skulled players or players attacking you and try to teleport away. Requires an equipped charged amulet of glory.",
position = 50
)
default Keybind pkTeleport() {
return new Keybind(KeyEvent.VK_F1, InputEvent.CTRL_DOWN_MASK);
}
@ConfigItem(
keyName = "tpOnDangerousPlayer",
name = "TP on dangerous player",
description = "Attempt to teleport when a skulled player within level range appears.",
position = 51
)
default boolean tpOnDangerousPlayer() { return true; }
@ConfigItem(
keyName = "tpOnPlayerAttack",
name = "TP on player attack",
description = "Attempt to teleport when we're being attacked by a player.",
position = 52
)
default boolean tpOnPlayerAttack() { return true; }
} }

View File

@ -11,21 +11,28 @@ import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.iutils.game.EquipmentItem;
import net.runelite.client.plugins.iutils.game.Game; import net.runelite.client.plugins.iutils.game.Game;
import net.runelite.client.plugins.iutils.game.InventoryItem; import net.runelite.client.plugins.iutils.game.InventoryItem;
import net.runelite.client.plugins.iutils.game.iWidget; import net.runelite.client.plugins.iutils.game.iWidget;
import net.runelite.client.plugins.iutils.iUtils; import net.runelite.client.plugins.iutils.iUtils;
import net.runelite.client.plugins.iutils.ui.Bank; import net.runelite.client.plugins.iutils.ui.Bank;
import net.runelite.client.plugins.iutils.ui.Equipment;
import org.pf4j.Extension; import org.pf4j.Extension;
import javax.inject.Inject; import javax.inject.Inject;
import java.awt.event.KeyEvent;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Extension @Extension
@PluginDependency(Util.class) @PluginDependency(Util.class)
@ -36,7 +43,7 @@ import java.util.concurrent.TimeUnit;
enabledByDefault = false enabledByDefault = false
) )
@Slf4j @Slf4j
public class Consume extends Plugin { public class Consume extends Plugin implements KeyListener {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Inject @Inject
private Game game; private Game game;
@ -45,6 +52,9 @@ public class Consume extends Plugin {
@Inject @Inject
private Config config; private Config config;
@Inject
private KeyManager keyManager;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Inject @Inject
private Calculations calc; private Calculations calc;
@ -52,6 +62,9 @@ public class Consume extends Plugin {
@Inject @Inject
private Bank bank; private Bank bank;
@Inject
private Equipment equipment;
private final Set<Integer> IGNORE_FOOD = Set.of(ItemID.DWARVEN_ROCK_CAKE, ItemID.DWARVEN_ROCK_CAKE_7510); private final Set<Integer> IGNORE_FOOD = Set.of(ItemID.DWARVEN_ROCK_CAKE, ItemID.DWARVEN_ROCK_CAKE_7510);
private final Set<Integer> DRINK_SET = Set.of(ItemID.JUG_OF_WINE, ItemID.SARADOMIN_BREW1, ItemID.SARADOMIN_BREW2, ItemID.SARADOMIN_BREW3, ItemID.SARADOMIN_BREW4, ItemID.XERICS_AID_1, ItemID.XERICS_AID_2, ItemID.XERICS_AID_3, ItemID.XERICS_AID_4, ItemID.XERICS_AID_1_20977, ItemID.XERICS_AID_2_20978, ItemID.XERICS_AID_3_20979, ItemID.XERICS_AID_4_20980, ItemID.XERICS_AID_1_20981, ItemID.XERICS_AID_2_20982, ItemID.XERICS_AID_3_20983, ItemID.XERICS_AID_4_20984, ItemID.BANDAGES); private final Set<Integer> DRINK_SET = Set.of(ItemID.JUG_OF_WINE, ItemID.SARADOMIN_BREW1, ItemID.SARADOMIN_BREW2, ItemID.SARADOMIN_BREW3, ItemID.SARADOMIN_BREW4, ItemID.XERICS_AID_1, ItemID.XERICS_AID_2, ItemID.XERICS_AID_3, ItemID.XERICS_AID_4, ItemID.XERICS_AID_1_20977, ItemID.XERICS_AID_2_20978, ItemID.XERICS_AID_3_20979, ItemID.XERICS_AID_4_20980, ItemID.XERICS_AID_1_20981, ItemID.XERICS_AID_2_20982, ItemID.XERICS_AID_3_20983, ItemID.XERICS_AID_4_20984, ItemID.BANDAGES);
private final Set<Integer> ANTI_POISON_IDS = Set.of(ItemID.ANTIPOISON1, ItemID.ANTIPOISON2, ItemID.ANTIPOISON3, ItemID.ANTIPOISON4, ItemID.SUPERANTIPOISON1, ItemID.SUPERANTIPOISON2, ItemID.SUPERANTIPOISON3, ItemID.SUPERANTIPOISON4, private final Set<Integer> ANTI_POISON_IDS = Set.of(ItemID.ANTIPOISON1, ItemID.ANTIPOISON2, ItemID.ANTIPOISON3, ItemID.ANTIPOISON4, ItemID.SUPERANTIPOISON1, ItemID.SUPERANTIPOISON2, ItemID.SUPERANTIPOISON3, ItemID.SUPERANTIPOISON4,
@ -113,6 +126,8 @@ public class Consume extends Plugin {
private boolean shouldDrinkMagic; private boolean shouldDrinkMagic;
private long lastMagic; private long lastMagic;
private boolean shouldUseSpecial; private boolean shouldUseSpecial;
private long lastSpecial;
private boolean pkTeleport;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@ -128,6 +143,7 @@ public class Consume extends Plugin {
generateNewPrayerThreshold(); generateNewPrayerThreshold();
executor = Executors.newSingleThreadScheduledExecutor(); executor = Executors.newSingleThreadScheduledExecutor();
keyManager.registerKeyListener(this);
} }
@Override @Override
@ -135,6 +151,7 @@ public class Consume extends Plugin {
log.info("Stopping Chaos Consume"); log.info("Stopping Chaos Consume");
executor.shutdownNow(); executor.shutdownNow();
keyManager.unregisterKeyListener(this);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -163,7 +180,8 @@ public class Consume extends Plugin {
if (config.useSpecial() if (config.useSpecial()
&& event.getIndex() == VarPlayer.SPECIAL_ATTACK_PERCENT.getId() && event.getIndex() == VarPlayer.SPECIAL_ATTACK_PERCENT.getId()
&& game.client().getVarpValue(VarPlayer.SPECIAL_ATTACK_PERCENT.getId()) > config.specialCost()) { && game.client().getVarpValue(VarPlayer.SPECIAL_ATTACK_PERCENT.getId()) / 10 >= config.specialCost()
&& lastSpecial + 2000 < System.currentTimeMillis()) {
shouldUseSpecial = true; shouldUseSpecial = true;
} }
} }
@ -237,7 +255,6 @@ public class Consume extends Plugin {
} }
private void tick() { private void tick() {
int hp = game.modifiedLevel(Skill.HITPOINTS); int hp = game.modifiedLevel(Skill.HITPOINTS);
if (config.enableEating() && hp <= eatThreshold && canEat()) { if (config.enableEating() && hp <= eatThreshold && canEat()) {
@ -266,8 +283,9 @@ public class Consume extends Plugin {
if (shouldUseSpecial && game.client().getVarpValue(VarPlayer.SPECIAL_ATTACK_ENABLED.getId()) == 0) { if (shouldUseSpecial && game.client().getVarpValue(VarPlayer.SPECIAL_ATTACK_ENABLED.getId()) == 0) {
shouldUseSpecial = false; shouldUseSpecial = false;
lastSpecial = System.currentTimeMillis();
if (game.client().getVar(Varbits.PVP_SPEC_ORB) == 0) { if (game.varb(Varbits.PVP_SPEC_ORB.getId()) == 0) {
iWidget special = game.widget(WidgetInfo.MINIMAP_SPEC_CLICKBOX); iWidget special = game.widget(WidgetInfo.MINIMAP_SPEC_CLICKBOX);
if (special == null) return; if (special == null) return;
@ -357,6 +375,85 @@ public class Consume extends Plugin {
} }
} }
@Subscribe
private void onPlayerSpawned(PlayerSpawned event) {
if (!config.tpOnDangerousPlayer() || !pkTeleport || game.client().getVar(Varbits.IN_WILDERNESS) == 0 || event.getPlayer() == null) return;
iWidget wildernessLevelWidget = game.widget(WidgetInfo.PVP_WILDERNESS_LEVEL);
if (wildernessLevelWidget == null || wildernessLevelWidget.text() == null) return;
Pattern regex = Pattern.compile("\\d+-\\d+");
Matcher levelMatcher = regex.matcher(wildernessLevelWidget.text());
if (levelMatcher.find()) {
String[] levelRange = levelMatcher.group(0).split("-");
int lowerLevel = Integer.parseInt(levelRange[0]);
int upperLevel = Integer.parseInt(levelRange[1]);
int playerLevel = event.getPlayer().getCombatLevel();
if (event.getPlayer().getSkullIcon() != null && (playerLevel >= lowerLevel && playerLevel <= upperLevel)) {
log.info("Dangerous player spawned: " + event.getPlayer().getName());
executor.schedule(this::teleport, 0, TimeUnit.MILLISECONDS);
}
}
}
@Subscribe
private void onInteractingChanged(InteractingChanged event) {
if (!config.tpOnPlayerAttack() || !pkTeleport || game.client().getVar(Varbits.IN_WILDERNESS) == 0) return;
if (event.getSource() == null || event.getTarget() == null || event.getTarget().getName() == null) return;
if (event.getSource() instanceof Player && event.getTarget().equals(game.client().getLocalPlayer())) {
log.info("Player attacking us: " + event.getSource().getName());
executor.schedule(this::teleport, 0, TimeUnit.MILLISECONDS);
}
}
private void teleport() {
pkTeleport = false;
iWidget wildernessLevelWidget = game.widget(WidgetInfo.PVP_WILDERNESS_LEVEL);
if (wildernessLevelWidget == null || wildernessLevelWidget.text() == null) return;
Pattern regex = Pattern.compile("Level: \\d+");
Matcher levelMatcher = regex.matcher(wildernessLevelWidget.text());
if (!levelMatcher.find()) return;
if (Integer.parseInt(levelMatcher.group(0).split(" ")[1]) > 30) return;
EquipmentItem amuletOfGlory = game.equipment().withAction("Edgeville").first();
if (amuletOfGlory == null) return;
amuletOfGlory.interact("Edgeville");
game.tick(3);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (config.pkTeleport().matches(e)) {
pkTeleport = !pkTeleport;
if (pkTeleport) {
game.utils.sendGameMessage("Enabled PK teleport");
} else {
game.utils.sendGameMessage("Disabled PK teleport");
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
private void generateNewEatThreshold() { private void generateNewEatThreshold() {
eatThreshold = calc.random(config.minEatHP(), config.maxEatHP() + 1); eatThreshold = calc.random(config.minEatHP(), config.maxEatHP() + 1);
} }

View File

@ -39,6 +39,14 @@ public interface Config extends net.runelite.client.config.Config {
) )
default Product targetProduct() { return Product.LANTERN_LENS; } default Product targetProduct() { return Product.LANTERN_LENS; }
@ConfigItem(
keyName = "farmSeaweedSpores",
name = "Farm seaweed spores",
description = "Go underwater at the Fossil Island to farm seaweed spores.",
position = 1
)
default boolean farmSeaweedSpores() { return true; }
@ConfigItem( @ConfigItem(
keyName = "startButton", keyName = "startButton",
name = "Start/Stop", name = "Start/Stop",

View File

@ -32,7 +32,7 @@ public class Blow extends Task {
@Override @Override
public void execute() { public void execute() {
if (game.localPlayer().position().regionID() == Glassblower.FOSSIL_ISLAND_SMALL_ISLAND_REGION) { if (config.farmSeaweedSpores() && game.localPlayer().position().regionID() == Glassblower.FOSSIL_ISLAND_SMALL_ISLAND_REGION) {
iObject rowboat = game.objects().withName("Rowboat").nearest(); iObject rowboat = game.objects().withName("Rowboat").nearest();
if (rowboat == null) return; if (rowboat == null) return;
@ -47,7 +47,7 @@ public class Blow extends Task {
game.tick(); game.tick();
} }
if (game.groundItems().withId(ItemID.SEAWEED_SPORE).exists()) return; if (config.farmSeaweedSpores() && game.groundItems().withId(ItemID.SEAWEED_SPORE).exists()) return;
InventoryItem pipe = game.inventory().withId(ItemID.GLASSBLOWING_PIPE).first(); InventoryItem pipe = game.inventory().withId(ItemID.GLASSBLOWING_PIPE).first();
InventoryItem moltenGlass = game.inventory().withId(ItemID.MOLTEN_GLASS).first(); InventoryItem moltenGlass = game.inventory().withId(ItemID.MOLTEN_GLASS).first();

View File

@ -1,14 +1,17 @@
package io.reisub.openosrs.glassblower.tasks; package io.reisub.openosrs.glassblower.tasks;
import io.reisub.openosrs.glassblower.Config;
import io.reisub.openosrs.glassblower.Glassblower; import io.reisub.openosrs.glassblower.Glassblower;
import io.reisub.openosrs.util.Task; import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.tasks.BankTask;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import net.runelite.client.plugins.iutils.game.iObject; import net.runelite.client.plugins.iutils.game.iObject;
import javax.inject.Inject;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
public class HandleBank extends Task { public class HandleBank extends BankTask {
private Instant lastBanking = Instant.EPOCH; private Instant lastBanking = Instant.EPOCH;
@Override @Override
@ -39,13 +42,7 @@ public class HandleBank extends Task {
game.tick(); game.tick();
} }
if (!bank.isOpen()) { openBank(5);
iObject bankObj = game.objects().withName("Bank chest", "Bank booth", "Bank Chest-wreck").nearest();
if (bankObj == null) return;
bankObj.interact(0);
game.waitUntil(() -> bank.isOpen(), 15);
}
bank.depositExcept(false, ItemID.GLASSBLOWING_PIPE, ItemID.SEAWEED_SPORE); bank.depositExcept(false, ItemID.GLASSBLOWING_PIPE, ItemID.SEAWEED_SPORE);
// bank.depositAll(false, ItemID.BEER_GLASS, // bank.depositAll(false, ItemID.BEER_GLASS,

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
version = "1.0.0"
project.extra["PluginName"] = "Chaos Motherlode Miner" // This is the name that is used in the external plugin manager panel
project.extra["PluginDescription"] = "Diggy, diggy hole" // This is the description that is used in the external plugin manager panel
dependencies {
compileOnly(project(":util"))
}
tasks {
jar {
manifest {
attributes(mapOf(
"Plugin-Version" to project.version,
"Plugin-Id" to nameToId(project.extra["PluginName"] as String),
"Plugin-Provider" to project.extra["PluginProvider"],
"Plugin-Description" to project.extra["PluginDescription"],
"Plugin-Dependencies" to
arrayOf(
nameToId("Chaos Util"),
nameToId("iUtils")
).joinToString(),
"Plugin-License" to project.extra["PluginLicense"]
))
}
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2018, Andrew EP | ElPinche256 <https://github.com/ElPinche256>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package io.reisub.openosrs.motherlodeminer;
import net.runelite.client.config.Button;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("chaosmotherlodeminer")
public interface Config extends net.runelite.client.config.Config {
@ConfigItem(
keyName = "startButton",
name = "Start/Stop",
description = "Start the script",
position = 100
)
default Button startButton() {
return new Button();
}
}

View File

@ -0,0 +1,232 @@
package io.reisub.openosrs.motherlodeminer;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Provides;
import io.reisub.openosrs.motherlodeminer.tasks.*;
import io.reisub.openosrs.util.CScript;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.Util;
import io.reisub.openosrs.util.enums.Activity;
import io.reisub.openosrs.util.tasks.Eat;
import io.reisub.openosrs.util.tasks.KittenTask;
import io.reisub.openosrs.util.tasks.Run;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.*;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.events.*;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.iutils.iUtils;
import net.runelite.client.plugins.iutils.scene.Position;
import net.runelite.client.plugins.iutils.scripts.iScript;
import org.pf4j.Extension;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Extension
@PluginDependency(Util.class)
@PluginDependency(iUtils.class)
@PluginDescriptor(
name = "Chaos Motherlode Miner",
description = "Diggy, diggy hole",
enabledByDefault = false
)
@Slf4j
public class MotherlodeMiner extends CScript {
@Provides
Config provideConfig(ConfigManager configManager) {
return configManager.getConfig(Config.class);
}
private static final Set<Integer> MOTHERLODE_MAP_REGIONS = ImmutableSet.of(14679, 14680, 14681, 14935, 14936, 14937, 15191, 15192, 15193);
private static final int UPPER_FLOOR_HEIGHT = -490;
private static final int SACK_LARGE_SIZE = 162;
private static final int SACK_SIZE = 81;
private int curSackSize, maxSackSize;
@Getter
@Setter
private boolean sackFull;
@Getter
private boolean inMlm;
@Getter
@Setter
private Position currentVeinPosition;
private ScheduledExecutorService executor;
@Override
protected void loop() {
game.tick();
}
@Override
protected void onStart() {
super.onStart();
inMlm = checkInMlm();
executor = Executors.newSingleThreadScheduledExecutor();
addTask(Mine.class);
addTask(GoDown.class);
addTask(Deposit.class);
addTask(FixWheel.class);
addTask(WithdrawSack.class);
addTask(HandleBank.class);
addTask(GoUp.class);
}
@Override
protected void onStop() {
executor.shutdownNow();
}
@Subscribe
private void onGameTick(GameTick event) {
if (currentVeinPosition != null && currentActivity == Activity.MINING) {
if (game.objects().withPosition(currentVeinPosition).withAction("Mine").first() == null) {
currentVeinPosition = null;
setActivity(Activity.IDLE);
}
}
if (executor != null) {
executor.schedule(() -> {
for (Task t : tasks) {
if (t.validate()) {
log.info(t.getStatus());
t.execute();
break;
}
}
checkActionTimeout();
}, 0, TimeUnit.MILLISECONDS);
}
}
@Subscribe
private void onAnimationChanged(AnimationChanged event) {
Actor actor = event.getActor();
if (actor == null || actor.getName() == null || !actor.getName().equals(game.localPlayer().name())) return;
int animId = game.localPlayer().animation();
switch (animId) {
case AnimationID.MINING_MOTHERLODE_BRONZE:
case AnimationID.MINING_MOTHERLODE_IRON:
case AnimationID.MINING_MOTHERLODE_STEEL:
case AnimationID.MINING_MOTHERLODE_BLACK:
case AnimationID.MINING_MOTHERLODE_MITHRIL:
case AnimationID.MINING_MOTHERLODE_ADAMANT:
case AnimationID.MINING_MOTHERLODE_RUNE:
case AnimationID.MINING_MOTHERLODE_DRAGON:
case AnimationID.MINING_MOTHERLODE_DRAGON_OR:
case AnimationID.MINING_MOTHERLODE_DRAGON_UPGRADED:
case AnimationID.MINING_MOTHERLODE_CRYSTAL:
case AnimationID.MINING_MOTHERLODE_GILDED:
case AnimationID.MINING_MOTHERLODE_INFERNAL:
case AnimationID.MINING_MOTHERLODE_3A:
setActivity(Activity.MINING);
break;
}
}
@Subscribe
private void onGameObjectDespawned(GameObjectDespawned event) {
if (currentActivity == Activity.REPAIRING && event.getGameObject().getName().equals("Broken strut")) {
setActivity(Activity.IDLE);
}
}
@Subscribe
private void onItemContainerChanged(ItemContainerChanged event) {
if (currentActivity == Activity.DEPOSITING) {
if (!game.inventory().withName("Pay-dirt").exists()) {
setActivity(Activity.IDLE);
}
} else if (currentActivity == Activity.WITHDRAWING) {
if (game.inventory().withId(
ItemID.RUNITE_ORE,
ItemID.ADAMANTITE_ORE,
ItemID.MITHRIL_ORE,
ItemID.GOLD_ORE,
ItemID.COAL,
ItemID.UNCUT_SAPPHIRE,
ItemID.UNCUT_EMERALD,
ItemID.UNCUT_RUBY,
ItemID.UNCUT_DIAMOND,
ItemID.UNCUT_DRAGONSTONE
).exists()) {
setActivity(Activity.IDLE);
}
} else if (currentActivity == Activity.MINING) {
if (game.inventory().full()) {
setActivity(Activity.IDLE);
currentVeinPosition = null;
}
}
}
@Subscribe
private void onVarbitChanged(VarbitChanged event) {
if (inMlm) {
refreshSackValues();
if (curSackSize >= maxSackSize - 26) {
sackFull = true;
}
}
}
@Subscribe
private void onGameStateChanged(GameStateChanged event) {
if (event.getGameState() == GameState.LOADING) {
inMlm = checkInMlm();
} else if (event.getGameState() == GameState.LOGIN_SCREEN) {
inMlm = false;
}
}
private boolean checkInMlm() {
GameState state = game.client.getGameState();
if (state != GameState.LOGGED_IN && state != GameState.LOADING) {
return false;
}
int[] currentMapRegions = game.client.getMapRegions();
for (int region : currentMapRegions) {
if (!MOTHERLODE_MAP_REGIONS.contains(region)) {
return false;
}
}
return true;
}
private void refreshSackValues() {
curSackSize = game.client.getVar(Varbits.SACK_NUMBER);
boolean sackUpgraded = game.client.getVar(Varbits.SACK_UPGRADED) == 1;
maxSackSize = sackUpgraded ? SACK_LARGE_SIZE : SACK_SIZE;
if (curSackSize == 0) {
sackFull = false;
}
}
public boolean isUpstairs() {
return Perspective.getTileHeight(game.client, game.client.getLocalPlayer().getLocalLocation(), 0) < UPPER_FLOOR_HEIGHT;
}
}

View File

@ -0,0 +1,44 @@
package io.reisub.openosrs.motherlodeminer.tasks;
import io.reisub.openosrs.motherlodeminer.MotherlodeMiner;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.enums.Activity;
import net.runelite.client.plugins.iutils.game.iObject;
import net.runelite.client.plugins.iutils.scene.Position;
import net.runelite.client.plugins.iutils.scene.RectangularArea;
import javax.inject.Inject;
public class Deposit extends Task {
@Inject
private MotherlodeMiner plugin;
private final RectangularArea hopperArea = new RectangularArea(
new Position(3741, 5657, 0),
new Position(3755, 5674, 0)
);
@Override
public String getStatus() {
return "Depositing in hopper";
}
@Override
public boolean validate() {
return plugin.getCurrentActivity() == Activity.IDLE
&& !plugin.isUpstairs()
&& game.inventory().withName("Pay-dirt").exists();
}
@Override
public void execute() {
iObject hopper = game.objects().withName("Hopper").nearest();
if (hopper == null) return;
plugin.setActivity(Activity.DEPOSITING);
hopper.interact("Deposit");
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.IDLE, 15);
game.tick(2);
}
}

View File

@ -0,0 +1,39 @@
package io.reisub.openosrs.motherlodeminer.tasks;
import io.reisub.openosrs.motherlodeminer.MotherlodeMiner;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.enums.Activity;
import net.runelite.client.plugins.iutils.game.iObject;
import javax.inject.Inject;
import java.util.List;
public class FixWheel extends Task {
@Inject
private MotherlodeMiner plugin;
private List<iObject> brokenStruts;
@Override
public String getStatus() {
return "Fixing wheel";
}
@Override
public boolean validate() {
if (plugin.getCurrentActivity() != Activity.IDLE || plugin.isUpstairs()) return false;
brokenStruts = game.objects().withName("Broken strut").all();
return brokenStruts.size() == 2;
}
@Override
public void execute() {
plugin.setActivity(Activity.REPAIRING);
brokenStruts.get(0).interact("Hammer");
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.IDLE, 30);
}
}

View File

@ -0,0 +1,42 @@
package io.reisub.openosrs.motherlodeminer.tasks;
import io.reisub.openosrs.motherlodeminer.MotherlodeMiner;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.enums.Activity;
import net.runelite.client.plugins.iutils.game.iObject;
import net.runelite.client.plugins.iutils.scene.Position;
import net.runelite.client.plugins.iutils.scene.RectangularArea;
import javax.inject.Inject;
public class GoDown extends Task {
@Inject
private MotherlodeMiner plugin;
private final RectangularArea miningArea = new RectangularArea(
new Position(3748, 5676, 0),
new Position(3754, 5684, 0)
);
@Override
public String getStatus() {
return "Going down";
}
@Override
public boolean validate() {
return plugin.getCurrentActivity() == Activity.IDLE
&& plugin.isUpstairs()
&& game.inventory().full();
}
@Override
public void execute() {
iObject ladder = game.objects().withName("Ladder").nearest();
if (ladder == null) return;
ladder.interact("Climb");
game.waitUntil(() -> !plugin.isUpstairs(), 15);
game.tick();
}
}

View File

@ -0,0 +1,32 @@
package io.reisub.openosrs.motherlodeminer.tasks;
import io.reisub.openosrs.motherlodeminer.MotherlodeMiner;
import io.reisub.openosrs.util.Task;
import net.runelite.client.plugins.iutils.game.iObject;
import javax.inject.Inject;
public class GoUp extends Task {
@Inject
private MotherlodeMiner plugin;
@Override
public String getStatus() {
return "Going up";
}
@Override
public boolean validate() {
return !plugin.isUpstairs();
}
@Override
public void execute() {
iObject ladder = game.objects().withName("Ladder").withAction("Climb").nearest();
if (ladder == null) return;
ladder.interact("Climb");
game.waitUntil(() -> plugin.isUpstairs(), 15);
game.tick();
}
}

View File

@ -0,0 +1,45 @@
package io.reisub.openosrs.motherlodeminer.tasks;
import io.reisub.openosrs.motherlodeminer.MotherlodeMiner;
import io.reisub.openosrs.util.enums.Activity;
import io.reisub.openosrs.util.tasks.BankTask;
import net.runelite.api.ItemID;
import javax.inject.Inject;
import java.time.Duration;
import java.time.Instant;
public class HandleBank extends BankTask {
@Inject
private MotherlodeMiner plugin;
@Override
public boolean validate() {
if (plugin.isUpstairs() || plugin.getCurrentActivity() != Activity.IDLE) return false;
return isLastBankDurationAgo(Duration.ofSeconds(2))
&& game.inventory().withId(
ItemID.RUNITE_ORE,
ItemID.ADAMANTITE_ORE,
ItemID.MITHRIL_ORE,
ItemID.GOLD_ORE,
ItemID.COAL,
ItemID.UNCUT_SAPPHIRE,
ItemID.UNCUT_EMERALD,
ItemID.UNCUT_RUBY,
ItemID.UNCUT_DIAMOND,
ItemID.UNCUT_DRAGONSTONE
).exists();
}
@Override
public void execute() {
openBank();
bank.depositExcept(false, ItemID.HAMMER, ItemID.GOLDEN_NUGGET);
bank.close();
game.waitUntil(() -> !bank.isOpen(), 3);
last = Instant.now();
}
}

View File

@ -0,0 +1,52 @@
package io.reisub.openosrs.motherlodeminer.tasks;
import io.reisub.openosrs.motherlodeminer.MotherlodeMiner;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.enums.Activity;
import net.runelite.client.plugins.iutils.game.iObject;
import net.runelite.client.plugins.iutils.scene.Position;
import net.runelite.client.plugins.iutils.scene.RectangularArea;
import javax.inject.Inject;
public class Mine extends Task {
@Inject
private MotherlodeMiner plugin;
private final RectangularArea miningArea = new RectangularArea(
new Position(3748, 5676, 0),
new Position(3754, 5684, 0)
);
private iObject oreVein;
@Override
public String getStatus() {
return "Mining";
}
@Override
public boolean validate() {
if (plugin.getCurrentActivity() != Activity.IDLE) return false;
if (!plugin.isUpstairs()) return false;
oreVein = game.objects()
.withName("Ore vein")
.withAction("Mine")
.filter((obj) -> miningArea.contains(obj.position()) && !obj.position().equals(new Position(3764, 5665, 0))).nearest();
return plugin.getCurrentActivity() == Activity.IDLE
&& !game.inventory().full()
&& oreVein != null;
}
@Override
public void execute() {
plugin.setCurrentVeinPosition(oreVein.position());
oreVein.interact("Mine");
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.MINING, 15);
}
}

View File

@ -0,0 +1,50 @@
package io.reisub.openosrs.motherlodeminer.tasks;
import io.reisub.openosrs.motherlodeminer.MotherlodeMiner;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.enums.Activity;
import net.runelite.api.ItemID;
import net.runelite.client.plugins.iutils.game.iObject;
import javax.inject.Inject;
public class WithdrawSack extends Task {
@Inject
private MotherlodeMiner plugin;
@Override
public String getStatus() {
return "Withdrawing from sack";
}
@Override
public boolean validate() {
return !plugin.isUpstairs()
&& plugin.getCurrentActivity() == Activity.IDLE
&& plugin.isSackFull()
&& !game.inventory().withId(
ItemID.RUNITE_ORE,
ItemID.ADAMANTITE_ORE,
ItemID.MITHRIL_ORE,
ItemID.GOLD_ORE,
ItemID.COAL,
ItemID.UNCUT_SAPPHIRE,
ItemID.UNCUT_EMERALD,
ItemID.UNCUT_RUBY,
ItemID.UNCUT_DIAMOND,
ItemID.UNCUT_DRAGONSTONE
).exists();
}
@Override
public void execute() {
iObject sack = game.objects().withName("Sack").withAction("Search").nearest();
if (sack == null) return;
plugin.setActivity(Activity.WITHDRAWING);
sack.interact("Search");
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.IDLE, 30);
}
}

View File

@ -84,11 +84,41 @@ public interface Config extends net.runelite.client.config.Config {
return new Keybind(KeyEvent.VK_3, InputEvent.CTRL_DOWN_MASK); return new Keybind(KeyEvent.VK_3, InputEvent.CTRL_DOWN_MASK);
} }
@ConfigItem(
keyName = "hotkeyMeleeBuff",
name = "Melee buff hotkey",
description = "When you press this key melee buff(s) will be set as quickprayer",
position = 23
)
default Keybind hotkeyMeleeBuff() {
return new Keybind(KeyEvent.VK_Q, InputEvent.CTRL_DOWN_MASK);
}
@ConfigItem(
keyName = "hotkeyRangedBuff",
name = "Ranged buff hotkey",
description = "When you press this key ranged buff will be set as quickprayer",
position = 24
)
default Keybind hotkeyRangedBuff() {
return new Keybind(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK);
}
@ConfigItem(
keyName = "hotkeyMagicBuff",
name = "Magic buff hotkey",
description = "When you press this key magic buff will be set as quickprayer",
position = 25
)
default Keybind hotkeyMagicBuff() {
return new Keybind(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK);
}
@ConfigItem( @ConfigItem(
keyName = "openInventory", keyName = "openInventory",
name = "Open inventory", name = "Open inventory",
description = "Open inventory after swapping quickprayers", description = "Open inventory after swapping quickprayers",
position = 23 position = 26
) )
default boolean openInventory() { return true; } default boolean openInventory() { return true; }
@ -96,7 +126,7 @@ public interface Config extends net.runelite.client.config.Config {
keyName = "allowToggleOff", keyName = "allowToggleOff",
name = "Allow toggling off", name = "Allow toggling off",
description = "Will allow turning the protect prayer off when pressing the hotkey for the current one.", description = "Will allow turning the protect prayer off when pressing the hotkey for the current one.",
position = 24 position = 27
) )
default boolean allowToggleOff() { return true; } default boolean allowToggleOff() { return true; }
@ -104,7 +134,7 @@ public interface Config extends net.runelite.client.config.Config {
keyName = "jadPrayerFlick", keyName = "jadPrayerFlick",
name = "Jad Auto Prayer Flick", name = "Jad Auto Prayer Flick",
description = "Automatically swap prayers against Jad.", description = "Automatically swap prayers against Jad.",
position = 30 position = 40
) )
default boolean jadPrayerFlick() { return true; } default boolean jadPrayerFlick() { return true; }
@ -112,7 +142,7 @@ public interface Config extends net.runelite.client.config.Config {
keyName = "hesporiPrayerFlick", keyName = "hesporiPrayerFlick",
name = "Hespori Auto Prayer Flick", name = "Hespori Auto Prayer Flick",
description = "Automatically swap prayers against Hespori.", description = "Automatically swap prayers against Hespori.",
position = 31 position = 41
) )
default boolean hesporiPrayerFlick() { return true; } default boolean hesporiPrayerFlick() { return true; }

View File

@ -7,7 +7,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.*; import net.runelite.api.*;
import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;
import net.runelite.api.events.VarbitChanged; import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
@ -17,6 +17,7 @@ import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.iutils.api.Prayers;
import net.runelite.client.plugins.iutils.game.Game; import net.runelite.client.plugins.iutils.game.Game;
import net.runelite.client.plugins.iutils.game.iWidget; import net.runelite.client.plugins.iutils.game.iWidget;
import net.runelite.client.plugins.iutils.iUtils; import net.runelite.client.plugins.iutils.iUtils;
@ -70,7 +71,8 @@ public class Prayerflick extends Plugin implements KeyListener {
private boolean toggleFlicking; private boolean toggleFlicking;
private boolean firstFlick; private boolean firstFlick;
private boolean toggledOff; private boolean toggledOff;
private volatile ProtectFrom currently; private volatile QuickPrayer currentOverhead;
private int level;
@Override @Override
protected void startUp() { protected void startUp() {
@ -124,12 +126,12 @@ public class Prayerflick extends Plugin implements KeyListener {
switch (actor.getAnimation()) { switch (actor.getAnimation()) {
case AnimationID.TZTOK_JAD_MAGIC_ATTACK: case AnimationID.TZTOK_JAD_MAGIC_ATTACK:
case JALTOK_JAD_MAGE_ATTACK: case JALTOK_JAD_MAGE_ATTACK:
setPrayer(ProtectFrom.MAGIC, false); setPrayer(false, QuickPrayer.PROTECT_FROM_MAGIC);
game.utils.sendGameMessage("Pray against magic!"); game.utils.sendGameMessage("Pray against magic!");
break; break;
case AnimationID.TZTOK_JAD_RANGE_ATTACK: case AnimationID.TZTOK_JAD_RANGE_ATTACK:
case JALTOK_JAD_RANGE_ATTACK: case JALTOK_JAD_RANGE_ATTACK:
setPrayer(ProtectFrom.MISSILES, false); setPrayer(false, QuickPrayer.PROTECT_FROM_MISSILES);
game.utils.sendGameMessage("Pray against missiles!"); game.utils.sendGameMessage("Pray against missiles!");
break; break;
} }
@ -138,10 +140,10 @@ public class Prayerflick extends Plugin implements KeyListener {
if (config.hesporiPrayerFlick()) { if (config.hesporiPrayerFlick()) {
switch (actor.getAnimation()) { switch (actor.getAnimation()) {
case HESPORI_MAGE_ATTACK: case HESPORI_MAGE_ATTACK:
setPrayer(ProtectFrom.MAGIC, false); setPrayer(false, QuickPrayer.PROTECT_FROM_MAGIC);
break; break;
case HESPORI_RANGE_ATTACK: case HESPORI_RANGE_ATTACK:
setPrayer(ProtectFrom.MISSILES, false); setPrayer(false, QuickPrayer.PROTECT_FROM_MISSILES);
break; break;
} }
} }
@ -158,6 +160,8 @@ public class Prayerflick extends Plugin implements KeyListener {
@Override @Override
public void keyPressed(KeyEvent e) { public void keyPressed(KeyEvent e) {
level = game.baseLevel(Skill.PRAYER);
if (config.prayerFlickHotkey().matches(e)) { if (config.prayerFlickHotkey().matches(e)) {
if (toggleFlicking) { if (toggleFlicking) {
toggledOff = true; toggledOff = true;
@ -167,42 +171,52 @@ public class Prayerflick extends Plugin implements KeyListener {
toggleFlicking = !toggleFlicking; toggleFlicking = !toggleFlicking;
} else if (config.hotkeyMelee().matches(e)) { } else if (config.hotkeyMelee().matches(e)) {
setPrayer(ProtectFrom.MELEE, config.allowToggleOff()); setPrayer(config.allowToggleOff(), QuickPrayer.PROTECT_FROM_MELEE);
} else if (config.hotkeyMissiles().matches(e)) { } else if (config.hotkeyMissiles().matches(e)) {
setPrayer(ProtectFrom.MISSILES, config.allowToggleOff()); setPrayer(config.allowToggleOff(), QuickPrayer.PROTECT_FROM_MISSILES);
} else if (config.hotkeyMagic().matches(e)) { } else if (config.hotkeyMagic().matches(e)) {
setPrayer(ProtectFrom.MAGIC, config.allowToggleOff()); setPrayer(config.allowToggleOff(), QuickPrayer.PROTECT_FROM_MAGIC);
} else if (config.hotkeyMeleeBuff().matches(e)) {
setPrayer(config.allowToggleOff(), QuickPrayer.getBestMeleeBuff(level));
} else if (config.hotkeyRangedBuff().matches(e)) {
setPrayer(config.allowToggleOff(), QuickPrayer.getBestRangedBuff(level));
} else if (config.hotkeyMagicBuff().matches(e)) {
setPrayer(config.allowToggleOff(), QuickPrayer.getBestMagicBuff(level));
} }
} }
@Override @Override
public void keyReleased(KeyEvent e) {} public void keyReleased(KeyEvent e) {}
private void setPrayer(ProtectFrom protectFrom, boolean allowToggleOff) { private void setPrayer(boolean allowToggleOff, QuickPrayer... quickPrayers) {
if (!allowToggleOff && protectFrom == currently) return; if (!allowToggleOff && quickPrayers[0] == currentOverhead) return;
if (currently == protectFrom) { if (currentOverhead == quickPrayers[0]) {
currently = ProtectFrom.NONE; currentOverhead = QuickPrayer.NONE;
} else { } else if (quickPrayers[0] == QuickPrayer.PROTECT_FROM_MAGIC
currently = protectFrom; || quickPrayers[0] == QuickPrayer.PROTECT_FROM_MISSILES
|| quickPrayers[0] == QuickPrayer.PROTECT_FROM_MELEE) {
currentOverhead = quickPrayers[0];
} }
executor.schedule(() -> { executor.schedule(() -> {
iWidget quickPrayers = game.widget(WidgetInfo.MINIMAP_QUICK_PRAYER_ORB); iWidget quickPrayersWidget = game.widget(WidgetInfo.MINIMAP_QUICK_PRAYER_ORB);
if (quickPrayers == null) return; if (quickPrayersWidget == null) return;
quickPrayers.interact(1); quickPrayersWidget.interact(1);
game.waitUntil(() -> { game.waitUntil(() -> {
iWidget w = game.widget(77, 4); iWidget w = game.widget(WidgetID.QUICK_PRAYERS_GROUP_ID, 4);
return w != null && !w.hidden(); return w != null && !w.hidden();
}); });
iWidget protection = game.widget(77, 4, protectFrom.getChildId()); for (QuickPrayer quickPrayer : quickPrayers) {
iWidget protection = game.widget(WidgetID.QUICK_PRAYERS_GROUP_ID, 4, quickPrayer.getChildId());
if (protection == null) return; if (protection == null) return;
protection.interact(0); protection.interact(0);
}
iWidget update = game.widget(77, 5); iWidget update = game.widget(WidgetID.QUICK_PRAYERS_GROUP_ID, 5);
if (update == null) return; if (update == null) return;
update.interact(0); update.interact(0);

View File

@ -1,15 +0,0 @@
package io.reisub.openosrs.prayerflick;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum ProtectFrom {
NONE(0),
MAGIC(12),
MISSILES(13),
MELEE(14);
private final int childId;
}

View File

@ -0,0 +1,132 @@
package io.reisub.openosrs.prayerflick;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.widgets.WidgetID;
@AllArgsConstructor
@Getter
public enum QuickPrayer {
NONE(0, 0),
THICK_SKIN(WidgetID.QuickPrayer.THICK_SKIN_CHILD_ID, 1),
BURST_OF_STRENGTH(WidgetID.QuickPrayer.BURST_OF_STRENGTH_CHILD_ID, 4),
CLARITY_OF_THOUGHT(WidgetID.QuickPrayer.CLARITY_OF_THOUGHT_CHILD_ID, 7),
SHARP_EYE(WidgetID.QuickPrayer.SHARP_EYE_CHILD_ID, 8),
MYSTIC_WILL(WidgetID.QuickPrayer.MYSTIC_WILL_CHILD_ID, 9),
ROCK_SKIN(WidgetID.QuickPrayer.ROCK_SKIN_CHILD_ID, 10),
SUPERHUMAN_STRENGTH(WidgetID.QuickPrayer.SUPERHUMAN_STRENGTH_CHILD_ID, 13),
IMPROVED_REFLEXES(WidgetID.QuickPrayer.IMPROVED_REFLEXES_CHILD_ID, 16),
RAPID_RESTORE(WidgetID.QuickPrayer.RAPID_RESTORE_CHILD_ID, 19),
RAPID_HEAL(WidgetID.QuickPrayer.RAPID_HEAL_CHILD_ID, 22),
PROTECT_ITEM(WidgetID.QuickPrayer.PROTECT_ITEM_CHILD_ID, 25),
HAWK_EYE(WidgetID.QuickPrayer.HAWK_EYE_CHILD_ID, 26),
MYSTIC_LORE(WidgetID.QuickPrayer.MYSTIC_LORE_CHILD_ID, 27),
STEEL_SKIN(WidgetID.QuickPrayer.STEEL_SKIN_CHILD_ID, 28),
ULTIMATE_STRENGTH(WidgetID.QuickPrayer.ULTIMATE_STRENGTH_CHILD_ID, 31),
INCREDIBLE_REFLEXES(WidgetID.QuickPrayer.INCREDIBLE_REFLEXES_CHILD_ID, 34),
PROTECT_FROM_MAGIC(WidgetID.QuickPrayer.PROTECT_FROM_MAGIC_CHILD_ID, 37),
PROTECT_FROM_MISSILES(WidgetID.QuickPrayer.PROTECT_FROM_MISSILES_CHILD_ID, 40),
PROTECT_FROM_MELEE(WidgetID.QuickPrayer.PROTECT_FROM_MELEE_CHILD_ID, 43),
EAGLE_EYE(WidgetID.QuickPrayer.EAGLE_EYE_CHILD_ID, 44),
MYSTIC_MIGHT(WidgetID.QuickPrayer.MYSTIC_MIGHT_CHILD_ID, 45),
RETRIBUTION(WidgetID.QuickPrayer.RETRIBUTION_CHILD_ID, 46),
REDEMPTION(WidgetID.QuickPrayer.REDEMPTION_CHILD_ID, 49),
SMITE(WidgetID.QuickPrayer.SMITE_CHILD_ID, 52),
PRESERVE(WidgetID.QuickPrayer.PRESERVE_CHILD_ID, 55),
CHIVALRY(WidgetID.QuickPrayer.CHIVALRY_CHILD_ID, 60),
PIETY(WidgetID.QuickPrayer.PIETY_CHILD_ID, 70),
RIGOUR(WidgetID.QuickPrayer.RIGOUR_CHILD_ID, 74),
AUGURY(WidgetID.QuickPrayer.AUGURY_CHILD_ID, 77);
private final int childId;
private final int level;
public static QuickPrayer[] getBestMeleeBuff(int level) {
if (level >= PIETY.level) {
return new QuickPrayer[] { PIETY };
} else if (level >= CHIVALRY.level) {
return new QuickPrayer[] { CHIVALRY };
} else {
QuickPrayer[] quickPrayers;
if (level >= 7) {
quickPrayers = new QuickPrayer[3];
quickPrayers[0] = getBestDefence(level);
quickPrayers[1] = getBestStrength(level);
quickPrayers[2] = getBestAttack(level);
} else if (level >= 4) {
quickPrayers = new QuickPrayer[2];
quickPrayers[0] = getBestDefence(level);
quickPrayers[1] = getBestStrength(level);
} else {
quickPrayers = new QuickPrayer[1];
quickPrayers[0] = getBestDefence(level);
}
return quickPrayers;
}
}
private static QuickPrayer getBestAttack(int level) {
if (level >= INCREDIBLE_REFLEXES.level) {
return INCREDIBLE_REFLEXES;
} else if (level >= IMPROVED_REFLEXES.level) {
return IMPROVED_REFLEXES;
} else if (level >= CLARITY_OF_THOUGHT.level) {
return CLARITY_OF_THOUGHT;
}
return null;
}
private static QuickPrayer getBestStrength(int level) {
if (level >= ULTIMATE_STRENGTH.level) {
return ULTIMATE_STRENGTH;
} else if (level >= SUPERHUMAN_STRENGTH.level) {
return SUPERHUMAN_STRENGTH;
} else if (level >= BURST_OF_STRENGTH.level) {
return BURST_OF_STRENGTH;
}
return null;
}
private static QuickPrayer getBestDefence(int level) {
if (level >= STEEL_SKIN.level) {
return STEEL_SKIN;
} else if (level >= ROCK_SKIN.level) {
return ROCK_SKIN;
} else if (level >= THICK_SKIN.level) {
return THICK_SKIN;
}
return null;
}
public static QuickPrayer[] getBestRangedBuff(int level) {
if (level >= RIGOUR.level) {
return new QuickPrayer[] { RIGOUR };
} else if (level >= EAGLE_EYE.level) {
return new QuickPrayer[] { EAGLE_EYE };
} else if (level >= HAWK_EYE.level) {
return new QuickPrayer[] { HAWK_EYE };
} else if (level >= SHARP_EYE.level) {
return new QuickPrayer[] { SHARP_EYE };
}
return new QuickPrayer[]{};
}
public static QuickPrayer[] getBestMagicBuff(int level) {
if (level >= AUGURY.level) {
return new QuickPrayer[] { AUGURY };
} else if (level >= MYSTIC_MIGHT.level) {
return new QuickPrayer[] { MYSTIC_MIGHT };
} else if (level >= MYSTIC_LORE.level) {
return new QuickPrayer[] { MYSTIC_LORE };
} else if (level >= MYSTIC_WILL.level) {
return new QuickPrayer[] { MYSTIC_WILL };
}
return new QuickPrayer[]{};
}
}

BIN
release/agility-0.0.1.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
release/consume-0.0.1.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
release/cooker-0.0.1.jar Normal file

Binary file not shown.

BIN
release/fisher-0.0.1.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -26,6 +26,7 @@
rootProject.name = "Chaos Plugins" rootProject.name = "Chaos Plugins"
include(":agility") include(":agility")
include(":autoalcher")
include(":autobones") include(":autobones")
include(":autodropper") include(":autodropper")
include(":birdhouse") include(":birdhouse")
@ -39,6 +40,7 @@ include(":glassblower")
include(":herblore") include(":herblore")
include(":masterthiever") include(":masterthiever")
include(":miner") include(":miner")
include(":motherlodeminer")
include(":mtahelper") include(":mtahelper")
include(":prayerflick") include(":prayerflick")
include(":shopper") include(":shopper")

View File

@ -12,7 +12,9 @@ import net.runelite.api.Skill;
import net.runelite.api.events.*; import net.runelite.api.events.*;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.iutils.game.iPlayer; import net.runelite.client.plugins.iutils.game.iPlayer;
import net.runelite.client.plugins.iutils.scene.GameObjectStream;
import net.runelite.client.plugins.iutils.scripts.iScript; import net.runelite.client.plugins.iutils.scripts.iScript;
import net.runelite.client.plugins.iutils.ui.InventoryItemStream;
import javax.inject.Inject; import javax.inject.Inject;
import java.time.Duration; import java.time.Duration;
@ -157,8 +159,10 @@ public abstract class CScript extends iScript {
if (Duration.between(lastInventoryChange, Instant.now()).compareTo(lastActionTimeout) < 0) return; if (Duration.between(lastInventoryChange, Instant.now()).compareTo(lastActionTimeout) < 0) return;
int animId = game.localPlayer().animation(); if (!game.localPlayer().isIdle() || lastActionTime == null) {
if (animId != IDLE || lastActionTime == null) return; lastActionTime = Instant.now();
return;
}
Duration sinceAction = Duration.between(lastActionTime, Instant.now()); Duration sinceAction = Duration.between(lastActionTime, Instant.now());

View File

@ -15,5 +15,9 @@ public enum Activity {
CLEANING_HERBS(), CLEANING_HERBS(),
CREATING_UNFINISHED_POTIONS(), CREATING_UNFINISHED_POTIONS(),
CREATING_POTIONS(), CREATING_POTIONS(),
SMITHING(); SMITHING(),
FIGHTING(),
DEPOSITING(),
REPAIRING(),
WITHDRAWING();
} }

View File

@ -0,0 +1,66 @@
package io.reisub.openosrs.util.tasks;
import io.reisub.openosrs.util.Task;
import net.runelite.client.plugins.iutils.game.iNPC;
import net.runelite.client.plugins.iutils.game.iObject;
import java.time.Duration;
import java.time.Instant;
public abstract class BankTask extends Task {
protected Instant last = Instant.EPOCH;
@Override
public String getStatus() {
return "Banking";
}
protected void openBank() {
openBank(15);
}
protected boolean openBank(int waitTicks) {
if (!bank.isOpen()) {
iObject bankObj = getBankObject();
if (bankObj != null) {
if (bankObj.actions().contains("Bank")) {
bankObj.interact("Bank");
} else if (bankObj.actions().contains("Use")) {
bankObj.interact("Use");
} else {
bankObj.interact(0);
}
} else {
iNPC bankNpc = getBankNpc();
if (bankNpc == null) return false;
if (bankNpc.actions().contains("Bank")) {
bankNpc.interact("Bank");
} else {
bankNpc.interact(0);
}
}
game.waitUntil(() -> bank.isOpen(), waitTicks);
}
return bank.isOpen();
}
protected boolean isLastBankDurationAgo(Duration duration) {
return Duration.between(last, Instant.now()).compareTo(duration) >= 0;
}
protected iObject getBankObject() {
return game.objects()
.withName("Bank chest", "Bank booth", "Bank Chest-wreck", "Bank chest")
.nearest();
}
protected iNPC getBankNpc() {
return game.npcs()
.withAction("Bank")
.nearest();
}
}

View File

@ -307,7 +307,7 @@ public class Wintertodt extends CScript {
if (projectile.getId() == 501) { if (projectile.getId() == 501) {
int x = game.client().getBaseX() + event.getPosition().getSceneX(); int x = game.client().getBaseX() + event.getPosition().getSceneX();
int y = game.client().getBaseY() + event.getPosition().getSceneY(); int y = game.client().getBaseY() + event.getPosition().getSceneY();
int cycles = projectile.getEndCycle() - projectile.getStartMovementCycle(); int cycles = projectile.getEndCycle() - projectile.getStartCycle();
// we don't care about any of the projectiles that don't go to our play area // we don't care about any of the projectiles that don't go to our play area
if (y >= 4001) return; if (y >= 4001) return;