From ab4cc921647155c730f4bcf4ef391746bfd96da2 Mon Sep 17 00:00:00 2001 From: Ganom Date: Fri, 28 Jun 2019 18:44:26 -0400 Subject: [PATCH] Rework and Improve Fight Caves (#801) --- .../java/net/runelite/api/AnimationID.java | 11 +- .../plugins/fightcave/FightCaveConfig.java | 101 ++++- .../plugins/fightcave/FightCaveContainer.java | 138 +++++++ .../plugins/fightcave/FightCaveOverlay.java | 201 ++++++++++ .../plugins/fightcave/FightCavePlugin.java | 347 +++++++++--------- .../client/plugins/fightcave/JadAttack.java | 53 --- .../client/plugins/fightcave/JadOverlay.java | 87 ----- .../plugins/fightcave/NPCContainer.java | 77 ---- .../plugins/fightcave/TimersOverlay.java | 184 ---------- .../client/plugins/fightcave/WaveMonster.java | 12 +- .../client/plugins/fightcave/WaveOverlay.java | 46 ++- 11 files changed, 652 insertions(+), 605 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveContainer.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadAttack.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcave/NPCContainer.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/fightcave/TimersOverlay.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 8ff7fcd3cc..45ce683b6e 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -22,7 +22,7 @@ * (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.api;; +package net.runelite.api; /** * Utility class used for mapping animation IDs. @@ -166,8 +166,15 @@ public final class AnimationID public static final int BLOCK_UNARMED = 424; // Same Animation as failed pickpocked // NPC animations - public static final int TZTOK_JAD_MAGIC_ATTACK = 2656; public static final int TZTOK_JAD_RANGE_ATTACK = 2652; + public static final int TZTOK_JAD_MELEE_ATTACK = 2655; + public static final int TZTOK_JAD_MAGIC_ATTACK = 2656; + public static final int TOK_XIL_RANGE_ATTACK = 2633; + public static final int TOK_XIL_MELEE_ATTACK = 2628; + public static final int KET_ZEK_MELEE_ATTACK = 2644; + public static final int KET_ZEK_MAGE_ATTACK = 2647; + public static final int MEJ_KOT_MELEE_ATTACK = 2637; + public static final int MEJ_KOT_HEAL_ATTACK = 2639; public static final int HELLHOUND_DEFENCE = 6566; public static final int VORKATH_WAKE_UP = 7950; public static final int VORKATH_DEATH = 7949; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveConfig.java index f1e5457f7a..72c21243c5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveConfig.java @@ -24,20 +24,119 @@ */ package net.runelite.client.plugins.fightcave; +import java.awt.Font; +import lombok.AllArgsConstructor; +import lombok.Getter; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Range; +import net.runelite.client.config.Stub; @ConfigGroup("fightcave") public interface FightCaveConfig extends Config { @ConfigItem( + position = 0, + keyName = "mainConfig", + name = "Main Config", + description = "" + ) + default Stub mainConfig() + { + return new Stub(); + } + + @ConfigItem( + position = 1, keyName = "waveDisplay", name = "Wave display", - description = "Shows monsters that will spawn on the selected wave(s)." + description = "Shows monsters that will spawn on the selected wave(s).", + parent = "mainConfig" ) default WaveDisplayMode waveDisplay() { return WaveDisplayMode.BOTH; } + + @ConfigItem( + position = 2, + keyName = "tickTimersWidget", + name = "Tick Timers in Prayer", + description = "Adds an overlay to the Praayer Interface with the ticks until next attack for that prayer.", + parent = "mainConfig" + ) + default boolean tickTimersWidget() + { + return true; + } + + @ConfigItem( + position = 3, + keyName = "text", + name = "Text", + description = "" + ) + default Stub text() + { + return new Stub(); + } + + @ConfigItem( + position = 4, + keyName = "fontStyle", + name = "Font Style", + description = "Plain | Bold | Italics", + parent = "text" + ) + default FontStyle fontStyle() + { + return FontStyle.BOLD; + } + + @Range( + min = 14, + max = 40 + ) + @ConfigItem( + position = 5, + keyName = "textSize", + name = "Text Size", + description = "Text Size for Timers.", + parent = "text" + ) + default int textSize() + { + return 32; + } + + @ConfigItem( + position = 6, + keyName = "shadows", + name = "Shadows", + description = "Adds Shadows to text.", + parent = "text" + ) + default boolean shadows() + { + return false; + } + + @Getter + @AllArgsConstructor + enum FontStyle + { + BOLD("Bold", Font.BOLD), + ITALIC("Italic", Font.ITALIC), + PLAIN("Plain", Font.PLAIN); + + private String name; + private int font; + + @Override + public String toString() + { + return getName(); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveContainer.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveContainer.java new file mode 100644 index 0000000000..cc0f1a523c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveContainer.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019, Ganom + * Copyright (c) 2019, Lucas + * 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.fightcave; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.runelite.api.Actor; +import net.runelite.api.AnimationID; +import net.runelite.api.NPC; +import net.runelite.api.NPCDefinition; +import net.runelite.api.NpcID; +import net.runelite.api.Prayer; + +@Getter +class FightCaveContainer +{ + private NPC npc; + private String npcName; + private int npcIndex; + private int npcSize; + private int attackSpeed; + private int priority; + private ImmutableSet animations; + @Setter + private int ticksUntilAttack; + @Setter + private Actor npcInteracting; + @Setter + private AttackStyle attackStyle; + + FightCaveContainer(NPC npc, int attackSpeed) + { + this.npc = npc; + this.npcName = npc.getName(); + this.npcIndex = npc.getIndex(); + this.npcInteracting = npc.getInteracting(); + this.attackStyle = AttackStyle.UNKNOWN; + this.attackSpeed = attackSpeed; + this.ticksUntilAttack = -1; + final NPCDefinition composition = npc.getTransformedDefinition(); + + BossMonsters monster = BossMonsters.of(npc.getId()); + + if (monster == null) + { + throw new IllegalStateException(); + } + + this.animations = monster.animations; + this.attackStyle = monster.attackStyle; + this.priority = monster.priority; + + if (composition != null) + { + this.npcSize = composition.getSize(); + } + } + + @RequiredArgsConstructor + enum BossMonsters + { + TOK_XIL1(NpcID.TOKXIL_3121, AttackStyle.RANGE, ImmutableSet.of(AnimationID.TOK_XIL_RANGE_ATTACK, AnimationID.TOK_XIL_MELEE_ATTACK), 1), + TOK_XIL2(NpcID.TOKXIL_3122, AttackStyle.RANGE, ImmutableSet.of(AnimationID.TOK_XIL_RANGE_ATTACK, AnimationID.TOK_XIL_MELEE_ATTACK), 1), + KETZEK1(NpcID.KETZEK, AttackStyle.MAGE, ImmutableSet.of(AnimationID.KET_ZEK_MAGE_ATTACK, AnimationID.KET_ZEK_MELEE_ATTACK), 0), + KETZEK2(NpcID.KETZEK_3126, AttackStyle.MAGE, ImmutableSet.of(AnimationID.KET_ZEK_MAGE_ATTACK, AnimationID.KET_ZEK_MELEE_ATTACK), 0), + YTMEJKOT1(NpcID.YTMEJKOT, AttackStyle.MELEE, ImmutableSet.of(AnimationID.MEJ_KOT_HEAL_ATTACK, AnimationID.MEJ_KOT_MELEE_ATTACK), 2), + YTMEJKOT2(NpcID.YTMEJKOT_3124, AttackStyle.MELEE, ImmutableSet.of(AnimationID.MEJ_KOT_HEAL_ATTACK, AnimationID.MEJ_KOT_MELEE_ATTACK), 2), + TZTOKJAD1(NpcID.TZTOKJAD, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.TZTOK_JAD_MAGIC_ATTACK, AnimationID.TZTOK_JAD_RANGE_ATTACK, AnimationID.TZTOK_JAD_MELEE_ATTACK), 0), + TZTOKJAD2(NpcID.TZTOKJAD_6506, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.TZTOK_JAD_MAGIC_ATTACK, AnimationID.TZTOK_JAD_RANGE_ATTACK, AnimationID.TZTOK_JAD_MELEE_ATTACK), 0); + + private static ImmutableMap idMap; + + static + { + ImmutableMap.Builder builder = ImmutableMap.builder(); + + for (BossMonsters monster : values()) + { + builder.put(monster.npcID, monster); + } + + idMap = builder.build(); + } + + private final int npcID; + private final AttackStyle attackStyle; + private final ImmutableSet animations; + private final int priority; + + static BossMonsters of(int npcID) + { + return idMap.get(npcID); + } + } + + @Getter(AccessLevel.PACKAGE) + @AllArgsConstructor + enum AttackStyle + { + MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC), + RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES), + MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE), + UNKNOWN("Unknown", Color.WHITE, null); + + private String name; + private Color color; + private Prayer prayer; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveOverlay.java new file mode 100644 index 0000000000..68569157d5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCaveOverlay.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2019, Ganom + * 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.fightcave; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.Prayer; +import net.runelite.api.SpriteID; +import net.runelite.client.game.SpriteManager; +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; +import net.runelite.client.util.ImageUtil; + +public class FightCaveOverlay extends Overlay +{ + private FightCavePlugin plugin; + private FightCaveConfig config; + private Client client; + private SpriteManager spriteManager; + + @Inject + FightCaveOverlay(Client client, FightCavePlugin plugin, FightCaveConfig config, SpriteManager spriteManager) + { + this.client = client; + this.plugin = plugin; + this.config = config; + this.spriteManager = spriteManager; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGHEST); + setLayer(OverlayLayer.ALWAYS_ON_TOP); + } + + @Override + public Dimension render(Graphics2D graphics) + { + for (FightCaveContainer npc : plugin.getFightCaveContainer()) + { + if (npc.getNpc() == null) + { + continue; + } + + final int ticksLeft = npc.getTicksUntilAttack(); + final FightCaveContainer.AttackStyle attackStyle = npc.getAttackStyle(); + + if (ticksLeft <= 0) + { + continue; + } + + final String ticksLeftStr = String.valueOf(ticksLeft); + final int font = config.fontStyle().getFont(); + final boolean shadows = config.shadows(); + Color color = (ticksLeft <= 1 ? Color.WHITE : attackStyle.getColor()); + final Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, Integer.toString(ticksLeft), 0); + + if (npc.getNpcName().equals("TzTok-Jad")) + { + color = (ticksLeft <= 1 || ticksLeft == 8 ? attackStyle.getColor() : Color.WHITE); + + BufferedImage pray = getPrayerImage(npc.getAttackStyle()); + + if (pray == null) + { + continue; + } + + renderImageLocation(graphics, npc.getNpc().getCanvasImageLocation(ImageUtil.resizeImage(pray, 36, 36), 0), pray, 12, 30); + } + + OverlayUtil.renderTextLocation(graphics, ticksLeftStr, config.textSize(), font, color, canvasPoint, shadows, 0); + } + + if (config.tickTimersWidget()) + { + + if (!plugin.getMageTicks().isEmpty()) + { + widgetHandler(graphics, + Prayer.PROTECT_FROM_MAGIC, + plugin.getMageTicks().get(0) == 1 ? Color.WHITE : Color.CYAN, + Integer.toString(plugin.getMageTicks().get(0)), + config.shadows() + ); + } + if (!plugin.getRangedTicks().isEmpty()) + { + widgetHandler(graphics, + Prayer.PROTECT_FROM_MISSILES, + plugin.getRangedTicks().get(0) == 1 ? Color.WHITE : Color.GREEN, + Integer.toString(plugin.getRangedTicks().get(0)), + config.shadows() + ); + } + if (!plugin.getMeleeTicks().isEmpty()) + { + widgetHandler(graphics, + Prayer.PROTECT_FROM_MELEE, + plugin.getMeleeTicks().get(0) == 1 ? Color.WHITE : Color.RED, + Integer.toString(plugin.getMeleeTicks().get(0)), + config.shadows() + ); + } + } + return null; + } + + private void widgetHandler(Graphics2D graphics, Prayer prayer, Color color, String ticks, boolean shadows) + { + if (prayer != null) + { + Rectangle bounds = OverlayUtil.renderPrayerOverlay(graphics, client, prayer, color); + + if (bounds != null) + { + renderTextLocation(graphics, ticks, 16, config.fontStyle().getFont(), color, centerPoint(bounds), shadows); + } + } + } + + private BufferedImage getPrayerImage(FightCaveContainer.AttackStyle attackStyle) + { + switch (attackStyle) + { + case MAGE: + return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0); + case MELEE: + return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MELEE, 0); + case RANGE: + return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0); + } + return null; + } + + private void renderImageLocation(Graphics2D graphics, Point imgLoc, BufferedImage image, int xOffset, int yOffset) + { + int x = imgLoc.getX() + xOffset; + int y = imgLoc.getY() - yOffset; + + graphics.drawImage(image, x, y, null); + } + + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows) + { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) + { + final Point canvasCenterPoint = new Point( + canvasPoint.getX() - 3, + canvasPoint.getY() + 6); + final Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() - 2, + canvasPoint.getY() + 7); + if (shadows) + { + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + } + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } + + private Point centerPoint(Rectangle rect) + { + int x = (int) (rect.getX() + rect.getWidth() / 2); + int y = (int) (rect.getY() + rect.getHeight() / 2); + return new Point(x, y); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java index 7b8281becf..c694aae2f2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java @@ -27,22 +27,23 @@ package net.runelite.client.plugins.fightcave; import com.google.inject.Provides; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumMap; -import java.util.HashMap; +import java.util.HashSet; import java.util.List; -import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.annotation.Nullable; import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.AnimationID; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.NPC; import net.runelite.api.NpcID; -import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; @@ -50,6 +51,7 @@ import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.NPCManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -64,59 +66,16 @@ import org.apache.commons.lang3.ArrayUtils; enabledByDefault = false ) +@Slf4j public class FightCavePlugin extends Plugin { + static final int MAX_WAVE = 63; + @Getter(AccessLevel.PACKAGE) + static final List> WAVES = new ArrayList<>(); private static final Pattern WAVE_PATTERN = Pattern.compile(".*Wave: (\\d+).*"); private static final int FIGHT_CAVE_REGION = 9551; private static final int MAX_MONSTERS_OF_TYPE_PER_WAVE = 2; - static final int MAX_WAVE = 63; - - @Getter - static final List> WAVES = new ArrayList<>(); - - @Getter - private int currentWave = -1; - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private WaveOverlay waveOverlay; - - @Inject - private JadOverlay jadOverlay; - - @Inject - private TimersOverlay timersOverlay; - - @Inject - private ConfigManager externalConfig; - - @Getter(AccessLevel.PACKAGE) - private Map Rangers = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private Map Magers = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private Map Meleers = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private Map Drainers = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private Map Ignore = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - @Nullable - private JadAttack attack; - - private NPC jad; - static { final WaveMonster[] waveMonsters = WaveMonster.values(); @@ -157,6 +116,36 @@ public class FightCavePlugin extends Plugin } } + @Inject + private Client client; + @Inject + private NPCManager npcManager; + @Inject + private OverlayManager overlayManager; + @Inject + private WaveOverlay waveOverlay; + @Inject + private FightCaveOverlay fightCaveOverlay; + @Inject + private FightCaveConfig config; + @Getter(AccessLevel.PACKAGE) + private Set fightCaveContainer = new HashSet<>(); + @Getter(AccessLevel.PACKAGE) + private int currentWave = -1; + @Getter(AccessLevel.PACKAGE) + private boolean validRegion; + @Getter(AccessLevel.PACKAGE) + private List mageTicks = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) + private List rangedTicks = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) + private List meleeTicks = new ArrayList<>(); + + static String formatMonsterQuantity(final WaveMonster monster, final int quantity) + { + return String.format("%dx %s", quantity, monster); + } + @Provides FightCaveConfig provideConfig(ConfigManager configManager) { @@ -166,21 +155,41 @@ public class FightCavePlugin extends Plugin @Override public void startUp() { - overlayManager.add(waveOverlay); - overlayManager.add(jadOverlay); - overlayManager.add(timersOverlay); + if (client.getGameState() == GameState.LOGGED_IN) + { + if (regionCheck()) + { + validRegion = true; + overlayManager.add(waveOverlay); + overlayManager.add(fightCaveOverlay); + } + } } @Override public void shutDown() { overlayManager.remove(waveOverlay); + overlayManager.remove(fightCaveOverlay); currentWave = -1; - overlayManager.remove(timersOverlay); - overlayManager.remove(jadOverlay); - jad = null; - attack = null; + } + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (!validRegion) + { + return; + } + + final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage()); + + if (event.getType() != ChatMessageType.GAMEMESSAGE || !waveMatcher.matches()) + { + return; + } + + currentWave = Integer.parseInt(waveMatcher.group(1)); } @Subscribe @@ -191,98 +200,43 @@ public class FightCavePlugin extends Plugin return; } - if (!inFightCave()) + if (regionCheck()) { - currentWave = -1; + validRegion = true; + overlayManager.add(waveOverlay); + overlayManager.add(fightCaveOverlay); } + else + { + validRegion = false; + overlayManager.remove(fightCaveOverlay); + overlayManager.remove(fightCaveOverlay); + } + + fightCaveContainer.clear(); } - @Subscribe - public void onGameTick(GameTick Event) - { - for (NPCContainer ranger : getRangers().values()) - { - ranger.setTicksUntilAttack(ranger.getTicksUntilAttack() - 1); - if (ranger.getNpc().getAnimation() == 2633) - { - if (ranger.getTicksUntilAttack() < 1) - { - ranger.setTicksUntilAttack(4); - } - } - } - - for (NPCContainer meleer : getMeleers().values()) - { - meleer.setTicksUntilAttack(meleer.getTicksUntilAttack() - 1); - if (meleer.getNpc().getAnimation() == 2637 || meleer.getNpc().getAnimation() == 2639) - { - if (meleer.getTicksUntilAttack() < 1) - { - meleer.setTicksUntilAttack(4); - } - } - } - - for (NPCContainer mager : getMagers().values()) - { - mager.setTicksUntilAttack(mager.getTicksUntilAttack() - 1); - if (mager.getNpc().getAnimation() == 2647) - { - if (mager.getTicksUntilAttack() < 1) - { - mager.setTicksUntilAttack(4); - } - } - } - } - - @Subscribe - public void onChatMessage(ChatMessage event) - { - final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage()); - - if (event.getType() != ChatMessageType.GAMEMESSAGE - || !inFightCave() - || !waveMatcher.matches()) - { - return; - } - - currentWave = Integer.parseInt(waveMatcher.group(1)); - } - - @Subscribe public void onNpcSpawned(NpcSpawned event) { + if (!validRegion) + { + return; + } + NPC npc = event.getNpc(); + switch (npc.getId()) { - case NpcID.TZKIH_3116: - case NpcID.TZKIH_3117: - Drainers.put(npc, new NPCContainer(npc)); - break; - case NpcID.TZKEK_3118: - case NpcID.TZKEK_3119: - case NpcID.TZKEK_3120: - Ignore.put(npc, new NPCContainer(npc)); - break; case NpcID.TOKXIL_3121: case NpcID.TOKXIL_3122: - Rangers.put(npc, new NPCContainer(npc)); - break; case NpcID.YTMEJKOT: case NpcID.YTMEJKOT_3124: - Meleers.put(npc, new NPCContainer(npc)); - break; case NpcID.KETZEK: case NpcID.KETZEK_3126: - Magers.put(npc, new NPCContainer(npc)); - break; case NpcID.TZTOKJAD: case NpcID.TZTOKJAD_6506: - jad = npc; + fightCaveContainer.add(new FightCaveContainer(npc, npcManager.getAttackSpeed(npc.getId()))); break; } } @@ -290,55 +244,106 @@ public class FightCavePlugin extends Plugin @Subscribe public void onNpcDespawned(NpcDespawned event) { - if (Rangers.remove(event.getNpc()) != null && Rangers.isEmpty()) - { - Rangers.clear(); - } - if (Meleers.remove(event.getNpc()) != null && Meleers.isEmpty()) - { - Meleers.clear(); - } - if (Magers.remove(event.getNpc()) != null && Magers.isEmpty()) - { - Magers.clear(); - } - if (Drainers.remove(event.getNpc()) != null && Drainers.isEmpty()) - { - Drainers.clear(); - } - if (Ignore.remove(event.getNpc()) != null && Ignore.isEmpty()) - { - Ignore.clear(); - } - - } - - @Subscribe - public void onAnimationChanged(AnimationChanged event) - { - if (event.getActor() != jad) + if (!validRegion) { return; } - if (jad.getAnimation() == JadAttack.MAGIC.getAnimation()) - { - attack = JadAttack.MAGIC; - } + NPC npc = event.getNpc(); - else if (jad.getAnimation() == JadAttack.RANGE.getAnimation()) + switch (npc.getId()) { - attack = JadAttack.RANGE; + case NpcID.TOKXIL_3121: + case NpcID.TOKXIL_3122: + case NpcID.YTMEJKOT: + case NpcID.YTMEJKOT_3124: + case NpcID.KETZEK: + case NpcID.KETZEK_3126: + case NpcID.TZTOKJAD: + case NpcID.TZTOKJAD_6506: + fightCaveContainer.removeIf(c -> c.getNpc() == npc); + break; } } - boolean inFightCave() + @Subscribe + public void onGameTick(GameTick Event) + { + if (!validRegion) + { + return; + } + + mageTicks.clear(); + rangedTicks.clear(); + meleeTicks.clear(); + + for (FightCaveContainer npc : fightCaveContainer) + { + if (npc.getTicksUntilAttack() >= 0) + { + npc.setTicksUntilAttack(npc.getTicksUntilAttack() - 1); + } + + for (int anims : npc.getAnimations()) + { + if (anims == npc.getNpc().getAnimation()) + { + if (npc.getTicksUntilAttack() < 1) + { + npc.setTicksUntilAttack(npc.getAttackSpeed()); + } + + switch (anims) + { + case AnimationID.TZTOK_JAD_RANGE_ATTACK: + npc.setAttackStyle(FightCaveContainer.AttackStyle.RANGE); + break; + case AnimationID.TZTOK_JAD_MAGIC_ATTACK: + npc.setAttackStyle(FightCaveContainer.AttackStyle.MAGE); + break; + case AnimationID.TZTOK_JAD_MELEE_ATTACK: + npc.setAttackStyle(FightCaveContainer.AttackStyle.MELEE); + break; + } + } + } + + if (npc.getNpcName().equals("TzTok-Jad")) + { + continue; + } + + switch (npc.getAttackStyle()) + { + case RANGE: + if (npc.getTicksUntilAttack() > 0) + { + rangedTicks.add(npc.getTicksUntilAttack()); + } + break; + case MELEE: + if (npc.getTicksUntilAttack() > 0) + { + meleeTicks.add(npc.getTicksUntilAttack()); + } + break; + case MAGE: + if (npc.getTicksUntilAttack() > 0) + { + mageTicks.add(npc.getTicksUntilAttack()); + } + break; + } + } + + Collections.sort(mageTicks); + Collections.sort(rangedTicks); + Collections.sort(meleeTicks); + } + + private boolean regionCheck() { return ArrayUtils.contains(client.getMapRegions(), FIGHT_CAVE_REGION); } - - static String formatMonsterQuantity(final WaveMonster monster, final int quantity) - { - return String.format("%dx %s", quantity, monster); - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadAttack.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadAttack.java deleted file mode 100644 index ae752e015a..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadAttack.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017, Devin French - * 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.fightcave; - -import net.runelite.api.AnimationID; -import net.runelite.api.Prayer; - -public enum JadAttack -{ - MAGIC(AnimationID.TZTOK_JAD_MAGIC_ATTACK, Prayer.PROTECT_FROM_MAGIC), - RANGE(AnimationID.TZTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES); - - private final int animation; - private final Prayer prayer; - - JadAttack(int animation, Prayer prayer) - { - this.animation = animation; - this.prayer = prayer; - } - - public int getAnimation() - { - return animation; - } - - public Prayer getPrayer() - { - return prayer; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadOverlay.java deleted file mode 100644 index 25ca70820d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/JadOverlay.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2017, Devin French - * 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.fightcave; - -import java.awt.Color; -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.SpriteID; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.components.ComponentConstants; -import net.runelite.client.ui.overlay.components.ImageComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; - -public class JadOverlay extends Overlay -{ - private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); - - private final Client client; - private final FightCavePlugin plugin; - private final SpriteManager spriteManager; - private final PanelComponent imagePanelComponent = new PanelComponent(); - - @Inject - private JadOverlay(Client client, FightCavePlugin plugin, SpriteManager spriteManager) - { - setPosition(OverlayPosition.BOTTOM_RIGHT); - setPriority(OverlayPriority.HIGH); - this.client = client; - this.plugin = plugin; - this.spriteManager = spriteManager; - } - - @Override - public Dimension render(Graphics2D graphics) - { - final JadAttack attack = plugin.getAttack(); - - if (attack == null) - { - return null; - } - - final BufferedImage prayerImage = getPrayerImage(attack); - - imagePanelComponent.getChildren().clear(); - imagePanelComponent.getChildren().add(new ImageComponent(prayerImage)); - imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer()) - ? ComponentConstants.STANDARD_BACKGROUND_COLOR - : NOT_ACTIVATED_BACKGROUND_COLOR); - - return imagePanelComponent.render(graphics); - } - - private BufferedImage getPrayerImage(JadAttack attack) - { - final int prayerSpriteID = attack == JadAttack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES; - return spriteManager.getSprite(prayerSpriteID, 0); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/NPCContainer.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/NPCContainer.java deleted file mode 100644 index 9ad21108f4..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/NPCContainer.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2018, Woox - * Copyright (c) 2019, Ganom - * 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.fightcave; - -import lombok.Getter; -import lombok.Setter; -import net.runelite.api.Actor; -import net.runelite.api.NPC; -import net.runelite.api.NPCDefinition; - -class NPCContainer -{ - - @Getter - private NPC npc; - - @Getter - private int npcIndex; - - @Getter - private String npcName; - - @Getter - private int npcSize; - - @Setter - @Getter - private int TicksUntilAttack; - - @Setter - @Getter - private int npcSpeed; - - @Setter - @Getter - private Actor npcInteracting; - - - NPCContainer(NPC npc) - { - this.npc = npc; - this.npcName = npc.getName(); - this.npcIndex = npc.getIndex(); - this.npcInteracting = npc.getInteracting(); - this.npcSpeed = 0; - this.TicksUntilAttack = 0; - final NPCDefinition composition = npc.getTransformedDefinition(); - - if (composition != null) - { - this.npcSize = composition.getSize(); - } - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/TimersOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/TimersOverlay.java deleted file mode 100644 index 88998a3841..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/TimersOverlay.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2019, Ganom - * 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.fightcave; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Polygon; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.NPC; -import net.runelite.api.NPCDefinition; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -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; - -public class TimersOverlay extends Overlay -{ - private FightCavePlugin plugin; - private Client client; - - @Inject - TimersOverlay(FightCavePlugin plugin, Client client) - { - this.plugin = plugin; - this.client = client; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGHEST); - setLayer(OverlayLayer.ALWAYS_ON_TOP); - } - - @Override - public Dimension render(Graphics2D graphics) - { - for (NPCContainer npc : plugin.getDrainers().values()) - { - renderNpcOverlay(graphics, npc.getNpc(), Color.RED, 255, 20); - String str = "drainer"; - Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, str, 0); - renderTextLocation(graphics, str, 12, Color.WHITE, canvasPoint); - } - - for (NPCContainer npc : plugin.getIgnore().values()) - { - renderNpcOverlay(graphics, npc.getNpc(), Color.BLACK, 50, 5); - String str = "ignore"; - Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, str, 0); - renderTextLocation(graphics, str, 10, Color.WHITE, canvasPoint); - } - - Color tickcolor; - - for (NPCContainer npc : plugin.getRangers().values()) - { - renderNpcOverlay(graphics, npc.getNpc(), Color.GREEN, 100, 10); - final int ticksLeft = npc.getTicksUntilAttack(); - if (ticksLeft > 0) - { - if (ticksLeft == 1) - { - tickcolor = Color.GREEN; - } - else - { - tickcolor = Color.WHITE; - } - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0); - renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint); - } - } - - for (NPCContainer npc : plugin.getMagers().values()) - { - renderNpcOverlay(graphics, npc.getNpc(), Color.CYAN, 100, 10); - final int ticksLeft = npc.getTicksUntilAttack(); - if (ticksLeft > 0) - { - if (ticksLeft == 1) - { - tickcolor = Color.CYAN; - } - else - { - - tickcolor = Color.WHITE; - } - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0); - renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint); - } - } - - for (NPCContainer npc : plugin.getMeleers().values()) - { - renderNpcOverlay(graphics, npc.getNpc(), Color.RED, 100, 10); - final int ticksLeft = npc.getTicksUntilAttack(); - if (ticksLeft > 0) - { - if (ticksLeft == 1) - { - tickcolor = Color.RED; - } - else - { - - tickcolor = Color.WHITE; - } - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0); - renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint); - } - } - - return null; - } - - private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineAlpha, int fillAlpha) - { - int size = 1; - NPCDefinition composition = actor.getTransformedDefinition(); - if (composition != null) - { - size = composition.getSize(); - } - LocalPoint lp = actor.getLocalLocation(); - Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); - - if (tilePoly != null) - { - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); - graphics.setStroke(new BasicStroke(2)); - graphics.draw(tilePoly); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); - graphics.fill(tilePoly); - } - } - - private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, Color fontColor, Point canvasPoint) - { - graphics.setFont(new Font("Arial", Font.BOLD, fontSize)); - if (canvasPoint != null) - { - final Point canvasCenterPoint = new Point( - canvasPoint.getX(), - canvasPoint.getY()); - final Point canvasCenterPoint_shadow = new Point( - canvasPoint.getX() + 1, - canvasPoint.getY() + 1); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveMonster.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveMonster.java index 9919623124..399cd1947b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveMonster.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveMonster.java @@ -29,12 +29,12 @@ import lombok.AllArgsConstructor; @AllArgsConstructor enum WaveMonster { - TZ_KIH("Tz-Kih", 22), - TZ_KEK("Tz-Kek", 45), - TOK_XIL("Tok-Xil", 90), - YT_MEJKOT("Yt-MejKot", 180), - KET_ZEK("Ket-Zek", 360), - TZKOK_JAD("TzTok-Jad", 702); + TZ_KIH("Drainer", 22), + TZ_KEK("Blob", 45), + TOK_XIL("Range", 90), + YT_MEJKOT("Melee", 180), + KET_ZEK("Mage", 360), + TZKOK_JAD("Jad", 702); private final String name; private final int level; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveOverlay.java index 2b5fdf370b..f1d81816f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/WaveOverlay.java @@ -37,8 +37,8 @@ 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; -import net.runelite.client.ui.overlay.components.table.TableComponent; import net.runelite.client.ui.overlay.components.table.TableAlignment; +import net.runelite.client.ui.overlay.components.table.TableComponent; class WaveOverlay extends Overlay { @@ -46,22 +46,38 @@ class WaveOverlay extends Overlay private final FightCaveConfig config; private final FightCavePlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); @Inject private WaveOverlay(FightCaveConfig config, FightCavePlugin plugin) { - setPosition(OverlayPosition.TOP_RIGHT); this.config = config; this.plugin = plugin; + setPosition(OverlayPosition.TOP_RIGHT); + } + + private static Collection buildWaveLines(final Map wave) + { + final List> monsters = new ArrayList<>(wave.entrySet()); + monsters.sort(Map.Entry.comparingByKey()); + final List outputLines = new ArrayList<>(); + + for (Map.Entry monsterEntry : monsters) + { + final WaveMonster monster = monsterEntry.getKey(); + final int quantity = monsterEntry.getValue(); + final String line = FightCavePlugin.formatMonsterQuantity(monster, quantity); + + outputLines.add(line); + } + + return outputLines; } @Override public Dimension render(Graphics2D graphics) { - if (!plugin.inFightCave() - || plugin.getCurrentWave() < 0) + if (!plugin.isValidRegion() || plugin.getCurrentWave() < 0) { return null; } @@ -108,26 +124,8 @@ class WaveOverlay extends Overlay } if (!tableComponent.isEmpty()) - { - panelComponent.getChildren().add(tableComponent); - } - } - - private static Collection buildWaveLines(final Map wave) - { - final List> monsters = new ArrayList<>(wave.entrySet()); - monsters.sort(Map.Entry.comparingByKey()); - final List outputLines = new ArrayList<>(); - - for (Map.Entry monsterEntry : monsters) { - final WaveMonster monster = monsterEntry.getKey(); - final int quantity = monsterEntry.getValue(); - final String line = FightCavePlugin.formatMonsterQuantity(monster, quantity); - - outputLines.add(line); + panelComponent.getChildren().add(tableComponent); } - - return outputLines; } }