From 90b00b234fce06c2622f101209799992c54b3773 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Mon, 26 Nov 2018 01:20:14 -0700 Subject: [PATCH] runelite-client: centralize sprite overrides --- .../runelite/client/game/SpriteManager.java | 36 ++++++++++++++++ .../runelite/client/game/SpriteOverride.java | 42 +++++++++++++++++++ .../plugins/banktags/BankTagsPlugin.java | 12 +++--- .../plugins/banktags/tabs/TabSprites.java | 33 +++------------ .../net/runelite/client/util/ImageUtil.java | 16 ++++++- 5 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/game/SpriteOverride.java diff --git a/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java b/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java index f0df8286cd..f177377818 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java @@ -28,6 +28,7 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.inject.Inject; import java.awt.image.BufferedImage; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import javax.annotation.Nullable; @@ -36,11 +37,14 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.SwingUtilities; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.SpritePixels; import net.runelite.client.callback.ClientThread; +import net.runelite.client.util.ImageUtil; +@Slf4j @Singleton public class SpriteManager { @@ -127,4 +131,36 @@ public class SpriteManager }); }); } + + public void addSpriteOverrides(SpriteOverride[] add) + { + if (add.length <= 0) + { + return; + } + + clientThread.invokeLater(() -> + { + Map overrides = client.getSpriteOverrides(); + Class owner = add[0].getClass(); + for (SpriteOverride o : add) + { + BufferedImage image = ImageUtil.getResourceStreamFromClass(owner, o.getFileName()); + SpritePixels sp = ImageUtil.getImageSpritePixels(image, client); + overrides.put(o.getSpriteId(), sp); + } + }); + } + + public void removeSpriteOverrides(SpriteOverride[] remove) + { + clientThread.invokeLater(() -> + { + Map overrides = client.getSpriteOverrides(); + for (SpriteOverride o : remove) + { + overrides.remove(o.getSpriteId()); + } + }); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/game/SpriteOverride.java b/runelite-client/src/main/java/net/runelite/client/game/SpriteOverride.java new file mode 100644 index 0000000000..a4f894d5c0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/SpriteOverride.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Abex + * 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.game; + +import net.runelite.api.SpriteID; + +public interface SpriteOverride +{ + /** + * An ID for a sprite. Negative numbers are used by RuneLite specific sprites + * + * @see SpriteID + */ + int getSpriteId(); + + /** + * The file name for the resource to be loaded, relative to the implementing class + */ + String getFileName(); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 620cc586be..6a3a7f3416 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -60,6 +60,7 @@ import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; @@ -125,6 +126,9 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis @Inject private KeyManager keyManager; + @Inject + private SpriteManager spriteManager; + private boolean shiftPressed = false; @Provides @@ -139,7 +143,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis keyManager.registerKeyListener(this); mouseManager.registerMouseWheelListener(this); clientThread.invokeLater(tabInterface::init); - client.getSpriteOverrides().putAll(TabSprites.toMap(client)); + spriteManager.addSpriteOverrides(TabSprites.values()); } @Override @@ -148,11 +152,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis keyManager.unregisterKeyListener(this); mouseManager.unregisterMouseWheelListener(this); clientThread.invokeLater(tabInterface::destroy); - - for (TabSprites value : TabSprites.values()) - { - client.getSpriteOverrides().remove(value.getSpriteId()); - } + spriteManager.removeSpriteOverrides(TabSprites.values()); shiftPressed = false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java index e7706679b0..20f9d0dfb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java @@ -25,17 +25,12 @@ */ package net.runelite.client.plugins.banktags.tabs; -import java.awt.image.BufferedImage; -import java.util.HashMap; -import java.util.Map; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.SpritePixels; -import net.runelite.client.util.ImageUtil; +import lombok.RequiredArgsConstructor; +import net.runelite.client.game.SpriteOverride; -@Slf4j -public enum TabSprites +@RequiredArgsConstructor +public enum TabSprites implements SpriteOverride { INCINERATOR(-200, "incinerator.png"), TAB_BACKGROUND(-201, "tag-tab.png"), @@ -46,23 +41,7 @@ public enum TabSprites @Getter private final int spriteId; - private final BufferedImage image; - TabSprites(final int spriteId, final String imageName) - { - this.spriteId = spriteId; - this.image = ImageUtil.getResourceStreamFromClass(this.getClass(), imageName); - } - - public static Map toMap(Client client) - { - final Map map = new HashMap<>(); - - for (TabSprites value : values()) - { - map.put(value.spriteId, ImageUtil.getImageSpritePixels(value.image, client)); - } - - return map; - } + @Getter + private final String fileName; } diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java index 1fa63d815e..16a6b1c78a 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java @@ -30,6 +30,7 @@ import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; +import java.awt.image.DirectColorModel; import java.awt.image.PixelGrabber; import java.awt.image.RescaleOp; import java.io.IOException; @@ -426,8 +427,19 @@ public class ImageUtil try { - new PixelGrabber(image, 0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()) - .grabPixels(); + PixelGrabber g = new PixelGrabber(image, 0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); + g.setColorModel(new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000)); + g.grabPixels(); + + // Make any fully transparent pixels fully black, because the sprite draw routines + // check for == 0, not actual transparency + for (int i = 0; i < pixels.length; i++) + { + if ((pixels[i] & 0xFF000000) == 0) + { + pixels[i] = 0; + } + } } catch (InterruptedException ex) {