diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItem.java new file mode 100644 index 0000000000..f713e23ff3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItem.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.grounditems; + +import lombok.Builder; +import lombok.Data; +import lombok.Value; +import net.runelite.api.coords.WorldPoint; + +@Data +@Builder +class GroundItem +{ + private int index; + private int id; + private int itemId; + private String name; + private int quantity; + private WorldPoint location; + private int haPrice; + private int gePrice; + + @Value + static class GroundItemKey + { + private int itemId; + private WorldPoint location; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 213c445aac..31b4b8fe63 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -29,72 +29,50 @@ import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Rectangle; -import static java.lang.Math.max; -import static java.lang.Math.min; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; +import java.util.HashMap; import java.util.Map; import javax.inject.Inject; import net.runelite.api.Client; -import net.runelite.api.Item; -import net.runelite.api.ItemComposition; -import net.runelite.api.ItemID; -import net.runelite.api.ItemLayer; -import net.runelite.api.Node; +import net.runelite.api.Perspective; import net.runelite.api.Player; import net.runelite.api.Point; -import net.runelite.api.Region; -import net.runelite.api.Tile; import net.runelite.api.coords.LocalPoint; -import net.runelite.client.game.ItemManager; +import net.runelite.api.coords.WorldPoint; import net.runelite.client.ui.FontManager; 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.components.TextComponent; import net.runelite.client.util.StackFormatter; -import net.runelite.http.api.item.ItemPrice; public class GroundItemsOverlay extends Overlay { - private static final int REGION_SIZE = 104; + private static final int MAX_DISTANCE = 2500; // We must offset the text on the z-axis such that // it doesn't obscure the ground items below it. private static final int OFFSET_Z = 20; // The game won't send anything higher than this value to the plugin - // so we replace any item quantity higher with "Lots" instead. private static final int MAX_QUANTITY = 65535; - // The max distance in tiles between the player and the item. - private static final int MAX_RANGE = 18; // The 15 pixel gap between each drawn ground item. private static final int STRING_GAP = 15; // Threshold for highlighting items as blue. - static final int LOW_VALUE = 20_000; + private static final int LOW_VALUE = 20_000; // Threshold for highlighting items as green. private static final int MEDIUM_VALUE = 100_000; // Threshold for highlighting items as amber. private static final int HIGH_VALUE = 1_000_000; // Threshold for highlighting items as pink. private static final int INSANE_VALUE = 10_000_000; - // Used when getting High Alchemy value - multiplied by general store price. - private static final float HIGH_ALCHEMY_CONSTANT = 0.6f; - // ItemID for coins - private static final int COINS = ItemID.COINS_995; - // Size of the hidden/highlight boxes private static final int RECTANGLE_SIZE = 8; - private Rectangle itemHiddenBox; - private Rectangle itemHighlightBox; - private final Client client; private final GroundItemsPlugin plugin; private final GroundItemsConfig config; private final StringBuilder itemStringBuilder = new StringBuilder(); - - @Inject - private ItemManager itemManager; + private final TextComponent textComponent = new TextComponent(); + private final Map offsetMap = new HashMap<>(); @Inject public GroundItemsOverlay(Client client, GroundItemsPlugin plugin, GroundItemsConfig config) @@ -109,239 +87,156 @@ public class GroundItemsOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - Region region = client.getRegion(); - Tile[][][] tiles = region.getTiles(); - FontMetrics fm = graphics.getFontMetrics(); + final FontMetrics fm = graphics.getFontMetrics(); + final Player player = client.getLocalPlayer(); - Player player = client.getLocalPlayer(); if (player == null || client.getViewportWidget() == null) { return null; } graphics.setFont(FontManager.getRunescapeSmallFont()); + offsetMap.clear(); + final LocalPoint localLocation = player.getLocalLocation(); - int z = client.getPlane(); - LocalPoint from = player.getLocalLocation(); - - int lowerX = max(0, from.getRegionX() - MAX_RANGE); - int lowerY = max(0, from.getRegionY() - MAX_RANGE); - - int upperX = min(from.getRegionX() + MAX_RANGE, REGION_SIZE - 1); - int upperY = min(from.getRegionY() + MAX_RANGE, REGION_SIZE - 1); - - // Clear boxes - if (plugin.isHotKeyPressed()) + plugin.getCollectedGroundItems().forEach(item -> { - plugin.getHiddenBoxes().clear(); - plugin.getHighlightBoxes().clear(); - } + final LocalPoint groundPoint = LocalPoint.fromWorld(client, item.getLocation()); - for (int x = lowerX; x <= upperX; ++x) - { - for (int y = lowerY; y <= upperY; ++y) + if (groundPoint == null || localLocation.distanceTo(groundPoint) > MAX_DISTANCE) { - Tile tile = tiles[z][x][y]; - if (tile == null) + return; + } + + final boolean highlighted = plugin.isHighlighted(item.getName()); + + if (!plugin.isHotKeyPressed() && !highlighted + && ((item.getGePrice() > 0 && item.getGePrice() < config.getHideUnderGeValue()) + || item.getHaPrice() < config.getHideUnderHAValue())) + { + return; + } + + final boolean hidden = plugin.isHidden(item.getName()); + final Color color = getCostColor(item.getGePrice() > 0 ? item.getGePrice() : item.getHaPrice(), highlighted); + itemStringBuilder.append(item.getName()); + + if (item.getQuantity() > 1) + { + if (item.getQuantity() >= MAX_QUANTITY) { - continue; + itemStringBuilder.append(" (Lots!)"); } - - ItemLayer itemLayer = tile.getItemLayer(); - if (itemLayer == null) + else { - continue; - } - - Node current = itemLayer.getBottom(); - Map items = new LinkedHashMap<>(); - // adds the items on the ground to the ArrayList to be drawn - while (current instanceof Item) - { - Item item = (Item) current; - int itemId = item.getId(); - int itemQuantity = item.getQuantity(); - ItemComposition itemDefinition = itemManager.getItemComposition(itemId); - - Integer currentQuantity = items.get(itemId); - - if ((config.showHighlightedOnly() ? plugin.isHighlighted(itemDefinition.getName()) : !plugin.isHidden(itemDefinition.getName())) || plugin.isHotKeyPressed()) - { - if (itemDefinition.getNote() != -1) - { - itemId = itemDefinition.getLinkedNoteId(); - } - - int quantity = currentQuantity == null - ? itemQuantity - : currentQuantity + itemQuantity; - - ItemPrice itemPrice = itemManager.getItemPriceAsync(itemId); - - int gePrice, alchPrice; - - if (itemId == COINS) - { - gePrice = quantity; - alchPrice = quantity; - } - else - { - gePrice = itemPrice == null ? 0 : itemPrice.getPrice() * quantity; - alchPrice = Math.round(itemDefinition.getPrice() * HIGH_ALCHEMY_CONSTANT) * quantity; - } - if (plugin.isHighlighted(itemDefinition.getName()) || - gePrice == 0 || ((gePrice >= config.getHideUnderGeValue()) && - (alchPrice >= config.getHideUnderHAValue()))) - { - items.put(itemId, quantity); - } - } - - current = current.getNext(); - } - - // The bottom item is drawn first - List itemIds = new ArrayList<>(items.keySet()); - Collections.reverse(itemIds); - - for (int i = 0; i < itemIds.size(); ++i) - { - Point point = itemLayer.getCanvasLocation(itemLayer.getHeight() + OFFSET_Z); - // if the item is offscreen, don't bother drawing it - if (point == null) - { - continue; - } - - int itemId = itemIds.get(i); - int quantity = items.get(itemId); - ItemComposition item = itemManager.getItemComposition(itemId); - - if (item == null) - { - continue; - } - - itemStringBuilder.append(item.getName()); - if (quantity > 1) - { - if (quantity >= MAX_QUANTITY) - { - itemStringBuilder.append(" (Lots!)"); - } - else - { - itemStringBuilder.append(" (").append(quantity).append(")"); - } - } - - // sets item ID to unnoted version, if noted - if (item.getNote() != -1) - { - itemId = item.getLinkedNoteId(); - } - - Color textColor = config.defaultColor(); // Color to use when drawing the ground item - ItemPrice itemPrice = itemManager.getItemPriceAsync(itemId); - if (itemPrice != null && config.showGEPrice()) - { - int cost = itemPrice.getPrice() * quantity; - - textColor = getCostColor(cost); - - itemStringBuilder.append(" (EX: ") - .append(StackFormatter.quantityToStackSize(cost)) - .append(" gp)"); - } - - if (config.showHAValue()) - { - itemStringBuilder.append(" (HA: ") - .append(Math.round(item.getPrice() * HIGH_ALCHEMY_CONSTANT) * quantity) - .append(" gp)"); - } - - if (plugin.isHighlighted(item.getName())) - { - textColor = config.highlightedColor(); - } - - String itemString = itemStringBuilder.toString(); - itemStringBuilder.setLength(0); - - int screenX = point.getX() + 2 - (fm.stringWidth(itemString) / 2); - int screenY = point.getY() - (STRING_GAP * i); - - // Drawing the shadow for the text, 1px on both x and y - graphics.setColor(Color.BLACK); - graphics.drawString(itemString, screenX + 1, screenY + 1); - // Drawing the text itself - graphics.setColor(textColor); - graphics.drawString(itemString, screenX, screenY); - - if (plugin.isHotKeyPressed()) - { - // Hidden box - itemHiddenBox = new Rectangle - ( - screenX + fm.stringWidth(itemString), - screenY - (fm.getHeight() / 2) - fm.getDescent(), - RECTANGLE_SIZE, - fm.getHeight() / 2 - ); - plugin.getHiddenBoxes().put(itemHiddenBox, item.getName()); - - // Highlight box - itemHighlightBox = new Rectangle - ( - screenX + fm.stringWidth(itemString) + RECTANGLE_SIZE + 2, - screenY - (fm.getHeight() / 2) - fm.getDescent(), - RECTANGLE_SIZE, - fm.getHeight() / 2 - ); - plugin.getHighlightBoxes().put(itemHighlightBox, item.getName()); - - Point mousePos = client.getMouseCanvasPosition(); - boolean mouseInHiddenBox = itemHiddenBox.contains(mousePos.getX(), mousePos.getY()); - boolean mouseInHighlightBox = itemHighlightBox.contains(mousePos.getX(), mousePos.getY()); - - // Draw hidden box - drawRectangle(graphics, itemHiddenBox, mouseInHiddenBox ? Color.RED : textColor, plugin.isHidden(item.getName()), true); - - // Draw highlight box - drawRectangle(graphics, itemHighlightBox, mouseInHighlightBox ? Color.GREEN : textColor, plugin.isHighlighted(item.getName()), false); - } + itemStringBuilder.append(" (").append(item.getQuantity()).append(")"); } } - } + + if (config.showGEPrice() && item.getGePrice() > 0) + { + itemStringBuilder.append(" (EX: ") + .append(StackFormatter.quantityToStackSize(item.getGePrice())) + .append(" gp)"); + } + + if (config.showHAValue() && item.getHaPrice() > 0) + { + itemStringBuilder.append(" (HA: ") + .append(StackFormatter.quantityToStackSize(item.getHaPrice())) + .append(" gp)"); + } + + final String itemString = itemStringBuilder.toString(); + itemStringBuilder.setLength(0); + + final Point textPoint = Perspective.getCanvasTextLocation(client, + graphics, + groundPoint, + itemString, OFFSET_Z); + + if (textPoint == null) + { + return; + } + + final int offset = offsetMap.compute(item.getLocation(), (k, v) -> v != null ? v + 1 : 0); + final int textX = textPoint.getX(); + final int textY = textPoint.getY() - (STRING_GAP * offset); + + textComponent.setText(itemString); + textComponent.setColor(color); + textComponent.setPosition(new java.awt.Point(textX, textY)); + textComponent.render(graphics); + + if (plugin.isHotKeyPressed()) + { + final int stringWidth = fm.stringWidth(itemString); + final int stringHeight = fm.getHeight(); + final int descent = fm.getDescent(); + + // Hidden box + final Rectangle itemHiddenBox = new Rectangle( + textX + stringWidth, + textY - (stringHeight / 2) - descent, + RECTANGLE_SIZE, + stringHeight / 2); + + plugin.getHiddenBoxes().put(itemHiddenBox, item.getName()); + + // Highlight box + final Rectangle itemHighlightBox = new Rectangle( + textX + stringWidth + RECTANGLE_SIZE + 2, + textY - (stringHeight / 2) - descent, + RECTANGLE_SIZE, + stringHeight / 2); + + plugin.getHighlightBoxes().put(itemHighlightBox, item.getName()); + + final Point mousePos = client.getMouseCanvasPosition(); + boolean mouseInHiddenBox = itemHiddenBox.contains(mousePos.getX(), mousePos.getY()); + boolean mouseInHighlightBox = itemHighlightBox.contains(mousePos.getX(), mousePos.getY()); + + // Draw hidden box + drawRectangle(graphics, itemHiddenBox, mouseInHiddenBox ? Color.RED : color, hidden, true); + + // Draw highlight box + drawRectangle(graphics, itemHighlightBox, mouseInHighlightBox ? Color.GREEN : color, highlighted, false); + } + }); return null; } - Color getCostColor(int cost) + Color getCostColor(int cost, boolean highlighted) { + if (highlighted) + { + return config.highlightedColor(); + } + // set the color according to rarity, if possible if (cost >= INSANE_VALUE) // 10,000,000 gp { return config.insaneValueColor(); } - else if (cost >= HIGH_VALUE) // 1,000,000 gp + + if (cost >= HIGH_VALUE) // 1,000,000 gp { return config.highValueColor(); } - else if (cost >= MEDIUM_VALUE) // 100,000 gp + + if (cost >= MEDIUM_VALUE) // 100,000 gp { return config.mediumValueColor(); } - else if (cost >= LOW_VALUE) // 20,000 gp + + if (cost >= LOW_VALUE) // 20,000 gp { return config.lowValueColor(); } - else - { - return config.defaultColor(); - } + + return config.defaultColor(); } private void drawRectangle(Graphics2D graphics, Rectangle rect, Color color, boolean inList, boolean hiddenBox) @@ -360,23 +255,23 @@ public class GroundItemsOverlay extends Overlay graphics.setColor(Color.WHITE); // Minus symbol graphics.drawLine - ( - rect.x + 2, - rect.y + (RECTANGLE_SIZE / 2), - rect.x + RECTANGLE_SIZE - 2, - rect.y + (RECTANGLE_SIZE / 2) - ); + ( + rect.x + 2, + rect.y + (RECTANGLE_SIZE / 2), + rect.x + RECTANGLE_SIZE - 2, + rect.y + (RECTANGLE_SIZE / 2) + ); if (!hiddenBox) { // Plus symbol graphics.drawLine - ( - rect.x + (RECTANGLE_SIZE / 2), - rect.y + 2, - rect.x + (RECTANGLE_SIZE / 2), - rect.y + RECTANGLE_SIZE - 2 - ); + ( + rect.x + (RECTANGLE_SIZE / 2), + rect.y + 2, + rect.x + (RECTANGLE_SIZE / 2), + rect.y + RECTANGLE_SIZE - 2 + ); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index f07d27c27d..839cdc476a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -38,22 +38,33 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Function; import java.util.regex.Pattern; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import javax.annotation.Nullable; import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.GameState; import net.runelite.api.Item; import net.runelite.api.ItemComposition; +import net.runelite.api.ItemID; import net.runelite.api.ItemLayer; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.Node; +import net.runelite.api.Player; import net.runelite.api.Region; import net.runelite.api.Tile; +import net.runelite.api.coords.LocalPoint; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.FocusChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.config.ConfigManager; import net.runelite.client.game.ItemManager; @@ -67,8 +78,32 @@ import net.runelite.http.api.item.ItemPrice; @PluginDescriptor( name = "Ground Items" ) +@Slf4j public class GroundItemsPlugin extends Plugin { + //Size of one region + private static final int REGION_SIZE = 104; + // The max distance in tiles between the player and the item. + private static final int MAX_RANGE = 18; + // Used when getting High Alchemy value - multiplied by general store price. + private static final float HIGH_ALCHEMY_CONSTANT = 0.6f; + // ItemID for coins + private static final int COINS = ItemID.COINS_995; + // Collects similar ground items + private static final Collector> GROUND_ITEM_MAP_COLLECTOR = Collectors + .toMap + ((item) -> new GroundItem.GroundItemKey(item.getItemId(), item.getLocation()), Function.identity(), ((a, b) -> + GroundItem.builder() + .index(b.getIndex()) + .id(b.getId()) + .itemId(b.getItemId()) + .name(b.getName()) + .location(b.getLocation()) + .haPrice(a.getHaPrice() + b.getHaPrice()) + .gePrice(a.getGePrice() + b.getGePrice()) + .quantity(a.getQuantity() + b.getQuantity()) + .build())); + @Getter(AccessLevel.PACKAGE) private final Map hiddenBoxes = new HashMap<>(); @@ -94,9 +129,6 @@ public class GroundItemsPlugin extends Plugin @Inject private Client client; - @Inject - private ConfigManager configManager; - @Inject private ItemManager itemManager; @@ -106,6 +138,9 @@ public class GroundItemsPlugin extends Plugin @Inject private GroundItemsOverlay overlay; + @Getter + private final List collectedGroundItems = new ArrayList<>(); + private final List groundItems = new ArrayList<>(); private LoadingCache highlightedItems; private LoadingCache hiddenItems; @@ -125,7 +160,6 @@ public class GroundItemsPlugin extends Plugin protected void startUp() { reset(); - mouseManager.registerMouseListener(inputListener); keyManager.registerKeyListener(inputListener); } @@ -135,6 +169,14 @@ public class GroundItemsPlugin extends Plugin { mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); + groundItems.clear(); + collectedGroundItems.clear(); + highlightedItems.invalidateAll(); + highlightedItems = null; + hiddenItems.invalidateAll(); + hiddenItems = null; + hiddenItemList = null; + highlightedItemsList = null; } @Subscribe @@ -146,6 +188,139 @@ public class GroundItemsPlugin extends Plugin } } + @Subscribe + public void onGameStateChanged(final GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + { + groundItems.clear(); + collectedGroundItems.clear(); + } + } + + @Subscribe + public void onGameTick(final GameTick event) + { + final Player player = client.getLocalPlayer(); + + if (player == null || client.getViewportWidget() == null) + { + return; + } + + final Region region = client.getRegion(); + final Tile[][][] tiles = region.getTiles(); + final int z = client.getPlane(); + final LocalPoint from = player.getLocalLocation(); + + final int lowerX = Math.max(0, from.getRegionX() - MAX_RANGE); + final int lowerY = Math.max(0, from.getRegionY() - MAX_RANGE); + + final int upperX = Math.min(from.getRegionX() + MAX_RANGE, REGION_SIZE - 1); + final int upperY = Math.min(from.getRegionY() + MAX_RANGE, REGION_SIZE - 1); + + groundItems.clear(); + int index = 0; + + for (int x = lowerX; x <= upperX; ++x) + { + for (int y = lowerY; y <= upperY; ++y) + { + Tile tile = tiles[z][x][y]; + if (tile == null) + { + continue; + } + + ItemLayer itemLayer = tile.getItemLayer(); + if (itemLayer == null) + { + continue; + } + + Node current = itemLayer.getBottom(); + + // adds the items on the ground to the ArrayList to be drawn + while (current instanceof Item) + { + final Item item = (Item) current; + + // Continue iteration + current = current.getNext(); + + // Build ground item + final GroundItem groundItem = buildGroundItem(tile, item); + + if (groundItem != null) + { + groundItems.add(groundItem); + + // Required for preserving the correct order later + groundItem.setIndex(index); + index++; + } + } + } + } + + // Group ground items together and sort them properly + collectedGroundItems.clear(); + groundItems.stream() + .collect(GROUND_ITEM_MAP_COLLECTOR) + .values() + .stream() + .sorted((left, right) -> Integer.compare(right.getIndex(), left.getIndex())) + .collect(Collectors.toCollection(() -> collectedGroundItems)); + } + + @Nullable + private GroundItem buildGroundItem(final Tile tile, final Item item) + { + // Collect the data for the item + final int itemId = item.getId(); + final ItemComposition itemComposition = itemManager.getItemComposition(itemId); + final int realItemId = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemId; + final int alchPrice = Math.round(itemComposition.getPrice() * HIGH_ALCHEMY_CONSTANT); + final String name = itemComposition.getName(); + + final boolean hidden = isHidden(name); + + if (!isHotKeyPressed() && hidden) + { + return null; + } + + final boolean highlighted = isHighlighted(name); + + if (config.showHighlightedOnly() && !isHotKeyPressed() && !highlighted) + { + return null; + } + + final GroundItem groundItem = GroundItem.builder() + .id(itemId) + .location(tile.getWorldLocation()) + .itemId(realItemId) + .quantity(item.getQuantity()) + .name(itemComposition.getName()) + .haPrice(alchPrice * item.getQuantity()) + .build(); + + // Set the correct item price + if (realItemId == COINS) + { + groundItem.setHaPrice(item.getQuantity()); + groundItem.setGePrice(item.getQuantity()); + } + else + { + final ItemPrice itemPrice = itemManager.getItemPriceAsync(realItemId); + groundItem.setGePrice(itemPrice != null ? itemPrice.getPrice() * item.getQuantity() : 0); + } + + return groundItem; + } + private void reset() { Splitter COMMA_SPLITTER = Splitter.on(Pattern.compile("\\s*,\\s*")); @@ -219,20 +394,9 @@ public class GroundItemsPlugin extends Plugin ItemPrice itemPrice = getItemPrice(itemComposition); int price = itemPrice == null ? itemComposition.getPrice() : itemPrice.getPrice(); int cost = quantity * price; + Color color = overlay.getCostColor(cost, isHighlighted(itemComposition.getName())); - Color color = null; - - if (cost >= GroundItemsOverlay.LOW_VALUE) - { - color = overlay.getCostColor(cost); - } - - if (isHighlighted(itemComposition.getName())) - { - color = config.highlightedColor(); - } - - if (color != null) + if (!color.equals(config.defaultColor())) { String hexColor = Integer.toHexString(color.getRGB() & 0xFFFFFF); String colTag = "";