grounditems: rewrite to use item spawn events

This commit is contained in:
Adam
2018-07-15 16:23:54 -04:00
parent 1bac71f840
commit 3016b84cfe
3 changed files with 70 additions and 101 deletions

View File

@@ -44,6 +44,16 @@ class GroundItem
private int offset; private int offset;
private boolean tradeable; private boolean tradeable;
int getHaPrice()
{
return haPrice * quantity;
}
int getGePrice()
{
return gePrice * quantity;
}
@Value @Value
static class GroundItemKey static class GroundItemKey
{ {

View File

@@ -43,7 +43,6 @@ import net.runelite.api.Player;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.client.game.ItemManager;
import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.MENU; import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.MENU;
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
@@ -53,7 +52,6 @@ import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.BackgroundComponent; import net.runelite.client.ui.overlay.components.BackgroundComponent;
import net.runelite.client.ui.overlay.components.TextComponent; import net.runelite.client.ui.overlay.components.TextComponent;
import net.runelite.client.util.StackFormatter; import net.runelite.client.util.StackFormatter;
import net.runelite.http.api.item.ItemPrice;
public class GroundItemsOverlay extends Overlay public class GroundItemsOverlay extends Overlay
{ {
@@ -76,17 +74,15 @@ public class GroundItemsOverlay extends Overlay
private final BackgroundComponent backgroundComponent = new BackgroundComponent(); private final BackgroundComponent backgroundComponent = new BackgroundComponent();
private final TextComponent textComponent = new TextComponent(); private final TextComponent textComponent = new TextComponent();
private final Map<WorldPoint, Integer> offsetMap = new HashMap<>(); private final Map<WorldPoint, Integer> offsetMap = new HashMap<>();
private final ItemManager itemManager;
@Inject @Inject
private GroundItemsOverlay(Client client, GroundItemsPlugin plugin, GroundItemsConfig config, ItemManager itemManager) private GroundItemsOverlay(Client client, GroundItemsPlugin plugin, GroundItemsConfig config)
{ {
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE); setLayer(OverlayLayer.ABOVE_SCENE);
this.client = client; this.client = client;
this.plugin = plugin; this.plugin = plugin;
this.config = config; this.config = config;
this.itemManager = itemManager;
} }
@Override @Override
@@ -107,8 +103,6 @@ public class GroundItemsOverlay extends Overlay
return null; return null;
} }
plugin.checkItems();
offsetMap.clear(); offsetMap.clear();
final LocalPoint localLocation = player.getLocalLocation(); final LocalPoint localLocation = player.getLocalLocation();
final Point mousePos = client.getMouseCanvasPosition(); final Point mousePos = client.getMouseCanvasPosition();
@@ -177,14 +171,6 @@ public class GroundItemsOverlay extends Overlay
continue; continue;
} }
// Update GE price for item
final ItemPrice itemPrice = itemManager.getItemPrice(item.getItemId());
if (itemPrice != null && itemPrice.getPrice() > 0)
{
item.setGePrice(itemPrice.getPrice() * item.getQuantity());
}
final Color highlighted = plugin.getHighlighted(item.getName(), item.getGePrice(), item.getHaPrice()); final Color highlighted = plugin.getHighlighted(item.getName(), item.getGePrice(), item.getHaPrice());
final Color hidden = plugin.getHidden(item.getName(), item.getGePrice(), item.getHaPrice(), item.isTradeable()); final Color hidden = plugin.getHidden(item.getName(), item.getGePrice(), item.getHaPrice(), item.isTradeable());

View File

