test1
This commit is contained in:
@@ -4,6 +4,7 @@ import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Optional;
|
||||
@@ -16,27 +17,33 @@ public class EasyGOTRHighlightTarget {
|
||||
private final TileObject tileObject;
|
||||
private final NPC npc;
|
||||
private final WorldPoint worldPoint;
|
||||
private final Widget widget;
|
||||
private final Color color;
|
||||
private final String label;
|
||||
|
||||
private EasyGOTRHighlightTarget(TileObject tileObject, NPC npc, WorldPoint worldPoint, Color color, String label) {
|
||||
private EasyGOTRHighlightTarget(TileObject tileObject, NPC npc, WorldPoint worldPoint, Widget widget, Color color, String label) {
|
||||
this.tileObject = tileObject;
|
||||
this.npc = npc;
|
||||
this.worldPoint = worldPoint;
|
||||
this.widget = widget;
|
||||
this.color = color;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static EasyGOTRHighlightTarget forTileObject(TileObject tileObject, Color color, String label) {
|
||||
return new EasyGOTRHighlightTarget(tileObject, null, null, color, label);
|
||||
return new EasyGOTRHighlightTarget(tileObject, null, null, null, color, label);
|
||||
}
|
||||
|
||||
public static EasyGOTRHighlightTarget forNpc(NPC npc, Color color, String label) {
|
||||
return new EasyGOTRHighlightTarget(null, npc, null, color, label);
|
||||
return new EasyGOTRHighlightTarget(null, npc, null, null, color, label);
|
||||
}
|
||||
|
||||
public static EasyGOTRHighlightTarget forWorldPoint(WorldPoint worldPoint, Color color, String label) {
|
||||
return new EasyGOTRHighlightTarget(null, null, worldPoint, color, label);
|
||||
return new EasyGOTRHighlightTarget(null, null, worldPoint, null, color, label);
|
||||
}
|
||||
|
||||
public static EasyGOTRHighlightTarget forWidget(Widget widget, Color color, String label) {
|
||||
return new EasyGOTRHighlightTarget(null, null, null, widget, color, label);
|
||||
}
|
||||
|
||||
public Optional<TileObject> getTileObjectOptional() {
|
||||
@@ -51,6 +58,10 @@ public class EasyGOTRHighlightTarget {
|
||||
return Optional.ofNullable(worldPoint);
|
||||
}
|
||||
|
||||
public Optional<Widget> getWidgetOptional() {
|
||||
return Optional.ofNullable(widget);
|
||||
}
|
||||
|
||||
public Color getColorOrDefault(Color defaultColor) {
|
||||
return color != null ? color : defaultColor;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
@Inject
|
||||
private EasyGOTRSceneOverlay sceneOverlay;
|
||||
@Inject
|
||||
private EasyGOTRWidgetOverlay widgetOverlay;
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
@@ -127,6 +129,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
keyManager.registerKeyListener(toggle);
|
||||
overlayManager.add(overlay);
|
||||
overlayManager.add(sceneOverlay);
|
||||
overlayManager.add(widgetOverlay);
|
||||
timeout = 0;
|
||||
timer = Instant.now();
|
||||
pouchManager.register();
|
||||
@@ -134,6 +137,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
currentHint = null;
|
||||
overlay.setHint(null);
|
||||
sceneOverlay.setHint(null);
|
||||
widgetOverlay.setHint(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,6 +145,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
keyManager.unregisterKeyListener(toggle);
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(sceneOverlay);
|
||||
overlayManager.remove(widgetOverlay);
|
||||
pouchManager.deregister();
|
||||
riftState.deregister();
|
||||
timeout = 0;
|
||||
@@ -149,6 +154,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
currentHint = null;
|
||||
overlay.setHint(null);
|
||||
sceneOverlay.setHint(null);
|
||||
widgetOverlay.setHint(null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -187,6 +193,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
currentHint = buildHint(state);
|
||||
overlay.setHint(currentHint);
|
||||
sceneOverlay.setHint(currentHint);
|
||||
widgetOverlay.setHint(currentHint);
|
||||
|
||||
if (BaseApiPlugin.isMoving()) {
|
||||
//Attempt to put runes in pouch where possible
|
||||
@@ -217,10 +224,10 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private EasyGOTRState getState() {
|
||||
if (config.startingFrags() > 0) {
|
||||
needsMoreStartingFragments = getFragmentCount() > config.startingFrags();
|
||||
} else if (config.startingFrags() == 0) {
|
||||
needsMoreStartingFragments = true;
|
||||
if (config.startingFrags() <= 0) {
|
||||
needsMoreStartingFragments = false;
|
||||
} else {
|
||||
needsMoreStartingFragments = getFragmentCount() < config.startingFrags();
|
||||
}
|
||||
|
||||
if (!riftState.isGameStarted() && !riftState.isInAltar()) {
|
||||
@@ -280,8 +287,10 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
return EasyGOTRState.LEAVE_ALTAR;
|
||||
}
|
||||
|
||||
boolean hasEssenceReady = hasEssenceToImbue();
|
||||
|
||||
//If we're here, were in the game area
|
||||
if (riftState.isPortalSpawned() && (pouchManager.hasEmptyPouches() || Inventory.getEmptySlots() > 15)) {
|
||||
if (riftState.isPortalSpawned() && !hasEssenceReady && (pouchManager.hasEmptyPouches() || Inventory.getEmptySlots() > 15)) {
|
||||
return EasyGOTRState.ENTER_PORTAL;
|
||||
}
|
||||
|
||||
@@ -645,9 +654,7 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
pouchManager.setStarted(started);
|
||||
if (started) {
|
||||
timer = Instant.now();
|
||||
if (config.usePouches()) {
|
||||
clientThread.invokeLater(() -> pouchManager.refreshPouches());
|
||||
}
|
||||
clientThread.invokeLater(pouchManager::refreshPouches);
|
||||
|
||||
//breakHandler.startPlugin(this);
|
||||
} else {
|
||||
@@ -811,13 +818,20 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
builder.nextAction("Deposit runes or power the guardian.");
|
||||
findPortal().ifPresent(portal ->
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(portal, Color.MAGENTA, "Use portal")));
|
||||
if (!pouchManager.hasFullPouch() && Inventory.getItemAmount(ItemID.GUARDIAN_ESSENCE) == 0) {
|
||||
builder.note("Pouches and inventory are empty—leave now to stay on the max-points cycle.");
|
||||
}
|
||||
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")));
|
||||
nextAltar.ifPresent(altar -> {
|
||||
builder.highlight(EasyGOTRHighlightTarget.forTileObject(altar, Color.GREEN, "Enter altar"));
|
||||
if (isElementalGuardian(altar)) {
|
||||
builder.note("Cast Magic Imbue as you step in so every trip produces combination runes.");
|
||||
}
|
||||
});
|
||||
if (nextAltar.isEmpty()) {
|
||||
builder.note("Wait for a guardian to become active.");
|
||||
}
|
||||
@@ -829,6 +843,8 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
break;
|
||||
}
|
||||
|
||||
addGuideNotes(builder, state);
|
||||
|
||||
if (getInventoryRunes().isPresent() && config.dropRunes()) {
|
||||
builder.note("Drop leftover runes to free space (per config).");
|
||||
}
|
||||
@@ -852,6 +868,8 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
}
|
||||
});
|
||||
|
||||
maybeHighlightBindingNecklace(builder);
|
||||
|
||||
EasyGOTRActionHint hint = builder.build();
|
||||
if (hint.getCurrentAction() == null || hint.getCurrentAction().isEmpty()) {
|
||||
return hint.toBuilder().currentAction("Track the highlighted targets.").build();
|
||||
@@ -860,6 +878,61 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
return hint;
|
||||
}
|
||||
|
||||
private void addGuideNotes(EasyGOTRActionHint.EasyGOTRActionHintBuilder builder, EasyGOTRState state) {
|
||||
switch (state) {
|
||||
case WAITING_FOR_GAME:
|
||||
builder.note("Max points prep: run north to the east mine as soon as the lobby opens and skip the cell table until portals spawn (per Jwell guide).");
|
||||
builder.note("Refresh binding necklace / NPC Contact between rounds and spam Quick-pass at 30 seconds.");
|
||||
break;
|
||||
case MOVE_TO_EAST_MINE:
|
||||
builder.note("Use the starting phase to stand on the east rubble so you can instantly begin mining when the timer hits 0.");
|
||||
builder.note("Dragon/infernal pick special can be queued around 2 seconds before the game starts.");
|
||||
break;
|
||||
case MINE_LARGE_GUARDIANS:
|
||||
case MINE_REGULAR_GUARDIANS:
|
||||
case MINING:
|
||||
builder.note("Stay on the highlighted rocks until the portal timer hits ~1:40, then rotate to the centre to catch the huge guardian portal.");
|
||||
getPortalTimerText().ifPresent(timer -> builder.note("Portal timer: " + timer + " (leave near 1:40 for max points)."));
|
||||
break;
|
||||
case ENTER_PORTAL:
|
||||
builder.note("Use the portal immediately to access the huge guardian remains and fill every pouch before leaving.");
|
||||
break;
|
||||
case MINE_HUGE_GUARDIANS:
|
||||
builder.note("Mine until both inventory and pouches are full, then exit to begin the combination rune cycle.");
|
||||
break;
|
||||
case CRAFT_RUNES:
|
||||
builder.note("Cast Magic Imbue on entry, craft combination runes (fire + water) and convert them into polyelemental stones for +3 elemental energy.");
|
||||
break;
|
||||
case DEPOSIT_RUNES:
|
||||
builder.note("Use the deposit pool (the guide binds key 4) and avoid the 'Deposit runes' button so your fire/water rune stack stays intact.");
|
||||
break;
|
||||
case CRAFT_ESSENCE:
|
||||
case CRAFTING_ESSENCE:
|
||||
builder.note("Immediately work the bench after every altar trip so fragments become essence before the next portal.");
|
||||
break;
|
||||
case POWER_GUARDIAN:
|
||||
builder.note("Dump stones on the Great Guardian right away for energy + run energy refills before heading back to portals.");
|
||||
break;
|
||||
case ENTER_ALTAR:
|
||||
builder.note("Prioritise elemental guardians first so you can keep crafting combination runes every trip.");
|
||||
break;
|
||||
case LEAVE_ALTAR:
|
||||
builder.note("Exit quickly and deposit runes within ~5 seconds of the guardian reaching 100% to secure the third catalytic point.");
|
||||
break;
|
||||
case USE_CELL:
|
||||
builder.note("Place charged cells in ascending order (weak → overcharged) to keep barriers stacked, matching the wiki strategy.");
|
||||
break;
|
||||
case ENTER_GAME:
|
||||
builder.note("Spam Quick-pass as soon as the barrier reopens; standing north keeps travel time minimal.");
|
||||
break;
|
||||
case BREAK:
|
||||
builder.note("Wait for the reward XP drop before leaving the arena so points are saved, just like the guide stresses.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<EasyGOTRHighlightTarget> determineCellPlacement() {
|
||||
if (!config.collectUnchargedCells()) {
|
||||
return Optional.empty();
|
||||
@@ -1106,6 +1179,10 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
return Inventory.search().idInList(PoweredCellList).first().isPresent();
|
||||
}
|
||||
|
||||
private boolean hasEssenceToImbue() {
|
||||
return Inventory.getItemAmount(ItemID.GUARDIAN_ESSENCE) > 0 || pouchManager.getEssenceInPouches() > 0;
|
||||
}
|
||||
|
||||
private void enterPortal() {
|
||||
if (BaseApiPlugin.isMoving()) {
|
||||
return;
|
||||
@@ -1349,4 +1426,34 @@ public class EasyGOTRPlugin extends Plugin {
|
||||
Optional<Widget> frags = Inventory.search().withId(ItemID.GUARDIAN_FRAGMENTS).first();
|
||||
return frags.map(Widget::getItemQuantity).orElse(0);
|
||||
}
|
||||
|
||||
private boolean isElementalGuardian(TileObject altar) {
|
||||
if (altar == null) {
|
||||
return false;
|
||||
}
|
||||
switch (altar.getId()) {
|
||||
case GOTRState.AIR_ALTAR:
|
||||
case GOTRState.WATER_ALTAR:
|
||||
case GOTRState.EARTH_ALTAR:
|
||||
case GOTRState.FIRE_ALTAR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeHighlightBindingNecklace(EasyGOTRActionHint.EasyGOTRActionHintBuilder builder) {
|
||||
if (hasBindingNecklaceEquipped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory.search().withId(ItemID.BINDING_NECKLACE).first().ifPresent(widget -> {
|
||||
builder.highlight(EasyGOTRHighlightTarget.forWidget(widget, Color.MAGENTA, "Equip binding necklace"));
|
||||
builder.note("Binding necklace broke—equip a fresh one before crafting combos.");
|
||||
});
|
||||
}
|
||||
|
||||
private boolean hasBindingNecklaceEquipped() {
|
||||
return Equipment.search().withId(ItemID.BINDING_NECKLACE).first().isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
55
src/main/java/ee/futur/easygotr/EasyGOTRWidgetOverlay.java
Normal file
55
src/main/java/ee/futur/easygotr/EasyGOTRWidgetOverlay.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package ee.futur.easygotr;
|
||||
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Overlay that highlights UI widgets (inventory items) the player should interact with.
|
||||
*/
|
||||
public class EasyGOTRWidgetOverlay extends Overlay {
|
||||
|
||||
@Setter
|
||||
private EasyGOTRActionHint hint;
|
||||
|
||||
@Inject
|
||||
private EasyGOTRWidgetOverlay() {
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
EasyGOTRActionHint localHint = hint;
|
||||
if (localHint == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (EasyGOTRHighlightTarget target : localHint.getHighlightsSafe()) {
|
||||
target.getWidgetOptional().ifPresent(widget -> highlightWidget(graphics, widget, target.getColorOrDefault(Color.CYAN), target.getLabel()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void highlightWidget(Graphics2D graphics, Widget widget, Color color, String label) {
|
||||
Rectangle bounds = widget.getBounds();
|
||||
if (bounds == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.draw(bounds);
|
||||
|
||||
if (label != null && !label.isEmpty()) {
|
||||
graphics.drawString(label, (int) bounds.getX(), (int) (bounds.getY() - 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,16 +83,9 @@ public class PouchManager {
|
||||
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);
|
||||
pouch.setCurrentEssence(getPouchAmount(pouch.getPouchID(), pouch.getEssenceTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,4 +224,37 @@ public class PouchManager {
|
||||
syncPouchQuantities();
|
||||
return pouches.stream().mapToInt(Pouch::getCurrentEssence).sum();
|
||||
}
|
||||
|
||||
private int getPouchAmount(int pouchId, int capacity) {
|
||||
int varbit = getVarbitForPouch(pouchId);
|
||||
if (varbit == -1 || client == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amount = client.getVarbitValue(varbit);
|
||||
if (amount < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (amount > capacity) {
|
||||
return capacity;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
private int getVarbitForPouch(int pouchId) {
|
||||
switch (pouchId) {
|
||||
case ItemID.SMALL_POUCH:
|
||||
return Varbits.ESSENCE_POUCH_SMALL_AMOUNT;
|
||||
case ItemID.MEDIUM_POUCH:
|
||||
return Varbits.ESSENCE_POUCH_MEDIUM_AMOUNT;
|
||||
case ItemID.LARGE_POUCH:
|
||||
return Varbits.ESSENCE_POUCH_LARGE_AMOUNT;
|
||||
case ItemID.GIANT_POUCH:
|
||||
return Varbits.ESSENCE_POUCH_GIANT_AMOUNT;
|
||||
case ItemID.COLOSSAL_POUCH:
|
||||
return Varbits.ESSENCE_POUCH_COLOSSAL_AMOUNT;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user