item stats: add item information panel when buying items in the ge
Co-authored-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
@@ -68,6 +68,11 @@ public enum VarPlayer
|
||||
*/
|
||||
THRONE_OF_MISCELLANIA(359),
|
||||
|
||||
/**
|
||||
* Item currently active in the creation of a buy or sell offer
|
||||
*/
|
||||
CURRENT_GE_ITEM(1151),
|
||||
|
||||
/**
|
||||
* Experience tracker goal start.
|
||||
*/
|
||||
|
||||
@@ -468,7 +468,14 @@ public enum Varbits
|
||||
BANK_TAB_SIX_COUNT(4176),
|
||||
BANK_TAB_SEVEN_COUNT(4177),
|
||||
BANK_TAB_EIGHT_COUNT(4178),
|
||||
BANK_TAB_NINE_COUNT(4179);
|
||||
BANK_TAB_NINE_COUNT(4179),
|
||||
|
||||
/**
|
||||
* Type of GE offer currently being created
|
||||
* 0 = buy
|
||||
* 1 = sell
|
||||
*/
|
||||
GE_OFFER_CREATION_TYPE(4397);
|
||||
|
||||
/**
|
||||
* The raw varbit ID.
|
||||
|
||||
@@ -350,6 +350,7 @@ public class WidgetID
|
||||
static final int ROOT_INTERFACE_CONTAINER = 62;
|
||||
static final int BANK_CONTAINER = 64;
|
||||
static final int INTERFACE_CONTAINER = 65;
|
||||
static final int INVENTORY_CONTAINER = 69;
|
||||
}
|
||||
|
||||
static class ResizableViewport
|
||||
@@ -383,6 +384,7 @@ public class WidgetID
|
||||
static final int PRAYER_ICON = 63;
|
||||
static final int MAGIC_ICON = 64;
|
||||
static final int INTERFACE_CONTAINER = 65;
|
||||
static final int INVENTORY_CONTAINER = 71;
|
||||
}
|
||||
|
||||
static class ResizableViewportBottomLine
|
||||
@@ -415,6 +417,7 @@ public class WidgetID
|
||||
static final int MUSIC_TAB = 40;
|
||||
static final int MUSIC_ICON = 46;
|
||||
static final int MAGIC_ICON = 63;
|
||||
static final int INVENTORY_CONTAINER = 71;
|
||||
}
|
||||
|
||||
static class Chatbox
|
||||
|
||||
@@ -168,6 +168,7 @@ public enum WidgetInfo
|
||||
FIXED_VIEWPORT_ROOT_INTERFACE_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.ROOT_INTERFACE_CONTAINER),
|
||||
FIXED_VIEWPORT_BANK_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.BANK_CONTAINER),
|
||||
FIXED_VIEWPORT_INTERFACE_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.INTERFACE_CONTAINER),
|
||||
FIXED_VIEWPORT_INVENTORY_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.INVENTORY_CONTAINER),
|
||||
FIXED_VIEWPORT_COMBAT_TAB(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.COMBAT_TAB),
|
||||
FIXED_VIEWPORT_STATS_TAB(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.STATS_TAB),
|
||||
FIXED_VIEWPORT_QUESTS_TAB(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.QUESTS_TAB),
|
||||
@@ -258,7 +259,9 @@ public enum WidgetInfo
|
||||
RESIZABLE_VIEWPORT_BOTTOM_LINE_OPTIONS_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.SETTINGS_ICON),
|
||||
RESIZABLE_VIEWPORT_BOTTOM_LINE_EMOTES_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.EMOTE_ICON),
|
||||
RESIZABLE_VIEWPORT_BOTTOM_LINE_MUSIC_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.MUSIC_ICON),
|
||||
RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.INVENTORY_CONTAINER),
|
||||
RESIZABLE_VIEWPORT_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INTERFACE_CONTAINER),
|
||||
RESIZABLE_VIEWPORT_INVENTORY_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INVENTORY_CONTAINER),
|
||||
RESIZABLE_VIEWPORT_BOTTOM_LINE_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.INTERFACE_CONTAINER),
|
||||
|
||||
PRAYER_THICK_SKIN(WidgetID.PRAYER_GROUP_ID, WidgetID.Prayer.THICK_SKIN),
|
||||
|
||||
@@ -52,6 +52,16 @@ public interface ItemStatConfig extends Config
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "geStats",
|
||||
name = "Enable GE item information",
|
||||
description = "Shows an item information panel when buying items in the GE"
|
||||
)
|
||||
default boolean geStats()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "relative",
|
||||
name = "Show Relative",
|
||||
|
||||
@@ -24,13 +24,45 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.itemstats;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.FontMetrics;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetHiddenChanged;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetTextAlignment;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.JagexColors;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
import net.runelite.http.api.item.ItemEquipmentStats;
|
||||
import net.runelite.http.api.item.ItemStats;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Item Stats",
|
||||
@@ -39,12 +71,27 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
)
|
||||
public class ItemStatPlugin extends Plugin
|
||||
{
|
||||
private static final int ORANGE_TEXT = JagexColors.DARK_ORANGE_INTERFACE_TEXT.getRGB();
|
||||
private static final int YELLOW_TEXT = JagexColors.YELLOW_INTERFACE_TEXT.getRGB();
|
||||
private static final int TEXT_HEIGHT = 11;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private ItemStatOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private ItemStatConfig config;
|
||||
|
||||
private Widget itemInformationTitle;
|
||||
|
||||
@Provides
|
||||
ItemStatConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -67,5 +114,323 @@ public class ItemStatPlugin extends Plugin
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
resetGEInventory();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getKey().equals("geStats"))
|
||||
{
|
||||
resetGEInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetHiddenChanged(WidgetHiddenChanged event)
|
||||
{
|
||||
if (!config.geStats())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getWidget() == client.getWidget(WidgetInfo.INVENTORY))
|
||||
{
|
||||
resetGEInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
if (client.getVar(VarPlayer.CURRENT_GE_ITEM) == -1 && config.geStats())
|
||||
{
|
||||
resetGEInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
if (event.getEventName().equals("geBuilt") && config.geStats())
|
||||
{
|
||||
int currentGeItem = client.getVar(VarPlayer.CURRENT_GE_ITEM);
|
||||
if (currentGeItem != -1 && client.getVar(Varbits.GE_OFFER_CREATION_TYPE) == 0)
|
||||
{
|
||||
createItemInformation(currentGeItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createItemInformation(int id)
|
||||
{
|
||||
final ItemStats itemStats = itemManager.getItemStats(id, false);
|
||||
|
||||
if (itemStats == null || !itemStats.isEquipable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemEquipmentStats equipmentStats = itemStats.getEquipment();
|
||||
|
||||
if (equipmentStats == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget geInv = client.getWidget(WidgetInfo.GRAND_EXCHANGE_INVENTORY_ITEMS_CONTAINER);
|
||||
|
||||
if (geInv == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget invContainer = getInventoryContainer();
|
||||
|
||||
if (invContainer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
invContainer.deleteAllChildren();
|
||||
geInv.setHidden(true);
|
||||
|
||||
int yPos = 0;
|
||||
|
||||
final FontMetrics smallFM = client.getCanvas().getFontMetrics(FontManager.getRunescapeSmallFont());
|
||||
|
||||
// HEADER
|
||||
|
||||
itemInformationTitle = createText(invContainer, "Item Information", FontID.BOLD_12, ORANGE_TEXT,
|
||||
8, 8, invContainer.getWidth(), 16);
|
||||
itemInformationTitle.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
|
||||
Widget closeButton = invContainer.createChild(-1, WidgetType.GRAPHIC);
|
||||
closeButton.setOriginalY(8);
|
||||
closeButton.setOriginalX(invContainer.getWidth() - 24);
|
||||
closeButton.setOriginalHeight(16);
|
||||
closeButton.setOriginalWidth(16);
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL);
|
||||
closeButton.setAction(0, "Close");
|
||||
closeButton.setOnMouseOverListener((JavaScriptCallback) (ev) ->
|
||||
{
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL_HOVERED);
|
||||
});
|
||||
closeButton.setOnMouseLeaveListener((JavaScriptCallback) (ev) ->
|
||||
{
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL);
|
||||
});
|
||||
closeButton.setOnOpListener((JavaScriptCallback) (ev) -> resetGEInventory());
|
||||
closeButton.setHasListener(true);
|
||||
closeButton.revalidate();
|
||||
|
||||
yPos += 15;
|
||||
|
||||
createSeparator(invContainer, yPos);
|
||||
|
||||
// ICON AND TITLE
|
||||
|
||||
yPos += 25;
|
||||
|
||||
Widget icon = invContainer.createChild(-1, WidgetType.GRAPHIC);
|
||||
icon.setOriginalX(8);
|
||||
icon.setOriginalY(yPos);
|
||||
icon.setOriginalWidth(36);
|
||||
icon.setOriginalHeight(32);
|
||||
icon.setItemId(id);
|
||||
icon.setItemQuantityMode(0);
|
||||
icon.setBorderType(1);
|
||||
icon.revalidate();
|
||||
|
||||
Widget itemName = createText(invContainer, itemManager.getItemComposition(id).getName(), FontID.PLAIN_12, ORANGE_TEXT,
|
||||
50, yPos, invContainer.getWidth() - 40, 30);
|
||||
itemName.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
|
||||
yPos += 20;
|
||||
|
||||
createSeparator(invContainer, yPos);
|
||||
|
||||
// STATS HEADER
|
||||
|
||||
yPos += 25;
|
||||
|
||||
createText(invContainer, "Attack", FontID.PLAIN_11, ORANGE_TEXT, 5, yPos, 50, -1);
|
||||
|
||||
int defenceXPos = invContainer.getWidth() - (smallFM.stringWidth("Defence") + 5);
|
||||
createText(invContainer, "Defence", FontID.PLAIN_11, ORANGE_TEXT, defenceXPos, yPos, 50, -1);
|
||||
|
||||
// STYLE BONUSES
|
||||
|
||||
final Set<String> stats = ImmutableSet.of(
|
||||
"Stab",
|
||||
"Slash",
|
||||
"Crush",
|
||||
"Magic",
|
||||
"Ranged"
|
||||
);
|
||||
|
||||
final List<Integer> attackStats = ImmutableList.of(
|
||||
equipmentStats.getAstab(),
|
||||
equipmentStats.getAslash(),
|
||||
equipmentStats.getAcrush(),
|
||||
equipmentStats.getAmagic(),
|
||||
equipmentStats.getArange()
|
||||
);
|
||||
|
||||
final List<Integer> defenceStats = ImmutableList.of(
|
||||
equipmentStats.getDstab(),
|
||||
equipmentStats.getDslash(),
|
||||
equipmentStats.getDcrush(),
|
||||
equipmentStats.getDmagic(),
|
||||
equipmentStats.getDrange()
|
||||
);
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (final String stat : stats)
|
||||
{
|
||||
yPos += TEXT_HEIGHT + 2;
|
||||
|
||||
// Style label
|
||||
final Widget styleText = createText(invContainer, stat, FontID.PLAIN_11, ORANGE_TEXT,
|
||||
0, yPos, invContainer.getWidth(), -1);
|
||||
styleText.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
|
||||
// Attack bonus
|
||||
createText(invContainer, attackStats.get(index).toString(), FontID.PLAIN_11, YELLOW_TEXT,
|
||||
5, yPos, 50, -1);
|
||||
|
||||
// Defence bonus
|
||||
final int defenceX = invContainer.getWidth() - (smallFM.stringWidth(defenceStats.get(index).toString()) + 5);
|
||||
createText(invContainer, defenceStats.get(index).toString(), FontID.PLAIN_11, YELLOW_TEXT,
|
||||
defenceX, yPos, 50, -1);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
// MISC BONUSES
|
||||
|
||||
yPos += TEXT_HEIGHT + 8;
|
||||
|
||||
final Map<String, Integer> miscStats = ImmutableMap.of(
|
||||
"Strength", equipmentStats.getStr(),
|
||||
"Ranged Strength", equipmentStats.getRstr(),
|
||||
"Magic Damage", equipmentStats.getMdmg(),
|
||||
"Prayer Bonus", equipmentStats.getPrayer()
|
||||
);
|
||||
|
||||
for (final Map.Entry<String, Integer> miscStat : miscStats.entrySet())
|
||||
{
|
||||
final String name = miscStat.getKey();
|
||||
final String value = miscStat.getValue().toString();
|
||||
|
||||
// Stat label
|
||||
createText(invContainer, name, FontID.PLAIN_11, ORANGE_TEXT, 5, yPos, 50, -1);
|
||||
|
||||
// Stat bonus
|
||||
int valueXPos = invContainer.getWidth() - (smallFM.stringWidth(value) + 5);
|
||||
createText(invContainer, value, FontID.PLAIN_11, YELLOW_TEXT, valueXPos, yPos, 50, -1);
|
||||
|
||||
yPos += TEXT_HEIGHT + 2;
|
||||
}
|
||||
|
||||
// COINS
|
||||
|
||||
createSeparator(invContainer, invContainer.getHeight() - 40);
|
||||
|
||||
final String coinText = "You have " + StackFormatter.quantityToRSStackSize(getCurrentGP())
|
||||
+ (getCurrentGP() == 1 ? " coin." : " coins.");
|
||||
|
||||
final Widget coinWidget = createText(invContainer, coinText, FontID.PLAIN_12, ORANGE_TEXT,
|
||||
0, invContainer.getHeight() - 18, invContainer.getWidth(), -1);
|
||||
|
||||
coinWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
}
|
||||
|
||||
private static Widget createText(Widget parent, String text, int fontId, int textColor,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
final Widget widget = parent.createChild(-1, WidgetType.TEXT);
|
||||
widget.setText(text);
|
||||
widget.setFontId(fontId);
|
||||
widget.setTextColor(textColor);
|
||||
widget.setTextShadowed(true);
|
||||
widget.setOriginalHeight(height == -1 ? TEXT_HEIGHT : height);
|
||||
widget.setOriginalWidth(width);
|
||||
widget.setOriginalY(y);
|
||||
widget.setOriginalX(x);
|
||||
widget.revalidate();
|
||||
return widget;
|
||||
}
|
||||
|
||||
private static void createSeparator(Widget parent, int y)
|
||||
{
|
||||
Widget separator = parent.createChild(-1, WidgetType.GRAPHIC);
|
||||
separator.setOriginalWidth(parent.getWidth());
|
||||
separator.setOriginalY(y);
|
||||
separator.setOriginalHeight(32);
|
||||
separator.setSpriteId(SpriteID.UNKNOWN_BORDER_EDGE_HORIZONTAL_995);
|
||||
separator.revalidate();
|
||||
}
|
||||
|
||||
private void resetGEInventory()
|
||||
{
|
||||
final Widget invContainer = getInventoryContainer();
|
||||
|
||||
if (invContainer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemInformationTitle != null && invContainer.getChild(0) == itemInformationTitle)
|
||||
{
|
||||
invContainer.deleteAllChildren();
|
||||
itemInformationTitle = null;
|
||||
}
|
||||
|
||||
final Widget geInv = client.getWidget(WidgetInfo.GRAND_EXCHANGE_INVENTORY_ITEMS_CONTAINER);
|
||||
if (geInv != null)
|
||||
{
|
||||
geInv.setHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
private int getCurrentGP()
|
||||
{
|
||||
final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
|
||||
|
||||
if (inventory == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (final Item item : inventory.getItems())
|
||||
{
|
||||
if (item.getId() == ItemID.COINS_995)
|
||||
{
|
||||
return item.getQuantity();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Widget getInventoryContainer()
|
||||
{
|
||||
if (client.isResized())
|
||||
{
|
||||
if (client.getVar(Varbits.SIDE_PANELS) == 1)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_CONTAINER);
|
||||
}
|
||||
else
|
||||
{
|
||||
return client.getWidget(WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_CONTAINER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return client.getWidget(WidgetInfo.FIXED_VIEWPORT_INVENTORY_CONTAINER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,4 +62,10 @@ public class JagexColors
|
||||
public static final Color TOOLTIP_BACKGROUND = new Color(255, 255, 160);
|
||||
public static final Color TOOLTIP_BORDER = Color.BLACK;
|
||||
public static final Color TOOLTIP_TEXT = Color.BLACK;
|
||||
|
||||
/*
|
||||
* Colors used in interfaces
|
||||
*/
|
||||
public static final Color DARK_ORANGE_INTERFACE_TEXT = new Color(255, 152, 31);
|
||||
public static final Color YELLOW_INTERFACE_TEXT = Color.YELLOW;
|
||||
}
|
||||
|
||||
@@ -389,4 +389,6 @@ LABEL315:
|
||||
iload 13
|
||||
invoke 780
|
||||
LABEL319:
|
||||
return
|
||||
sconst "geBuilt" ;
|
||||
runelite_callback ;
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user