diff --git a/runelite-api/src/main/java/net/runelite/api/Actor.java b/runelite-api/src/main/java/net/runelite/api/Actor.java index 1d6ba09f47..84dd389df7 100644 --- a/runelite-api/src/main/java/net/runelite/api/Actor.java +++ b/runelite-api/src/main/java/net/runelite/api/Actor.java @@ -56,5 +56,7 @@ public interface Actor extends Renderable Point getCanvasImageLocation(Graphics2D graphics, BufferedImage image, int zOffset); + Point getCanvasSpriteLocation(Graphics2D graphics, SpritePixels sprite, int zOffset); + Point getMinimapLocation(); } diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 348c296fef..d49b1d70fe 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -82,6 +82,8 @@ public interface Client ItemComposition getItemDefinition(int id); + SpritePixels createItemSprite(int itemId, int quantity, int border, int shadowColor, int stackable, boolean noted); + int getBaseX(); int getBaseY(); diff --git a/runelite-api/src/main/java/net/runelite/api/Perspective.java b/runelite-api/src/main/java/net/runelite/api/Perspective.java index cf5f5de8f9..47aa5f07b5 100644 --- a/runelite-api/src/main/java/net/runelite/api/Perspective.java +++ b/runelite-api/src/main/java/net/runelite/api/Perspective.java @@ -307,4 +307,32 @@ public class Perspective return new Point(xOffset, yOffset); } + /** + * Calculates sprite position and centers depending on sprite size. + * + * @param client + * @param graphics + * @param localLocation local location of the tile + * @param sprite SpritePixel for size measurement + * @param zOffset offset from ground plane + * @return a {@link Point} on screen corresponding to the given + * localLocation. + */ + public static Point getCanvasSpriteLocation(Client client, Graphics2D graphics, Point localLocation, SpritePixels sprite, int zOffset) + { + int plane = client.getPlane(); + + Point p = Perspective.worldToCanvas(client, localLocation.getX(), localLocation.getY(), plane, zOffset); + + if (p == null) + { + return null; + } + + int xOffset = p.getX() - sprite.getWidth() / 2; + int yOffset = p.getY() - sprite.getHeight() / 2; + + return new Point(xOffset, yOffset); + } + } diff --git a/runelite-api/src/main/java/net/runelite/api/SpritePixels.java b/runelite-api/src/main/java/net/runelite/api/SpritePixels.java new file mode 100644 index 0000000000..df4c31396a --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/SpritePixels.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017, Tyler + * 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; + +public interface SpritePixels +{ + int DEFAULT_SHADOW_COLOR = 3153952; + + void drawAt(int x, int y); + + int getWidth(); + + int getHeight(); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java index 048df1847b..6b9823c618 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java @@ -24,6 +24,8 @@ */ package net.runelite.client.plugins.fishing; +import net.runelite.api.ItemID; + import java.util.HashMap; import java.util.Map; import static net.runelite.api.NpcID.FISHING_SPOT_1506; @@ -58,32 +60,32 @@ import static net.runelite.api.NpcID.FISHING_SPOT_7734; public enum FishingSpot { - SHRIMP("Shrimp, Anchovies", "shrimp", + SHRIMP("Shrimp, Anchovies", ItemID.RAW_SHRIMPS, FISHING_SPOT_1518, FISHING_SPOT_1525, FISHING_SPOT_1528, FISHING_SPOT_1530, FISHING_SPOT_1544, FISHING_SPOT_7155, FISHING_SPOT_7469 ), - LOBSTER("Lobster, Swordfish, Tuna", "lobster", + LOBSTER("Lobster, Swordfish, Tuna", ItemID.RAW_LOBSTER, FISHING_SPOT_1510, FISHING_SPOT_1519, FISHING_SPOT_1521, FISHING_SPOT_1522, FISHING_SPOT_7199, FISHING_SPOT_7470 ), - SHARK("Shark, Bass", "shark", + SHARK("Shark, Bass", ItemID.RAW_SHARK, FISHING_SPOT_1511, FISHING_SPOT_1520, FISHING_SPOT_7200 ), - MONKFISH("Monkfish", "monkfish", + MONKFISH("Monkfish", ItemID.RAW_MONKFISH, FISHING_SPOT_4316 ), - SALMON("Salmon, Trout", "salmon", + SALMON("Salmon, Trout", ItemID.RAW_SALMON, FISHING_SPOT_1506, FISHING_SPOT_1508, FISHING_SPOT_1515, FISHING_SPOT_1526, FISHING_SPOT_1527 ), - BARB_FISH("Sturgeon, Salmon, Trout", "barb", + BARB_FISH("Sturgeon, Salmon, Trout", ItemID.LEAPING_STURGEON, FISHING_SPOT_1542 ), - ANGLERFISH("Anglerfish", "anglerfish", + ANGLERFISH("Anglerfish", ItemID.RAW_ANGLERFISH, FISHING_SPOT_6825 ), - MINNOW("Minnow", "minnow", + MINNOW("Minnow", ItemID.MINNOW, FISHING_SPOT_7730, FISHING_SPOT_7731, FISHING_SPOT_7732, FISHING_SPOT_7733, FISHING_SPOT_7734 ); @@ -91,7 +93,7 @@ public enum FishingSpot private static final Map fishingSpots = new HashMap<>(); private final String name; - private final String image; + private final int itemSpriteId; private final int[] spots; static @@ -107,10 +109,10 @@ public enum FishingSpot } } - FishingSpot(String spot, String image, int... spots) + FishingSpot(String spot, int itemSpriteId, int... spots) { this.name = spot; - this.image = image; + this.itemSpriteId = itemSpriteId; this.spots = spots; } @@ -119,9 +121,9 @@ public enum FishingSpot return name; } - public String getImage() + public int getItemSpriteId() { - return image; + return itemSpriteId; } public int[] getIds() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java index 26f5c724df..8f2cc6503c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java @@ -28,15 +28,12 @@ import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; -import javax.imageio.ImageIO; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.NPC; +import net.runelite.api.SpritePixels; import net.runelite.api.queries.NPCQuery; import net.runelite.client.RuneLite; import net.runelite.client.ui.overlay.Overlay; @@ -49,8 +46,6 @@ class FishingSpotOverlay extends Overlay { private static final Logger logger = LoggerFactory.getLogger(FishingSpotOverlay.class); - private final BufferedImage[] imgCache = new BufferedImage[FishingSpot.values().length]; - private final List ids = new ArrayList<>(); private final RuneLite runelite = RuneLite.getRunelite(); @@ -86,10 +81,10 @@ class FishingSpotOverlay extends Overlay Color color = npc.getId() == FishingSpot.FLYING_FISH ? Color.RED : Color.CYAN; if (config.showIcons()) { - BufferedImage fishImage = getFishImage(spot); - if (fishImage != null) + SpritePixels fishSprite = getFishSprite(spot); + if (fishSprite != null) { - OverlayUtil.renderActorOverlayImage(graphics, npc, fishImage, color.darker()); + OverlayUtil.renderActorOverlaySprite(graphics, npc, fishSprite, color.darker()); } } else @@ -102,28 +97,9 @@ class FishingSpotOverlay extends Overlay return null; } - private BufferedImage getFishImage(FishingSpot spot) + private SpritePixels getFishSprite(FishingSpot spot) { - int fishIdx = spot.ordinal(); - BufferedImage fishImage = null; - - if (imgCache[fishIdx] != null) - { - return imgCache[fishIdx]; - } - - try - { - InputStream in = FishingSpotOverlay.class.getResourceAsStream(spot.getImage() + ".png"); - fishImage = ImageIO.read(in); - imgCache[fishIdx] = fishImage; - } - catch (IOException e) - { - logger.warn("Error Loading fish icon", e); - } - - return fishImage; + return client.createItemSprite(spot.getItemSpriteId(), 5, 1, SpritePixels.DEFAULT_SHADOW_COLOR, 0, false); } public void updateConfig() diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java index f9ca92fa6e..95c3d06c5e 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java @@ -32,6 +32,7 @@ import java.awt.image.BufferedImage; import net.runelite.api.Actor; import net.runelite.api.Point; +import net.runelite.api.SpritePixels; import net.runelite.api.TileObject; @@ -78,6 +79,14 @@ public class OverlayUtil graphics.drawImage(image, x, y, null); } + public static void renderSpriteLocation(Graphics2D graphics, Point imgLoc, SpritePixels sprite) + { + int x = imgLoc.getX(); + int y = imgLoc.getY(); + + sprite.drawAt(x, y); + } + public static void renderActorOverlay(Graphics2D graphics, Actor actor, String text, Color color) { Polygon poly = actor.getCanvasTilePoly(); @@ -120,6 +129,27 @@ public class OverlayUtil } } + public static void renderActorOverlaySprite(Graphics2D graphics, Actor actor, SpritePixels sprite, Color color) + { + Polygon poly = actor.getCanvasTilePoly(); + if (poly != null) + { + renderPolygon(graphics, poly, color); + } + + Point minimapLocation = actor.getMinimapLocation(); + if (minimapLocation != null) + { + renderMinimapLocation(graphics, minimapLocation, color); + } + + Point imageLocation = actor.getCanvasSpriteLocation(graphics, sprite, actor.getModelHeight()); + if (imageLocation != null) + { + renderSpriteLocation(graphics, imageLocation, sprite); + } + } + public static void renderTileOverlay(Graphics2D graphics, TileObject tileObject, String text, Color color) { Polygon poly = tileObject.getCanvasTilePoly(); diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/anglerfish.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/anglerfish.png deleted file mode 100644 index dfa4666ebf..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/anglerfish.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/barb.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/barb.png deleted file mode 100644 index 1fb97cde71..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/barb.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/lobster.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/lobster.png deleted file mode 100644 index 8c76b053c0..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/lobster.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/minnow.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/minnow.png deleted file mode 100644 index 7829433de1..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/minnow.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/monkfish.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/monkfish.png deleted file mode 100644 index 0b0f0faf28..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/monkfish.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/salmon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/salmon.png deleted file mode 100644 index d59b4494c7..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/salmon.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/shark.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/shark.png deleted file mode 100644 index 2624fb4e45..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/shark.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/shrimp.png b/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/shrimp.png deleted file mode 100644 index 54cf89512b..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/fishing/shrimp.png and /dev/null differ diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java index 60ce77b5a8..364bd14941 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java @@ -32,6 +32,7 @@ import net.runelite.api.NPC; import net.runelite.api.Perspective; import net.runelite.api.Player; import net.runelite.api.Point; +import net.runelite.api.SpritePixels; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Shadow; @@ -143,6 +144,13 @@ public abstract class RSActorMixin implements RSActor return Perspective.getCanvasImageLocation(client, graphics, getLocalLocation(), image, zOffset); } + @Inject + @Override + public Point getCanvasSpriteLocation(Graphics2D graphics, SpritePixels sprite, int zOffset) + { + return Perspective.getCanvasSpriteLocation(client, graphics, getLocalLocation(), sprite, zOffset); + } + @Inject @Override public Point getMinimapLocation() 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 ba739f0c91..dc69eafa18 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 @@ -230,6 +230,10 @@ public interface RSClient extends RSGameEngine, Client @Override RSItemComposition getItemDefinition(int itemId); + @Import("createSprite") + @Override + RSSpritePixels createItemSprite(int itemId, int quantity, int thickness, int borderColor, int stackable, boolean noted); + @Import("componentTable") @Override RSHashTable getComponentTable(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java b/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java index 46de44150e..f59d6a34f4 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java @@ -24,6 +24,20 @@ */ package net.runelite.rs.api; -public interface RSSpritePixels +import net.runelite.api.SpritePixels; +import net.runelite.mapping.Import; + +public interface RSSpritePixels extends SpritePixels { + @Import("drawAt") + @Override + void drawAt(int x, int y); + + @Import("height") + @Override + int getHeight(); + + @Import("width") + @Override + int getWidth(); }