@@ -29,13 +29,11 @@ import com.google.common.base.Joiner;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.awt.Rectangle; import java.awt.Rectangle;
import static java.lang.Boolean.TRUE; import static java.lang.Boolean.TRUE;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@@ -43,17 +41,12 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import static net.runelite.api.Constants.SCENE_SIZE;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.Item; import net.runelite.api.Item;
import net.runelite.api.ItemComposition; import net.runelite.api.ItemComposition;
@@ -62,14 +55,14 @@ import net.runelite.api.ItemLayer;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry; import net.runelite.api.MenuEntry;
import net.runelite.api.Node; import net.runelite.api.Node;
import net.runelite.api.Player;
import net.runelite.api.Scene; import net.runelite.api.Scene;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ItemLayerChanged; import net.runelite.api.events.ItemDespawned;
import net.runelite.api.events.ItemQuantityChanged;
import net.runelite.api.events.ItemSpawned;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
@@ -122,7 +115,6 @@ public class GroundItemsPlugin extends Plugin
private List<String> hiddenItemList = new CopyOnWriteArrayList<>(); private List<String> hiddenItemList = new CopyOnWriteArrayList<>();
private List<String> highlightedItemsList = new CopyOnWriteArrayList<>(); private List<String> highlightedItemsList = new CopyOnWriteArrayList<>();
private boolean dirty;
@Inject @Inject
private GroundItemInputListener inputListener; private GroundItemInputListener inputListener;
@@ -150,23 +142,10 @@ public class GroundItemsPlugin extends Plugin
@Getter @Getter
private final Map<GroundItem.GroundItemKey, GroundItem> collectedGroundItems = new LinkedHashMap<>(); private final Map<GroundItem.GroundItemKey, GroundItem> collectedGroundItems = new LinkedHashMap<>();
private final List<GroundItem> groundItems = new ArrayList<>();
private final Map<Integer, Color> priceChecks = new LinkedHashMap<>(); private final Map<Integer, Color> priceChecks = new LinkedHashMap<>();
private LoadingCache<String, Boolean> highlightedItems; private LoadingCache<String, Boolean> highlightedItems;
private LoadingCache<String, Boolean> hiddenItems; private LoadingCache<String, Boolean> hiddenItems;
// Collects similar ground items
private final Collector<GroundItem, ?, Map<GroundItem.GroundItemKey, GroundItem>> groundItemMapCollector = Collectors
.toMap
((item) -> new GroundItem.GroundItemKey(item.getItemId(), item.getLocation()), Function.identity(), (a, b) ->
{
b.setHaPrice(a.getHaPrice() + b.getHaPrice());
b.setGePrice(a.getGePrice() + b.getGePrice());
b.setQuantity(a.getQuantity() + b.getQuantity());
return b;
},
() -> collectedGroundItems);
@Provides @Provides
GroundItemsConfig provideConfig(ConfigManager configManager) GroundItemsConfig provideConfig(ConfigManager configManager)
{ {
@@ -188,13 +167,13 @@ public class GroundItemsPlugin extends Plugin
overlayManager.remove(overlay); overlayManager.remove(overlay);
mouseManager.unregisterMouseListener(inputListener); mouseManager.unregisterMouseListener(inputListener);
keyManager.unregisterKeyListener(inputListener); keyManager.unregisterKeyListener(inputListener);
groundItems.clear();
highlightedItems.invalidateAll(); highlightedItems.invalidateAll();
highlightedItems = null; highlightedItems = null;
hiddenItems.invalidateAll(); hiddenItems.invalidateAll();
hiddenItems = null; hiddenItems = null;
hiddenItemList = null; hiddenItemList = null;
highlightedItemsList = null; highlightedItemsList = null;
collectedGroundItems.clear();
} }
@Subscribe @Subscribe
@@ -209,80 +188,68 @@ public class GroundItemsPlugin extends Plugin
@Subscribe @Subscribe
public void onGameStateChanged(final GameStateChanged event) public void onGameStateChanged(final GameStateChanged event)
{ {
if (event.getGameState() == GameState.LOGGED_IN) if (event.getGameState() == GameState.LOADING)
{ {
dirty = true; collectedGroundItems.clear();
} }
} }
@Subscribe @Subscribe
public void onItemLayerChanged(ItemLayerChanged event) public void onItemSpawned(ItemSpawned itemSpawned)
{ {
dirty = true; Item item = itemSpawned.getItem();
Tile tile = itemSpawned.getTile();
GroundItem groundItem = buildGroundItem(tile, item);
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
GroundItem existing = collectedGroundItems.putIfAbsent(groundItemKey, groundItem);
if (existing != null)
{
existing.setQuantity(existing.getQuantity() + groundItem.getQuantity());
}
} }
void checkItems() @Subscribe
public void onItemDespawned(ItemDespawned itemDespawned)
{ {
final Player player = client.getLocalPlayer(); Item item = itemDespawned.getItem();
Tile tile = itemDespawned.getTile();
if (!dirty || player == null || client.getViewportWidget() == null) GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
GroundItem groundItem = collectedGroundItems.get(groundItemKey);
if (groundItem == null)
{ {
return; return;
} }
dirty = false; if (groundItem.getQuantity() <= item.getQuantity())
final Scene scene = client.getScene();
final Tile[][][] tiles = scene.getTiles();
final int z = client.getPlane();
final LocalPoint from = player.getLocalLocation();
groundItems.clear();
for (int x = 0; x < SCENE_SIZE; ++x)
{ {
for (int y = 0; y < SCENE_SIZE; ++y) collectedGroundItems.remove(groundItemKey);
{ }
Tile tile = tiles[z][x][y]; else
if (tile == null) {
{ groundItem.setQuantity(groundItem.getQuantity() - item.getQuantity());
continue; }
} }
ItemLayer itemLayer = tile.getItemLayer(); @Subscribe
if (itemLayer == null) public void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged)
{ {
continue; Item item = itemQuantityChanged.getItem();
} Tile tile = itemQuantityChanged.getTile();
int oldQuantity = itemQuantityChanged.getOldQuantity();
Node current = itemLayer.getBottom(); int newQuantity = itemQuantityChanged.getNewQuantity();
// adds the items on the ground to the ArrayList to be drawn int diff = newQuantity - oldQuantity;
while (current instanceof Item) GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
{ GroundItem groundItem = collectedGroundItems.get(groundItemKey);
final Item item = (Item) current; if (groundItem != null)
{
// Continue iteration groundItem.setQuantity(groundItem.getQuantity() + diff);
current = current.getNext();
// Build ground item
final GroundItem groundItem = buildGroundItem(tile, item);
if (groundItem != null)
{
groundItem.setHeight(itemLayer.getHeight());
groundItems.add(groundItem);
}
}
}
} }
// Group ground items together and sort them properly
collectedGroundItems.clear();
Lists.reverse(groundItems).stream().collect(groundItemMapCollector);
} }
@Nullable
private GroundItem buildGroundItem(final Tile tile, final Item item) private GroundItem buildGroundItem(final Tile tile, final Item item)
{ {
// Collect the data for the item // Collect the data for the item
@@ -297,7 +264,7 @@ public class GroundItemsPlugin extends Plugin
.itemId(realItemId) .itemId(realItemId)
.quantity(item.getQuantity()) .quantity(item.getQuantity())
.name(itemComposition.getName()) .name(itemComposition.getName())
.haPrice(alchPrice * item.getQuantity()) .haPrice(alchPrice)
.tradeable(itemComposition.isTradeable()) .tradeable(itemComposition.isTradeable())
.build(); .build();
@@ -305,8 +272,16 @@ public class GroundItemsPlugin extends Plugin
// Update item price in case it is coins // Update item price in case it is coins
if (realItemId == COINS) if (realItemId == COINS)
{ {
groundItem.setHaPrice(groundItem.getQuantity()); groundItem.setHaPrice(1);
groundItem.setGePrice(groundItem.getQuantity()); groundItem.setGePrice(1);
}
else
{
final ItemPrice itemPrice = itemManager.getItemPrice(realItemId);
if (itemPrice != null)
{
groundItem.setGePrice(itemPrice.getPrice());
}
} }
return groundItem; return groundItem;
@@ -330,8 +305,6 @@ public class GroundItemsPlugin extends Plugin
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(10, TimeUnit.MINUTES)
.build(new WildcardMatchLoader(hiddenItemList)); .build(new WildcardMatchLoader(hiddenItemList));
dirty = true;
// Cache colors // Cache colors
priceChecks.clear(); priceChecks.clear();