Add plugin to display items dropped on the ground (#70)
This commit is contained in:
@@ -28,6 +28,7 @@ import java.awt.Canvas;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.rs.api.ItemComposition;
|
||||||
|
|
||||||
public class Client
|
public class Client
|
||||||
{
|
{
|
||||||
@@ -187,6 +188,11 @@ public class Client
|
|||||||
return new Region(this, client.getRegion());
|
return new Region(this, client.getRegion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemComposition getItemDefinition(int id)
|
||||||
|
{
|
||||||
|
return client.getItemDefinition(id);
|
||||||
|
}
|
||||||
|
|
||||||
public int getBaseX()
|
public int getBaseX()
|
||||||
{
|
{
|
||||||
return client.getBaseX();
|
return client.getBaseX();
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import net.runelite.client.plugins.clanchat.ClanChat;
|
|||||||
import net.runelite.client.plugins.config.ConfigPlugin;
|
import net.runelite.client.plugins.config.ConfigPlugin;
|
||||||
import net.runelite.client.plugins.devtools.DevTools;
|
import net.runelite.client.plugins.devtools.DevTools;
|
||||||
import net.runelite.client.plugins.fpsinfo.FPS;
|
import net.runelite.client.plugins.fpsinfo.FPS;
|
||||||
|
import net.runelite.client.plugins.grounditems.GroundItems;
|
||||||
import net.runelite.client.plugins.hiscore.Hiscore;
|
import net.runelite.client.plugins.hiscore.Hiscore;
|
||||||
import net.runelite.client.plugins.idlenotifier.IdleNotifier;
|
import net.runelite.client.plugins.idlenotifier.IdleNotifier;
|
||||||
import net.runelite.client.plugins.mousehighlight.MouseHighlight;
|
import net.runelite.client.plugins.mousehighlight.MouseHighlight;
|
||||||
@@ -79,6 +80,7 @@ public class PluginManager
|
|||||||
plugins.add(new Zulrah());
|
plugins.add(new Zulrah());
|
||||||
plugins.add(new AccountPlugin());
|
plugins.add(new AccountPlugin());
|
||||||
plugins.add(new ConfigPlugin());
|
plugins.add(new ConfigPlugin());
|
||||||
|
plugins.add(new GroundItems());
|
||||||
|
|
||||||
if (RuneLite.getOptions().has("developer-mode"))
|
if (RuneLite.getOptions().has("developer-mode"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.grounditems;
|
||||||
|
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
|
||||||
|
public class GroundItems extends Plugin
|
||||||
|
{
|
||||||
|
private final GroundItemsConfig config = RuneLite.getRunelite().getConfigManager()
|
||||||
|
.getConfig(GroundItemsConfig.class);
|
||||||
|
|
||||||
|
private final Overlay overlay = new GroundItemsOverlay(this);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startUp()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Overlay getOverlay()
|
||||||
|
{
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroundItemsConfig getConfig()
|
||||||
|
{
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.runelite.client.plugins.grounditems;
|
||||||
|
|
||||||
|
import net.runelite.client.config.ConfigGroup;
|
||||||
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
|
||||||
|
@ConfigGroup(
|
||||||
|
keyName = "grounditems",
|
||||||
|
name = "Ground Items",
|
||||||
|
description = "Configuration for the ground items plugin"
|
||||||
|
)
|
||||||
|
public interface GroundItemsConfig
|
||||||
|
{
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "enabled",
|
||||||
|
name = "Enabled",
|
||||||
|
description = "Configures whether or not item names/quantities are displayed"
|
||||||
|
)
|
||||||
|
|
||||||
|
default boolean enabled()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.grounditems;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemLayer;
|
||||||
|
import net.runelite.api.Node;
|
||||||
|
import net.runelite.api.Player;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.Region;
|
||||||
|
import net.runelite.api.Tile;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.rs.api.ItemComposition;
|
||||||
|
|
||||||
|
public class GroundItemsOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private static final int REGION_SIZE = 104;
|
||||||
|
// The game won't send anything higher than this value to the plugin -
|
||||||
|
// so we replace any item quantity higher with "Lots" instead.
|
||||||
|
private static final int MAX_QUANTITY = 65535;
|
||||||
|
// The max distance between the player and the item.
|
||||||
|
private static final int MAX_RANGE = 2400;
|
||||||
|
// The 15 pixel gap between each drawn ground item.
|
||||||
|
private static final int STRING_GAP = 15;
|
||||||
|
|
||||||
|
private final Client client = RuneLite.getClient();
|
||||||
|
private final GroundItemsConfig config;
|
||||||
|
private final StringBuilder itemStringBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
public GroundItemsOverlay(GroundItems plugin)
|
||||||
|
{
|
||||||
|
super(OverlayPosition.DYNAMIC);
|
||||||
|
this.config = plugin.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
// won't draw if not logged in
|
||||||
|
if (client.getGameState() != GameState.LOGGED_IN || !config.enabled())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget bank = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER);
|
||||||
|
if (bank != null && !bank.isHidden())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Region region = client.getRegion();
|
||||||
|
Tile[][][] tiles = region.getTiles();
|
||||||
|
FontMetrics fm = graphics.getFontMetrics();
|
||||||
|
|
||||||
|
Player player = client.getLocalPlayer();
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int z = client.getPlane();
|
||||||
|
|
||||||
|
for (int x = 0; x < REGION_SIZE; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < REGION_SIZE; y++)
|
||||||
|
{
|
||||||
|
Tile tile = tiles[z][x][y];
|
||||||
|
if (tile == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemLayer itemLayer = tile.getItemLayer();
|
||||||
|
if (itemLayer == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.getLocalLocation().distanceTo(itemLayer.getLocalLocation()) >= MAX_RANGE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node current = itemLayer.getBottom();
|
||||||
|
Map<Integer, Integer> items = new LinkedHashMap<>();
|
||||||
|
// adds the items on the ground to the ArrayList to be drawn
|
||||||
|
while (current instanceof Item)
|
||||||
|
{
|
||||||
|
Item item = (Item) current;
|
||||||
|
int itemId = item.getId();
|
||||||
|
int itemQuantity = item.getQuantity();
|
||||||
|
|
||||||
|
Integer currentQuantity = items.get(itemId);
|
||||||
|
if (currentQuantity == null)
|
||||||
|
{
|
||||||
|
items.put(itemId, itemQuantity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items.put(itemId, currentQuantity + itemQuantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current.getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The bottom item is drawn first
|
||||||
|
List<Integer> itemIds = new ArrayList<>(items.keySet());
|
||||||
|
Collections.reverse(itemIds);
|
||||||
|
|
||||||
|
for (int i = 0; i < itemIds.size(); ++i)
|
||||||
|
{
|
||||||
|
int itemId = itemIds.get(i);
|
||||||
|
int quantity = items.get(itemId);
|
||||||
|
ItemComposition item = client.getItemDefinition(itemId);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemStringBuilder.append(item.getName());
|
||||||
|
if (quantity > 1)
|
||||||
|
{
|
||||||
|
if (quantity >= MAX_QUANTITY)
|
||||||
|
{
|
||||||
|
itemStringBuilder.append(" (Lots!)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemStringBuilder.append(" (").append(quantity).append(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String itemString = itemStringBuilder.toString();
|
||||||
|
itemStringBuilder.setLength(0);
|
||||||
|
|
||||||
|
Point point = itemLayer.getCanvasLocation();
|
||||||
|
// if the item is offscreen, don't bother drawing it
|
||||||
|
if (point == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int screenX = point.getX() + 2 - (fm.stringWidth(itemString) / 2);
|
||||||
|
|
||||||
|
// Drawing the shadow for the text, 1px on both x and y
|
||||||
|
graphics.setColor(Color.BLACK);
|
||||||
|
graphics.drawString(itemString, screenX + 1, point.getY() - (STRING_GAP * i) + 1);
|
||||||
|
// Drawing the text itself
|
||||||
|
graphics.setColor(Color.WHITE);
|
||||||
|
graphics.drawString(itemString, screenX, point.getY() - (STRING_GAP * i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Aria <aria@snorflake.com>
|
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Aria <aria@snorflake.com>
|
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
@@ -193,6 +193,9 @@ public interface Client extends GameEngine
|
|||||||
@Import("itemContainers")
|
@Import("itemContainers")
|
||||||
XHashTable getItemContainers();
|
XHashTable getItemContainers();
|
||||||
|
|
||||||
|
@Import("getItemDefinition")
|
||||||
|
ItemComposition getItemDefinition(int itemId);
|
||||||
|
|
||||||
@Import("componentTable")
|
@Import("componentTable")
|
||||||
XHashTable getComponentTable();
|
XHashTable getComponentTable();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user