@@ -25,24 +25,16 @@
|
||||
package net.runelite.api.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.Tile;
|
||||
|
||||
/**
|
||||
* An event called when an item pile on a {@link Tile} is modified.
|
||||
* <p>
|
||||
* Examples of when this event may trigger include:
|
||||
* <ul>
|
||||
* <li>Dropping an item</li>
|
||||
* <li>Picking up an item</li>
|
||||
* <li>A dropped item spawning</li>
|
||||
* <li>Loading a region with dropped items</li>
|
||||
* </ul>
|
||||
* 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 ItemLayerChanged
|
||||
public class ItemDespawned
|
||||
{
|
||||
/**
|
||||
* The affected tile.
|
||||
*/
|
||||
private Tile tile;
|
||||
private final Tile tile;
|
||||
private final Item item;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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<WorldPoint, Integer> 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());
|
||||
|
||||
|
||||
@@ -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<String> hiddenItemList = new CopyOnWriteArrayList<>();
|
||||
private List<String> highlightedItemsList = new CopyOnWriteArrayList<>();
|
||||
private boolean dirty;
|
||||
|
||||
@Inject
|
||||
private GroundItemInputListener inputListener;
|
||||
@@ -150,23 +142,10 @@ public class GroundItemsPlugin extends Plugin
|
||||
|
||||
@Getter
|
||||
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 LoadingCache<String, Boolean> highlightedItems;
|
||||
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
|
||||
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();
|
||||
|
||||
|
||||
@@ -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<Item> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Tile> 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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -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,8 @@ 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.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;
|
||||
@@ -59,7 +60,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,14 +275,94 @@ 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;
|
||||
}
|
||||
|
||||
ItemLayerChanged itemLayerChanged = new ItemLayerChanged(this);
|
||||
client.getCallbacks().post(itemLayerChanged);
|
||||
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));
|
||||
}
|
||||
|
||||
@Inject
|
||||
@@ -405,7 +490,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;
|
||||
|
||||
@@ -644,4 +644,8 @@ public interface RSClient extends RSGameEngine, Client
|
||||
@Import("oculusOrbNormalSpeed")
|
||||
@Override
|
||||
void setOculusOrbNormalSpeed(int state);
|
||||
|
||||
RSItem getLastItemDespawn();
|
||||
|
||||
void setLastItemDespawn(RSItem lastItemDespawn);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user