runelite-client: Handle missing sprites correctly
This commit is contained in:
@@ -360,6 +360,7 @@ public interface Client extends GameEngine
|
||||
* @param scale the scale of the sprite
|
||||
* @return the created sprite
|
||||
*/
|
||||
@Nullable
|
||||
SpritePixels createItemSprite(int itemId, int quantity, int border, int shadowColor, int stackable, boolean noted, int scale);
|
||||
|
||||
/**
|
||||
@@ -370,6 +371,7 @@ public interface Client extends GameEngine
|
||||
* @param fileId the sprites file ID
|
||||
* @return the sprite image of the file
|
||||
*/
|
||||
@Nullable
|
||||
SpritePixels[] getSprites(IndexDataBase source, int archiveId, int fileId);
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,8 @@ 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.ui.overlay.infobox.InfoBox;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Slf4j
|
||||
@@ -54,6 +56,9 @@ public class SpriteManager
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
public Cache<Long, BufferedImage> cache = CacheBuilder.newBuilder()
|
||||
.maximumSize(128L)
|
||||
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||
@@ -76,6 +81,11 @@ public class SpriteManager
|
||||
}
|
||||
|
||||
SpritePixels[] sp = client.getSprites(client.getIndexSprites(), archive, 0);
|
||||
if (sp == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferedImage img = sp[file].toBufferedImage();
|
||||
|
||||
cache.put(key, img);
|
||||
@@ -104,6 +114,15 @@ public class SpriteManager
|
||||
});
|
||||
}
|
||||
|
||||
public void getSpriteAsync(int archive, int file, InfoBox infoBox)
|
||||
{
|
||||
getSpriteAsync(archive, file, img ->
|
||||
{
|
||||
infoBox.setImage(img);
|
||||
infoBoxManager.updateInfoBoxImage(infoBox);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls setIcon on c, ensuring it is repainted when this changes
|
||||
*/
|
||||
|
||||
@@ -322,10 +322,12 @@ public class BarrowsPlugin extends Plugin
|
||||
final LoopTimer loopTimer = new LoopTimer(
|
||||
PRAYER_DRAIN_INTERVAL_MS,
|
||||
ChronoUnit.MILLIS,
|
||||
spriteManager.getSprite(SpriteID.TAB_PRAYER, 0),
|
||||
null,
|
||||
this,
|
||||
true);
|
||||
|
||||
spriteManager.getSpriteAsync(SpriteID.TAB_PRAYER, 0, loopTimer);
|
||||
|
||||
loopTimer.setPriority(InfoBoxPriority.MED);
|
||||
loopTimer.setTooltip("Prayer Drain");
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
@@ -87,8 +88,10 @@ class InstanceMapOverlay extends Overlay
|
||||
|
||||
@Setter
|
||||
private boolean isCloseButtonHovered;
|
||||
|
||||
@Getter
|
||||
private Rectangle closeButtonBounds;
|
||||
|
||||
private BufferedImage closeButtonImage;
|
||||
private BufferedImage closeButtonHoveredImage;
|
||||
|
||||
@@ -166,8 +169,6 @@ class InstanceMapOverlay extends Overlay
|
||||
|
||||
if (image == null)
|
||||
{
|
||||
BufferedImage closeButton = getCloseButtonImage();
|
||||
|
||||
SpritePixels map = client.drawInstanceMap(viewedPlane);
|
||||
image = minimapToBufferedImage(map);
|
||||
synchronized (this)
|
||||
@@ -177,7 +178,12 @@ class InstanceMapOverlay extends Overlay
|
||||
mapImage = image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferedImage closeButton = getCloseButtonImage();
|
||||
BufferedImage closeButtonHover = getCloseButtonHoveredImage();
|
||||
if (closeButton != null && closeButtonBounds == null)
|
||||
{
|
||||
closeButtonBounds = new Rectangle(image.getWidth() - closeButton.getWidth() - 5, 6,
|
||||
closeButton.getWidth(), closeButton.getHeight());
|
||||
}
|
||||
@@ -191,8 +197,15 @@ class InstanceMapOverlay extends Overlay
|
||||
drawPlayerDot(graphics, client.getLocalPlayer(), Color.white, Color.black);
|
||||
}
|
||||
|
||||
graphics.drawImage(isCloseButtonHovered ? getCloseButtonHoveredImage() : getCloseButtonImage(),
|
||||
(int) closeButtonBounds.getX(), (int) closeButtonBounds.getY(), null);
|
||||
if (isCloseButtonHovered)
|
||||
{
|
||||
closeButton = closeButtonHover;
|
||||
}
|
||||
|
||||
if (closeButton != null)
|
||||
{
|
||||
graphics.drawImage(closeButton, (int) closeButtonBounds.getX(), (int) closeButtonBounds.getY(), null);
|
||||
}
|
||||
|
||||
return new Dimension(image.getWidth(), image.getHeight());
|
||||
}
|
||||
@@ -252,6 +265,7 @@ class InstanceMapOverlay extends Overlay
|
||||
return img;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BufferedImage getCloseButtonImage()
|
||||
{
|
||||
if (closeButtonImage == null)
|
||||
@@ -261,6 +275,7 @@ class InstanceMapOverlay extends Overlay
|
||||
return closeButtonImage;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BufferedImage getCloseButtonHoveredImage()
|
||||
{
|
||||
if (closeButtonHoveredImage == null)
|
||||
|
||||
@@ -299,6 +299,11 @@ public class PuzzleSolverOverlay extends Overlay
|
||||
arrow = getUpArrow();
|
||||
}
|
||||
|
||||
if (arrow == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int x = puzzleBoxLocation.getX() + blankX * PUZZLE_TILE_SIZE
|
||||
+ PUZZLE_TILE_SIZE / 2 - arrow.getWidth() / 2;
|
||||
|
||||
|
||||
@@ -193,7 +193,8 @@ public class RaidsPlugin extends Plugin
|
||||
|
||||
if (config.raidsTimer() && message.startsWith(RAID_START_MESSAGE))
|
||||
{
|
||||
timer = new RaidsTimer(spriteManager.getSprite(TAB_QUESTS_BROWN_RAIDING_PARTY, 0), this, Instant.now());
|
||||
timer = new RaidsTimer(this, Instant.now());
|
||||
spriteManager.getSpriteAsync(TAB_QUESTS_BROWN_RAIDING_PARTY, 0, timer);
|
||||
infoBoxManager.addInfoBox(timer);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
package net.runelite.client.plugins.raids;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalTime;
|
||||
@@ -47,9 +46,9 @@ public class RaidsTimer extends InfoBox
|
||||
@Setter
|
||||
private boolean stopped;
|
||||
|
||||
public RaidsTimer(BufferedImage image, Plugin plugin, Instant startTime)
|
||||
public RaidsTimer(Plugin plugin, Instant startTime)
|
||||
{
|
||||
super(image, plugin);
|
||||
super(null, plugin);
|
||||
this.startTime = startTime;
|
||||
floorTime = startTime;
|
||||
stopped = false;
|
||||
|
||||
@@ -64,7 +64,6 @@ import net.runelite.api.Point;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.LocalPlayerDeath;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
@@ -235,6 +234,8 @@ public class ScreenshotPlugin extends Plugin
|
||||
.build();
|
||||
|
||||
clientToolbar.addNavigation(titleBarButton);
|
||||
|
||||
spriteManager.getSpriteAsync(SpriteID.CHATBOX_REPORT_BUTTON, 0, s -> reportButton = s);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,16 +246,6 @@ public class ScreenshotPlugin extends Plugin
|
||||
keyManager.unregisterKeyListener(hotkeyListener);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGGED_IN
|
||||
&& reportButton == null)
|
||||
{
|
||||
reportButton = spriteManager.getSprite(SpriteID.CHATBOX_REPORT_BUTTON, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
|
||||
@@ -25,22 +25,17 @@
|
||||
package net.runelite.client.plugins.timers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
enum GameIndicator
|
||||
{
|
||||
VENGEANCE_ACTIVE(SpriteID.SPELL_VENGEANCE_OTHER, GameTimerImageType.SPRITE, "Vengeance active");
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final String description;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private String text;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color textColor;
|
||||
private final int imageId;
|
||||
private final GameTimerImageType imageType;
|
||||
@@ -58,17 +53,4 @@ enum GameIndicator
|
||||
{
|
||||
this(imageId, idType, description, "", null);
|
||||
}
|
||||
|
||||
BufferedImage getImage(ItemManager itemManager, SpriteManager spriteManager)
|
||||
{
|
||||
switch (imageType)
|
||||
{
|
||||
case ITEM:
|
||||
return itemManager.getImage(imageId);
|
||||
case SPRITE:
|
||||
return spriteManager.getSprite(imageId, 0);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,16 +26,15 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.timers;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.GraphicID;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
enum GameTimer
|
||||
{
|
||||
STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", 2, ChronoUnit.MINUTES, true),
|
||||
@@ -81,15 +80,10 @@ enum GameTimer
|
||||
MINIGAME_TELEPORT(SpriteID.TAB_QUESTS_RED_MINIGAMES, GameTimerImageType.SPRITE, "Minigame Teleport", 20, ChronoUnit.MINUTES),
|
||||
DRAGON_FIRE_SHIELD(ItemID.DRAGONFIRE_SHIELD_11284, GameTimerImageType.ITEM, "Dragonfire Shield Special", 2, ChronoUnit.MINUTES);
|
||||
|
||||
@Getter
|
||||
private final Duration duration;
|
||||
@Getter
|
||||
private final Integer graphicId;
|
||||
@Getter
|
||||
private final String description;
|
||||
@Getter
|
||||
private final boolean removedOnDeath;
|
||||
@Getter
|
||||
private final Duration initialDelay;
|
||||
private final int imageId;
|
||||
private final GameTimerImageType imageType;
|
||||
@@ -129,17 +123,4 @@ enum GameTimer
|
||||
{
|
||||
this(imageId, idType, description, null, time, unit, delay, false);
|
||||
}
|
||||
|
||||
BufferedImage getImage(ItemManager itemManager, SpriteManager spriteManager)
|
||||
{
|
||||
switch (imageType)
|
||||
{
|
||||
case ITEM:
|
||||
return itemManager.getImage(imageId);
|
||||
case SPRITE:
|
||||
return spriteManager.getSprite(imageId, 0);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
package net.runelite.client.plugins.timers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Image;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
@@ -36,9 +35,9 @@ public class IndicatorIndicator extends InfoBox
|
||||
@Getter
|
||||
private final GameIndicator indicator;
|
||||
|
||||
IndicatorIndicator(GameIndicator indicator, Image image, Plugin plugin)
|
||||
IndicatorIndicator(GameIndicator indicator, Plugin plugin)
|
||||
{
|
||||
super(image, plugin);
|
||||
super(null, plugin);
|
||||
this.indicator = indicator;
|
||||
setPriority(InfoBoxPriority.MED);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.timers;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
@@ -36,9 +35,9 @@ class TimerTimer extends Timer
|
||||
{
|
||||
private final GameTimer timer;
|
||||
|
||||
TimerTimer(GameTimer timer, Plugin plugin, BufferedImage image)
|
||||
TimerTimer(GameTimer timer, Plugin plugin)
|
||||
{
|
||||
super(timer.getDuration().toMillis(), ChronoUnit.MILLIS, image, plugin);
|
||||
super(timer.getDuration().toMillis(), ChronoUnit.MILLIS, null, plugin);
|
||||
this.timer = timer;
|
||||
setPriority(InfoBoxPriority.MED);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
package net.runelite.client.plugins.timers;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -866,8 +865,16 @@ public class TimersPlugin extends Plugin
|
||||
{
|
||||
removeGameTimer(timer);
|
||||
|
||||
BufferedImage image = timer.getImage(itemManager, spriteManager);
|
||||
TimerTimer t = new TimerTimer(timer, this, image);
|
||||
TimerTimer t = new TimerTimer(timer, this);
|
||||
switch (timer.getImageType())
|
||||
{
|
||||
case SPRITE:
|
||||
spriteManager.getSpriteAsync(timer.getImageId(), 0, t);
|
||||
break;
|
||||
case ITEM:
|
||||
t.setImage(itemManager.getImage(timer.getImageId()));
|
||||
break;
|
||||
}
|
||||
t.setTooltip(timer.getDescription());
|
||||
infoBoxManager.addInfoBox(t);
|
||||
return t;
|
||||
@@ -882,8 +889,16 @@ public class TimersPlugin extends Plugin
|
||||
{
|
||||
removeGameIndicator(gameIndicator);
|
||||
|
||||
BufferedImage image = gameIndicator.getImage(itemManager, spriteManager);
|
||||
IndicatorIndicator indicator = new IndicatorIndicator(gameIndicator, image, this);
|
||||
IndicatorIndicator indicator = new IndicatorIndicator(gameIndicator, this);
|
||||
switch (gameIndicator.getImageType())
|
||||
{
|
||||
case SPRITE:
|
||||
spriteManager.getSpriteAsync(gameIndicator.getImageId(), 0, indicator);
|
||||
break;
|
||||
case ITEM:
|
||||
indicator.setImage(itemManager.getImage(gameIndicator.getImageId()));
|
||||
break;
|
||||
}
|
||||
indicator.setTooltip(gameIndicator.getDescription());
|
||||
infoBoxManager.addInfoBox(indicator);
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ public class InfoBoxManager
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInfoBoxImage(final InfoBox infoBox)
|
||||
public void updateInfoBoxImage(final InfoBox infoBox)
|
||||
{
|
||||
if (infoBox.getImage() == null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user