Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/com/choiceman/ChoiceManConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/choiceman/ui/CardRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
57 changes: 57 additions & 0 deletions src/main/java/com/choiceman/ui/ChoiceManOverlay.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -546,6 +573,36 @@ private int indexAt(Point p) {
return -1;
}

/**
* Opens the OSRS Wiki page for the item backing a choice card.
* <p>
* 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.
*
Expand Down