diff --git a/runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java index 31bfc77f25..2153072fb8 100644 --- a/runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java +++ b/runelite-api/src/main/java/net/runelite/api/queries/BankItemQuery.java @@ -67,7 +67,7 @@ public class BankItemQuery extends WidgetItemQuery Rectangle bounds = child.getBounds(); bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); // Index is set to 0 because the widget's index does not correlate to the order in the bank - widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), 0, bounds, child)); + widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), 0, bounds, child, false)); } } return widgetItems; diff --git a/runelite-api/src/main/java/net/runelite/api/queries/DialogQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/DialogQuery.java index 426bdf00a4..0b4cfb8c03 100644 --- a/runelite-api/src/main/java/net/runelite/api/queries/DialogQuery.java +++ b/runelite-api/src/main/java/net/runelite/api/queries/DialogQuery.java @@ -73,7 +73,7 @@ public class DialogQuery extends WidgetItemQuery // set bounds to same size as default inventory Rectangle bounds = child.getBounds(); bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); - widgetItems.add(new WidgetItem(child.getId(), child.getItemQuantity(), i - 1, bounds, child)); + widgetItems.add(new WidgetItem(child.getId(), child.getItemQuantity(), i - 1, bounds, child, false)); } } return widgetItems; diff --git a/runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java index e6d4e2a588..9072dbeeda 100644 --- a/runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java +++ b/runelite-api/src/main/java/net/runelite/api/queries/InventoryWidgetItemQuery.java @@ -30,6 +30,7 @@ import java.util.Collection; import java.util.Objects; import java.util.stream.Collectors; import net.runelite.api.Client; +import net.runelite.api.Point; import net.runelite.api.QueryResults; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; @@ -79,10 +80,20 @@ public class InventoryWidgetItemQuery extends WidgetItemQuery for (int i = 0; i < children.length; i++) { Widget child = children[i]; + boolean isDragged = child.isWidgetItemDragged(child.getItemId()); + int dragOffsetX = 0; + int dragOffsetY = 0; + + if (isDragged) + { + Point p = child.getWidgetItemDragOffsets(); + dragOffsetX = p.getX(); + dragOffsetY = p.getY(); + } // set bounds to same size as default inventory Rectangle bounds = child.getBounds(); - bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); - widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), i, bounds, child)); + bounds.setBounds(bounds.x + dragOffsetX, bounds.y + dragOffsetY, 32, 32); + widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), i, bounds, child, isDragged)); } break; } diff --git a/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java index 92116d2b9a..a76851fe0a 100644 --- a/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java +++ b/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java @@ -60,7 +60,7 @@ public class ShopItemQuery extends WidgetItemQuery // set bounds to same size as default inventory Rectangle bounds = child.getBounds(); bounds.setBounds(bounds.x - 1, bounds.y - 1, 32, 32); - widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), i - 1, bounds, child)); + widgetItems.add(new WidgetItem(child.getItemId(), child.getItemQuantity(), i - 1, bounds, child, false)); // todo: maybe this shouldnt just be "false" } } return widgetItems; 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 b8cb626ae6..e003e30950 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 @@ -946,4 +946,8 @@ public interface Widget * @param args A ScriptID, then the args for the script */ void setOnReleaseListener(Object ...args); + + boolean isWidgetItemDragged(int index); + + Point getWidgetItemDragOffsets(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index 860b419548..803219035a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -83,7 +83,6 @@ import net.runelite.client.task.ScheduledMethod; import net.runelite.client.task.Scheduler; import net.runelite.client.ui.RuneLiteSplashScreen; import net.runelite.client.util.GameEventManager; -import net.runelite.client.util.ReflectUtil; @Singleton @Slf4j @@ -547,45 +546,10 @@ public class PluginManager return plugins; } - private void schedule(Plugin plugin) + public void schedule(Object plugin) { - for (Method method : plugin.getClass().getMethods()) - { - Schedule schedule = method.getAnnotation(Schedule.class); - - if (schedule == null) - { - continue; - } - - Runnable runnable = null; - try - { - final Class clazz = method.getDeclaringClass(); - final MethodHandles.Lookup caller = ReflectUtil.privateLookupIn(clazz); - final MethodType subscription = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); - final MethodHandle target = caller.findVirtual(clazz, method.getName(), subscription); - final CallSite site = LambdaMetafactory.metafactory( - caller, - "run", - MethodType.methodType(Runnable.class, clazz), - subscription, - target, - subscription); - - final MethodHandle factory = site.getTarget(); - runnable = (Runnable) factory.bindTo(plugin).invokeExact(); - } - catch (Throwable e) - { - log.warn("Unable to create lambda for method {}", method, e); - } - - ScheduledMethod scheduledMethod = new ScheduledMethod(schedule, method, plugin, runnable); - log.debug("Scheduled task {}", scheduledMethod); - - scheduler.addScheduledMethod(scheduledMethod); - } + // note to devs: this method will almost certainly merge conflict in the future, just apply the changes in the scheduler instead + scheduler.registerObject(plugin); } private void unschedule(Plugin plugin) diff --git a/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java b/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java index c4d5405925..8fcba6baf1 100644 --- a/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java +++ b/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java @@ -24,6 +24,11 @@ */ package net.runelite.client.task; +import java.lang.invoke.CallSite; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.time.Duration; @@ -62,15 +67,41 @@ public class Scheduler public void registerObject(Object obj) { - for (Method method : obj.getClass().getDeclaredMethods()) + for (Method method : obj.getClass().getMethods()) { Schedule schedule = method.getAnnotation(Schedule.class); + if (schedule == null) { continue; } - ScheduledMethod scheduledMethod = new ScheduledMethod(schedule, method, obj); + Runnable runnable = null; + try + { + final Class clazz = method.getDeclaringClass(); + final MethodHandles.Lookup caller = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); + final MethodType subscription = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); + final MethodHandle target = caller.findVirtual(clazz, method.getName(), subscription); + final CallSite site = LambdaMetafactory.metafactory( + caller, + "run", + MethodType.methodType(Runnable.class, clazz), + subscription, + target, + subscription); + + final MethodHandle factory = site.getTarget(); + runnable = (Runnable) factory.bindTo(obj).invokeExact(); + } + catch (Throwable e) + { + log.warn("Unable to create lambda for method {}", method, e); + } + + ScheduledMethod scheduledMethod = new ScheduledMethod(schedule, method, obj, runnable); + log.debug("Scheduled task {}", scheduledMethod); + addScheduledMethod(scheduledMethod); } } 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 4ba47a93fd..faa87bf2d1 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1529,7 +1529,7 @@ public abstract class RSClientMixin implements RSClient { if (renderX >= minX && renderX <= maxX && renderY >= minY && renderY <= maxY) { - WidgetItem widgetItem = new WidgetItem(widget.getItemId(), widget.getItemQuantity(), -1, widget.getBounds(), widget); + WidgetItem widgetItem = new WidgetItem(widget.getItemId(), widget.getItemQuantity(), -1, widget.getBounds(), widget, false); callbacks.drawItem(widget.getItemId(), widgetItem); } } 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 466baf67d1..f10da765f4 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -24,11 +24,6 @@ */ package net.runelite.mixins; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; import net.runelite.api.HashTable; import net.runelite.api.Node; import net.runelite.api.Point; @@ -42,8 +37,6 @@ import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; 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.rs.api.RSClient; import net.runelite.rs.api.RSModel; @@ -52,24 +45,26 @@ import net.runelite.rs.api.RSNodeHashTable; import net.runelite.rs.api.RSPlayerAppearance; import net.runelite.rs.api.RSSequenceDefinition; import net.runelite.rs.api.RSWidget; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import static net.runelite.api.widgets.WidgetInfo.TO_CHILD; +import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; @Mixin(RSWidget.class) public abstract class RSWidgetMixin implements RSWidget { private static final int ITEM_SLOT_SIZE = 32; - @Shadow("client") private static RSClient client; - @Inject private static int rl$widgetLastPosChanged; - @Inject private int rl$parentId; - @Inject private int rl$x; - @Inject private int rl$y; @@ -295,8 +290,19 @@ public abstract class RSWidgetMixin implements RSWidget int itemX = rl$x + ((ITEM_SLOT_SIZE + xPitch) * col); int itemY = rl$y + ((ITEM_SLOT_SIZE + yPitch) * row); - Rectangle bounds = new Rectangle(itemX, itemY, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE); - return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this); + boolean isDragged = isWidgetItemDragged(index); + int dragOffsetX = 0; + int dragOffsetY = 0; + + if (isDragged) + { + Point p = getWidgetItemDragOffsets(); + dragOffsetX = p.getX(); + dragOffsetY = p.getY(); + } + + Rectangle bounds = new Rectangle(itemX + dragOffsetX, itemY + dragOffsetY, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE); + return new WidgetItem(itemId - 1, itemQuantity, index, bounds, this, isDragged); } @Inject @@ -587,4 +593,31 @@ public abstract class RSWidgetMixin implements RSWidget } return rs$getModel(sequence, frame, alternate, playerComposition); } + + @Inject + @Override + public boolean isWidgetItemDragged(int index) + { + return client.getIf1DraggedWidget() == this && client.getItemPressedDuration() >= 5 && + client.getIf1DraggedItemIndex() == index; + } + + @Inject + public Point getWidgetItemDragOffsets() + { + int dragOffsetX = client.getMouseX() - client.getDraggedWidgetX(); + int dragOffsetY = client.getMouseY() - client.getDraggedWidgetY(); + + if (dragOffsetX < 5 && dragOffsetX > -5) + { + dragOffsetX = 0; + } + + if (dragOffsetY < 5 && dragOffsetY > -5) + { + dragOffsetY = 0; + } + + return new Point(dragOffsetX, dragOffsetY); + } } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 9c10487a47..3d30a06166 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -1146,4 +1146,10 @@ public interface RSClient extends RSGameShell, Client @Import("showMouseCross") @Override void setShowMouseCross(boolean show); + + @Import("draggedWidgetX") + int getDraggedWidgetX(); // these should probably have if1 in their names somewhere + + @Import("draggedWidgetY") + int getDraggedWidgetY(); } diff --git a/runescape-client/src/main/java/Client.java b/runescape-client/src/main/java/Client.java index 7eeccb4ce8..a1a6af5193 100644 --- a/runescape-client/src/main/java/Client.java +++ b/runescape-client/src/main/java/Client.java @@ -1049,12 +1049,14 @@ public final class Client extends GameShell implements Usernamed { @ObfuscatedGetter( intValue = 1858822219 ) - static int field863; + @Export("draggedWidgetX") + static int draggedWidgetX; @ObfuscatedName("jd") @ObfuscatedGetter( intValue = 1449162079 ) - static int field738; + @Export("draggedWidgetY") + static int draggedWidgetY; @ObfuscatedName("jy") @ObfuscatedGetter( intValue = -1787846911 @@ -1372,8 +1374,8 @@ public final class Client extends GameShell implements Usernamed { field764 = 0; field735 = 0; dragItemSlotSource = 0; - field863 = 0; - field738 = 0; + draggedWidgetX = 0; + draggedWidgetY = 0; dragItemSlotDestination = 0; field768 = false; itemDragDuration = 0; @@ -3765,10 +3767,10 @@ public final class Client extends GameShell implements Usernamed { packetWriter.addNode(var27); } } else if (this.shouldLeftClickOpenMenu()) { - this.openMenu(field863, field738); + this.openMenu(draggedWidgetX, draggedWidgetY); } else if (menuOptionsCount > 0) { - var4 = field863; - var5 = field738; + var4 = draggedWidgetX; + var5 = draggedWidgetY; Messages.method2231(LoginType.tempMenuAction, var4, var5); LoginType.tempMenuAction = null; } @@ -3776,7 +3778,7 @@ public final class Client extends GameShell implements Usernamed { field764 = 10; MouseHandler.MouseHandler_lastButton = 0; ClientPreferences.dragInventoryWidget = null; - } else if (itemDragDuration >= 5 && (MouseHandler.MouseHandler_x > field863 + 5 || MouseHandler.MouseHandler_x < field863 - 5 || MouseHandler.MouseHandler_y > field738 + 5 || MouseHandler.MouseHandler_y < field738 - 5)) { + } else if (itemDragDuration >= 5 && (MouseHandler.MouseHandler_x > draggedWidgetX + 5 || MouseHandler.MouseHandler_x < draggedWidgetX - 5 || MouseHandler.MouseHandler_y > draggedWidgetY + 5 || MouseHandler.MouseHandler_y < draggedWidgetY - 5)) { field768 = true; } } @@ -5795,8 +5797,8 @@ public final class Client extends GameShell implements Usernamed { } if (ClientPreferences.dragInventoryWidget != null && !field768 && menuOptionsCount > 0 && !this.shouldLeftClickOpenMenu()) { - var13 = field863; - var10 = field738; + var13 = draggedWidgetX; + var10 = draggedWidgetY; Messages.method2231(LoginType.tempMenuAction, var13, var10); LoginType.tempMenuAction = null; } @@ -5809,8 +5811,8 @@ public final class Client extends GameShell implements Usernamed { ClientPreferences.dragInventoryWidget = Tile.getWidget(var5); dragItemSlotSource = var4; - field863 = MouseHandler.MouseHandler_lastPressedX; - field738 = MouseHandler.MouseHandler_lastPressedY; + draggedWidgetX = MouseHandler.MouseHandler_lastPressedX; + draggedWidgetY = MouseHandler.MouseHandler_lastPressedY; if (var2 >= 0) { BuddyRankComparator.method3361(var2); } diff --git a/runescape-client/src/main/java/UserComparator7.java b/runescape-client/src/main/java/UserComparator7.java index 92842c9f5d..639faa4ff2 100644 --- a/runescape-client/src/main/java/UserComparator7.java +++ b/runescape-client/src/main/java/UserComparator7.java @@ -400,8 +400,8 @@ public class UserComparator7 extends AbstractUserComparator { if (var27 != null) { if (var10 == ClientPreferences.dragInventoryWidget && var30 == Client.dragItemSlotSource) { - var24 = MouseHandler.MouseHandler_x - Client.field863; - var25 = MouseHandler.MouseHandler_y - Client.field738; + var24 = MouseHandler.MouseHandler_x - Client.draggedWidgetX; + var25 = MouseHandler.MouseHandler_y - Client.draggedWidgetY; if (var24 < 5 && var24 > -5) { var24 = 0; } @@ -430,7 +430,7 @@ public class UserComparator7 extends AbstractUserComparator { } var28.scrollY -= var29; - Client.field738 += var29; + Client.draggedWidgetY += var29; LoginPacket.invalidateWidget(var28); } @@ -445,7 +445,7 @@ public class UserComparator7 extends AbstractUserComparator { } var28.scrollY += var29; - Client.field738 -= var29; + Client.draggedWidgetY -= var29; LoginPacket.invalidateWidget(var28); } }