From 1bac71f8402646dbd4cbb2e32fa8eab310c8eb31 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 15 Jul 2018 14:50:11 -0400 Subject: [PATCH 1/6] Add item spawn events --- .../runelite/api/events/ItemDespawned.java | 40 ++++++ .../api/events/ItemQuantityChanged.java | 41 ++++++ .../net/runelite/api/events/ItemSpawned.java | 40 ++++++ .../net/runelite/mixins/RSClientMixin.java | 18 +++ .../java/net/runelite/mixins/RSItemMixin.java | 125 ++++++++++++++++++ .../java/net/runelite/mixins/RSNodeMixin.java | 46 +++++++ .../java/net/runelite/mixins/RSTileMixin.java | 97 +++++++++++++- .../java/net/runelite/rs/api/RSClient.java | 4 + .../main/java/net/runelite/rs/api/RSItem.java | 15 +++ .../main/java/net/runelite/rs/api/RSNode.java | 8 ++ 10 files changed, 430 insertions(+), 4 deletions(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/events/ItemDespawned.java create mode 100644 runelite-api/src/main/java/net/runelite/api/events/ItemQuantityChanged.java create mode 100644 runelite-api/src/main/java/net/runelite/api/events/ItemSpawned.java create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/RSItemMixin.java create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/RSNodeMixin.java diff --git a/runelite-api/src/main/java/net/runelite/api/events/ItemDespawned.java b/runelite-api/src/main/java/net/runelite/api/events/ItemDespawned.java new file mode 100644 index 0000000000..4e60837d9d --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/ItemDespawned.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, Adam + * 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.api.events; + +import lombok.Value; +import net.runelite.api.Item; +import net.runelite.api.Tile; + +/** + * Called when an item pile despawns from the ground. When the client loads a new scene, + * all item piles are implicitly despawned, and despawn events will not be sent. + */ +@Value +public class ItemDespawned +{ + private final Tile tile; + private final Item item; +} diff --git a/runelite-api/src/main/java/net/runelite/api/events/ItemQuantityChanged.java b/runelite-api/src/main/java/net/runelite/api/events/ItemQuantityChanged.java new file mode 100644 index 0000000000..fb6b4f37ae --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/ItemQuantityChanged.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018, Adam + * 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.api.events; + +import lombok.Value; +import net.runelite.api.Item; +import net.runelite.api.Tile; + +/** + * Called when the quantity of an item pile changes. + */ +@Value +public class ItemQuantityChanged +{ + private final Item item; + private final Tile tile; + private final int oldQuantity; + private final int newQuantity; +} diff --git a/runelite-api/src/main/java/net/runelite/api/events/ItemSpawned.java b/runelite-api/src/main/java/net/runelite/api/events/ItemSpawned.java new file mode 100644 index 0000000000..e02d927cfc --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/ItemSpawned.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, Adam + * 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.api.events; + +import lombok.Value; +import net.runelite.api.Item; +import net.runelite.api.Tile; + +/** + * Called when an item pile spawns on the ground. When the client loads a new scene, + * all item piles are implicitly reset and a new spawn event will be sent. + */ +@Value +public class ItemSpawned +{ + private final Tile tile; + private final Item item; +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index d128571a99..9708ae1379 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -102,6 +102,7 @@ import net.runelite.rs.api.RSFriendContainer; import net.runelite.rs.api.RSFriendManager; import net.runelite.rs.api.RSHashTable; import net.runelite.rs.api.RSIndexedSprite; +import net.runelite.rs.api.RSItem; import net.runelite.rs.api.RSItemContainer; import net.runelite.rs.api.RSNPC; import net.runelite.rs.api.RSName; @@ -149,6 +150,9 @@ public abstract class RSClientMixin implements RSClient @Inject private static int oldMenuEntryCount; + @Inject + private static RSItem lastItemDespawn; + @Inject @Override public Callbacks getCallbacks() @@ -1148,4 +1152,18 @@ public abstract class RSClientMixin implements RSClient } } } + + @Inject + @Override + public RSItem getLastItemDespawn() + { + return lastItemDespawn; + } + + @Inject + @Override + public void setLastItemDespawn(RSItem lastItemDespawn) + { + RSClientMixin.lastItemDespawn = lastItemDespawn; + } } \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSItemMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSItemMixin.java new file mode 100644 index 0000000000..1d0732d9f6 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSItemMixin.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2018, Adam + * 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.mixins; + +import net.runelite.api.Tile; +import net.runelite.api.events.ItemQuantityChanged; +import net.runelite.api.mixins.FieldHook; +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSClient; +import net.runelite.rs.api.RSItem; + +@Mixin(RSItem.class) +public abstract class RSItemMixin implements RSItem +{ + @Shadow("clientInstance") + private static RSClient client; + + @Inject + private int rl$sceneX = -1; + + @Inject + private int rl$sceneY = -1; + + @Inject + RSItemMixin() + { + } + + @Inject + @Override + public Tile getTile() + { + int x = rl$sceneX; + int y = rl$sceneY; + + if (x == -1 || y == -1) + { + return null; + } + + Tile[][][] tiles = client.getScene().getTiles(); + Tile tile = tiles[client.getPlane()][x][y]; + return tile; + } + + @Inject + @Override + public void onUnlink() + { + if (rl$sceneX != -1) + { + // on despawn, the first item unlinked is the item despawning. However on spawn + // items can be delinked in order to sort them, so we can't assume the item here is despawning + if (client.getLastItemDespawn() == null) + { + client.setLastItemDespawn(this); + } + } + } + + @Inject + @FieldHook(value = "quantity", before = true) + public void quantityChanged(int quantity) + { + if (rl$sceneX != -1) + { + client.getLogger().debug("Item quantity changed: {} ({} -> {})", getId(), getQuantity(), quantity); + + ItemQuantityChanged itemQuantityChanged = new ItemQuantityChanged(this, getTile(), getQuantity(), quantity); + client.getCallbacks().post(itemQuantityChanged); + } + } + + @Inject + @Override + public int getX() + { + return rl$sceneX; + } + + @Inject + @Override + public void setX(int x) + { + rl$sceneX = x; + } + + @Inject + @Override + public int getY() + { + return rl$sceneY; + } + + @Inject + @Override + public void setY(int y) + { + rl$sceneY = y; + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNodeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNodeMixin.java new file mode 100644 index 0000000000..4a8f7162cf --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNodeMixin.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, Adam + * 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.mixins; + +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.MethodHook; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSNode; + +@Mixin(RSNode.class) +public abstract class RSNodeMixin implements RSNode +{ + @Inject + public void onUnlink() + { + } + + @Inject + @MethodHook("unlink") + public void rl$unlink() + { + onUnlink(); + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java index b0dab51ca2..23f5f163cb 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java @@ -30,11 +30,11 @@ import net.runelite.api.Actor; import net.runelite.api.CollisionDataFlag; import net.runelite.api.DecorativeObject; import net.runelite.api.GameObject; -import net.runelite.api.GameState; import net.runelite.api.GroundObject; import net.runelite.api.Item; import net.runelite.api.ItemLayer; import net.runelite.api.Node; +import net.runelite.api.Perspective; import net.runelite.api.Point; import net.runelite.api.Tile; import net.runelite.api.WallObject; @@ -49,7 +49,9 @@ import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; +import net.runelite.api.events.ItemDespawned; import net.runelite.api.events.ItemLayerChanged; +import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; @@ -59,7 +61,11 @@ import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Shadow; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSCollisionData; +import net.runelite.rs.api.RSDeque; import net.runelite.rs.api.RSGameObject; +import net.runelite.rs.api.RSItem; +import net.runelite.rs.api.RSItemLayer; +import net.runelite.rs.api.RSNode; import net.runelite.rs.api.RSTile; @Mixin(RSTile.class) @@ -270,12 +276,95 @@ public abstract class RSTileMixin implements RSTile @Inject public void itemLayerChanged(int idx) { - if (client.getGameState() != GameState.LOGGED_IN) + RSItem lastUnlink = client.getLastItemDespawn(); + if (lastUnlink != null) { - // during loading this gets set to null 104x104 times + client.setLastItemDespawn(null); + } + + RSItemLayer itemLayer = (RSItemLayer) getItemLayer(); + if (itemLayer == null) + { + if (lastUnlink != null) + { + client.getLogger().debug("Item despawn: {} ({})", lastUnlink.getId(), lastUnlink.getQuantity()); + ItemDespawned itemDespawned = new ItemDespawned(this, lastUnlink); + client.getCallbacks().post(itemDespawned); + } return; } + int x = itemLayer.getX() / Perspective.LOCAL_TILE_SIZE; + int y = itemLayer.getY() / Perspective.LOCAL_TILE_SIZE; + int z = client.getPlane(); + + RSDeque[][][] groundItemDeque = client.getGroundItemDeque(); + RSDeque itemDeque = groundItemDeque[z][x][y]; + + if (itemDeque == null) + { + if (lastUnlink != null) + { + client.getLogger().debug("Item despawn: {} ({})", lastUnlink.getId(), lastUnlink.getQuantity()); + ItemDespawned itemDespawned = new ItemDespawned(this, lastUnlink); + client.getCallbacks().post(itemDespawned); + } + return; + } + + // The new item gets added to either the head, or the tail, depending on its price + RSNode head = itemDeque.getHead(); + RSNode current = null; + RSNode previous = head.getPrevious(); + boolean forward = false; + if (head != previous) + { + RSItem prev = (RSItem) previous; + if (x != prev.getX() || y != prev.getY()) + { + current = prev; + } + } + + RSNode next = head.getNext(); + if (current == null && head != next) + { + RSItem n = (RSItem) next; + if (x != n.getX() || y != n.getY()) + { + current = n; + forward = true; + } + } + + if (lastUnlink != null && lastUnlink != previous && lastUnlink != next) + { + client.getLogger().debug("Item despawn: {} ({})", lastUnlink.getId(), lastUnlink.getQuantity()); + ItemDespawned itemDespawned = new ItemDespawned(this, lastUnlink); + client.getCallbacks().post(itemDespawned); + } + + if (current == null) + { + return; // already seen this spawn, or no new item + } + + do + { + RSItem item = (RSItem) current; + client.getLogger().debug("Item spawn: {} ({})", item.getId(), item.getQuantity()); + item.setX(x); + item.setY(y); + + ItemSpawned itemSpawned = new ItemSpawned(this, item); + client.getCallbacks().post(itemSpawned); + + current = forward ? current.getNext() : current.getPrevious(); + + // Send spawn events for anything on this tile which is at the wrong location, which happens + // when the scene base changes + } while (current != head && (((RSItem) current).getX() != x || ((RSItem) current).getY() != y)); + ItemLayerChanged itemLayerChanged = new ItemLayerChanged(this); client.getCallbacks().post(itemLayerChanged); } @@ -405,7 +494,7 @@ public abstract class RSTileMixin implements RSTile Node node = layer.getBottom(); while (node instanceof Item) { - result.add((Item)node); + result.add((Item) node); node = node.getNext(); } return result; diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 2134363b54..5c64dd89ec 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -644,4 +644,8 @@ public interface RSClient extends RSGameEngine, Client @Import("oculusOrbNormalSpeed") @Override void setOculusOrbNormalSpeed(int state); + + RSItem getLastItemDespawn(); + + void setLastItemDespawn(RSItem lastItemDespawn); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSItem.java b/runescape-api/src/main/java/net/runelite/rs/api/RSItem.java index 9cd5604d70..4f451cf028 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSItem.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSItem.java @@ -25,6 +25,7 @@ package net.runelite.rs.api; import net.runelite.api.Item; +import net.runelite.api.Tile; import net.runelite.mapping.Import; public interface RSItem extends RSRenderable, Item @@ -42,4 +43,18 @@ public interface RSItem extends RSRenderable, Item @Import("quantity") void setQuantity(int quantity); + + int getX(); + + void setX(int x); + + int getY(); + + void setY(int y); + + /** + * Get the tile this item is on + * @return + */ + Tile getTile(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSNode.java b/runescape-api/src/main/java/net/runelite/rs/api/RSNode.java index f279e2bda2..ab24b70dda 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSNode.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSNode.java @@ -40,4 +40,12 @@ public interface RSNode extends Node @Import("previous") @Override RSNode getPrevious(); + + @Import("unlink") + void unlink(); + + /** + * Called when this node is unlinked + */ + void onUnlink(); } From 3016b84cfef5950a551240e6571189c4b1b0d856 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 15 Jul 2018 16:23:54 -0400 Subject: [PATCH 2/6] grounditems: rewrite to use item spawn events --- .../plugins/grounditems/GroundItem.java | 10 ++ .../grounditems/GroundItemsOverlay.java | 16 +- .../grounditems/GroundItemsPlugin.java | 145 +++++++----------- 3 files changed, 70 insertions(+), 101 deletions(-) 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 index be06ab8163..67cf9b5192 100644 --- 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 @@ -44,6 +44,16 @@ class GroundItem private int offset; private boolean tradeable; + int getHaPrice() + { + return haPrice * quantity; + } + + int getGePrice() + { + return gePrice * quantity; + } + @Value static class GroundItemKey { 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 20bf6ad373..b3006eeaf6 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 @@ -43,7 +43,6 @@ import net.runelite.api.Player; import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; -import net.runelite.client.game.ItemManager; import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.MENU; import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; 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.TextComponent; import net.runelite.client.util.StackFormatter; -import net.runelite.http.api.item.ItemPrice; public class GroundItemsOverlay extends Overlay { @@ -76,17 +74,15 @@ public class GroundItemsOverlay extends Overlay private final BackgroundComponent backgroundComponent = new BackgroundComponent(); private final TextComponent textComponent = new TextComponent(); private final Map offsetMap = new HashMap<>(); - private final ItemManager itemManager; @Inject - private GroundItemsOverlay(Client client, GroundItemsPlugin plugin, GroundItemsConfig config, ItemManager itemManager) + private GroundItemsOverlay(Client client, GroundItemsPlugin plugin, GroundItemsConfig config) { setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_SCENE); this.client = client; this.plugin = plugin; this.config = config; - this.itemManager = itemManager; } @Override @@ -107,8 +103,6 @@ public class GroundItemsOverlay extends Overlay return null; } - plugin.checkItems(); - offsetMap.clear(); final LocalPoint localLocation = player.getLocalLocation(); final Point mousePos = client.getMouseCanvasPosition(); @@ -177,14 +171,6 @@ public class GroundItemsOverlay extends Overlay 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 hidden = plugin.getHidden(item.getName(), item.getGePrice(), item.getHaPrice(), item.isTradeable()); 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 abb8200340..850e6c307b 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 @@ -29,13 +29,11 @@ import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.cache.CacheBuilder; import com.google.common.cache.LoadingCache; -import com.google.common.collect.Lists; import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.awt.Color; import java.awt.Rectangle; import static java.lang.Boolean.TRUE; -import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -43,17 +41,12 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; 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 lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import static net.runelite.api.Constants.SCENE_SIZE; import net.runelite.api.GameState; import net.runelite.api.Item; import net.runelite.api.ItemComposition; @@ -62,14 +55,14 @@ 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.Scene; 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.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.client.config.ConfigManager; import net.runelite.client.game.ItemManager; @@ -122,7 +115,6 @@ public class GroundItemsPlugin extends Plugin private List hiddenItemList = new CopyOnWriteArrayList<>(); private List highlightedItemsList = new CopyOnWriteArrayList<>(); - private boolean dirty; @Inject private GroundItemInputListener inputListener; @@ -150,23 +142,10 @@ public class GroundItemsPlugin extends Plugin @Getter private final Map collectedGroundItems = new LinkedHashMap<>(); - private final List groundItems = new ArrayList<>(); private final Map priceChecks = new LinkedHashMap<>(); private LoadingCache highlightedItems; private LoadingCache hiddenItems; - // Collects similar ground items - private final Collector> 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 GroundItemsConfig provideConfig(ConfigManager configManager) { @@ -188,13 +167,13 @@ public class GroundItemsPlugin extends Plugin overlayManager.remove(overlay); mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); - groundItems.clear(); highlightedItems.invalidateAll(); highlightedItems = null; hiddenItems.invalidateAll(); hiddenItems = null; hiddenItemList = null; highlightedItemsList = null; + collectedGroundItems.clear(); } @Subscribe @@ -209,80 +188,68 @@ public class GroundItemsPlugin extends Plugin @Subscribe public void onGameStateChanged(final GameStateChanged event) { - if (event.getGameState() == GameState.LOGGED_IN) + if (event.getGameState() == GameState.LOADING) { - dirty = true; + collectedGroundItems.clear(); } } @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; } - dirty = false; - - 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) + if (groundItem.getQuantity() <= item.getQuantity()) { - for (int y = 0; y < SCENE_SIZE; ++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) - { - groundItem.setHeight(itemLayer.getHeight()); - groundItems.add(groundItem); - } - } - } + collectedGroundItems.remove(groundItemKey); + } + else + { + groundItem.setQuantity(groundItem.getQuantity() - item.getQuantity()); + } + } + + @Subscribe + public void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged) + { + Item item = itemQuantityChanged.getItem(); + Tile tile = itemQuantityChanged.getTile(); + int oldQuantity = itemQuantityChanged.getOldQuantity(); + int newQuantity = itemQuantityChanged.getNewQuantity(); + + int diff = newQuantity - oldQuantity; + GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation()); + GroundItem groundItem = collectedGroundItems.get(groundItemKey); + if (groundItem != null) + { + groundItem.setQuantity(groundItem.getQuantity() + diff); } - - // 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) { // Collect the data for the item @@ -297,7 +264,7 @@ public class GroundItemsPlugin extends Plugin .itemId(realItemId) .quantity(item.getQuantity()) .name(itemComposition.getName()) - .haPrice(alchPrice * item.getQuantity()) + .haPrice(alchPrice) .tradeable(itemComposition.isTradeable()) .build(); @@ -305,8 +272,16 @@ public class GroundItemsPlugin extends Plugin // Update item price in case it is coins if (realItemId == COINS) { - groundItem.setHaPrice(groundItem.getQuantity()); - groundItem.setGePrice(groundItem.getQuantity()); + groundItem.setHaPrice(1); + groundItem.setGePrice(1); + } + else + { + final ItemPrice itemPrice = itemManager.getItemPrice(realItemId); + if (itemPrice != null) + { + groundItem.setGePrice(itemPrice.getPrice()); + } } return groundItem; @@ -330,8 +305,6 @@ public class GroundItemsPlugin extends Plugin .expireAfterAccess(10, TimeUnit.MINUTES) .build(new WildcardMatchLoader(hiddenItemList)); - dirty = true; - // Cache colors priceChecks.clear(); From c5ab07340784183e403727ac29b523b6591550c0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 15 Jul 2018 16:29:59 -0400 Subject: [PATCH 3/6] region tile manager: send item spawns at plugin start --- .../client/util/SceneTileManager.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/util/SceneTileManager.java b/runelite-client/src/main/java/net/runelite/client/util/SceneTileManager.java index 4027c189cd..a2ee3288b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/SceneTileManager.java +++ b/runelite-client/src/main/java/net/runelite/client/util/SceneTileManager.java @@ -35,11 +35,14 @@ import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.Constants; import net.runelite.api.GameState; +import net.runelite.api.Item; +import net.runelite.api.Node; import net.runelite.api.Scene; import net.runelite.api.Tile; import net.runelite.api.events.DecorativeObjectSpawned; import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GroundObjectSpawned; +import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.WallObjectSpawned; @Singleton @@ -56,6 +59,7 @@ public class SceneTileManager /** * Iterates over each tile in the scene if player is logged in + * * @param consumer consumer accepting tile as parameter */ public void forEachTile(Consumer consumer) @@ -91,6 +95,7 @@ public class SceneTileManager /** * Simulate object spawns for EventBus subscriber + * * @param subscriber EventBus subscriber */ public void simulateObjectSpawns(Object subscriber) @@ -132,6 +137,21 @@ public class SceneTileManager objectSpawned.setGameObject(object); eventBus.post(objectSpawned); }); + + Optional.ofNullable(tile.getItemLayer()).ifPresent(itemLayer -> + { + Node current = itemLayer.getBottom(); + + while (current instanceof Item) + { + final Item item = (Item) current; + + current = current.getNext(); + + final ItemSpawned itemSpawned = new ItemSpawned(tile, item); + eventBus.post(itemSpawned); + } + }); }); eventBus.unregister(subscriber); From 216d24ef5d4d4b7cdacecba5524c7f0efd8c02f1 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 15 Jul 2018 16:33:24 -0400 Subject: [PATCH 4/6] agility plugin: use item events --- .../client/plugins/agility/AgilityPlugin.java | 51 +++++++------------ 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java index b30b95c74a..06a33a285c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java @@ -35,8 +35,6 @@ import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.Item; import net.runelite.api.ItemID; -import net.runelite.api.ItemLayer; -import net.runelite.api.Node; import net.runelite.api.Player; import static net.runelite.api.Skill.AGILITY; import net.runelite.api.Tile; @@ -55,7 +53,8 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; -import net.runelite.api.events.ItemLayerChanged; +import net.runelite.api.events.ItemDespawned; +import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; @@ -182,8 +181,8 @@ public class AgilityPlugin extends Plugin Courses course = Courses.getCourse(client.getLocalPlayer().getWorldLocation().getRegionID()); if (course == null || (course.getCourseEndWorldPoints().length == 0 - ? Math.abs(course.getLastObstacleXp() - skillGained) > 1 - : Arrays.stream(course.getCourseEndWorldPoints()).noneMatch(wp -> wp.equals(client.getLocalPlayer().getWorldLocation())))) + ? Math.abs(course.getLastObstacleXp() - skillGained) > 1 + : Arrays.stream(course.getCourseEndWorldPoints()).noneMatch(wp -> wp.equals(client.getLocalPlayer().getWorldLocation())))) { return; } @@ -202,47 +201,31 @@ public class AgilityPlugin extends Plugin } @Subscribe - public void onItemLayerChanged(ItemLayerChanged event) + public void onItemSpawned(ItemSpawned itemSpawned) { if (obstacles.isEmpty()) { return; } - final Tile tile = event.getTile(); - final ItemLayer itemLayer = tile.getItemLayer(); - final boolean hasMark = tileHasMark(itemLayer); + final Item item = itemSpawned.getItem(); + final Tile tile = itemSpawned.getTile(); - if (markOfGrace != null && tile.getWorldLocation().equals(markOfGrace.getWorldLocation()) && !hasMark) - { - markOfGrace = null; - } - else if (hasMark) + if (item.getId() == ItemID.MARK_OF_GRACE) { markOfGrace = tile; } } - private boolean tileHasMark(ItemLayer itemLayer) + @Subscribe + public void onItemDespawned(ItemDespawned itemDespawned) { - if (itemLayer != null) + final Item item = itemDespawned.getItem(); + + if (item.getId() == ItemID.MARK_OF_GRACE) { - Node currentItem = itemLayer.getBottom(); - - while (currentItem instanceof Item) - { - final Item item = (Item) currentItem; - - currentItem = currentItem.getNext(); - - if (item.getId() == ItemID.MARK_OF_GRACE) - { - return true; - } - } + markOfGrace = null; } - - return false; } @Subscribe @@ -377,9 +360,9 @@ public class AgilityPlugin extends Plugin } if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) || - Obstacles.SHORTCUT_OBSTACLE_IDS.contains(newObject.getId()) || - (Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId()) - && Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID()))) + Obstacles.SHORTCUT_OBSTACLE_IDS.contains(newObject.getId()) || + (Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId()) + && Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID()))) { obstacles.put(newObject, tile); } From ca4616bac4fda211bc2ac26cd7cd2add92761366 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 15 Jul 2018 16:36:29 -0400 Subject: [PATCH 5/6] mta plugin: use item events --- .../mta/enchantment/EnchantmentRoom.java | 59 +++++++------------ 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java index b74c696b6d..a084b12606 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java @@ -33,13 +33,13 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.Item; import net.runelite.api.ItemID; -import net.runelite.api.ItemLayer; import net.runelite.api.Player; import net.runelite.api.Tile; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; -import net.runelite.api.events.ItemLayerChanged; +import net.runelite.api.events.ItemDespawned; +import net.runelite.api.events.ItemSpawned; import net.runelite.client.plugins.mta.MTAConfig; import net.runelite.client.plugins.mta.MTARoom; @@ -61,12 +61,9 @@ public class EnchantmentRoom extends MTARoom @Subscribe public void onGameStateChanged(GameStateChanged gameStateChanged) { - if (gameStateChanged.getGameState() == GameState.LOGGED_IN) + if (gameStateChanged.getGameState() == GameState.LOADING) { - if (!inside()) - { - dragonstones.clear(); - } + dragonstones.clear(); } } @@ -103,42 +100,30 @@ public class EnchantmentRoom extends MTARoom } @Subscribe - public void onItemLayerChanged(ItemLayerChanged event) + public void onItemSpawned(ItemSpawned itemSpawned) { - if (!inside()) + final Item item = itemSpawned.getItem(); + final Tile tile = itemSpawned.getTile(); + + if (item.getId() == ItemID.DRAGONSTONE_6903) { - return; + WorldPoint location = tile.getWorldLocation(); + log.debug("Adding dragonstone at {}", location); + dragonstones.add(location); } + } - Tile changed = event.getTile(); - ItemLayer itemLayer = changed.getItemLayer(); - WorldPoint worldPoint = changed.getWorldLocation(); + @Subscribe + public void onItemDespawned(ItemDespawned itemDespawned) + { + final Item item = itemDespawned.getItem(); + final Tile tile = itemDespawned.getTile(); - List groundItems = changed.getGroundItems(); - if (groundItems == null) + if (item.getId() == ItemID.DRAGONSTONE_6903) { - boolean removed = dragonstones.remove(worldPoint); - if (removed) - { - log.debug("Removed dragonstone at {}", worldPoint); - } - return; - } - - for (Item item : changed.getGroundItems()) - { - if (item.getId() == ItemID.DRAGONSTONE_6903) - { - log.debug("Adding dragonstone at {}", worldPoint); - dragonstones.add(worldPoint); - return; - } - } - - boolean removed = dragonstones.remove(worldPoint); - if (removed) - { - log.debug("Removed dragonstone at {}", worldPoint); + WorldPoint location = tile.getWorldLocation(); + log.debug("Removed dragonstone at {}", location); + dragonstones.remove(location); } } From 99c78482948e08caf633d747eb4ed9e23552d4f4 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 15 Jul 2018 16:37:39 -0400 Subject: [PATCH 6/6] Remove item layer changed event --- .../runelite/api/events/ItemLayerChanged.java | 48 ------------------- .../java/net/runelite/mixins/RSTileMixin.java | 4 -- 2 files changed, 52 deletions(-) delete mode 100644 runelite-api/src/main/java/net/runelite/api/events/ItemLayerChanged.java diff --git a/runelite-api/src/main/java/net/runelite/api/events/ItemLayerChanged.java b/runelite-api/src/main/java/net/runelite/api/events/ItemLayerChanged.java deleted file mode 100644 index d730e5ac38..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/events/ItemLayerChanged.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2018, Adam - * 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.api.events; - -import lombok.Value; -import net.runelite.api.Tile; - -/** - * An event called when an item pile on a {@link Tile} is modified. - *

- * Examples of when this event may trigger include: - *

    - *
  • Dropping an item
  • - *
  • Picking up an item
  • - *
  • A dropped item spawning
  • - *
  • Loading a region with dropped items
  • - *
- */ -@Value -public class ItemLayerChanged -{ - /** - * The affected tile. - */ - private Tile tile; -} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java index 23f5f163cb..a9056cbf1e 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java @@ -50,7 +50,6 @@ import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.ItemDespawned; -import net.runelite.api.events.ItemLayerChanged; import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; @@ -364,9 +363,6 @@ public abstract class RSTileMixin implements RSTile // Send spawn events for anything on this tile which is at the wrong location, which happens // when the scene base changes } while (current != head && (((RSItem) current).getX() != x || ((RSItem) current).getY() != y)); - - ItemLayerChanged itemLayerChanged = new ItemLayerChanged(this); - client.getCallbacks().post(itemLayerChanged); } @Inject