diff --git a/src/main/java/com/choiceman/ChoiceManConfig.java b/src/main/java/com/choiceman/ChoiceManConfig.java index 2f5505f..5f4228d 100644 --- a/src/main/java/com/choiceman/ChoiceManConfig.java +++ b/src/main/java/com/choiceman/ChoiceManConfig.java @@ -76,6 +76,14 @@ public interface ChoiceManConfig extends Config ) default int sfxVolume() { return 100; } + @ConfigItem( + keyName = "wikiLookup", + name = "Right-click choices for wiki", + description = "Right-click an unlock choice card to open that item on the OSRS Wiki.", + position = 23 + ) + default boolean wikiLookup() { return true; } + @ConfigSection( name = "Advanced", description = "Advanced settings. Incorrect formatting or item IDs may break progression, restrictions, or unlock behavior.", diff --git a/src/main/java/com/choiceman/ui/CardRenderer.java b/src/main/java/com/choiceman/ui/CardRenderer.java index 36b5cf5..2f34150 100644 --- a/src/main/java/com/choiceman/ui/CardRenderer.java +++ b/src/main/java/com/choiceman/ui/CardRenderer.java @@ -402,6 +402,27 @@ Rectangle drawMinimizePillAt(Graphics2D g, int x, int y, int w, int h, return new Rectangle(x, y, w, h); } + /** + * Draws a small, unobtrusive hint line at the given top-left position. Rendered with a soft + * shadow so it stays legible over the game world. + * + * @param g graphics context + * @param x left edge of the text + * @param topY top y-coordinate of the text block + * @param text hint text to draw + */ + void drawHint(Graphics2D g, int x, int topY, String text) { + Font old = g.getFont(); + g.setFont(old.deriveFont(Font.PLAIN, 11f)); + FontMetrics fm = g.getFontMetrics(); + int baseline = topY + fm.getAscent(); + g.setColor(new Color(0, 0, 0, 160)); + g.drawString(text, x + 1, baseline + 1); + g.setColor(new Color(255, 255, 255, 145)); + g.drawString(text, x, baseline); + g.setFont(old); + } + /** * Draws the centered restore pill used when the presentation is minimized, and returns * the painted extent to help layout upstream overlays. diff --git a/src/main/java/com/choiceman/ui/ChoiceManOverlay.java b/src/main/java/com/choiceman/ui/ChoiceManOverlay.java index 92d0eb0..bda61ed 100644 --- a/src/main/java/com/choiceman/ui/ChoiceManOverlay.java +++ b/src/main/java/com/choiceman/ui/ChoiceManOverlay.java @@ -15,6 +15,8 @@ import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.LinkBrowser; +import okhttp3.HttpUrl; import javax.inject.Inject; import javax.inject.Singleton; @@ -86,6 +88,11 @@ public class ChoiceManOverlay extends Overlay { */ private static final int TITLE_TOP_Y = 0, CARDS_PULL_UP_Y = 9; + /** + * OSRS Wiki lookup endpoint, matching the query shape used by RuneLite's own Wiki plugin. + */ + private static final HttpUrl WIKI_BASE = HttpUrl.get("https://oldschool.runescape.wiki"); + private final Client client; private final EventBus eventBus; private final CardRenderer renderer; @@ -174,6 +181,21 @@ public MouseEvent mouseMoved(MouseEvent e) { @Override public MouseEvent mousePressed(MouseEvent e) { if (!active || choices == null || choices.isEmpty() || animating) return e; + + // Right-click a fully revealed card to open its item on the wiki. Does not touch + // selection (left-click), and never fires while minimized. + if (e.getButton() == MouseEvent.BUTTON3) { + if (minimized) return e; + Point rp = toOverlayLocal(e); + if (rp == null) return e; + int idx = indexAt(rp); + if (isCardFullyRevealed(idx) && idx >= 0 && idx < choices.size() + && openWiki(choices.get(idx))) { + e.consume(); + } + return e; + } + if (e.getButton() != MouseEvent.BUTTON1) return e; Point lp = toOverlayLocal(e); if (lp == null) return e; @@ -515,6 +537,11 @@ public Dimension render(Graphics2D g) { g, pillX, pillY, MIN_BTN_W, MIN_BTN_H, "Minimize", !animating && hoverMinimize, this::getAccent); + // Discoverability hint for the right-click wiki lookup, tucked under the Minimize pill. + if (!animating && (config == null || config.wikiLookup())) { + renderer.drawHint(g, pillX, pillY + MIN_BTN_H + 4, "Right-click a card for wiki"); + } + return new Dimension(totalW, totalH); } @@ -546,6 +573,36 @@ private int indexAt(Point p) { return -1; } + /** + * Opens the OSRS Wiki page for the item backing a choice card. + *
+ * Uses the base's first concrete item ID with the same {@code Special:Lookup} query the + * RuneLite Wiki plugin uses, so the wiki resolves variants to the right article. Opening a + * URL performs no game action and is safe from the input thread; {@link LinkBrowser} handles + * the browser hand-off. + * + * @param base the base name shown on the card + * @return true if a lookup was launched (so the caller can consume the click) + */ + private boolean openWiki(String base) { + if (config != null && !config.wikiLookup()) return false; + if (repo == null || base == null) return false; + + int id = repo.getIdsForBase(base).stream().filter(Objects::nonNull).findFirst().orElse(-1); + if (id <= 0) return false; + + String url = WIKI_BASE.newBuilder() + .addPathSegments("w/Special:Lookup") + .addQueryParameter("type", "item") + .addQueryParameter("id", Integer.toString(id)) + .addQueryParameter("name", base) + .addQueryParameter("utm_source", "runelite") + .build() + .toString(); + LinkBrowser.browse(url); + return true; + } + /** * Resolve the accent color for UI elements. Falls back to a warm yellow when config is missing. *