diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 5c33240e16..0f1fb47b6a 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -53,6 +53,7 @@ import net.runelite.client.plugins.PluginManager; import net.runelite.client.task.Scheduler; import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.overlay.OverlayRenderer; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.http.api.account.AccountClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,6 +85,7 @@ public class RuneLite private AccountSession accountSession; private final ConfigManager configManager = new ConfigManager(eventBus); private final ItemManager itemManager = new ItemManager(this); + private final InfoBoxManager infoBoxManager = new InfoBoxManager(); static { @@ -365,4 +367,9 @@ public class RuneLite { return itemManager; } + + public InfoBoxManager getInfoBoxManager() + { + return infoBoxManager; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index af1e347a4c..41182b6637 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -34,6 +34,7 @@ import net.runelite.client.events.*; import net.runelite.client.game.DeathChecker; import net.runelite.client.task.Scheduler; import net.runelite.client.ui.overlay.OverlayRenderer; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.rs.api.MainBufferProvider; import net.runelite.rs.api.MessageNode; import org.slf4j.Logger; @@ -70,8 +71,13 @@ public class Hooks logger.warn("error during death check", ex); } + // tick pending scheduled tasks Scheduler scheduler = runelite.getScheduler(); scheduler.tick(); + + // cull infoboxes + InfoBoxManager infoBoxManager = runelite.getInfoBoxManager(); + infoBoxManager.cull(); } public static void draw(Object provider, Graphics graphics, int x, int y) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java index 60d940fe0c..2dcfdab658 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java @@ -25,7 +25,6 @@ package net.runelite.client.plugins; import com.google.common.util.concurrent.AbstractIdleService; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.concurrent.Executor; @@ -41,7 +40,7 @@ public abstract class Plugin extends AbstractIdleService public Collection getOverlays() { Overlay overlay = getOverlay(); - return overlay != null ? Arrays.asList(overlay) : Collections.EMPTY_LIST; + return overlay != null ? Collections.singletonList(overlay) : Collections.EMPTY_LIST; } /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index f19d362641..9d0440aac9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -55,6 +55,7 @@ import net.runelite.client.plugins.pestcontrol.PestControl; import net.runelite.client.plugins.pricecommands.PriceCommands; import net.runelite.client.plugins.rememberusername.RememberUsername; import net.runelite.client.plugins.runecraft.Runecraft; +import net.runelite.client.plugins.timers.Timers; import net.runelite.client.plugins.woodcutting.WoodcuttingPlugin; import net.runelite.client.plugins.xpglobes.XpGlobes; import net.runelite.client.plugins.xptracker.XPTracker; @@ -106,6 +107,7 @@ public class PluginManager plugins.add(new RememberUsername()); plugins.add(new PriceCommands()); plugins.add(new ClueScrollPlugin()); + plugins.add(new Timers()); if (RuneLite.getOptions().has("developer-mode")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java new file mode 100644 index 0000000000..431b934df0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, Seth + * Copyright (c) 2017, Adam + * 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.timers; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import javax.imageio.ImageIO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public enum GameTimer +{ + STAMINA("stamina", 2, ChronoUnit.MINUTES), + ANTIFIRE("antifire", 6, ChronoUnit.MINUTES), + EXANTIFIRE("exantifire", 12, ChronoUnit.MINUTES), + OVERLOAD("overload", 5, ChronoUnit.MINUTES), + CANNON("cannon", 25, ChronoUnit.MINUTES), + MAGICIMBUE("magicimbue", 15, ChronoUnit.SECONDS), + FULLTB("teleblock", 5, ChronoUnit.MINUTES), + HALFTB("teleblock", 150, ChronoUnit.SECONDS), + SUPERANTIVENOM("antivenom", 3, ChronoUnit.MINUTES); + + private static final Logger logger = LoggerFactory.getLogger(GameTimer.class); + + private final String imageResource; + private final Duration duration; + + private BufferedImage image; + + GameTimer(String imageResource, long time, ChronoUnit unit) + { + this.imageResource = imageResource; + this.duration = Duration.of(time, unit); + } + + public String getImageResource() + { + return imageResource; + } + + public Duration getDuration() + { + return duration; + } + + public BufferedImage getImage() + { + if (image != null) + { + return image; + } + + InputStream in = GameTimer.class.getResourceAsStream(imageResource + ".png"); + try + { + image = ImageIO.read(in); + } + catch (IOException ex) + { + logger.warn("unable to load image", ex); + } + + return image; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java new file mode 100644 index 0000000000..4b7e77a693 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017, Adam + * 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.timers; + +import java.time.temporal.ChronoUnit; +import net.runelite.client.ui.overlay.infobox.Timer; + +public class TimerTimer extends Timer +{ + private final GameTimer timer; + + public TimerTimer(GameTimer timer) + { + super(timer.getDuration().toMillis(), ChronoUnit.MILLIS, timer.getImage()); + this.timer = timer; + } + + public GameTimer getTimer() + { + return timer; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/Timers.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/Timers.java new file mode 100644 index 0000000000..e61c10fa53 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/Timers.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2017, Seth + * 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.timers; + +import com.google.common.eventbus.Subscribe; +import net.runelite.api.ChatMessageType; +import net.runelite.client.RuneLite; +import net.runelite.client.events.ChatMessage; +import net.runelite.client.events.ConfigChanged; +import net.runelite.client.plugins.Plugin; +import static net.runelite.client.plugins.timers.GameTimer.*; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; + +public class Timers extends Plugin +{ + private final TimersConfig config = RuneLite.getRunelite().getConfigManager().getConfig(TimersConfig.class); + + private final InfoBoxManager infoBoxManager = RuneLite.getRunelite().getInfoBoxManager(); + + @Override + protected void startUp() throws Exception + { + } + + @Override + protected void shutDown() throws Exception + { + } + + public TimersConfig getConfig() + { + return config; + } + + @Subscribe + public void updateConfig(ConfigChanged event) + { + if (!config.showStamina()) + { + removeGameTimer(STAMINA); + } + + if (!config.showAntiFire()) + { + removeGameTimer(ANTIFIRE); + } + + if (!config.showExAntiFire()) + { + removeGameTimer(EXANTIFIRE); + } + + if (!config.showOverload()) + { + removeGameTimer(OVERLOAD); + } + + if (!config.showCannon()) + { + removeGameTimer(CANNON); + } + + if (!config.showMagicImbue()) + { + removeGameTimer(MAGICIMBUE); + } + + if (!config.showAntiVenom()) + { + removeGameTimer(SUPERANTIVENOM); + } + if (!config.showTeleblock()) + { + removeGameTimer(FULLTB); + removeGameTimer(HALFTB); + } + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (event.getType() != ChatMessageType.FILTERED && event.getType() != ChatMessageType.SERVER) + { + return; + } + + if (event.getMessage().equals("You drink some of your stamina potion.") && config.showStamina()) + { + createGameTimer(STAMINA); + } + + if (event.getMessage().equals("Your stamina potion has expired.")) + { + removeGameTimer(STAMINA); + } + + if (event.getMessage().equals("You drink some of your antifire potion.") && config.showAntiFire()) + { + createGameTimer(ANTIFIRE); + } + + if (event.getMessage().equals("You drink some of your extended antifire potion.") && config.showExAntiFire()) + { + createGameTimer(EXANTIFIRE); + } + + if (event.getMessage().equals("Your antifire potion has expired.")) + { + //they have the same expired message + removeGameTimer(ANTIFIRE); + removeGameTimer(EXANTIFIRE); + } + + if (event.getMessage().contains("You drink some of your overload potion") && config.showOverload()) + { + createGameTimer(OVERLOAD); + } + + if ((event.getMessage().equals("You add the furnace.") || event.getMessage().contains("You repair your cannon, restoring it to working order.")) && config.showCannon()) + { + createGameTimer(CANNON); + } + + if (event.getMessage().equals("You pick up the cannon. It's really heavy.")) + { + removeGameTimer(CANNON); + } + + if (event.getMessage().contains("You drink some of your super antivenom potion") && config.showAntiVenom()) + { + createGameTimer(SUPERANTIVENOM); + } + + if (event.getMessage().equals("You are charged to combine runes!") && config.showMagicImbue()) + { + createGameTimer(MAGICIMBUE); + } + + if (event.getMessage().equals("Your Magic Imbue charge has ended.")) + { + removeGameTimer(MAGICIMBUE); + } + + if (event.getMessage().equals("A teleblock spell has been cast on you. It will expire in 5 minutes, 0 seconds.") && config.showTeleblock()) + { + createGameTimer(FULLTB); + } + + if (event.getMessage().equals("A teleblock spell has been cast on you. It will expire in 2 minutes, 30 seconds.") && config.showTeleblock()) + { + createGameTimer(HALFTB); + } + } + + public void createGameTimer(GameTimer timer) + { + removeGameTimer(timer); + + TimerTimer t = new TimerTimer(timer); + infoBoxManager.addInfoBox(t); + } + + public void removeGameTimer(GameTimer timer) + { + infoBoxManager.removeIf(t -> t instanceof TimerTimer && ((TimerTimer) t).getTimer() == timer); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java new file mode 100644 index 0000000000..d31ecbd5b8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2017, Seth + * 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.timers; + +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup( + keyName = "timers", + name = "Timers", + description = "Configuration for the timers plugin" +) +public interface TimersConfig +{ + @ConfigItem( + keyName = "enabled", + name = "Enable", + description = "Configures whether the timer plugin is displayed" + ) + default boolean enabled() + { + return true; + } + + @ConfigItem( + keyName = "showStamina", + name = "Stamina timer", + description = "Configures whether stamina timer is displayed" + ) + default boolean showStamina() + { + return true; + } + + @ConfigItem( + keyName = "showAntiFire", + name = "AntiFire timer", + description = "Configures whether antifire timer is displayed" + ) + default boolean showAntiFire() + { + return true; + } + + @ConfigItem( + keyName = "showExAntiFire", + name = "Extended Antifire timer", + description = "Configures whether extended antifire timer is displayed" + ) + default boolean showExAntiFire() + { + return true; + } + + @ConfigItem( + keyName = "showOverload", + name = "Overload timer", + description = "Configures whether overload timer is displayed" + ) + default boolean showOverload() + { + return true; + } + + @ConfigItem( + keyName = "showCannon", + name = "Cannon timer", + description = "Configures whether cannon timer is displayed" + ) + default boolean showCannon() + { + return true; + } + + @ConfigItem( + keyName = "showMagicImbue", + name = "Magic Imbue timer", + description = "Configures whether magic imbue timer is displayed" + ) + default boolean showMagicImbue() + { + return true; + } + + @ConfigItem( + keyName = "showTeleblock", + name = "Teleblock timer", + description = "Configures whether teleblock timer is displayed" + ) + default boolean showTeleblock() + { + return true; + } + + @ConfigItem( + keyName = "showAntiVenom", + name = "Anti Venom+ timer", + description = "Configures whether anti venom+ timer is displayed" + ) + default boolean showAntiVenom() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index 7e8e6b7d74..f5bdbce3a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -25,12 +25,14 @@ package net.runelite.client.ui.overlay; import java.awt.image.BufferedImage; - import net.runelite.client.RuneLite; import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay; public class OverlayRenderer { + private final InfoBoxOverlay infoBoxOverlay = new InfoBoxOverlay(); + public void render(BufferedImage clientBuffer) { TopDownRendererLeft tdl = new TopDownRendererLeft(); @@ -56,6 +58,8 @@ public class OverlayRenderer } } + tdl.add(infoBoxOverlay); + tdl.render(clientBuffer); tdr.render(clientBuffer); dr.render(clientBuffer); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Counter.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Counter.java new file mode 100644 index 0000000000..be9e026105 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Counter.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, Adam + * 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.ui.overlay.infobox; + +import java.awt.Color; +import java.awt.image.BufferedImage; + +public class Counter extends InfoBox +{ + private String text; + + public Counter(BufferedImage image, String text) + { + super(image); + this.text = text; + } + + @Override + public String toString() + { + return "Counter{" + "text=" + text + '}'; + } + + @Override + public String getText() + { + return text; + } + + public void setText(String text) + { + this.text = text; + } + + @Override + public Color getTextColor() + { + return Color.WHITE; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java new file mode 100644 index 0000000000..347bd5d5fb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017, Adam + * 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.ui.overlay.infobox; + +import java.awt.Color; +import java.awt.image.BufferedImage; + +public abstract class InfoBox +{ + private final BufferedImage image; + + public InfoBox(BufferedImage image) + { + this.image = image; + } + + public BufferedImage getImage() + { + return image; + } + + public abstract String getText(); + + public abstract Color getTextColor(); + + public boolean render() + { + return true; + } + + public boolean cull() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java new file mode 100644 index 0000000000..ef841c383c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017, Adam + * 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.ui.overlay.infobox; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class InfoBoxManager +{ + private static final Logger logger = LoggerFactory.getLogger(InfoBoxManager.class); + + private final List infoBoxes = new ArrayList<>(); + + public void addInfoBox(InfoBox infoBox) + { + logger.debug("Adding InfoBox {}", infoBox); + infoBoxes.add(infoBox); + } + + public void removeInfoBox(InfoBox infoBox) + { + logger.debug("Removing InfoBox {}", infoBox); + infoBoxes.remove(infoBox); + } + + public void removeIf(Predicate filter) + { + logger.debug("Removing InfoBoxs for filter {}", filter); + infoBoxes.removeIf(filter); + } + + public List getInfoBoxes() + { + return Collections.unmodifiableList(infoBoxes); + } + + public void cull() + { + for (Iterator it = infoBoxes.iterator(); it.hasNext();) + { + InfoBox box = it.next(); + + if (box.cull()) + { + logger.debug("Culling InfoBox {}", box); + it.remove(); + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java new file mode 100644 index 0000000000..abbdcf9e46 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, Seth + * Copyright (c) 2017, Adam + * 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.ui.overlay.infobox; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.util.List; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.client.RuneLite; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; + +public class InfoBoxOverlay extends Overlay +{ + private static final int BOXSIZE = 35; + private static final int SEPARATOR = 2; + private static final Color BACKGROUND = new Color(Color.gray.getRed(), Color.gray.getGreen(), Color.gray.getBlue(), 127); + + private final RuneLite runelite = RuneLite.getRunelite(); + private final Client client = RuneLite.getClient(); + + public InfoBoxOverlay() + { + super(OverlayPosition.TOP_LEFT, OverlayPriority.LOW); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return null; + } + + List infoBoxes = runelite.getInfoBoxManager().getInfoBoxes(); + + if (infoBoxes.isEmpty()) + { + return null; + } + + FontMetrics metrics = graphics.getFontMetrics(); + + int width = infoBoxes.size() * BOXSIZE; + int x = 0; + + for (InfoBox box : infoBoxes) + { + if (!box.render()) + { + continue; + } + + graphics.setColor(BACKGROUND); + graphics.fillRect(x, 0, BOXSIZE, BOXSIZE); + + graphics.setColor(Color.darkGray); + graphics.drawRect(x, 0, BOXSIZE, BOXSIZE); + + String str = box.getText(); + Color color = box.getTextColor(); + + BufferedImage image = box.getImage(); + if (image != null) + { + graphics.drawImage(image, x + (BOXSIZE - image.getWidth()) / 2, SEPARATOR, null); + } + + // text shaddow + graphics.setColor(Color.black); + graphics.drawString(str, x + ((BOXSIZE - metrics.stringWidth(str)) / 2) + 1, BOXSIZE - SEPARATOR + 1); + + graphics.setColor(color); + graphics.drawString(str, x + ((BOXSIZE - metrics.stringWidth(str)) / 2), BOXSIZE - SEPARATOR); + + x += BOXSIZE + SEPARATOR; + } + + return new Dimension(width, BOXSIZE); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Timer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Timer.java new file mode 100644 index 0000000000..197fd53597 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Timer.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017, Adam + * 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.ui.overlay.infobox; + +import com.google.common.base.Preconditions; +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +public class Timer extends InfoBox +{ + private final Instant startTime; + private final Instant endTime; + private final Duration duration; + + public Timer(long period, ChronoUnit unit, BufferedImage image) + { + super(image); + + Preconditions.checkArgument(period > 0, "negative period!"); + + startTime = Instant.now(); + duration = Duration.of(period, unit); + endTime = startTime.plus(duration); + } + + @Override + public String toString() + { + return "Timer{" + "startTime=" + startTime + ", endTime=" + endTime + ", duration=" + duration + '}'; + } + + @Override + public String getText() + { + Duration timeLeft = Duration.between(Instant.now(), endTime); + + int seconds = (int) (timeLeft.toMillis() / 1000L); + + int minutes = (seconds % 3600) / 60; + int secs = seconds % 60; + + return String.format("%d:%02d", minutes, secs); + } + + @Override + public Color getTextColor() + { + Duration timeLeft = Duration.between(Instant.now(), endTime); + + //check if timer has 10% of time left + if (timeLeft.getSeconds() < (duration.getSeconds() * .10)) + { + return Color.RED.brighter(); + } + + return Color.WHITE; + } + + @Override + public boolean render() + { + Duration timeLeft = Duration.between(Instant.now(), endTime); + return !timeLeft.isNegative(); + } + + @Override + public boolean cull() + { + Duration timeLeft = Duration.between(Instant.now(), endTime); + return timeLeft.isZero() || timeLeft.isNegative(); + } + +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/antifire.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/antifire.png new file mode 100644 index 0000000000..cc1d3d2548 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/antifire.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/antivenom.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/antivenom.png new file mode 100644 index 0000000000..ded709eb2a Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/antivenom.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/cannon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/cannon.png new file mode 100644 index 0000000000..b00bdc143b Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/cannon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/exantifire.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/exantifire.png new file mode 100644 index 0000000000..b6007c0d41 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/exantifire.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/magicimbue.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/magicimbue.png new file mode 100644 index 0000000000..e79369b21b Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/magicimbue.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/overload.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/overload.png new file mode 100644 index 0000000000..7f13b3ad02 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/overload.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/stamina.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/stamina.png new file mode 100644 index 0000000000..77aadd9784 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/stamina.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timers/teleblock.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/teleblock.png new file mode 100644 index 0000000000..6b1cfe5258 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timers/teleblock.png differ