test
3
.gitignore
vendored
@@ -6,4 +6,5 @@ build
|
||||
.classpath
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
nbproject/
|
||||
nbproject/
|
||||
bin/
|
||||
|
||||
BIN
banner_black.png
|
Before Width: | Height: | Size: 109 KiB |
BIN
banner_white.png
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 265 KiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 6.4 MiB |
|
Before Width: | Height: | Size: 733 KiB |
|
Before Width: | Height: | Size: 710 KiB |
@@ -1 +1 @@
|
||||
rootProject.name = 'easy-giantsfoundry'
|
||||
rootProject.name = 'k4rli-plugins'
|
||||
|
||||
@@ -655,6 +655,26 @@ public class BankItemWidget implements Widget {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlippedVertically() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlippedVertically(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlippedHorizontally() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlippedHorizontally(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getTextShadowed() {
|
||||
return false;
|
||||
|
||||
@@ -585,6 +585,26 @@ public class EquipmentItemWidget implements Widget {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlippedVertically() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlippedVertically(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlippedHorizontally() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlippedHorizontally(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getTextShadowed() {
|
||||
return false;
|
||||
|
||||
28
src/main/java/ee/futur/easygotr/EasyGOTRActionHint.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package ee.futur.easygotr;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Singular;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Value
|
||||
@Builder(toBuilder = true)
|
||||
public class EasyGOTRActionHint {
|
||||
EasyGOTRState state;
|
||||
String currentAction;
|
||||
String nextAction;
|
||||
@Singular
|
||||
List<String> notes;
|
||||
@Singular
|
||||
List<EasyGOTRHighlightTarget> highlights;
|
||||
|
||||
public List<String> getNotesSafe() {
|
||||
return notes == null ? Collections.emptyList() : notes;
|
||||
}
|
||||
|
||||
public List<EasyGOTRHighlightTarget> getHighlightsSafe() {
|
||||
return highlights == null ? Collections.emptyList() : highlights;
|
||||
}
|
||||
}
|
||||
@@ -55,33 +55,44 @@ public interface EasyGOTRConfig extends Config {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "collectUnchargedCells",
|
||||
name = "Collect Uncharged Cells",
|
||||
description = "When disabled, the plugin will no longer recommend picking up uncharged cells.",
|
||||
position = 6,
|
||||
section = easyGOTRConfig
|
||||
)
|
||||
default boolean collectUnchargedCells() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "keepImbueRunes",
|
||||
name = "Keep Imbue Runes",
|
||||
description = "Ignore water and fire runes when deciding to deposit runes (useful for Magic Imbue).",
|
||||
position = 7,
|
||||
section = easyGOTRConfig
|
||||
)
|
||||
default boolean keepImbueRunes() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "usePouches",
|
||||
name = "Use Essence Pouches?",
|
||||
description = "Requires NPC Contact runes in Rune Pouch or Redwood lit Lantern",
|
||||
position = 6,
|
||||
position = 8,
|
||||
section = easyGOTRConfig
|
||||
)
|
||||
default boolean usePouches() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hasBook",
|
||||
name = "Abyssal Book in bank? (IMPORTANT FOR NPC CONTACT)",
|
||||
description = "IMPORTANT TO USE NPC CONTACT",
|
||||
position = 7,
|
||||
section = easyGOTRConfig
|
||||
)
|
||||
default boolean hasBook() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "startFrags",
|
||||
name = "Starting Fragments (0 to wait for first portal)",
|
||||
description = "How many fragments you should get before leaving the starting zone",
|
||||
position = 8,
|
||||
position = 10,
|
||||
section = easyGOTRConfig
|
||||
)
|
||||
default int startingFrags() {
|
||||
|
||||
57
src/main/java/ee/futur/easygotr/EasyGOTRHighlightTarget.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package ee.futur.easygotr;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents an entity or tile that should be highlighted for the player.
|
||||
*/
|
||||
@Getter
|
||||
public class EasyGOTRHighlightTarget {
|
||||
private final TileObject tileObject;
|
||||
private final NPC npc;
|
||||
private final WorldPoint worldPoint;
|
||||
private final Color color;
|
||||
private final String label;
|
||||
|
||||
private EasyGOTRHighlightTarget(TileObject tileObject, NPC npc, WorldPoint worldPoint, Color color, String label) {
|
||||
this.tileObject = tileObject;
|
||||
this.npc = npc;
|
||||
this.worldPoint = worldPoint;
|
||||
this.color = color;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static EasyGOTRHighlightTarget forTileObject(TileObject tileObject, Color color, String label) {
|
||||
return new EasyGOTRHighlightTarget(tileObject, null, null, color, label);
|
||||
}
|
||||
|
||||
public static EasyGOTRHighlightTarget forNpc(NPC npc, Color color, String label) {
|
||||
return new EasyGOTRHighlightTarget(null, npc, null, color, label);
|
||||
}
|
||||
|
||||
public static EasyGOTRHighlightTarget forWorldPoint(WorldPoint worldPoint, Color color, String label) {
|
||||
return new EasyGOTRHighlightTarget(null, null, worldPoint, color, label);
|
||||
}
|
||||
|
||||
public Optional<TileObject> getTileObjectOptional() {
|
||||
return Optional.ofNullable(tileObject);
|
||||
}
|
||||
|
||||
public Optional<NPC> getNpcOptional() {
|
||||
return Optional.ofNullable(npc);
|
||||
}
|
||||
|
||||
public Optional<WorldPoint> getWorldPointOptional() {
|
||||
return Optional.ofNullable(worldPoint);
|
||||
}
|
||||
|
||||
public Color getColorOrDefault(Color defaultColor) {
|
||||
return color != null ? color : defaultColor;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ public class EasyGOTROverlay extends OverlayPanel {
|
||||
private final Client client;
|
||||
private final EasyGOTRPlugin plugin;
|
||||
public String overlayState = "";
|
||||
private EasyGOTRActionHint hint;
|
||||
|
||||
@Inject
|
||||
private EasyGOTROverlay(Client client, EasyGOTRPlugin plugin) {
|
||||
@@ -24,8 +25,13 @@ public class EasyGOTROverlay extends OverlayPanel {
|
||||
setPosition(OverlayPosition.BOTTOM_LEFT);
|
||||
}
|
||||
|
||||
public void setHint(EasyGOTRActionHint hint) {
|
||||
this.hint = hint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
panelComponent.getChildren().clear();
|
||||
String timeFormat = (plugin.runningDuration.toHours() < 1) ? "mm:ss" : "HH:mm:ss";
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("EasyGOTR")
|
||||
@@ -63,6 +69,71 @@ public class EasyGOTROverlay extends OverlayPanel {
|
||||
.right(String.valueOf(plugin.riftState.hasFirstPortalSpawned))
|
||||
.rightColor(Color.WHITE)
|
||||
.build());
|
||||
|
||||
plugin.getPortalTimerText().ifPresent(timer -> panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Portal:")
|
||||
.leftColor(Color.WHITE)
|
||||
.right(timer)
|
||||
.rightColor(Color.WHITE)
|
||||
.build()));
|
||||
|
||||
plugin.getPortalTimingSummary().ifPresent(summary -> panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Portal Timing:")
|
||||
.leftColor(Color.WHITE)
|
||||
.right(summary)
|
||||
.rightColor(Color.WHITE)
|
||||
.build()));
|
||||
|
||||
plugin.getMainTimerText().ifPresent(mainTimer -> panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Main Timer:")
|
||||
.leftColor(Color.WHITE)
|
||||
.right(mainTimer)
|
||||
.rightColor(Color.WHITE)
|
||||
.build()));
|
||||
|
||||
plugin.getNextAltarName().ifPresent(name -> panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Next Altar:")
|
||||
.leftColor(Color.WHITE)
|
||||
.right(name)
|
||||
.rightColor(Color.WHITE)
|
||||
.build()));
|
||||
|
||||
plugin.getEnergySummary().ifPresent(summary -> panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Energy:")
|
||||
.leftColor(Color.WHITE)
|
||||
.right(summary)
|
||||
.rightColor(Color.WHITE)
|
||||
.build()));
|
||||
|
||||
EasyGOTRActionHint localHint = hint;
|
||||
if (localHint != null) {
|
||||
if (localHint.getCurrentAction() != null && !localHint.getCurrentAction().isEmpty()) {
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Current:")
|
||||
.leftColor(Color.WHITE)
|
||||
.right(localHint.getCurrentAction())
|
||||
.rightColor(Color.WHITE)
|
||||
.build());
|
||||
}
|
||||
if (localHint.getNextAction() != null && !localHint.getNextAction().isEmpty()) {
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Next:")
|
||||
.leftColor(Color.WHITE)
|
||||
.right(localHint.getNextAction())
|
||||
.rightColor(Color.WHITE)
|
||||
.build());
|
||||
}
|
||||
|
||||
for (String note : localHint.getNotesSafe()) {
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Tip:")
|
||||
.leftColor(Color.LIGHT_GRAY)
|
||||
.right(note)
|
||||
.rightColor(Color.LIGHT_GRAY)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
panelComponent.setPreferredSize(new Dimension(250, 250));
|
||||
}
|
||||
return super.render(graphics);
|
||||
|
||||
@@ -4,11 +4,11 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provides;
|
||||
import ee.futur.baseapi.BaseApiPlugin;
|
||||
import ee.futur.baseapi.collections.*;
|
||||
import ee.futur.baseapi.collections.query.TileObjectQuery;
|
||||
import ee.futur.baseapi.BaseApiPlugin;
|
||||
import ee.futur.easygotr.data.CellMapper;
|
||||
import ee.futur.easygotr.data.Constants;
|
||||
import ee.futur.easygotr.data.GOTRGameConstants;
|
||||
import ee.futur.utils.InventoryUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.*;
|
||||
@@ -23,11 +23,14 @@ import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.HotkeyListener;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@PluginDescriptor(
|
||||
@@ -45,6 +48,8 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
@Inject
|
||||
private EasyGOTROverlay overlay;
|
||||
@Inject
|
||||
private EasyGOTRSceneOverlay sceneOverlay;
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
@@ -103,12 +108,14 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
ItemID.CRYSTAL_PICKAXE_INACTIVE,
|
||||
ItemID.INFERNAL_PICKAXE_OR);
|
||||
private final List<Integer> PoweredCellList = ImmutableList.of(ItemID.WEAK_CELL, ItemID.OVERCHARGED_CELL, ItemID.STRONG_CELL, ItemID.MEDIUM_CELL);
|
||||
private static final Duration PORTAL_ACTIVE_DURATION = Duration.ofMillis(43L * 600);
|
||||
public boolean started = false;
|
||||
public int timeout = 0;
|
||||
private boolean startingRun = false;
|
||||
private boolean needsMoreStartingFragments = false;
|
||||
|
||||
private boolean canEnterBarrier = false;
|
||||
private EasyGOTRActionHint currentHint;
|
||||
|
||||
@Provides
|
||||
private EasyGOTRConfig getConfig(ConfigManager configManager) {
|
||||
@@ -119,30 +126,44 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
protected void startUp() throws Exception {
|
||||
keyManager.registerKeyListener(toggle);
|
||||
overlayManager.add(overlay);
|
||||
overlayManager.add(sceneOverlay);
|
||||
timeout = 0;
|
||||
timer = Instant.now();
|
||||
pouchManager.register();
|
||||
riftState.register();
|
||||
currentHint = null;
|
||||
overlay.setHint(null);
|
||||
sceneOverlay.setHint(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
keyManager.unregisterKeyListener(toggle);
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(sceneOverlay);
|
||||
pouchManager.deregister();
|
||||
riftState.deregister();
|
||||
timeout = 0;
|
||||
toggle();
|
||||
timer = Instant.now();
|
||||
currentHint = null;
|
||||
overlay.setHint(null);
|
||||
sceneOverlay.setHint(null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameTick(GameTick event) {
|
||||
if (timeout > 0) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
if (client.getGameState() != GameState.LOGGED_IN || !started) {
|
||||
|
||||
if (!started) {
|
||||
overlay.setHint(null);
|
||||
sceneOverlay.setHint(null);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,22 +182,11 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
runningDuration = runningDuration.plus(Duration.between(timer, Instant.now()));
|
||||
timer = Instant.now();
|
||||
|
||||
if (Inventory.full()
|
||||
&& config.usePouches()
|
||||
&& pouchManager.hasEmptyPouches()
|
||||
&& Inventory.getItemAmount(ItemID.GUARDIAN_ESSENCE) > 0
|
||||
&& !riftState.isInAltar()) {
|
||||
pouchManager.fillPouches();
|
||||
if (riftState.isInHugeMine()) {
|
||||
mineHugeGuardians();
|
||||
} else {
|
||||
craftEssence();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
EasyGOTRState state = getState();
|
||||
overlay.overlayState = state.toString();
|
||||
overlay.overlayState = formatStateName(state);
|
||||
currentHint = buildHint(state);
|
||||
overlay.setHint(currentHint);
|
||||
sceneOverlay.setHint(currentHint);
|
||||
|
||||
if (BaseApiPlugin.isMoving()) {
|
||||
//Attempt to put runes in pouch where possible
|
||||
@@ -204,70 +214,11 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case WAITING_FOR_GAME:
|
||||
waitForGame();
|
||||
break;
|
||||
case MOVE_TO_EAST_MINE:
|
||||
case LEAVE_EAST_MINE:
|
||||
climbLargeMine();
|
||||
break;
|
||||
case ENTER_PORTAL:
|
||||
enterPortal();
|
||||
break;
|
||||
case LEAVE_ALTAR:
|
||||
exitAltar();
|
||||
break;
|
||||
case GET_CELLS:
|
||||
getCells();
|
||||
break;
|
||||
case CRAFT_ESSENCE:
|
||||
craftEssence();
|
||||
break;
|
||||
case REPAIR_POUCH:
|
||||
repairPouch();
|
||||
break;
|
||||
case POWER_GUARDIAN:
|
||||
powerGuardian();
|
||||
break;
|
||||
case MINE_HUGE_GUARDIANS:
|
||||
mineHugeGuardians();
|
||||
break;
|
||||
case MINE_LARGE_GUARDIANS:
|
||||
mineLargeGuardians();
|
||||
break;
|
||||
case MINE_REGULAR_GUARDIANS:
|
||||
mineGameGuardians();
|
||||
break;
|
||||
case CRAFTING_ESSENCE:
|
||||
break;
|
||||
case DEPOSIT_RUNES:
|
||||
depositRunes();
|
||||
break;
|
||||
case USE_CELL:
|
||||
usePowerCell();
|
||||
break;
|
||||
case CRAFT_RUNES:
|
||||
craftRunes();
|
||||
break;
|
||||
case ENTER_ALTAR:
|
||||
enterRift();
|
||||
break;
|
||||
case ENTER_GAME:
|
||||
enterGame();
|
||||
break;
|
||||
case GAME_BUSY:
|
||||
gameBusy();
|
||||
break;
|
||||
case BREAK:
|
||||
// @TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private EasyGOTRState getState() {
|
||||
if (config.startingFrags() > 0 && getFragmentCount() > config.startingFrags()) {
|
||||
needsMoreStartingFragments = false;
|
||||
if (config.startingFrags() > 0) {
|
||||
needsMoreStartingFragments = getFragmentCount() > config.startingFrags();
|
||||
} else if (config.startingFrags() == 0) {
|
||||
needsMoreStartingFragments = true;
|
||||
}
|
||||
@@ -340,7 +291,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
return EasyGOTRState.POWER_GUARDIAN;
|
||||
}
|
||||
|
||||
if (hasPowerCell()) {
|
||||
if (config.collectUnchargedCells() && hasPowerCell()) {
|
||||
return EasyGOTRState.USE_CELL;
|
||||
}
|
||||
|
||||
@@ -351,7 +302,11 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
return EasyGOTRState.CRAFTING_ESSENCE;
|
||||
}
|
||||
|
||||
if (getCellCount() == 0) {
|
||||
if (hasPowerEssence()) {
|
||||
return EasyGOTRState.POWER_GUARDIAN;
|
||||
}
|
||||
|
||||
if (config.collectUnchargedCells() && getCellCount() == 0) {
|
||||
return EasyGOTRState.GET_CELLS;
|
||||
}
|
||||
|
||||
@@ -386,7 +341,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
return EasyGOTRState.POWER_GUARDIAN;
|
||||
}
|
||||
|
||||
if (hasPowerCell()) {
|
||||
if (config.collectUnchargedCells() && hasPowerCell()) {
|
||||
return EasyGOTRState.USE_CELL;
|
||||
}
|
||||
|
||||
@@ -423,7 +378,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
if (riftState.isInLargeMine()) {
|
||||
if (hasPowerCell()) {
|
||||
if (config.collectUnchargedCells() && hasPowerCell()) {
|
||||
Inventory.search().idInList(PoweredCellList).first().ifPresent(widget -> {
|
||||
//InventoryInteraction.useItem(widget, "Drop");
|
||||
});
|
||||
@@ -437,7 +392,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
|
||||
//If we get here, we're probably walking to east from the portal.
|
||||
//Make a quick stop at cells if we need too
|
||||
if (getCellCount() < 10) {
|
||||
if (config.collectUnchargedCells() && getCellCount() < 10) {
|
||||
return EasyGOTRState.GET_CELLS;
|
||||
}
|
||||
|
||||
@@ -463,11 +418,15 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
return EasyGOTRState.LEAVE_ALTAR;
|
||||
}
|
||||
|
||||
if (hasPowerEssence()) {
|
||||
return EasyGOTRState.POWER_GUARDIAN;
|
||||
}
|
||||
|
||||
if (getInventoryRunes().isPresent()) {
|
||||
return EasyGOTRState.DEPOSIT_RUNES;
|
||||
}
|
||||
|
||||
if (getCellCount() < 10) {
|
||||
if (config.collectUnchargedCells() && getCellCount() < 10) {
|
||||
return EasyGOTRState.GET_CELLS;
|
||||
}
|
||||
|
||||
@@ -479,7 +438,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private void waitForGame() {
|
||||
if (client.getLocalPlayer().getWorldLocation().getX() == Constants.LARGE_MINE_X) {
|
||||
if (client.getLocalPlayer().getWorldLocation().getX() == GOTRGameConstants.LARGE_MINE_X) {
|
||||
if (tickDelay() % 2 == 0) {
|
||||
//MousePackets.queueClickPacket();
|
||||
//MovementPackets.queueMovement(3639, 9500, false);
|
||||
@@ -549,6 +508,10 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private void getCells() {
|
||||
if (!config.collectUnchargedCells()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Inventory.full() && Inventory.getItemAmount(ItemID.UNCHARGED_CELL) == 0) {
|
||||
Inventory.search().withId(ItemID.GUARDIAN_ESSENCE).first().ifPresent(widget -> {
|
||||
//InventoryInteraction.useItem(widget, "Drop");
|
||||
@@ -567,7 +530,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
|
||||
private void craftEssence() {
|
||||
if (riftState.isGameStarted()) {
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(Constants.WORKBENCH).nearestToPlayer();
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(GOTRGameConstants.WORKBENCH).nearestToPlayer();
|
||||
if (tileObject.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -578,7 +541,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private void mineHugeGuardians() {
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(Constants.HUGE_REMAINS).nearestToPlayer();
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(GOTRGameConstants.HUGE_REMAINS).nearestToPlayer();
|
||||
if (tileObject.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -594,7 +557,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
});
|
||||
}
|
||||
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(Constants.LARGE_REMAINS).nearestToPlayer();
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(GOTRGameConstants.LARGE_REMAINS).nearestToPlayer();
|
||||
if (tileObject.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -606,11 +569,13 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private Optional<Widget> getInventoryRunes() {
|
||||
return Inventory.search().idInList(RuneList).first();
|
||||
return Inventory.search().idInList(RuneList)
|
||||
.filter(widget -> !isProtectedImbueRune(widget.getItemId()))
|
||||
.first();
|
||||
}
|
||||
|
||||
private void mineGameGuardians() {
|
||||
Optional<TileObject> tileObject = nameContainsNoCase(Constants.GAME_PARTS).nearestToPlayer();
|
||||
Optional<TileObject> tileObject = nameContainsNoCase(GOTRGameConstants.GAME_PARTS).nearestToPlayer();
|
||||
if (tileObject.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -635,7 +600,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
if (RandomUtils.nextInt(0, 100) == 30) {
|
||||
TileObjects.search().withId(Constants.BARRIER_BUSY_ID).first().ifPresent(tileObject -> {
|
||||
TileObjects.search().withId(GOTRGameConstants.BARRIER_BUSY_ID).first().ifPresent(tileObject -> {
|
||||
// TileObjectInteraction.interact(tileObject, "Peek");
|
||||
});
|
||||
}
|
||||
@@ -686,6 +651,9 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
|
||||
//breakHandler.startPlugin(this);
|
||||
} else {
|
||||
currentHint = null;
|
||||
overlay.setHint(null);
|
||||
sceneOverlay.setHint(null);
|
||||
//breakHandler.stopPlugin(this);
|
||||
}
|
||||
}
|
||||
@@ -716,6 +684,390 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", message, null);
|
||||
}
|
||||
|
||||
private EasyGOTRActionHint buildHint(EasyGOTRState state) {
|
||||
EasyGOTRActionHint.EasyGOTRActionHintBuilder builder = EasyGOTRActionHint.builder()
|
||||
.state(state);
|
||||
|
||||
switch (state) {
|
||||
case WAITING_FOR_GAME:
|
||||
builder.currentAction("Wait in the lobby for the next round.");
|
||||
builder.nextAction("Quick-pass the barrier when it opens.");
|
||||
findBarrier().ifPresent(barrier ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(barrier, Color.YELLOW, "Barrier")));
|
||||
break;
|
||||
case MOVE_TO_EAST_MINE:
|
||||
builder.currentAction("Head down into the east mine.");
|
||||
builder.nextAction("Mine the highlighted remains for fragments.");
|
||||
findClimbableRubble().ifPresent(rubble ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(rubble, Color.ORANGE, "Climb down")));
|
||||
break;
|
||||
case LEAVE_EAST_MINE:
|
||||
builder.currentAction("Leave the east mine.");
|
||||
builder.nextAction("Return to crafting or enter the portal.");
|
||||
findClimbableRubble().ifPresent(rubble ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(rubble, Color.ORANGE, "Climb up")));
|
||||
break;
|
||||
case ENTER_PORTAL:
|
||||
builder.currentAction("Enter the guardian portal.");
|
||||
builder.nextAction("Continue with the highlighted activity in the temple.");
|
||||
findPortal().ifPresent(portal ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(portal, Color.MAGENTA, "Enter portal")));
|
||||
break;
|
||||
case ENTER_GAME:
|
||||
builder.currentAction("Quick-pass the barrier to join the round.");
|
||||
builder.nextAction("Move to the mine once inside.");
|
||||
findBarrier().ifPresent(barrier ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(barrier, Color.YELLOW, "Quick-pass")));
|
||||
break;
|
||||
case GAME_BUSY:
|
||||
builder.currentAction("Wait by the barrier until the game opens.");
|
||||
builder.nextAction("Quick-pass the barrier as soon as it is available.");
|
||||
findBarrier().ifPresent(barrier ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(barrier, Color.YELLOW, "Barrier")));
|
||||
builder.note("Combine your fragments and prepare while you wait.");
|
||||
break;
|
||||
case GET_CELLS:
|
||||
if (config.collectUnchargedCells()) {
|
||||
builder.currentAction("Take uncharged cells from the table.");
|
||||
builder.nextAction("Craft guardian essence at the workbench.");
|
||||
findUnchargedCells().ifPresent(cells ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(cells, Color.CYAN, "Take cells")));
|
||||
} else {
|
||||
builder.currentAction("Cell collection disabled in config.");
|
||||
builder.nextAction("Continue with your current rotation.");
|
||||
builder.note("Enable \"Collect Uncharged Cells\" to receive guidance here.");
|
||||
}
|
||||
break;
|
||||
case CRAFT_ESSENCE:
|
||||
case CRAFTING_ESSENCE:
|
||||
builder.currentAction("Use the workbench to make guardian essence.");
|
||||
builder.nextAction("Refill pouches or mine more fragments when done.");
|
||||
findWorkbench().ifPresent(workbench ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(workbench, Color.CYAN, "Work-at")));
|
||||
break;
|
||||
case REPAIR_POUCH:
|
||||
builder.currentAction("Repair your pouches via NPC Contact (Dark Mage).");
|
||||
builder.nextAction("Resume mining once pouches are fixed.");
|
||||
builder.note("Ensure you have NPC Contact runes or a rune pouch ready.");
|
||||
break;
|
||||
case POWER_GUARDIAN:
|
||||
builder.currentAction("Use stones on the Great Guardian.");
|
||||
builder.nextAction("Enter the highlighted altar afterwards.");
|
||||
findGreatGuardian().ifPresent(guardian ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forNpc(guardian, Color.GREEN, "Power Guardian")));
|
||||
break;
|
||||
case MINE_HUGE_GUARDIANS:
|
||||
case MINING:
|
||||
if (riftState.isInHugeMine()) {
|
||||
builder.currentAction("Mine the huge guardian remains.");
|
||||
builder.nextAction("Enter the portal when your inventory is full.");
|
||||
findHugeRemains().ifPresent(remains ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Mine")));
|
||||
} else if (riftState.isInLargeMine()) {
|
||||
builder.currentAction("Mine the large guardian remains.");
|
||||
builder.nextAction("Craft essence at the workbench after mining.");
|
||||
findLargeRemains().ifPresent(remains ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Mine")));
|
||||
} else {
|
||||
builder.currentAction("Mine guardian remains in the temple.");
|
||||
builder.nextAction("Craft essence once you have enough fragments.");
|
||||
findRegularRemains().ifPresent(remains ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Mine")));
|
||||
}
|
||||
break;
|
||||
case MINE_LARGE_GUARDIANS:
|
||||
builder.currentAction("Mine the large guardian remains.");
|
||||
builder.nextAction("Return to the workbench to craft essence.");
|
||||
findLargeRemains().ifPresent(remains ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Mine")));
|
||||
break;
|
||||
case MINE_REGULAR_GUARDIANS:
|
||||
builder.currentAction("Mine guardian remains in the temple.");
|
||||
builder.nextAction("Craft essence at the workbench once ready.");
|
||||
findRegularRemains().ifPresent(remains ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Mine")));
|
||||
break;
|
||||
case DEPOSIT_RUNES:
|
||||
builder.currentAction("Deposit your crafted runes.");
|
||||
builder.nextAction("Return to mining or crafting essence.");
|
||||
findDepositPool().ifPresent(pool ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(pool, Color.CYAN, "Deposit")));
|
||||
break;
|
||||
case USE_CELL:
|
||||
builder.currentAction("Place a charged cell on the highlighted tile.");
|
||||
builder.nextAction("Power the guardian or prepare for the next altar.");
|
||||
Inventory.search().idInList(PoweredCellList).first()
|
||||
.ifPresent(widget -> builder.note("Cell tier: " + getCellTierName(CellMapper.GetCellTier(widget.getItemId()))));
|
||||
determineCellPlacement().ifPresent(builder::highlight);
|
||||
break;
|
||||
case CRAFT_RUNES:
|
||||
builder.currentAction("Craft runes at the active altar.");
|
||||
builder.nextAction("Exit back to the temple once finished.");
|
||||
findCraftingAltar().ifPresent(altar ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(altar, Color.GREEN, "Craft-rune")));
|
||||
break;
|
||||
case LEAVE_ALTAR:
|
||||
builder.currentAction("Exit the altar to return to the temple.");
|
||||
builder.nextAction("Deposit runes or power the guardian.");
|
||||
findPortal().ifPresent(portal ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(portal, Color.MAGENTA, "Use portal")));
|
||||
break;
|
||||
case ENTER_ALTAR:
|
||||
builder.currentAction("Enter the highlighted guardian portal.");
|
||||
builder.nextAction("Craft runes inside the altar.");
|
||||
Optional<TileObject> nextAltar = Optional.ofNullable(riftState.getNextAltar());
|
||||
nextAltar.ifPresent(altar ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(altar, Color.GREEN, "Enter altar")));
|
||||
if (nextAltar.isEmpty()) {
|
||||
builder.note("Wait for a guardian to become active.");
|
||||
}
|
||||
break;
|
||||
case BREAK:
|
||||
builder.currentAction("Idle until the next round begins.");
|
||||
builder.nextAction("Move to the barrier when a game starts.");
|
||||
builder.note("Gather fragments or restock supplies while waiting.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (getInventoryRunes().isPresent() && config.dropRunes()) {
|
||||
builder.note("Drop leftover runes to free space (per config).");
|
||||
}
|
||||
|
||||
if (config.usePouches() && pouchManager.hasDegradedPouches()) {
|
||||
builder.note("Repair pouches before continuing.");
|
||||
}
|
||||
|
||||
int essence = Inventory.getItemAmount(ItemID.GUARDIAN_ESSENCE);
|
||||
if (essence == 0 && getFragmentCount() < neededFrags() && !riftState.isInAltar()) {
|
||||
builder.note("Mine fragments until you can craft more essence.");
|
||||
}
|
||||
|
||||
if (riftState.getNextAltar() != null) {
|
||||
builder.note("Next altar: " + getObjectName(riftState.getNextAltar()));
|
||||
}
|
||||
|
||||
getInventoryRunes().ifPresent(runeWidget -> {
|
||||
if (getRunePouch().isPresent() && canDepositRune(runeWidget.getItemId())) {
|
||||
builder.note("Store spare runes in your rune pouch (click rune \u2192 pouch).");
|
||||
}
|
||||
});
|
||||
|
||||
EasyGOTRActionHint hint = builder.build();
|
||||
if (hint.getCurrentAction() == null || hint.getCurrentAction().isEmpty()) {
|
||||
return hint.toBuilder().currentAction("Track the highlighted targets.").build();
|
||||
}
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
private Optional<EasyGOTRHighlightTarget> determineCellPlacement() {
|
||||
if (!config.collectUnchargedCells()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Optional<Widget> optCell = Inventory.search().idInList(PoweredCellList).first();
|
||||
if (optCell.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Widget cell = optCell.get();
|
||||
TileObject nextAltar = riftState.getNextAltar();
|
||||
int cellTier = CellMapper.GetCellTier(cell.getItemId());
|
||||
List<TileObject> shieldCells = TileObjects.search().nameContains("cell tile").result();
|
||||
for (TileObject tile : shieldCells) {
|
||||
if (CellMapper.GetShieldTier(tile.getId()) < cellTier) {
|
||||
return Optional.of(EasyGOTRHighlightTarget.forTileObject(tile, Color.CYAN, "Upgrade shield"));
|
||||
}
|
||||
}
|
||||
|
||||
if (nextAltar == null) {
|
||||
Optional<NPC> bestBarrier = NPCs.search()
|
||||
.filter(x -> x.getId() <= 11425 && x.getId() >= 11418)
|
||||
.result().stream().min(Comparator.comparingDouble(this::getBarrierHealth));
|
||||
if (bestBarrier.isPresent()) {
|
||||
Optional<TileObject> tile = TileObjects.search().nameContains("cell tile").nearestToPoint(bestBarrier.get().getWorldLocation());
|
||||
if (tile.isPresent()) {
|
||||
return Optional.of(EasyGOTRHighlightTarget.forTileObject(tile.get(), Color.CYAN, "Support barrier"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Optional<NPC> damagedBarrier = NPCs.search()
|
||||
.filter(x -> x.getId() <= 11425 && x.getId() >= 11418 && getBarrierHealth(x) <= 50)
|
||||
.first();
|
||||
if (damagedBarrier.isPresent()) {
|
||||
Optional<TileObject> tile = TileObjects.search().nameContains("cell tile").nearestToPoint(damagedBarrier.get().getWorldLocation());
|
||||
if (tile.isPresent()) {
|
||||
return Optional.of(EasyGOTRHighlightTarget.forTileObject(tile.get(), Color.CYAN, "Repair barrier"));
|
||||
}
|
||||
}
|
||||
|
||||
Optional<NPC> bestBarrier = NPCs.search()
|
||||
.filter(x -> x.getId() <= 11425 && x.getId() >= 11418)
|
||||
.result().stream().min(Comparator.comparingInt(x -> x.getWorldLocation().distanceTo(nextAltar.getWorldLocation())));
|
||||
|
||||
if (bestBarrier.isPresent()) {
|
||||
Optional<TileObject> tile = TileObjects.search().nameContains("cell tile").nearestToPoint(bestBarrier.get().getWorldLocation());
|
||||
if (tile.isPresent()) {
|
||||
return Optional.of(EasyGOTRHighlightTarget.forTileObject(tile.get(), Color.CYAN, "Boost shield"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private String getCellTierName(int tier) {
|
||||
switch (tier) {
|
||||
case 1:
|
||||
return "Weak";
|
||||
case 2:
|
||||
return "Medium";
|
||||
case 3:
|
||||
return "Strong";
|
||||
case 4:
|
||||
return "Overcharged";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
private String getObjectName(TileObject tileObject) {
|
||||
ObjectComposition composition = TileObjectQuery.getObjectComposition(tileObject);
|
||||
if (composition == null) {
|
||||
return "Unknown";
|
||||
}
|
||||
return composition.getName();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findClimbableRubble() {
|
||||
return TileObjects.search().withAction("Climb").nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findPortal() {
|
||||
return nameContainsNoCase(GOTRGameConstants.PORTAL).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findWorkbench() {
|
||||
return TileObjects.search().nameContains(GOTRGameConstants.WORKBENCH).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findHugeRemains() {
|
||||
return TileObjects.search().nameContains(GOTRGameConstants.HUGE_REMAINS).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findLargeRemains() {
|
||||
return TileObjects.search().nameContains(GOTRGameConstants.LARGE_REMAINS).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findRegularRemains() {
|
||||
return nameContainsNoCase(GOTRGameConstants.GAME_PARTS).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findDepositPool() {
|
||||
return TileObjects.search().nameContains(GOTRGameConstants.DEPOSIT_POOL).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findUnchargedCells() {
|
||||
return TileObjects.search().nameContains(GOTRGameConstants.UNCHARGED_CELLS).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findCraftingAltar() {
|
||||
return TileObjects.search().withAction(GOTRGameConstants.CRAFT_RUNES).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<TileObject> findBarrier() {
|
||||
return TileObjects.search().withName(GOTRGameConstants.BARRIER).nearestToPlayer();
|
||||
}
|
||||
|
||||
private Optional<NPC> findGreatGuardian() {
|
||||
return NPCs.search().nameContains(GOTRGameConstants.GREAT_GUARDIAN).nearestToPlayer();
|
||||
}
|
||||
|
||||
private String formatStateName(EasyGOTRState state) {
|
||||
String name = state.name().toLowerCase(Locale.ROOT).replace('_', ' ');
|
||||
if (name.isEmpty()) {
|
||||
return name;
|
||||
}
|
||||
return Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
||||
}
|
||||
|
||||
public Optional<String> getPortalTimerText() {
|
||||
Widget portalWidget = client.getWidget(GOTRGameConstants.PORTAL_TIMER);
|
||||
if (portalWidget == null || portalWidget.isHidden()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String rawText = portalWidget.getText();
|
||||
if (rawText == null || rawText.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String clean = Text.removeTags(rawText).trim();
|
||||
return clean.isEmpty() ? Optional.empty() : Optional.of(clean);
|
||||
}
|
||||
|
||||
public Optional<String> getPortalTimingSummary() {
|
||||
Instant now = Instant.now();
|
||||
if (riftState.isPortalSpawned()) {
|
||||
return riftState.getPortalSpawnTime().map(spawn -> {
|
||||
long sinceMillis = Math.max(0L, Duration.between(spawn, now).toMillis());
|
||||
long remainingMillis = Math.max(0L, PORTAL_ACTIVE_DURATION.toMillis() - sinceMillis);
|
||||
double sinceSeconds = sinceMillis / 1000d;
|
||||
double remainingSeconds = remainingMillis / 1000d;
|
||||
return String.format("Open %.1fs (closes in %.1fs)", sinceSeconds, remainingSeconds);
|
||||
});
|
||||
}
|
||||
|
||||
return riftState.getLastPortalCloseTime().map(close -> {
|
||||
long sinceMillis = Math.max(0L, Duration.between(close, now).toMillis());
|
||||
double sinceSeconds = sinceMillis / 1000d;
|
||||
return String.format("Closed %.1fs ago", sinceSeconds);
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<String> getMainTimerText() {
|
||||
Widget mainTimer = client.getWidget(GOTRGameConstants.MAIN_TIMER);
|
||||
if (mainTimer == null || mainTimer.isHidden()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String text = Text.removeTags(mainTimer.getText()).trim();
|
||||
return text.isEmpty() ? Optional.empty() : Optional.of(text);
|
||||
}
|
||||
|
||||
public Optional<String> getNextAltarName() {
|
||||
TileObject next = riftState.getNextAltar();
|
||||
if (next == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String name = getObjectName(next);
|
||||
if (name == null || name.isEmpty() || "Unknown".equals(name)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(name);
|
||||
}
|
||||
|
||||
public Optional<String> getEnergySummary() {
|
||||
int elemental = riftState.getElementalPoints();
|
||||
int catalytic = riftState.getCatalyticPoints();
|
||||
if (elemental < 0 || catalytic < 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String summary = String.format("E: %,d | C: %,d", elemental, catalytic);
|
||||
return Optional.of(summary);
|
||||
}
|
||||
|
||||
private boolean isProtectedImbueRune(int itemId) {
|
||||
if (!config.keepImbueRunes()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return itemId == ItemID.WATER_RUNE || itemId == ItemID.FIRE_RUNE;
|
||||
}
|
||||
|
||||
private boolean hasRuneAmount(int runeId, int amount) {
|
||||
return (client.getVarbitValue(Varbits.RUNE_POUCH_RUNE1) == runeId
|
||||
&& client.getVarbitValue(Varbits.RUNE_POUCH_AMOUNT1) >= amount)
|
||||
@@ -758,7 +1110,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
if (BaseApiPlugin.isMoving()) {
|
||||
return;
|
||||
}
|
||||
Optional<TileObject> tileObject = nameContainsNoCase(Constants.PORTAL).filter(to -> to.getWorldLocation().getY() >= Constants.OUTSIDE_BARRIER_Y).nearestToPlayer();
|
||||
Optional<TileObject> tileObject = nameContainsNoCase(GOTRGameConstants.PORTAL).filter(to -> to.getWorldLocation().getY() >= GOTRGameConstants.OUTSIDE_BARRIER_Y).nearestToPlayer();
|
||||
if (tileObject.isEmpty()) {
|
||||
//MousePackets.queueClickPacket();
|
||||
//MovementPackets.queueMovement(new WorldPoint(3615, 9499, 0));
|
||||
@@ -775,7 +1127,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
if (BaseApiPlugin.isMoving()) {
|
||||
return;
|
||||
}
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(Constants.PORTAL).nearestToPlayer();
|
||||
Optional<TileObject> tileObject = TileObjects.search().nameContains(GOTRGameConstants.PORTAL).nearestToPlayer();
|
||||
if (tileObject.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -786,7 +1138,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private void powerGuardian() {
|
||||
Optional<NPC> npc = NPCs.search().nameContains(Constants.GREAT_GUARDIAN).nearestToPlayer();
|
||||
Optional<NPC> npc = NPCs.search().nameContains(GOTRGameConstants.GREAT_GUARDIAN).nearestToPlayer();
|
||||
if (npc.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -905,7 +1257,10 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
String[] runeFilterConfig = config.dropRunesFilter().split(",");
|
||||
for (String rune : runeFilterConfig) {
|
||||
rune = rune.trim();
|
||||
Inventory.search().matchesWildCardNoCase(rune).first().ifPresent(runesToDrop::add);
|
||||
Inventory.search().matchesWildCardNoCase(rune)
|
||||
.first()
|
||||
.filter(widget -> !isProtectedImbueRune(widget.getItemId()))
|
||||
.ifPresent(runesToDrop::add);
|
||||
}
|
||||
return runesToDrop;
|
||||
}
|
||||
@@ -916,7 +1271,10 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
if (config.dropRunes()) {
|
||||
Optional<Widget> itemWidget = InventoryUtil.nameContainsNoCase("rune").filter(item -> !item.getName().contains("pickaxe")).first();
|
||||
Optional<Widget> itemWidget = InventoryUtil.nameContainsNoCase("rune")
|
||||
.filter(item -> !item.getName().contains("pickaxe"))
|
||||
.filter(item -> !isProtectedImbueRune(item.getItemId()))
|
||||
.first();
|
||||
if (itemWidget.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -939,7 +1297,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private void craftRunes() {
|
||||
Optional<TileObject> tileObject = TileObjects.search().withAction(Constants.CRAFT_RUNES).nearestToPlayer();
|
||||
Optional<TileObject> tileObject = TileObjects.search().withAction(GOTRGameConstants.CRAFT_RUNES).nearestToPlayer();
|
||||
if (tileObject.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
111
src/main/java/ee/futur/easygotr/EasyGOTRSceneOverlay.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package ee.futur.easygotr;
|
||||
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.outline.ModelOutlineRenderer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Scene overlay that highlights the objects the user should click next.
|
||||
*/
|
||||
public class EasyGOTRSceneOverlay extends Overlay {
|
||||
private static final Color DEFAULT_COLOR = new Color(255, 140, 0, 180);
|
||||
private static final int OUTLINE_WIDTH = 3;
|
||||
private static final int OUTLINE_FEATHER = 2;
|
||||
|
||||
private final Client client;
|
||||
private final ModelOutlineRenderer modelOutlineRenderer;
|
||||
|
||||
@Setter
|
||||
private EasyGOTRActionHint hint;
|
||||
|
||||
@Inject
|
||||
private EasyGOTRSceneOverlay(Client client, ModelOutlineRenderer modelOutlineRenderer) {
|
||||
this.client = client;
|
||||
this.modelOutlineRenderer = modelOutlineRenderer;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (client.getLocalPlayer() == null || hint == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (EasyGOTRHighlightTarget target : hint.getHighlightsSafe()) {
|
||||
Color color = target.getColorOrDefault(DEFAULT_COLOR);
|
||||
String label = target.getLabel();
|
||||
target.getTileObjectOptional().ifPresent(tileObject -> drawTileObject(graphics, tileObject, color, label));
|
||||
target.getNpcOptional().ifPresent(npc -> drawNpc(graphics, npc, color, label));
|
||||
target.getWorldPointOptional().ifPresent(worldPoint -> drawWorldPoint(graphics, worldPoint, color, label));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawTileObject(Graphics2D graphics, TileObject tileObject, Color color, String label) {
|
||||
modelOutlineRenderer.drawOutline(tileObject, OUTLINE_WIDTH, color, OUTLINE_FEATHER);
|
||||
if (label == null || label.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalPoint localLocation = tileObject.getLocalLocation();
|
||||
if (localLocation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, localLocation);
|
||||
if (poly == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Point labelPoint = new Point(poly.getBounds().x + poly.getBounds().width / 2, poly.getBounds().y);
|
||||
OverlayUtil.renderTextLocation(graphics, labelPoint, label, color);
|
||||
}
|
||||
|
||||
private void drawNpc(Graphics2D graphics, NPC npc, Color color, String label) {
|
||||
modelOutlineRenderer.drawOutline(npc, OUTLINE_WIDTH, color, OUTLINE_FEATHER);
|
||||
if (label == null || label.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
net.runelite.api.Point textLocation = npc.getCanvasTextLocation(graphics, label, npc.getLogicalHeight());
|
||||
if (textLocation != null) {
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, label, color);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawWorldPoint(Graphics2D graphics, WorldPoint worldPoint, Color color, String label) {
|
||||
LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||
if (localPoint == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, localPoint);
|
||||
if (poly == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.draw(poly);
|
||||
|
||||
if (label != null && !label.isEmpty()) {
|
||||
Point labelPoint = new Point(poly.getBounds().x + poly.getBounds().width / 2, poly.getBounds().y);
|
||||
OverlayUtil.renderTextLocation(graphics, labelPoint, label, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,9 @@ import com.google.inject.Inject;
|
||||
import ee.futur.baseapi.collections.Inventory;
|
||||
import ee.futur.baseapi.collections.TileObjects;
|
||||
import ee.futur.baseapi.collections.Widgets;
|
||||
import ee.futur.easygotr.data.Constants;
|
||||
import ee.futur.easygotr.data.GOTRGameConstants;
|
||||
import ee.futur.easygotr.data.Utility;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
@@ -17,6 +16,7 @@ import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -44,7 +44,6 @@ public class GOTRState {
|
||||
private int catalyticPoints = -1;
|
||||
@Getter
|
||||
private boolean gameStarted;
|
||||
@Setter
|
||||
private boolean started;
|
||||
public boolean hasFirstPortalSpawned = false;
|
||||
@Inject
|
||||
@@ -62,6 +61,11 @@ public class GOTRState {
|
||||
int timeout = 0;
|
||||
int gameEndTimeout = 10;
|
||||
public boolean isGameEnding = false;
|
||||
@Getter
|
||||
private Optional<Instant> portalSpawnTime = Optional.empty();
|
||||
@Getter
|
||||
private Optional<Instant> lastPortalCloseTime = Optional.empty();
|
||||
private boolean portalVisibleLastTick = false;
|
||||
|
||||
@Inject
|
||||
public GOTRState(EventBus eventBus, EasyGOTRConfig config) {
|
||||
@@ -78,6 +82,18 @@ public class GOTRState {
|
||||
eventBus.unregister(this);
|
||||
}
|
||||
|
||||
public void setStarted(boolean started) {
|
||||
this.started = started;
|
||||
if (!started) {
|
||||
portalSpawnTime = Optional.empty();
|
||||
lastPortalCloseTime = Optional.empty();
|
||||
portalVisibleLastTick = false;
|
||||
gameStarted = false;
|
||||
hasFirstPortalSpawned = false;
|
||||
isGameEnding = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameTick(GameTick event) {
|
||||
if (client.getGameState() != GameState.LOGGED_IN || !started) {
|
||||
@@ -95,6 +111,16 @@ public class GOTRState {
|
||||
Quest.MOURNINGS_END_PART_II.getState(client), Quest.SINS_OF_THE_FATHER.getState(client));
|
||||
}
|
||||
|
||||
boolean portalVisible = isPortalSpawned();
|
||||
if (portalVisible && !portalVisibleLastTick) {
|
||||
portalSpawnTime = Optional.of(Instant.now());
|
||||
lastPortalCloseTime = Optional.empty();
|
||||
} else if (!portalVisible && portalVisibleLastTick) {
|
||||
lastPortalCloseTime = Optional.of(Instant.now());
|
||||
portalSpawnTime = Optional.empty();
|
||||
}
|
||||
portalVisibleLastTick = portalVisible;
|
||||
|
||||
Optional<Widget> frags = Inventory.search().withId(ItemID.GUARDIAN_FRAGMENTS).first();
|
||||
|
||||
if (!hasFirstPortalSpawned && (isPortalSpawned() || getPower() > 15 || (frags.isPresent() && frags.get().getItemQuantity() >= 250))) {
|
||||
@@ -146,7 +172,7 @@ public class GOTRState {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getMessage().contains(ee.futur.easygotr.data.Constants.GAME_STARTED)) {
|
||||
if (event.getMessage().contains(GOTRGameConstants.GAME_STARTED)) {
|
||||
gameStarted = true;
|
||||
}
|
||||
|
||||
@@ -182,7 +208,7 @@ public class GOTRState {
|
||||
}
|
||||
|
||||
private boolean isWidgetVisible() {
|
||||
Optional<Widget> widget = Widgets.search().withId(ee.futur.easygotr.data.Constants.PARENT_WIDGET).first();
|
||||
Optional<Widget> widget = Widgets.search().withId(GOTRGameConstants.PARENT_WIDGET).first();
|
||||
return widget.isPresent() && !widget.get().isHidden();
|
||||
}
|
||||
|
||||
@@ -197,19 +223,19 @@ public class GOTRState {
|
||||
}
|
||||
|
||||
public boolean isOutsideBarrier() {
|
||||
return client.getLocalPlayer().getWorldLocation().getY() <= ee.futur.easygotr.data.Constants.OUTSIDE_BARRIER_Y && !isInAltar();
|
||||
return client.getLocalPlayer().getWorldLocation().getY() <= GOTRGameConstants.OUTSIDE_BARRIER_Y && !isInAltar();
|
||||
}
|
||||
|
||||
public boolean isInLargeMine() {
|
||||
return !isInAltar() && client.getLocalPlayer().getWorldLocation().getX() >= ee.futur.easygotr.data.Constants.LARGE_MINE_X;
|
||||
return !isInAltar() && client.getLocalPlayer().getWorldLocation().getX() >= GOTRGameConstants.LARGE_MINE_X;
|
||||
}
|
||||
|
||||
public boolean isInHugeMine() {
|
||||
return !isInAltar() && client.getLocalPlayer().getWorldLocation().getX() <= ee.futur.easygotr.data.Constants.HUGE_MINE_X;
|
||||
return !isInAltar() && client.getLocalPlayer().getWorldLocation().getX() <= GOTRGameConstants.HUGE_MINE_X;
|
||||
}
|
||||
|
||||
public boolean isGameBusy() {
|
||||
return !isInAltar() && isOutsideBarrier() && TileObjects.search().withId(Constants.BARRIER_BUSY_ID).nearestToPlayer().isPresent();
|
||||
return !isInAltar() && isOutsideBarrier() && TileObjects.search().withId(GOTRGameConstants.BARRIER_BUSY_ID).nearestToPlayer().isPresent();
|
||||
}
|
||||
|
||||
public boolean isPortalSpawned() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import ee.futur.baseapi.collections.Inventory;
|
||||
import ee.futur.easygotr.data.Constants;
|
||||
import ee.futur.easygotr.data.GOTRGameConstants;
|
||||
import ee.futur.easygotr.data.Pouch;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -79,10 +79,22 @@ public class PouchManager {
|
||||
pouches.removeIf(p -> p.getPouchID() == ItemID.COLOSSAL_POUCH);
|
||||
pouches.add(colossalEssPouch);
|
||||
}
|
||||
|
||||
log.info("Setting Pouches: " + pouches);
|
||||
syncPouchQuantities();
|
||||
log.info("Setting Pouches: {}", pouches);
|
||||
}
|
||||
|
||||
private Optional<Widget> getPouchWidget(int pouchId) {
|
||||
return Inventory.search().withId(pouchId).first();
|
||||
}
|
||||
|
||||
private void syncPouchQuantities() {
|
||||
for (Pouch pouch : pouches) {
|
||||
int essence = getPouchWidget(pouch.getPouchID())
|
||||
.map(Widget::getItemQuantity)
|
||||
.orElse(0);
|
||||
pouch.setCurrentEssence(essence);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onChatMessage(ChatMessage event) {
|
||||
@@ -97,20 +109,21 @@ public class PouchManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getMessage().contains(ee.futur.easygotr.data.Constants.GAME_STARTED)) {
|
||||
if (event.getMessage().contains(GOTRGameConstants.GAME_STARTED)) {
|
||||
setEssenceInPouches(0);
|
||||
}
|
||||
|
||||
if (event.getMessage().contains(ee.futur.easygotr.data.Constants.GAME_WIN)) {
|
||||
if (event.getMessage().contains(GOTRGameConstants.GAME_WIN)) {
|
||||
setEssenceInPouches(0);
|
||||
}
|
||||
|
||||
if (event.getMessage().contains(Constants.GAME_OVER)) {
|
||||
if (event.getMessage().contains(GOTRGameConstants.GAME_OVER)) {
|
||||
setEssenceInPouches(0);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Pouch> getFullPouches() {
|
||||
syncPouchQuantities();
|
||||
List<Pouch> result = new ArrayList<>();
|
||||
for (Pouch pouch : pouches) {
|
||||
if (pouch.getCurrentEssence() > 0) {
|
||||
@@ -121,6 +134,7 @@ public class PouchManager {
|
||||
}
|
||||
|
||||
public boolean hasFullPouch() {
|
||||
syncPouchQuantities();
|
||||
for (Pouch pouch : pouches) {
|
||||
if (pouch.getCurrentEssence() > 0) {
|
||||
return true;
|
||||
@@ -130,6 +144,7 @@ public class PouchManager {
|
||||
}
|
||||
|
||||
public void fillPouches() {
|
||||
syncPouchQuantities();
|
||||
int essenceAmount = Inventory.getItemAmount(ItemID.GUARDIAN_ESSENCE);
|
||||
List<Pouch> result = getEmptyPouches();
|
||||
for (Pouch pouch : result) {
|
||||
@@ -154,6 +169,7 @@ public class PouchManager {
|
||||
}
|
||||
|
||||
public void emptyPouches() {
|
||||
syncPouchQuantities();
|
||||
int spaces = Inventory.getEmptySlots();
|
||||
List<Pouch> result = getFullPouches();
|
||||
for (Pouch pouch : result) {
|
||||
@@ -172,6 +188,7 @@ public class PouchManager {
|
||||
}
|
||||
|
||||
public List<Pouch> getEmptyPouches() {
|
||||
syncPouchQuantities();
|
||||
List<Pouch> result = new ArrayList<>();
|
||||
for (Pouch pouch : pouches) {
|
||||
if (!isPouchFull(pouch)) {
|
||||
@@ -182,6 +199,7 @@ public class PouchManager {
|
||||
}
|
||||
|
||||
public boolean hasEmptyPouches() {
|
||||
syncPouchQuantities();
|
||||
for (Pouch pouch : pouches) {
|
||||
if (!isPouchFull(pouch)) {
|
||||
return true;
|
||||
@@ -205,10 +223,12 @@ public class PouchManager {
|
||||
}
|
||||
|
||||
public int getAvailableSpace() {
|
||||
syncPouchQuantities();
|
||||
return pouches.stream().mapToInt(pouch -> pouch.getEssenceTotal() - pouch.getCurrentEssence()).sum();
|
||||
}
|
||||
|
||||
public int getEssenceInPouches() {
|
||||
syncPouchQuantities();
|
||||
return pouches.stream().mapToInt(Pouch::getCurrentEssence).sum();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,18 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum Altar {
|
||||
AIR(43701, Constants.AIR_SPRITE),
|
||||
MIND(43705, Constants.MIND_SPRITE),
|
||||
WATER(43702, Constants.WATER_SPRITE),
|
||||
EARTH(43703, Constants.EARTH_SPRITE),
|
||||
FIRE(43704, Constants.FIRE_SPRITE),
|
||||
BODY(43709, Constants.BODY_SPRITE),
|
||||
COSMIC(43710, Constants.COSMIC_SPRITE),
|
||||
CHAOS(43706, Constants.CHAOS_SPRITE),
|
||||
NATURE(43711, Constants.NATURE_SPRITE),
|
||||
LAW(43712, Constants.LAW_SPRITE),
|
||||
DEATH(43707, Constants.DEATH_SPRITE),
|
||||
BLOOD(43708, Constants.BLOOD_SPRITE);
|
||||
AIR(43701, GOTRGameConstants.AIR_SPRITE),
|
||||
MIND(43705, GOTRGameConstants.MIND_SPRITE),
|
||||
WATER(43702, GOTRGameConstants.WATER_SPRITE),
|
||||
EARTH(43703, GOTRGameConstants.EARTH_SPRITE),
|
||||
FIRE(43704, GOTRGameConstants.FIRE_SPRITE),
|
||||
BODY(43709, GOTRGameConstants.BODY_SPRITE),
|
||||
COSMIC(43710, GOTRGameConstants.COSMIC_SPRITE),
|
||||
CHAOS(43706, GOTRGameConstants.CHAOS_SPRITE),
|
||||
NATURE(43711, GOTRGameConstants.NATURE_SPRITE),
|
||||
LAW(43712, GOTRGameConstants.LAW_SPRITE),
|
||||
DEATH(43707, GOTRGameConstants.DEATH_SPRITE),
|
||||
BLOOD(43708, GOTRGameConstants.BLOOD_SPRITE);
|
||||
|
||||
final int id;
|
||||
final int spriteId;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package ee.futur.easygotr.data;
|
||||
|
||||
public class Constants {
|
||||
public class GOTRGameConstants {
|
||||
//Locations
|
||||
public static final int OUTSIDE_BARRIER_Y = 9482;
|
||||
public static final int LARGE_MINE_X = 3637;
|
||||