diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java index 105bf9fa89..7156045eb8 100644 --- a/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java +++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java @@ -184,6 +184,25 @@ public class WorldArea return isInMeleeDistance(new WorldArea(other, 1, 1)); } + /** + * Checks whether this area is within melee distance of another without blocking in-between. + * + * @param client the client to test in + * @param other the other area + * @return true if in melee distance without blocking, false otherwise + */ + public boolean canMelee(Client client, WorldArea other) + { + if (isInMeleeDistance(other)) + { + Point p1 = this.getComparisonPoint(other); + Point p2 = other.getComparisonPoint(this); + WorldArea w1 = new WorldArea(p1.getX(), p1.getY() , 1, 1, this.getPlane()); + return (w1.canTravelInDirection(client, p2.getX() - p1.getX(), p2.getY() - p1.getY())); + } + return false; + } + /** * Checks whether this area intersects with another. * diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 70c5c83000..98b1c9529c 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -284,6 +284,11 @@ asm-all 6.0_BETA + + org.json + json + 20180813 + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationConfig.java new file mode 100644 index 0000000000..565aec82d8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationConfig.java @@ -0,0 +1,78 @@ +package net.runelite.client.plugins.chattranslation; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("chattranslation") +public interface ChatTranslationConfig extends Config +{ + + @ConfigItem( + keyName = "publicChat", + name = "Translate incoming Messages", + description = "Would you like to Translate Public Chat?", + position = 0, + group = "Public Chat Translation", + hidden = true + ) + default boolean publicChat() + { + return false; + } + + @ConfigItem( + keyName = "translateOptionVisable", + name = "Show 'Translate' menu option", + description = "Adds 'Translate' to the right-click menu in the Chatbox.", + position = 1, + group = "Public Chat Translation", + hidden = true +// unhide = "publicChat" + ) + default boolean translateOptionVisable() + { + return false; + } + + @ConfigItem( + keyName = "publicTargetLanguage", + name = "Target Language", + description = "Language to translate messages too.", + position = 2, + group = "Public Chat Translation", + hidden = true +// unhide = "publicChat" + ) + default Languages publicTargetLanguage() + { + return Languages.ENGLISH; + } + + @ConfigItem( + keyName = "playerChat", + name = "Translate outgoing Messages", + description = "Would you like to Translate your Messages?", + position = 3, + group = "Player Message Translation" + ) + default boolean playerChat() + { + return false; + } + + @ConfigItem( + keyName = "playerTargetLanguage", + name = "Target Language", + description = "Language to translate messages too.", + position = 4, + group = "Player Message Translation", + hidden = true, + unhide = "playerChat" + ) + default Languages playerTargetLanguage() + { + return Languages.SPANISH; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java new file mode 100644 index 0000000000..85dc748859 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java @@ -0,0 +1,236 @@ +package net.runelite.client.plugins.chattranslation; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ObjectArrays; +import com.google.inject.Provides; +import net.runelite.api.*; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.PlayerMenuOptionClicked; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.input.KeyListener; +import net.runelite.client.input.KeyManager; +import net.runelite.client.menus.MenuManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import org.apache.commons.lang3.ArrayUtils; + +import javax.inject.Inject; +import javax.inject.Provider; +import java.awt.event.KeyEvent; + +@PluginDescriptor( + name = "Chat Translator", + description = "Translates messages from one Language to another.", + tags = {"translate", "language", "english", "spanish", "dutch", "french"}, + type = PluginType.UTILITY +) +public class ChatTranslationPlugin extends Plugin implements KeyListener +{ + + private static final String TRANSLATE = "Translate"; + private static final ImmutableList AFTER_OPTIONS = ImmutableList.of("Message", "Add ignore", "Remove friend", "Kick"); + + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private Provider menuManager; + + @Inject + private ChatMessageManager chatMessageManager; + + @Inject + private KeyManager keyManager; + + @Inject + private ChatTranslationConfig config; + + @Provides + ChatTranslationConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(ChatTranslationConfig.class); + } + + @Override + protected void startUp() throws Exception + { + if (client != null) + { + if (config.translateOptionVisable()) + { + menuManager.get().addPlayerMenuItem(TRANSLATE); + } + } + keyManager.registerKeyListener(this); + } + + @Override + protected void shutDown() throws Exception + { + if (client != null) + { + if (config.translateOptionVisable()) + { + menuManager.get().removePlayerMenuItem(TRANSLATE); + } + } + keyManager.unregisterKeyListener(this); + } + + @Subscribe + public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + { + if (event.getMenuOption().equals(TRANSLATE)) + { + //TODO: Translate selected message. + } + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + if (!config.translateOptionVisable()) + { + return; + } + + int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); + String option = event.getOption(); + + if (groupId == WidgetInfo.CHATBOX.getGroupId()) + { + boolean after; + + if (!AFTER_OPTIONS.contains(option)) + { + return; + } + + final MenuEntry lookup = new MenuEntry(); + lookup.setOption(TRANSLATE); + lookup.setTarget(event.getTarget()); + lookup.setType(MenuAction.RUNELITE.getId()); + lookup.setParam0(event.getActionParam0()); + lookup.setParam1(event.getActionParam1()); + lookup.setIdentifier(event.getIdentifier()); + + MenuEntry[] newMenu = ObjectArrays.concat(lookup, client.getMenuEntries()); + int menuEntryCount = newMenu.length; + ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); + client.setMenuEntries(newMenu); + } + } + + @Subscribe + public void onChatMessage(ChatMessage chatMessage) + { + if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) + { + return; + } + switch (chatMessage.getType()) + { + case PUBLICCHAT: + case MODCHAT: + if (!config.publicChat()) + { + return; + } + break; + default: + return; + } + + String message = chatMessage.getMessage(); + + Translator translator = new Translator(); + + try + { + //Automatically check language of message and translate to selected language. + String translation = translator.translate("auto", config.publicTargetLanguage().toString(), message); + if (translation != null) + { + final MessageNode messageNode = chatMessage.getMessageNode(); + messageNode.setRuneLiteFormatMessage(translation); + chatMessageManager.update(messageNode); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + + client.refreshChat(); + } + + @Override + public void keyPressed(KeyEvent event) + { + if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + if (!config.playerChat()) + { + return; + } + + Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT); + + if (chatboxParent != null && chatboxParent.getOnKeyListener() != null) + { + if (event.getKeyCode() == 0xA) + { + event.consume(); + + Translator translator = new Translator(); + String message = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); + + try + { + //Automatically check language of message and translate to selected language. + String translation = translator.translate("auto", config.playerTargetLanguage().toString(), message); + if (translation != null) + { + client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, translation); + + clientThread.invoke(() -> + { + client.runScript(96, 0, translation); + }); + } + client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, ""); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + } + + @Override + public void keyReleased(KeyEvent e) + { + // Nothing. + } + + @Override + public void keyTyped(KeyEvent e) + { + // Nothing. + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/Languages.java b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/Languages.java new file mode 100644 index 0000000000..3ec7b3ad81 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/Languages.java @@ -0,0 +1,24 @@ +package net.runelite.client.plugins.chattranslation; + +public enum Languages +{ + + ENGLISH("en"), + DUTCH("nl"), + SPANISH("es"), + FRENCH("fr"); + + private final String shortName; + + Languages(String shortName) + { + this.shortName = shortName; + } + + @Override + public String toString() + { + return shortName; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/Translator.java b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/Translator.java new file mode 100644 index 0000000000..df8f26ea29 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/Translator.java @@ -0,0 +1,46 @@ +package net.runelite.client.plugins.chattranslation; + +import org.json.JSONArray; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; + +public class Translator +{ + + public String translate(String source, String target, String message) throws Exception + { + + String url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=" + source + "&tl=" + target + "&dt=t&q=" + URLEncoder.encode(message, "UTF-8"); + + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestProperty("User-Agent", "Mozilla/5.0"); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) + { + response.append(inputLine); + } + in.close(); + + return parseResult(response.toString()); + } + + private String parseResult(String inputJson) throws Exception + { + //TODO: find a way to do this using google.gson + JSONArray jsonArray = new JSONArray(inputJson); + JSONArray jsonArray2 = (JSONArray) jsonArray.get(0); + JSONArray jsonArray3 = (JSONArray) jsonArray2.get(0); + + return jsonArray3.get(0).toString(); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/DigsitePendantMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/DigsitePendantMode.java index 95e84a3188..dd9b58eea5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/DigsitePendantMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/DigsitePendantMode.java @@ -29,7 +29,7 @@ public enum DigsitePendantMode { DIGSITE("Digsite"), FOSSIL_ISLAND("Fossil Island"), - LITHKREN("Lithkren"); + LITHKREN("Lithkren Dungeon"); private final String name; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/MemorizedNpc.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/MemorizedNpc.java index 09531c4cfc..404748db74 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/MemorizedNpc.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/MemorizedNpc.java @@ -25,7 +25,9 @@ package net.runelite.client.plugins.npchighlight; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import lombok.Getter; import lombok.Setter; import net.runelite.api.NPC; @@ -38,7 +40,7 @@ class MemorizedNpc private int npcIndex; @Getter - private String npcName; + private Set npcNames; @Getter private int npcSize; @@ -63,7 +65,8 @@ class MemorizedNpc MemorizedNpc(NPC npc) { - this.npcName = npc.getName(); + this.npcNames = new HashSet<>(); + this.npcNames.add(npc.getName()); this.npcIndex = npc.getIndex(); this.possibleRespawnLocations = new ArrayList<>(); this.respawnTime = -1; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 34d89e1944..07b877e1a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -34,6 +34,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -58,6 +59,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.GraphicsObjectCreated; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.NpcCompositionChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.callback.ClientThread; @@ -304,14 +306,15 @@ public class NpcIndicatorsPlugin extends Plugin if (removed) { - highlightedNpcs.remove(npc); - memorizedNpcs.remove(npc.getIndex()); + MemorizedNpc mn = memorizedNpcs.get(npc.getIndex()); + if (mn != null && isNpcMemorizationUnnecessary(mn)) + { + memorizedNpcs.remove(npc.getIndex()); + } } else { - memorizeNpc(npc); npcTags.add(id); - highlightedNpcs.add(npc); } click.consume(); @@ -320,30 +323,28 @@ public class NpcIndicatorsPlugin extends Plugin @Subscribe public void onNpcSpawned(NpcSpawned npcSpawned) { - final NPC npc = npcSpawned.getNpc(); - final String npcName = npc.getName(); + NPC npc = npcSpawned.getNpc(); + highlightNpcIfMatch(npc); - if (npcName == null) + if (memorizedNpcs.containsKey(npc.getIndex())) { - return; - } - - if (npcTags.contains(npc.getIndex())) - { - memorizeNpc(npc); - highlightedNpcs.add(npc); spawnedNpcsThisTick.add(npc); - return; } + } - for (String highlight : highlights) + @Subscribe + public void onNpcCompositionChanged(NpcCompositionChanged event) + { + NPC npc = event.getNpc(); + highlightNpcIfMatch(npc); + + MemorizedNpc mn = memorizedNpcs.get(npc.getIndex()); + if (mn != null) { - if (WildcardMatcher.matches(highlight, npcName)) + String npcName = npc.getName(); + if (npcName != null) { - memorizeNpc(npc); - highlightedNpcs.add(npc); - spawnedNpcsThisTick.add(npc); - break; + mn.getNpcNames().add(npcName); } } } @@ -428,12 +429,59 @@ public class NpcIndicatorsPlugin extends Plugin return new WorldPoint(currWP.getX() - dx, currWP.getY() - dy, currWP.getPlane()); } + private void highlightNpcIfMatch(final NPC npc) + { + if (npcTags.contains(npc.getIndex())) + { + memorizeNpc(npc); + highlightedNpcs.add(npc); + return; + } + + final String npcName = npc.getName(); + if (npcName != null) + { + for (String highlight : highlights) + { + if (WildcardMatcher.matches(highlight, npcName)) + { + memorizeNpc(npc); + highlightedNpcs.add(npc); + return; + } + } + } + + highlightedNpcs.remove(npc); + } + private void memorizeNpc(NPC npc) { final int npcIndex = npc.getIndex(); memorizedNpcs.putIfAbsent(npcIndex, new MemorizedNpc(npc)); } + private boolean isNpcMemorizationUnnecessary(final MemorizedNpc mn) + { + if (npcTags.contains(mn.getNpcIndex())) + { + return false; + } + + for (String npcName : mn.getNpcNames()) + { + for (String highlight : highlights) + { + if (WildcardMatcher.matches(highlight, npcName)) + { + return false; + } + } + } + + return true; + } + private void removeOldHighlightedRespawns() { deadNpcsToDisplay.values().removeIf(x -> x.getDiedOnTick() + x.getRespawnTime() <= client.getTickCount() + 1); @@ -464,34 +512,21 @@ public class NpcIndicatorsPlugin extends Plugin return; } - outer: + Iterator> it = memorizedNpcs.entrySet().iterator(); + while (it.hasNext()) + { + MemorizedNpc mn = it.next().getValue(); + + if (isNpcMemorizationUnnecessary(mn)) + { + deadNpcsToDisplay.remove(mn.getNpcIndex()); + it.remove(); + } + } + for (NPC npc : client.getNpcs()) { - final String npcName = npc.getName(); - - if (npcName == null) - { - continue; - } - - if (npcTags.contains(npc.getIndex())) - { - highlightedNpcs.add(npc); - continue; - } - - for (String highlight : highlights) - { - if (WildcardMatcher.matches(highlight, npcName)) - { - memorizeNpc(npc); - highlightedNpcs.add(npc); - continue outer; - } - } - - // NPC is not highlighted - memorizedNpcs.remove(npc.getIndex()); + highlightNpcIfMatch(npc); } } @@ -524,7 +559,7 @@ public class NpcIndicatorsPlugin extends Plugin if (!mn.getPossibleRespawnLocations().isEmpty()) { - log.debug("Starting {} tick countdown for {}", mn.getRespawnTime(), mn.getNpcName()); + log.debug("Starting {} tick countdown for {}", mn.getRespawnTime(), mn.getNpcNames().iterator().next()); deadNpcsToDisplay.put(mn.getNpcIndex(), mn); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/MemorizedNPC.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/MemorizedNPC.java new file mode 100644 index 0000000000..4a746e63db --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/MemorizedNPC.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019, GeChallengeM + * 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.npcstatus; + +import java.awt.Color; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.NPC; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.Actor; + +@Getter +class MemorizedNPC +{ + private NPC npc; + private int npcIndex; + private String npcName; + private int attackSpeed; + @Setter + private int combatTimerEnd; + @Setter + private int timeLeft; + @Setter + private int flinchTimerEnd; + @Setter + private Status status; + @Setter + private WorldArea lastnpcarea; + @Setter + private Actor lastinteracted; + @Setter + private int lastspotanimation; + + MemorizedNPC(NPC npc, int attackSpeed, WorldArea worldArea) + { + this.npc = npc; + this.npcIndex = npc.getIndex(); + this.npcName = npc.getName(); + this.attackSpeed = attackSpeed; + this.combatTimerEnd = -1; + this.flinchTimerEnd = -1; + this.timeLeft = 0; + this.status = Status.OUT_OF_COMBAT; + this.lastnpcarea = worldArea; + this.lastinteracted = null; + this.lastspotanimation = -1; + } + + @Getter + @AllArgsConstructor + enum Status + { + FLINCHING("Flinching", Color.GREEN), + IN_COMBAT_DELAY("In Combat Delay", Color.ORANGE), + IN_COMBAT("In Combat", Color.RED), + OUT_OF_COMBAT("Out of Combat", Color.BLUE); + + private String name; + private Color color; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusConfig.java new file mode 100644 index 0000000000..bf0495fae5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusConfig.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019, GeChallengeM + * 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.npcstatus; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("npcstatus") +public interface NpcStatusConfig extends Config +{ + @ConfigItem( + keyName = "AttackRange", + name = "NPC Attack range", + description = "The attack range of the NPC" + ) + default int getRange() + { + return 1; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusOverlay.java new file mode 100644 index 0000000000..7b948f24c0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusOverlay.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018, GeChallengeM + * 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.npcstatus; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Point; +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.OverlayUtil; + +public class NpcStatusOverlay extends Overlay +{ + private final Client client; + private final NpcStatusPlugin plugin; + + @Inject + NpcStatusOverlay(Client client, NpcStatusPlugin plugin) + { + this.client = client; + this.plugin = plugin; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + for (MemorizedNPC npc : plugin.getMemorizedNPCs()) + { + if (npc.getNpc().getInteracting() == null) + { + continue; + } + if (npc.getNpc().getInteracting() == client.getLocalPlayer() || client.getLocalPlayer().getInteracting() == npc.getNpc()) + { + switch (npc.getStatus()) + { + case FLINCHING: + npc.setTimeLeft(Math.max(0, npc.getFlinchTimerEnd() - client.getTickCount())); + break; + case IN_COMBAT_DELAY: + npc.setTimeLeft(Math.max(0, npc.getCombatTimerEnd() - client.getTickCount() - 7)); + break; + case IN_COMBAT: + npc.setTimeLeft(Math.max(0, npc.getCombatTimerEnd() - client.getTickCount())); + break; + case OUT_OF_COMBAT: + default: + npc.setTimeLeft(0); + break; + } + + Point textLocation = npc.getNpc().getCanvasTextLocation(graphics, Integer.toString(npc.getTimeLeft()), npc.getNpc().getLogicalHeight() + 40); + + if (textLocation != null) + { + OverlayUtil.renderTextLocation(graphics, textLocation, Integer.toString(npc.getTimeLeft()), npc.getStatus().getColor()); + } + } + } + return null; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusPlugin.java new file mode 100644 index 0000000000..0f1a59a17a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusPlugin.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2019, GeChallengeM + * 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.npcstatus; + +import com.google.inject.Provides; +import java.time.Instant; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.GraphicID; +import net.runelite.api.Hitsplat; +import net.runelite.api.NPC; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.HitsplatApplied; +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.ItemManager; +import net.runelite.client.game.NPCManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +@Slf4j +@PluginDescriptor( + name = "NPC Status Timer", + description = "Adds a timer on NPC's for their attacks and flinching.", + tags = {"flinch", "npc"}, + enabledByDefault = false +) +public class NpcStatusPlugin extends Plugin +{ + @Getter(AccessLevel.PACKAGE) + private final Set memorizedNPCs = new HashSet<>(); + @Inject + private Client client; + @Inject + private OverlayManager overlayManager; + @Inject + private ItemManager itemManager; + @Inject + private NPCManager npcManager; + @Inject + private NpcStatusConfig config; + @Inject + private NpcStatusOverlay npcStatusOverlay; + @Getter(AccessLevel.PACKAGE) + private Instant lastTickUpdate; + private WorldArea lastPlayerLocation; + + @Provides + NpcStatusConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(NpcStatusConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(npcStatusOverlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(npcStatusOverlay); + memorizedNPCs.clear(); + } + + @Subscribe + public void onNpcSpawned(NpcSpawned npcSpawned) + { + final NPC npc = npcSpawned.getNpc(); + final String npcName = npc.getName(); + + if (npcName == null || !Arrays.asList(npc.getDefinition().getActions()).contains("Attack")) + { + return; + } + memorizedNPCs.add(new MemorizedNPC(npc, npcManager.getAttackSpeed(npc.getId()), npc.getWorldArea())); + } + + @Subscribe + public void onNpcDespawned(NpcDespawned npcDespawned) + { + final NPC npc = npcDespawned.getNpc(); + memorizedNPCs.removeIf(c -> c.getNpc() == npc); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGIN_SCREEN || + event.getGameState() == GameState.HOPPING) + { + memorizedNPCs.clear(); + } + } + + @Subscribe + public void onHitsplatApplied(HitsplatApplied event) + { + if (event.getActor().getInteracting() != client.getLocalPlayer()) + { + return; + } + final Hitsplat hitsplat = event.getHitsplat(); + if (hitsplat.getHitsplatType() == Hitsplat.HitsplatType.DAMAGE || hitsplat.getHitsplatType() == Hitsplat.HitsplatType.BLOCK) + { + if (event.getActor() instanceof NPC) + { + for (MemorizedNPC mn : memorizedNPCs) + { + if (mn.getStatus() == MemorizedNPC.Status.OUT_OF_COMBAT || (mn.getStatus() == MemorizedNPC.Status.IN_COMBAT && mn.getCombatTimerEnd() - client.getTickCount() < 1) || mn.getLastinteracted() == null) + { + mn.setStatus(MemorizedNPC.Status.FLINCHING); + mn.setCombatTimerEnd(-1); + mn.setFlinchTimerEnd(client.getTickCount() + mn.getAttackSpeed() / 2 + 1); + } + } + } + } + } + + private void checkStatus() + { + for (MemorizedNPC npc : memorizedNPCs) + { + final int ATTACK_SPEED = npc.getAttackSpeed(); + final double CombatTime = npc.getCombatTimerEnd() - client.getTickCount(); + final double FlinchTime = npc.getFlinchTimerEnd() - client.getTickCount(); + if (npc.getNpc().getWorldArea() == null) + { + continue; + } + if (npc.getNpc().getInteracting() == client.getLocalPlayer()) + { + if (npc.getLastspotanimation() == GraphicID.SPLASH && npc.getNpc().getSpotAnimation() == GraphicID.SPLASH) //For splash flinching + { + npc.setLastspotanimation(-1); + if ((npc.getStatus() == MemorizedNPC.Status.OUT_OF_COMBAT ) || npc.getLastinteracted() == null) + { + npc.setStatus(MemorizedNPC.Status.FLINCHING); + npc.setCombatTimerEnd(-1); + npc.setFlinchTimerEnd(client.getTickCount() + ATTACK_SPEED / 2 + 1); + npc.setLastnpcarea(npc.getNpc().getWorldArea()); + npc.setLastinteracted(npc.getNpc().getInteracting()); + continue; + } + } + //Checks: will the NPC attack this tick? + if (((npc.getNpc().getWorldArea().canMelee(client, lastPlayerLocation) && config.getRange() == 1) //Separate mechanics for meleerange-only NPC's because they have extra collisiondata checks (fences etc.) and can't attack diagonally + || (lastPlayerLocation.hasLineOfSightTo(client, npc.getNpc().getWorldArea()) && npc.getNpc().getWorldArea().distanceTo(lastPlayerLocation) <= config.getRange() && config.getRange() > 1)) + && ((npc.getStatus() != MemorizedNPC.Status.FLINCHING && CombatTime < 9) || (npc.getStatus() == MemorizedNPC.Status.FLINCHING && FlinchTime < 2)) + && npc.getNpc().getAnimation() != -1 //Failsafe, attacking NPC's always have an animation. + && !(npc.getLastnpcarea().distanceTo(lastPlayerLocation) == 0 && npc.getLastnpcarea() != npc.getNpc().getWorldArea())) //Weird mechanic: NPC's can't attack on the tick they do a random move + { + npc.setCombatTimerEnd(client.getTickCount() + ATTACK_SPEED + 8); + npc.setStatus(MemorizedNPC.Status.IN_COMBAT_DELAY); + npc.setLastnpcarea(npc.getNpc().getWorldArea()); + npc.setLastspotanimation(npc.getNpc().getSpotAnimation()); + npc.setLastinteracted(npc.getNpc().getInteracting()); + continue; + } + } + switch (npc.getStatus()) + { + case IN_COMBAT: + if (CombatTime < 2) + { + npc.setStatus(MemorizedNPC.Status.OUT_OF_COMBAT); + } + break; + case IN_COMBAT_DELAY: + if (CombatTime < 9) + { + npc.setStatus(MemorizedNPC.Status.IN_COMBAT); + } + break; + case FLINCHING: + if (FlinchTime < 2) + { + npc.setStatus(MemorizedNPC.Status.IN_COMBAT); + npc.setCombatTimerEnd(client.getTickCount() + 8); + } + } + npc.setLastnpcarea(npc.getNpc().getWorldArea()); + npc.setLastspotanimation(npc.getNpc().getSpotAnimation()); + npc.setLastinteracted(npc.getNpc().getInteracting()); + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + lastTickUpdate = Instant.now(); + checkStatus(); + lastPlayerLocation = client.getLocalPlayer().getWorldArea(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java index 79dca36797..d54b21f7dd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java @@ -36,6 +36,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -66,6 +67,7 @@ import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.InteractingChanged; +import net.runelite.api.events.NpcCompositionChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.VarbitChanged; @@ -79,7 +81,6 @@ import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; import net.runelite.client.game.AsyncBufferedImage; @@ -215,11 +216,8 @@ public class SlayerPlugin extends Plugin @Inject private ChatClient chatClient; - @Inject - private EventBus eventBus; - @Getter(AccessLevel.PACKAGE) - private List highlightedTargets = new ArrayList<>(); + private final Set highlightedTargets = new HashSet<>(); @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) @@ -349,8 +347,17 @@ public class SlayerPlugin extends Plugin if (isTarget(npc, targetNames)) { highlightedTargets.add(npc); - NPCPresence newPresence = NPCPresence.buildPresence(npc); - // log.debug("New presence of " + newPresence.toString()); + } + } + + @Subscribe + public void onNpcCompositionChanged(NpcCompositionChanged event) + { + NPC npc = event.getNpc(); + + if (isTarget(npc, targetNames)) + { + highlightedTargets.add(npc); } } @@ -363,7 +370,6 @@ public class SlayerPlugin extends Plugin { NPCPresence lingeringPresence = NPCPresence.buildPresence(npc); lingeringPresences.add(lingeringPresence); - // log.debug("Presence of " + lingeringPresence.toString() + " now lingering"); } } @@ -583,8 +589,6 @@ public class SlayerPlugin extends Plugin streak = 1; break; case 1: - streak = Integer.parseInt(matches.get(0)); - break; case 3: streak = Integer.parseInt(matches.get(0)); break; @@ -665,29 +669,13 @@ public class SlayerPlugin extends Plugin // this is not the initial xp sent on login so these are new xp gains int gains = slayerExp - cachedXp; - //log.debug("Slayer xp drop received"); - - //StringBuilder debugString = new StringBuilder(); - // potential npcs to give xp drop are current highlighted npcs and the lingering presences - List potentialNPCs = new ArrayList<>(); - //debugString.append("Lingering presences {"); - for (NPCPresence presence : lingeringPresences) - { - potentialNPCs.add(presence); - // debugString.append(presence.toString()); - // debugString.append(", "); - } - //debugString.append("}\nCurrent presences {"); + List potentialNPCs = new ArrayList<>(lingeringPresences); for (NPC npc : highlightedTargets) { NPCPresence currentPresence = NPCPresence.buildPresence(npc); potentialNPCs.add(currentPresence); - // debugString.append(currentPresence.toString()); - // debugString.append(", "); } - //debugString.append("}"); - //log.debug(debugString.toString()); int killCount = estimateKillCount(potentialNPCs, gains); for (int i = 0; i < killCount; i++) @@ -906,8 +894,7 @@ public class SlayerPlugin extends Plugin if (task != null) { - task.getNpcIds().stream() - .forEach(targetIds::add); + targetIds.addAll(task.getNpcIds()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetClickboxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetClickboxOverlay.java index c5bd4f1130..12eeac7ead 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetClickboxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetClickboxOverlay.java @@ -30,7 +30,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Polygon; -import java.util.List; +import java.util.Set; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.NPC; @@ -71,7 +71,7 @@ public class TargetClickboxOverlay extends Overlay { if (config.highlightTargets()) { - List targets = plugin.getHighlightedTargets(); + Set targets = plugin.getHighlightedTargets(); for (NPC target : targets) { if (target == null || target.getName() == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetMinimapOverlay.java index 57615b2a10..ceb81e6cd2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetMinimapOverlay.java @@ -29,9 +29,8 @@ package net.runelite.client.plugins.slayer; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.util.List; +import java.util.Set; import javax.inject.Inject; -import net.runelite.api.Client; import net.runelite.api.NPC; import net.runelite.api.Point; import net.runelite.client.ui.overlay.Overlay; @@ -41,15 +40,12 @@ import net.runelite.client.ui.overlay.OverlayUtil; public class TargetMinimapOverlay extends Overlay { - - private final Client client; private final SlayerConfig config; private final SlayerPlugin plugin; @Inject - TargetMinimapOverlay(Client client, SlayerConfig config, SlayerPlugin plugin) + TargetMinimapOverlay(SlayerConfig config, SlayerPlugin plugin) { - this.client = client; this.config = config; this.plugin = plugin; setPosition(OverlayPosition.DYNAMIC); @@ -64,7 +60,7 @@ public class TargetMinimapOverlay extends Overlay return null; } - List targets = plugin.getHighlightedTargets(); + Set targets = plugin.getHighlightedTargets(); for (NPC target : targets) { if (target == null || target.getName() == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/RoomHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/RoomHandler.java index e67560663f..3615d58f6d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/RoomHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/RoomHandler.java @@ -1,17 +1,23 @@ package net.runelite.client.plugins.theatre; -import net.runelite.api.*; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.Iterator; +import java.util.Map; +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.Projectile; import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; import net.runelite.client.ui.overlay.OverlayUtil; -import java.awt.*; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -public abstract class RoomHandler +public abstract class RoomHandler { protected final Client client; @@ -29,7 +35,7 @@ public abstract class RoomHandler public abstract void onStop(); - protected void drawTile2(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) + protected void drawTile2(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); if (point.distanceTo(playerLocation) >= 32) @@ -71,14 +77,14 @@ public abstract class RoomHandler Point textLocation = Perspective.getCanvasTextLocation(client, graphics, projectilePoint, text, 0); if (textLocation != null) { - if (projectileId == 1607) + if (projectileId == 1607) { // range renderTextLocation(graphics, text, 17, Font.BOLD, new Color(57, 255, 20, 255), textLocation); - } + } else if (projectileId == 1606) { //mage renderTextLocation(graphics, text, 17, Font.BOLD, new Color(64, 224, 208, 255), textLocation); - } + } else { //Orb of death? i hope renderTextLocation(graphics, text, 20, Font.BOLD, Color.WHITE, textLocation); @@ -87,20 +93,26 @@ public abstract class RoomHandler } } - protected void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) + protected void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); if (point.distanceTo(playerLocation) >= 32) + { return; + } LocalPoint lp = LocalPoint.fromWorld(client, point); if (lp == null) + { return; + } Polygon poly = Perspective.getCanvasTilePoly(client, lp); if (poly == null) + { return; + } graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); graphics.setStroke(new BasicStroke(strokeWidth)); @@ -109,13 +121,15 @@ public abstract class RoomHandler graphics.fill(poly); } - protected void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) + protected void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, 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); @@ -143,26 +157,6 @@ public abstract class RoomHandler } } - protected List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) - { - List little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList(); - List big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); - - if (!includeUnder) - { - for (Iterator it = big.iterator(); it.hasNext(); ) - { - WorldPoint p = it.next(); - if (little.contains(p)) - { - it.remove(); - } - } - } - - return big; - } - protected String twoDigitString(long number) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConfig.java index 39a5cc7e41..bf9a5e5963 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConfig.java @@ -8,30 +8,15 @@ package net.runelite.client.plugins.theatre; +import java.awt.Color; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -import java.awt.*; @ConfigGroup("Theatre") public interface TheatreConfig extends Config { - enum NYLOCAS - { - NONE, - MAGE, - MELEE, - RANGER - } - - enum NYLOOPTION - { - NONE, - TILE, - TIMER - } - @ConfigItem( position = 0, keyName = "showMaidenBloodToss", @@ -39,7 +24,7 @@ public interface TheatreConfig extends Config description = "Displays the tile location where tossed blood will land.", group = "Maiden" ) - default boolean showMaidenBloodToss() + default boolean showMaidenBloodToss() { return true; } @@ -51,7 +36,19 @@ public interface TheatreConfig extends Config description = "Show the tiles that blood spawns will travel to.", group = "Maiden" ) - default boolean showMaidenBloodSpawns() + default boolean showMaidenBloodSpawns() + { + return true; + } + + @ConfigItem( + position = 2, + keyName = "showNyloFreezeHighlights", + name = "Show Nylo Freeze Highlights", + description = "Show when to freeze Nylos at maiden. Say n1,n2,s1,s2 in chat for it to register.", + group = "Maiden" + ) + default boolean showNyloFreezeHighlights() { return true; } @@ -63,7 +60,7 @@ public interface TheatreConfig extends Config description = "Displays Bloat's status (asleep, wake, and enrage) using color code.", group = "Bloat" ) - default boolean showBloatIndicator() + default boolean showBloatIndicator() { return true; } @@ -75,7 +72,7 @@ public interface TheatreConfig extends Config description = "Highlights the falling hands inside Bloat.", group = "Bloat" ) - default boolean showBloatHands() + default boolean showBloatHands() { return true; } @@ -87,8 +84,8 @@ public interface TheatreConfig extends Config description = "", group = "Bloat" ) - default boolean BloatFeetIndicatorRaveEdition() - { + default boolean BloatFeetIndicatorRaveEdition() + { return false; } @@ -135,45 +132,40 @@ public interface TheatreConfig extends Config description = "An overlay will appear that counts the amount of Nylocas in the room.", group = "Nylocas" ) - default boolean showNylocasAmount() + default boolean showNylocasAmount() { return true; } /** - @ConfigItem( - position = 8, - keyName = "showNylocasSpawns", - name = "Show Nylocas Pre-spawns", - description = "Know the contents of the next upcoming wave." - ) - default boolean showNylocasSpawns() - { - return true; - } - - @ConfigItem( - position = 9, - keyName = "highlightNyloRoles", - name = "Highlight Nylo Prespawns", - description = "Highlights the next upcoming wave based on role. FOR BEGINNERS" - ) - default NYLOCAS highlightNyloRoles() - { - return NYLOCAS.NONE; - } - - @ConfigItem( - position = 10, - keyName = "highlightNyloParents", - name = "Show Nylo Parents (Un-used)", - description = "Highlight the Nylocas that spawn outside the center." - ) - default boolean highlightNyloParents() - { - return true; - } - **/ + * @ConfigItem( position = 8, + * keyName = "showNylocasSpawns", + * name = "Show Nylocas Pre-spawns", + * description = "Know the contents of the next upcoming wave." + * ) + * default boolean showNylocasSpawns() + * { + * return true; + * } + * @ConfigItem( position = 9, + * keyName = "highlightNyloRoles", + * name = "Highlight Nylo Prespawns", + * description = "Highlights the next upcoming wave based on role. FOR BEGINNERS" + * ) + * default NYLOCAS highlightNyloRoles() + * { + * return NYLOCAS.NONE; + * } + * @ConfigItem( position = 10, + * keyName = "highlightNyloParents", + * name = "Show Nylo Parents (Un-used)", + * description = "Highlight the Nylocas that spawn outside the center." + * ) + * default boolean highlightNyloParents() + * { + * return true; + * } + **/ @ConfigItem( position = 11, @@ -218,7 +210,7 @@ public interface TheatreConfig extends Config description = "Marks the tiles of Sotetseg's maze while in the underworld.", group = "Sotetseg" ) - default boolean showSotetsegSolo() + default boolean showSotetsegSolo() { return true; } @@ -234,6 +226,7 @@ public interface TheatreConfig extends Config { return Color.WHITE; } + @ConfigItem( position = 15, keyName = "showXarpusHeals", @@ -302,10 +295,10 @@ public interface TheatreConfig extends Config group = "Verzik" ) default boolean VerzikTankTile() - { + { return false; } - + @ConfigItem( position = 22, keyName = "verzikrangeattacks", @@ -314,10 +307,10 @@ public interface TheatreConfig extends Config group = "Verzik" ) default boolean verzikRangeAttacks() - { - return true; + { + return true; } - + @ConfigItem( position = 23, keyName = "extratimers", @@ -329,7 +322,7 @@ public interface TheatreConfig extends Config { return false; } - + @ConfigItem( position = 24, keyName = "p1attacks", @@ -341,7 +334,7 @@ public interface TheatreConfig extends Config { return true; } - + @ConfigItem( position = 25, keyName = "p2attacks", @@ -353,7 +346,7 @@ public interface TheatreConfig extends Config { return true; } - + @ConfigItem( position = 26, keyName = "p3attacks", @@ -365,4 +358,19 @@ public interface TheatreConfig extends Config { return true; } + + enum NYLOCAS + { + NONE, + MAGE, + MELEE, + RANGER + } + + enum NYLOOPTION + { + NONE, + TILE, + TIMER + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConstant.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConstant.java index 90e47bd242..0724fb099e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConstant.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConstant.java @@ -1,6 +1,6 @@ package net.runelite.client.plugins.theatre; -public class TheatreConstant +public class TheatreConstant { public static final int MAIDEN_BLOOD_THROW = 1579; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreOverlay.java index 492e9a25c4..e4dc6c2683 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreOverlay.java @@ -8,28 +8,30 @@ package net.runelite.client.plugins.theatre; -import java.awt.*; -import java.util.*; +import java.awt.Dimension; +import java.awt.Graphics2D; import javax.inject.Inject; -import net.runelite.api.*; +import net.runelite.api.Client; +import net.runelite.client.graphics.ModelOutlineRenderer; 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; -public class TheatreOverlay extends Overlay +public class TheatreOverlay extends Overlay { - private final Client client; private final TheatrePlugin plugin; private final TheatreConfig config; + private final ModelOutlineRenderer modelOutline; @Inject - private TheatreOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) + private TheatreOverlay(Client client, TheatrePlugin plugin, TheatreConfig config, ModelOutlineRenderer modelOutline) { this.client = client; this.plugin = plugin; this.config = config; + this.modelOutline = modelOutline; setPosition(OverlayPosition.DYNAMIC); setPriority(OverlayPriority.HIGH); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java index 0fe357d9e3..5f975d675e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java @@ -9,32 +9,43 @@ package net.runelite.client.plugins.theatre; import com.google.inject.Provides; +import java.awt.Color; +import java.util.LinkedList; +import java.util.List; +import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import java.util.LinkedList; -import java.util.List; -import net.runelite.api.events.*; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.GroundObjectSpawned; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.ProjectileMoved; +import net.runelite.api.events.SpotAnimationChanged; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.graphics.ModelOutlineRenderer; +import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.theatre.rooms.BloatHandler; import net.runelite.client.plugins.theatre.rooms.MaidenHandler; import net.runelite.client.plugins.theatre.rooms.SotetsegHandler; import net.runelite.client.plugins.theatre.rooms.VerzikHandler; -import net.runelite.client.plugins.theatre.rooms.xarpus.XarpusHandler; import net.runelite.client.plugins.theatre.rooms.nylocas.NyloHandler; +import net.runelite.client.plugins.theatre.rooms.xarpus.XarpusHandler; import net.runelite.client.ui.overlay.OverlayManager; -import javax.inject.Inject; -import java.awt.*; - @PluginDescriptor( name = "Theatre of Blood", description = "All-in-one plugin for Theatre of Blood.", @@ -43,9 +54,9 @@ import java.awt.*; enabledByDefault = false ) -public class TheatrePlugin extends Plugin +@Slf4j +public class TheatrePlugin extends Plugin { - @Getter(AccessLevel.PUBLIC) @Setter(AccessLevel.PUBLIC) private TheatreRoom room; @@ -83,6 +94,9 @@ public class TheatrePlugin extends Plugin @Inject private TheatreConfig config; + @Inject + private ModelOutlineRenderer modelOutline; + @Provides TheatreConfig getConfig(ConfigManager configManager) { @@ -94,7 +108,7 @@ public class TheatrePlugin extends Plugin { room = TheatreRoom.UNKNOWN; - maidenHandler = new MaidenHandler(client, this, config); + maidenHandler = new MaidenHandler(client, this, config, modelOutline); bloatHandler = new BloatHandler(client, this, config); nyloHandler = new NyloHandler(client, this, config); sotetsegHandler = new SotetsegHandler(client, this, config); @@ -131,26 +145,47 @@ public class TheatrePlugin extends Plugin overlayManager.remove(overlay); } + @Subscribe + public void onSpotAnimationChanged(SpotAnimationChanged event) + { + if (maidenHandler != null) + { + maidenHandler.onSpotAnimationChanged(event); + } + } + @Subscribe public void onNpcSpawned(NpcSpawned event) { if (maidenHandler != null) + { maidenHandler.onNpcSpawned(event); + } if (bloatHandler != null) + { bloatHandler.onNpcSpawned(event); + } if (nyloHandler != null) + { nyloHandler.onNpcSpawned(event); + } if (sotetsegHandler != null) + { sotetsegHandler.onNpcSpawned(event); + } if (xarpusHandler != null) + { xarpusHandler.onNpcSpawned(event); + } if (verzikHandler != null) + { verzikHandler.onNpcSpawned(event); + } } @@ -158,19 +193,29 @@ public class TheatrePlugin extends Plugin public void onNpcDespawned(NpcDespawned event) { if (maidenHandler != null) + { maidenHandler.onNpcDespawned(event); + } if (bloatHandler != null) + { bloatHandler.onNpcDespawned(event); + } if (nyloHandler != null) + { nyloHandler.onNpcDespawned(event); + } if (sotetsegHandler != null) + { sotetsegHandler.onNpcDespawned(event); + } if (xarpusHandler != null) + { xarpusHandler.onNpcDespawned(event); + } } @@ -178,7 +223,18 @@ public class TheatrePlugin extends Plugin public void onAnimationChanged(AnimationChanged event) { if (verzikHandler != null) + { verzikHandler.onAnimationChanged(event); + } + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (maidenHandler != null) + { + maidenHandler.onChatMessage(event); + } } @Subscribe @@ -204,22 +260,34 @@ public class TheatrePlugin extends Plugin public void onGameTick(GameTick event) { if (maidenHandler != null) + { maidenHandler.onGameTick(); + } if (bloatHandler != null) + { bloatHandler.onGameTick(); + } if (nyloHandler != null) + { nyloHandler.onGameTick(); + } if (sotetsegHandler != null) + { sotetsegHandler.onGameTick(); + } if (xarpusHandler != null) + { xarpusHandler.onGameTick(); + } if (verzikHandler != null) + { verzikHandler.onGameTick(); + } if (widget == null) { @@ -315,27 +383,37 @@ public class TheatrePlugin extends Plugin public void onGroundObjectSpawned(GroundObjectSpawned event) { if (sotetsegHandler != null) + { sotetsegHandler.onGroundObjectSpawned(event); + } if (xarpusHandler != null) + { xarpusHandler.onGroundObjectSpawned(event); + } } @Subscribe public void onConfigChanged(ConfigChanged event) { if (nyloHandler != null) + { nyloHandler.onConfigChanged(); + } } @Subscribe public void onVarbitChanged(VarbitChanged event) { if (bloatHandler != null) + { bloatHandler.onVarbitChanged(event); + } if (xarpusHandler != null) + { xarpusHandler.onVarbitChanged(event); + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreRoom.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreRoom.java index e13635b13f..4da8512503 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreRoom.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreRoom.java @@ -1,6 +1,6 @@ package net.runelite.client.plugins.theatre; -public enum TheatreRoom +public enum TheatreRoom { MAIDEN, BLOAT, @@ -8,5 +8,5 @@ public enum TheatreRoom SOTETSEG, XARPUS, VERSIK, - UNKNOWN; + UNKNOWN } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java index 98e229a58b..b62b979012 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java @@ -1,42 +1,36 @@ package net.runelite.client.plugins.theatre.rooms; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.util.Random; import lombok.AccessLevel; import lombok.Getter; -import net.runelite.api.*; +import net.runelite.api.Client; +import net.runelite.api.GraphicsObject; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; import net.runelite.api.Point; +import net.runelite.api.Varbits; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.VarbitChanged; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.theatre.RoomHandler; import net.runelite.client.plugins.theatre.TheatreConfig; import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.plugins.theatre.TheatreRoom; -import net.runelite.client.plugins.theatre.RoomHandler; - -import java.awt.*; -import java.util.Random; public class BloatHandler extends RoomHandler { - public static enum BloatState - { - DOWN, - UP, - WARN; - } - + private int bloatTimer; @Getter(AccessLevel.PUBLIC) private NPC bloat; - private int counter; - - //My variables private boolean bloatFlag; - int bloatTimer; private Color color; - @Getter(AccessLevel.PUBLIC) private BloatState bloatState; @@ -49,7 +43,9 @@ public class BloatHandler extends RoomHandler public void onStart() { if (this.plugin.getRoom() == TheatreRoom.BLOAT) + { return; + } this.reset(); this.plugin.setRoom(TheatreRoom.BLOAT); @@ -106,8 +102,8 @@ public class BloatHandler extends RoomHandler WorldPoint point = WorldPoint.fromLocal(client, object.getLocation()); if (!config.BloatFeetIndicatorRaveEdition()) { - drawTile(graphics, point, new Color(36, 248, 229), 2, 255, 10); - } + drawTile(graphics, point, new Color(36, 248, 229), 2, 255, 10); + } else { drawTile(graphics, point, color, 2, 255, 10); @@ -120,15 +116,15 @@ public class BloatHandler extends RoomHandler if (config.showBloatTimer()) { final String tickCounter = String.valueOf(bloatTimer); - int secondConversion = (int)(bloatTimer * .6); + int secondConversion = (int) (bloatTimer * .6); if (bloat != null) { Point canvasPoint = bloat.getCanvasTextLocation(graphics, tickCounter, 60); - if (bloatTimer <= 37) + if (bloatTimer <= 37) { renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.WHITE, canvasPoint); - } - else + } + else { renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.RED, canvasPoint); } @@ -139,9 +135,9 @@ public class BloatHandler extends RoomHandler @Subscribe public void onVarbitChanged(VarbitChanged event) { - if (client.getVar(Varbits.BLOAT_DOOR) == 1) + if (client.getVar(Varbits.BLOAT_DOOR) == 1) { - if (!bloatFlag) + if (!bloatFlag) { bloatTimer = 0; bloatFlag = true; @@ -149,12 +145,12 @@ public class BloatHandler extends RoomHandler } } - public void onNpcSpawned(NpcSpawned event) + public void onNpcSpawned(NpcSpawned event) { NPC npc = event.getNpc(); int id = npc.getId(); - if (id == NpcID.PESTILENT_BLOAT) + if (id == NpcID.PESTILENT_BLOAT) { this.onStart(); bloatTimer = 0; @@ -162,12 +158,12 @@ public class BloatHandler extends RoomHandler } } - public void onNpcDespawned(NpcDespawned event) + public void onNpcDespawned(NpcDespawned event) { NPC npc = event.getNpc(); int id = npc.getId(); - if (id == NpcID.PESTILENT_BLOAT) + if (id == NpcID.PESTILENT_BLOAT) { this.onStop(); bloatTimer = 0; @@ -175,9 +171,9 @@ public class BloatHandler extends RoomHandler } } - public void onGameTick() + public void onGameTick() { - if (plugin.getRoom() != TheatreRoom.BLOAT) + if (plugin.getRoom() != TheatreRoom.BLOAT) { return; } @@ -196,39 +192,46 @@ public class BloatHandler extends RoomHandler counter++; - if (bloat.getAnimation() == -1) + if (bloat.getAnimation() == -1) { bloatTimer++; counter = 0; if (bloat.getHealth() == 0) { bloatState = BloatState.DOWN; - } - else + } + else { bloatState = BloatState.UP; } - } - else + } + else { - if (25 < counter && counter < 35) + if (25 < counter && counter < 35) { bloatState = BloatState.WARN; - } - else if (counter < 26) + } + else if (counter < 26) { bloatTimer = 0; bloatState = BloatState.DOWN; - } - else if (bloat.getModelHeight() == 568) + } + else if (bloat.getModelHeight() == 568) { bloatTimer = 0; bloatState = BloatState.DOWN; - } - else + } + else { bloatState = BloatState.UP; } } } + + public enum BloatState + { + DOWN, + UP, + WARN + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/MaidenHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/MaidenHandler.java index 5c926e127b..4f109e80c6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/MaidenHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/MaidenHandler.java @@ -1,162 +1,298 @@ package net.runelite.client.plugins.theatre.rooms; -import lombok.AccessLevel; -import lombok.Getter; +import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GraphicsObject; import net.runelite.api.NPC; -import net.runelite.api.NpcID; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ChatMessage; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.SpotAnimationChanged; +import net.runelite.client.graphics.ModelOutlineRenderer; import net.runelite.client.plugins.theatre.RoomHandler; import net.runelite.client.plugins.theatre.TheatreConfig; import net.runelite.client.plugins.theatre.TheatreConstant; import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.plugins.theatre.TheatreRoom; +import net.runelite.client.util.Text; -import java.awt.*; -import java.util.ArrayList; -import java.util.List; - -public class MaidenHandler extends RoomHandler +@Slf4j +public class MaidenHandler extends RoomHandler { - - @Getter(AccessLevel.PACKAGE) + private static final ImmutableSet N1 = ImmutableSet.of( + new WorldPoint(3182, 4457, 0), + new WorldPoint(3174, 4457, 0) + ); + private static final ImmutableSet N2 = ImmutableSet.of( + new WorldPoint(3178, 4457, 0), + new WorldPoint(3186, 4455, 0), + new WorldPoint(3186, 4457, 0) + ); + private static final ImmutableSet S1 = ImmutableSet.of( + new WorldPoint(3174, 4437, 0), + new WorldPoint(3182, 4437, 0) + ); + private static final ImmutableSet S2 = ImmutableSet.of( + new WorldPoint(3186, 4439, 0), + new WorldPoint(3186, 4437, 0), + new WorldPoint(3178, 4437, 0) + ); + private static final ImmutableSet FREEZEANIMS = ImmutableSet.of( + 361, + 363, + 367, + 369 + ); + private static final Color TRANSPARENT = new Color(0, 0, 0, 0); + private static final Color FREEZE = new Color(0, 226, 255, 255); private List bloodThrows = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) private List bloodSpawns = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) private List bloodSpawnLocation = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) private List bloodSpawnTarget = new ArrayList<>(); - + private NPC maiden; + private String nyloCall = "n1"; + private Set nylos = new HashSet<>(); private List healers = new ArrayList<>(); private int healerCount = 0; private int wave = 1; private long startTime = 0; + private ModelOutlineRenderer modelOutline; - public MaidenHandler(Client client, TheatrePlugin plugin, TheatreConfig config) + public MaidenHandler(Client client, TheatrePlugin plugin, TheatreConfig config, ModelOutlineRenderer modelOutline) { super(client, plugin, config); + this.modelOutline = modelOutline; } @Override - public void onStart() + public void onStart() { if (this.plugin.getRoom() == TheatreRoom.MAIDEN) + { return; - + } this.reset(); - this.plugin.setRoom(TheatreRoom.MAIDEN); this.startTime = System.currentTimeMillis(); - System.out.println("Starting Maiden Room"); + log.debug("Starting Maiden Room"); } @Override - public void onStop() + public void onStop() { this.reset(); this.plugin.setRoom(TheatreRoom.UNKNOWN); - System.out.println("Stopping Maiden Room"); + log.debug("Stopping Maiden Room"); } - public void reset() + public void reset() { this.bloodThrows.clear(); this.bloodSpawns.clear(); this.bloodSpawnLocation.clear(); this.bloodSpawnTarget.clear(); - this.healers.clear(); this.healerCount = 0; this.startTime = -1; this.wave = 1; } - public void render(Graphics2D graphics) + public void render(Graphics2D graphics) { - if (config.showMaidenBloodToss()) + for (Nylos nylo : nylos) { - for (WorldPoint point : bloodThrows) + if (nylo.getNpc() == null || nylo.getNpc().getId() == -1) + { + continue; + } + + final String location = nylo.getSpawnLocation().getName(); + + if (location.equals(nyloCall)) + { + Color color = Color.WHITE; + int width = 4; + + if (nylo.getNpc().getWorldArea().distanceTo(maiden.getWorldArea()) <= 3) + { + color = FREEZE; + width = 8; + } + + modelOutline.drawOutline(nylo.getNpc(), width, color, TRANSPARENT); + } + } + + if (config.showMaidenBloodToss()) + { + for (WorldPoint point : bloodThrows) { drawTile(graphics, point, new Color(36, 248, 229), 2, 150, 10); } } - if (config.showMaidenBloodSpawns()) + if (config.showMaidenBloodSpawns()) { - for (WorldPoint point : bloodSpawnLocation) + for (WorldPoint point : bloodSpawnLocation) { drawTile(graphics, point, new Color(36, 248, 229), 2, 180, 20); } - for (WorldPoint point : bloodSpawnTarget) + for (WorldPoint point : bloodSpawnTarget) { drawTile(graphics, point, new Color(36, 248, 229), 1, 120, 10); } } } - public void onNpcSpawned(NpcSpawned event) + public void onSpotAnimationChanged(SpotAnimationChanged event) { - NPC npc = event.getNpc(); - String name = npc.getName(); - int id = npc.getId(); + if (event.getActor() instanceof NPC) + { + NPC npc = (NPC) event.getActor(); - if (npc.getName() != null && name.equals("The Maiden of Sugadinti")) - { - this.onStart(); - } - else if (plugin.getRoom() == TheatreRoom.MAIDEN) - { - if (id == NpcID.BLOOD_SPAWN) + if (npc.getId() != 8366) { - if (!bloodSpawns.contains(npc)) - bloodSpawns.add(npc); - } - else if (name != null && name.equalsIgnoreCase("Nylocas Matomenos")) + return; + } + + int anim = npc.getSpotAnimation(); + + if (FREEZEANIMS.contains(anim)) { - this.healers.add(npc); + nylos.removeIf(c -> c.getNpc() == npc); } } } - public void onNpcDespawned(NpcDespawned event) + public void onNpcSpawned(NpcSpawned event) { NPC npc = event.getNpc(); - String name = npc.getName(); - int id = npc.getId(); - if (npc.getName() != null && name.equals("The Maiden of Sugadinti")) - { - this.onStop(); - } - else if (plugin.getRoom() == TheatreRoom.MAIDEN) - { - if (id == NpcID.BLOOD_SPAWN) - { - bloodSpawns.remove(npc); - } - } - } - - public void onGameTick() - { - if (plugin.getRoom() != TheatreRoom.MAIDEN) + if (npc.getName() == null) { return; } - bloodThrows.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) + switch (npc.getName()) { - if (o.getId() == TheatreConstant.MAIDEN_BLOOD_THROW) + case "The Maiden of Sugadinti": + this.onStart(); + maiden = npc; + break; + case "Nylocas Matomenos": + if (!config.showNyloFreezeHighlights()) + { + return; + } + + this.healers.add(npc); + + WorldPoint wp = WorldPoint.fromLocalInstance(client, npc.getLocalLocation()); + + if (N1.contains(wp)) + { + addNylo(npc, Nylos.SpawnLocation.N1); + } + if (N2.contains(wp)) + { + addNylo(npc, Nylos.SpawnLocation.N2); + } + if (S1.contains(wp)) + { + addNylo(npc, Nylos.SpawnLocation.S1); + } + if (S2.contains(wp)) + { + addNylo(npc, Nylos.SpawnLocation.S2); + } + if (!N1.contains(wp) && !N2.contains(wp) && !S1.contains(wp) && !S2.contains(wp)) + { + log.debug("------------------------"); + log.debug("No World Points Matched"); + log.debug("Dumping Location"); + log.debug("Instance Loc: " + wp); + log.debug("------------------------"); + } + break; + case "Blood spawn": + if (!bloodSpawns.contains(npc)) + { + bloodSpawns.add(npc); + } + break; + } + } + + public void onChatMessage(ChatMessage event) + { + if (event.getSender() != null && !event.getSender().equals(client.getLocalPlayer().getName())) + { + return; + } + + String msg = Text.standardize(event.getMessageNode().getValue()); + + switch (msg) + { + case "n1": + case "n2": + case "s1": + case "s2": + nyloCall = msg; + break; + } + } + + public void onNpcDespawned(NpcDespawned event) + { + NPC npc = event.getNpc(); + + if (npc.getName() == null) + { + return; + } + + switch (npc.getName()) + { + case "The Maiden of Sugadinti": + this.onStop(); + break; + case "Blood Spawn": + bloodSpawns.remove(npc); + break; + } + } + + public void onGameTick() + { + if (plugin.getRoom() != TheatreRoom.MAIDEN) + { + return; + } + + if (!nylos.isEmpty()) + { + for (Nylos nylo : nylos) + { + nylos.removeIf(c -> c.getNpc().getId() == -1); + } + } + + bloodThrows.clear(); + + for (GraphicsObject o : client.getGraphicsObjects()) + { + if (o.getId() == TheatreConstant.MAIDEN_BLOOD_THROW) { bloodThrows.add(WorldPoint.fromLocal(client, o.getLocation())); } @@ -164,12 +300,13 @@ public class MaidenHandler extends RoomHandler bloodSpawnLocation = new ArrayList<>(bloodSpawnTarget); bloodSpawnTarget.clear(); - for (NPC spawn : bloodSpawns) + + for (NPC spawn : bloodSpawns) { bloodSpawnTarget.add(spawn.getWorldLocation()); } - if (this.healerCount != this.healers.size()) + if (this.healerCount != this.healers.size()) { this.healerCount = this.healers.size(); @@ -181,7 +318,15 @@ public class MaidenHandler extends RoomHandler int percentage = 70 - (20 * ((wave++) - 1)); if (config.extraTimers()) - this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Maiden of Sugadinti - " + percentage + "%' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + { + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Maiden of Sugadinti - " + percentage + "%' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } } } + + + private void addNylo(NPC npc, Nylos.SpawnLocation spawnLocation) + { + nylos.add(new Nylos(npc, spawnLocation)); + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/Nylos.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/Nylos.java new file mode 100644 index 0000000000..53469f3fe4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/Nylos.java @@ -0,0 +1,36 @@ +package net.runelite.client.plugins.theatre.rooms; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.NPC; + +class Nylos +{ + @Getter + private NPC npc; + @Getter + private int npcIndex; + @Getter + @Setter + private SpawnLocation spawnLocation; + + Nylos(NPC npc, SpawnLocation spawnLocation) + { + this.npc = npc; + this.npcIndex = npc.getIndex(); + this.spawnLocation = spawnLocation; + } + + @Getter + @AllArgsConstructor + enum SpawnLocation + { + N1("n1"), + N2("n2"), + S1("s1"), + S2("s2"); + + private String name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java index 03c706c154..13551b9ec4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java @@ -1,9 +1,23 @@ package net.runelite.client.plugins.theatre.rooms; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import lombok.AccessLevel; import lombok.Getter; -import net.runelite.api.*; +import net.runelite.api.Client; +import net.runelite.api.GroundObject; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; import net.runelite.api.Point; +import net.runelite.api.Projectile; +import net.runelite.api.Tile; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.NpcDespawned; @@ -16,33 +30,24 @@ import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.plugins.theatre.TheatreRoom; import net.runelite.client.ui.overlay.OverlayUtil; -import java.awt.*; -import java.util.*; -import java.util.List; - public class SotetsegHandler extends RoomHandler { @Getter(AccessLevel.PUBLIC) private final Map redTiles = new LinkedHashMap<>(); - + //My variables + private int playerX; + private int playerY; @Getter(AccessLevel.PUBLIC) private List redOverworld = new ArrayList<>(); - private List blackOverworld = new ArrayList<>(); - private List blackUnderworld = new ArrayList<>(); - private List redUnderworld = new ArrayList<>(); - private List gridPath = new ArrayList<>(); - - //My variables - int playerX; - int playerY; private Map soteyProjectiles = new HashMap<>(); private NPC npc; private long startTime = 0; + public SotetsegHandler(Client client, TheatrePlugin plugin, TheatreConfig config) { super(client, plugin, config); @@ -52,7 +57,9 @@ public class SotetsegHandler extends RoomHandler public void onStart() { if (this.plugin.getRoom() == TheatreRoom.SOTETSEG) + { return; + } this.reset(); this.plugin.setRoom(TheatreRoom.SOTETSEG); @@ -125,68 +132,16 @@ public class SotetsegHandler extends RoomHandler String countdownStr; if (id == 1607) { - countdownStr = "R " + String.valueOf(ticksRemaining); + countdownStr = "R " + ticksRemaining; } else { - countdownStr = "M " + String.valueOf(ticksRemaining); + countdownStr = "M " + ticksRemaining; } projectileMap.put(p, countdownStr); } renderProjectiles(graphics, projectileMap); - //Legacy code from yuri, works great but shows all projectiles not just ones targetting local player - /** - for (Projectile projectile : client.getProjectiles()) - { - int id = projectile.getId(); - - String name = null; - Color color = null; - - double millis = projectile.getRemainingCycles(); - double ticks = millis / 60; // 10 millis per cycle, 0.6 ticks per second, 10/0.6 = 60 - double round = Math.round(ticks * 10d) / 10d; - if (id == TheatreConstant.SOTETSEG_BOMB) - { - name = "" + round; - color = Color.WHITE; - } - else if (id == TheatreConstant.SOTETSEG_MAGE) - { - - name = "" + round; - color = new Color(64, 224, 208, 255); - } - else if (id == TheatreConstant.SOTETSEG_RANGE) - { - name = "" + round; - color = new Color(57, 255, 20, 255); - } - - if (name != null) - { - int x = (int) projectile.getX(); - int y = (int) projectile.getY(); - - LocalPoint point = new LocalPoint(x, y); - Point loc = Perspective.getCanvasTextLocation(client, graphics, point, name, 0); - - if (loc != null) - { - if (id == TheatreConstant.SOTETSEG_BOMB) - { - graphics.setFont(new Font("Arial", Font.BOLD, 20)); - } - else - { - graphics.setFont(new Font("Arial", Font.BOLD, 17)); - } - - OverlayUtil.renderTextLocation(graphics, loc, name, color); - } - } - }**/ } } @@ -242,12 +197,16 @@ public class SotetsegHandler extends RoomHandler if (t.getPlane() == 0) { if (!blackOverworld.contains(p)) + { blackOverworld.add(p); + } } else { if (!blackUnderworld.contains(p)) + { blackUnderworld.add(p); + } } } @@ -265,7 +224,9 @@ public class SotetsegHandler extends RoomHandler else { if (!redUnderworld.contains(p)) + { redUnderworld.add(p); + } } } } @@ -282,19 +243,10 @@ public class SotetsegHandler extends RoomHandler playerY = client.getLocalPlayer().getLocalLocation().getY(); - - //Remove projectiles that are about to die if (!soteyProjectiles.isEmpty()) { - for (Iterator it = soteyProjectiles.keySet().iterator(); it.hasNext(); ) - { - Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { - it.remove(); - } - } + soteyProjectiles.keySet().removeIf(p -> p.getRemainingCycles() < 1); } boolean sotetsegFighting = false; @@ -338,7 +290,7 @@ public class SotetsegHandler extends RoomHandler WorldPoint pW = new WorldPoint(p.getX() - 1, p.getY(), p.getPlane()); if (!((redUnderworld.contains(pN) && redUnderworld.contains(pS)) || - (redUnderworld.contains(pE) && redUnderworld.contains(pW)))) + (redUnderworld.contains(pE) && redUnderworld.contains(pW)))) { gridPath.add(new Point(p.getX() - minX, p.getY() - minY)); if (!messageSent) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/VerzikHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/VerzikHandler.java index 7b02a32106..0f92345fa4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/VerzikHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/VerzikHandler.java @@ -1,5 +1,12 @@ package net.runelite.client.plugins.theatre.rooms; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.Actor; @@ -22,38 +29,26 @@ import net.runelite.client.plugins.theatre.TheatreConfig; import net.runelite.client.plugins.theatre.TheatreConstant; import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.plugins.theatre.TheatreRoom; -import java.awt.*; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class VerzikHandler extends RoomHandler { @Getter(AccessLevel.PACKAGE) private final Map Verzik_RangeProjectiles = new HashMap<>(); - + //My variables + private int redCrabsTimer; @Getter(AccessLevel.PUBLIC) private int versikCounter = 0; private int attacksLeft = 0; - @Getter(AccessLevel.PUBLIC) private NPC npc; - private int lastId = -1; - private int autosSinceYellows; private int yellows; - private boolean tornados; - private int attackTick = -1; - private long startTime = 0; - //My variables - int redCrabsTimer; - public VerzikHandler(Client client, TheatrePlugin plugin, TheatreConfig config) { super(client, plugin, config); @@ -63,7 +58,9 @@ public class VerzikHandler extends RoomHandler public void onStart() { if (this.plugin.getRoom() == TheatreRoom.VERSIK) + { return; + } this.reset(); this.plugin.setRoom(TheatreRoom.VERSIK); @@ -117,10 +114,10 @@ public class VerzikHandler extends RoomHandler if (this.versikCounter >= 0) { String str = Integer.toString(versikCounter); - + LocalPoint lp = npc.getLocalLocation(); Point point = Perspective.getCanvasTextLocation(client, graphics, lp, str, 0); - + renderTextLocation(graphics, str, 20, Font.BOLD, Color.CYAN, point); } } @@ -141,19 +138,6 @@ public class VerzikHandler extends RoomHandler } } -/* - if (npc.getAnimation() == 8117){ - if (this.redCrabsTimer > 0){ - String str = Integer.toString(redCrabsTimer); - - LocalPoint lp = npc.getLocalLocation(); - Point point = Perspective.getCanvasTextLocation(client, graphics, lp, str, 60); - renderTextLocation(graphics, str, 15, Font.BOLD, Color.WHITE, point); - } - - - }*/ - else if (id == TheatreConstant.VERZIK_ID_P3) { if (config.p3attacks()) @@ -162,10 +146,10 @@ public class VerzikHandler extends RoomHandler if (versikCounter > 0 && versikCounter < 8) { String str = Math.max(versikCounter, 0) + "";// + " | " + model.getModelHeight();// + " | " + model.getRadius(); - + LocalPoint lp = npc.getLocalLocation(); Point point = Perspective.getCanvasTextLocation(client, graphics, lp, str, 0); - + renderTextLocation(graphics, str, 15, Font.BOLD, Color.WHITE, point); } } @@ -210,16 +194,22 @@ public class VerzikHandler extends RoomHandler for (NPC npc : client.getNpcs()) { if (npc.getName() == null) + { continue; + } Pattern p = Pattern.compile("Nylocas (Hagios|Toxobolos|Ischyros)"); Matcher m = p.matcher(npc.getName()); if (!m.matches()) + { continue; + } Actor target = npc.getInteracting(); if (target == null || target.getName() == null) + { continue; + } LocalPoint lp = npc.getLocalLocation(); Color color = local.getName().equals(target.getName()) ? Color.RED : Color.GREEN; @@ -231,15 +221,17 @@ public class VerzikHandler extends RoomHandler } } -public void onProjectileMoved(ProjectileMoved event) -{ - Projectile projectile = event.getProjectile(); - if (projectile.getId() == 1583) + + public void onProjectileMoved(ProjectileMoved event) { - WorldPoint p = WorldPoint.fromLocal(client, event.getPosition()); - Verzik_RangeProjectiles.put(projectile, p); + Projectile projectile = event.getProjectile(); + if (projectile.getId() == 1583) + { + WorldPoint p = WorldPoint.fromLocal(client, event.getPosition()); + Verzik_RangeProjectiles.put(projectile, p); + } } -} + public void onNpcSpawned(NpcSpawned event) { NPC npc = event.getNpc(); @@ -282,7 +274,9 @@ public void onProjectileMoved(ProjectileMoved event) Actor actor = event.getActor(); if (!(actor instanceof NPC)) + { return; + } NPC npc = (NPC) actor; int id = npc.getId(); @@ -325,29 +319,22 @@ public void onProjectileMoved(ProjectileMoved event) } if (!Verzik_RangeProjectiles.isEmpty()) { - for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext();) - { - Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { - it.remove(); - } - } + Verzik_RangeProjectiles.keySet().removeIf(p -> p.getRemainingCycles() < 1); } if (this.yellows == 0) { //if (this.autosSinceYellows > 0){ - for (GraphicsObject object : client.getGraphicsObjects()) + for (GraphicsObject object : client.getGraphicsObjects()) + { + if (object.getId() == TheatreConstant.GRAPHIC_ID_YELLOWS) { - if (object.getId() == TheatreConstant.GRAPHIC_ID_YELLOWS) - { - this.yellows = 14; + this.yellows = 14; // this.versikCounter = 22; - this.autosSinceYellows = 0; - System.out.println("Yellows have spawned."); - break; - } + this.autosSinceYellows = 0; + System.out.println("Yellows have spawned."); + break; } + } //} } else @@ -380,7 +367,9 @@ public void onProjectileMoved(ProjectileMoved event) } if (foundTornado && foundVerzik) + { break; + } } if (!foundVerzik) @@ -390,7 +379,9 @@ public void onProjectileMoved(ProjectileMoved event) } if (npc == null) + { return; + } int id = npc.getId(); @@ -410,7 +401,9 @@ public void onProjectileMoved(ProjectileMoved event) long minutes = seconds / 60L; seconds = seconds % 60; if (config.extraTimers()) - this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Final Challenge - Part 1' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + { + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Final Challenge - Part 1' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } } else if (id == TheatreConstant.VERZIK_ID_P2_TRANSFORM && this.startTime != 0) { @@ -424,7 +417,9 @@ public void onProjectileMoved(ProjectileMoved event) this.versikCounter = -1; this.attacksLeft = 9; if (config.extraTimers()) - this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Final Challenge - Part 2' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + { + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Final Challenge - Part 2' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } } } @@ -443,7 +438,9 @@ public void onProjectileMoved(ProjectileMoved event) { versikCounter--; if (versikCounter < 0) + { versikCounter = 0; + } } else if (id == TheatreConstant.VERZIK_ID_P3) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloHandler.java index 1e84e21eb6..4ff3c17ae7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloHandler.java @@ -1,5 +1,17 @@ package net.runelite.client.plugins.theatre.rooms.nylocas; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -18,41 +30,26 @@ import net.runelite.client.plugins.theatre.TheatreConstant; import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.plugins.theatre.TheatreRoom; -import java.awt.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class NyloHandler extends RoomHandler +public class NyloHandler extends RoomHandler { + public long startTime = 0L; + int startTick = 0; + ArrayList waveSpawns = new ArrayList(); + ArrayList waveAgros = new ArrayList(); @Getter(AccessLevel.PUBLIC) private Map pillars = new HashMap<>(); - @Getter(AccessLevel.PUBLIC) private Map spiders = new HashMap<>(); - @Getter @Setter private int wave = 0; - private NyloOverlay overlay = null; private NyloPredictor predictor = null; - private Point south = new Point(64, 41); private Point west = new Point(49, 56); private Point east = new Point(78, 56); - public long startTime = 0L; - public int startTick = 0; - - public ArrayList waveSpawns = new ArrayList(); - public ArrayList waveAgros = new ArrayList(); - public NyloHandler(Client client, TheatrePlugin plugin, TheatreConfig config) { super(client, plugin, config); @@ -62,7 +59,9 @@ public class NyloHandler extends RoomHandler public void onStart() { if (this.plugin.getRoom() == TheatreRoom.NYLOCAS) + { return; + } this.reset(); @@ -102,7 +101,9 @@ public class NyloHandler extends RoomHandler if (this.startTime != 0) { if (config.extraTimers()) - this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Nylocas - Waves' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + { + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Nylocas - Waves' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } } System.out.println("Stopping Nylocas Room"); } @@ -159,7 +160,7 @@ public class NyloHandler extends RoomHandler for (NPC npc : pillars.keySet()) { final int health = pillars.get(npc); - final String healthStr = String.valueOf(health) + "%"; + final String healthStr = health + "%"; WorldPoint p = npc.getWorldLocation(); LocalPoint lp = LocalPoint.fromWorld(client, p.getX() + 1, p.getY() + 1); @@ -203,45 +204,21 @@ public class NyloHandler extends RoomHandler Set toHighlight = new HashSet(); - /** - if (config.highlightNyloParents()) - { - for (NPC npc : new ArrayList(this.waveSpawns)) - { - try - { - if (npc.getHealthRatio() == 0 || npc.isDead()) - { - this.waveSpawns.remove(npc); - continue; - } - - if (!toHighlight.contains(npc)) - toHighlight.add(npc); - } - catch (Exception ex) - { - - } - } - }**/ - - if (config.highlightNyloAgros()) + if (config.highlightNyloAgros()) { for (NPC npc : new ArrayList(this.waveAgros)) { try { - if (npc.getHealthRatio() == 0 || npc.isDead()) + if (npc.getHealthRatio() == 0 || npc.isDead()) { this.waveAgros.remove(npc); continue; } - if (!toHighlight.contains(npc)) - toHighlight.add(npc); - } - catch (Exception ex) + toHighlight.add(npc); + } + catch (Exception ex) { } @@ -258,58 +235,25 @@ public class NyloHandler extends RoomHandler String name = npc.getName() != null ? npc.getName() : ""; if (name.contains("Hagios")) + { color = Color.CYAN; + } else if (name.contains("Toxobolos")) + { color = Color.GREEN; + } else + { color = Color.LIGHT_GRAY; + } renderPoly(graphics, color, objectClickbox); - } + } catch (Exception ex) { } } -/** - if (config.showNylocasSpawns() && predictor != null) - { - NyloPredictor.Wave nextWave = predictor.getNextWave(); - if (nextWave != null) - { - TheatreConfig.NYLOCAS mark = config.highlightNyloRoles(); - - String southStr = predictor.getSpawnStr(NyloPredictor.Spawn.SOUTH, nextWave); - if (southStr != null && south != null) - { - LocalPoint lp = LocalPoint.fromScene(south.getX(), south.getY()); - Point point = Perspective.getCanvasTextLocation(client, graphics, lp, southStr, 1); - Color color = mark != TheatreConfig.NYLOCAS.NONE ? (((southStr.contains("Mage") && mark == TheatreConfig.NYLOCAS.MAGE) || (southStr.contains("Range") && mark == TheatreConfig.NYLOCAS.RANGER) || (southStr.contains("Melee") && mark == TheatreConfig.NYLOCAS.MELEE)) ? Color.MAGENTA : Color.RED) : Color.RED; - renderTextLocation(graphics, southStr, 18, Font.BOLD, color, point); -// drawTile(graphics, WorldPoint.fromLocal(client, lp), new Color(0, 150, 200), 2, 150, 10); - } - - String westStr = predictor.getSpawnStr(NyloPredictor.Spawn.WEST, nextWave); - if (westStr != null && west != null) - { - LocalPoint lp = LocalPoint.fromScene(west.getX(), west.getY()); - Point point = Perspective.getCanvasTextLocation(client, graphics, lp, westStr, 1); - Color color = mark != TheatreConfig.NYLOCAS.NONE ? (((westStr.contains("Mage") && mark == TheatreConfig.NYLOCAS.MAGE) || (westStr.contains("Range") && mark == TheatreConfig.NYLOCAS.RANGER) || (westStr.contains("Melee") && mark == TheatreConfig.NYLOCAS.MELEE)) ? Color.MAGENTA : Color.RED) : Color.RED; - renderTextLocation(graphics, westStr, 18, Font.BOLD, color, point); -// drawTile(graphics, WorldPoint.fromLocal(client, lp), new Color(0, 150, 200), 2, 150, 10); - } - - String eastStr = predictor.getSpawnStr(NyloPredictor.Spawn.EAST, nextWave); - if (eastStr != null && east != null) - { - LocalPoint lp = LocalPoint.fromScene(east.getX(), east.getY()); - Point point = Perspective.getCanvasTextLocation(client, graphics, lp, eastStr, 1); - Color color = mark != TheatreConfig.NYLOCAS.NONE ? (((eastStr.contains("Mage") && mark == TheatreConfig.NYLOCAS.MAGE) || (eastStr.contains("Range") && mark == TheatreConfig.NYLOCAS.RANGER) || (eastStr.contains("Melee") && mark == TheatreConfig.NYLOCAS.MELEE)) ? Color.MAGENTA : Color.RED) : Color.RED; - renderTextLocation(graphics, eastStr, 18, Font.BOLD, color, point); -// drawTile(graphics, WorldPoint.fromLocal(client, lp), new Color(0, 150, 200), 2, 150, 10); - } - } - }**/ } public void onNpcSpawned(NpcSpawned event) @@ -351,15 +295,9 @@ public class NyloHandler extends RoomHandler NPC npc = event.getNpc(); int id = npc.getId(); - if (this.waveSpawns.contains(npc)) - { - this.waveSpawns.remove(npc); - } + this.waveSpawns.remove(npc); - if (this.waveAgros.contains(npc)) - { - this.waveAgros.remove(npc); - } + this.waveAgros.remove(npc); if (id == TheatreConstant.NPC_ID_NYLOCAS_PILLAR) { @@ -393,7 +331,7 @@ public class NyloHandler extends RoomHandler if (plugin.getRoom() != TheatreRoom.NYLOCAS) { return; - } + } else { boolean findPillar = false; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloOverlay.java index 0f3e4dd26d..9c57485f26 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloOverlay.java @@ -43,18 +43,17 @@ import net.runelite.client.ui.overlay.components.table.TableAlignment; import net.runelite.client.ui.overlay.components.table.TableComponent; import net.runelite.client.util.ColorUtil; -class NyloOverlay extends Overlay +class NyloOverlay extends Overlay { private final Client client; private final TheatrePlugin plugin; - private final TheatreConfig config; private final PanelComponent panelComponent = new PanelComponent(); private NyloHandler nylohandler; - public NyloOverlay(Client client, TheatrePlugin plugin, TheatreConfig config, NyloHandler nylohandler) + NyloOverlay(Client client, TheatrePlugin plugin, TheatreConfig config, NyloHandler nylohandler) { super(plugin); @@ -63,7 +62,6 @@ class NyloOverlay extends Overlay this.client = client; this.plugin = plugin; - this.config = config; this.nylohandler = nylohandler; getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Nylocas Overlay")); @@ -111,14 +109,14 @@ class NyloOverlay extends Overlay if (nyloCount > 12) { tableComponent.addRow("Total Nylocas:", ColorUtil.prependColorTag(nyloCount + " / 12", Color.RED)); - } + } else { tableComponent.addRow("Total Nylocas:", ColorUtil.prependColorTag(nyloCount + " / 12", Color.GREEN)); } - } - else + } + else { if (nyloCount > 24) { @@ -132,23 +130,6 @@ class NyloOverlay extends Overlay panelComponent.getChildren().add(tableComponent); - - /** - panelComponent.getChildren().add(LineComponent.builder() - .left("Ischyros:") - .right(Integer.toString(ischyros)) - .build()); - - panelComponent.getChildren().add(LineComponent.builder() - .left("Toxobolos:") - .right(Integer.toString(toxobolos)) - .build()); - - panelComponent.getChildren().add(LineComponent.builder() - .left("Hagios:") - .right(Integer.toString(hagios)) - .build()); - **/ return panelComponent.render(graphics); } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloPredictor.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloPredictor.java index 75042fa328..b9d3e19b44 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloPredictor.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloPredictor.java @@ -1,91 +1,19 @@ package net.runelite.client.plugins.theatre.rooms.nylocas; -import net.runelite.api.Client; -import net.runelite.api.NPC; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.events.NpcSpawned; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.events.NpcSpawned; public class NyloPredictor { - public enum NylocasType - { - MELEE_162, - RANGE_162, - MAGE_162, - MELEE_260, - RANGE_260, - MAGE_260; - } - - public enum Spawn - { - WEST, - SOUTH, - EAST; - } - - public static class Nylocas - { - - private NylocasType type; - private Spawn spawn; - - public Nylocas(NylocasType type, Spawn spawn) + private static final Wave[] NYLOCAS_WAVES = new Wave[] { - this.type = type; - this.spawn = spawn; - } - - public NylocasType getType() - { - return this.type; - } - - public Spawn getSpawn() - { - return this.spawn; - } - - @Override - public boolean equals(Object object) - { - if (object != null && (object instanceof Nylocas)) - { - Nylocas nylo = (Nylocas) object; - if (nylo.getType() == this.type && nylo.getSpawn() == this.spawn) - { - return true; - } - } - - return false; - } - } - - public static class Wave - { - - private Nylocas[] spawns; - - public Wave(Nylocas... nylocas) - { - this.spawns = nylocas; - } - - public Nylocas[] getSpawns() - { - return this.spawns; - } - } - - public static final Wave[] NYLOCAS_WAVES = new Wave[] - { new Wave(new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_162, Spawn.EAST)), new Wave(new Nylocas(NylocasType.MAGE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.EAST)), new Wave(new Nylocas(NylocasType.MELEE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)), @@ -117,15 +45,16 @@ public class NyloPredictor new Wave(new Nylocas(NylocasType.MELEE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_260, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.EAST), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)), new Wave(new Nylocas(NylocasType.RANGE_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_260, Spawn.EAST)), new Wave(new Nylocas(NylocasType.MELEE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.EAST), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)) - }; - + }; public Client client; - public NyloHandler handler; + int westBound = 50; + int eastBound = 77; + int southBound = 42; + private NyloHandler handler; + private Map currentSpawns = new HashMap(); + private int currentIndex = -1; - public Map currentSpawns = new HashMap(); - public int currentIndex = -1; - - public NyloPredictor(Client client, NyloHandler handler) + NyloPredictor(Client client, NyloHandler handler) { this.client = client; this.handler = handler; @@ -138,12 +67,6 @@ public class NyloPredictor this.currentIndex = -1; } - public int westBound = 50; - - public int eastBound = 77; - - public int southBound = 42; - public void onNpcSpawned(NpcSpawned event) { NPC npc = event.getNpc(); @@ -157,11 +80,11 @@ public class NyloPredictor if (x <= westBound) { spawn = Spawn.WEST; - } + } else if (x >= eastBound) { spawn = Spawn.EAST; - } + } else if (y <= southBound) { spawn = Spawn.SOUTH; @@ -175,11 +98,11 @@ public class NyloPredictor if (name.contains("Hagios")) { type = NylocasType.valueOf("MAGE_" + level); - } + } else if (name.contains("Toxobolos")) { type = NylocasType.valueOf("RANGE_" + level); - } + } else if (name.contains("Ischyros")) { type = NylocasType.valueOf("MELEE_" + level); @@ -213,7 +136,7 @@ public class NyloPredictor int index = queue.indexOf(nylocas); Nylocas hashed = queue.remove(index); npcs.put(currentSpawns.get(hashed), hashed); - } + } else { found = false; @@ -257,12 +180,14 @@ public class NyloPredictor for (NPC npc : client.getNpcs()) { if (npc.getHealthRatio() == 0) + { continue; + } if (npc.getName().equalsIgnoreCase("Nylocas Hagios")) { mage_level += npc.getCombatLevel(); mage_count += 1; - } + } else if (npc.getName().equalsIgnoreCase("Nylocas Toxobolos")) { range_level += npc.getCombatLevel(); @@ -300,7 +225,7 @@ public class NyloPredictor } } - public boolean isAgressive(NylocasType type, Spawn spawn, int wave) + private boolean isAgressive(NylocasType type, Spawn spawn, int wave) { if (wave == 0 && spawn == Spawn.WEST) { @@ -329,9 +254,13 @@ public class NyloPredictor else if (wave == 9) { if (spawn == Spawn.EAST && type == NylocasType.RANGE_162) + { return true; - else if (spawn == Spawn.WEST) - return true; + } + else + { + return spawn == Spawn.WEST; + } } else if (wave == 10 && (spawn == Spawn.EAST || spawn == Spawn.WEST)) { @@ -344,23 +273,35 @@ public class NyloPredictor else if (wave == 12) { if (spawn == Spawn.WEST && type == NylocasType.MAGE_162) + { return true; - else if (spawn == Spawn.EAST) - return true; + } + else + { + return spawn == Spawn.EAST; + } } else if (wave == 13) { if (spawn == Spawn.WEST && type == NylocasType.MELEE_162) + { return true; - else if (spawn == Spawn.EAST) - return true; + } + else + { + return spawn == Spawn.EAST; + } } else if (wave == 14) { if (spawn == Spawn.WEST && type == NylocasType.RANGE_162) + { return true; - else if (spawn == Spawn.EAST && type == NylocasType.MAGE_162) - return true; + } + else + { + return spawn == Spawn.EAST && type == NylocasType.MAGE_162; + } } else if (wave == 17 && spawn == Spawn.WEST) { @@ -405,17 +346,20 @@ public class NyloPredictor else if (wave == 28) { if (spawn == Spawn.EAST && type == NylocasType.RANGE_162) + { return true; - else if (spawn == Spawn.WEST && type == NylocasType.MELEE_162) - return true; + } + else + { + return spawn == Spawn.WEST && type == NylocasType.MELEE_162; + } } - else if (wave == 29 && spawn == Spawn.EAST) + else { - return true; + return wave == 29 && spawn == Spawn.EAST; } - return false; } public int getCurrentWave() @@ -487,4 +431,72 @@ public class NyloPredictor return types.length() > 0 ? types : null; } } + + public enum NylocasType + { + MELEE_162, + RANGE_162, + MAGE_162, + MELEE_260, + RANGE_260, + MAGE_260 + } + + public enum Spawn + { + WEST, + SOUTH, + EAST + } + + public static class Nylocas + { + + private NylocasType type; + private Spawn spawn; + + public Nylocas(NylocasType type, Spawn spawn) + { + this.type = type; + this.spawn = spawn; + } + + public NylocasType getType() + { + return this.type; + } + + public Spawn getSpawn() + { + return this.spawn; + } + + @Override + public boolean equals(Object object) + { + if (object != null && (object instanceof Nylocas)) + { + Nylocas nylo = (Nylocas) object; + return nylo.getType() == this.type && nylo.getSpawn() == this.spawn; + } + + return false; + } + } + + public static class Wave + { + + private Nylocas[] spawns; + + public Wave(Nylocas... nylocas) + { + this.spawns = nylocas; + } + + public Nylocas[] getSpawns() + { + return this.spawns; + } + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusCounter.java index 3b39af4640..2be0d90109 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusCounter.java @@ -22,10 +22,8 @@ public class XarpusCounter extends Overlay private final Client client; private final TheatrePlugin plugin; private final TheatreConfig config; - - private XarpusHandler xarpusHandler; - PanelComponent panelComponent = new PanelComponent(); + private XarpusHandler xarpusHandler; public XarpusCounter(Client client, TheatrePlugin plugin, TheatreConfig config, XarpusHandler xarpushandler) { @@ -51,13 +49,13 @@ public class XarpusCounter extends Overlay // Build overlay title panelComponent.getChildren().add(TitleComponent.builder() - .text(overlayTitle) - .color(Color.GREEN) - .build()); + .text(overlayTitle) + .color(Color.GREEN) + .build()); //Set the size of overlay panelComponent.setPreferredSize(new Dimension( - graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0 + graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0 )); TableComponent tableComponent = new TableComponent(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusHandler.java index f8395e14b4..d2c278806e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusHandler.java @@ -1,5 +1,13 @@ package net.runelite.client.plugins.theatre.rooms.xarpus; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; @@ -19,20 +27,13 @@ import net.runelite.client.plugins.theatre.TheatreConfig; import net.runelite.client.plugins.theatre.TheatreConstant; import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.plugins.theatre.TheatreRoom; -import java.awt.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; public class XarpusHandler extends RoomHandler { - private int previousTurn; - - private boolean staring; - private final Map exhumes = new HashMap<>(); - + private int previousTurn; + private boolean staring; private int ticksUntilShoot = 8; @Getter @@ -56,7 +57,9 @@ public class XarpusHandler extends RoomHandler public void onStart() { if (this.plugin.getRoom() == TheatreRoom.XARPUS) + { return; + } this.reset(); this.plugin.setRoom(TheatreRoom.XARPUS); @@ -102,7 +105,9 @@ public class XarpusHandler extends RoomHandler public void render(Graphics2D graphics) { if (npc == null) + { return; + } if (npc.getId() == NpcID.XARPUS_8340) //&& !staring&& config.showXarpusTick()) { @@ -111,13 +116,15 @@ public class XarpusHandler extends RoomHandler this.up = true; long elapsedTime = System.currentTimeMillis() - this.startTime; long seconds = elapsedTime / 1000L; - + long minutes = seconds / 60L; seconds = seconds % 60; - + this.ticksUntilShoot = 8; if (config.extraTimers()) - this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'Xarpus - Recovery' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + { + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'Xarpus - Recovery' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } } final String ticksLeftStr = String.valueOf(ticksUntilShoot); @@ -257,7 +264,9 @@ public class XarpusHandler extends RoomHandler long minutes = seconds / 60L; seconds = seconds % 60; if (config.extraTimers()) - this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'Xarpus - Acid' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + { + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'Xarpus - Acid' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } } ticksUntilShoot = 6; @@ -275,7 +284,7 @@ public class XarpusHandler extends RoomHandler if (staring) { ticksUntilShoot = 8; - } + } else { ticksUntilShoot = 4; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/RoomTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/RoomTimer.java index 9fb911a542..3a9c13252f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/RoomTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/RoomTimer.java @@ -1,18 +1,20 @@ package net.runelite.client.plugins.theatre.timers; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; import net.runelite.api.Client; +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import net.runelite.api.Player; import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.ui.overlay.Overlay; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; -import javax.inject.Inject; -import java.awt.*; -import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; -import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; public class RoomTimer extends Overlay { @@ -25,9 +27,9 @@ public class RoomTimer extends Overlay @Inject - public RoomTimer (Client client, TheatrePlugin plugin) + public RoomTimer(Client client, TheatrePlugin plugin) { - super (plugin); + super(plugin); setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); setPriority(OverlayPriority.HIGH); @@ -40,15 +42,17 @@ public class RoomTimer extends Overlay @Override - public Dimension render(Graphics2D graphics) + public Dimension render(Graphics2D graphics) { panelComponent.getChildren().clear(); Player local = client.getLocalPlayer(); if (local == null || local.getName() == null) + { return null; + } - switch (plugin.getRoom()) + switch (plugin.getRoom()) { case MAIDEN: plugin.getMaidenHandler().render(graphics); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/Timeable.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/Timeable.java index e19452b435..04c5a1a6c5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/Timeable.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/Timeable.java @@ -4,5 +4,5 @@ import java.util.HashMap; public interface Timeable { - public abstract HashMap getTimes(); + HashMap getTimes(); } \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java index 9b58f3eb2c..327886a637 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java @@ -112,13 +112,7 @@ public abstract class RSNPCMixin implements RSNPC { client.getCallbacks().post(new NpcDespawned(this)); } - } - - @FieldHook("definition") - @Inject - public void afterCompositionChanged(int idx) - { - if (this.getDefinition() != null && this.getId() != -1) + else if (this.getId() != -1) { client.getCallbacks().post(new NpcCompositionChanged(this)); }