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:
trimbe
2018-12-14 15:50:56 -05:00
parent e73b969a4f
commit 849e044bb0
8 changed files with 403 additions and 2 deletions

View File

@@ -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.
*/

View File

@@ -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.

View File

@@ -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

View File

@@ -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),

View File

@@ -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",

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View File

@@ -389,4 +389,6 @@ LABEL315:
iload 13
invoke 780
LABEL319:
return
sconst "geBuilt" ;
runelite_callback ;
return