diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrothers.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrothers.java new file mode 100644 index 0000000000..b7634fabf2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrothers.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, 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.barrows; + +import lombok.Getter; +import net.runelite.api.Point; + +public enum BarrowsBrothers +{ + VERAC("V", new Point(3557, 3298)), + DHAROK("D", new Point(3575, 3298)), + AHRIM("A", new Point(3566, 3289)), + TORAG("T", new Point(3553, 3283)), + KARIL("K", new Point(3566, 3275)), + GUTHAN("G", new Point(3577, 3283)); + + @Getter + private final String name; + @Getter + private final Point location; + + BarrowsBrothers(String name, net.runelite.api.Point location) + { + this.name = name; + this.location = location; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsConfig.java new file mode 100644 index 0000000000..3031645729 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsConfig.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018, 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.barrows; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup( + keyName = "barrows", + name = "Barrows Plugin", + description = "Configuration for the Barrows plugin" +) +public interface BarrowsConfig extends Config +{ + @ConfigItem( + keyName = "enabled", + name = "Enabled", + description = "Configures whether or not the Barrows plugin is displayed" + ) + default boolean enabled() + { + return true; + } + + @ConfigItem( + keyName = "showMinimap", + name = "Show Minimap in tunnels", + description = "Configures whether or not the minimap is displayed" + ) + default boolean showMinimap() + { + return true; + } + + @ConfigItem( + keyName = "showBrotherLoc", + name = "Show Brothers location", + description = "Configures whether or not the brothers location is displayed" + ) + default boolean showBrotherLoc() + { + return true; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsOverlay.java new file mode 100644 index 0000000000..22685c5131 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsOverlay.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2018, 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.barrows; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.util.List; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.NPC; +import net.runelite.api.ObjectComposition; +import net.runelite.api.Perspective; +import net.runelite.api.Player; +import net.runelite.api.WallObject; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +class BarrowsOverlay extends Overlay +{ + private static final int MAX_DISTANCE = 2350; + + private final Client client; + private final BarrowsPlugin plugin; + private final BarrowsConfig config; + + @Inject + BarrowsOverlay(Client client, BarrowsPlugin plugin, BarrowsConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + this.client = client; + this.plugin = plugin; + this.config = config; + } + + @Override + public Dimension render(Graphics2D graphics, Point parent) + { + if (!config.enabled()) + { + return null; + } + + Player local = client.getLocalPlayer(); + + // tunnels are only on z=0 + if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && config.showMinimap()) + { + //NPC yellow dot + List npcs = client.getNpcs(); + for (NPC npc : npcs) + { + net.runelite.api.Point minimapLocation = npc.getMinimapLocation(); + if (minimapLocation != null) + { + graphics.setColor(Color.yellow); + graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4); + } + } + + //Render barrows walls/doors + renderObjects(graphics, local); + + //Player white dot + graphics.setColor(Color.white); + graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3); + } + else if (config.showBrotherLoc()) + { + renderBarrowsBrothers(graphics); + } + + return null; + } + + private void renderObjects(Graphics2D graphics, Player local) + { + net.runelite.api.Point localLocation = local.getLocalLocation(); + for (WallObject wall : plugin.getWalls()) + { + net.runelite.api.Point location = wall.getLocalLocation(); + if (localLocation.distanceTo(location) <= MAX_DISTANCE) + { + renderWalls(graphics, wall); + } + } + + for (GameObject ladder : plugin.getLadders()) + { + net.runelite.api.Point location = ladder.getLocalLocation(); + if (localLocation.distanceTo(location) <= MAX_DISTANCE) + { + renderLadders(graphics, ladder); + } + } + } + + private void renderWalls(Graphics2D graphics, WallObject wall) + { + net.runelite.api.Point minimapLocation = wall.getMinimapLocation(); + + if (minimapLocation == null) + { + return; + } + + ObjectComposition objectComp = client.getObjectDefinition(wall.getId()); + ObjectComposition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null; + + if (impostor != null && impostor.getActions()[0] != null) + { + graphics.setColor(Color.green); + } + else + { + graphics.setColor(Color.gray); + } + + graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3); + } + + private void renderLadders(Graphics2D graphics, GameObject ladder) + { + net.runelite.api.Point minimapLocation = ladder.getMinimapLocation(); + + if (minimapLocation == null) + { + return; + } + + ObjectComposition objectComp = client.getObjectDefinition(ladder.getId()); + + if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null) + { + graphics.setColor(Color.orange); + graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6); + } + } + + private void renderBarrowsBrothers(Graphics2D graphics) + { + for (BarrowsBrothers brother : BarrowsBrothers.values()) + { + net.runelite.api.Point location = brother.getLocation(); + + if (!Perspective.isWorldInScene(client, location)) + { + continue; + } + + net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics, + Perspective.worldToLocal(client, brother.getLocation()), brother.getName()); + + if (minimapText != null) + { + graphics.setColor(Color.black); + graphics.drawString(brother.getName(), minimapText.getX() + 1, minimapText.getY() + 1); + + graphics.setColor(Color.cyan); + graphics.drawString(brother.getName(), minimapText.getX(), minimapText.getY()); + } + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java new file mode 100644 index 0000000000..580beacd9a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2018, 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.barrows; + +import com.google.common.collect.Sets; +import com.google.common.eventbus.Subscribe; +import com.google.inject.Binder; +import com.google.inject.Provides; +import java.util.HashSet; +import java.util.Set; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.GameObject; +import net.runelite.api.GameState; +import net.runelite.api.ObjectID; +import net.runelite.api.WallObject; +import net.runelite.api.events.GameObjectChanged; +import net.runelite.api.events.GameObjectDespawned; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.WallObjectChanged; +import net.runelite.api.events.WallObjectDespawned; +import net.runelite.api.events.WallObjectSpawned; +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 = "Barrows plugin" +) +public class BarrowsPlugin extends Plugin +{ + @Getter(AccessLevel.PACKAGE) + private static final Set BARROWS_WALLS = Sets.newHashSet + ( + ObjectID.DOOR_20678, ObjectID.NULL_20681, ObjectID.NULL_20682, ObjectID.NULL_20683, ObjectID.NULL_20684, ObjectID.NULL_20685, ObjectID.NULL_20686, ObjectID.NULL_20687, + ObjectID.NULL_20688, ObjectID.NULL_20689, ObjectID.NULL_20690, ObjectID.NULL_20691, ObjectID.NULL_20692, ObjectID.NULL_20693, ObjectID.NULL_20694, ObjectID.NULL_20695, + ObjectID.NULL_20696, ObjectID.DOOR_20697, ObjectID.NULL_20700, ObjectID.NULL_20701, ObjectID.NULL_20702, ObjectID.NULL_20703, ObjectID.NULL_20704, ObjectID.NULL_20705, + ObjectID.NULL_20706, ObjectID.NULL_20707, ObjectID.NULL_20708, ObjectID.NULL_20709, ObjectID.NULL_20710, ObjectID.NULL_20711, ObjectID.NULL_20712, ObjectID.NULL_20713, + ObjectID.NULL_20714, ObjectID.NULL_20715, ObjectID.NULL_20728, ObjectID.NULL_20730 + ); + + private static final Set BARROWS_LADDERS = Sets.newHashSet(ObjectID.NULL_20675, ObjectID.NULL_20676, ObjectID.NULL_20677); + + @Getter(AccessLevel.PACKAGE) + private final Set walls = new HashSet<>(); + @Getter(AccessLevel.PACKAGE) + private final Set ladders = new HashSet<>(); + @Inject + BarrowsOverlay barrowsOverlay; + + @Override + public void configure(Binder binder) + { + binder.bind(BarrowsOverlay.class); + } + + @Provides + BarrowsConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(BarrowsConfig.class); + } + + @Override + public Overlay getOverlay() + { + return barrowsOverlay; + } + + @Subscribe + public void onWallObjectSpanwed(WallObjectSpawned event) + { + WallObject wallObject = event.getWallObject(); + if (BARROWS_WALLS.contains(wallObject.getId())) + { + walls.add(wallObject); + } + } + + @Subscribe + public void onWallObjectChanged(WallObjectChanged event) + { + WallObject previous = event.getPrevious(); + WallObject wallObject = event.getWallObject(); + + walls.remove(previous); + if (BARROWS_WALLS.contains(wallObject.getId())) + { + walls.add(wallObject); + } + } + + @Subscribe + public void onWallObjectDespawned(WallObjectDespawned event) + { + WallObject wallObject = event.getWallObject(); + walls.remove(wallObject); + } + + @Subscribe + public void onGameObjectSpawned(GameObjectSpawned event) + { + GameObject gameObject = event.getGameObject(); + if (BARROWS_LADDERS.contains(gameObject.getId())) + { + ladders.add(gameObject); + } + } + + @Subscribe + public void onGameObjectChanged(GameObjectChanged event) + { + GameObject previous = event.getPrevious(); + GameObject gameObject = event.getGameObject(); + + ladders.remove(previous); + if (BARROWS_LADDERS.contains(gameObject.getId())) + { + ladders.add(gameObject); + } + } + + @Subscribe + public void onGameObjectDespawned(GameObjectDespawned event) + { + GameObject gameObject = event.getGameObject(); + ladders.remove(gameObject); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOADING) + { + // on region changes the tiles get set to null + walls.clear(); + ladders.clear(); + } + } +}