project: Update mixins
This commit is contained in:
@@ -1838,6 +1838,11 @@ public interface Client extends GameShell
|
||||
*/
|
||||
int getItemCount();
|
||||
|
||||
/**
|
||||
* Makes all widgets behave as if they are {@link WidgetConfig#WIDGET_USE_TARGET}
|
||||
*/
|
||||
void setAllWidgetsAreOpTargetable(boolean value);
|
||||
|
||||
/**
|
||||
* Adds a MenuEntry to the current menu.
|
||||
*/
|
||||
|
||||
@@ -232,6 +232,11 @@ public enum MenuOpcode
|
||||
*/
|
||||
WIDGET_DEFAULT(57),
|
||||
|
||||
/**
|
||||
* Casting a spell / op target on a widget
|
||||
*/
|
||||
SPELL_CAST_ON_WIDGET(58),
|
||||
|
||||
/**
|
||||
* Sub 1000 so it doesn't get sorted down in the list
|
||||
*/
|
||||
|
||||
@@ -65,4 +65,5 @@ public interface WallObject extends TileObject
|
||||
* @see net.runelite.api.model.Jarvis
|
||||
*/
|
||||
Shape getConvexHull();
|
||||
Shape getConvexHull2();
|
||||
}
|
||||
|
||||
@@ -247,6 +247,11 @@ public class MenuManager
|
||||
|
||||
private void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (client.isSpellSelected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (AbstractComparableEntry e : hiddenEntries)
|
||||
{
|
||||
if (e.matches(event))
|
||||
|
||||
@@ -37,8 +37,6 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
@@ -76,9 +74,6 @@ import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||
@Singleton
|
||||
class DevToolsOverlay extends Overlay
|
||||
{
|
||||
private static final int ITEM_EMPTY = 6512;
|
||||
private static final int ITEM_FILLED = 20594;
|
||||
|
||||
private static final Font FONT = FontManager.getRunescapeFont().deriveFont(Font.BOLD, 16);
|
||||
private static final Color RED = new Color(221, 44, 0);
|
||||
private static final Color GREEN = new Color(0, 200, 83);
|
||||
@@ -97,13 +92,6 @@ class DevToolsOverlay extends Overlay
|
||||
private final DevToolsPlugin plugin;
|
||||
private final TooltipManager toolTipManager;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private Widget widget;
|
||||
|
||||
@Setter
|
||||
private int itemIndex = -1;
|
||||
|
||||
@Inject
|
||||
private DevToolsOverlay(Client client, DevToolsPlugin plugin, TooltipManager toolTipManager)
|
||||
{
|
||||
@@ -155,8 +143,6 @@ class DevToolsOverlay extends Overlay
|
||||
renderCursorTooltip(graphics);
|
||||
}
|
||||
|
||||
renderWidgets(graphics);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -490,70 +476,6 @@ class DevToolsOverlay extends Overlay
|
||||
}
|
||||
}
|
||||
|
||||
private void renderWidgets(Graphics2D graphics)
|
||||
{
|
||||
if (widget == null || widget.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rectangle childBounds = widget.getBounds();
|
||||
graphics.setColor(CYAN);
|
||||
graphics.draw(childBounds);
|
||||
|
||||
if (itemIndex == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (widget.getItemId() != ITEM_EMPTY
|
||||
&& widget.getItemId() != ITEM_FILLED)
|
||||
{
|
||||
Rectangle componentBounds = widget.getBounds();
|
||||
|
||||
graphics.setColor(ORANGE);
|
||||
graphics.draw(componentBounds);
|
||||
|
||||
renderWidgetText(graphics, componentBounds, widget.getItemId(), YELLOW);
|
||||
}
|
||||
|
||||
WidgetItem widgetItem = widget.getWidgetItem(itemIndex);
|
||||
if (widgetItem == null
|
||||
|| widgetItem.getId() < 0
|
||||
|| widgetItem.getId() == ITEM_EMPTY
|
||||
|| widgetItem.getId() == ITEM_FILLED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rectangle itemBounds = widgetItem.getCanvasBounds();
|
||||
|
||||
graphics.setColor(ORANGE);
|
||||
graphics.draw(itemBounds);
|
||||
|
||||
renderWidgetText(graphics, itemBounds, widgetItem.getId(), YELLOW);
|
||||
}
|
||||
|
||||
private void renderWidgetText(Graphics2D graphics, Rectangle bounds, int itemId, Color color)
|
||||
{
|
||||
if (itemId == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String text = itemId + "";
|
||||
FontMetrics fm = graphics.getFontMetrics();
|
||||
Rectangle2D textBounds = fm.getStringBounds(text, graphics);
|
||||
|
||||
int textX = (int) (bounds.getX() + (bounds.getWidth() / 2) - (textBounds.getWidth() / 2));
|
||||
int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (textBounds.getHeight() / 2));
|
||||
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawString(text, textX + 1, textY + 1);
|
||||
graphics.setColor(color);
|
||||
graphics.drawString(text, textX, textY);
|
||||
}
|
||||
|
||||
private void renderPlayerWireframe(Graphics2D graphics, Player player, Color color)
|
||||
{
|
||||
Polygon[] polys = player.getPolygons();
|
||||
|
||||
@@ -27,13 +27,20 @@
|
||||
package net.runelite.client.plugins.devtools;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFrame;
|
||||
@@ -45,29 +52,67 @@ import javax.swing.JTree;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.MenuOpcode;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetConfig;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
class WidgetInspector extends JFrame
|
||||
{
|
||||
private static final Map<Integer, WidgetInfo> widgetIdMap = new HashMap<>();
|
||||
|
||||
static final Color SELECTED_WIDGET_COLOR = Color.CYAN;
|
||||
private static final float SELECTED_WIDGET_HUE;
|
||||
|
||||
static
|
||||
{
|
||||
float[] hsb = new float[3];
|
||||
Color.RGBtoHSB(SELECTED_WIDGET_COLOR.getRed(), SELECTED_WIDGET_COLOR.getGreen(), SELECTED_WIDGET_COLOR.getBlue(), hsb);
|
||||
SELECTED_WIDGET_HUE = hsb[0];
|
||||
}
|
||||
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
private final DevToolsConfig config;
|
||||
private final DevToolsOverlay overlay;
|
||||
private final Provider<WidgetInspectorOverlay> overlay;
|
||||
private final OverlayManager overlayManager;
|
||||
|
||||
private final JTree widgetTree;
|
||||
private final WidgetInfoTableModel infoTableModel;
|
||||
private final JCheckBox alwaysOnTop;
|
||||
private final JCheckBox hideHidden;
|
||||
|
||||
private static final Map<Integer, WidgetInfo> widgetIdMap = new HashMap<>();
|
||||
private DefaultMutableTreeNode root;
|
||||
|
||||
@Getter
|
||||
private Widget selectedWidget;
|
||||
|
||||
@Getter
|
||||
private int selectedItem;
|
||||
|
||||
private Widget picker = null;
|
||||
|
||||
@Getter
|
||||
private boolean pickerSelected = false;
|
||||
|
||||
@Inject
|
||||
private WidgetInspector(
|
||||
@@ -75,17 +120,21 @@ class WidgetInspector extends JFrame
|
||||
ClientThread clientThread,
|
||||
WidgetInfoTableModel infoTableModel,
|
||||
DevToolsConfig config,
|
||||
DevToolsPlugin plugin,
|
||||
EventBus eventBus,
|
||||
DevToolsOverlay overlay,
|
||||
DevToolsPlugin plugin)
|
||||
Provider<WidgetInspectorOverlay> overlay,
|
||||
OverlayManager overlayManager)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
this.infoTableModel = infoTableModel;
|
||||
this.config = config;
|
||||
this.overlay = overlay;
|
||||
this.overlayManager = overlayManager;
|
||||
|
||||
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked);
|
||||
eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded);
|
||||
|
||||
setTitle("RuneLite Widget Inspector");
|
||||
setIconImage(ClientUI.ICON);
|
||||
@@ -96,7 +145,6 @@ class WidgetInspector extends JFrame
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e)
|
||||
{
|
||||
eventBus.unregister(this);
|
||||
close();
|
||||
plugin.getWidgetInspector().setActive(false);
|
||||
}
|
||||
@@ -114,16 +162,12 @@ class WidgetInspector extends JFrame
|
||||
{
|
||||
WidgetTreeNode node = (WidgetTreeNode) selected;
|
||||
Widget widget = node.getWidget();
|
||||
overlay.setWidget(widget);
|
||||
overlay.setItemIndex(widget.getItemId());
|
||||
refreshInfo();
|
||||
log.debug("Set widget to {} and item index to {}", widget, widget.getItemId());
|
||||
setSelectedWidget(widget, -1, false);
|
||||
}
|
||||
else if (selected instanceof WidgetItemNode)
|
||||
{
|
||||
WidgetItemNode node = (WidgetItemNode) selected;
|
||||
overlay.setItemIndex(node.getWidgetItem().getIndex());
|
||||
log.debug("Set item index to {}", node.getWidgetItem().getIndex());
|
||||
setSelectedWidget(node.getWidgetItem().getWidget(), node.getWidgetItem().getIndex(), false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -149,15 +193,20 @@ class WidgetInspector extends JFrame
|
||||
onConfigChanged(null);
|
||||
bottomPanel.add(alwaysOnTop);
|
||||
|
||||
hideHidden = new JCheckBox("Hide hidden");
|
||||
hideHidden.setSelected(true);
|
||||
hideHidden.addItemListener(ev -> refreshWidgets());
|
||||
bottomPanel.add(hideHidden);
|
||||
|
||||
final JButton revalidateWidget = new JButton("Revalidate");
|
||||
revalidateWidget.addActionListener(ev -> clientThread.invokeLater(() ->
|
||||
{
|
||||
if (overlay.getWidget() == null)
|
||||
if (selectedWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
overlay.getWidget().revalidate();
|
||||
selectedWidget.revalidate();
|
||||
}));
|
||||
bottomPanel.add(revalidateWidget);
|
||||
|
||||
@@ -165,7 +214,6 @@ class WidgetInspector extends JFrame
|
||||
add(split, BorderLayout.CENTER);
|
||||
|
||||
pack();
|
||||
|
||||
}
|
||||
|
||||
private void onConfigChanged(ConfigChanged ev)
|
||||
@@ -180,10 +228,13 @@ class WidgetInspector extends JFrame
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
Widget[] rootWidgets = client.getWidgetRoots();
|
||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
|
||||
root = new DefaultMutableTreeNode();
|
||||
|
||||
overlay.setWidget(null);
|
||||
overlay.setItemIndex(-1);
|
||||
Widget wasSelectedWidget = selectedWidget;
|
||||
int wasSelectedItem = selectedItem;
|
||||
|
||||
selectedWidget = null;
|
||||
selectedItem = -1;
|
||||
|
||||
for (Widget widget : rootWidgets)
|
||||
{
|
||||
@@ -196,17 +247,15 @@ class WidgetInspector extends JFrame
|
||||
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
overlay.setWidget(null);
|
||||
overlay.setItemIndex(-1);
|
||||
refreshInfo();
|
||||
widgetTree.setModel(new DefaultTreeModel(root));
|
||||
setSelectedWidget(wasSelectedWidget, wasSelectedItem, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private DefaultMutableTreeNode addWidget(String type, Widget widget)
|
||||
{
|
||||
if (widget == null || widget.isHidden())
|
||||
if (widget == null || (hideHidden.isSelected() && widget.isHidden()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -269,9 +318,70 @@ class WidgetInspector extends JFrame
|
||||
return node;
|
||||
}
|
||||
|
||||
private void refreshInfo()
|
||||
private void setSelectedWidget(Widget widget, int item, boolean updateTree)
|
||||
{
|
||||
infoTableModel.setWidget(overlay.getWidget());
|
||||
infoTableModel.setWidget(widget);
|
||||
|
||||
if (this.selectedWidget == widget && this.selectedItem == item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectedWidget = widget;
|
||||
this.selectedItem = item;
|
||||
|
||||
if (root == null || !updateTree)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
Stack<Widget> treePath = new Stack<>();
|
||||
for (Widget w = widget; w != null; w = w.getParent())
|
||||
{
|
||||
treePath.push(w);
|
||||
}
|
||||
|
||||
DefaultMutableTreeNode node = root;
|
||||
deeper:
|
||||
for (; !treePath.empty(); )
|
||||
{
|
||||
Widget w = treePath.pop();
|
||||
for (Enumeration<?> it = node.children(); it.hasMoreElements(); )
|
||||
{
|
||||
WidgetTreeNode inner = (WidgetTreeNode) it.nextElement();
|
||||
if (inner.getWidget().getId() == w.getId() && inner.getWidget().getIndex() == w.getIndex())
|
||||
{
|
||||
node = inner;
|
||||
continue deeper;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectedItem != -1)
|
||||
{
|
||||
for (Enumeration<?> it = node.children(); it.hasMoreElements(); )
|
||||
{
|
||||
Object wiw = it.nextElement();
|
||||
if (wiw instanceof WidgetItemNode)
|
||||
{
|
||||
WidgetItemNode inner = (WidgetItemNode) wiw;
|
||||
if (inner.getWidgetItem().getIndex() == selectedItem)
|
||||
{
|
||||
node = inner;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final DefaultMutableTreeNode fnode = node;
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
widgetTree.getSelectionModel().clearSelection();
|
||||
widgetTree.getSelectionModel().addSelectionPath(new TreePath(fnode.getPath()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static WidgetInfo getWidgetInfo(int packedId)
|
||||
@@ -295,12 +405,176 @@ class WidgetInspector extends JFrame
|
||||
setVisible(true);
|
||||
toFront();
|
||||
repaint();
|
||||
overlayManager.add(this.overlay.get());
|
||||
clientThread.invokeLater(this::addPickerWidget);
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
overlay.setWidget(null);
|
||||
overlay.setItemIndex(-1);
|
||||
overlayManager.remove(this.overlay.get());
|
||||
clientThread.invokeLater(this::removePickerWidget);
|
||||
setSelectedWidget(null, -1, false);
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void removePickerWidget()
|
||||
{
|
||||
if (picker == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget parent = picker.getParent();
|
||||
if (parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget[] children = parent.getChildren();
|
||||
if (children == null || children.length <= picker.getIndex() || children[picker.getIndex()] != picker)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
children[picker.getIndex()] = null;
|
||||
}
|
||||
|
||||
private void addPickerWidget()
|
||||
{
|
||||
removePickerWidget();
|
||||
|
||||
int x = 10, y = 2;
|
||||
Widget parent = client.getWidget(WidgetInfo.MINIMAP_ORBS);
|
||||
if (parent == null)
|
||||
{
|
||||
Widget[] roots = client.getWidgetRoots();
|
||||
|
||||
parent = Stream.of(roots)
|
||||
.filter(w -> w.getType() == WidgetType.LAYER && w.getContentType() == 0 && !w.isSelfHidden())
|
||||
.sorted(Comparator.comparing((Widget w) -> w.getRelativeX() + w.getRelativeY())
|
||||
.reversed()
|
||||
.thenComparing(Widget::getId)
|
||||
.reversed())
|
||||
.findFirst().get();
|
||||
x = 4;
|
||||
y = 4;
|
||||
}
|
||||
|
||||
picker = parent.createChild(-1, WidgetType.GRAPHIC);
|
||||
|
||||
log.info("Picker is {}.{} [{}]", WidgetInfo.TO_GROUP(picker.getId()), WidgetInfo.TO_CHILD(picker.getId()), picker.getIndex());
|
||||
|
||||
picker.setSpriteId(SpriteID.MOBILE_FINGER_ON_INTERFACE);
|
||||
picker.setOriginalWidth(15);
|
||||
picker.setOriginalHeight(17);
|
||||
picker.setOriginalX(x);
|
||||
picker.setOriginalY(y);
|
||||
picker.revalidate();
|
||||
picker.setTargetVerb("Select");
|
||||
picker.setName("Pick");
|
||||
picker.setClickMask(WidgetConfig.USE_WIDGET | WidgetConfig.USE_ITEM);
|
||||
picker.setNoClickThrough(true);
|
||||
picker.setOnTargetEnterListener((JavaScriptCallback) ev ->
|
||||
{
|
||||
pickerSelected = true;
|
||||
picker.setOpacity(30);
|
||||
client.setAllWidgetsAreOpTargetable(true);
|
||||
});
|
||||
picker.setOnTargetLeaveListener((JavaScriptCallback) ev -> onPickerDeselect());
|
||||
}
|
||||
|
||||
private void onPickerDeselect()
|
||||
{
|
||||
client.setAllWidgetsAreOpTargetable(false);
|
||||
picker.setOpacity(0);
|
||||
pickerSelected = false;
|
||||
}
|
||||
|
||||
private void onMenuOptionClicked(MenuOptionClicked ev)
|
||||
{
|
||||
if (!pickerSelected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
onPickerDeselect();
|
||||
client.setSpellSelected(false);
|
||||
ev.consume();
|
||||
|
||||
Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuOpcode().getId(), ev.getParam0(), ev.getParam1());
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (target instanceof WidgetItem)
|
||||
{
|
||||
WidgetItem iw = (WidgetItem) target;
|
||||
setSelectedWidget(iw.getWidget(), iw.getIndex(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelectedWidget((Widget) target, -1, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (!pickerSelected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
|
||||
for (int i = 0; i < menuEntries.length; i++)
|
||||
{
|
||||
MenuEntry entry = menuEntries[i];
|
||||
if (entry.getOpcode() != MenuOpcode.ITEM_USE_ON_WIDGET.getId()
|
||||
&& entry.getOpcode() != MenuOpcode.SPELL_CAST_ON_WIDGET.getId())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String name = WidgetInfo.TO_GROUP(entry.getParam1()) + "." + WidgetInfo.TO_CHILD(entry.getParam1());
|
||||
|
||||
if (entry.getParam0() != -1)
|
||||
{
|
||||
name += " [" + entry.getParam0() + "]";
|
||||
}
|
||||
|
||||
Color color = colorForWidget(i, menuEntries.length);
|
||||
|
||||
entry.setTarget(ColorUtil.wrapWithColorTag(name, color));
|
||||
}
|
||||
|
||||
client.setMenuEntries(menuEntries);
|
||||
}
|
||||
|
||||
Color colorForWidget(int index, int length)
|
||||
{
|
||||
float h = SELECTED_WIDGET_HUE + .1f + (.8f / length) * index;
|
||||
|
||||
return Color.getHSBColor(h, 1, 1);
|
||||
}
|
||||
|
||||
Object getWidgetOrWidgetItemForMenuOption(int type, int param0, int param1)
|
||||
{
|
||||
if (type == MenuOpcode.SPELL_CAST_ON_WIDGET.getId())
|
||||
{
|
||||
Widget w = client.getWidget(WidgetInfo.TO_GROUP(param1), WidgetInfo.TO_CHILD(param1));
|
||||
if (param0 != -1)
|
||||
{
|
||||
w = w.getChild(param0);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
else if (type == MenuOpcode.ITEM_USE_ON_WIDGET.getId())
|
||||
{
|
||||
Widget w = client.getWidget(WidgetInfo.TO_GROUP(param1), WidgetInfo.TO_CHILD(param1));
|
||||
return w.getWidgetItem(param0);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* Copyright (c) 2017, Kronos <https://github.com/KronosDesign>
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.devtools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
|
||||
@Singleton
|
||||
public class WidgetInspectorOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final WidgetInspector inspector;
|
||||
|
||||
@Inject
|
||||
public WidgetInspectorOverlay(
|
||||
Client client,
|
||||
WidgetInspector inspector
|
||||
)
|
||||
{
|
||||
this.client = client;
|
||||
this.inspector = inspector;
|
||||
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
Widget w = inspector.getSelectedWidget();
|
||||
if (w != null)
|
||||
{
|
||||
Object wiw = w;
|
||||
if (inspector.getSelectedItem() != -1)
|
||||
{
|
||||
wiw = w.getWidgetItem(inspector.getSelectedItem());
|
||||
}
|
||||
|
||||
renderWiw(g, wiw, WidgetInspector.SELECTED_WIDGET_COLOR);
|
||||
}
|
||||
|
||||
if (inspector.isPickerSelected())
|
||||
{
|
||||
boolean menuOpen = client.isMenuOpen();
|
||||
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
for (int i = menuOpen ? 0 : entries.length - 1; i < entries.length; i++)
|
||||
{
|
||||
MenuEntry e = entries[i];
|
||||
|
||||
Object wiw = inspector.getWidgetOrWidgetItemForMenuOption(e.getOpcode(), e.getParam0(), e.getParam1());
|
||||
if (wiw == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Color color = inspector.colorForWidget(i, entries.length);
|
||||
renderWiw(g, wiw, color);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderWiw(Graphics2D g, Object wiw, Color color)
|
||||
{
|
||||
g.setColor(color);
|
||||
|
||||
if (wiw instanceof WidgetItem)
|
||||
{
|
||||
WidgetItem wi = (WidgetItem) wiw;
|
||||
Rectangle bounds = wi.getCanvasBounds();
|
||||
g.draw(bounds);
|
||||
|
||||
String text = wi.getId() + "";
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
Rectangle2D textBounds = fm.getStringBounds(text, g);
|
||||
|
||||
int textX = (int) (bounds.getX() + (bounds.getWidth() / 2) - (textBounds.getWidth() / 2));
|
||||
int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (textBounds.getHeight() / 2));
|
||||
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawString(text, textX + 1, textY + 1);
|
||||
g.setColor(Color.ORANGE);
|
||||
g.drawString(text, textX, textY);
|
||||
}
|
||||
else
|
||||
{
|
||||
Widget w = (Widget) wiw;
|
||||
g.draw(w.getBounds());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import net.runelite.api.Client;
|
||||
import net.runelite.api.DecorativeObject;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.client.graphics.ModelOutlineRenderer;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
@@ -107,6 +108,11 @@ class ObjectIndicatorsOverlay extends Overlay
|
||||
{
|
||||
polygon = ((GameObject) object).getConvexHull();
|
||||
}
|
||||
else if (object instanceof WallObject)
|
||||
{
|
||||
polygon = ((WallObject) object).getConvexHull();
|
||||
polygon2 = ((WallObject) object).getConvexHull2();
|
||||
}
|
||||
else if (object instanceof DecorativeObject)
|
||||
{
|
||||
polygon = ((DecorativeObject) object).getConvexHull();
|
||||
|
||||
@@ -38,21 +38,25 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.REGION_SIZE;
|
||||
import net.runelite.api.DecorativeObject;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GroundObject;
|
||||
import net.runelite.api.MenuOpcode;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.ObjectDefinition;
|
||||
import net.runelite.api.Scene;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.DecorativeObjectDespawned;
|
||||
@@ -61,8 +65,13 @@ import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GroundObjectDespawned;
|
||||
import net.runelite.api.events.GroundObjectSpawned;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.WallObjectChanged;
|
||||
import net.runelite.api.events.WallObjectDespawned;
|
||||
import net.runelite.api.events.WallObjectSpawned;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
@@ -78,6 +87,7 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
private static final String CONFIG_GROUP = "objectindicators";
|
||||
@@ -152,10 +162,15 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventbus.subscribe(FocusChanged.class, this, this::onFocusChanged);
|
||||
eventbus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned);
|
||||
eventbus.subscribe(WallObjectChanged.class, this, this::onWallObjectChanged);
|
||||
eventbus.subscribe(WallObjectDespawned.class, this, this::onWallObjectDespawned);
|
||||
eventbus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned);
|
||||
eventbus.subscribe(DecorativeObjectSpawned.class, this, this::onDecorativeObjectSpawned);
|
||||
eventbus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned);
|
||||
eventbus.subscribe(DecorativeObjectDespawned.class, this, this::onDecorativeObjectDespawned);
|
||||
eventbus.subscribe(GroundObjectDespawned.class, this, this::onGroundObjectDespawned);
|
||||
eventbus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned);
|
||||
eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventbus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked);
|
||||
eventbus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded);
|
||||
@@ -193,6 +208,25 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
}
|
||||
}
|
||||
|
||||
private void onWallObjectSpawned(WallObjectSpawned event)
|
||||
{
|
||||
checkObjectPoints(event.getWallObject());
|
||||
}
|
||||
|
||||
private void onWallObjectChanged(WallObjectChanged event)
|
||||
{
|
||||
WallObject previous = event.getPrevious();
|
||||
WallObject wallObject = event.getWallObject();
|
||||
|
||||
objects.remove(previous);
|
||||
checkObjectPoints(wallObject);
|
||||
}
|
||||
|
||||
private void onWallObjectDespawned(WallObjectDespawned event)
|
||||
{
|
||||
objects.remove(event.getWallObject());
|
||||
}
|
||||
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject eventObject = event.getGameObject();
|
||||
@@ -215,6 +249,18 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
objects.remove(event.getDecorativeObject());
|
||||
}
|
||||
|
||||
private void onGroundObjectSpawned(GroundObjectSpawned groundObjectSpawned)
|
||||
{
|
||||
final GroundObject groundObject = groundObjectSpawned.getGroundObject();
|
||||
checkObjectPoints(groundObject);
|
||||
}
|
||||
|
||||
private void onGroundObjectDespawned(GroundObjectDespawned groundObjectDespawned)
|
||||
{
|
||||
GroundObject groundObject = groundObjectDespawned.getGroundObject();
|
||||
objects.remove(groundObject);
|
||||
}
|
||||
|
||||
private void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
GameState gameState = gameStateChanged.getGameState();
|
||||
@@ -283,9 +329,13 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectDefinition objectDefinition = client.getObjectDefinition(object.getId());
|
||||
// object.getId() is always the base object id, getObjectComposition transforms it to
|
||||
// the correct object we see
|
||||
ObjectDefinition objectDefinition = getObjectDefinition(object.getId());
|
||||
String name = objectDefinition.getName();
|
||||
if (Strings.isNullOrEmpty(name))
|
||||
// Name is probably never "null" - however prevent adding it if it is, as it will
|
||||
// become ambiguous as objects with no name are assigned name "null"
|
||||
if (Strings.isNullOrEmpty(name) || name.equals("null"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -306,11 +356,15 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
for (ObjectPoint objectPoint : objectPoints)
|
||||
{
|
||||
if ((worldPoint.getX() & (REGION_SIZE - 1)) == objectPoint.getRegionX()
|
||||
&& (worldPoint.getY() & (REGION_SIZE - 1)) == objectPoint.getRegionY()
|
||||
&& objectPoint.getName().equals(client.getObjectDefinition(object.getId()).getName()))
|
||||
&& (worldPoint.getY() & (REGION_SIZE - 1)) == objectPoint.getRegionY())
|
||||
{
|
||||
objects.add(object);
|
||||
break;
|
||||
// Transform object to get the name which matches against what we've stored
|
||||
if (objectPoint.getName().equals(getObjectDefinition(object.getId()).getName()))
|
||||
{
|
||||
log.debug("Marking object {} due to matching {}", object, objectPoint);
|
||||
objects.add(object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,42 +378,65 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
|
||||
final GameObject[] tileGameObjects = tile.getGameObjects();
|
||||
final DecorativeObject tileDecorativeObject = tile.getDecorativeObject();
|
||||
final WallObject tileWallObject = tile.getWallObject();
|
||||
final GroundObject groundObject = tile.getGroundObject();
|
||||
|
||||
if (tileDecorativeObject != null && tileDecorativeObject.getId() == id)
|
||||
if (objectIdEquals(tileWallObject, id))
|
||||
{
|
||||
return tileWallObject;
|
||||
}
|
||||
|
||||
if (objectIdEquals(tileDecorativeObject, id))
|
||||
{
|
||||
return tileDecorativeObject;
|
||||
}
|
||||
|
||||
if (objectIdEquals(groundObject, id))
|
||||
{
|
||||
return groundObject;
|
||||
}
|
||||
|
||||
for (GameObject object : tileGameObjects)
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object.getId() == id)
|
||||
if (objectIdEquals(object, id))
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
// Check impostors
|
||||
final ObjectDefinition comp = client.getObjectDefinition(object.getId());
|
||||
|
||||
if (comp.getImpostorIds() != null)
|
||||
{
|
||||
for (int impostorId : comp.getImpostorIds())
|
||||
{
|
||||
if (impostorId == id)
|
||||
{
|
||||
return object;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean objectIdEquals(TileObject tileObject, int id)
|
||||
{
|
||||
if (tileObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tileObject.getId() == id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Menu action EXAMINE_OBJECT sends the transformed object id, not the base id, unlike
|
||||
// all of the GAME_OBJECT_OPTION actions, so check the id against the impostor ids
|
||||
final ObjectDefinition comp = client.getObjectDefinition(tileObject.getId());
|
||||
|
||||
if (comp.getImpostorIds() != null)
|
||||
{
|
||||
for (int impostorId : comp.getImpostorIds())
|
||||
{
|
||||
if (impostorId == id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void markObject(String name, final TileObject object)
|
||||
{
|
||||
if (object == null)
|
||||
@@ -382,11 +459,13 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
objectPoints.remove(point);
|
||||
objects.remove(object);
|
||||
log.debug("Unmarking object: {}", point);
|
||||
}
|
||||
else
|
||||
{
|
||||
objectPoints.add(point);
|
||||
objects.add(object);
|
||||
log.debug("Marking object: {}", point);
|
||||
}
|
||||
|
||||
savePoints(regionId, objectPoints);
|
||||
@@ -414,11 +493,18 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
return null;
|
||||
}
|
||||
|
||||
return GSON.fromJson(json, new TypeToken<Set<ObjectPoint>>()
|
||||
Set<ObjectPoint> points = GSON.fromJson(json, new TypeToken<Set<ObjectPoint>>()
|
||||
{
|
||||
}.getType());
|
||||
// Prior to multiloc support the plugin would mark objects named "null", which breaks
|
||||
// in most cases due to the specific object being identified being ambiguous, so remove
|
||||
// them
|
||||
return points.stream()
|
||||
.filter(point -> !point.getName().equals("null"))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!event.getGroup().equals("objectindicators"))
|
||||
@@ -436,4 +522,10 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
this.objectMarkerColor = config.objectMarkerColor();
|
||||
this.objectMarkerAlpha = config.objectMarkerAlpha();
|
||||
}
|
||||
|
||||
private ObjectDefinition getObjectDefinition(int id)
|
||||
{
|
||||
ObjectDefinition objectComposition = client.getObjectDefinition(id);
|
||||
return objectComposition.getImpostorIds() == null ? objectComposition : objectComposition.getImpostor();
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,14 @@
|
||||
package net.runelite.client.plugins.wiki;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.MenuOpcode;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
@@ -40,6 +41,7 @@ import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetConfig;
|
||||
@@ -55,7 +57,6 @@ import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.LinkBrowser;
|
||||
import net.runelite.api.util.Text;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
@Slf4j
|
||||
@@ -82,9 +83,6 @@ public class WikiPlugin extends Plugin
|
||||
private static final String MENUOP_QUICKGUIDE = "Quick Guide";
|
||||
private static final String MENUOP_WIKI = "Wiki";
|
||||
|
||||
private static final Pattern SKILL_REGEX = Pattern.compile("([A-Za-z]+) guide");
|
||||
private static final Pattern DIARY_REGEX = Pattern.compile("([A-Za-z &]+) Journal");
|
||||
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@@ -177,12 +175,14 @@ public class WikiPlugin extends Plugin
|
||||
icon.setOriginalHeight(16);
|
||||
icon.setTargetVerb("Lookup");
|
||||
icon.setName("Wiki");
|
||||
icon.setClickMask(WidgetConfig.USE_GROUND_ITEM | WidgetConfig.USE_ITEM | WidgetConfig.USE_NPC | WidgetConfig.USE_OBJECT);
|
||||
icon.setClickMask(WidgetConfig.USE_GROUND_ITEM | WidgetConfig.USE_ITEM | WidgetConfig.USE_NPC
|
||||
| WidgetConfig.USE_OBJECT | WidgetConfig.USE_WIDGET);
|
||||
icon.setNoClickThrough(true);
|
||||
icon.setOnTargetEnterListener((JavaScriptCallback) ev ->
|
||||
{
|
||||
wikiSelected = true;
|
||||
icon.setSpriteId(WikiSprite.WIKI_SELECTED_ICON.getSpriteId());
|
||||
client.setAllWidgetsAreOpTargetable(true);
|
||||
});
|
||||
icon.setAction(5, "Search"); // Start at option 5 so the target op is ontop
|
||||
icon.setOnOpListener((JavaScriptCallback) ev ->
|
||||
@@ -199,6 +199,8 @@ public class WikiPlugin extends Plugin
|
||||
|
||||
private void onDeselect()
|
||||
{
|
||||
client.setAllWidgetsAreOpTargetable(false);
|
||||
|
||||
wikiSelected = false;
|
||||
if (icon != null)
|
||||
{
|
||||
@@ -208,6 +210,7 @@ public class WikiPlugin extends Plugin
|
||||
|
||||
private void onMenuOptionClicked(MenuOptionClicked ev)
|
||||
{
|
||||
optarget:
|
||||
if (wikiSelected)
|
||||
{
|
||||
onDeselect();
|
||||
@@ -221,6 +224,9 @@ public class WikiPlugin extends Plugin
|
||||
|
||||
switch (ev.getMenuOpcode())
|
||||
{
|
||||
case RUNELITE:
|
||||
// This is a quest widget op
|
||||
break optarget;
|
||||
case CANCEL:
|
||||
return;
|
||||
case ITEM_USE_ON_WIDGET:
|
||||
@@ -255,6 +261,18 @@ public class WikiPlugin extends Plugin
|
||||
location = WorldPoint.fromScene(client, ev.getParam0(), ev.getParam1(), client.getPlane());
|
||||
break;
|
||||
}
|
||||
case SPELL_CAST_ON_WIDGET:
|
||||
Widget w = getWidget(ev.getParam1(), ev.getParam0());
|
||||
|
||||
if (w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1)
|
||||
{
|
||||
type = "item";
|
||||
id = itemManager.canonicalize(w.getItemId());
|
||||
name = itemManager.getItemDefinition(id).getName();
|
||||
location = null;
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
default:
|
||||
log.info("Unknown menu option: {} {} {}", ev, ev.getMenuOpcode(), ev.getMenuOpcode() == MenuOpcode.CANCEL);
|
||||
return;
|
||||
@@ -303,25 +321,11 @@ public class WikiPlugin extends Plugin
|
||||
LinkBrowser.browse(ub.build().toString());
|
||||
break;
|
||||
case MENUOP_WIKI:
|
||||
Matcher skillRegex = WikiPlugin.SKILL_REGEX.matcher(Text.removeTags(ev.getTarget()));
|
||||
Matcher diaryRegex = WikiPlugin.DIARY_REGEX.matcher(Text.removeTags(ev.getTarget()));
|
||||
|
||||
if (skillRegex.find())
|
||||
{
|
||||
LinkBrowser.browse(WIKI_BASE.newBuilder()
|
||||
.addPathSegment("w")
|
||||
.addPathSegment(skillRegex.group(1))
|
||||
.addQueryParameter(UTM_SOURCE_KEY, UTM_SOURCE_VALUE)
|
||||
.build().toString());
|
||||
}
|
||||
else if (diaryRegex.find())
|
||||
{
|
||||
LinkBrowser.browse(WIKI_BASE.newBuilder()
|
||||
.addPathSegment("w")
|
||||
.addPathSegment(diaryRegex.group(1) + " Diary")
|
||||
.addQueryParameter(UTM_SOURCE_KEY, UTM_SOURCE_VALUE)
|
||||
.build().toString());
|
||||
}
|
||||
LinkBrowser.browse(WIKI_BASE.newBuilder()
|
||||
.addPathSegment("w")
|
||||
.addPathSegment(Text.removeTags(ev.getTarget()))
|
||||
.addQueryParameter(UTM_SOURCE_KEY, UTM_SOURCE_VALUE)
|
||||
.build().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,16 +336,51 @@ public class WikiPlugin extends Plugin
|
||||
.build();
|
||||
}
|
||||
|
||||
private Widget getWidget(int wid, int index)
|
||||
{
|
||||
Widget w = client.getWidget(WidgetInfo.TO_GROUP(wid), WidgetInfo.TO_CHILD(wid));
|
||||
if (index != -1)
|
||||
{
|
||||
w = w.getChild(index);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
private void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
int widgetIndex = event.getParam0();
|
||||
int widgetID = event.getParam1();
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
|
||||
if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID) && "Read Journal:".equals(event.getOption()))
|
||||
if (wikiSelected && event.getOpcode() == MenuOpcode.SPELL_CAST_ON_WIDGET.getId())
|
||||
{
|
||||
Widget w = getWidget(widgetID, widgetIndex);
|
||||
if (!(w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1))
|
||||
{
|
||||
// we don't support this widget
|
||||
// remove the last SPELL_CAST_ON_WIDGET; we can't blindly remove the top action because some other
|
||||
// plugin might have added something on this same event, and we probably shouldn't remove that instead
|
||||
MenuEntry[] oldEntries = menuEntries;
|
||||
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length - 1);
|
||||
for (int ourEntry = oldEntries.length - 1;
|
||||
ourEntry >= 2 && oldEntries[oldEntries.length - 1].getOpcode() != MenuOpcode.SPELL_CAST_ON_WIDGET.getId();
|
||||
ourEntry--)
|
||||
{
|
||||
menuEntries[ourEntry - 1] = oldEntries[ourEntry];
|
||||
}
|
||||
client.setMenuEntries(menuEntries);
|
||||
}
|
||||
}
|
||||
|
||||
if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID)
|
||||
&& ((wikiSelected && widgetIndex != -1) || "Read Journal:".equals(event.getOption())))
|
||||
{
|
||||
Widget w = getWidget(widgetID, widgetIndex);
|
||||
String target = w.getName();
|
||||
|
||||
client.insertMenuItem(
|
||||
MENUOP_QUICKGUIDE,
|
||||
event.getTarget(),
|
||||
target,
|
||||
MenuOpcode.RUNELITE.getId(),
|
||||
0,
|
||||
widgetIndex,
|
||||
@@ -351,7 +390,7 @@ public class WikiPlugin extends Plugin
|
||||
|
||||
client.insertMenuItem(
|
||||
MENUOP_GUIDE,
|
||||
event.getTarget(),
|
||||
target,
|
||||
MenuOpcode.RUNELITE.getId(),
|
||||
0,
|
||||
widgetIndex,
|
||||
@@ -360,12 +399,52 @@ public class WikiPlugin extends Plugin
|
||||
);
|
||||
}
|
||||
|
||||
if ((WidgetInfo.TO_GROUP(widgetID) == WidgetID.SKILLS_GROUP_ID && event.getOption().startsWith("View"))
|
||||
|| (WidgetInfo.TO_GROUP(widgetID) == WidgetID.ACHIEVEMENT_DIARY_GROUP_ID && event.getOption().startsWith("Open")))
|
||||
if (widgetID == WidgetInfo.ACHIEVEMENT_DIARY_CONTAINER.getId())
|
||||
{
|
||||
Widget w = getWidget(widgetID, widgetIndex);
|
||||
if (w.getActions() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String action = Stream.of(w.getActions())
|
||||
.filter(s -> s != null && !s.isEmpty())
|
||||
.findFirst().orElse(null);
|
||||
if (action == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.insertMenuItem(
|
||||
MENUOP_WIKI,
|
||||
event.getOption().replace("View ", "").replace("Open ", ""),
|
||||
action.replace("Open ", "").replace("Journal", "Diary"),
|
||||
MenuOpcode.RUNELITE.getId(),
|
||||
0,
|
||||
widgetIndex,
|
||||
widgetID,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
if (WidgetInfo.TO_GROUP(widgetID) == WidgetInfo.SKILLS_CONTAINER.getGroupId())
|
||||
{
|
||||
Widget w = getWidget(widgetID, widgetIndex);
|
||||
if (w.getParentId() != WidgetInfo.SKILLS_CONTAINER.getId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String action = Stream.of(w.getActions())
|
||||
.filter(s -> s != null && !s.isEmpty())
|
||||
.findFirst().orElse(null);
|
||||
if (action == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.insertMenuItem(
|
||||
MENUOP_WIKI,
|
||||
action.replace("View ", "").replace("Guide ", ""),
|
||||
MenuOpcode.RUNELITE.getId(),
|
||||
event.getIdentifier(),
|
||||
widgetIndex,
|
||||
|
||||
@@ -316,7 +316,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
||||
graphics.setColor(previous);
|
||||
}
|
||||
|
||||
if (menuEntries == null && !client.isMenuOpen() && bounds.contains(mouse))
|
||||
if (menuEntries == null && !client.isMenuOpen() && !client.isSpellSelected() && bounds.contains(mouse))
|
||||
{
|
||||
menuEntries = createRightClickMenuEntries(overlay);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.geometry.Shapes;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
@@ -86,6 +86,11 @@ public abstract class RSBoundaryObjectMixin implements RSBoundaryObject
|
||||
return null;
|
||||
}
|
||||
|
||||
if (clickboxA != null && clickboxB != null)
|
||||
{
|
||||
return new Shapes(new Shape[]{clickboxA, clickboxB});
|
||||
}
|
||||
|
||||
if (clickboxA != null)
|
||||
{
|
||||
return clickboxA;
|
||||
@@ -94,11 +99,9 @@ public abstract class RSBoundaryObjectMixin implements RSBoundaryObject
|
||||
return clickboxB;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Polygon getConvexHull()
|
||||
public Shape getConvexHull()
|
||||
{
|
||||
RSModel model = getModelA();
|
||||
|
||||
@@ -108,6 +111,23 @@ public abstract class RSBoundaryObjectMixin implements RSBoundaryObject
|
||||
}
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, new LocalPoint(getX(), getY()), client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX(), getY(), 0, tileHeight);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Shape getConvexHull2()
|
||||
{
|
||||
RSModel model = getModelB();
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, new LocalPoint(getX(), getY()), client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX(), getY(), 0, tileHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import net.runelite.api.HintArrowType;
|
||||
import net.runelite.api.Ignore;
|
||||
import net.runelite.api.IndexDataBase;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.IntegerNode;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.MenuOpcode;
|
||||
@@ -111,6 +112,7 @@ import net.runelite.api.mixins.Replace;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.api.vars.AccountType;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetConfig;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
@@ -215,6 +217,9 @@ public abstract class RSClientMixin implements RSClient
|
||||
@Inject
|
||||
private static boolean hideClanmateCastOptions = false;
|
||||
|
||||
@Inject
|
||||
private static boolean allWidgetsAreOpTargetable = false;
|
||||
|
||||
@Inject
|
||||
private static Set<String> unhiddenCasts = new HashSet<String>();
|
||||
|
||||
@@ -260,6 +265,13 @@ public abstract class RSClientMixin implements RSClient
|
||||
hideClanmateCastOptions = yes;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setAllWidgetsAreOpTargetable(boolean yes)
|
||||
{
|
||||
allWidgetsAreOpTargetable = yes;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setUnhiddenCasts(Set<String> casts)
|
||||
@@ -1820,4 +1832,28 @@ public abstract class RSClientMixin implements RSClient
|
||||
client.getCallbacks().post(VolumeChanged.class, volumeChanged);
|
||||
}
|
||||
}
|
||||
|
||||
@Replace("getWidgetClickMask")
|
||||
public static int getWidgetClickMask(Widget widget)
|
||||
{
|
||||
IntegerNode integerNode = (IntegerNode) client.getWidgetFlags().get(((long) widget.getId() << 32) + (long) widget.getIndex());
|
||||
|
||||
int widgetClickMask;
|
||||
|
||||
if (integerNode == null)
|
||||
{
|
||||
widgetClickMask = widget.getClickMask();
|
||||
}
|
||||
else
|
||||
{
|
||||
widgetClickMask = integerNode.getValue();
|
||||
}
|
||||
|
||||
if (allWidgetsAreOpTargetable)
|
||||
{
|
||||
widgetClickMask |= WidgetConfig.WIDGET_USE_TARGET;
|
||||
}
|
||||
|
||||
return widgetClickMask;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
@@ -60,7 +59,7 @@ public abstract class RSFloorDecorationMixin implements RSFloorDecoration
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Polygon getConvexHull()
|
||||
public Shape getConvexHull()
|
||||
{
|
||||
RSModel model = getModel();
|
||||
|
||||
@@ -70,6 +69,7 @@ public abstract class RSFloorDecorationMixin implements RSFloorDecoration
|
||||
}
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, new LocalPoint(getX(), getY()), client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX(), getY(), 0, tileHeight);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
@@ -87,7 +86,7 @@ public abstract class RSGameObjectMixin implements RSGameObject
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Polygon getConvexHull()
|
||||
public Shape getConvexHull()
|
||||
{
|
||||
RSModel model = getModel();
|
||||
|
||||
@@ -97,6 +96,7 @@ public abstract class RSGameObjectMixin implements RSGameObject
|
||||
}
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, new LocalPoint(getX(), getY()), client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX(), getY(), getRsOrientation(), tileHeight);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,11 @@
|
||||
*/
|
||||
package net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.api.mixins.Copy;
|
||||
import net.runelite.api.mixins.FieldHook;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Replace;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import net.runelite.rs.api.RSItemContainer;
|
||||
@@ -41,11 +39,8 @@ public abstract class RSItemContainerMixin implements RSItemContainer
|
||||
@Shadow("client")
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
static private int rl$lastCycle;
|
||||
|
||||
@Inject
|
||||
static private int rl$lastContainer;
|
||||
@Shadow("changedItemContainers")
|
||||
private static int[] changedItemContainers;
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
@@ -67,35 +62,22 @@ public abstract class RSItemContainerMixin implements RSItemContainer
|
||||
return items;
|
||||
}
|
||||
|
||||
@Copy("itemContainerSetItem")
|
||||
static void rs$itemContainerSetItem(int itemContainerId, int index, int itemId, int itemQuantity)
|
||||
@FieldHook("changedItemContainers")
|
||||
@Inject
|
||||
public static void onItemContainerUpdate(int idx)
|
||||
{
|
||||
}
|
||||
|
||||
@Replace("itemContainerSetItem")
|
||||
static void rl$itemContainerSetItem(int itemContainerId, int index, int itemId, int itemQuantity)
|
||||
{
|
||||
rs$itemContainerSetItem(itemContainerId, index, itemId, itemQuantity);
|
||||
|
||||
int cycle = client.getGameCycle();
|
||||
|
||||
if (rl$lastCycle == cycle && rl$lastContainer == itemContainerId)
|
||||
if (idx != -1)
|
||||
{
|
||||
// Limit item container updates to one per cycle per container
|
||||
return;
|
||||
int changedId = idx - 1 & 31;
|
||||
int containerId = changedItemContainers[changedId];
|
||||
|
||||
RSItemContainer changedContainer = (RSItemContainer) client.getItemContainers().get(containerId);
|
||||
|
||||
if (changedContainer != null)
|
||||
{
|
||||
ItemContainerChanged event = new ItemContainerChanged(containerId, changedContainer);
|
||||
client.getCallbacks().postDeferred(ItemContainerChanged.class, event);
|
||||
}
|
||||
}
|
||||
|
||||
InventoryID container = InventoryID.getValue(itemContainerId);
|
||||
|
||||
if (container == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rl$lastCycle = cycle;
|
||||
rl$lastContainer = itemContainerId;
|
||||
|
||||
ItemContainerChanged event = new ItemContainerChanged(itemContainerId, client.getItemContainer(container));
|
||||
client.getCallbacks().postDeferred(ItemContainerChanged.class, event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,11 @@
|
||||
*/
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.mixins.Copy;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.MethodHook;
|
||||
@@ -140,7 +139,7 @@ public abstract class RSModelMixin implements RSModel
|
||||
int[] trianglesZ = getTrianglesZ();
|
||||
|
||||
List<Vertex> vertices = getVertices();
|
||||
List<Triangle> triangles = new ArrayList<Triangle>(getTrianglesCount());
|
||||
List<Triangle> triangles = new ArrayList<>(getTrianglesCount());
|
||||
|
||||
for (int i = 0; i < getTrianglesCount(); ++i)
|
||||
{
|
||||
@@ -321,49 +320,14 @@ public abstract class RSModelMixin implements RSModel
|
||||
|
||||
@Override
|
||||
@Inject
|
||||
public Polygon getConvexHull(int localX, int localY, int orientation, int tileHeight)
|
||||
public Shape getConvexHull(int localX, int localY, int orientation, int tileHeight)
|
||||
{
|
||||
assert client.isClientThread();
|
||||
int[] x2d = new int[this.getVerticesCount()];
|
||||
int[] y2d = new int[this.getVerticesCount()];
|
||||
|
||||
List<Vertex> vertices = getVertices();
|
||||
Perspective.modelToCanvas(client, this.getVerticesCount(), localX, localY, tileHeight, orientation, this.getVerticesX(), this.getVerticesZ(), this.getVerticesY(), x2d, y2d);
|
||||
|
||||
// rotate vertices
|
||||
for (int i = 0; i < vertices.size(); ++i)
|
||||
{
|
||||
Vertex v = vertices.get(i);
|
||||
vertices.set(i, v.rotate(orientation));
|
||||
}
|
||||
|
||||
List<Point> points = new ArrayList<Point>();
|
||||
|
||||
for (Vertex v : vertices)
|
||||
{
|
||||
// Compute canvas location of vertex
|
||||
Point p = Perspective.localToCanvas(client,
|
||||
localX - v.getX(),
|
||||
localY - v.getZ(),
|
||||
tileHeight + v.getY());
|
||||
if (p != null)
|
||||
{
|
||||
points.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Run Jarvis march algorithm
|
||||
points = Jarvis.convexHull(points);
|
||||
if (points == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Convert to a polygon
|
||||
Polygon p = new Polygon();
|
||||
for (Point point : points)
|
||||
{
|
||||
p.addPoint(point.getX(), point.getY());
|
||||
}
|
||||
|
||||
return p;
|
||||
return Jarvis.convexHull(x2d, y2d);
|
||||
}
|
||||
|
||||
@Inject
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.Perspective;
|
||||
@@ -178,7 +178,7 @@ public abstract class RSNPCMixin implements RSNPC
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Polygon getConvexHull()
|
||||
public Shape getConvexHull()
|
||||
{
|
||||
RSModel model = getModel();
|
||||
if (model == null)
|
||||
@@ -192,6 +192,7 @@ public abstract class RSNPCMixin implements RSNPC
|
||||
size * Perspective.LOCAL_HALF_TILE_SIZE - Perspective.LOCAL_HALF_TILE_SIZE + getY());
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, tileHeightPoint, client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX(), getY(), getOrientation(), tileHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import static net.runelite.api.HeadIcon.MAGIC;
|
||||
import static net.runelite.api.HeadIcon.MELEE;
|
||||
@@ -36,7 +36,6 @@ import static net.runelite.api.HeadIcon.RETRIBUTION;
|
||||
import static net.runelite.api.HeadIcon.SMITE;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.SkullIcon;
|
||||
import static net.runelite.api.SkullIcon.DEAD_MAN_FIVE;
|
||||
import static net.runelite.api.SkullIcon.DEAD_MAN_FOUR;
|
||||
@@ -52,8 +51,6 @@ import net.runelite.api.mixins.MethodHook;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Replace;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.api.model.Triangle;
|
||||
import net.runelite.api.model.Vertex;
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import net.runelite.rs.api.RSModel;
|
||||
import net.runelite.rs.api.RSPlayer;
|
||||
@@ -148,58 +145,42 @@ public abstract class RSPlayerMixin implements RSPlayer
|
||||
return null;
|
||||
}
|
||||
|
||||
int[] x2d = new int[model.getVerticesCount()];
|
||||
int[] y2d = new int[model.getVerticesCount()];
|
||||
|
||||
int localX = getX();
|
||||
int localY = getY();
|
||||
|
||||
int orientation = getOrientation();
|
||||
|
||||
final int tileHeight = Perspective.getTileHeight(client, new LocalPoint(localX, localY), client.getPlane());
|
||||
|
||||
List<Triangle> triangles = model.getTriangles();
|
||||
Perspective.modelToCanvas(client, model.getVerticesCount(), localX, localY, tileHeight, getOrientation(), model.getVerticesX(), model.getVerticesZ(), model.getVerticesY(), x2d, y2d);
|
||||
ArrayList polys = new ArrayList(model.getTrianglesCount());
|
||||
|
||||
triangles = rotate(triangles, orientation);
|
||||
int[] trianglesX = model.getTrianglesX();
|
||||
int[] trianglesY = model.getTrianglesY();
|
||||
int[] trianglesZ = model.getTrianglesZ();
|
||||
|
||||
List<Polygon> polys = new ArrayList<Polygon>();
|
||||
for (Triangle triangle : triangles)
|
||||
for (int triangle = 0; triangle < model.getTrianglesCount(); ++triangle)
|
||||
{
|
||||
Vertex vx = triangle.getA();
|
||||
Vertex vy = triangle.getB();
|
||||
Vertex vz = triangle.getC();
|
||||
|
||||
System.err.println("vx: " + vx.getX() + " localX: " + localX);
|
||||
|
||||
Point x = Perspective.localToCanvas(client,
|
||||
localX - vx.getX(),
|
||||
localY - vx.getZ(),
|
||||
tileHeight + vx.getY());
|
||||
|
||||
Point y = Perspective.localToCanvas(client,
|
||||
localX - vy.getX(),
|
||||
localY - vy.getZ(),
|
||||
tileHeight + vy.getY());
|
||||
|
||||
Point z = Perspective.localToCanvas(client,
|
||||
localX - vz.getX(),
|
||||
localY - vz.getZ(),
|
||||
tileHeight + vz.getY());
|
||||
|
||||
int[] xx =
|
||||
{
|
||||
x.getX(), y.getX(), z.getX()
|
||||
x2d[trianglesX[triangle]], x2d[trianglesY[triangle]], x2d[trianglesZ[triangle]]
|
||||
};
|
||||
|
||||
int[] yy =
|
||||
{
|
||||
x.getY(), y.getY(), z.getY()
|
||||
y2d[trianglesX[triangle]], y2d[trianglesY[triangle]], y2d[trianglesZ[triangle]]
|
||||
};
|
||||
|
||||
polys.add(new Polygon(xx, yy, 3));
|
||||
}
|
||||
|
||||
return polys.toArray(new Polygon[polys.size()]);
|
||||
return (Polygon[]) polys.toArray(new Polygon[0]);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Polygon getConvexHull()
|
||||
public Shape getConvexHull()
|
||||
{
|
||||
RSModel model = getModel();
|
||||
if (model == null)
|
||||
@@ -208,29 +189,10 @@ public abstract class RSPlayerMixin implements RSPlayer
|
||||
}
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, new LocalPoint(getX(), getY()), client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX(), getY(), getOrientation(), tileHeight);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private List<Triangle> rotate(List<Triangle> triangles, int orientation)
|
||||
{
|
||||
List<Triangle> rotatedTriangles = new ArrayList<Triangle>();
|
||||
for (Triangle triangle : triangles)
|
||||
{
|
||||
Vertex a = triangle.getA();
|
||||
Vertex b = triangle.getB();
|
||||
Vertex c = triangle.getC();
|
||||
|
||||
Triangle rotatedTriangle = new Triangle(
|
||||
a.rotate(orientation),
|
||||
b.rotate(orientation),
|
||||
c.rotate(orientation)
|
||||
);
|
||||
rotatedTriangles.add(rotatedTriangle);
|
||||
}
|
||||
return rotatedTriangles;
|
||||
}
|
||||
|
||||
@Copy("getModel")
|
||||
public abstract RSModel rs$getModel();
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Area;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.geometry.Shapes;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
@@ -89,9 +88,8 @@ public abstract class RSWallDecorationMixin implements RSWallDecoration
|
||||
@Override
|
||||
public Shape getClickbox()
|
||||
{
|
||||
Area clickbox = new Area();
|
||||
|
||||
LocalPoint lp = getLocalLocation();
|
||||
|
||||
Shape clickboxA = Perspective.getClickbox(client, getModel1(), 0,
|
||||
new LocalPoint(lp.getX() + getXOffset(), lp.getY() + getYOffset()));
|
||||
Shape clickboxB = Perspective.getClickbox(client, getModel2(), 0, lp);
|
||||
@@ -101,6 +99,11 @@ public abstract class RSWallDecorationMixin implements RSWallDecoration
|
||||
return null;
|
||||
}
|
||||
|
||||
if (clickboxA != null && clickboxB != null)
|
||||
{
|
||||
return new Shapes(new Shape[]{clickboxA, clickboxB});
|
||||
}
|
||||
|
||||
if (clickboxA != null)
|
||||
{
|
||||
return clickboxA;
|
||||
@@ -111,7 +114,7 @@ public abstract class RSWallDecorationMixin implements RSWallDecoration
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Polygon getConvexHull()
|
||||
public Shape getConvexHull()
|
||||
{
|
||||
RSModel model = getModel1();
|
||||
|
||||
@@ -121,12 +124,13 @@ public abstract class RSWallDecorationMixin implements RSWallDecoration
|
||||
}
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, new LocalPoint(getX(), getY()), client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX() + getXOffset(), getY() + getYOffset(), 0, tileHeight);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Polygon getConvexHull2()
|
||||
public Shape getConvexHull2()
|
||||
{
|
||||
RSModel model = getModel2();
|
||||
|
||||
@@ -136,6 +140,7 @@ public abstract class RSWallDecorationMixin implements RSWallDecoration
|
||||
}
|
||||
|
||||
int tileHeight = Perspective.getTileHeight(client, new LocalPoint(getX(), getY()), client.getPlane());
|
||||
|
||||
return model.getConvexHull(getX(), getY(), 0, tileHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
*/
|
||||
package net.runelite.rs.api;
|
||||
|
||||
import java.awt.Shape;
|
||||
import net.runelite.api.Model;
|
||||
import java.awt.Polygon;
|
||||
import net.runelite.mapping.Import;
|
||||
|
||||
public interface RSModel extends RSEntity, Model
|
||||
@@ -163,7 +163,7 @@ public interface RSModel extends RSEntity, Model
|
||||
/**
|
||||
* Compute the convex hull of this model
|
||||
*/
|
||||
Polygon getConvexHull(int localX, int localY, int orientation, int tileHeight);
|
||||
Shape getConvexHull(int localX, int localY, int orientation, int tileHeight);
|
||||
|
||||
float[][] getFaceTextureUCoordinates();
|
||||
void setFaceTextureUCoordinates(float[][] rl$faceTextureUCoordinates);
|
||||
|
||||
@@ -723,7 +723,7 @@ public class ArchiveLoader {
|
||||
if (var9.invTransmitTriggers != null && Client.field820 - var9.field2567 <= 32) {
|
||||
label862:
|
||||
for (var35 = var9.field2567; var35 < Client.field820; ++var35) {
|
||||
var23 = Client.field816[var35 & 31];
|
||||
var23 = Client.changedItemContainers[var35 & 31];
|
||||
|
||||
for (var36 = 0; var36 < var9.invTransmitTriggers.length; ++var36) {
|
||||
if (var23 == var9.invTransmitTriggers[var36]) {
|
||||
|
||||
@@ -216,7 +216,8 @@ public final class Client extends GameShell implements Usernamed {
|
||||
@Export("meslayerContinueWidget")
|
||||
static Widget meslayerContinueWidget;
|
||||
@ObfuscatedName("no")
|
||||
static int[] field816;
|
||||
@Export("changedItemContainers")
|
||||
static int[] changedItemContainers;
|
||||
@ObfuscatedName("sm")
|
||||
@ObfuscatedGetter(
|
||||
intValue = 857681821
|
||||
@@ -1451,7 +1452,7 @@ public final class Client extends GameShell implements Usernamed {
|
||||
cycleCntr = 1;
|
||||
field817 = new int[32];
|
||||
field679 = 0;
|
||||
field816 = new int[32];
|
||||
changedItemContainers = new int[32];
|
||||
field820 = 0;
|
||||
changedSkills = new int[32];
|
||||
changedSkillsCount = 0;
|
||||
@@ -5071,7 +5072,7 @@ public final class Client extends GameShell implements Usernamed {
|
||||
}
|
||||
|
||||
BoundaryObject.method3393();
|
||||
field816[++field820 - 1 & 31] = var5 & 32767;
|
||||
changedItemContainers[++field820 - 1 & 31] = var5 & 32767;
|
||||
var1.serverPacket = null;
|
||||
return true;
|
||||
}
|
||||
@@ -5079,7 +5080,7 @@ public final class Client extends GameShell implements Usernamed {
|
||||
if (ServerPacket.field2136 == var1.serverPacket) {
|
||||
var16 = var3.method5646();
|
||||
WorldMapIcon_0.method252(var16);
|
||||
field816[++field820 - 1 & 31] = var16 & 32767;
|
||||
changedItemContainers[++field820 - 1 & 31] = var16 & 32767;
|
||||
var1.serverPacket = null;
|
||||
return true;
|
||||
}
|
||||
@@ -5590,7 +5591,7 @@ public final class Client extends GameShell implements Usernamed {
|
||||
}
|
||||
|
||||
BoundaryObject.method3393();
|
||||
field816[++field820 - 1 & 31] = var5 & 32767;
|
||||
changedItemContainers[++field820 - 1 & 31] = var5 & 32767;
|
||||
var1.serverPacket = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user