diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index 84ad7d0e5d..cc70a39eec 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -123,6 +123,27 @@ public interface MenuEntry @Nullable Widget getWidget(); + /** + * Get the {@link NPC} this menu entry is targeting, if any. + * @return + */ + @Nullable + NPC getNpc(); + + /** + * Get the {@link Player} this menu entry is targeting, if any. + * @return + */ + @Nullable + Player getPlayer(); + + /** + * Get the {@link Actor} this menu entry is targeting, if any. + * @return + */ + @Nullable + Actor getActor(); + @Deprecated int getOpcode(); @Deprecated @@ -140,4 +161,4 @@ public interface MenuEntry @Deprecated MenuAction getMenuAction(); -} \ No newline at end of file +} diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java index faf369be56..c03f1683e4 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java @@ -24,58 +24,77 @@ */ package net.runelite.api.events; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; /** * An event when a new entry is added to a right-click menu. */ +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@ToString(onlyExplicitlyIncluded = true) public class MenuEntryAdded { // Here for RuneLite compatibility (different parameter order) - public MenuEntryAdded(String option, String target, int type, int identifier, int actionParam0, int actionParam1) + public MenuEntryAdded(MenuEntry menuEntry) { - this(option, target, identifier, type, actionParam0, actionParam1, false); - } + this.menuEntry = menuEntry; - public MenuEntryAdded(String option, String target, int identifier, int type, int param0, int param1, boolean forceLeftClick) - { - this.option = option; - this.target = target; - this.identifier = identifier; - this.type = type; - this.actionParam0 = param0; - this.actionParam1 = param1; - this.forceLeftClick = forceLeftClick; + this.option = menuEntry.getOption(); + this.target = menuEntry.getTarget(); + this.identifier = menuEntry.getIdentifier(); + this.type = menuEntry.getType().getId(); + this.actionParam0 = menuEntry.getParam0(); + this.actionParam1 = menuEntry.getParam1(); + this.forceLeftClick = false; } + @Getter + private final MenuEntry menuEntry; + @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private String option; @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private String target; @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private int type; @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private int identifier; @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private int actionParam0; @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private int actionParam1; @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private boolean forceLeftClick; /** @@ -87,6 +106,8 @@ public class MenuEntryAdded */ @Getter @Setter + @EqualsAndHashCode.Include + @ToString.Include private boolean modified; public void setModified() @@ -134,4 +155,4 @@ public class MenuEntryAdded { return MenuAction.of(type); } -} +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java index 4396273a65..cab8c5ca4c 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java @@ -24,9 +24,12 @@ */ package net.runelite.api.events; +import javax.annotation.Nullable; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; +import lombok.ToString; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.widgets.Widget; @@ -43,12 +46,16 @@ import net.runelite.api.widgets.Widget; * it seems that this event still triggers with the "Cancel" action. */ @RequiredArgsConstructor +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@ToString(onlyExplicitlyIncluded = true) public class MenuOptionClicked { /** * The clicked menu entry */ + @Getter private final MenuEntry menuEntry; + /** * Whether or not the event has been consumed by a subscriber. */ @@ -59,6 +66,8 @@ public class MenuOptionClicked /** * Action parameter 0. Its value depends on the menuAction. */ + @EqualsAndHashCode.Include + @ToString.Include public int getParam0() { return menuEntry.getParam0(); @@ -72,6 +81,8 @@ public class MenuOptionClicked /** * Action parameter 1. Its value depends on the menuAction. */ + @EqualsAndHashCode.Include + @ToString.Include public int getParam1() { return menuEntry.getParam1(); @@ -85,6 +96,8 @@ public class MenuOptionClicked /** * The option text added to the menu. */ + @EqualsAndHashCode.Include + @ToString.Include public String getMenuOption() { return menuEntry.getOption(); @@ -98,6 +111,8 @@ public class MenuOptionClicked /** * The target of the action. */ + @EqualsAndHashCode.Include + @ToString.Include public String getMenuTarget() { return menuEntry.getTarget(); @@ -111,6 +126,8 @@ public class MenuOptionClicked /** * The action performed. */ + @EqualsAndHashCode.Include + @ToString.Include public MenuAction getMenuAction() { return menuEntry.getType(); @@ -124,6 +141,8 @@ public class MenuOptionClicked /** * The ID of the object, actor, or item that the interaction targets. */ + @EqualsAndHashCode.Include + @ToString.Include public int getId() { return menuEntry.getIdentifier(); @@ -168,6 +187,7 @@ public class MenuOptionClicked * with an associated widget. Such as eg, CC_OP. * @return */ + @Nullable public Widget getWidget() { return menuEntry.getWidget(); diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java index a6bda5c0d6..10fba4954d 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java @@ -183,6 +183,17 @@ public interface Widget @Deprecated void setRelativeY(int y); + /** + * Set a forced position for the widget. This position overrides the relative x/y for the + * widget, even if the widget is revalidated. To clear the forced position pass -1 for x/y. + * @param x x pos relative to the parent + * @param y y pos relative to the parent + */ + void setForcedPosition(int x, int y); + + void setForcedX(); + void setForcedY(); + /** * Gets the text displayed on this widget. * diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/thieving/CrowdsourcingThieving.java b/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/thieving/CrowdsourcingThieving.java index 4a58c97a66..669f63716b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/thieving/CrowdsourcingThieving.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/thieving/CrowdsourcingThieving.java @@ -118,9 +118,8 @@ public class CrowdsourcingThieving { if (event.getMenuOption().equals("Pickpocket") || event.getMenuOption().equals("Knock-Out")) { - NPC[] cachedNPCs = client.getCachedNPCs(); - NPC npc = cachedNPCs[event.getId()]; - lastPickpocketTarget = npc.getId(); + NPC npc = event.getMenuEntry().getNpc(); + lastPickpocketTarget = npc != null ? npc.getId() : -1; } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index ee0dfb7711..3e37005eba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -476,7 +476,8 @@ public class DevToolsPlugin extends Plugin if (action == MenuAction.EXAMINE_NPC) { - NPC npc = client.getCachedNPCs()[identifier]; + NPC npc = entry.getNpc(); + assert npc != null; info += npc.getId(); } else diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index dd2e015eb1..f893f48e27 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -50,7 +50,7 @@ class SceneUploader @Inject private Client client; - int sceneId = (int) (System.currentTimeMillis() / 1000L); + int sceneId = (int) System.nanoTime(); private int offset; private int uvoffset; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index 693412bcb3..70952d3f37 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -185,9 +185,7 @@ public class HiscorePlugin extends Plugin { if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER && event.getMenuOption().equals(LOOKUP)) { - // The player id is included in the event, so we can use that to get the player name, - // which avoids having to parse out the combat level and any icons preceding the name. - Player player = client.getCachedPlayers()[event.getId()]; + Player player = event.getMenuEntry().getPlayer(); if (player == null) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java index aa38a95ab6..01326990f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java @@ -114,8 +114,7 @@ class InteractHighlightOverlay extends Overlay case NPC_FIFTH_OPTION: case EXAMINE_NPC: { - int id = entry.getIdentifier(); - NPC npc = plugin.findNpc(id); + NPC npc = entry.getNpc(); if (npc != null && config.npcShowHover() && (npc != plugin.getInteractedTarget() || !config.npcShowInteract())) { Color highlightColor = menuAction == MenuAction.NPC_SECOND_OPTION diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightPlugin.java index fc9a71a480..3ab3dec06f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightPlugin.java @@ -167,9 +167,8 @@ public class InteractHighlightPlugin extends Plugin case NPC_FOURTH_OPTION: case NPC_FIFTH_OPTION: { - int id = menuOptionClicked.getId(); interactedObject = null; - interactedNpc = findNpc(id); + interactedNpc = menuOptionClicked.getMenuEntry().getNpc(); attacked = menuOptionClicked.getMenuAction() == MenuAction.NPC_SECOND_OPTION || menuOptionClicked.getMenuAction() == MenuAction.WIDGET_TARGET_ON_NPC && WidgetInfo.TO_GROUP(client.getSelectedWidget().getId()) == WidgetID.SPELLBOOK_GROUP_ID; clickTick = client.getTickCount(); @@ -242,11 +241,6 @@ public class InteractHighlightPlugin extends Plugin return null; } - NPC findNpc(int id) - { - return client.getCachedNPCs()[id]; - } - @Nullable Actor getInteractedTarget() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index ceade87a76..230077f4a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -723,11 +723,11 @@ public class MenuEntrySwapperPlugin extends Plugin { final MenuEntry entry = entries[idx]; final MenuAction type = entry.getType(); - final int id = entry.getIdentifier(); if (type == MenuAction.EXAMINE_NPC) { - final NPC npc = client.getCachedNPCs()[id]; + final NPC npc = entry.getNpc(); + assert npc != null; final NPCComposition composition = npc.getTransformedComposition(); final String[] actions = composition.getActions(); @@ -977,7 +977,8 @@ public class MenuEntrySwapperPlugin extends Plugin if (NPC_MENU_TYPES.contains(menuAction)) { - final NPC npc = client.getCachedNPCs()[eventId]; + final NPC npc = menuEntry.getNpc(); + assert npc != null; final NPCComposition composition = npc.getTransformedComposition(); Integer customOption = getNpcSwapConfig(composition.getId()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 062a184d22..a9806d0d43 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -26,7 +26,6 @@ package net.runelite.client.plugins.npchighlight; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; import java.awt.Color; import java.time.Instant; @@ -48,7 +47,6 @@ import net.runelite.api.GraphicID; import net.runelite.api.GraphicsObject; import net.runelite.api.KeyCode; import net.runelite.api.MenuAction; -import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import net.runelite.api.MenuEntry; import net.runelite.api.NPC; import net.runelite.api.coords.WorldPoint; @@ -89,10 +87,6 @@ public class NpcIndicatorsPlugin extends Plugin private static final String TAG_ALL = "Tag-All"; private static final String UNTAG_ALL = "Un-tag-All"; - private static final Set NPC_MENU_ACTIONS = ImmutableSet.of(MenuAction.NPC_FIRST_OPTION, MenuAction.NPC_SECOND_OPTION, - MenuAction.NPC_THIRD_OPTION, MenuAction.NPC_FOURTH_OPTION, MenuAction.NPC_FIFTH_OPTION, MenuAction.WIDGET_TARGET_ON_NPC, - MenuAction.ITEM_USE_ON_NPC); - @Inject private Client client; @@ -239,46 +233,19 @@ public class NpcIndicatorsPlugin extends Plugin @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - int type = event.getType(); + final MenuEntry menuEntry = event.getMenuEntry(); + final MenuAction menuAction = menuEntry.getType(); + final NPC npc = menuEntry.getNpc(); - if (type >= MENU_ACTION_DEPRIORITIZE_OFFSET) + if (npc == null) { - type -= MENU_ACTION_DEPRIORITIZE_OFFSET; + return; } - final MenuAction menuAction = MenuAction.of(type); - - if (NPC_MENU_ACTIONS.contains(menuAction)) - { - NPC npc = client.getCachedNPCs()[event.getIdentifier()]; - - Color color = null; - if (npc.isDead()) - { - color = config.deadNpcMenuColor(); - } - - if (color == null && highlightedNpcs.containsKey(npc) && config.highlightMenuNames() && (!npc.isDead() || !config.ignoreDeadNpcs())) - { - color = config.highlightColor(); - } - - if (color != null) - { - MenuEntry[] menuEntries = client.getMenuEntries(); - final MenuEntry menuEntry = menuEntries[menuEntries.length - 1]; - final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color); - menuEntry.setTarget(target); - } - } - else if (menuAction == MenuAction.EXAMINE_NPC && client.isKeyPressed(KeyCode.KC_SHIFT)) + if (menuAction == MenuAction.EXAMINE_NPC && client.isKeyPressed(KeyCode.KC_SHIFT)) { // Add tag and tag-all options - final int id = event.getIdentifier(); - final NPC[] cachedNPCs = client.getCachedNPCs(); - final NPC npc = cachedNPCs[id]; - - if (npc == null || npc.getName() == null) + if (npc.getName() == null) { return; } @@ -306,6 +273,25 @@ public class NpcIndicatorsPlugin extends Plugin .setType(MenuAction.RUNELITE) .onClick(this::tag); } + else + { + Color color = null; + if (npc.isDead()) + { + color = config.deadNpcMenuColor(); + } + + if (color == null && highlightedNpcs.containsKey(npc) && config.highlightMenuNames() && (!npc.isDead() || !config.ignoreDeadNpcs())) + { + color = config.highlightColor(); + } + + if (color != null) + { + final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color); + menuEntry.setTarget(target); + } + } } private void tag(MenuEntry entry) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index 17c2bf39b7..0e0891e9d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -159,8 +159,7 @@ public class OpponentInfoPlugin extends Plugin return; } - int npcIndex = menuEntryAdded.getIdentifier(); - NPC npc = client.getCachedNPCs()[npcIndex]; + NPC npc = menuEntryAdded.getMenuEntry().getNpc(); if (npc == null) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java index 5d84ac22f3..99c6363ed9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java @@ -116,7 +116,7 @@ class PrayerBarOverlay extends Overlay graphics.fillRect(barX + xOffset, barY + HD_PRAYER_BAR_PADDING, 1, barHeight - HD_PRAYER_BAR_PADDING * 2); } - return new Dimension(barWidth, barHeight); + return null; } // Draw bar @@ -145,7 +145,7 @@ class PrayerBarOverlay extends Overlay graphics.fillRect(barX + xOffset, barY, 1, barHeight); } - return new Dimension(barWidth, barHeight); + return null; } void onTick() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java index 7dc097a295..a43bb28f59 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java @@ -151,8 +151,7 @@ class PrayerDoseOverlay extends Overlay graphics.setColor(ColorUtil.colorLerp(START_COLOR, END_COLOR, Math.sin(t))); graphics.setStroke(new BasicStroke(2)); graphics.drawOval(orbInnerX, orbInnerY, orbInnerSize, orbInnerSize); - - return new Dimension((int) bounds.getWidth(), (int) bounds.getHeight()); + return null; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java index 8853590724..30ab416527 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java @@ -91,7 +91,6 @@ class PrayerFlickOverlay extends Overlay graphics.setColor(Color.cyan); graphics.fillRect(orbInnerX + xOffset, orbInnerY + yOffset, 1, indicatorHeight); - - return new Dimension((int) bounds.getWidth(), (int) bounds.getHeight()); + return null; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/randomevents/RandomEventPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/randomevents/RandomEventPlugin.java index 2dad55c9bf..1e246efe67 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/randomevents/RandomEventPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/randomevents/RandomEventPlugin.java @@ -160,7 +160,7 @@ public class RandomEventPlugin extends Plugin && event.getType() <= MenuAction.NPC_FIFTH_OPTION.getId() && EVENT_OPTIONS.contains(event.getOption())) { - NPC npc = client.getCachedNPCs()[event.getIdentifier()]; + NPC npc = event.getMenuEntry().getNpc(); if (npc != null && EVENT_NPCS.contains(npc.getId()) && npc != currentRandomEvent && config.removeMenuOptions()) { client.setMenuEntries(Arrays.copyOf(client.getMenuEntries(), client.getMenuEntries().length - 1)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java index 79f9932de3..39f7f27b32 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java @@ -279,7 +279,8 @@ public class WikiPlugin extends Plugin case WIDGET_TARGET_ON_NPC: { type = "npc"; - NPC npc = client.getCachedNPCs()[ev.getId()]; + NPC npc = ev.getMenuEntry().getNpc(); + assert npc != null; NPCComposition nc = npc.getTransformedComposition(); id = nc.getId(); name = nc.getName(); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index cd27715bd2..2f4bc5348e 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -357,7 +357,7 @@ public class OverlayRenderer extends MouseAdapter if (!bounds.isEmpty()) { - if (inOverlayManagingMode) + if (inOverlayManagingMode && overlay.isMovable()) { Color boundsColor; if (inOverlayResizingMode && currentManagedOverlay == overlay) @@ -407,7 +407,7 @@ public class OverlayRenderer extends MouseAdapter // See if we've clicked on an overlay currentManagedOverlay = lastHoveredOverlay; - if (currentManagedOverlay == null) + if (currentManagedOverlay == null || !currentManagedOverlay.isMovable()) { return mouseEvent; } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java index 5806234f65..382ea1046a 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java @@ -136,8 +136,7 @@ public class WidgetOverlay extends Overlay if (getPreferredLocation() != null || getPreferredPosition() != null) { // The widget relative pos is relative to the parent - widget.setRelativeX(bounds.x - parent.x); - widget.setRelativeY(bounds.y - parent.y); + widget.setForcedPosition(bounds.x - parent.x, bounds.y - parent.y); } else { @@ -145,6 +144,7 @@ public class WidgetOverlay extends Overlay { revalidate = false; log.debug("Revalidating {}", widgetInfo); + widget.setForcedPosition(-1, -1); // Revalidate the widget to reposition it back to its normal location after an overlay reset widget.revalidate(); } diff --git a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java index cd33ded89b..a89ee37a9d 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java @@ -33,7 +33,6 @@ import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import static net.runelite.api.MenuAction.CC_OP; import static net.runelite.api.MenuAction.RUNELITE; import net.runelite.api.MenuEntry; import net.runelite.api.events.MenuEntryAdded; @@ -99,13 +98,7 @@ public class MenuManagerTest menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); - menuManager.onMenuEntryAdded(new MenuEntryAdded( - CANCEL.getOption(), - CANCEL.getTarget(), - CC_OP.getId(), - CANCEL.getIdentifier(), - CANCEL.getParam0(), - CANCEL.getParam1())); + menuManager.onMenuEntryAdded(new MenuEntryAdded(createMenuEntry("Cancel", "", MenuAction.CC_OP, MINIMAP_WORLDMAP_OPTIONS.getPackedId()))); verify(client, times(3)).createMenuEntry(anyInt()); diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java index 536c50dd7b..56693803a9 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -28,8 +28,11 @@ import java.util.function.Consumer; import javax.annotation.Nullable; import lombok.EqualsAndHashCode; import lombok.Setter; +import net.runelite.api.Actor; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; +import net.runelite.api.NPC; +import net.runelite.api.Player; import net.runelite.api.widgets.Widget; @EqualsAndHashCode(callSuper = false) @@ -48,6 +51,8 @@ public class TestMenuEntry implements MenuEntry private int itemId = -1; @Setter private Widget widget; + @Setter + private Actor actor; @Override public String getOption() @@ -239,4 +244,25 @@ public class TestMenuEntry implements MenuEntry { return widget; } + + @Nullable + @Override + public NPC getNpc() + { + return actor instanceof NPC ? (NPC) actor : null; + } + + @Nullable + @Override + public Player getPlayer() + { + return actor instanceof Player ? (Player) actor : null; + } + + @Nullable + @Override + public Actor getActor() + { + return actor; + } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java index b715902e47..acbf5aea8b 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java @@ -86,6 +86,7 @@ public class MenuEntrySwapperPluginTest @Inject MenuEntrySwapperPlugin menuEntrySwapperPlugin; + private NPC npc; private MenuEntry[] entries; @Before @@ -96,10 +97,9 @@ public class MenuEntrySwapperPluginTest when(client.getGameState()).thenReturn(GameState.LOGGED_IN); when(client.getObjectDefinition(anyInt())).thenReturn(mock(ObjectComposition.class)); - NPC npc = mock(NPC.class); + npc = mock(NPC.class); NPCComposition composition = mock(NPCComposition.class); when(npc.getTransformedComposition()).thenReturn(composition); - when(client.getCachedNPCs()).thenReturn(new NPC[] { npc }); when(client.getMenuEntries()).thenAnswer((Answer) invocationOnMock -> { @@ -117,18 +117,19 @@ public class MenuEntrySwapperPluginTest menuEntrySwapperPlugin.setupSwaps(); } - private static MenuEntry menu(String option, String target, MenuAction menuAction) + private MenuEntry menu(String option, String target, MenuAction menuAction) { return menu(option, target, menuAction, 0); } - private static MenuEntry menu(String option, String target, MenuAction menuAction, int identifier) + private MenuEntry menu(String option, String target, MenuAction menuAction, int identifier) { - MenuEntry menuEntry = new TestMenuEntry(); + TestMenuEntry menuEntry = new TestMenuEntry(); menuEntry.setOption(option); menuEntry.setTarget(target); menuEntry.setType(menuAction); menuEntry.setIdentifier(identifier); + menuEntry.setActor(npc); return menuEntry; } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java index 1179f3e48c..25688d2de7 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java @@ -34,7 +34,6 @@ import java.util.concurrent.ScheduledExecutorService; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NPC; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.NpcChanged; @@ -109,11 +108,12 @@ public class NpcIndicatorsPluginTest when(npc.isDead()).thenReturn(true); npcIndicatorsPlugin.onNpcSpawned(new NpcSpawned(npc)); - when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 + TestMenuEntry entry = new TestMenuEntry(); + entry.setTarget("Goblin"); + entry.setIdentifier(MenuAction.NPC_FIRST_OPTION.getId()); + entry.setActor(npc); - MenuEntry entry = new TestMenuEntry(); - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); - MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); + MenuEntryAdded menuEntryAdded = new MenuEntryAdded(entry); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); assertEquals("Goblin", entry.getTarget()); // red @@ -133,11 +133,12 @@ public class NpcIndicatorsPluginTest when(npc.getName()).thenReturn("Goblin"); npcIndicatorsPlugin.onNpcSpawned(new NpcSpawned(npc)); - when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 + TestMenuEntry entry = new TestMenuEntry(); + entry.setTarget("Goblin"); + entry.setIdentifier(MenuAction.NPC_FIRST_OPTION.getId()); + entry.setActor(npc); - MenuEntry entry = new TestMenuEntry(); - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); - MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); + MenuEntryAdded menuEntryAdded = new MenuEntryAdded(entry); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); assertEquals("Goblin", entry.getTarget()); // blue diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index e5a64dffb2..1ea6cd2784 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1089,13 +1089,6 @@ public abstract class RSClientMixin implements RSClient client.getMenuTargets()[tmpOptionsCount] = "null"; } - String menuOption = client.getMenuOptions()[tmpOptionsCount]; - String menuTarget = client.getMenuTargets()[tmpOptionsCount]; - int menuOpcode = client.getMenuOpcodes()[tmpOptionsCount]; - int menuIdentifier = client.getMenuIdentifiers()[tmpOptionsCount]; - int menuArgument1 = client.getMenuArguments1()[tmpOptionsCount]; - int menuArgument2 = client.getMenuArguments2()[tmpOptionsCount]; - if (rl$menuEntries[tmpOptionsCount] == null) { rl$menuEntries[tmpOptionsCount] = newRuneliteMenuEntry(tmpOptionsCount); @@ -1106,13 +1099,9 @@ public abstract class RSClientMixin implements RSClient } MenuEntryAdded menuEntryAdded = new MenuEntryAdded( - menuOption, - menuTarget, - menuOpcode, - menuIdentifier, - menuArgument1, - menuArgument2 + rl$menuEntries[tmpOptionsCount] ); + client.getCallbacks().post(menuEntryAdded); if (menuEntryAdded.isModified() && client.getMenuOptionCount() == optionCount) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java index 908bacbff1..7df3b69b41 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -44,6 +44,7 @@ import net.runelite.api.widgets.Widget; import static net.runelite.api.widgets.WidgetInfo.TO_CHILD; import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; import net.runelite.api.widgets.WidgetItem; +import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSModel; import net.runelite.rs.api.RSNode; @@ -66,6 +67,10 @@ public abstract class RSWidgetMixin implements RSWidget private int rl$x; @Inject private int rl$y; + @Inject + private short forcedX; + @Inject + private short forcedY; @Inject RSWidgetMixin() @@ -73,6 +78,8 @@ public abstract class RSWidgetMixin implements RSWidget rl$parentId = -1; rl$x = -1; rl$y = -1; + forcedX = -1; + forcedY = -1; } @Inject @@ -642,4 +649,99 @@ public abstract class RSWidgetMixin implements RSWidget return new Point(dragOffsetX, dragOffsetY); } + + @Inject + public void setForcedX() + { + if (this.forcedX > -1) + { + this.setRelativeX(this.forcedX); + } + } + + @Inject + public void setForcedY() + { + if (this.forcedY > -1) + { + this.setRelativeY(this.forcedY); + } + } + + @Inject + @Override + public void setForcedPosition(int x, int y) + { + this.forcedX = (short) x; + this.forcedY = (short) y; + this.setRelativeX(x); + this.setRelativeY(y); + } + + @Copy("alignWidgetPosition") + @Replace("alignWidgetPosition") + public static void alignWidgetPosition(Widget widget, int x, int y) + { + if (widget.getXPositionMode() == WidgetPositionMode.ABSOLUTE_LEFT) + { + widget.setRelativeX(widget.getOriginalX()); + widget.setForcedX(); + } + else if (widget.getXPositionMode() == WidgetPositionMode.ABSOLUTE_CENTER) + { + widget.setRelativeX(widget.getOriginalX() + (x - widget.getWidth()) / 2); + widget.setForcedX(); + } + else if (widget.getXPositionMode() == WidgetPositionMode.ABSOLUTE_RIGHT) + { + widget.setRelativeX(x - widget.getWidth() - widget.getOriginalX()); + widget.setForcedX(); + } + else if (widget.getXPositionMode() == WidgetPositionMode.LEFT_16384THS) + { + widget.setRelativeX(widget.getOriginalX() * x >> 14); + widget.setForcedX(); + } + else if (widget.getXPositionMode() == WidgetPositionMode.CENTER_16384THS) + { + widget.setRelativeX((widget.getOriginalX() * x >> 14) + (x - widget.getWidth()) / 2); + widget.setForcedX(); + } + else + { + widget.setRelativeX(x - widget.getWidth() - (widget.getOriginalX() * x >> 14)); + widget.setForcedX(); + } + + if (widget.getYPositionMode() == WidgetPositionMode.ABSOLUTE_TOP) + { + widget.setRelativeY(widget.getOriginalY()); + widget.setForcedY(); + } + else if (widget.getYPositionMode() == WidgetPositionMode.ABSOLUTE_CENTER) + { + widget.setRelativeY((y - widget.getHeight()) / 2 + widget.getOriginalY()); + widget.setForcedY(); + } + else if (widget.getYPositionMode() == WidgetPositionMode.ABSOLUTE_BOTTOM) + { + widget.setRelativeY(y - widget.getHeight() - widget.getOriginalY()); + widget.setForcedY(); + } + else if (widget.getYPositionMode() == WidgetPositionMode.TOP_16384THS) + { + widget.setRelativeY(y * widget.getOriginalY() >> 14); + widget.setForcedY(); + } + else if (widget.getYPositionMode() == WidgetPositionMode.CENTER_16384THS) + { + widget.setRelativeY((y - widget.getHeight()) / 2 + (y * widget.getOriginalY() >> 14)); + widget.setForcedY(); + } + else + { + widget.setRelativeY(y - widget.getHeight() - (y * widget.getOriginalY() >> 14)); + widget.setForcedY(); + } + } } diff --git a/runescape-client/src/main/java/RuneLiteMenuEntry.java b/runescape-client/src/main/java/RuneLiteMenuEntry.java index 0ac7adf6e8..c9fd1c388e 100644 --- a/runescape-client/src/main/java/RuneLiteMenuEntry.java +++ b/runescape-client/src/main/java/RuneLiteMenuEntry.java @@ -1,8 +1,13 @@ import java.util.function.Consumer; +import net.runelite.api.Actor; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.api.events.NpcSpawned; import net.runelite.api.widgets.Widget; import net.runelite.rs.api.RSClient; +import net.runelite.rs.api.RSNPC; import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class RuneLiteMenuEntry implements MenuEntry @@ -455,6 +460,82 @@ public class RuneLiteMenuEntry implements MenuEntry return widget; } + @Override + public NPC getNpc() + { + NPC[] npcs = client.getCachedNPCs(); + NPC npc = null; + + MenuAction menuAction = this.getType(); + + if (menuAction == MenuAction.NPC_FIRST_OPTION || + menuAction == MenuAction.NPC_SECOND_OPTION || + menuAction == MenuAction.NPC_THIRD_OPTION || + menuAction == MenuAction.NPC_FOURTH_OPTION || + menuAction == MenuAction.NPC_FIFTH_OPTION || + menuAction == MenuAction.WIDGET_TARGET_ON_NPC) + { + int identifier = this.getIdentifier(); + + if (identifier >= 0 && identifier < npcs.length) + { + npc = npcs[identifier]; + } + } + + return npc; + } + + @Override + public Player getPlayer() + { + Player[] players = client.getCachedPlayers(); + Player player = null; + + MenuAction menuAction = this.getType(); + + if (menuAction == MenuAction.PLAYER_FIRST_OPTION || + menuAction == MenuAction.PLAYER_SECOND_OPTION || + menuAction == MenuAction.PLAYER_THIRD_OPTION || + menuAction == MenuAction.PLAYER_FOURTH_OPTION || + menuAction == MenuAction.PLAYER_FIFTH_OPTION || + menuAction == MenuAction.PLAYER_SIXTH_OPTION || + menuAction == MenuAction.PLAYER_SEVENTH_OPTION || + menuAction == MenuAction.PLAYER_EIGTH_OPTION || + menuAction == MenuAction.WIDGET_TARGET_ON_PLAYER || + menuAction == MenuAction.RUNELITE_PLAYER) + { + int identifier = this.getIdentifier(); + + if (identifier >= 0 && identifier < players.length) + { + player = players[identifier]; + } + } + + return player; + } + + @Override + public Actor getActor() + { + NPC npc = getNpc(); + + if (npc != null) + { + return npc; + } + + Player player = getPlayer(); + + if (player != null) + { + return player; + } + + return null; + } + @Override public int hashCode() {