Initial commit

This commit is contained in:
2022-01-08 19:46:18 +01:00
commit 57ba5a5858
207 changed files with 12402 additions and 0 deletions

View File

@ -0,0 +1,17 @@
package io.reisub.openosrs.wintertodt;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum Activity {
IDLE("Idle"),
WOODCUTTING("Woodcutting"),
FLETCHING("Fletching"),
FEEDING_BRAZIER("Feeding"),
FIXING_BRAZIER("Fixing"),
LIGHTING_BRAZIER("Lighting");
private final String actionString;
}

View File

@ -0,0 +1,22 @@
package io.reisub.openosrs.wintertodt;
import lombok.AllArgsConstructor;
import lombok.Getter;
import javax.annotation.concurrent.Immutable;
@AllArgsConstructor
@Immutable
public class BossData {
@Getter
private final int health;
@Getter
private final int world;
@Getter
private final long time;
@Getter
private final int timer;
}

View File

@ -0,0 +1,132 @@
/*
* 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.wintertodt;
import net.runelite.client.config.Button;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Range;
@ConfigGroup("ChaosWintertodtConfig")
public interface Config extends net.runelite.client.config.Config {
@Range(min = 1, max = 99)
@ConfigItem(
keyName = "minEatHP",
name = "Minimum Eat HP",
description = "Minimum HP to eat at. i.e. will always eat",
position = 0
)
default int minEatHP() {
return 10;
}
@Range(min = 1, max = 100)
@ConfigItem(
keyName = "maxEatHP",
name = "Maximum Eat HP",
description = "Highest HP to consider eating. Value MUST be higher than minimum HP config. If HP drops below this value bot may randomly decide to eat.",
position = 1
)
default int maxEatHP() {
return 20;
}
@ConfigItem(
position = 10,
keyName = "sideSelection",
name = "Select side",
description = "Choose which side you want to play the game at."
)
default Side sideSelection() { return Side.EAST; }
@Range(min = 1, max = 100)
@ConfigItem(
position = 11,
keyName = "sideTimeout",
name = "Side timeout",
description = "Seconds to wait before switching side because of an incapacitated pyromancer."
)
default int sideTimeout() { return 15; }
@ConfigItem(
keyName = "fletchNearBrazier",
name = "Fletch near brazier",
description = "Fletch near brazier so we can quickly fix/light the brazier for more experience and points at the cost of taking more damage.",
position = 20
)
default boolean fletchNearBrazier() {
return true;
}
@ConfigItem(
keyName = "dodgeProjectiles",
name = "Dodge projectiles",
description = "Attempts to dodge snow fall and exploding braziers.",
position = 21
)
default boolean dodgeProjectiles() {
return true;
}
@ConfigItem(
keyName = "openCrates",
name = "Open crates",
description = "Enable to open crates.",
position = 22
)
default boolean openCrates() {
return true;
}
@ConfigItem(
keyName = "hop",
name = "Hop",
description = "Hop to different worlds after finishing game.",
position = 30
)
default boolean hop() {
return true;
}
@Range(min = 40, max = 100)
@ConfigItem(
position = 31,
keyName = "hopPercentage",
name = "Hop percentage",
description = "Minimum percentage the boss' health should be at before hopping. Low values risk not getting enough points. 70 is safe, 60 should work, anything lower is very risky."
)
default int hopPercentage() { return 70; }
@ConfigItem(
keyName = "startButton",
name = "Start/Stop",
description = "Start the script",
position = 100
)
default Button startButton() {
return new Button();
}
}

View File

@ -0,0 +1,21 @@
package io.reisub.openosrs.wintertodt;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum InterruptType {
COLD("Damaged by Wintertodt Cold"),
SNOWFALL("Damaged by Wintertodt Snowfall"),
BRAZIER("Brazier Shattered"),
INVENTORY_FULL("Inventory full of Bruma Roots"),
OUT_OF_ROOTS("Out of Bruma Roots"),
FIXED_BRAZIER("Fixed Brazier"),
LIT_BRAZIER("Lit Brazier"),
BRAZIER_WENT_OUT("Brazier went out"),
EAT("You ate"),
TOO_COLD("Your hands are too cold");
private final String interruptSourceString;
}

View File

@ -0,0 +1,91 @@
package io.reisub.openosrs.wintertodt;
import com.google.gson.*;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.plugins.iutils.game.Game;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Slf4j
@Singleton
public class Scouter {
@Inject
public Wintertodt plugin;
@Inject
public Game game;
@Inject
public OkHttpClient okHttpClient;
@Getter
private final List<BossData> data = new ArrayList<>(4);
private Instant lastUpdate;
public void onGameTick() {
if (lastUpdate == null || Duration.between(lastUpdate, Instant.now()).getSeconds() > 2) {
lastUpdate = Instant.now();
getRemoteData();
}
}
public BossData getLocalData() {
return new BossData(
plugin.getBossHealth(),
game.client().getWorld(),
System.currentTimeMillis() / 1000,
plugin.getRespawnTimer()
);
}
private void getRemoteData() {
try {
Request r = new Request.Builder()
.url("https://www.wintertodt.com/scouter/")
.addHeader("User-Agent", "RuneLite")
.addHeader("Authorization", "2")
.build();
okHttpClient.newCall(r).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
log.debug("Error retrieving Wintertodt boss data", e);
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) {
if (response.isSuccessful()) {
try {
JsonArray jsonArray = new Gson().fromJson(Objects.requireNonNull(response.body()).string(), JsonArray.class);
parseData(jsonArray);
} catch (IOException | JsonSyntaxException ignored) {}
}
}
});
} catch (IllegalArgumentException ignored) {}
}
private void parseData(JsonArray jsonArray) {
for (JsonElement jsonElement : jsonArray) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
try {
BossData bossData = new BossData(jsonObject.get("a").getAsInt(), jsonObject.get("b").getAsInt(), jsonObject.get("c").getAsLong(), jsonObject.get("d").getAsInt());
if (bossData.getWorld() != game.client().getWorld()) {
data.add(bossData);
}
} catch (UnsupportedOperationException ignored) {}
}
}
}

View File

@ -0,0 +1,15 @@
package io.reisub.openosrs.wintertodt;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.client.plugins.iutils.scene.Position;
@AllArgsConstructor
@Getter
public enum Side {
EAST(new Position(1638, 3996, 0), new Position(1638, 3988, 0)),
WEST(new Position(1622, 3996, 0), new Position(1622, 3988, 0));
private final Position positionNearBrazier;
private final Position positionNearRoots;
}

View File

@ -0,0 +1,472 @@
package io.reisub.openosrs.wintertodt;
import com.google.inject.Inject;
import com.google.inject.Provides;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.util.Util;
import io.reisub.openosrs.util.tasks.Eat;
import io.reisub.openosrs.util.tasks.KittenTask;
import io.reisub.openosrs.wintertodt.tasks.*;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.*;
import net.runelite.api.events.*;
import net.runelite.api.widgets.Widget;
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.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static net.runelite.api.AnimationID.*;
import static net.runelite.api.ItemID.BRUMA_KINDLING;
import static net.runelite.api.ItemID.BRUMA_ROOT;
@Extension
@PluginDependency(Util.class)
@PluginDependency(iUtils.class)
@PluginDescriptor(
name = "Chaos Wintertodt",
description = "Plays the Wintertodt minigame",
enabledByDefault = false
)
@Slf4j
public class Wintertodt extends iScript {
@Inject
public Config config;
public static final int WINTERTODT_REGION = 6462;
public static final int WINTERTODT_HEALTH_PACKED_ID = 25952277;
public static final int WINTERTODT_GAME_TIMER_ID = 25952259;
@Getter
private Activity currentActivity = Activity.IDLE;
@Getter
private Activity previousActivity = Activity.IDLE;
@Getter
private int respawnTimer;
@Getter
private int bossHealth;
@Getter
@Setter
private boolean tooCold;
@Getter
@Setter
private Instant lastHop;
@Getter
private final List<WintertodtProjectile> projectiles = new ArrayList<>();
private List<Task> tasks;
private KittenTask kittenTask;
private Hop hopTask;
private Scouter scouter;
private int fmLevel, wcLevel, fletchLevel;
private Instant lastActionTime;
private int previousTimerValue;
@SuppressWarnings("unused")
@Provides
Config provideConfig(ConfigManager configManager) {
return configManager.getConfig(Config.class);
}
@Override
protected void loop() {
for (Task t : tasks) {
if (t.validate()) {
log.info(t.getStatus());
t.execute();
break;
}
}
game.sleepDelay();
}
@Override
protected void onStart() {
log.info("Starting Chaos Wintertodt");
fmLevel = game.baseLevel(Skill.FIREMAKING);
wcLevel = game.baseLevel(Skill.WOODCUTTING);
fletchLevel = game.baseLevel(Skill.FLETCHING);
if (config.hop()) scouter = injector.getInstance(Scouter.class);
Eat eatTask = injector.getInstance(Eat.class);
eatTask.setInterval(config.minEatHP(), config.maxEatHP());
kittenTask = KittenTask.getInstance(injector);
tasks = new ArrayList<>();
tasks.add(eatTask);
tasks.add(kittenTask);
if (config.dodgeProjectiles()) {
tasks.add(injector.getInstance(DodgeProjectile.class));
}
tasks.add(injector.getInstance(OpenInventory.class));
tasks.add(injector.getInstance(EatWhileWaiting.class));
tasks.add(injector.getInstance(OpenCrates.class));
tasks.add(injector.getInstance(GoToBank.class));
tasks.add(injector.getInstance(HandleBank.class));
tasks.add(injector.getInstance(GoToWintertodt.class));
if (config.hop()) {
hopTask = injector.getInstance(Hop.class);
tasks.add(hopTask);
}
tasks.add(injector.getInstance(MoveToBrazier.class));
tasks.add(injector.getInstance(Fix.class));
tasks.add(injector.getInstance(Light.class));
tasks.add(injector.getInstance(Fletch.class));
tasks.add(injector.getInstance(ChangeSide.class));
tasks.add(injector.getInstance(Burn.class));
tasks.add(injector.getInstance(Chop.class));
}
@Override
protected void onStop() {
log.info("Stopping Chaos Wintertodt");
if (tasks != null) {
tasks.clear();
}
KittenTask.handleKitten = false;
scouter = null;
}
@SuppressWarnings("unused")
@Subscribe
private void onConfigButtonPressed(ConfigButtonClicked configButtonClicked) {
if (configButtonClicked.getKey().equals("startButton")) {
execute();
}
}
@SuppressWarnings("unused")
@Subscribe
private void onStatChanged(StatChanged event) {
Skill skill = event.getSkill();
int level = event.getLevel();
if (skill == Skill.FIREMAKING && level > fmLevel) {
setActivity(Activity.IDLE);
fmLevel = event.getLevel();
} else if (skill == Skill.WOODCUTTING && level > wcLevel) {
setActivity(Activity.IDLE);
wcLevel = event.getLevel();
} else if (skill == Skill.FLETCHING && level > fletchLevel) {
setActivity(Activity.IDLE);
fletchLevel = event.getLevel();
} else if (skill == Skill.FIREMAKING && currentActivity == Activity.LIGHTING_BRAZIER) {
setActivity(Activity.IDLE);
} else if (skill == Skill.CONSTRUCTION && currentActivity == Activity.FIXING_BRAZIER) {
setActivity(Activity.IDLE);
}
}
@SuppressWarnings("unused")
@Subscribe
private void onGameTick(GameTick event) {
if (!isInWintertodtRegion() || game.client().getGameState() != GameState.LOGGED_IN) return;
if (scouter != null) {
scouter.onGameTick();
}
if (hopTask != null) {
hopTask.onGameTick();
}
parseBossHealth();
//parseRespawnTime();
checkActionTimeout();
}
@SuppressWarnings("unused")
@Subscribe
private void onChatMessage(ChatMessage chatMessage) {
if (kittenTask != null) {
kittenTask.onChatMessage(chatMessage);
}
if (!isInWintertodtRegion()) return;
ChatMessageType chatMessageType = chatMessage.getType();
if (chatMessageType != ChatMessageType.GAMEMESSAGE && chatMessageType != ChatMessageType.SPAM) return;
MessageNode messageNode = chatMessage.getMessageNode();
final InterruptType interruptType;
if (messageNode.getValue().startsWith("You carefully fletch the root")) {
setActivity(Activity.FLETCHING);
return;
}
if (messageNode.getValue().startsWith("The cold of")) {
interruptType = InterruptType.COLD;
} else if (messageNode.getValue().startsWith("The freezing cold attack")) {
interruptType = InterruptType.SNOWFALL;
} else if (messageNode.getValue().startsWith("The brazier is broken and shrapnel")) {
interruptType = InterruptType.BRAZIER;
} else if (messageNode.getValue().startsWith("You have run out of bruma roots")) {
interruptType = InterruptType.OUT_OF_ROOTS;
} else if (messageNode.getValue().startsWith("Your inventory is too full")) {
interruptType = InterruptType.INVENTORY_FULL;
} else if (messageNode.getValue().startsWith("You fix the brazier")) {
interruptType = InterruptType.FIXED_BRAZIER;
} else if (messageNode.getValue().startsWith("You light the brazier.")) {
interruptType = InterruptType.LIT_BRAZIER;
} else if (messageNode.getValue().startsWith("The brazier has gone out.")) {
interruptType = InterruptType.BRAZIER_WENT_OUT;
} else if (messageNode.getValue().startsWith("You eat")) {
interruptType = InterruptType.EAT;
} else if (messageNode.getValue().startsWith("Your hands are too cold")) {
interruptType = InterruptType.TOO_COLD;
tooCold = true;
} else {
return;
}
boolean wasInterrupted = false;
switch (interruptType) {
case EAT:
case LIT_BRAZIER:
case INVENTORY_FULL:
case OUT_OF_ROOTS:
case BRAZIER_WENT_OUT:
case FIXED_BRAZIER:
wasInterrupted = true;
break;
case COLD:
case BRAZIER:
case SNOWFALL:
if (currentActivity != Activity.WOODCUTTING && currentActivity != Activity.IDLE) {
wasInterrupted = true;
}
break;
}
if (wasInterrupted) {
setActivity(Activity.IDLE);
}
}
@SuppressWarnings("unused")
@Subscribe
private void onAnimationChanged(AnimationChanged event) {
if (game.client().getGameState() != GameState.LOGGED_IN || !isInWintertodtRegion()) return;
if (event.getActor() != game.client().getLocalPlayer()) return;
int animId = game.localPlayer().animation();
switch (animId) {
case WOODCUTTING_BRONZE:
case WOODCUTTING_IRON:
case WOODCUTTING_STEEL:
case WOODCUTTING_BLACK:
case WOODCUTTING_MITHRIL:
case WOODCUTTING_ADAMANT:
case WOODCUTTING_RUNE:
case WOODCUTTING_GILDED:
case WOODCUTTING_DRAGON:
case WOODCUTTING_DRAGON_OR:
case WOODCUTTING_INFERNAL:
case WOODCUTTING_3A_AXE:
case WOODCUTTING_CRYSTAL:
case WOODCUTTING_TRAILBLAZER:
setActivity(Activity.WOODCUTTING);
break;
case FLETCHING_BOW_CUTTING:
setActivity(Activity.FLETCHING);
break;
case LOOKING_INTO:
setActivity(Activity.FEEDING_BRAZIER);
break;
case FIREMAKING:
setActivity(Activity.LIGHTING_BRAZIER);
break;
case CONSTRUCTION:
case CONSTRUCTION_IMCANDO:
setActivity(Activity.FIXING_BRAZIER);
break;
}
}
@SuppressWarnings("unused")
@Subscribe
private void onItemContainerChanged(ItemContainerChanged event) {
final ItemContainer container = event.getItemContainer();
if (!isInWintertodtRegion() || container != game.client().getItemContainer(InventoryID.INVENTORY)) return;
int logs = (int) game.inventory().withId(BRUMA_ROOT).count();
int kindling = (int) game.inventory().withId(BRUMA_KINDLING).count();
if (logs == 0 && currentActivity == Activity.FLETCHING) {
setActivity(Activity.IDLE);
} else if (logs == 0 && kindling == 0 && currentActivity == Activity.FEEDING_BRAZIER) {
setActivity(Activity.IDLE);
} else if (shouldStartFeeding() && (currentActivity == Activity.WOODCUTTING || currentActivity == Activity.FLETCHING)) {
setActivity(Activity.IDLE);
} else if (shouldStartFletching() && currentActivity == Activity.WOODCUTTING) {
setActivity(Activity.IDLE);
}
}
@SuppressWarnings("unused")
@Subscribe
private void onVarbitChanged(VarbitChanged varbitChanged) {
int timerValue = game.client().getVar(Varbits.WINTERTODT_TIMER);
if (timerValue != previousTimerValue) {
respawnTimer = timerValue * 30 / 50;
previousTimerValue = timerValue;
}
}
@Subscribe
private void onProjectileMoved(ProjectileMoved event) {
Projectile projectile = event.getProjectile();
if (projectile.getInteracting() != null) return;
if (projectile.getId() == 501) {
int x = game.client().getBaseX() + event.getPosition().getSceneX();
int y = game.client().getBaseY() + event.getPosition().getSceneY();
int cycles = projectile.getEndCycle() - projectile.getStartMovementCycle();
// we don't care about any of the projectiles that don't go to our play area
if (y >= 4001) return;
if (cycles == 200) {
projectiles.add(new WintertodtProjectile(x, y, true, Instant.now()));
} else if ((x == 1638 && y == 3997) || (x == 1619 && y == 3997)) {
if (cycles == 120) {
projectiles.add(new WintertodtProjectile(x, y, false, Instant.now()));
}
}
}
}
public boolean isInWintertodtRegion() {
return game.localPlayer().position().regionID() == WINTERTODT_REGION;
}
public boolean bossIsUp() {
return isInWintertodtRegion()
&& getBossHealth() > 0
&& getRespawnTimer() <= 0;
}
public boolean shouldStartFletching() {
long rootCount = game.inventory().withName("Bruma root").count();
long kindlingCount = game.inventory().withName("Bruma kindling").count();
return rootCount * 2 + kindlingCount >= getBossHealth();
}
public boolean shouldStartFeeding() {
long burnablesCount = game.inventory().withNamePart("Bruma").count();
return burnablesCount >= getBossHealth();
}
public Side getNearestSide() {
Position playerPos = game.localPlayer().position();
if (playerPos.distanceTo(Side.EAST.getPositionNearBrazier()) > playerPos.distanceTo(Side.WEST.getPositionNearBrazier())) {
return Side.WEST;
} else {
return Side.EAST;
}
}
public Side getFurthestSide() {
Position playerPos = game.localPlayer().position();
if (playerPos.distanceTo(Side.EAST.getPositionNearBrazier()) < playerPos.distanceTo(Side.WEST.getPositionNearBrazier())) {
return Side.WEST;
} else {
return Side.EAST;
}
}
private void setActivity(Activity action) {
if (action == Activity.IDLE && currentActivity != Activity.IDLE) {
previousActivity = currentActivity;
}
currentActivity = action;
if (action != Activity.IDLE) {
lastActionTime = Instant.now();
}
}
private void checkActionTimeout() {
if (currentActivity == Activity.IDLE) return;
int animId = game.localPlayer().animation();
if (animId != IDLE || lastActionTime == null) return;
Duration timeout = Duration.ofSeconds(3);
Duration sinceAction = Duration.between(lastActionTime, Instant.now());
if (sinceAction.compareTo(timeout) >= 0) {
setActivity(Activity.IDLE);
}
}
private void parseBossHealth() {
Widget healthWidget = game.client.getWidget(WINTERTODT_HEALTH_PACKED_ID);
if (healthWidget != null) {
Pattern regex = Pattern.compile("\\d+");
Matcher bossHealthMatcher = regex.matcher(healthWidget.getText());
if (bossHealthMatcher.find()) {
bossHealth = Integer.parseInt(bossHealthMatcher.group(0));
if (bossHealth > 0) {
respawnTimer = -1;
}
} else {
bossHealth = -1;
}
}
}
private void parseRespawnTime() {
Widget timerWidget = game.client.getWidget(WINTERTODT_GAME_TIMER_ID);
if (timerWidget != null) {
Pattern regex = Pattern.compile("\\d:\\d+");
Matcher timerMatcher = regex.matcher(timerWidget.getText());
if (timerMatcher.find()) {
String[] time = timerMatcher.group(0).split(":");
String minutes = time[0];
String seconds = time[1];
respawnTimer = Integer.parseInt(minutes) * 60 + Integer.parseInt(seconds);
} else {
respawnTimer = -1;
}
}
}
}

View File

@ -0,0 +1,30 @@
package io.reisub.openosrs.wintertodt;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.client.plugins.iutils.scene.Area;
import net.runelite.client.plugins.iutils.scene.RectangularArea;
import java.time.Instant;
@AllArgsConstructor
public class WintertodtProjectile {
private final int x;
private final int y;
private final boolean aoe;
@Getter
private final Instant start;
public Area getDamageArea() {
if (aoe) {
return new RectangularArea(x-1, y-1, x+1, y+1);
} else {
if (x == 1638) {
return new RectangularArea(x,y-1, x+3, y+2);
} else {
return new RectangularArea(x-1, y-1, x+2, y+2);
}
}
}
}

View File

@ -0,0 +1,49 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Activity;
import io.reisub.openosrs.wintertodt.Side;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.client.plugins.iutils.scene.Position;
import javax.inject.Inject;
import static net.runelite.api.ItemID.BRUMA_KINDLING;
import static net.runelite.api.ItemID.BRUMA_ROOT;
public class Burn extends Task {
@Inject
public Wintertodt plugin;
@Override
public boolean validate() {
if (!plugin.bossIsUp()) return false;
if (plugin.getPreviousActivity() == Activity.WOODCUTTING && !game.inventory().full() && !plugin.shouldStartFeeding()) return false;
return plugin.getCurrentActivity() == Activity.IDLE
&& game.inventory().withId(BRUMA_ROOT, BRUMA_KINDLING).exists();
}
@Override
public void execute() {
if (plugin.getNearestSide() == Side.WEST
&& !game.localPlayer().position().equals(new Position(1622, 3996, 0))) {
walking.walkTo(new Position(1622, 3996, 0));
game.tick();
game.sleepDelay();
}
game.objects().withName("Burning brazier").within(15).findFirst().ifPresent((brazier) -> {
brazier.interact("Feed");
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.FEEDING_BRAZIER || !game.objects().withName("Burning brazier").within(10).exists(), 10);
game.tick();
});
}
@Override
public String getStatus() {
return "Feeding brazier";
}
}

View File

@ -0,0 +1,57 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Activity;
import io.reisub.openosrs.wintertodt.Config;
import io.reisub.openosrs.wintertodt.Wintertodt;
import javax.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import static net.runelite.api.NpcID.INCAPACITATED_PYROMANCER;
public class ChangeSide extends Task {
@Inject
public Wintertodt plugin;
@Inject
public Config config;
private Instant lastIncap;
@Override
public String getStatus() {
return "Changing side";
}
@Override
public boolean validate() {
if (!plugin.bossIsUp()) {
lastIncap = null;
return false;
}
if (game.npcs().within(6).withId(INCAPACITATED_PYROMANCER).exists()
&& !game.objects().withName("Burning brazier").within(15).exists()) {
if (lastIncap == null) {
lastIncap = Instant.now();
}
} else {
lastIncap = null;
return false;
}
return lastIncap != null
&& Duration.between(lastIncap, Instant.now()).getSeconds() > config.sideTimeout()
&& plugin.getCurrentActivity() == Activity.IDLE;
}
@Override
public void execute() {
lastIncap = null;
walking.walkTo(plugin.getFurthestSide().getPositionNearBrazier());
game.tick();
}
}

View File

@ -0,0 +1,52 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Activity;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.client.plugins.iutils.scene.Position;
import javax.inject.Inject;
public class Chop extends Task {
@Inject
public Wintertodt plugin;
@Override
public boolean validate() {
if (!plugin.bossIsUp()) return false;
return plugin.getCurrentActivity() == Activity.IDLE
&& !plugin.shouldStartFeeding()
&& !plugin.shouldStartFletching()
&& plugin.getBossHealth() > 4
&& !game.inventory().full();
}
@Override
public void execute() {
Position nearRoots = plugin.getNearestSide().getPositionNearRoots();
Position nearRoots2 = new Position(nearRoots.x, nearRoots.y+1, nearRoots.z);
if (!game.localPlayer().position().equals(nearRoots) && !game.localPlayer().position().equals(nearRoots2)) {
if (calc.random(0, 10) == 5) {
walking.walkTo(nearRoots2);
} else {
walking.walkTo(nearRoots);
}
game.tick();
game.sleepDelay();
}
game.objects().withName("Bruma roots").nearestFirst().findFirst().ifPresent(roots -> {
roots.interact("Chop");
});
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.WOODCUTTING, 20);
game.tick();
}
@Override
public String getStatus() {
return "Chopping bruma roots";
}
}

View File

@ -0,0 +1,89 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Wintertodt;
import io.reisub.openosrs.wintertodt.WintertodtProjectile;
import net.runelite.client.plugins.iutils.scene.Position;
import javax.inject.Inject;
import java.time.Instant;
import java.util.Iterator;
public class DodgeProjectile extends Task {
@Inject
public Wintertodt plugin;
private WintertodtProjectile projectile;
@Override
public String getStatus() {
return "Dodging projectile";
}
@Override
public boolean validate() {
if (plugin.getProjectiles().isEmpty()) return false;
Instant now = Instant.now();
for (Iterator<WintertodtProjectile> it = plugin.getProjectiles().listIterator(); it.hasNext();) {
WintertodtProjectile p = it.next();
if (now.isAfter(p.getStart().plusSeconds(4))) {
it.remove();
continue;
}
if (p.getDamageArea().contains(game.localPlayer().position())) {
projectile = p;
return true;
}
}
return false;
}
@Override
public void execute() {
Position safePosition = findSafePosition(game.localPlayer().position());
if (safePosition != null) {
walking.walkTo(safePosition);
game.tick();
}
game.waitUntil(() -> Instant.now().isAfter(projectile.getStart().plusSeconds(4)));
game.sleepDelay();
}
private Position findSafePosition(Position startPosition) {
Position safePosition = startPosition;
while (projectile.getDamageArea().contains(safePosition)) {
safePosition = safePosition.south();
}
if (walking.reachable(safePosition)) return safePosition;
safePosition = startPosition;
while (projectile.getDamageArea().contains(safePosition)) {
safePosition = safePosition.north();
}
if (walking.reachable(safePosition)) return safePosition;
safePosition = startPosition;
while (projectile.getDamageArea().contains(safePosition)) {
safePosition = safePosition.west();
}
if (walking.reachable(safePosition)) return safePosition;
safePosition = startPosition;
while (projectile.getDamageArea().contains(safePosition)) {
safePosition = safePosition.east();
}
if (walking.reachable(safePosition)) return safePosition;
return null;
}
}

View File

@ -0,0 +1,41 @@
package io.reisub.openosrs.wintertodt.tasks;
import com.google.inject.Inject;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.api.Skill;
import static net.runelite.api.ItemID.BRUMA_KINDLING;
import static net.runelite.api.ItemID.BRUMA_ROOT;
public class EatWhileWaiting extends Task {
@Inject
public Wintertodt plugin;
@Override
public String getStatus() {
return "Eating";
}
@Override
public boolean validate() {
int missingHP = game.baseLevel(Skill.HITPOINTS) - game.modifiedLevel(Skill.HITPOINTS);
return plugin.isInWintertodtRegion()
&& (plugin.getRespawnTimer() > 0 || plugin.getBossHealth() <= 4 && !game.inventory().withId(BRUMA_ROOT, BRUMA_KINDLING).exists())
&& game.inventory().withAction("Eat", "Drink").exists()
&& missingHP > calc.random(9, 12);
}
@Override
public void execute() {
game.inventory().withAction("Eat", "Drink").findFirst().ifPresent(inventoryItem -> {
if (inventoryItem.actions().contains("Eat")) {
inventoryItem.interact("Eat");
} else {
inventoryItem.interact("Drink");
}
game.tick(calc.random(3, 5));
});
}
}

View File

@ -0,0 +1,43 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Activity;
import io.reisub.openosrs.wintertodt.Wintertodt;
import javax.inject.Inject;
public class Fix extends Task {
@Inject
public Wintertodt plugin;
@Override
public String getStatus() {
return "Fixing brazier";
}
@Override
public boolean validate() {
if (!plugin.bossIsUp()) return false;
int distance = plugin.getCurrentActivity() == Activity.IDLE ? 8 : 2;
return game.objects().within(distance).withAction("Fix").exists()
&& plugin.getCurrentActivity() != Activity.FIXING_BRAZIER;
}
@Override
public void execute() {
int distance = plugin.getCurrentActivity() == Activity.IDLE ? 8 : 2;
game.objects().within(distance).withAction("Fix").findFirst().ifPresent((brazier) -> {
brazier.interact("Fix");
game.tick();
});
if (distance == 2) {
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.FIXING_BRAZIER || !game.objects().within(distance).withAction("Fix").exists(), 3);
} else {
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.FIXING_BRAZIER || !game.objects().within(distance).withAction("Fix").exists(), 6);
}
}
}

View File

@ -0,0 +1,55 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Activity;
import io.reisub.openosrs.wintertodt.Config;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.client.plugins.iutils.scene.Position;
import javax.inject.Inject;
import static net.runelite.api.ItemID.BRUMA_ROOT;
import static net.runelite.api.ItemID.KNIFE;
public class Fletch extends Task {
@Inject
public Wintertodt plugin;
@Inject
public Config config;
@Override
public boolean validate() {
if (!plugin.bossIsUp()) return false;
if (plugin.getPreviousActivity() == Activity.WOODCUTTING && !game.inventory().full() && !plugin.shouldStartFletching()) return false;
return plugin.getCurrentActivity() == Activity.IDLE
&& !plugin.shouldStartFeeding()
&& game.inventory().withId(BRUMA_ROOT).exists();
}
@Override
public void execute() {
if (config.fletchNearBrazier()) {
Position nearBrazier = plugin.getNearestSide().getPositionNearBrazier();
if (!game.localPlayer().position().equals(nearBrazier) && !game.localPlayer().position().equals(nearBrazier.south())) {
walking.walkTo(nearBrazier);
}
}
game.tick();
game.inventory().withId(KNIFE).findFirst().ifPresent((knife) -> {
game.inventory().withId(BRUMA_ROOT).findFirst().ifPresent(knife::useOn);
});
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.FLETCHING, 5);
game.tick();
}
@Override
public String getStatus() {
return "Cutting roots into kindlings";
}
}

View File

@ -0,0 +1,56 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.api.Skill;
import net.runelite.client.plugins.iutils.game.iObject;
import net.runelite.client.plugins.iutils.scene.Position;
import javax.inject.Inject;
import static net.runelite.api.ItemID.BRUMA_KINDLING;
import static net.runelite.api.ItemID.BRUMA_ROOT;
import static net.runelite.api.ObjectID.DOORS_OF_DINH;
public class GoToBank extends Task {
@Inject
public Wintertodt plugin;
@Override
public boolean validate() {
if (!plugin.isInWintertodtRegion()) return false;
if (game.inventory().withAction("Eat", "Drink").findAny().isEmpty() && game.modifiedLevel(Skill.HITPOINTS) <= 10) return true;
return game.inventory().withAction("Eat", "Drink").count() <= 1
&& (plugin.getRespawnTimer() > 0 || (plugin.getBossHealth() <= 4 && !game.inventory().withId(BRUMA_ROOT, BRUMA_KINDLING).exists()));
}
@Override
public void execute() {
iObject doorsOfDinh = game.objects().withId(DOORS_OF_DINH).first();
if (doorsOfDinh == null) return;
Position target = new Position(1630, 3970, 0);
if (game.localPlayer().position().y > doorsOfDinh.position().y && game.localPlayer().position().distanceTo(doorsOfDinh.position()) > 8) {
walking.walkTo(target.areaWithin(calc.random(1, 9)));
game.tick();
}
game.waitUntil(() -> !plugin.bossIsUp(), 200);
doorsOfDinh.interact("Enter");
game.tick();
game.waitUntil(() -> game.localPlayer().position().y < 3965, 20);
final Position bank = new Position(1639, 3944, 0);
walking.walkTo(bank.areaWithin(calc.random(1, 4)));
game.tick();
}
@Override
public String getStatus() {
return "Going to the bank";
}
}

View File

@ -0,0 +1,60 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Config;
import io.reisub.openosrs.wintertodt.Side;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.client.plugins.iutils.game.iObject;
import net.runelite.client.plugins.iutils.scene.Area;
import net.runelite.client.plugins.iutils.scene.Position;
import javax.inject.Inject;
import static net.runelite.api.ObjectID.DOORS_OF_DINH;
public class GoToWintertodt extends Task {
@Inject
public Wintertodt plugin;
@Inject
public Config config;
@Override
public boolean validate() {
return !plugin.isInWintertodtRegion()
&& game.inventory().withAction("Eat", "Drink").count() > 1;
}
@Override
public void execute() {
iObject doorsOfDinh = game.objects().withId(DOORS_OF_DINH).first();
if (doorsOfDinh == null) return;
Position target = new Position(1630, 3962, 0);
if (game.localPlayer().position().y < doorsOfDinh.position().y && game.localPlayer().position().distanceTo(doorsOfDinh.position()) > 7) {
walking.walkTo(target.areaWithin(calc.random(1, 9)));
game.tick();
}
doorsOfDinh.interact("Enter");
game.tick();
game.waitUntil(() -> game.localPlayer().position().y > 3965, 20);
Side side = config.sideSelection();
if (plugin.getBossHealth() > 0) {
iObject roots = game.objects().withName("Bruma roots").nearest(game.localPlayer().position());
roots.interact("Chop");
} else {
final Area wintertodtSpot = plugin.getRespawnTimer() >= 5 ? side.getPositionNearBrazier() : side.getPositionNearRoots().areaWithin(1);
walking.walkTo(wintertodtSpot);
}
game.tick();
}
@Override
public String getStatus() {
return "Going to Wintertodt area";
}
}

View File

@ -0,0 +1,71 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Config;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.api.Skill;
import net.runelite.client.plugins.iutils.game.iObject;
import javax.inject.Inject;
import static net.runelite.api.ItemID.*;
public class HandleBank extends Task {
@Inject
public Wintertodt plugin;
@Inject
public Config config;
private iObject bankObj;
@Override
public boolean validate() {
bankObj = game.objects().withAction("Bank").nearest();
return !plugin.isInWintertodtRegion()
&& bank != null
&& game.localPlayer().position().distanceTo(bankObj.position()) < calc.random(5, 7)
&& (!config.openCrates() || !game.inventory().withId(SUPPLY_CRATE).exists())
&& game.inventory().withAction("Eat", "Drink").count() <= 1;
}
@Override
public void execute() {
if (!bank.isOpen()) {
bankObj.interact("Bank");
game.tick();
game.waitUntil(() -> bank.isOpen(), 15);
}
bank.depositExcept(false,
BRONZE_AXE,
IRON_AXE,
STEEL_AXE,
BLACK_AXE,
MITHRIL_AXE,
ADAMANT_AXE,
RUNE_AXE,
DRAGON_AXE,
HAMMER,
KNIFE,
TINDERBOX,
CAKE,
_23_CAKE,
SLICE_OF_CAKE,
SALMON,
RAW_KARAMBWANJI);
game.tick();
int quantity = 10 + (game.baseLevel(Skill.HITPOINTS) - game.modifiedLevel(Skill.HITPOINTS)) / 12;
bank.withdraw(SALMON, quantity, false);
game.waitUntil(() -> game.inventory().withAction("Eat", "Drink").count() > 1, 6);
}
@Override
public String getStatus() {
return "Banking";
}
}

View File

@ -0,0 +1,122 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.BossData;
import io.reisub.openosrs.wintertodt.Config;
import io.reisub.openosrs.wintertodt.Scouter;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.api.GameState;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.game.WorldService;
import net.runelite.client.util.WorldUtil;
import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldResult;
import javax.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
public class Hop extends Task {
@Inject
public Wintertodt plugin;
@Inject
public Config config;
@Inject
public Scouter scouter;
@Inject
public WorldService worldService;
private Instant lastAttempt;
@Override
public String getStatus() {
return "Hopping to other world";
}
private BossData best;
private net.runelite.api.World quickHopTargetWorld;
private int displaySwitcherAttempts = 0;
@Override
public boolean validate() {
if (!plugin.isInWintertodtRegion()) return false;
if (plugin.bossIsUp()) return false;
best = findBestWorld();
return best.getWorld() != game.client().getWorld()
&& (lastAttempt == null || Duration.between(lastAttempt, Instant.now()).getSeconds() >= 5);
}
@Override
public void execute() {
WorldResult worldResult = worldService.getWorlds();
if (worldResult == null) return;
World world = worldResult.findWorld(best.getWorld());
if (world == null) return;
final net.runelite.api.World rsWorld = game.client().createWorld();
rsWorld.setActivity(world.getActivity());
rsWorld.setAddress(world.getAddress());
rsWorld.setId(world.getId());
rsWorld.setPlayerCount(world.getPlayers());
rsWorld.setLocation(world.getLocation());
rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes()));
if (game.client().getGameState() == GameState.LOGIN_SCREEN) {
game.client().changeWorld(rsWorld);
return;
}
quickHopTargetWorld = rsWorld;
displaySwitcherAttempts = 0;
lastAttempt = Instant.now();
}
public void onGameTick() {
if (quickHopTargetWorld == null) return;
if (game.client().getWidget(WidgetInfo.WORLD_SWITCHER_LIST) == null) {
game.client().openWorldHopper();
if (++displaySwitcherAttempts >= 5) {
logWarn("Failed to hop after 5 attempts");
displaySwitcherAttempts = 0;
quickHopTargetWorld = null;
}
} else {
game.client().hopToWorld(quickHopTargetWorld);
plugin.setLastHop(Instant.now());
quickHopTargetWorld = null;
}
}
private BossData findBestWorld() {
List<BossData> dataList = scouter.getData();
BossData best = scouter.getLocalData();
for (BossData data : dataList) {
// ignore data older than 5 seconds
if (System.currentTimeMillis() - (data.getTime() * 1000) >= 5000) continue;
if (best.getHealth() > 0) {
if (data.getHealth() >= config.hopPercentage() && data.getHealth() < best.getHealth()) {
best = data;
}
} else {
if (data.getHealth() >= config.hopPercentage()) {
best = data;
} else if (data.getHealth() <= 0 && data.getTimer() < best.getTimer()) {
best = data;
}
}
}
return best;
}
}

View File

@ -0,0 +1,47 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Activity;
import io.reisub.openosrs.wintertodt.Wintertodt;
import javax.inject.Inject;
import static net.runelite.api.NpcID.INCAPACITATED_PYROMANCER;
public class Light extends Task {
@Inject
public Wintertodt plugin;
@Override
public String getStatus() {
return "Lighting the brazier";
}
@Override
public boolean validate() {
if (!plugin.isInWintertodtRegion()) return false;
int distance = plugin.getCurrentActivity() == Activity.IDLE ? 8 : 2;
return game.objects().within(distance).withAction("Light").exists()
&& (plugin.getBossHealth() > 0 || plugin.getRespawnTimer() == 0)
&& plugin.getCurrentActivity() != Activity.LIGHTING_BRAZIER
&& !game.npcs().within(6).withId(INCAPACITATED_PYROMANCER).exists();
}
@Override
public void execute() {
int distance = plugin.getCurrentActivity() == Activity.IDLE ? 8 : 2;
game.objects().within(distance).withAction("Light").findFirst().ifPresent((brazier) -> {
brazier.interact("Light");
game.tick();
});
if (distance == 2) {
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.LIGHTING_BRAZIER || !game.objects().within(distance).withAction("Light").exists(), 3);
} else {
game.waitUntil(() -> plugin.getCurrentActivity() == Activity.LIGHTING_BRAZIER || !game.objects().within(distance).withAction("Light").exists(), 6);
}
}
}

View File

@ -0,0 +1,38 @@
package io.reisub.openosrs.wintertodt.tasks;
import com.google.inject.Inject;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Activity;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.client.plugins.iutils.scene.Position;
public class MoveToBrazier extends Task {
@Inject
public Wintertodt plugin;
@Override
public String getStatus() {
return "Moving near brazier";
}
@Override
public boolean validate() {
if (!plugin.isInWintertodtRegion()) return false;
if (plugin.isTooCold()
|| (game.localPlayer().position().equals(new Position(1634, 3987, 0)) && plugin.getPreviousActivity() == Activity.FLETCHING)) {
return true;
}
return plugin.getRespawnTimer() > 0
&& !game.localPlayer().position().equals(plugin.getNearestSide().getPositionNearBrazier())
&& !game.localPlayer().isMoving();
}
@Override
public void execute() {
plugin.setTooCold(false);
walking.walkTo(plugin.getNearestSide().getPositionNearBrazier());
game.tick();
}
}

View File

@ -0,0 +1,48 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Config;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.client.plugins.iutils.game.iObject;
import javax.inject.Inject;
import static net.runelite.api.ItemID.*;
public class OpenCrates extends Task {
@Inject
public Wintertodt plugin;
@Inject
public Config config;
@Override
public boolean validate() {
iObject bankObj = game.objects().withAction("Bank").nearest();
return !plugin.isInWintertodtRegion()
&& game.localPlayer().position().distanceTo(bankObj.position()) < calc.random(5, 7)
&& config.openCrates()
&& game.inventory().withId(SUPPLY_CRATE).exists();
}
@Override
public void execute() {
game.inventory().withId(SUPPLY_CRATE).forEach((crate) -> {
crate.interact("Open");
game.tick();
game.sleepDelay();
});
game.inventory().withId(PYROMANCER_BOOTS, PYROMANCER_GARB, PYROMANCER_HOOD, PYROMANCER_ROBE).forEach((outfit) -> {
outfit.interact("Wear");
game.tick(calc.random(2, 4));
game.sleepDelay();
});
}
@Override
public String getStatus() {
return "Opening supply crates";
}
}

View File

@ -0,0 +1,32 @@
package io.reisub.openosrs.wintertodt.tasks;
import io.reisub.openosrs.util.Task;
import io.reisub.openosrs.wintertodt.Wintertodt;
import net.runelite.api.GameState;
import net.runelite.api.widgets.WidgetInfo;
import javax.inject.Inject;
public class OpenInventory extends Task {
@Inject
public Wintertodt plugin;
@Override
public String getStatus() {
return "Opening inventory";
}
@Override
public boolean validate() {
return game.client().getGameState() == GameState.LOGGED_IN
&& !bank.isOpen()
&& (game.widget(WidgetInfo.INVENTORY) == null || game.widget(WidgetInfo.INVENTORY).hidden());
}
@Override
public void execute() {
game.sleepDelay();
game.openInterface(3);
game.tick();
}
}

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 = "0.0.1"
project.extra["PluginName"] = "Chaos Wintertodt" // This is the name that is used in the external plugin manager panel
project.extra["PluginDescription"] = "Plays the Wintertodt game" // 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"]
))
}
}
}