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 net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.rs.api.ItemComposition;
|
||||
|
||||
public class Client
|
||||
{
|
||||
@@ -187,6 +188,11 @@ public class Client
|
||||
return new Region(this, client.getRegion());
|
||||
}
|
||||
|
||||
public ItemComposition getItemDefinition(int id)
|
||||
{
|
||||
return client.getItemDefinition(id);
|
||||
}
|
||||
|
||||
public int 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.devtools.DevTools;
|
||||
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.idlenotifier.IdleNotifier;
|
||||
import net.runelite.client.plugins.mousehighlight.MouseHighlight;
|
||||
@@ -79,6 +80,7 @@ public class PluginManager
|
||||
plugins.add(new Zulrah());
|
||||
plugins.add(new AccountPlugin());
|
||||
plugins.add(new ConfigPlugin());
|
||||
plugins.add(new GroundItems());
|
||||
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -193,6 +193,9 @@ public interface Client extends GameEngine
|
||||
@Import("itemContainers")
|
||||
XHashTable getItemContainers();
|
||||
|
||||
@Import("getItemDefinition")
|
||||
ItemComposition getItemDefinition(int itemId);
|
||||
|
||||
@Import("componentTable")
|
||||
XHashTable getComponentTable();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user