From cca17bf93ebaa1551da0b104fbfe1190d880f835 Mon Sep 17 00:00:00 2001 From: vanni <43923017+gazivodag@users.noreply.github.com> Date: Thu, 1 Aug 2019 06:31:31 -0400 Subject: [PATCH] zalcano: add plugin (#1177) * Zalcano plugin Shows AOE for bosses and when to run from the glowing rocks and more. Still have to improve the step system telling users to mine/smelt so it's a hidden option for now. * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Requested changes * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Did not know you can make events private! Will do this from now on. Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java Co-Authored-By: Owain van Brakel * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java Co-Authored-By: Owain van Brakel * slight changes * various region checks and null checks moved most of the heavy weight from overlay into util * checkstyle (oops!) * Update runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java Co-Authored-By: Owain van Brakel * Apply suggestions from code review Co-Authored-By: Owain van Brakel * Apply suggestions from code review Co-Authored-By: Owain van Brakel * access fix --- .../java/net/runelite/api/AnimationID.java | 5 + .../java/net/runelite/api/ProjectileID.java | 2 + .../runelite/client/plugins/zalcano/Step.java | 11 + .../client/plugins/zalcano/ZalcanoConfig.java | 185 +++++++++++++ .../plugins/zalcano/ZalcanoOverlay.java | 242 ++++++++++++++++++ .../client/plugins/zalcano/ZalcanoPlugin.java | 234 +++++++++++++++++ .../plugins/zalcano/ZalcanoStepsOverlay.java | 72 ++++++ .../client/plugins/zalcano/ZalcanoUtil.java | 236 +++++++++++++++++ 8 files changed, 987 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java index aca0d2ac66..87dfad539a 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -332,4 +332,9 @@ public final class AnimationID public static final int HUNLEFF_TRAMPLE = 8420; public static final int HUNLEFF_ATTACK = 8419; public static final int HUNLEFF_TORNADO = 8418; + + //Zalcano + public static final int ZALCANO_KNOCKED_DOWN = 8437; + public static final int ZALCANO_WAKEUP = 8439; + public static final int ZALCANO_ROCK_GLOWING = 8448; } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java index 706151e1c8..8d733e7a74 100644 --- a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java +++ b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java @@ -107,4 +107,6 @@ public class ProjectileID public static final int HUNLEFF_RANGE_ATTACK = 1711; public static final int HUNLEFF_CORRUPTED_RANGE_ATTACK = 1712; + public static final int ZALCANO_PROJECTILE = 1728; + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java new file mode 100644 index 0000000000..91b1103607 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java @@ -0,0 +1,11 @@ +package net.runelite.client.plugins.zalcano; + +enum Step +{ + IDLE, + MINE, + SMELT, + RUNECRAFT, + THROW, + MINE_ZALCANO +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoConfig.java new file mode 100644 index 0000000000..6c84d5d155 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoConfig.java @@ -0,0 +1,185 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Stub; + +@ConfigGroup("zalcano") +public interface ZalcanoConfig extends Config +{ + + @ConfigItem( + keyName = "zalcanoStub", + name = "Zalcano", + description = "", + position = 0 + ) + default Stub zalcanoStub() + { + return new Stub(); + } + + @ConfigItem( + keyName = "highlightZalcanoHull", + name = "Highlight Zalcano", + description = "Highlight Zalcano\'s convex hull.", + parent = "zalcanoStub", + position = 1 + ) + default boolean highlightZalcanoHull() + { + return false; + } + + @ConfigItem( + keyName = "zalcanoHullColor", + name = "Color for highlight", + description = "", + parent = "zalcanoStub", + position = 2 + ) + default Color zalcanoHullColor() + { + return new Color(255, 25, 0); + } + + @ConfigItem( + keyName = "zalcanoAoesStub", + name = "Area of Effect", + description = "", + position = 3 + ) + default Stub zalcanoAoesStub() + { + return new Stub(); + } + + @ConfigItem( + keyName = "showAoeZalcanoWakeup", + name = "Zalcano Wakeup", + description = "Shows an AOE warning for Zalcano waking back up.", + parent = "zalcanoAoesStub", + position = 4 + ) + default boolean showAoeZalcanoWakeup() + { + return true; + } + + @ConfigItem( + keyName = "showAoeForRockfall", + name = "Small Rocks", + description = "Shows an AOE warning for the rocks that fall occasionally.", + parent = "zalcanoAoesStub", + position = 5 + ) + default boolean showAoeForRockfall() + { + return true; + } + + @ConfigItem( + keyName = "showAoeForRedSymbols", + name = "Red Symbols", + description = "Shows an AOE warning for the 3x3 red symbols that appear.", + parent = "zalcanoAoesStub", + position = 6 + ) + default boolean showAoeForRedSymbols() + { + return true; + } + + @ConfigItem( + keyName = "highlightMiningSpot", + name = "Mining spot", + description = "Highlights the glowing rock and warns you if Zalcano attacks it.", + parent = "zalcanoAoesStub", + position = 7 + ) + default boolean highlightMiningSpot() + { + return true; + } + + @ConfigItem( + keyName = "helperStub", + name = "Helpers", + description = "", + position = 8 + ) + default Stub helperStub() + { + return new Stub(); + } + + /** + * TODO: improve helper + */ + @ConfigItem( + keyName = "showSteps", + name = "Show Step", + description = "", + parent = "helperStub", + position = 9, + hidden = true //hidden until fully functional + ) + default boolean showSteps() + { + return false; + } + + @ConfigItem( + keyName = "showAoeZalcanoMineable", + name = "Zalcano Mineable", + description = "Highlights Zalcano if she is mineable.", + parent = "helperStub", + position = 10 + ) + default boolean showAoeZalcanoMineable() + { + return true; + } + + @ConfigItem( + keyName = "highlightGolem", + name = "Highlight Golem", + description = "Highlights the Golem that Zalcano spawns in.", + parent = "helperStub", + position = 11 + ) + default boolean highlightGolem() + { + return true; + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoOverlay.java new file mode 100644 index 0000000000..b0c97ef371 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoOverlay.java @@ -0,0 +1,242 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.AnimationID; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.GraphicsObject; +import net.runelite.api.Perspective; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; + +import javax.inject.Inject; +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.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; + +/** + * some ids + * 9049 = zalcano npc id 8439 wakeup animation 8437 mineable stage + * 1727 = rocks falling graphics object id + * 1728 = red projectile flying into rock + *

+ * 36192 + anim 8448 = glowing rock + *

+ * 36199 red circle + * 36200 blue circle + *

+ * golem id = 9051 + *

+ * 23905, 23906, 23907 + */ +@Slf4j +public class ZalcanoOverlay extends Overlay +{ + + private final ZalcanoPlugin plugin; + private final ZalcanoConfig config; + private final ZalcanoUtil util; + private final Client client; + + + @Inject + ZalcanoOverlay(final ZalcanoPlugin plugin, final ZalcanoConfig config, final ZalcanoUtil util, final Client client) + { + super(plugin); + this.plugin = plugin; + this.config = config; + this.util = util; + this.client = client; + + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!util.isInZalcanoRegion()) + { + return null; + } + + if (config.showAoeForRockfall()) + { + renderBadTiles(graphics); + } + if (config.showAoeForRedSymbols()) + { + renderRedSymbols(graphics); + } + if (config.highlightMiningSpot()) + { + renderRockToMine(graphics); + } + if (config.highlightGolem()) + { + renderGolem(graphics); + } + if (config.highlightZalcanoHull()) + { + renderZalcano(graphics); + } + + //has their own configs within this method + renderZalcanoAnimations(graphics); + + return null; + } + + private void renderBadTiles(Graphics2D graphics) + { + List rockFall = util.getRockfall(); + + if (rockFall != null) + { + for (GraphicsObject graphicsObject : rockFall) + { + WorldPoint worldPoint = WorldPoint.fromLocal(client, graphicsObject.getLocation()); + OverlayUtil.drawTiles(graphics, client, worldPoint, client.getLocalPlayer().getWorldLocation(), Color.RED, 2, 150, 50); + } + } + } + + private void renderRedSymbols(Graphics2D graphics) + { + List symbolsToRender = util.getRedSymbols(); + + if (symbolsToRender != null) + { + for (GameObject gameObject : symbolsToRender) + { + final LocalPoint loc = gameObject.getLocalLocation(); + final Polygon poly = Perspective.getCanvasTileAreaPoly(client, loc, 3); + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, new Color(249, 47, 30)); + } + } + } + } + + private void renderRockToMine(Graphics2D graphics) + { + GameObject glowingRock = util.getGlowingRock(); + + if (glowingRock != null) + { + final Polygon poly = Perspective.getCanvasTileAreaPoly(client, glowingRock.getLocalLocation(), !util.projectileExists() ? 2 : 4); + + if (poly != null) + { + final Color green = new Color(140, 255, 60); + OverlayUtil.renderPolygon(graphics, poly, !util.projectileExists() ? green : Color.RED); + OverlayUtil.renderTextLocation(graphics, glowingRock.getCanvasLocation(), !util.projectileExists() ? util.mine : util.warning, !util.projectileExists() ? green : Color.RED); + } + } + } + + private void renderGolem(Graphics2D graphics) + { + if (plugin.getGolem() != null) + { + Polygon hull = plugin.getGolem().getConvexHull(); + if (hull != null) + { + OverlayUtil.renderPolygon(graphics, hull, new Color(206, 41, 231)); + } + + } + } + + private void renderZalcano(Graphics2D graphics) + { + if (plugin.getZalcano() != null) + { + Polygon hull = plugin.getZalcano().getConvexHull(); + if (hull != null) + { + OverlayUtil.renderPolygon(graphics, hull, config.zalcanoHullColor()); + } + + } + } + + private void renderZalcanoAnimations(Graphics2D graphics) + { + if (plugin.getZalcano() != null) + { + switch (plugin.getZalcano().getAnimation()) + { + case AnimationID.ZALCANO_KNOCKED_DOWN: + if (config.showAoeZalcanoMineable()) + { + renderZalcanoMineable(graphics); + } + break; + case AnimationID.ZALCANO_WAKEUP: + if (config.showAoeZalcanoWakeup()) + { + renderZalcanoWakeup(graphics); + } + break; + } + } + } + + private void renderZalcanoMineable(Graphics2D graphics) + { + renderZalcanoAOE(graphics, 4, util.mine, Color.GREEN); + } + + private void renderZalcanoWakeup(Graphics2D graphics) + { + renderZalcanoAOE(graphics, 6, ZalcanoUtil.warning, Color.RED); + } + + private void renderZalcanoAOE(Graphics2D graphics, int polySize, String text, Color color) + { + Polygon poly = Perspective.getCanvasTileAreaPoly(client, plugin.getZalcano().getLocalLocation(), polySize); + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + OverlayUtil.renderTextLocation(graphics, plugin.getZalcano().getCanvasTextLocation(graphics, text, plugin.getZalcano().getLogicalHeight() / 2), text, color); + } + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java new file mode 100644 index 0000000000..a5d0be7736 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java @@ -0,0 +1,234 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import com.google.inject.Binder; +import com.google.inject.Inject; +import com.google.inject.Provides; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.AnimationID; +import net.runelite.api.Client; +import net.runelite.api.ItemID; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.kit.KitType; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "Zalcano", + description = "Highlights Zalcano AOEs and useful stuff", + tags = {"zalcano", "aoe", "prifddinas", "elf", "boss"}, + type = PluginType.PVM +) +@Slf4j +public class ZalcanoPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private ZalcanoConfig config; + + @Inject + private ZalcanoUtil util; + + @Inject + private ZalcanoOverlay overlay; + + @Inject + private ZalcanoStepsOverlay stepsOverlay; + + @Inject + private OverlayManager overlayManager; + + @Inject + private EventBus eventBus; + + @Setter(AccessLevel.PACKAGE) + @Getter(AccessLevel.PACKAGE) + private NPC zalcano; + + @Getter(AccessLevel.PACKAGE) + private NPC golem; + + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private Step step; + + private int ores = 0; + + @Provides + ZalcanoConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(ZalcanoConfig.class); + } + + @Override + protected void startUp() + { + eventBus.subscribe(GameTick.class, "regionchecker", this::onGameTickCheckRegion); + } + + @Override + protected void shutDown() + { + eventBus.unregister(this); + eventBus.unregister("regionchecker"); + overlayManager.remove(overlay); + overlayManager.remove(stepsOverlay); + } + + @Override + public void configure(Binder binder) + { + } + + private void onGameTickCheckRegion(GameTick gameTick) + { + if (util.isInZalcanoRegion()) + { + log.debug("region check complete loading other events"); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::gameTickStepMachine); + eventBus.subscribe(GameTick.class, this, this::gameTickOreListener); + + util.manuallyFindZalcano(); //this is here because the new subscribed npcspawn doesn't catch a pre existing zalcano + + overlayManager.add(overlay); + overlayManager.add(stepsOverlay); + + eventBus.unregister("regionchecker"); + } + } + + private void onNpcSpawned(NpcSpawned npcSpawned) + { + switch (npcSpawned.getNpc().getId()) + { + case NpcID.ZALCANO: + log.debug("zalcano spawned"); + zalcano = npcSpawned.getNpc(); + break; + case NpcID.GOLEM_9051: + log.debug("golem spawned"); + golem = npcSpawned.getNpc(); + break; + } + } + + private void onNpcDespawned(NpcDespawned npcDespawned) + { + switch (npcDespawned.getNpc().getId()) + { + case NpcID.ZALCANO: + zalcano = null; + break; + case NpcID.GOLEM_9051: + golem = null; + break; + } + } + + //23905 //ore + //23906 //smelted + //23907 //runecrafted ore + + /** + * This event switches steps based on different conditions (inaccurate) + * TODO: improve this. until then its option is disabled in the config + * + * @param gameTick + */ + private void gameTickStepMachine(GameTick gameTick) + { + if (!config.showSteps()) + { + return; + } + + if (getZalcano() != null) + { + if (getZalcano().getAnimation() == AnimationID.ZALCANO_KNOCKED_DOWN) //zalcano got knocked down + { + setStep(Step.MINE_ZALCANO); + return; + } + } + if (util.countItemInInventory(ItemID.TEPHRA) < 3 && util.countItemInInventory(ItemID.REFINED_TEPHRA) < 3 && util.countStackInInventory(ItemID.IMBUED_TEPHRA) < 3) + { + if (client.getLocalPlayer().getPlayerAppearance().getEquipmentId(KitType.WEAPON) == ItemID.IMBUED_TEPHRA) + { + setStep(Step.THROW); + return; + } + if (getZalcano() != null && util.countItemInInventory(ItemID.REFINED_TEPHRA) == 0 && util.countItemInInventory(ItemID.IMBUED_TEPHRA) == 0) + { + setStep(Step.MINE); + return; + } + } + if (util.countItemInInventory(ItemID.TEPHRA) >= 3) + { + setStep(Step.SMELT); + return; + } + if (util.countItemInInventory(ItemID.REFINED_TEPHRA) >= 3 && ores == 0) + { + setStep(Step.RUNECRAFT); + return; + } + if (util.countStackInInventory(ItemID.IMBUED_TEPHRA) >= 3) + { + setStep(Step.THROW); + return; + } + setStep(Step.IDLE); + } + + private void gameTickOreListener(GameTick gameTick) + { + if (!config.showSteps()) + { + return; + } + ores = util.countItemInInventory(ItemID.TEPHRA); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java new file mode 100644 index 0000000000..16256c215f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java @@ -0,0 +1,72 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +public class ZalcanoStepsOverlay extends Overlay +{ + private final Client client; + private final ZalcanoPlugin plugin; + private final ZalcanoConfig config; + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + ZalcanoStepsOverlay(final Client client, final ZalcanoPlugin plugin, final ZalcanoConfig config) + { + super(plugin); + setPosition(OverlayPosition.TOP_LEFT); + this.client = client; + this.config = config; + this.plugin = plugin; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (client.getLocalPlayer().getWorldLocation().getRegionID() == 12126 && config.showSteps()) + { + panelComponent.getChildren().clear(); + + panelComponent.getChildren().add(TitleComponent.builder() + .text("Step: " + plugin.getStep().name()) + .color(Color.CYAN) + .build()); + + return panelComponent.render(graphics); + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java new file mode 100644 index 0000000000..15023023fb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java @@ -0,0 +1,236 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import net.runelite.api.AnimationID; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.api.DynamicObject; +import net.runelite.api.GameObject; +import net.runelite.api.GraphicsObject; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.ObjectID; +import net.runelite.api.Projectile; +import net.runelite.api.ProjectileID; +import net.runelite.api.Renderable; +import net.runelite.api.Tile; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; + +public class ZalcanoUtil +{ + + private final Client client; + private final ZalcanoPlugin plugin; + + static final String mine = "MINE"; + protected static final String warning = "GET BACK"; + private static final int ZALCANO_REGION = 12126; + + @Inject + ZalcanoUtil(Client client, ZalcanoPlugin plugin) + { + this.client = client; + this.plugin = plugin; + } + + boolean isInZalcanoRegion() + { + return client.getLocalPlayer().getWorldLocation().getRegionID() == ZALCANO_REGION; + } + + + boolean projectileExists() + { + for (Projectile projectile : client.getProjectiles()) + { + if (projectile != null) + { + if (projectile.getId() == ProjectileID.ZALCANO_PROJECTILE) + { + return true; + } + } + } + return false; + } + + //this should be a project-wide standard + private List getGameObjects() + { + List gameObjectArrayList = new ArrayList<>(); + + for (int x = 0; x < Constants.SCENE_SIZE; x++) + { + for (int y = 0; y < Constants.SCENE_SIZE; y++) + { + Tile tile = client.getScene().getTiles()[client.getPlane()][x][y]; + + if (tile.getGameObjects() != null) + { + for (GameObject gameObject : tile.getGameObjects()) + { + if (gameObject != null) //im aware this can still give null objects + { + gameObjectArrayList.add(gameObject); + } + } + } + } + } + return gameObjectArrayList; + } + + GameObject getGlowingRock() + { + for (GameObject gameObject : getGameObjects()) + { + if (gameObject != null) + { + if (gameObject.getId() == ObjectID.ROCK_FORMATION_GLOWING) + { + if (client.getLocalPlayer().getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= 2400) + { + Renderable renderable = gameObject.getRenderable(); + if (renderable instanceof DynamicObject) + { + if (((DynamicObject) renderable).getAnimationID() == AnimationID.ZALCANO_ROCK_GLOWING) + { + return gameObject; + } + } + } + } + } + } + return null; + } + + List getRedSymbols() + { + List list = new ArrayList<>(); + for (GameObject gameObject : getGameObjects()) + { + if (gameObject != null) + { + if (gameObject.getId() == ObjectID.DEMONIC_SYMBOL) + { + if (client.getLocalPlayer().getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= 2400) + { + Renderable renderable = gameObject.getRenderable(); + if (renderable instanceof DynamicObject) + { + list.add(gameObject); + } + } + } + } + } + return list.size() > 0 ? list : null; + } + + List getRockfall() + { + List list = new ArrayList<>(); + for (GraphicsObject graphicsObject : client.getGraphicsObjects()) + { + if (graphicsObject != null) + { + if (graphicsObject.getId() == 1727/*<-- not sure where to add that*/) + { + list.add(graphicsObject); + } + } + } + return list.size() > 0 ? list : null; + } + + int countItemInInventory(int itemID) + { + int i = 0; + Widget widget = client.getWidget(WidgetInfo.INVENTORY); + for (WidgetItem widgetItem : widget.getWidgetItems()) + { + if (widgetItem.getId() == itemID) + { + i++; + } + } + return i; + } + + /** + * Courtesy of OP + * + * @param itemId + * @return + */ + int countStackInInventory(int itemId) + { + ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY); + if (inventory != null) + { + Item[] items = inventory.getItems(); + for (int i = 0; i < 28; ++i) + { + if (i < items.length) + { + Item item = items[i]; + if (item.getId() >= 0 && item.getId() == itemId) + { + return item.getQuantity(); + } + } + } + } + return 0; + } + + void manuallyFindZalcano() + { + for (NPC npc : client.getNpcs()) + { + if (npc != null) + { + if (npc.getId() == NpcID.ZALCANO) + { + plugin.setZalcano(npc); + } + } + } + } + + +}