This commit is contained in:
2025-11-17 19:16:57 +02:00
parent e3e7de9108
commit e555d5a114
22 changed files with 864 additions and 141 deletions

3
.gitignore vendored
View File

@@ -6,4 +6,5 @@ build
.classpath
nbactions.xml
nb-configuration.xml
nbproject/
nbproject/
bin/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 KiB

View File

@@ -1 +1 @@
rootProject.name = 'easy-giantsfoundry'
rootProject.name = 'k4rli-plugins'

View File

@@ -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;

View File

@@ -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;

View 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;
}
}

View File

@@ -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() {

View 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;
}
}

View File

@@ -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);

View File

@@ -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;
}

View 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);
}
}
}

View File

@@ -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() {

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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;