From 7d8d67f9f155405ad2229f1c1f69161838a1eda8 Mon Sep 17 00:00:00 2001 From: Unmoon Date: Fri, 2 Feb 2018 15:33:28 +0200 Subject: [PATCH] Add blast mine plugin --- .../main/java/net/runelite/api/Varbits.java | 9 + .../net/runelite/api/widgets/WidgetID.java | 1 + .../net/runelite/api/widgets/WidgetInfo.java | 4 +- .../blastmine/BlastMineOreCountOverlay.java | 92 ++++++++ .../plugins/blastmine/BlastMinePlugin.java | 127 +++++++++++ .../blastmine/BlastMinePluginConfig.java | 105 +++++++++ .../plugins/blastmine/BlastMineRock.java | 62 +++++ .../blastmine/BlastMineRockOverlay.java | 211 ++++++++++++++++++ .../plugins/blastmine/BlastMineRockType.java | 65 ++++++ 9 files changed, 675 insertions(+), 1 deletion(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePluginConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRock.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index 7fa6cf0bc1..a3657552de 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -236,6 +236,15 @@ public enum Varbits TITHE_FARM_SACK_AMOUNT(4900), TITHE_FARM_SACK_ICON(5370), TITHE_FARM_POINTS(4893), + + /** + * Blast Mine + */ + BLAST_MINE_COAL(4924), + BLAST_MINE_GOLD(4925), + BLAST_MINE_MITHRIL(4926), + BLAST_MINE_ADAMANTITE(4921), + BLAST_MINE_RUNITE(4922), /** * Raids diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index a15322a1a1..04fac9f777 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -94,6 +94,7 @@ public class WidgetID public static final int TITHE_FARM_GROUP_ID = 241; public static final int KINGDOM_GROUP_ID = 392; public static final int BARROWS_GROUP_ID = 24; + public static final int BLAST_MINE_GROUP_ID = 598; static class WorldMap { diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index b6d8cf5e77..62f03cb83c 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -321,7 +321,9 @@ public enum WidgetInfo BARROWS_INFO(WidgetID.BARROWS_GROUP_ID, 0), BARROWS_BROTHERS(WidgetID.BARROWS_GROUP_ID, WidgetID.Barrows.BARROWS_BROTHERS), BARROWS_POTENTIAL(WidgetID.BARROWS_GROUP_ID, WidgetID.Barrows.BARROWS_POTENTIAL), - BARROWS_REWARD_INVENTORY(WidgetID.BARROWS_REWARD_GROUP_ID, WidgetID.Barrows.BARROWS_REWARD_INVENTORY); + BARROWS_REWARD_INVENTORY(WidgetID.BARROWS_REWARD_GROUP_ID, WidgetID.Barrows.BARROWS_REWARD_INVENTORY), + + BLAST_MINE(WidgetID.BLAST_MINE_GROUP_ID, 0); private final int groupId; private final int childId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java new file mode 100644 index 0000000000..5256124334 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.blastmine; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.ItemID; +import net.runelite.api.Varbits; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +class BlastMineOreCountOverlay extends Overlay +{ + private final Client client; + private final BlastMinePluginConfig config; + private final ItemManager itemManager; + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + private BlastMineOreCountOverlay(Client client, BlastMinePluginConfig config, ItemManager itemManager) + { + setPosition(OverlayPosition.TOP_LEFT); + this.client = client; + this.config = config; + this.itemManager = itemManager; + panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + } + + @Override + public Dimension render(Graphics2D graphics) + { + final Widget blastMineWidget = client.getWidget(WidgetInfo.BLAST_MINE); + + if (blastMineWidget == null) + { + return null; + } + + panelComponent.getChildren().clear(); + + if (config.showOreOverlay()) + { + blastMineWidget.setHidden(true); + panelComponent.getChildren().add(new ImageComponent(getImage(ItemID.COAL, client.getVar(Varbits.BLAST_MINE_COAL)))); + panelComponent.getChildren().add(new ImageComponent(getImage(ItemID.GOLD_ORE, client.getVar(Varbits.BLAST_MINE_GOLD)))); + panelComponent.getChildren().add(new ImageComponent(getImage(ItemID.MITHRIL_ORE, client.getVar(Varbits.BLAST_MINE_MITHRIL)))); + panelComponent.getChildren().add(new ImageComponent(getImage(ItemID.ADAMANTITE_ORE, client.getVar(Varbits.BLAST_MINE_ADAMANTITE)))); + panelComponent.getChildren().add(new ImageComponent(getImage(ItemID.RUNITE_ORE, client.getVar(Varbits.BLAST_MINE_RUNITE)))); + } + else + { + blastMineWidget.setHidden(false); + } + + return panelComponent.render(graphics); + } + + private BufferedImage getImage(int itemID, int amount) + { + return itemManager.getImage(itemID, amount, true); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java new file mode 100644 index 0000000000..2c167f0a0f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.blastmine; + +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.GameState; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.Overlay; + +@PluginDescriptor(name = "Blast Mine") +public class BlastMinePlugin extends Plugin +{ + @Getter + private final Map rocks = new HashMap<>(); + + @Inject + private Client client; + + @Inject + private BlastMineRockOverlay blastMineRockOverlay; + + @Inject + private BlastMineOreCountOverlay blastMineOreCountOverlay; + + @Provides + BlastMinePluginConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(BlastMinePluginConfig.class); + } + + @Override + public Collection getOverlays() + { + return Arrays.asList(blastMineRockOverlay, blastMineOreCountOverlay); + } + + @Override + protected void shutDown() throws Exception + { + final Widget blastMineWidget = client.getWidget(WidgetInfo.BLAST_MINE); + + if (blastMineWidget != null) + { + blastMineWidget.setHidden(false); + } + } + + @Subscribe + public void onGameObjectSpawned(GameObjectSpawned event) + { + final GameObject gameObject = event.getGameObject(); + BlastMineRockType blastMineRockType = BlastMineRockType.getRockType(gameObject.getId()); + if (blastMineRockType == null) + { + return; + } + + final BlastMineRock newRock = new BlastMineRock(gameObject, blastMineRockType); + final BlastMineRock oldRock = rocks.get(gameObject.getWorldLocation()); + + if (oldRock == null || oldRock.getType() != newRock.getType()) + { + rocks.put(gameObject.getWorldLocation(), newRock); + } + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOADING) + { + rocks.clear(); + } + } + + @Subscribe + public void onGameTick(GameTick gameTick) + { + if (rocks.isEmpty()) + { + return; + } + + rocks.values().removeIf(rock -> + (rock.getRemainingTimeRelative() == 1 && rock.getType() != BlastMineRockType.NORMAL) || + (rock.getRemainingFuseTimeRelative() == 1 && rock.getType() == BlastMineRockType.LIT)); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePluginConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePluginConfig.java new file mode 100644 index 0000000000..d2ce5cf186 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePluginConfig.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.blastmine; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.Color; + +@ConfigGroup( + keyName = "blastmine", + name = "Blast Mine", + description = "Configuration for the Blast Mine plugin" +) +public interface BlastMinePluginConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "showOreOverlay", + name = "Show ore overlay", + description = "Configures whether or not the ore count overlay is displayed" + ) + default boolean showOreOverlay() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "showRockIconOverlay", + name = "Show icons overlay", + description = "Configures whether or not the icon overlay is displayed" + ) + default boolean showRockIconOverlay() + { + return true; + } + + @ConfigItem( + position = 2, + keyName = "showTimerOverlay", + name = "Show timer overlay", + description = "Configures whether or not the timer overlay is displayed" + ) + default boolean showTimerOverlay() + { + return true; + } + + @ConfigItem( + position = 3, + keyName = "showWarningOverlay", + name = "Show explosion warning", + description = "Configures whether or not the explosion warning overlay is displayed" + ) + default boolean showWarningOverlay() + { + return true; + } + + @ConfigItem( + position = 4, + keyName = "hexTimerColor", + name = "Timer color", + description = "Color of timer overlay" + ) + default Color getTimerColor() + { + return new Color(217, 54, 0); + } + + @ConfigItem( + position = 5, + keyName = "hexWarningColor", + name = "Warning color", + description = "Color of warning overlay" + ) + default Color getWarningColor() + { + return new Color(217, 54, 0); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRock.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRock.java new file mode 100644 index 0000000000..1f1cec4fb5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRock.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.blastmine; + +import java.time.Duration; +import java.time.Instant; +import lombok.Getter; +import net.runelite.api.GameObject; + +class BlastMineRock +{ + private static final Duration PLANT_TIME = Duration.ofSeconds(30); + private static final Duration FUSE_TIME = Duration.ofMillis(4200); + + @Getter + private final GameObject gameObject; + + @Getter + private final BlastMineRockType type; + + private final Instant creationTime = Instant.now(); + + BlastMineRock(final GameObject gameObject, BlastMineRockType blastMineRockType) + { + this.gameObject = gameObject; + this.type = blastMineRockType; + } + + double getRemainingFuseTimeRelative() + { + Duration duration = Duration.between(creationTime, Instant.now()); + return duration.compareTo(FUSE_TIME) < 0 ? (double) duration.toMillis() / FUSE_TIME.toMillis() : 1; + } + + double getRemainingTimeRelative() + { + Duration duration = Duration.between(creationTime, Instant.now()); + return duration.compareTo(PLANT_TIME) < 0 ? (double) duration.toMillis() / PLANT_TIME.toMillis() : 1; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockOverlay.java new file mode 100644 index 0000000000..ec89c17990 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockOverlay.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.blastmine; + +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.image.BufferedImage; +import java.util.Map; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.ItemID; +import net.runelite.api.ObjectID; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.Tile; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.widgets.Widget; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ProgressPieComponent; + +public class BlastMineRockOverlay extends Overlay +{ + private static final int MAX_DISTANCE = 16; + private static final int WARNING_DISTANCE = 2; + private static final ImmutableSet WALL_OBJECTS = ImmutableSet.of( + ObjectID.NULL_28570, ObjectID.NULL_28571, ObjectID.NULL_28572, ObjectID.NULL_28573, ObjectID.NULL_28574, + ObjectID.NULL_28575, ObjectID.NULL_28576, ObjectID.NULL_28577, ObjectID.NULL_28578, + ObjectID.HARD_ROCK, ObjectID.HARD_ROCK_28580, ObjectID.CAVITY, ObjectID.CAVITY_28582, + ObjectID.POT_OF_DYNAMITE, ObjectID.POT_OF_DYNAMITE_28584, ObjectID.POT_OF_DYNAMITE_28585, ObjectID.POT_OF_DYNAMITE_28586, + ObjectID.SHATTERED_ROCKFACE, ObjectID.SHATTERED_ROCKFACE_28588); + + private final Client client; + private final BlastMinePlugin plugin; + private final BlastMinePluginConfig config; + + private final BufferedImage chiselIcon; + private final BufferedImage dynamiteIcon; + private final BufferedImage tinderboxIcon; + + @Inject + private BlastMineRockOverlay(Client client, BlastMinePlugin plugin, BlastMinePluginConfig config, ItemManager itemManager) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.client = client; + this.plugin = plugin; + this.config = config; + chiselIcon = itemManager.getImage(ItemID.CHISEL); + dynamiteIcon = itemManager.getImage(ItemID.DYNAMITE); + tinderboxIcon = itemManager.getImage(ItemID.TINDERBOX); + } + + @Override + public Dimension render(Graphics2D graphics) + { + Map rocks = plugin.getRocks(); + if (rocks.isEmpty()) + { + return null; + } + + final Tile[][][] tiles = client.getRegion().getTiles(); + final Widget viewport = client.getViewportWidget(); + + for (final BlastMineRock rock : rocks.values()) + { + if (viewport == null || + rock.getGameObject().getCanvasLocation() == null || + rock.getGameObject().getWorldLocation().distanceTo(client.getLocalPlayer().getWorldLocation()) > MAX_DISTANCE) + { + continue; + } + + switch (rock.getType()) + { + case NORMAL: + drawIconOnRock(graphics, rock, chiselIcon); + break; + case CHISELED: + drawIconOnRock(graphics, rock, dynamiteIcon); + break; + case LOADED: + drawIconOnRock(graphics, rock, tinderboxIcon); + break; + case LIT: + drawTimerOnRock(graphics, rock, config.getTimerColor()); + drawAreaWarning(graphics, rock, config.getWarningColor(), tiles); + break; + } + } + + return null; + } + + private void drawIconOnRock(Graphics2D graphics, BlastMineRock rock, BufferedImage icon) + { + if (!config.showRockIconOverlay()) + { + return; + } + + Point loc = Perspective.getCanvasImageLocation(client, graphics, rock.getGameObject().getLocalLocation(), icon, 150); + + if (loc != null) + { + graphics.drawImage(icon, loc.getX(), loc.getY(), null); + } + } + + private void drawTimerOnRock(Graphics2D graphics, BlastMineRock rock, Color color) + { + if (!config.showTimerOverlay()) + { + return; + } + + Point loc = Perspective.worldToCanvas(client, rock.getGameObject().getX(), rock.getGameObject().getY(), client.getPlane(), 150); + + if (loc != null) + { + final double timeLeft = 1 - rock.getRemainingFuseTimeRelative(); + final ProgressPieComponent pie = new ProgressPieComponent(); + pie.setFill(color); + pie.setBorderColor(color); + pie.setPosition(loc); + pie.setProgress(timeLeft); + pie.render(graphics); + } + } + + private void drawAreaWarning(Graphics2D graphics, BlastMineRock rock, Color color, Tile[][][] tiles) + { + if (!config.showWarningOverlay()) + { + return; + } + + final int z = client.getPlane(); + int x = rock.getGameObject().getLocalLocation().getX() / Perspective.LOCAL_TILE_SIZE; + int y = rock.getGameObject().getLocalLocation().getY() / Perspective.LOCAL_TILE_SIZE; + final int orientation = tiles[z][x][y].getWallObject().getOrientationA(); + + switch (orientation) //calculate explosion around the tile in front of the wall + { + case 1: + x--; + break; + case 4: + x++; + break; + case 8: + y--; + break; + default: + y++; + } + + for (int i = -WARNING_DISTANCE; i <= WARNING_DISTANCE; i++) + { + for (int j = -WARNING_DISTANCE; j <= WARNING_DISTANCE; j++) + { + final GameObject gameObject = tiles[z][x + i][y + j].getGameObjects()[0]; + + //check if tile is empty, or is a wall... + if (gameObject == null || !WALL_OBJECTS.contains(gameObject.getId())) + { + final LocalPoint localTile = new LocalPoint( + (x + i) * Perspective.LOCAL_TILE_SIZE + Perspective.LOCAL_TILE_SIZE / 2, + (y + j) * Perspective.LOCAL_TILE_SIZE + Perspective.LOCAL_TILE_SIZE / 2); + final Polygon poly = Perspective.getCanvasTilePoly(client, localTile); + + if (poly != null) + { + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 100)); + graphics.fillPolygon(poly); + } + } + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java new file mode 100644 index 0000000000..7c7bda870a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.blastmine; + +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import net.runelite.api.ObjectID; + +public enum BlastMineRockType +{ + NORMAL(ObjectID.HARD_ROCK, ObjectID.HARD_ROCK_28580), + CHISELED(ObjectID.CAVITY, ObjectID.CAVITY_28582), + LOADED(ObjectID.POT_OF_DYNAMITE, ObjectID.POT_OF_DYNAMITE_28584), + LIT(ObjectID.POT_OF_DYNAMITE_28585, ObjectID.POT_OF_DYNAMITE_28586), + EXPLODED(ObjectID.SHATTERED_ROCKFACE, ObjectID.SHATTERED_ROCKFACE_28588); + + private static final Map rockTypes = new HashMap<>(); + + static + { + for (BlastMineRockType type : values()) + { + for (int spotId : type.getObjectIds()) + { + rockTypes.put(spotId, type); + } + } + } + + @Getter + private final int[] objectIds; + + BlastMineRockType(int... objectIds) + { + this.objectIds = objectIds; + } + + public static BlastMineRockType getRockType(int objectId) + { + return rockTypes.get(objectId); + } +}