diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounter.java new file mode 100644 index 0000000000..ef8a892c8e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounter.java @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2017, Devin French + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.combatcounter; + +import com.google.inject.Provides; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.Hitsplat; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.Player; +import net.runelite.api.Projectile; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.HitsplatApplied; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.kit.KitType; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.ui.overlay.OverlayManager; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@PluginDescriptor( + name = "[L] Tick Counter", + description = "Count the amount of perfect combat ticks performed by each player.", + tags = {"combat", "counter", "tick"}, + type = PluginType.UTILITY, + enabledByDefault = false +) + +public class CombatCounter extends Plugin +{ + + @Inject + private Client client; + + @Inject + private CombatOverlay tickOverlay; + + @Inject + private DamageOverlay damageOverlay; + + @Inject + private OverlayManager overlayManager; + + @Inject + private CombatCounterConfig config; + + private boolean instanced = false; + private boolean prevInstance = false; + @Setter + @Getter + private Map counter = new HashMap(); + private long BLOWPIPE_ID = 5061; + + private Map blowpipe = new HashMap<>(); + + public Map npcDamageMap = new HashMap(); + public Map playerDamage = new HashMap(); + + @Provides + CombatCounterConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(CombatCounterConfig.class); + } + + + + private Map variables = new HashMap() + { + { + this.put(422, 4); // Unarmed Punch, Block + this.put(423, 4); // Unarmed Kick + + this.put(8145, 4); // Rapier Stab, Lunge, Block + this.put(390, 4); // Rapier Slash + + this.put(7552, 5); // Armadyl Crossbow Accurate, Rapid, Longrange, Special + + this.put(1167, 4); // Trident Accurate, Accurate, Longrange + + this.put(401, 6); // Dragon Warhammer Pound, Pummel, Block + this.put(1378, 6); // Dragon Warhammer Special + + this.put(393, 4); // Dragon Claws Chop, Slash, Block + this.put(1067, 4); // Dragon Claws Lunge + this.put(7514, 4); // Dragon Claws Special + + this.put(8288, 4); // Dragon Hunter Lance Lunge, Block + this.put(8289, 4); // Dragon Hunter Lance Swipe + this.put(8290, 4); // Dragon Hunter Lance Pound + + this.put(7516, 6); // Elder maul Pound, Pummel, Block + + this.put(8056, 5); // Scythe of Vitur Reap, Chop, Jab, Block + + this.put(7045, 6); // Bandos Godsword Chop, Slash + this.put(7054, 6); // Bandos Godsword Smash + this.put(7055, 6); // Bandos Godsword Block + this.put(7642, 6); // Bandos Godsword Special + this.put(7643, 6); // Bandos Godsword Special (Ornamate) + + this.put(426, 5); // Twisted Bow Accurate, Rapid, Longrange + + this.put(414, 5); // Kodai Bash, Pound, Focus + + this.put(428, 4); // Staff of Light Jab + this.put(440, 4); // Staff of Light Swipe + this.put(419, 4); // Staff of Light Fend + this.put(7967, 4); // Staff of Light Special + + this.put(428, 7); // Crystal Halberd Jab, Fend + this.put(419, 7); // Crystal Halberd Swipe + this.put(1203, 7); // Crystal Halberd Special + + this.put(5061, 2); // Toxic Blowpipe Accurate, Rapid, Longrange, Special + + this.put(1979, 5); // Ancient Magicks Barrage + this.put(1978, 5); // Ancient Magicks Blitz + + this.put(7618, 3); // Chinchompa Short, Medium, Long Fuse + this.put(1658, 4); // Whip Flick, Lash, Deflect + + this.put(7555, 6); // Ballista Accurate, Rapid, Longrange + } + }; + + public List MELEE_ANIMATIONS = new ArrayList() + { + { + this.add(422); // Unarmed Punch, Block + this.add(423); // Unarmed Kick + + this.add(8145); // Rapier Stab, Lunge, Block + this.add(390); // Rapier Slash + + this.add(401); // Dragon Warhammer Pound, Pummel, Block + this.add(1378); // Dragon Warhammer Special + + this.add(393); // Dragon Claws Chop, Slash, Block + this.add(1067); // Dragon Claws Lunge + this.add(7514); // Dragon Claws Special + + this.add(8288); // Dragon Hunter Lance Lunge, Block + this.add(8289); // Dragon Hunter Lance Swipe + this.add(8290); // Dragon Hunter Lance Pound + + this.add(7516); // Elder maul Pound, Pummel, Block + + this.add(8056); // Scythe of Vitur Reap, Chop, Jab, Block + + this.add(7045); // Bandos Godsword Chop, Slash + this.add(7054); // Bandos Godsword Smash + this.add(7055); // Bandos Godsword Block + this.add(7642); // Bandos Godsword Special + this.add(7643); // Bandos Godsword Special (Ornamate) + + this.add(414); // Kodai Bash, Pound, Focus + + this.add(428); // Staff of Light Jab + this.add(440); // Staff of Light Swipe + this.add(419); // Staff of Light Fend + + this.add(428); // Crystal Halberd Jab, Fend + this.add(419); // Crystal Halberd Swipe + this.add(1203); // Crystal Halberd Special + + this.add(1658); // Whip Flick, Lash, Deflect + } + }; + + public List RANGE_ANIMATIONS = new ArrayList() + { + { + this.add(7552); // Armadyl Crossbow Accurate, Rapid, Longrange, Special + + this.add(426); // Twisted Bow Accurate, Rapid, Longrange + + this.add(7618); // Chinchompa Short, Medium, Long Fuse + + this.add(7555); // Ballista Accurate, Rapid, Longrange + } + }; + + public List MAGE_ANIMATIONS = new ArrayList() + { + { + this.add(1167); // Trident Accurate, Accurate, Longrange + this.add(1978); // Ancient Magicks Blitz + this.add(1979); // Ancient Magicks Barrage + } + }; + + @Override + protected void startUp() throws Exception + { + overlayManager.add(tickOverlay); + overlayManager.add(damageOverlay); + + this.counter.clear(); + this.blowpipe.clear(); + this.npcDamageMap.clear(); + this.playerDamage.clear(); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(tickOverlay); + overlayManager.remove(damageOverlay); + + this.counter.clear(); + this.blowpipe.clear(); + this.npcDamageMap.clear(); + this.playerDamage.clear(); + } + + + + @Subscribe + public void onAnimationChanged(AnimationChanged event) + { + Actor actor = event.getActor(); + + if (actor != null && actor instanceof Player) + { + Player p = (Player) actor; + String name = actor.getName(); + if (name != null) + { + int animation = p.getAnimation(); + if (animation != -1) + { + if (variables.containsKey(animation)) + { + /* + * This part handles the Tick Counter. + */ + long ticks = variables.get(animation); + if(((Player) actor).getPlayerComposition().getEquipmentId(KitType.WEAPON) == 23360) + { + ticks = 3; + } + if (counter.containsKey(name)) + ticks += counter.get(name); + counter.put(name, ticks); + counter = sortByValue(counter); + + if (animation == BLOWPIPE_ID) + { + this.blowpipe.put(name, -4L); + } + + /* + * This part handles the Damage Counter. + */ + Actor interacting = actor.getInteracting(); + if (interacting != null && interacting instanceof NPC) + { + NPC npc = (NPC) interacting; + + List actives = new ArrayList(); + actives.add(npc); + + if(animation == 1979 || animation == 7618) + { // Barrage or chin. + for(NPC nearby : this.client.getNpcs()) + { + int distance = npc.getWorldLocation().distanceTo(nearby.getWorldLocation()); + if(distance <= 1 && npc != nearby) + { + actives.add(nearby); + } + } + } + + int distance = calculateDistance(p, npc); + + int delay = -1; + boolean canFarcast = false; + + if (animation == 7618) + { + delay = this.calculateChinDelay(distance); + canFarcast = true; + } + else if (animation == 5061) + { + delay = this.calculateBPDelay(distance); + canFarcast = true; + } + else if (RANGE_ANIMATIONS.contains(animation)) + { + delay = this.calculateRangedDelay(distance); + canFarcast = true; + } + else if (MELEE_ANIMATIONS.contains(animation)) + { + delay = 1; + } + else if (MAGE_ANIMATIONS.contains(animation)) + { + delay = this.calculateMageDelay(distance); + canFarcast = true; + } + else + { + System.out.println("Unclassified Animation: " + animation); + } + + if (delay != -1) + { + List ticksToAdd = new ArrayList(); + ticksToAdd.add(delay); + + if(canFarcast && delay > 2) + { + ticksToAdd.add(delay - 1); + } + + /** + * Dragon Claw Specials are 2 ticks long. + */ + if (animation == 7514) + { + ticksToAdd.add(delay + 1); + } + + for(NPC target : actives) + { + NPCDamageCounter dc = new NPCDamageCounter(); + if (this.npcDamageMap.containsKey(target)) + dc = this.npcDamageMap.get(target); + + for (Integer tick : ticksToAdd) + { + List attackers = new ArrayList(); + if (dc.attackers.containsKey(tick)) + attackers = dc.attackers.get(tick); + + attackers.add(name); + dc.attackers.put(tick, attackers); + } + + this.npcDamageMap.put(target, dc); + } + } + } + } + } + else + { + this.blowpipe.remove(name); + } + } + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if(config.resetOnNewInstance()) + { + prevInstance = instanced; + instanced = client.isInInstancedRegion(); + if(!prevInstance && instanced) + { + this.counter.clear(); + this.blowpipe.clear(); + this.npcDamageMap.clear(); + this.playerDamage.clear(); + } + } + + Map visible = new HashMap(); + for (Player p : this.client.getPlayers()) + { + if (p.getName() != null) + visible.put(p.getName(), p); + } + + for (NPC npc : new ArrayList(this.npcDamageMap.keySet())) + { + NPCDamageCounter counter = this.npcDamageMap.get(npc); + + Map> attackers = counter.attackers; + for (Integer i : new ArrayList(attackers.keySet())) + { + List p = attackers.get(i); + attackers.put(i - 1, p); + attackers.remove(i); + } + + double totalDamage = 0d; + for (Integer damage : counter.damage) + totalDamage += damage; + + if (attackers.containsKey(-1)) + { + List players = attackers.get(-1); + double totalPlayers = players.size(); + + double damagePerPlayer = totalDamage / totalPlayers; + for (String name : players) + { + double count = 0d; + if (this.playerDamage.containsKey(name)) + count = this.playerDamage.get(name); + + count += damagePerPlayer; + this.playerDamage.put(name, count); + } + + counter.damage.clear(); + } +// else if (totalDamage > 0){ +// counter.damage.clear(); +// +// String name = "[Unknown]"; +// double count = 0d; +// if (this.playerDamage.containsKey(name)) +// count = this.playerDamage.get(name); +// +// count += totalDamage; +// this.playerDamage.put(name, count); +// } + + for (Integer i : new ArrayList(attackers.keySet())) + if (i <= -1) + attackers.remove(i); + + if (attackers.isEmpty()) + this.npcDamageMap.remove(npc); + } + + this.playerDamage = sortByValue(this.playerDamage); + + for (String user : new ArrayList(blowpipe.keySet())) + { + if (visible.containsKey(user)) + { + long count = blowpipe.get(user); + count++; + blowpipe.replace(user, count); + + if (count % 2 == 0 && count >= 0 && counter.containsKey(user)) + { + long ticks = counter.get(user); + counter.replace(user, ticks + 2); + counter = sortByValue(counter); + + Player p = visible.get(user); + Actor interacting = p.getInteracting(); + if (interacting != null && interacting instanceof NPC) + { + NPC npc = (NPC) interacting; + + int distance = calculateDistance(p, npc); + + NPCDamageCounter dc = new NPCDamageCounter(); + if (this.npcDamageMap.containsKey(npc)) + dc = this.npcDamageMap.get(npc); + + int delay = this.calculateBPDelay(distance); + + List counts = new ArrayList(); + counts.add(delay); + if(delay > 2) + counts.add(delay - 1); + + for(int tick : counts) + { + List attackers = new ArrayList(); + if (dc.attackers.containsKey(tick)) + attackers = dc.attackers.get(tick); + + attackers.add(user); + dc.attackers.put(tick, attackers); + } + + this.npcDamageMap.put(npc, dc); + } + } + } + else + { + blowpipe.remove(user); + } + } + } + + + @Subscribe + public void onHitsplatApplied(HitsplatApplied event) + { + Actor actor = event.getActor(); + + if (!(actor instanceof NPC)) + return; + + NPC npc = (NPC) actor; + + if (!this.npcDamageMap.containsKey(npc)) + return; + + Hitsplat splat = event.getHitsplat(); + NPCDamageCounter dc = this.npcDamageMap.get(npc); + + dc.damage.add(splat.getAmount()); + } + + private > Map sortByValue(Map map) + { + List> list = new ArrayList<>(map.entrySet()); + list.sort(Map.Entry.comparingByValue()); + + Map result = new LinkedHashMap<>(); + for (Map.Entry entry : list) + { + result.put(entry.getKey(), entry.getValue()); + } + + return result; + } + + public int calculateDistance(Player p, NPC npc) + { + int size = 1; + NPCComposition comp = npc.getTransformedComposition(); + if(comp != null) + { + size = comp.getSize(); + } + + WorldPoint wpPlayer = p.getWorldLocation(); + WorldPoint wpNPC = npc.getWorldLocation(); + int distance = wpNPC.distanceTo(wpPlayer); + + if(size > 1) + for(int x = 0; x < size; x++) + { + for(int y = 0; y < size; y++) + { + WorldPoint wpNPCB = WorldPoint.fromRegion(wpNPC.getRegionID(), wpNPC.getRegionX() + x, wpNPC.getRegionY() + y, wpNPC.getPlane()); + int distB = wpNPCB.distanceTo(wpPlayer); + if(distB >= 1 && distB < distance) + { + distance = distB; + } + } + } + return distance; + } + + public int calculateBPDelay(double distance) + { + return 2 + (int) Math.floor(distance / 6d); + } + + public int calculateChinDelay(double distance) + { + return 2 + (int) Math.floor(distance / 6d); + } + + public int calculateMageDelay(double distance) + { + return 2 + (int) Math.floor((1d + distance) / 3d); + } + + public int calculateRangedDelay(double distance) + { + return 2 + (int) Math.floor((3d + distance) / 6d); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounterConfig.java new file mode 100644 index 0000000000..39615aecd7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounterConfig.java @@ -0,0 +1,107 @@ +package net.runelite.client.plugins.combatcounter; + +import net.runelite.client.config.Alpha; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.*; + +@ConfigGroup("combatcounter") +public interface CombatCounterConfig extends Config +{ + + @ConfigItem( + keyName = "Show Tick Counter", + name = "Show Tick Counter", + description = "Turn the tick counter on", + position = 1 + ) + default boolean showTickCounter() + { + return false; + } + + @ConfigItem( + keyName = "Show Damage Counter", + name = "Show Damage Counter", + description = "Turn the damage counter on", + position = 2 + ) + default boolean showDamageCounter() + { + return false; + } + + + @ConfigItem( + keyName = "Reset on New Instance", + name = "Reset On New Instance", + description = "Resets counter when entering a new instance", + position = 4 + ) + default boolean resetOnNewInstance() + { + return false; + } + + @Alpha + @ConfigItem( + keyName = "selfColor", + name = "Your color", + description = "", + position = 4 + ) + default Color selfColor() + { + return Color.green; + } + + @Alpha + @ConfigItem( + keyName = "totalColor", + name = "Total color", + description = "", + position = 6 + ) + default Color totalColor() + { + return Color.RED; + } + + @Alpha + @ConfigItem( + keyName = "otherColor", + name = "Other players color", + description = "", + position = 5 + ) + default Color otherColor() + { + return Color.white; + } + + @Alpha + @ConfigItem( + keyName = "bgColor", + name = "Background color", + description = "", + position = 3 + ) + default Color bgColor() + { + return new Color(70, 61, 50, 156); + } + + @Alpha + @ConfigItem( + keyName = "titleColor", + name = "Title color", + description = "", + position = 2 + ) + default Color titleColor() + { + return Color.white; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatOverlay.java new file mode 100644 index 0000000000..7420e75295 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatOverlay.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018, Seth + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.combatcounter; + +import com.google.inject.Provides; +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.ui.overlay.Overlay; +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.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +import javax.inject.Inject; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +class CombatOverlay extends Overlay +{ + + private final Client client; + private final CombatCounter plugin; + private final PanelComponent panelComponent = new PanelComponent(); + private final CombatCounterConfig config; + private HashMap ticks = new HashMap<>(); + + @Inject + public CombatOverlay(Client client, CombatCounter plugin, CombatCounterConfig config) + { + super(plugin); + + setPosition(OverlayPosition.DYNAMIC); + setPosition(OverlayPosition.DETACHED); + setPosition(OverlayPosition.BOTTOM_RIGHT); + + this.config = config; + this.client = client; + this.plugin = plugin; + + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Tick Counter")); + } + + + + @Override + public Dimension render(Graphics2D graphics) + { + if(config.showTickCounter()) + { + panelComponent.getChildren().clear(); + + Player local = client.getLocalPlayer(); + if(local == null || local.getName() == null) + return null; + panelComponent.setBackgroundColor(config.bgColor()); + panelComponent.getChildren().add(TitleComponent.builder().text("Tick Counter").color(config.titleColor()).build()); + int total = 0; + if(plugin.getCounter().isEmpty()) + { + panelComponent.getChildren().add(LineComponent.builder().left(local.getName()).right("0").build()); + } + else + { + Map map = this.plugin.getCounter(); + if(map == null) + return null; + + for(String name : map.keySet()) + { + if(client.getLocalPlayer().getName().contains(name)) + { + panelComponent.getChildren().add(1, LineComponent.builder().left(name).right(Long.toString(map.get(name))).leftColor(config.selfColor()).rightColor(config.selfColor()).build()); + } + else + { + panelComponent.getChildren().add(1, LineComponent.builder().left(name).right(Long.toString(map.get(name))).leftColor(config.otherColor()).rightColor(config.otherColor()).build()); + } + total += map.get(name); + } + + if(!map.containsKey(local.getName())) + { + panelComponent.getChildren().add(LineComponent.builder().left(local.getName()).right("0").leftColor(config.selfColor()).rightColor(config.selfColor()).build()); + } + } + panelComponent.getChildren().add(LineComponent.builder().left("Total").leftColor(config.totalColor()).rightColor(config.totalColor()).right(String.valueOf(total)).build()); + return panelComponent.render(graphics); + } + else + { + return null; + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/DamageOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/DamageOverlay.java new file mode 100644 index 0000000000..7e7fb928b3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/DamageOverlay.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2018, Seth + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.combatcounter; + +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.client.ui.overlay.Overlay; +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.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +import javax.inject.Inject; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +class DamageOverlay extends Overlay +{ + + private final Client client; + + private final CombatCounter plugin; + + private final CombatCounterConfig config; + + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + public DamageOverlay(Client client, CombatCounter plugin, CombatCounterConfig config) + { + super(plugin); + + setPosition(OverlayPosition.DYNAMIC); + setPosition(OverlayPosition.DETACHED); + setPosition(OverlayPosition.BOTTOM_RIGHT); + + this.config = config; + this.client = client; + this.plugin = plugin; + + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Damage Counter Overlay")); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (config.showDamageCounter()) + { + panelComponent.getChildren().clear(); + + Player local = client.getLocalPlayer(); + if (local == null || local.getName() == null) + return null; + panelComponent.setBackgroundColor(config.bgColor()); + panelComponent.getChildren().add(TitleComponent.builder().text("Damage Counter").color(config.titleColor()).build()); + + if (plugin.getCounter().isEmpty()) + { + panelComponent.getChildren().add(LineComponent.builder().left(local.getName()).right("0").build()); + } + else + { + Map map = this.plugin.playerDamage; + if (map == null) + return null; + + for (String name : map.keySet()) + { + String val = String.format("%.1f", map.get(name)); + if(client.getLocalPlayer().getName().contains(name)) + { + panelComponent.getChildren().add(1, LineComponent.builder().left(name).right(val).leftColor(config.selfColor()).rightColor(config.selfColor()).build()); + } + else + { + panelComponent.getChildren().add(1, LineComponent.builder().left(name).right(val).leftColor(config.otherColor()).rightColor(config.otherColor()).build()); + } + } + + if (!map.containsKey(local.getName())) + { + panelComponent.getChildren().add(LineComponent.builder().left(local.getName()).right("0").leftColor(config.selfColor()).rightColor(config.selfColor()).build()); + } + } + + return panelComponent.render(graphics); + } + else + { + return null; + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/NPCDamageCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/NPCDamageCounter.java new file mode 100644 index 0000000000..781b043ffe --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/NPCDamageCounter.java @@ -0,0 +1,22 @@ +package net.runelite.client.plugins.combatcounter; + +import net.runelite.api.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class NPCDamageCounter +{ + + public Map> attackers; + + public List damage; + + public NPCDamageCounter() + { + this.attackers = new TreeMap>(); + this.damage = new ArrayList(); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java new file mode 100644 index 0000000000..725bbd3f2a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2019, Shaun Dreclin + * 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.musicindicator; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.inject.Inject; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.EnumComposition; +import net.runelite.api.EnumID; +import net.runelite.api.VarPlayer; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.VarbitChanged; +import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; + +@PluginDescriptor( + name = "Music Track Indicator", + description = "Show chat notifications when unlocking music tracks", + type = PluginType.UTILITY +) +public class MusicIndicatorPlugin extends Plugin +{ + private static final List MUSIC_TRACK_VARPS = ImmutableList.of( + VarPlayer.MUSIC_TRACKS_UNLOCKED_1, VarPlayer.MUSIC_TRACKS_UNLOCKED_2, VarPlayer.MUSIC_TRACKS_UNLOCKED_3, + VarPlayer.MUSIC_TRACKS_UNLOCKED_4, VarPlayer.MUSIC_TRACKS_UNLOCKED_5, VarPlayer.MUSIC_TRACKS_UNLOCKED_6, + VarPlayer.MUSIC_TRACKS_UNLOCKED_7, VarPlayer.MUSIC_TRACKS_UNLOCKED_8, VarPlayer.MUSIC_TRACKS_UNLOCKED_9, + VarPlayer.MUSIC_TRACKS_UNLOCKED_10, VarPlayer.MUSIC_TRACKS_UNLOCKED_11, VarPlayer.MUSIC_TRACKS_UNLOCKED_12, + VarPlayer.MUSIC_TRACKS_UNLOCKED_13, VarPlayer.MUSIC_TRACKS_UNLOCKED_14, VarPlayer.MUSIC_TRACKS_UNLOCKED_15, + VarPlayer.MUSIC_TRACKS_UNLOCKED_16, VarPlayer.MUSIC_TRACKS_UNLOCKED_17, VarPlayer.MUSIC_TRACKS_UNLOCKED_18, + VarPlayer.MUSIC_TRACKS_UNLOCKED_19 + ); + + private static final Map VARP_INDEX_TO_VARPLAYER = MUSIC_TRACK_VARPS.stream() + .collect(Collectors.collectingAndThen(Collectors.toMap(VarPlayer::getId, Function.identity()), + ImmutableMap::copyOf)); + + @Inject + private Client client; + + @Inject + private ChatMessageManager chatMessageManager; + + // Mapping of relevant varps to their values, used to compare against new values + private final Map musicTrackVarpValues = new HashMap<>(); + + private boolean loggingIn; + + @Override + public void startUp() + { + loggingIn = true; + } + + @Override + public void shutDown() + { + musicTrackVarpValues.clear(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + switch (event.getGameState()) + { + case LOGGING_IN: + case CONNECTION_LOST: + case HOPPING: + musicTrackVarpValues.clear(); + loggingIn = true; + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (!loggingIn) + { + return; + } + + loggingIn = false; + + for (VarPlayer musicTrackVarp : MUSIC_TRACK_VARPS) + { + int value = client.getVar(musicTrackVarp); + musicTrackVarpValues.put(musicTrackVarp, value); + } + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + int idx = event.getIndex(); + + VarPlayer varPlayer = VARP_INDEX_TO_VARPLAYER.get(idx); + if (varPlayer == null) + { + return; + } + + // Old varplayer values have not been initialized yet + if (musicTrackVarpValues.isEmpty()) + { + return; + } + + assert musicTrackVarpValues.containsKey(varPlayer); + + int newValue = client.getVar(varPlayer); + int oldValue = musicTrackVarpValues.put(varPlayer, newValue); + int musicTracksUnlocked = ~oldValue & newValue; + + if (musicTracksUnlocked == 0) + { + return; + } + + final EnumComposition names = client.getEnum(EnumID.MUSIC_TRACK_NAMES); + final int varpId = MUSIC_TRACK_VARPS.indexOf(varPlayer) + 1; + + for (int bit = 0; bit < Integer.SIZE; ++bit) + { + if ((musicTracksUnlocked & (1 << bit)) == 0) + { + continue; + } + + int musicTrackId = getTrackId(varpId, bit); + String musicTrackName = names.getStringValue(musicTrackId); + + sendChatMessage("You have unlocked a new music track: " + musicTrackName + "."); + } + } + + /** + * Get the id for a track identified by the given varp and a bit index + * @param variableId + * @param bit + * @return + */ + private int getTrackId(int variableId, int bit) + { + // values are packed into a coordgrid + int packed = (variableId << 14) | bit; + EnumComposition ids = client.getEnum(EnumID.MUSIC_TRACK_IDS); + for (int key : ids.getKeys()) + { + int value = ids.getIntValue(key); + if (value == packed) + { + return key; + } + } + return -1; + } + + private void sendChatMessage(String chatMessage) + { + final String message = new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append(chatMessage) + .build(); + + chatMessageManager.queue( + QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(message) + .build()); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerConfig.java new file mode 100644 index 0000000000..299122edf5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerConfig.java @@ -0,0 +1,32 @@ +package net.runelite.client.plugins.spawntimer; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +import java.awt.*; + +@ConfigGroup("spawntimer") +public interface SpawnTimerConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "npcToHighlight", + name = "NPCs to show timer for", + description = "List of NPC names to show timer for" + ) + default String getNpcToHighlight() + { + return ""; + } + @ConfigItem( + position = 2, + keyName = "npcColor", + name = "Text Color", + description = "Color of the NPC timer" + ) + default Color getHighlightColor() + { + return Color.RED; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerOverlay.java new file mode 100644 index 0000000000..1403fae8f7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerOverlay.java @@ -0,0 +1,78 @@ +package net.runelite.client.plugins.spawntimer; + +import net.runelite.api.*; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.client.plugins.npchighlight.NpcIndicatorsConfig; +import net.runelite.client.plugins.npchighlight.NpcIndicatorsPlugin; +import net.runelite.client.plugins.spawntimer.SpawnTimerPlugin; +import net.runelite.client.plugins.spawntimer.SpawnTimerConfig; +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; +import net.runelite.client.util.WildcardMatcher; + +import javax.inject.Inject; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +public class SpawnTimerOverlay extends Overlay +{ + private final Client client; + private final SpawnTimerConfig config; + private final SpawnTimerPlugin plugin; + private List highlights = new ArrayList<>(); + @Inject + SpawnTimerOverlay(Client client, SpawnTimerConfig config, SpawnTimerPlugin plugin) + { + this.client = client; + this.config = config; + this.plugin = plugin; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + highlights = plugin.getHighlights(); + for (thing npc : plugin.getTicks()) + { + if(npc == null) + { + continue; + } + if(npc.getNpc() == null) + { + continue; + } + if(npc.getNpc().getName() == null) + { + continue; + } + for (String highlight : highlights) + { + + if (WildcardMatcher.matches(highlight, npc.getNpc().getName())) + { + int tick = plugin.getCurrentTick() - npc.getTick(); + String tickString = "" + tick; + renderNpcOverlay(graphics, npc.getNpc(), tickString, config.getHighlightColor()); + } + } + } + return null; + } + + private void renderNpcOverlay(Graphics2D graphics, NPC actor, String name, Color color) + { + Point textLocation = actor.getCanvasTextLocation(graphics, name, actor.getLogicalHeight() - 40); + + if (textLocation != null) + { + OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerPlugin.java new file mode 100644 index 0000000000..f1a80bb485 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerPlugin.java @@ -0,0 +1,141 @@ +package net.runelite.client.plugins.spawntimer; + +import com.google.common.annotations.VisibleForTesting; +import com.google.inject.Provides; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.NPC; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +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.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.Text; + +import javax.inject.Inject; +import java.util.*; + +@PluginDescriptor( + name = "Spawn Timer", + description = "Shows NPC'S time since spawned", + tags = {"highlight", "minimap", "npcs", "overlay", "spawn", "tags", "lyzrd"}, + type = PluginType.PVM, + enabledByDefault = false +) + +public class SpawnTimerPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + + + @Getter(AccessLevel.PACKAGE) + private final Set highlightedNpcs = new HashSet<>(); + + @Getter(AccessLevel.PACKAGE) + Set ticks = new HashSet<>(); + + @Inject + private SpawnTimerOverlay SpawnTimerOverlay; + + @Inject + private Client client; + + @Inject + private SpawnTimerConfig config; + + @Provides + SpawnTimerConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(SpawnTimerConfig.class); + } + + + @Getter(AccessLevel.PACKAGE) + public int currentTick; + @Override + protected void startUp() throws Exception + { + currentTick = 0; + overlayManager.add(SpawnTimerOverlay); + } + + + @Override + protected void shutDown() throws Exception + { + ticks.clear(); + highlightedNpcs.clear(); + overlayManager.remove(SpawnTimerOverlay); + } + + @Subscribe + public void onGameTick(GameTick g) + { + currentTick++; + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGIN_SCREEN || + event.getGameState() == GameState.HOPPING) + { + highlightedNpcs.clear(); + ticks.clear(); + } + } + + @Subscribe + public void onNpcSpawned(NpcSpawned n) + { + if(n.getNpc() != null) + { + final NPC npc = n.getNpc(); + highlightedNpcs.add(npc); + thing temp = new thing(); + temp.setNpc(npc); + temp.setTick(currentTick); + ticks.add(temp); + } + } + + @Subscribe + public void onNpcDespawned(NpcDespawned n) + { + final NPC npc = n.getNpc(); + if(highlightedNpcs.contains(npc)) + { + highlightedNpcs.remove(npc); + for (Iterator iterator = ticks.iterator(); iterator.hasNext();) + { + thing t = iterator.next(); + if (t.getNpc() == npc) + { + iterator.remove(); + } + //currentTick = 0; + } + } + } + @VisibleForTesting + public List getHighlights() + { + final String configNpcs = config.getNpcToHighlight().toLowerCase(); + + if (configNpcs.isEmpty()) + { + return Collections.emptyList(); + } + + return Text.fromCSV(configNpcs); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/thing.java b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/thing.java new file mode 100644 index 0000000000..45095c18f7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/thing.java @@ -0,0 +1,25 @@ +package net.runelite.client.plugins.spawntimer; + +import net.runelite.api.NPC; + +public class thing +{ + private NPC npc; + private int tick; + public void setNpc(NPC n) + { + npc = n; + } + NPC getNpc() + { + return npc; + } + public void setTick(int n) + { + tick = n; + } + int getTick() + { + return tick; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..810ce7837e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/RoomHandler.java @@ -0,0 +1,181 @@ +package net.runelite.client.plugins.theatre; + +import net.runelite.api.*; +import net.runelite.api.Point; +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 +{ + + protected final Client client; + protected final TheatrePlugin plugin; + protected final TheatreConfig config; + + public RoomHandler(Client client, TheatrePlugin plugin, TheatreConfig config) + { + this.client = client; + this.plugin = plugin; + this.config = config; + } + + public abstract void onStart(); + + public abstract void onStop(); + + 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) + { + return; + } + LocalPoint lp = LocalPoint.fromWorld(client, point); + if (lp == null) + { + return; + } + + Polygon poly = Perspective.getCanvasTileAreaPoly(client, lp, 7); + if (poly == null) + { + return; + } + //OverlayUtil.renderPolygon(graphics, poly, color); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); + graphics.setStroke(new BasicStroke(strokeWidth)); + graphics.draw(poly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(poly); + + } + + protected void renderProjectiles(Graphics2D graphics, Map projectiles) + { + + Iterator> itr = projectiles.entrySet().iterator(); + while (itr.hasNext()) + { + Map.Entry entry = itr.next(); + int projectileId = entry.getKey().getId(); + String text = entry.getValue(); + int x = (int) entry.getKey().getX(); + int y = (int) entry.getKey().getY(); + LocalPoint projectilePoint = new LocalPoint(x, y); + Point textLocation = Perspective.getCanvasTextLocation(client, graphics, projectilePoint, text, 0); + if (textLocation != null) + { + 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); + } + } + } + } + + 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)); + graphics.draw(poly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(poly); + } + + protected void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) + { + int size = 1; + + NPCComposition composition = actor.getTransformedComposition(); + if (composition != null) + size = composition.getSize(); + + LocalPoint lp = actor.getLocalLocation(); + Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); + + if (tilePoly != null) + { + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); + graphics.setStroke(new BasicStroke(outlineWidth)); + graphics.draw(tilePoly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(tilePoly); + } + } + + protected void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) + { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) + { + final Point canvasCenterPoint = new Point(canvasPoint.getX(), canvasPoint.getY()); + final Point canvasCenterPointShadow = new Point(canvasPoint.getX() + 1, canvasPoint.getY() + 1); + + OverlayUtil.renderTextLocation(graphics, canvasCenterPointShadow, txtString, Color.BLACK); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } + + 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) + { + + if (number == 0) + { + return "00"; + } + + if (number / 10 == 0) + { + return "0" + number; + } + + return String.valueOf(number); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..827fb736eb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConfig.java @@ -0,0 +1,344 @@ +/* + * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI + * No rights reserved. Use, redistribute, and modify at your own discretion, + * and in accordance with Yagex and RuneLite guidelines. + * However, aforementioned monkey would prefer if you don't sell this plugin for profit. + * Good luck on your raids! + */ + +package net.runelite.client.plugins.theatre; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.plugins.theatre.rooms.nylocas.NyloPredictor; +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", + name = "Show Maiden Blood Toss", + description = "Displays the tile location where tossed blood will land." + ) + default boolean showMaidenBloodToss() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "showMaidenBloodSpawns", + name = "Show Maiden Blood Spawns", + description = "Show the tiles that blood spawns will travel to." + ) + default boolean showMaidenBloodSpawns() + { + return true; + } + + @ConfigItem( + position = 2, + keyName = "showBloatIndicator", + name = "Show Bloat Status", + description = "Displays Bloat's status (asleep, wake, and enrage) using color code." + ) + default boolean showBloatIndicator() + { + return true; + } + + @ConfigItem( + position = 3, + keyName = "showBloatHands", + name = "Show Bloat Hands", + description = "Highlights the falling hands inside Bloat." + ) + default boolean showBloatHands() + { + return true; + } + + @ConfigItem( + position = 4, + keyName = "bloatFeet", + name = "Bloat Hands Rave Edition", + description = "" + ) + default boolean BloatFeetIndicatorRaveEdition() + { + return false; + } + + @ConfigItem( + position = 4, + keyName = "showBloatTimer", + name = "Show Bloat Timer", + description = "Show the estimated time when Bloat will go down." + ) + default boolean showBloatTimer() + { + return false; + } + + @ConfigItem( + position = 5, + keyName = "showNyloPillarHealth", + name = "Show Nylocas Pillar Health", + description = "Show the health bars of the Nylocas pillars." + ) + default boolean showNyloPillarHealth() + { + return true; + } + + @ConfigItem( + position = 6, + keyName = "showNylocasExplosions", + name = "Highlight Old Nylocas", + description = "Either a timer on the nylo counting down to explosion, or a tile underneath." + ) + default NYLOOPTION showNylocasExplosions() + { + return NYLOOPTION.NONE; + } + + @ConfigItem( + position = 7, + keyName = "showNylocasAmount", + name = "Show Nylocas Amount", + description = "An overlay will appear that counts the amount of Nylocas in the room." + ) + 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 = 11, + keyName = "highlightNyloAgros", + name = "Show Nylocas Agros", + description = "Highlight the Nylocas that are aggressive to the player." + ) + default boolean highlightNyloAgros() + { + return true; + } + + @ConfigItem( + position = 12, + keyName = "showSotetsegAttacks", + name = "Show Sotetseg Attacks", + description = "Highlight the attacks which Sotetseg throws at you." + ) + default boolean showSotetsegAttacks() + { + return true; + } + + @ConfigItem( + position = 13, + keyName = "showSotetsegMaze", + name = "Mark Sotetseg Maze", + description = "Marks the tiles of Sotetseg's maze while in the overworld." + ) + default boolean showSotetsegMaze() + { + return true; + } + + @ConfigItem( + position = 14, + keyName = "showSotetsegSolo", + name = "Mark Sotetseg Maze (Solo)", + description = "Marks the tiles of Sotetseg's maze while in the underworld." + ) + default boolean showSotetsegSolo() + { + return true; + } + + @ConfigItem( + position = 14, + keyName = "markerColor", + name = "Sotey Tile Colour", + description = "Configures the color of marked tile" + ) + default Color mazeTileColour() + { + return Color.WHITE; + } + @ConfigItem( + position = 15, + keyName = "showXarpusHeals", + name = "Show Xarpus Heals", + description = "Highlights the tiles that Xarpus is healing with." + ) + default boolean showXarpusHeals() + { + return true; + } + + @ConfigItem( + position = 16, + keyName = "showXarpusTick", + name = "Show Xarpus Turn Tick", + description = "Count down the ticks until Xarpus turns their head." + ) + default boolean showXarpusTick() + { + return true; + } + + @ConfigItem( + position = 17, + keyName = "showVerzikAttacks", + name = "Show Verzik Attack Tick", + description = "Count down the ticks until Verzik attacks." + ) + default boolean showVerzikAttacks() + { + return true; + } + + @ConfigItem( + position = 18, + keyName = "showVerzikYellows", + name = "Show Yellows Tick", + description = "Count down the ticks until Verzik yellow's damage tick." + ) + default boolean showVerzikYellows() + { + return true; + } + + @ConfigItem( + position = 19, + keyName = "showCrabTargets", + name = "Show Crab Targets", + description = "Shows the target of crabs at Verzik." + ) + default boolean showCrabTargets() + { + return true; + } + + @ConfigItem( + position = 20, + keyName = "VerzikTankTile", + name = "Verzik P3 Tile Overlay", + description = "" + ) + default boolean VerzikTankTile() + { + return false; + } + + @ConfigItem( + position = 22, + keyName = "verzikrangeattacks", + name = "Show Verzik Range Attacks", + description = "" + ) + default boolean verzikRangeAttacks() + { + return true; + } + + @ConfigItem( + position = 23, + keyName = "extratimers", + name = "Show Extra Timers", + description = "" + ) + default boolean extraTimers() + { + return false; + } + + @ConfigItem( + position = 24, + keyName = "p1attacks", + name = "Verzik P1 Timer", + description = "" + ) + default boolean p1attacks() + { + return true; + } + + @ConfigItem( + position = 25, + keyName = "p2attacks", + name = "Verzik P2 Timer", + description = "" + ) + default boolean p2attacks() + { + return true; + } + + @ConfigItem( + position = 26, + keyName = "p3attacks", + name = "Verzik P3 Timer", + description = "" + ) + default boolean p3attacks() + { + return true; + } +} \ 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 new file mode 100644 index 0000000000..c661beb01c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreConstant.java @@ -0,0 +1,56 @@ +package net.runelite.client.plugins.theatre; + +import net.runelite.api.NpcID; + +public class TheatreConstant +{ + public static final int MAIDEN_BLOOD_THROW = 1579; + + public static final int NPC_ID_NYLOCAS_PILLAR = 8358; + + public static final int GROUNDOBJECT_ID_BLACKMAZE = 33034; + public static final int GROUNDOBJECT_ID_REDMAZE = 33035; + public static final int GROUNDOBJECT_ID_EXHUMED = 32743; + + public static final int ANIMATION_ID_XARPUS = 8059; + + public static final int SOTETSEG_NORMAL = 8388; + public static final int SOTETSEG_MAZE = 8387; + public static final int SOTETSEG_BOMB = 1604; + public static final int SOTETSEG_RANGE = 1607; + public static final int SOTETSEG_MAGE = 1606; + + public static final int GRAPHICSOBJECT_ID_YELLOW = 1595; + + public static final int PROJECTILE_ID_P2RANGE = 1583; + public static final int PROJECTILE_ID_YELLOW = 1596; + + public static final int ANIMATION_ID_P3_WEB = 8127; + public static final int ANIMATION_ID_P3_YELLOW = 8126; + public static final int ANIMATION_ID_P3_MELEE = 8123; + public static final int ANIMATION_ID_P3_MAGE = 8124; + public static final int ANIMATION_ID_P3_RANGE = 8125; + + public static final int ANIMATION_ID_P1_ATTACK = 8109; + public static final int ANIMATION_ID_P2_ATTACK_RANGE = 8114; + public static final int ANIMATION_ID_P2_ATTACK_MELEE = 8116; + public static final int ANIMATION_ID_P2_SHIELD = 8117; + + public static final int VERZIK_ID_P0 = 8369; + public static final int VERZIK_ID_P1 = 8370; + public static final int VERZIK_ID_P1_WALK = 8371; + public static final int VERZIK_ID_P2 = 8372; + public static final int VERZIK_ID_P2_TRANSFORM = 8373; + public static final int VERZIK_ID_P3 = 8374; + public static final int VERZIK_ID_P3_BAT = 8375; + + public static final int VERZIK_P3_RANGE = 1593; + public static final int VERZIK_P3_MAGE = 1594; + + public static final int NPC_ID_TORNADO = 8386; + public static final int PROJECTILE_ID_P3_GREEN = 1598; + + public static final int GRAPHIC_ID_YELLOWS = 1595; + + public static final int DOOR_VARP = 6447; +} \ No newline at end of file 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 new file mode 100644 index 0000000000..1c349e104a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreOverlay.java @@ -0,0 +1,73 @@ +/* + * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI + * No rights reserved. Use, redistribute, and modify at your own discretion, + * and in accordance with Yagex and RuneLite guidelines. + * However, aforementioned monkey would prefer if you don't sell this plugin for profit. + * Good luck on your raids! + */ + +package net.runelite.client.plugins.theatre; + +import java.awt.*; +import java.util.*; +import java.util.List; +import javax.inject.Inject; +import net.runelite.api.*; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; + +public class TheatreOverlay extends Overlay +{ + + private final Client client; + private final TheatrePlugin plugin; + private final TheatreConfig config; + + @Inject + private TheatreOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) + { + this.client = client; + this.plugin = plugin; + this.config = config; + + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + switch(plugin.getRoom()) + { + case MAIDEN: + plugin.getMaidenHandler().render(graphics); + break; + case BLOAT: + plugin.getBloatHandler().render(graphics); + break; + case NYLOCAS: + plugin.getNyloHandler().render(graphics); + break; + case SOTETSEG: + plugin.getSotetsegHandler().render(graphics); + break; + case XARPUS: + plugin.getXarpusHandler().render(graphics); + break; + case VERSIK: + plugin.getVerzikHandler().render(graphics); + break; + default: + break; + } + return null; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..d9fdda5039 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java @@ -0,0 +1,238 @@ +/* + * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI + * No rights reserved. Use, redistribute, and modify at your own discretion, + * and in accordance with Yagex and RuneLite guidelines. + * However, aforementioned monkey would prefer if you don't sell this plugin for profit. + * Good luck on your raids! + */ + +package net.runelite.client.plugins.theatre; + +import com.google.inject.Provides; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.Client; +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.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.ui.overlay.OverlayManager; + +import javax.inject.Inject; + +@PluginDescriptor( + name = "Theatre of Blood", + description = "All-in-one plugin for Theatre of Blood.", + tags = {"ToB", "Theatre", "Theatre of Blood", "Lyzrd"}, + type = PluginType.PVM, + enabledByDefault = false +) + +public class TheatrePlugin extends Plugin +{ + + @Getter(AccessLevel.PUBLIC) + @Setter(AccessLevel.PUBLIC) + private TheatreRoom room; + + @Getter(AccessLevel.PUBLIC) + private MaidenHandler maidenHandler; + + @Getter(AccessLevel.PUBLIC) + private BloatHandler bloatHandler; + + @Getter(AccessLevel.PUBLIC) + private NyloHandler nyloHandler; + + @Getter(AccessLevel.PUBLIC) + private SotetsegHandler sotetsegHandler; + + @Getter(AccessLevel.PUBLIC) + private XarpusHandler xarpusHandler; + + @Getter(AccessLevel.PUBLIC) + private VerzikHandler verzikHandler; + + @Inject + private Client client; + + @Getter(AccessLevel.PUBLIC) + @Inject + private OverlayManager overlayManager; + + @Inject + private TheatreOverlay overlay; + + @Inject + private TheatreConfig config; + + @Provides + TheatreConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(TheatreConfig.class); + } + + @Override + protected void startUp() + { + room = TheatreRoom.UNKNOWN; + + maidenHandler = new MaidenHandler(client, this, config); + bloatHandler = new BloatHandler(client, this, config); + nyloHandler = new NyloHandler(client, this, config); + sotetsegHandler = new SotetsegHandler(client, this, config); + xarpusHandler = new XarpusHandler(client, this, config); + verzikHandler = new VerzikHandler(client, this, config); + + overlayManager.add(overlay); + } + + @Override + protected void shutDown() + { + maidenHandler.onStop(); + maidenHandler = null; + + bloatHandler.onStop(); + bloatHandler = null; + + nyloHandler.startTime = 0L; + nyloHandler.onStop(); + nyloHandler = null; + + sotetsegHandler.onStop(); + sotetsegHandler = null; + + xarpusHandler.onStop(); + xarpusHandler = null; + + verzikHandler.onStop(); + verzikHandler = null; + + room = TheatreRoom.UNKNOWN; + + overlayManager.remove(overlay); + } + + @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); + + } + + @Subscribe + 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); + + } + + @Subscribe + public void onAnimationChanged(AnimationChanged event) + { + if (verzikHandler != null) + verzikHandler.onAnimationChanged(event); + } + + @Subscribe + 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(); + } + + @Subscribe + 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 + public void onProjectileMoved(ProjectileMoved event) + { + if(sotetsegHandler != null) + { + sotetsegHandler.onProjectileMoved(event); + + } + if(verzikHandler != null) + { + verzikHandler.onProjectileMoved(event); + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..e13635b13f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatreRoom.java @@ -0,0 +1,12 @@ +package net.runelite.client.plugins.theatre; + +public enum TheatreRoom +{ + MAIDEN, + BLOAT, + NYLOCAS, + SOTETSEG, + XARPUS, + VERSIK, + 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 new file mode 100644 index 0000000000..3dca56ea3b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java @@ -0,0 +1,234 @@ +package net.runelite.client.plugins.theatre.rooms; + +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.*; +import net.runelite.api.Point; +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.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; + } + + @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; + + public BloatHandler(Client client, TheatrePlugin plugin, TheatreConfig config) + { + super(client, plugin, config); + } + + @Override + public void onStart() + { + if (this.plugin.getRoom() == TheatreRoom.BLOAT) + return; + + this.reset(); + this.plugin.setRoom(TheatreRoom.BLOAT); + System.out.println("Starting Bloat Room"); + } + + @Override + public void onStop() + { + this.reset(); + this.plugin.setRoom(TheatreRoom.UNKNOWN); + System.out.println("Stopping Bloat Room"); + } + + public void reset() + { + bloat = null; + bloatFlag = false; + bloatTimer = 0; + counter = 0; + bloatState = BloatState.UP; + } + + public void render(Graphics2D graphics) + { + if (bloat == null) + { + return; + } + + if (config.showBloatIndicator()) + { + switch (bloatState) + { + case DOWN: + renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); + break; + case WARN: + renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); + break; + case UP: + renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); + break; + } + } + + if (config.showBloatHands()) + { + for (GraphicsObject object : client.getGraphicsObjects()) + { + int id = object.getId(); + if (id >= 1560 && id <= 1590) + { + WorldPoint point = WorldPoint.fromLocal(client, object.getLocation()); + if (!config.BloatFeetIndicatorRaveEdition()) + { + drawTile(graphics, point, new Color(36, 248, 229), 2, 255, 10); + } + else + { + drawTile(graphics, point, color, 2, 255, 10); + } + + } + } + } + + if(config.showBloatTimer()) + { + final String tickCounter = String.valueOf(bloatTimer); + int secondConversion = (int)(bloatTimer * .6); + if (bloat != null) + { + Point canvasPoint = bloat.getCanvasTextLocation(graphics, tickCounter, 60); + if (bloatTimer <= 37) + { + renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.WHITE, canvasPoint); + } + else + { + renderTextLocation(graphics, tickCounter+ "( " + secondConversion + " )", 15, Font.BOLD, Color.RED, canvasPoint); + } + } + } + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + if (client.getVar(Varbits.BLOAT_DOOR) == 1) + { + if (!bloatFlag) + { + bloatTimer = 0; + bloatFlag = true; + } + } + } + + public void onNpcSpawned(NpcSpawned event) + { + NPC npc = event.getNpc(); + int id = npc.getId(); + + if (id == NpcID.PESTILENT_BLOAT) + { + this.onStart(); + bloatTimer = 0; + bloat = npc; + } + } + + public void onNpcDespawned(NpcDespawned event) + { + NPC npc = event.getNpc(); + int id = npc.getId(); + + if (id == NpcID.PESTILENT_BLOAT) + { + this.onStop(); + bloatTimer = 0; + bloat = null; + } + } + + public void onGameTick() + { + if (plugin.getRoom() != TheatreRoom.BLOAT) + { + return; + } + + //Color generating code for bloat feet rave edition + int R = (int) (Math.random() * 256); + int G = (int) (Math.random() * 256); + int B = (int) (Math.random() * 256); + color = new Color(R, G, B); //random color, but can be bright or dull + Random random = new Random(); + final float hue = random.nextFloat(); + final float saturation = 0.9f;//1.0 for brilliant, 0.0 for dull + final float luminance = 1.0f; //1.0 for brighter, 0.0 for black + color = Color.getHSBColor(hue, saturation, luminance); + + + counter++; + + if (bloat.getAnimation() == -1) + { + bloatTimer++; + counter = 0; + if (bloat.getHealth() == 0) + { + bloatState = BloatState.DOWN; + } + else + { + bloatState = BloatState.UP; + } + } + else + { + if (25 < counter && counter < 35) + { + bloatState = BloatState.WARN; + } + else if (counter < 26) + { + bloatTimer = 0; + bloatState = BloatState.DOWN; + } + else if (bloat.getModelHeight() == 568) + { + bloatTimer = 0; + bloatState = BloatState.DOWN; + } + else + { + bloatState = BloatState.UP; + } + } + } +} \ 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 new file mode 100644 index 0000000000..936ad57522 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/MaidenHandler.java @@ -0,0 +1,188 @@ +package net.runelite.client.plugins.theatre.rooms; + +import lombok.AccessLevel; +import lombok.Getter; +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.GameTick; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +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.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.List; + +public class MaidenHandler extends RoomHandler +{ + + @Getter(AccessLevel.PACKAGE) + 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 List healers = new ArrayList<>(); + private int healerCount = 0; + private int wave = 1; + private long startTime = 0; + + public MaidenHandler(Client client, TheatrePlugin plugin, TheatreConfig config) + { + super(client, plugin, config); + } + + @Override + 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"); + } + + @Override + public void onStop() + { + this.reset(); + this.plugin.setRoom(TheatreRoom.UNKNOWN); + System.out.println("Stopping Maiden Room"); + } + + 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) + { + if (config.showMaidenBloodToss()) + { + for (WorldPoint point : bloodThrows) + { + drawTile(graphics, point, new Color(36, 248, 229), 2, 150, 10); + } + } + + if (config.showMaidenBloodSpawns()) + { + for (WorldPoint point : bloodSpawnLocation) + { + drawTile(graphics, point, new Color(36, 248, 229), 2, 180, 20); + } + + for (WorldPoint point : bloodSpawnTarget) + { + drawTile(graphics, point, new Color(36, 248, 229), 1, 120, 10); + } + } + } + + 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.onStart(); + } + else if (plugin.getRoom() == TheatreRoom.MAIDEN) + { + if (id == NpcID.BLOOD_SPAWN) + { + if (!bloodSpawns.contains(npc)) + bloodSpawns.add(npc); + } + else if (name != null && name.equalsIgnoreCase("Nylocas Matomenos")) + { + this.healers.add(npc); + } + } + } + + public void onNpcDespawned(NpcDespawned 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) + { + return; + } + + bloodThrows.clear(); + for (GraphicsObject o : client.getGraphicsObjects()) + { + if (o.getId() == TheatreConstant.MAIDEN_BLOOD_THROW) + { + bloodThrows.add(WorldPoint.fromLocal(client, o.getLocation())); + } + } + + bloodSpawnLocation = new ArrayList<>(bloodSpawnTarget); + bloodSpawnTarget.clear(); + for (NPC spawn : bloodSpawns) + { + bloodSpawnTarget.add(spawn.getWorldLocation()); + } + + if(this.healerCount != this.healers.size()) + { + this.healerCount = this.healers.size(); + + long elapsedTime = System.currentTimeMillis() - this.startTime; + long seconds = elapsedTime / 1000L; + + long minutes = seconds / 60L; + seconds = seconds % 60; + + 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); + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..e2158b7b8b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java @@ -0,0 +1,377 @@ +package net.runelite.client.plugins.theatre.rooms; + +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.*; +import net.runelite.api.Point; +import net.runelite.api.coords.WorldPoint; +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.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.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<>(); + + @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); + } + + @Override + public void onStart() + { + if (this.plugin.getRoom() == TheatreRoom.SOTETSEG) + return; + + this.reset(); + this.plugin.setRoom(TheatreRoom.SOTETSEG); + System.out.println("Starting Sotetseg Room"); + } + + @Override + public void onStop() + { + this.reset(); + this.plugin.setRoom(TheatreRoom.UNKNOWN); + System.out.println("Stopping Sotetseg Room"); + } + + public void reset() + { + startTime = 0; + npc = null; + soteyProjectiles.clear(); + redTiles.clear(); + redOverworld.clear(); + blackOverworld.clear(); + blackUnderworld.clear(); + redUnderworld.clear(); + gridPath.clear(); + } + + public void render(Graphics2D graphics) + { + if (config.showSotetsegMaze()) + { + int i = 1; + for (GroundObject o : redTiles.keySet()) + { + Polygon poly = o.getCanvasTilePoly(); + + if (poly != null) + { + graphics.setColor(config.mazeTileColour()); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(poly); + } + + Point textLocation = o.getCanvasTextLocation(graphics, String.valueOf(i), 0); + if (textLocation != null) + { + OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(i), Color.WHITE); + } + + i++; + } + } + + if (config.showSotetsegSolo()) + { + for (WorldPoint p : redOverworld) + { + drawTile(graphics, p, config.mazeTileColour(), 2, 255, 10); + } + } + + if (config.showSotetsegAttacks()) + { + + Map projectileMap = new HashMap<>(); + for(Projectile p : soteyProjectiles.keySet()){ + final int ticksRemaining = p.getRemainingCycles()/30; + int id = p.getId(); + String countdownStr; + if(id == 1607) + { + countdownStr = "R " + String.valueOf(ticksRemaining); + } + else + { + countdownStr = "M " + String.valueOf(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); + } + } + }**/ + } + } + + public void onProjectileMoved(ProjectileMoved event) + { + Projectile projectile = event.getProjectile(); + + //1604 ball + if (event.getPosition().getX() == playerX && event.getPosition().getY() == playerY || event.getProjectile().getId() == 1604) + { + WorldPoint p = WorldPoint.fromLocal(client, event.getPosition()); + soteyProjectiles.put(projectile, p); + } + } + + + public void onNpcSpawned(NpcSpawned event) + { + npc = event.getNpc(); + + if (npc.getName() != null && npc.getName().equals("Sotetseg")) + { + this.onStart(); + } + } + + public void onNpcDespawned(NpcDespawned event) + { + npc = event.getNpc(); + + if (npc.getName() != null && npc.getName().equals("Sotetseg")) + { + redTiles.clear(); + if (client.getPlane() != 3) + { + this.onStop(); + } + } + } + + public void onGroundObjectSpawned(GroundObjectSpawned event) + { + if (plugin.getRoom() != TheatreRoom.SOTETSEG) + { + return; + } + + GroundObject o = event.getGroundObject(); + if (o.getId() == TheatreConstant.GROUNDOBJECT_ID_BLACKMAZE) + { + Tile t = event.getTile(); + WorldPoint p = t.getWorldLocation(); + if (t.getPlane() == 0) + { + if (!blackOverworld.contains(p)) + blackOverworld.add(p); + } + else + { + if (!blackUnderworld.contains(p)) + blackUnderworld.add(p); + } + } + + if (o.getId() == TheatreConstant.GROUNDOBJECT_ID_REDMAZE) + { + Tile t = event.getTile(); + WorldPoint p = t.getWorldLocation(); + if (p.getPlane() == 0){ + if (!redTiles.containsValue(t)) + { + redTiles.put(o, t); + } + } + else + { + if (!redUnderworld.contains(p)) + redUnderworld.add(p); + } + } + } + + public void onGameTick() + { + if (plugin.getRoom() != TheatreRoom.SOTETSEG) + { + return; + } + + //Update player position every game tick + playerX = client.getLocalPlayer().getLocalLocation().getX(); + 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(); + } + } + } + + boolean sotetsegFighting = false; + for (NPC npc : client.getNpcs()) + { + if (npc.getId() == NpcID.SOTETSEG_8388) + { + this.reset(); + sotetsegFighting = true; + break; + } + } + + if (!sotetsegFighting) + { + if (!blackUnderworld.isEmpty() && !redUnderworld.isEmpty() && gridPath.isEmpty()) + { + int minX = 99999; + int minY = 99999; + + for (WorldPoint p : blackUnderworld) + { + int x = p.getX(); + int y = p.getY(); + if (x < minX) + { + minX = x; + } + if (y < minY) + { + minY = y; + } + } + + boolean messageSent = false; + for (WorldPoint p : redUnderworld) + { + WorldPoint pN = new WorldPoint(p.getX(), p.getY() + 1, p.getPlane()); + WorldPoint pS = new WorldPoint(p.getX(), p.getY() - 1, p.getPlane()); + WorldPoint pE = new WorldPoint(p.getX() + 1, p.getY(), p.getPlane()); + WorldPoint pW = new WorldPoint(p.getX() - 1, p.getY(), p.getPlane()); + + if (!((redUnderworld.contains(pN) && redUnderworld.contains(pS)) || + (redUnderworld.contains(pE) && redUnderworld.contains(pW)))) + { + gridPath.add(new Point(p.getX() - minX, p.getY() - minY)); + if (!messageSent) + { + //client.addChatMessage(ChatMessageType.SERVER, "", "Maze path acquired.", null); + messageSent = true; + } + } + + } + } + + if (!blackOverworld.isEmpty() && !gridPath.isEmpty() && redOverworld.isEmpty()) + { + int minX = 99999; + int minY = 99999; + + for (WorldPoint p : blackOverworld) + { + int x = p.getX(); + int y = p.getY(); + if (x < minX) + { + minX = x; + } + if (y < minY){ + minY = y; + } + } + + for (Point p : gridPath) + { + redOverworld.add(new WorldPoint(minX + p.getX(), minY + p.getY(), 0)); + } + } + } + } +} 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 new file mode 100644 index 0000000000..3c3caf8714 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/VerzikHandler.java @@ -0,0 +1,528 @@ +package net.runelite.client.plugins.theatre.rooms; + +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.Actor; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GraphicsObject; +import net.runelite.api.Model; +import net.runelite.api.NPC; +import net.runelite.api.Perspective; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.api.Projectile; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.ProjectileMoved; +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.ui.overlay.OverlayUtil; + +import java.awt.*; +import java.util.*; +import java.util.List; +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<>(); + + @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); + } + + @Override + public void onStart() + { + if (this.plugin.getRoom() == TheatreRoom.VERSIK) + return; + + this.reset(); + this.plugin.setRoom(TheatreRoom.VERSIK); + System.out.println("Starting Verzik Room"); + } + + @Override + public void onStop() + { + this.reset(); + this.plugin.setRoom(TheatreRoom.UNKNOWN); + System.out.println("Stopping Verzik Room"); + } + + public void reset() + { + this.redCrabsTimer = 13; + this.Verzik_RangeProjectiles.clear(); + this.versikCounter = 19; + this.attacksLeft = 0; + this.npc = null; + this.yellows = 0; + this.autosSinceYellows = 0; + this.lastId = -1; + this.tornados = false; + this.startTime = 0; + } + + public void render(Graphics2D graphics) + { + if (npc == null) + { + return; + } + + int id = npc.getId(); + if (config.verzikRangeAttacks()) + { + for (WorldPoint p : getVerzik_RangeProjectiles().values()) + { + drawTile(graphics, p, Color.RED, 2, 180, 50); + } + } + if (config.showVerzikAttacks()) + { + + if (id == TheatreConstant.VERZIK_ID_P1) + { + if(config.p1attacks()) + { + 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); + } + } + } + else if (id == TheatreConstant.VERZIK_ID_P2) + { + if(config.p2attacks()) + { + 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); + } + } + } + +/* + 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()) + { + Model model = npc.getModel(); + 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); + } + } + } + } + + if(config.VerzikTankTile()) + { + if(id == TheatreConstant.VERZIK_ID_P3) + { + WorldPoint wp = new WorldPoint(npc.getWorldLocation().getX() + 3, npc.getWorldLocation().getY() + 3, client.getPlane()); + drawTile2(graphics,wp,new Color(75, 0, 130), 2, 255, 0); + //renderNpcOverlay(graphics, boss, new Color(75, 0, 130), 1, 255, 0); + } + + } + + if (config.showVerzikYellows()) + { + if (this.yellows > 0) + { + String text = Integer.toString(this.yellows); + + for (GraphicsObject object : client.getGraphicsObjects()) + { + if (object.getId() == TheatreConstant.GRAPHIC_ID_YELLOWS) + { + drawTile(graphics, WorldPoint.fromLocal(client, object.getLocation()), Color.YELLOW,3,255,0); + LocalPoint lp = object.getLocation(); + Point point = Perspective.getCanvasTextLocation(client, graphics, lp, text, 0); + renderTextLocation(graphics, text, 12, Font.BOLD, Color.WHITE, point); + } + } + } + } + + if (config.showCrabTargets()) + { + Player local = client.getLocalPlayer(); + if (local != null && local.getName() != null) + { + 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; + + Point point = Perspective.getCanvasTextLocation(client, graphics, lp, target.getName(), 0); + renderTextLocation(graphics, target.getName(), 14, Font.BOLD, color, point); + } + } + } + + } +public void onProjectileMoved(ProjectileMoved event) +{ + 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(); + int id = npc.getId(); + + if (npc.getName() != null && npc.getName().equals("Verzik Vitur")) + { + this.npc = npc; + if (id == TheatreConstant.VERZIK_ID_P3_BAT) + { + this.onStop(); + } + else + { + this.onStart(); + + if (id == TheatreConstant.VERZIK_ID_P1) + { + this.versikCounter = 19; + } + else if (id == TheatreConstant.VERZIK_ID_P2) + { + this.versikCounter = 3; + } + else if (id == TheatreConstant.VERZIK_ID_P3) + { + this.versikCounter = -1; + this.attacksLeft = 9; + } + } + } + } + + public void onAnimationChanged(AnimationChanged event) + { + if (plugin.getRoom() != TheatreRoom.VERSIK) + { + return; + } + + Actor actor = event.getActor(); + if (!(actor instanceof NPC)) + return; + + NPC npc = (NPC) actor; + int id = npc.getId(); + + if (event.getActor().getAnimation() == 8117) + { + redCrabsTimer = 11; + } + + if (id == TheatreConstant.VERZIK_ID_P1) + { + int animation = npc.getAnimation(); + if (animation == TheatreConstant.ANIMATION_ID_P1_ATTACK) + { +// System.out.println("Verzik is shooting her attack on P1."); + versikCounter = 15; + } + } + else if (id == TheatreConstant.VERZIK_ID_P2) + { + int animation = npc.getAnimation(); + if (animation == TheatreConstant.ANIMATION_ID_P2_ATTACK_RANGE || animation == TheatreConstant.ANIMATION_ID_P2_ATTACK_MELEE) + { +// System.out.println("Verzik is shooting her attack on P2."); + versikCounter = 5; + } + else if (animation == TheatreConstant.ANIMATION_ID_P2_SHIELD) + { +// System.out.println("Verzik is healing on P2."); + versikCounter = 13; + } + } + } + + public void onGameTick() + { + if (plugin.getRoom() != TheatreRoom.VERSIK) + { + return; + } + if (!Verzik_RangeProjectiles.isEmpty()) + { + for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext();) + { + Projectile projectile = it.next(); + if (projectile.getRemainingCycles() < 1) + { + it.remove(); + } + } + } + if (this.yellows == 0) + { + //if (this.autosSinceYellows > 0){ + for (GraphicsObject object : client.getGraphicsObjects()) + { + if (object.getId() == TheatreConstant.GRAPHIC_ID_YELLOWS) + { + this.yellows = 14; +// this.versikCounter = 22; + this.autosSinceYellows = 0; + System.out.println("Yellows have spawned."); + break; + } + } + // } + } + else + { + this.yellows--; + } + + if(npc != null) + { + if (npc.getAnimation() == 8117) + { + redCrabsTimer = redCrabsTimer - 1; + } + } + + + boolean foundVerzik = false; + boolean foundTornado = false; + + for (NPC npc : client.getNpcs()) + { + if (npc.getName() != null && npc.getName().equals("Verzik Vitur")) + { + foundVerzik = true; + this.npc = npc; + } else if (npc.getId() == TheatreConstant.NPC_ID_TORNADO) + { + foundTornado = true; + } + + if (foundTornado && foundVerzik) + break; + } + + if (!foundVerzik) + { + this.onStop(); + return; + } + + if (npc == null) + return; + + int id = npc.getId(); + + if (this.lastId != id) + { + this.lastId = id; + + if (id == TheatreConstant.VERZIK_ID_P1) + { + this.startTime = System.currentTimeMillis(); + } + else if (id == TheatreConstant.VERZIK_ID_P1_WALK && this.startTime != 0) + { + long elapsedTime = System.currentTimeMillis() - this.startTime; + long seconds = elapsedTime / 1000L; + + 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); + } + else if (id == TheatreConstant.VERZIK_ID_P2_TRANSFORM && this.startTime != 0) + { + long elapsedTime = System.currentTimeMillis() - this.startTime; + long seconds = elapsedTime / 1000L; + + long minutes = seconds / 60L; + seconds = seconds % 60; + + this.attackTick = this.client.getTickCount() - 4; + 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); + } + } + + if (id == TheatreConstant.VERZIK_ID_P3_BAT) + { + this.onStop(); + return; + } + else if (id == TheatreConstant.VERZIK_ID_P1_WALK) + { + versikCounter = 4; + return; + } + + if (id == TheatreConstant.VERZIK_ID_P1 || id == TheatreConstant.VERZIK_ID_P2) + { + versikCounter--; + if (versikCounter < 0) + versikCounter = 0; + } + else if (id == TheatreConstant.VERZIK_ID_P3) + { + if(foundTornado && !this.tornados) + { + this.tornados = true; + } + + boolean isGreenBall = false; + for (Projectile projectile : client.getProjectiles()) + { + if (projectile.getId() == TheatreConstant.PROJECTILE_ID_P3_GREEN) + { + isGreenBall = projectile.getRemainingCycles() > 210; + break; + } + } + + versikCounter--; + + int animation = npc.getAnimation(); + + switch (animation) + { + case TheatreConstant.ANIMATION_ID_P3_MELEE: + case TheatreConstant.ANIMATION_ID_P3_MAGE: + if (versikCounter < 2) + { + this.attacksLeft--; + if (this.tornados) + { + versikCounter = 5; + } + else + { + versikCounter = 7; + } + + if (attacksLeft < 1) + { + versikCounter = 24; + } + } + break; + case TheatreConstant.ANIMATION_ID_P3_RANGE: + if (versikCounter < 2) + { + attacksLeft--; + if (this.tornados) + { + versikCounter = 5; + } + else + { + versikCounter = 7; + } + + if (attacksLeft < 1) + { + versikCounter = 30; + } + + if (isGreenBall) + { + versikCounter = 12; + } + } + break; + case TheatreConstant.ANIMATION_ID_P3_WEB: + attacksLeft = 4; + versikCounter = 11; + break; + case TheatreConstant.ANIMATION_ID_P3_YELLOW: + attacksLeft = 14; + versikCounter = 11; + break; + } + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..051048733b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloHandler.java @@ -0,0 +1,473 @@ +package net.runelite.client.plugins.theatre.rooms.nylocas; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +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 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 +{ + + @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); + } + + @Override + public void onStart() + { + if (this.plugin.getRoom() == TheatreRoom.NYLOCAS) + return; + + this.reset(); + + this.plugin.setRoom(TheatreRoom.NYLOCAS); + if (overlay == null && config.showNylocasAmount()) + { + overlay = new NyloOverlay(client, plugin, config, this); + plugin.getOverlayManager().add(overlay); + } + + System.out.println("Starting Nylocas Room"); + this.startTime = System.currentTimeMillis(); + this.startTick = this.client.getTickCount(); + } + + @Override + public void onStop() + { + this.reset(); + + this.plugin.setRoom(TheatreRoom.UNKNOWN); + + if (overlay != null) + { + plugin.getOverlayManager().remove(overlay); + overlay = null; + } + + this.predictor = null; + + long elapsedTime = System.currentTimeMillis() - this.startTime; + long seconds = elapsedTime / 1000L; + + long minutes = seconds / 60L; + seconds = seconds % 60; + + if (this.startTime != 0) + { + if(config.extraTimers()) + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'The Nylocas - Waves' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } + System.out.println("Stopping Nylocas Room"); + } + + public void reset() + { + this.pillars.clear(); + this.spiders.clear(); + + this.wave = 0; + + this.predictor = new NyloPredictor(client, this); + this.waveSpawns.clear(); + this.waveAgros.clear(); + this.predictor.reset(); + } + + public void onConfigChanged() + { + if (plugin.getRoom() != TheatreRoom.NYLOCAS) + { + return; + } + + if (overlay == null && config.showNylocasAmount()) + { + overlay = new NyloOverlay(client, plugin, config, this); + plugin.getOverlayManager().add(overlay); + } + else if (overlay != null && !config.showNylocasAmount()) + { + plugin.getOverlayManager().remove(overlay); + overlay = null; + } + } + + private Color healthColorCode(int health) + { + health = Math.max(health, 0); + health = Math.min(health, 100); + + double rMod = 130.0 * health / 100.0; + double gMod = 255.0 * health / 100.0; + double bMod = 125.0 * health / 100.0; + Color c = new Color((int) (255 - rMod), (int) (0 + gMod), (int) (0 + bMod)); + + return c; + } + + public void render(Graphics2D graphics) + { + if (config.showNyloPillarHealth()) + { + for (NPC npc : pillars.keySet()) + { + final int health = pillars.get(npc); + final String healthStr = String.valueOf(health) + "%"; + WorldPoint p = npc.getWorldLocation(); + LocalPoint lp = LocalPoint.fromWorld(client, p.getX() + 1, p.getY() + 1); + + Color c = this.healthColorCode(health); + Point canvasPoint = Perspective.localToCanvas(client, lp, client.getPlane(), 65); + renderTextLocation(graphics, healthStr, 13, Font.BOLD, c, canvasPoint); + } + } + + switch(config.showNylocasExplosions()) + { + case TILE: + for (NPC npc : spiders.keySet()) + { + int ticksLeft = spiders.get(npc); + if (ticksLeft > -1 && ticksLeft < 6) { + Color color = new Color(255, 255,0 ,180); + int outlineWidth = 2; + int outlineAlpha = 150; + renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 15); + } + } + break; + case TIMER: + for (NPC npc : spiders.keySet()) + { + int ticksLeft = spiders.get(npc); + if (ticksLeft > -1 && ticksLeft < 15) + { + String str = Integer.toString(ticksLeft); + LocalPoint lp = npc.getLocalLocation(); + Point point = Perspective.getCanvasTextLocation(client, graphics, lp, str, 0); + renderTextLocation(graphics, str, 13, Font.BOLD, this.healthColorCode(ticksLeft), point); + } + } + break; + case NONE: + break; + } + + 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()) + { + for (NPC npc : new ArrayList(this.waveAgros)) + { + try + { + if (npc.getHealthRatio() == 0 || npc.isDead()) + { + this.waveAgros.remove(npc); + continue; + } + + if (!toHighlight.contains(npc)) + toHighlight.add(npc); + } + catch (Exception ex) + { + + } + } + } + + for (NPC npc : toHighlight) + { + try + { + Polygon objectClickbox = npc.getConvexHull(); + + Color color; + 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) + { + NPC npc = event.getNpc(); + int id = npc.getId(); + + if (id == TheatreConstant.NPC_ID_NYLOCAS_PILLAR) + { + this.onStart(); + this.pillars.put(npc, 100); + this.recalculateLocal(); + } + else if (npc.getName() != null) + { + if (this.plugin.getRoom() == TheatreRoom.NYLOCAS) + { + Pattern p = Pattern.compile("Nylocas (Hagios|Toxobolos|Ischyros)"); + Matcher m = p.matcher(npc.getName()); + if (m.matches()) { + this.spiders.put(npc, 52); + + if (this.predictor != null) + { + this.predictor.onNpcSpawned(event); + } + } + else if (npc.getName().equals("Nylocas Vasilias")) + { + this.onStop(); + } + } + } + } + + public void onNpcDespawned(NpcDespawned event) + { + NPC npc = event.getNpc(); + int id = npc.getId(); + + if (this.waveSpawns.contains(npc)) + { + this.waveSpawns.remove(npc); + } + + if (this.waveAgros.contains(npc)) + { + this.waveAgros.remove(npc); + } + + if (id == TheatreConstant.NPC_ID_NYLOCAS_PILLAR) + { + this.pillars.remove(npc); + } + else if (npc.getName() != null && this.plugin.getRoom() == TheatreRoom.NYLOCAS) + { + Pattern p = Pattern.compile("Nylocas (Hagios|Toxobolos|Ischyros)"); + Matcher m = p.matcher(npc.getName()); + if (m.matches()) + { + this.spiders.remove(npc); + } + } + } + + private void renderPoly(Graphics2D graphics, Color color, Polygon polygon) + { + if (polygon != null) + { + graphics.setColor(color); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(polygon); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20)); + graphics.fill(polygon); + } + } + + public void onGameTick() + { + if (plugin.getRoom() != TheatreRoom.NYLOCAS) + { + return; + } + else + { + boolean findPillar = false; + + for (NPC npc : client.getNpcs()) + { + if (npc.getId() == 8358) + { + findPillar = true; + break; + } + } + + if (!findPillar) + { + this.onStop(); + return; + } + } + + for (NPC spider : new ArrayList<>(spiders.keySet())) + { + int ticksLeft = spiders.get(spider); + + if (ticksLeft < 0) + { + spiders.remove(spider); + continue; + } + + spiders.replace(spider, ticksLeft - 1); + } + + this.recalculateLocal(); + for (NPC pillar : pillars.keySet()) + { + int healthPercent = pillar.getHealthRatio(); + if (healthPercent > -1) + { + pillars.replace(pillar, healthPercent); + } + } + } + + private void recalculateLocal() + { + if (this.pillars != null && this.pillars.size() == 4) + { + int minX = Integer.MAX_VALUE; + int minY = Integer.MAX_VALUE; + for (NPC npc : pillars.keySet()) + { + LocalPoint lp = npc.getLocalLocation(); + if (lp.getSceneX() < minX) + { + minX = lp.getSceneX(); + } + + if (lp.getSceneY() < minY) + { + minY = lp.getSceneY(); + } + } + + int centerX = minX + 5; + int centerY = minY + 5; + + south = new Point(centerX + 1, centerY - 14); + east = new Point(centerX + 15, centerY); + west = new Point(centerX - 14, centerY); + + if (this.predictor != null) + { + this.predictor.southBound = centerY - 12; + this.predictor.eastBound = centerX + 13; + this.predictor.westBound = centerX - 12; + } + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..ba6612b2a9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloOverlay.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2018, Seth + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.theatre.rooms.nylocas; + +import net.runelite.api.Client; +import net.runelite.api.NPC; +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.ui.overlay.Overlay; +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.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +import java.awt.*; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +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) + { + super(plugin); + + setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + setPriority(OverlayPriority.HIGH); + + this.client = client; + this.plugin = plugin; + this.config = config; + this.nylohandler = nylohandler; + + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Nylocas Overlay")); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.getRoom() != TheatreRoom.NYLOCAS) + { + return null; + } + + int hagios = 0; + int toxobolos = 0; + int ischyros = 0; + + for (NPC npc : this.client.getNpcs()) + { + String name = npc.getName(); + if (name != null) + { + if (name.equals("Nylocas Hagios")) + { + hagios++; + } + else if (name.equals("Nylocas Toxobolos")) + { + toxobolos++; + } else if (name.equals("Nylocas Ischyros")) + { + ischyros++; + } + } + } + + panelComponent.getChildren().clear(); + int nyloCount = (hagios + toxobolos + ischyros); + if(nylohandler.getWave() < 21) + { + if(nyloCount > 12) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Total Nylocas:") + .right(nyloCount + " / 12" ) + .rightColor(Color.RED) + .build()); + } + else + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Total Nylocas:") + .right(nyloCount + " / 12" ) + .rightColor(Color.GREEN) + .build()); + + } + + } + else + { + if(nyloCount > 24) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Total Nylocas:") + .right(nyloCount + " / 24" ) + .rightColor(Color.RED) + .build()); + } + else + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Total Nylocas:") + .right(nyloCount + " / 24" ) + .rightColor(Color.GREEN) + .build()); + } + } + + + /** + 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 new file mode 100644 index 0000000000..965b357f23 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/nylocas/NyloPredictor.java @@ -0,0 +1,487 @@ +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.coords.WorldPoint; +import net.runelite.api.events.NpcSpawned; +import net.runelite.client.plugins.theatre.TheatreConfig; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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) + { + 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)), + new Wave(new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.MAGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.RANGE_260, Spawn.WEST), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.RANGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_260, 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_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_260, Spawn.EAST), new Nylocas(NylocasType.RANGE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_162, Spawn.EAST), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MELEE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_260, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_162, Spawn.EAST), new Nylocas(NylocasType.MELEE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MELEE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.MAGE_260, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.EAST), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.RANGE_260, Spawn.WEST), new Nylocas(NylocasType.RANGE_260, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MELEE_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_162, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.WEST), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.EAST), new Nylocas(NylocasType.RANGE_162, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MELEE_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_162, Spawn.SOUTH), new Nylocas(NylocasType.RANGE_162, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_162, Spawn.WEST), new Nylocas(NylocasType.RANGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.RANGE_260, Spawn.WEST), new Nylocas(NylocasType.MAGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MELEE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MELEE_260, Spawn.WEST), new Nylocas(NylocasType.RANGE_260, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_260, Spawn.WEST), new Nylocas(NylocasType.MELEE_260, Spawn.SOUTH), new Nylocas(NylocasType.MAGE_260, Spawn.EAST)), + new Wave(new Nylocas(NylocasType.MAGE_260, Spawn.WEST), new Nylocas(NylocasType.MELEE_260, 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)), + 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; + + public Map currentSpawns = new HashMap(); + public int currentIndex = -1; + + public NyloPredictor(Client client, NyloHandler handler) + { + this.client = client; + this.handler = handler; + this.reset(); + } + + public void reset() + { + this.currentSpawns.clear(); + this.currentIndex = -1; + } + + public int westBound = 50; + + public int eastBound = 77; + + public int southBound = 42; + + public void onNpcSpawned(NpcSpawned event) + { + NPC npc = event.getNpc(); + + LocalPoint lp = npc.getLocalLocation(); + + int x = lp.getSceneX(); + int y = lp.getSceneY(); + + Spawn spawn = null; + if (x <= westBound) + { + spawn = Spawn.WEST; + } + else if (x >= eastBound) + { + spawn = Spawn.EAST; + } + else if (y <= southBound) + { + spawn = Spawn.SOUTH; + } + + NylocasType type = null; + + String name = npc.getName(); + int level = npc.getCombatLevel(); + + 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); + } + + System.out.println(npc.getName() + " | " + npc.getCombatLevel() + " | (" + lp.getSceneX() + ", " + lp.getSceneY() + ") | (" + westBound + ", " + eastBound + ", " + southBound + ") | " + type + " | " + spawn); + + if (spawn == null || type == null) + { + return; + } + + currentSpawns.put(new Nylocas(type, spawn), npc); + this.checkSpawns(); + } + + private void checkSpawns() + { + for (int i = (currentIndex + 1); i < NYLOCAS_WAVES.length; i++) + { + Wave checkWave = NYLOCAS_WAVES[i]; + + List queue = new ArrayList<>(currentSpawns.keySet()); + HashMap npcs = new HashMap(); + + boolean found = true; + for (Nylocas nylocas : checkWave.getSpawns()) + { + if (queue.contains(nylocas)) + { + int index = queue.indexOf(nylocas); + Nylocas hashed = queue.remove(index); + npcs.put(currentSpawns.get(hashed), hashed); + } + else + { + found = false; + break; + } + } + + if (found) + { + currentIndex = i; + currentSpawns.clear(); + + handler.setWave(currentIndex); + System.out.println("Nylocas Wave #" + currentIndex + " has spawned @ " + (this.client.getTickCount() - this.handler.startTick) + " | " + npcs.size() + " size."); + + for (NPC npc : npcs.keySet()) + { + Nylocas nylo = npcs.get(npc); + + if (!this.handler.waveSpawns.contains(npc)) + { + this.handler.waveSpawns.add(npc); + } + + if (this.isAgressive(nylo.getType(), nylo.getSpawn(), currentIndex) && !this.handler.waveAgros.contains(npc)) + { + this.handler.waveAgros.add(npc); + } + } + + int elapsedTicks = client.getTickCount() - this.handler.startTick; + + int mage_count = 0; + int range_count = 0; + int melee_count = 0; + + int mage_level = 0; + int range_level = 0; + int melee_level = 0; + + 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(); + range_count += 1; + } + else if (npc.getName().equalsIgnoreCase("Nylocas Ischyros")) + { + melee_level += npc.getCombatLevel(); + melee_count += 1; + } + } + + for (Nylocas nylocas : checkWave.getSpawns()) + { + NylocasType type = nylocas.getType(); + if (type.name().contains("RANGE")) + { + range_count--; + range_level -= Integer.parseInt(type.name().split("_")[1]); + } + else if (type.name().contains("MAGE")) + { + mage_count--; + mage_level -= Integer.parseInt(type.name().split("_")[1]); + } + else if (type.name().contains("MELEE")) + { + melee_count--; + melee_level -= Integer.parseInt(type.name().split("_")[1]); + } + } + + System.out.printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\n", elapsedTicks, mage_count, mage_level, range_count, range_level, melee_count, melee_level); + } + } + } + + public boolean isAgressive(NylocasType type, Spawn spawn, int wave) + { + if (wave == 0 && spawn == Spawn.WEST) + { + return true; + } + else if (wave == 1 && spawn == Spawn.SOUTH) + { + return true; + } + else if (wave == 2 && spawn == Spawn.EAST) + { + return true; + } + else if (wave == 6 && spawn == Spawn.SOUTH && type == NylocasType.RANGE_260) + { + return true; + } + else if (wave == 7 && spawn == Spawn.WEST) + { + return true; + } + else if (wave == 8 && spawn == Spawn.WEST && type == NylocasType.RANGE_260) + { + return true; + } + else if (wave == 9) + { + if (spawn == Spawn.EAST && type == NylocasType.RANGE_162) + return true; + else if (spawn == Spawn.WEST) + return true; + } + else if (wave == 10 && (spawn == Spawn.EAST || spawn == Spawn.WEST)) + { + return true; + } + else if (wave == 11 && (spawn == Spawn.EAST || spawn == Spawn.WEST)) + { + return true; + } + else if (wave == 12) + { + if (spawn == Spawn.WEST && type == NylocasType.MAGE_162) + return true; + else if (spawn == Spawn.EAST) + return true; + } + else if (wave == 13) + { + if (spawn == Spawn.WEST && type == NylocasType.MELEE_162) + return true; + else if (spawn == Spawn.EAST) + return true; + } + 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 if (wave == 17 && spawn == Spawn.WEST) + { + return true; + } + else if (wave == 18 && spawn == Spawn.EAST) + { + return true; + } + else if (wave == 19 && spawn == Spawn.SOUTH) + { + return true; + } + else if (wave == 20 && (spawn == Spawn.EAST || spawn == Spawn.SOUTH)) + { + return true; + } + else if (wave == 21 && spawn == Spawn.EAST) + { + return true; + } else if (wave == 22 && spawn == Spawn.SOUTH) { + return true; + } + else if (wave == 23) + { + return true; + } + else if ((wave == 24 || wave == 25) && spawn == Spawn.WEST) + { + return true; + } + else if (wave == 26 && spawn == Spawn.SOUTH) + { + return true; + } + else if (wave == 27 && spawn == Spawn.WEST && type == NylocasType.RANGE_162) + { + return true; + } + 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 if (wave == 29 && spawn == Spawn.EAST) + { + return true; + } + + return false; + } + + public int getCurrentWave() + { + return this.currentIndex + 1; + } + + public int getTotalWaves() + { + return NyloPredictor.NYLOCAS_WAVES.length; + } + + public Wave getNextWave() + { + if ((currentIndex + 1) < NYLOCAS_WAVES.length) + { + Wave nextWave = NYLOCAS_WAVES[currentIndex + 1]; + return nextWave; + } else + { + return null; + } + } + + public String getSpawnStr(Spawn spawn, Wave wave) + { + if (wave == null || spawn == null) + { + return null; + } else + { + String types = ""; + + for (Nylocas nylo : wave.getSpawns()) + { + if (nylo.getSpawn() == spawn) + { + if (types.length() > 0) + { + types += ", "; + } + + switch (nylo.getType()) + { + case MAGE_162: + types += "Small Mage"; + break; + case MAGE_260: + types += "Big Mage"; + break; + case MELEE_162: + types += "Small Melee"; + break; + case MELEE_260: + types += "Big Melee"; + break; + case RANGE_162: + types += "Small Range"; + break; + case RANGE_260: + types += "Big Range"; + break; + } + } + } + + return types.length() > 0 ? types : null; + } + } +} \ 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 new file mode 100644 index 0000000000..29ccf9c012 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusCounter.java @@ -0,0 +1,69 @@ +package net.runelite.client.plugins.theatre.rooms.xarpus; + +import net.runelite.api.Client; +import net.runelite.client.plugins.theatre.TheatreConfig; +import net.runelite.client.plugins.theatre.TheatrePlugin; +import net.runelite.client.ui.overlay.*; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; +import java.awt.*; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +public class XarpusCounter extends Overlay +{ + + private final Client client; + private final TheatrePlugin plugin; + private final TheatreConfig config; + + private XarpusHandler xarpusHandler; + + PanelComponent panelComponent = new PanelComponent(); + + public XarpusCounter(Client client, TheatrePlugin plugin, TheatreConfig config, XarpusHandler xarpushandler) + { + super(plugin); + this.client = client; + this.xarpusHandler = xarpushandler; + this.plugin = plugin; + this.config = config; + + setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Theatre xarpus overlay")); + + } + + @Override + public Dimension render(Graphics2D graphics) + { + + if (xarpusHandler.getNpc().getId() == 8339) + { + panelComponent.getChildren().clear(); + String overlayTitle = "Exhume Counter"; + + // Build overlay title + panelComponent.getChildren().add(TitleComponent.builder() + .text(overlayTitle) + .color(Color.GREEN) + .build()); + + //Set the size of overlay + panelComponent.setPreferredSize(new Dimension( + graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0 + )); + + panelComponent.getChildren().add(LineComponent.builder() + .left("Exhumes: ") + .right(String.valueOf(xarpusHandler.getExhumesCount())) + .build()); + + return panelComponent.render(graphics); + } + + return null; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..3f1d1e6804 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/xarpus/XarpusHandler.java @@ -0,0 +1,290 @@ +package net.runelite.client.plugins.theatre.rooms.xarpus; + +import lombok.Getter; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GroundObject; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.Varbits; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.events.GroundObjectSpawned; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.VarbitChanged; +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.plugins.theatre.timers.Timeable; +import net.runelite.client.ui.overlay.OverlayUtil; + +import java.awt.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class XarpusHandler extends RoomHandler +{ + + private int previousTurn; + + private boolean staring; + + private final Map exhumes = new HashMap<>(); + + private int ticksUntilShoot = 8; + + @Getter + private NPC npc; + + private long startTime = 0; + private boolean up = false; + + @Getter + private int exhumesCount; + private boolean xarpusFlag; + + private XarpusCounter overlay = null; + + public XarpusHandler(Client client, TheatrePlugin plugin, TheatreConfig config) + { + super(client, plugin, config); + } + + @Override + public void onStart() + { + if (this.plugin.getRoom() == TheatreRoom.XARPUS) + return; + + this.reset(); + this.plugin.setRoom(TheatreRoom.XARPUS); + + if (overlay == null) + { + overlay = new XarpusCounter(client, plugin, config, this); + plugin.getOverlayManager().add(overlay); + } + + System.out.println("Starting Xarpus Room"); + } + + @Override + public void onStop() + { + this.reset(); + this.plugin.setRoom(TheatreRoom.UNKNOWN); + + if (overlay != null) + { + plugin.getOverlayManager().remove(overlay); + overlay = null; + } + + System.out.println("Stopping Xarpus Room"); + } + + public void reset() + { + exhumesCount = 0; + xarpusFlag = false; + + npc = null; + staring = false; + ticksUntilShoot = 8; + previousTurn = 0; + this.startTime = 0; + this.up = false; + this.exhumes.clear(); + } + + public void render(Graphics2D graphics) + { + if (npc == null) + return; + + if (npc.getId() == NpcID.XARPUS_8340 //&& !staring&& config.showXarpusTick()) + { + if (!this.up) + { + 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); + } + + final String ticksLeftStr = String.valueOf(ticksUntilShoot); + Point canvasPoint = npc.getCanvasTextLocation(graphics, ticksLeftStr, 130); + renderTextLocation(graphics, ticksLeftStr, 12, Font.BOLD, Color.WHITE, canvasPoint); + } + + if (npc.getId() == NpcID.XARPUS_8339 && config.showXarpusHeals()) + { + for (GroundObject o : exhumes.keySet()) + { + Polygon poly = o.getCanvasTilePoly(); + if (poly != null) + { + Color c = new Color(0, 255, 0, 130); + graphics.setColor(c); + graphics.setStroke(new BasicStroke(1)); + graphics.draw(poly); + + String count = Integer.toString(exhumes.get(o) + 1); + LocalPoint lp = o.getLocalLocation(); + Point point = Perspective.getCanvasTextLocation(client, graphics, lp, count, 0); + if (point != null) + { + renderTextLocation(graphics, count, 14, Font.BOLD, Color.WHITE, point); + } + } + } + } + } + + public void onVarbitChanged(VarbitChanged event) + { + if (client.getVar(Varbits.MULTICOMBAT_AREA) == 1 || client.getVarbitValue(client.getVarps(), TheatreConstant.DOOR_VARP) == 2) + { + if (!xarpusFlag) + { + int players = client.getPlayers().size(); + + if (players == 5) + { + exhumesCount = 18; + } + else if (players == 4) + { + exhumesCount = 15; + } + else if (players == 3) + { + exhumesCount = 12; + } + else if (players == 2) + { + exhumesCount = 9; + } + else + { + exhumesCount = 7; + } + + xarpusFlag = true; + } + } + } + + public void onNpcSpawned(NpcSpawned event) + { + NPC npc = event.getNpc(); + + if (npc.getName() != null && npc.getName().equals("Xarpus")) + { + this.onStart(); + this.npc = npc; + } + } + + public void onNpcDespawned(NpcDespawned event) + { + NPC npc = event.getNpc(); + + if (npc.getName() != null && npc.getName().equals("Xarpus")) + { + this.onStop(); + } + } + + public void onGroundObjectSpawned(GroundObjectSpawned event) + { + if (plugin.getRoom() != TheatreRoom.XARPUS) + { + return; + } + + GroundObject o = event.getGroundObject(); + if (o.getId() == TheatreConstant.GROUNDOBJECT_ID_EXHUMED) + { + if (this.startTime == 0) + { + this.startTime = System.currentTimeMillis() - 2000L; + } + +// exhumes.put(o, 18); + exhumes.put(o, 11); + } + } + + public void onGameTick() + { + if (plugin.getRoom() != TheatreRoom.XARPUS) + { + return; + } + + for (GroundObject key : new ArrayList<>(exhumes.keySet())) + { + int i = exhumes.get(key) - 1; + if (i >= 0) + { + exhumes.replace(key, i); + } else + { + exhumes.remove(key); + this.exhumesCount--; + } + } + + if (npc.getOverheadText() != null) + { + if (!staring) + { + staring = true; + + long elapsedTime = System.currentTimeMillis() - this.startTime; + long seconds = elapsedTime / 1000L; + + long minutes = seconds / 60L; + seconds = seconds % 60; + if(config.extraTimers()) + this.client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Wave 'Xarpus - Acid' completed! Duration: " + minutes + ":" + twoDigitString(seconds), null); + } + + ticksUntilShoot = 6; + } + + ticksUntilShoot--; + ticksUntilShoot = Math.max(0, ticksUntilShoot); + if (ticksUntilShoot <= 0) + { + ticksUntilShoot = 4; + } + + if (previousTurn != npc.getOrientation()) + { + if (staring) + { + ticksUntilShoot = 8; + } + else + { + ticksUntilShoot = 4; + } + + previousTurn = npc.getOrientation(); + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..60ea5bd7e3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/RoomTimer.java @@ -0,0 +1,84 @@ +package net.runelite.client.plugins.theatre.timers; + +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.client.plugins.theatre.TheatrePlugin; +import net.runelite.client.ui.overlay.Overlay; +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.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +import javax.inject.Inject; + +import java.awt.*; +import java.util.Map; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +public class RoomTimer extends Overlay +{ + + private final Client client; + + private final TheatrePlugin plugin; + + private final PanelComponent panelComponent = new PanelComponent(); + + + @Inject + public RoomTimer(Client client, TheatrePlugin plugin) + { + super(plugin); + + setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + setPriority(OverlayPriority.HIGH); + + this.client = client; + this.plugin = plugin; + + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "TOB Timer Overlay")); + } + + + @Override + public Dimension render(Graphics2D graphics) + { + panelComponent.getChildren().clear(); + + Player local = client.getLocalPlayer(); + if (local == null || local.getName() == null) + return null; + + switch(plugin.getRoom()) + { + case MAIDEN: + plugin.getMaidenHandler().render(graphics); + break; + case BLOAT: + plugin.getBloatHandler().render(graphics); + break; + case NYLOCAS: + plugin.getNyloHandler().render(graphics); + break; + case SOTETSEG: + plugin.getSotetsegHandler().render(graphics); + break; + case XARPUS: + plugin.getXarpusHandler().render(graphics); + break; + case VERSIK: + plugin.getVerzikHandler().render(graphics); + break; + default: + break; + } + + panelComponent.getChildren().add(TitleComponent.builder().text("Room Timer").color(Color.WHITE).build()); + + return panelComponent.render(graphics); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..e19452b435 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/timers/Timeable.java @@ -0,0 +1,8 @@ +package net.runelite.client.plugins.theatre.timers; + +import java.util.HashMap; + +public interface Timeable +{ + public abstract HashMap getTimes(); +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java deleted file mode 100644 index 698203f54c..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.runelite.client.plugins.ztob; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Polygon; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; - -public class BloatTimerOverlay extends Overlay -{ - - private final Client client; - private final TheatrePlugin plugin; - private final TheatreConfig config; - - @Inject - private BloatTimerOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) - { - this.client = client; - this.plugin = plugin; - this.config = config; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - setLayer(OverlayLayer.ABOVE_SCENE); - } - - public Dimension render(Graphics2D graphics) - { - - if (config.bloatTimer()) - { - final String tickCounter = String.valueOf(plugin.bloatTimer); - int secondConversion = (int) (plugin.bloatTimer * .6); - if (plugin.getBloat_NPC() != null) - { - Point canvasPoint = plugin.getBloat_NPC().getCanvasTextLocation(graphics, tickCounter, 60); - if (plugin.bloatTimer <= 37) - { - renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.WHITE, canvasPoint); - } - else - { - renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.RED, canvasPoint); - } - } - } - - - return null; - } - - private 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; - } - //OverlayUtil.renderPolygon(graphics, poly, color); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); - graphics.setStroke(new BasicStroke(strokeWidth)); - graphics.draw(poly); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); - graphics.fill(poly); - } - - private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, net.runelite.api.Point canvasPoint) - { - graphics.setFont(new Font("Arial", fontStyle, fontSize)); - if (canvasPoint != null) - { - final net.runelite.api.Point canvasCenterPoint = new net.runelite.api.Point( - canvasPoint.getX(), - canvasPoint.getY()); - final net.runelite.api.Point canvasCenterPoint_shadow = new Point( - canvasPoint.getX() + 1, - canvasPoint.getY() + 1); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java deleted file mode 100644 index 5d11b59919..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI - * No rights reserved. Use, redistribute, and modify at your own discretion, - * and in accordance with Yagex and RuneLite guidelines. - * However, aforementioned monkey would prefer if you don't sell this plugin for profit. - * Good luck on your raids! - */ - -package net.runelite.client.plugins.ztob; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.Stub; - -@ConfigGroup("Theatre") - -public interface TheatreConfig extends Config -{ - @ConfigItem( - keyName = "maidenStub", - name = "Maiden", - description = "", - position = 0 - ) - default Stub maidenStub() - { - return new Stub(); - } - - @ConfigItem( - position = 1, - keyName = "MaidenBlood", - name = "Maiden blood attack", - description = "", - parent = "maidenStub" - ) - default boolean MaidenBlood() - { - return true; - } - - @ConfigItem( - position = 2, - keyName = "MaidenSpawns", - name = "Maiden blood spawns", - description = "", - parent = "maidenStub" - ) - default boolean MaidenSpawns() - { - return true; - } - - @ConfigItem( - keyName = "bloatStub", - name = "Bloat", - description = "", - position = 3 - ) - default Stub bloatStub() - { - return new Stub(); - } - - @ConfigItem( - position = 4, - keyName = "BloatIndicator", - name = "Bloat Indicator", - description = "", - parent = "bloatStub" - ) - default boolean BloatIndicator() - { - return true; - } - - @ConfigItem( - position = 5, - keyName = "bloat Timer", - name = "Bloat Timer", - description = "", - parent = "bloatStub" - ) - default boolean bloatTimer() - { - return true; - } - - @ConfigItem( - position = 6, - keyName = "bloatFeet", - name = "Bloat Feet", - description = "", - parent = "bloatStub" - ) - default boolean bloatFeetIndicator() - { - return true; - } - - @ConfigItem( - keyName = "nylocasStub", - name = "Nylocas", - description = "", - position = 7 - ) - default Stub NylocasStub() - { - return new Stub(); - } - - @ConfigItem( - position = 8, - keyName = "NyloPillars", - name = "Nylocas pillar health", - description = "", - parent = "nylocasStub" - ) - default boolean NyloPillars() - { - return true; - } - - - @ConfigItem( - position = 9, - keyName = "NyloBlasts", - name = "Nylocas explosions", - description = "", - parent = "nylocasStub" - ) - default boolean NyloBlasts() - { - return true; - } - - @ConfigItem( - position = 10, - keyName = "NyloMenu", - name = "Hide Attack options for Nylocas", - description = "", - parent = "nylocasStub" - ) - - default boolean NyloMenu() - { - return true; - } - - @ConfigItem( - keyName = "sotetsegStub", - name = "Sotetseg", - description = "", - position = 11 - ) - default Stub sotetsegStub() - { - return new Stub(); - } - - @ConfigItem( - position = 12, - keyName = "highlightSote", - name = "Sotetseg Missiles", - description = "Highlight Sotetseg's Missiles with pray type", - parent = "sotetsegStub" - ) - default boolean highlightSote() - { - return true; - } - - @ConfigItem( - position = 13, - keyName = "SotetsegMaze1", - name = "Sotetseg maze", - description = "", - parent = "sotetsegStub" - ) - default boolean SotetsegMaze1() - { - return true; - } - - @ConfigItem( - position = 14, - keyName = "SotetsegMaze2", - name = "Sotetseg maze (solo mode)", - description = "", - parent = "sotetsegStub" - ) - default boolean SotetsegMaze2() - { - return true; - } - - @ConfigItem( - keyName = "xarpusStub", - name = "Xarpus", - description = "", - position = 15 - ) - default Stub xarpusStub() - { - return new Stub(); - } - - @ConfigItem( - position = 16, - keyName = "XarpusExhumed", - name = "Xarpus Exhumed", - description = "", - parent = "xarpusStub" - ) - default boolean XarpusExhumed() - { - return true; - } - - @ConfigItem( - position = 17, - keyName = "XarpusTick", - name = "Xarpus Tick", - description = "", - parent = "xarpusStub" - ) - default boolean XarpusTick() - { - return false; - } - - @ConfigItem( - position = 18, - keyName = "xarpusExhumes", - name = "Xarpus Exhume Counter", - description = "", - parent = "xarpusStub" - ) - default boolean XarpusExhumeOverlay() - { - return false; - } - - @ConfigItem( - keyName = "verzikStub", - name = "Verzik", - description = "", - position = 19 - ) - default Stub verzikStub() - { - return new Stub(); - } - - @ConfigItem( - position = 20, - keyName = "VerzikCupcakes", - name = "Verzik Projectile Markers", - description = "", - parent = "verzikStub" - ) - default boolean VerzikCupcakes() - { - return false; - } - - @ConfigItem( - position = 21, - keyName = "VerzikTick", - name = "Verzik P3 Tick", - description = "", - parent = "verzikStub" - ) - default boolean VerzikTick() - { - return false; - } - - @ConfigItem( - position = 22, - keyName = "VerzikMelee", - name = "Verzik P3 Melee Range", - description = "", - parent = "verzikStub" - ) - default boolean VerzikMelee() - { - return false; - } - - @ConfigItem( - position = 23, - keyName = "VerzikYellow", - name = "Verzik Yellow Timing", - description = "", - parent = "verzikStub" - ) - default boolean VerzikYellow() - { - return false; - } - - @ConfigItem( - keyName = "verzikOverlayStub", - name = "Overlay", - description = "", - position = 24, - parent = "verzikStub" - ) - default Stub verzikOverlayStub() - { - return new Stub(); - } - - @ConfigItem( - position = 25, - keyName = "Verzik Nylo", - name = "Verzik Nylo Overlay", - description = "", - parent = "verzikOverlayStub" - ) - default boolean NyloTargetOverlay() - { - return false; - } - - @ConfigItem( - position = 26, - keyName = "VerzikTankTile", - name = "Verzik P3 Tile Overlay", - description = "", - parent = "verzikOverlayStub" - ) - default boolean verzikTankTile() - { - return true; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java deleted file mode 100644 index 222e83d8ac..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI - * No rights reserved. Use, redistribute, and modify at your own discretion, - * and in accordance with Yagex and RuneLite guidelines. - * However, aforementioned monkey would prefer if you don't sell this plugin for profit. - * Good luck on your raids! - */ - -package net.runelite.client.plugins.ztob; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Polygon; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import javax.inject.Inject; -import net.runelite.api.Client; -import net.runelite.api.GroundObject; -import net.runelite.api.NPC; -import net.runelite.api.NPCComposition; -import net.runelite.api.NpcID; -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.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; - -public class TheatreOverlay extends Overlay -{ - private final Client client; - private final TheatrePlugin plugin; - private final TheatreConfig config; - - @Inject - private TheatreOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) - { - this.client = client; - this.plugin = plugin; - this.config = config; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - setLayer(OverlayLayer.ABOVE_SCENE); - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (plugin.isRunMaiden()) - { - if (config.MaidenBlood()) - { - for (WorldPoint point : plugin.getMaiden_BloodSpatters()) - { - drawTile(graphics, point, new Color(36, 248, 229), 2, 150, 10); - } - } - - if (config.MaidenSpawns()) - { - for (WorldPoint point : plugin.getMaiden_SpawnLocations()) - { - drawTile(graphics, point, new Color(36, 248, 229), 2, 180, 20); - } - for (WorldPoint point : plugin.getMaiden_SpawnLocations2()) - { - drawTile(graphics, point, new Color(36, 248, 229), 1, 120, 10); - } - } - } - - if (plugin.isRunBloat() && config.BloatIndicator()) - { - if (config.bloatFeetIndicator()) - { - if (plugin.getTemp().size() > 0) - { - if (plugin.isTempFlag()) - { - for (WorldPoint point : plugin.getTemp()) - { - - drawTile(graphics, point, Color.black, 4, 255, 0); - - } - - } - } - else if (plugin.getTemp2().size() > 0) - { - if (plugin.isTemp2Flag()) - { - for (WorldPoint point : plugin.getTemp2()) - { - - drawTile(graphics, point, Color.black, 4, 255, 0); - - - } - - } - } - } - NPC bloat = plugin.getBloat_NPC(); - int state = plugin.getBloat_State(); - if (bloat == null) - { - return null; - } - switch (state) - { - case 2: - renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); - break; - case 3: - renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); - break; - default: - renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); - break; - } - } - - if (plugin.isRunNylocas()) - { - if (config.NyloPillars()) - { - Map pillars = plugin.getNylocas_Pillars(); - for (NPC npc : pillars.keySet()) - { - final int health = pillars.get(npc); - final String healthStr = health + "%"; - WorldPoint p = npc.getWorldLocation(); - LocalPoint lp = LocalPoint.fromWorld(client, p.getX() + 1, p.getY() + 1); - final double rMod = 130.0 * health / 100.0; - final double gMod = 255.0 * health / 100.0; - final double bMod = 125.0 * health / 100.0; - final Color c = new Color((int) (255 - rMod), (int) (0 + gMod), (int) (0 + bMod)); - Point canvasPoint = Perspective.localToCanvas(client, lp, client.getPlane(), - 65); - renderTextLocation(graphics, healthStr, 13, Font.BOLD, c, canvasPoint); - } - } - - if (config.NyloBlasts()) - { - final Map npcMap = plugin.getNylocas_Map(); - for (NPC npc : npcMap.keySet()) - { - int ticksLeft = npcMap.get(npc); - if (ticksLeft > -1) - { - if (ticksLeft <= 6) - { - Color color = new Color(255, 255, 0, 180); - int outlineWidth = 2; - int outlineAlpha = 150; - renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 15); - } - } - } - } - } - - if (plugin.isRunSotetseg()) - { - if (config.highlightSote()) - { - for (Projectile projectile : plugin.getSotetseg_MageProjectiles()) - { - String text = "Mage"; - int x = (int) projectile.getX(); - int y = (int) projectile.getY(); - LocalPoint projectilePoint = new LocalPoint(x, y); - Point textLocation = Perspective.getCanvasTextLocation(client, graphics, projectilePoint, text, 0); - if (textLocation != null) - { - OverlayUtil.renderTextLocation(graphics, textLocation, text, Color.CYAN); - } - } - - for (Projectile projectile : plugin.getSotetseg_RangeProjectiles()) - { - String text = "Range"; - int x = (int) projectile.getX(); - int y = (int) projectile.getY(); - LocalPoint projectilePoint = new LocalPoint(x, y); - Point textLocation = Perspective.getCanvasTextLocation(client, graphics, projectilePoint, text, 0); - if (textLocation != null) - { - OverlayUtil.renderTextLocation(graphics, textLocation, text, Color.GREEN); - } - } - } - - if (config.SotetsegMaze1()) - { - int i = 1; - for (GroundObject o : plugin.getRedTiles().keySet()) - { - Polygon poly = o.getCanvasTilePoly(); - if (poly != null) - { - graphics.setColor(Color.WHITE); - graphics.setStroke(new BasicStroke(2)); - graphics.draw(poly); - } - Point textLocation = o.getCanvasTextLocation(graphics, String.valueOf(i), 0); - if (textLocation != null) - { - OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(i), Color.WHITE); - } - - i++; - } - } - - if (config.SotetsegMaze2()) - { - for (WorldPoint p : plugin.getRedTilesOverworld()) - { - drawTile(graphics, p, Color.WHITE, 2, 255, 10); - } - } - } - - - if (plugin.isRunXarpus()) - { - NPC boss = plugin.getXarpus_NPC(); - - if (boss.getId() == NpcID.XARPUS_8340 && !plugin.isXarpus_Stare() && config.XarpusTick()) - { - int tick = plugin.getXarpus_TicksUntilShoot(); - if (tick < 1) - { - tick = tick % 4 + 4; - } - final String ticksLeftStr = String.valueOf(tick); - Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 130); - renderTextLocation(graphics, ticksLeftStr, 12, Font.BOLD, Color.WHITE, canvasPoint); - } - if (boss.getId() == NpcID.XARPUS_8339 && config.XarpusExhumed()) - { - for (GroundObject o : plugin.getXarpus_Exhumeds().keySet()) - { - - - Polygon poly = o.getCanvasTilePoly(); - if (poly != null) - { - graphics.setColor(new Color(0, 255, 0, 130)); - graphics.setStroke(new BasicStroke(1)); - graphics.draw(poly); - } - } - for (Map.Entry exhumes : plugin.getXarpusExhumedsTimer().entrySet()) - { - final String ticksremaining = String.valueOf(exhumes.getValue()); - if (Integer.valueOf(ticksremaining) > 0) - { - GroundObject ex = exhumes.getKey(); - Point point = ex.getCanvasTextLocation(graphics, ticksremaining, 0); - renderTextLocation(graphics, ticksremaining, 12, Font.BOLD, Color.white, point); - } - - } - - - } - - } - - - if (plugin.isRunVerzik()) - { - - - if (config.VerzikCupcakes()) - { - for (WorldPoint p : plugin.getVerzik_RangeProjectiles().values()) - { - drawTile(graphics, p, Color.RED, 2, 180, 50); - } - } - - if (config.VerzikYellow()) - { - for (WorldPoint p : plugin.getVerzik_YellowTiles()) - { - drawTile(graphics, p, Color.YELLOW, 3, 255, 0); - Projectile yellowBall = plugin.getVerzik_YellowBall(); - if (yellowBall != null) - { - final int ticksToImpact = yellowBall.getRemainingCycles() / 30; - final String countdownStr = String.valueOf(ticksToImpact); - Point canvasPoint = Perspective.getCanvasTextLocation(client, graphics, LocalPoint.fromWorld(client, p), countdownStr, 0); - renderTextLocation(graphics, countdownStr, 12, Font.BOLD, Color.WHITE, canvasPoint); - - } - } - } - - final NPC boss = plugin.getVerzik_NPC(); - if (boss.getId() == NpcID.VERZIK_VITUR_8374) - { - if (config.verzikTankTile()) - { - renderNpcOverlay(graphics, boss, new Color(75, 0, 130), 1, 255, 0); - } - - if (config.VerzikTick()) - { - final int ticksLeft = plugin.getP3_TicksUntilAttack(); - if (ticksLeft > 0 && ticksLeft < 8) - { - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); - renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); - } - } - - if (config.VerzikMelee()) - { - List meleeRange = getHitSquares(boss.getWorldLocation(), 7, 1, false); - - for (WorldPoint p : meleeRange) - { - drawTile(graphics, p, Color.WHITE, 1, 155, 10); - } - } - } - - if (boss.getAnimation() == 8117) - { - final int ticksLeft = plugin.getRedCrabsTimer(); - if (ticksLeft > 0) - { - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); - renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); - } - } - - } - - return null; - } - - private 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; - } - //OverlayUtil.renderPolygon(graphics, poly, color); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); - graphics.setStroke(new BasicStroke(strokeWidth)); - graphics.draw(poly); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); - graphics.fill(poly); - } - - private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) - { - int size = 1; - NPCComposition composition = actor.getTransformedComposition(); - if (composition != null) - { - size = composition.getSize(); - } - LocalPoint lp = actor.getLocalLocation(); - Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); - - if (tilePoly != null) - { - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); - graphics.setStroke(new BasicStroke(outlineWidth)); - graphics.draw(tilePoly); - graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); - graphics.fill(tilePoly); - } - } - - private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) - { - graphics.setFont(new Font("Arial", fontStyle, fontSize)); - if (canvasPoint != null) - { - final Point canvasCenterPoint = new Point( - canvasPoint.getX(), - canvasPoint.getY()); - final Point canvasCenterPoint_shadow = new Point( - canvasPoint.getX() + 1, - canvasPoint.getY() + 1); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); - } - } - - private 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; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java deleted file mode 100644 index 9b99327f11..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI - * No rights reserved. Use, redistribute, and modify at your own discretion, - * and in accordance with Yagex and RuneLite guidelines. - * However, aforementioned monkey would prefer if you don't sell this plugin for profit. - * Good luck on your raids! - */ - -package net.runelite.client.plugins.ztob; - -import com.google.inject.Provides; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.GraphicsObject; -import net.runelite.api.GroundObject; -import net.runelite.api.ItemID; -import net.runelite.api.MenuEntry; -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.Varbits; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.AnimationChanged; -import net.runelite.api.events.GameTick; -import net.runelite.api.events.GraphicsObjectCreated; -import net.runelite.api.events.GroundObjectSpawned; -import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.NpcDespawned; -import net.runelite.api.events.NpcSpawned; -import net.runelite.api.events.ProjectileMoved; -import net.runelite.api.events.VarbitChanged; -import net.runelite.api.kit.KitType; -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.PluginType; -import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.Text; - -@PluginDescriptor( - name = "Theater of Blood", - description = "All-in-one plugin for Theatre of Blood", - tags = {"ToB", "theatre", "blood"}, - enabledByDefault = false, - type = PluginType.PVM -) - -public class TheatrePlugin extends Plugin -{ - private static final int GRAPHICSOBJECT_ID_MAIDEN = 1579; - private static final int NPCID_NYLOCAS_PILLAR = 8358; - private static final int GROUNDOBJECT_ID_BLACKMAZE = 33034; - private static final int GROUNDOBJECT_ID_REDMAZE = 33035; - private static final int GROUNDOBJECT_ID_EXHUMED = 32743; - private static final int ANIMATION_ID_XARPUS = 8059; - private static final int GRAPHICSOBJECT_ID_YELLOW = 1595; - private static final int PROJECTILE_ID_P2RANGE = 1583; - private static final int PROJECTILE_ID_YELLOW = 1596; - private static final int ANIMATION_ID_P3_WEB = 8127; - private static final int ANIMATION_ID_P3_YELLOW = 8126; - private static final int ANIMATION_ID_P3_MELEE = 8123; - private static final int ANIMATION_ID_P3_MAGE = 8124; - private static final int ANIMATION_ID_P3_RANGE = 8125; - private static final int VERZIK_ID_P3 = NpcID.VERZIK_VITUR_8374; - private static final int NPC_ID_TORNADO = 8386; - private static final int PROJECTILE_ID_P3_GREEN = 1598; - - - @Getter - int exhumecount; - - @Getter(AccessLevel.PACKAGE) - private final Map xarpusExhumedsTimer = new HashMap<>(); - - @Getter - int bloatTimer = 0; - - int bloatFeetTimer = 0; - - @Getter - private Set bloatTiles = new HashSet<>(); - - @Getter - private Set temp = new HashSet<>(); - - @Getter - private Set temp2 = new HashSet<>(); - - @Getter - private Set localTemp = new HashSet<>(); - NPC BossNylo = null; - private boolean bloatFlag = false; - - //@Getter - //private List bloatTiles = new ArrayList<>(); - - - @Getter(AccessLevel.PACKAGE) - private boolean runMaiden; - - @Getter(AccessLevel.PACKAGE) - private List Maiden_BloodSpatters = new ArrayList<>(); - - private List Maiden_Spawns = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private List Maiden_SpawnLocations = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private List Maiden_SpawnLocations2 = new ArrayList<>(); - - - @Getter(AccessLevel.PACKAGE) - private boolean runBloat; - - @Getter(AccessLevel.PACKAGE) - private NPC Bloat_NPC; - - private int Bloat_downCount; - - @Getter(AccessLevel.PACKAGE) - private Integer Bloat_State; - - - @Getter(AccessLevel.PACKAGE) - private boolean runNylocas; - - @Getter(AccessLevel.PACKAGE) - private Map Nylocas_Pillars = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private Map Nylocas_Map = new HashMap<>(); - - - @Getter(AccessLevel.PACKAGE) - private boolean runSotetseg; - - @Getter(AccessLevel.PACKAGE) - private final Map RedTiles = new LinkedHashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private List RedTilesOverworld = new ArrayList<>(); - - private List BlackTilesOverworld = new ArrayList<>(); - @Getter - private boolean tempFlag = false; - @Getter - private boolean temp2Flag = false; - - private List GridPath = new ArrayList<>(); - private List BlackTilesUnderworld = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private boolean runXarpus; - - private int Xarpus_previousAnimation; - - @Getter(AccessLevel.PACKAGE) - private boolean Xarpus_Stare; - - @Getter(AccessLevel.PACKAGE) - private final Map Xarpus_Exhumeds = new HashMap<>(); - private List RedTilesUnderworld = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private int Xarpus_TicksUntilShoot = 9; - - @Getter(AccessLevel.PACKAGE) - private NPC Xarpus_NPC; - - @Getter(AccessLevel.PACKAGE) - private boolean runVerzik; - - @Getter(AccessLevel.PACKAGE) - private final Map Verzik_RangeProjectiles = new HashMap<>(); - - @Getter(AccessLevel.PACKAGE) - private final List Sotetseg_MageProjectiles = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private final List Sotetseg_RangeProjectiles = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private int P3_TicksUntilAttack = -1; - - @Getter(AccessLevel.PACKAGE) - private Projectile Verzik_YellowBall; - - @Getter(AccessLevel.PACKAGE) - private List Verzik_YellowTiles = new ArrayList<>(); - - @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC; - - @Getter(AccessLevel.PACKAGE) - private List tornadoList; - - @Getter(AccessLevel.PACKAGE) - private List crabList; - - @Getter - private int redCrabsTimer; - - private int P3_attacksLeft; - - @Inject - private Client client; - - @Inject - private OverlayManager overlayManager; - - @Inject - private TheatreOverlay overlay; - - @Inject - private TheatreConfig config; - - @Inject - private TheatreXarpusOverlay xarpusOverlay; - - @Inject - private ChatMessageManager chatMessageManager; - - @Inject - private VerzikNyloOverlay verzikNyloOverlay; - - @Inject - private BloatTimerOverlay bloatTimerOverlay; - - @Provides - TheatreConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(TheatreConfig.class); - } - - @Override - protected void startUp() - { - overlayManager.add(overlay); - overlayManager.add(xarpusOverlay); - overlayManager.add(verzikNyloOverlay); - overlayManager.add(bloatTimerOverlay); - } - - @Override - protected void shutDown() - { - overlayManager.remove(overlay); - overlayManager.remove(xarpusOverlay); - overlayManager.remove(xarpusOverlay); - overlayManager.remove(bloatTimerOverlay); - } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) - { - if (client.getGameState() != GameState.LOGGED_IN || !config.NyloMenu() || !runNylocas) - { - return; - } - - final String pOptionToReplace = Text.removeTags(event.getOption()).toUpperCase(); - - int attackType = 0; //0=idk 1= melee 2= range 3= mage - - for (KitType kitType : KitType.values()) - { - int itemId = client.getLocalPlayer().getPlayerComposition().getEquipmentId(kitType); - switch (itemId) - { - case ItemID.DRAGON_CLAWS: - case ItemID.SCYTHE_OF_VITUR: - case ItemID.SCYTHE_OF_VITUR_UNCHARGED: - case ItemID.SCYTHE_10735: - case ItemID.SCYTHE_OF_VITUR_22664: - case ItemID.HAM_JOINT: - case ItemID.EVENT_RPG: - case ItemID.ABYSSAL_WHIP: - case ItemID.ABYSSAL_TENTACLE: - case ItemID.FROZEN_ABYSSAL_WHIP: - case ItemID.VOLCANIC_ABYSSAL_WHIP: - case ItemID.GHRAZI_RAPIER: - case ItemID.DRAGON_WARHAMMER: - case ItemID.DRAGON_WARHAMMER_20785: - case ItemID.BANDOS_GODSWORD: - case ItemID.BANDOS_GODSWORD_OR: - case ItemID.BANDOS_GODSWORD_20782: - case ItemID.BANDOS_GODSWORD_21060: - case ItemID.CRYSTAL_HALBERD_510: - case ItemID.CRYSTAL_HALBERD_510_I: - case ItemID.CRYSTAL_HALBERD_610: - case ItemID.CRYSTAL_HALBERD_610_I: - case ItemID.CRYSTAL_HALBERD_710_I: - case ItemID.CRYSTAL_HALBERD_710: - case ItemID.CRYSTAL_HALBERD_110: - case ItemID.CRYSTAL_HALBERD_110_I: - case ItemID.CRYSTAL_HALBERD_210: - case ItemID.CRYSTAL_HALBERD_310: - case ItemID.CRYSTAL_HALBERD_310_I: - case ItemID.CRYSTAL_HALBERD_410: - case ItemID.CRYSTAL_HALBERD_410_I: - case ItemID.CRYSTAL_HALBERD_810: - case ItemID.CRYSTAL_HALBERD_810_I: - case ItemID.CRYSTAL_HALBERD_910: - case ItemID.CRYSTAL_HALBERD_910_I: - attackType = 1; - break; - case ItemID.TOXIC_BLOWPIPE: - case ItemID.TOXIC_BLOWPIPE_EMPTY: - case ItemID.RED_CHINCHOMPA_10034: - case ItemID.BLACK_CHINCHOMPA: - case ItemID.CHINCHOMPA_10033: - case ItemID.TWISTED_BOW: - attackType = 2; - break; - case ItemID.SANGUINESTI_STAFF: - case ItemID.TOXIC_STAFF_OF_THE_DEAD: - case ItemID.TRIDENT_OF_THE_SWAMP: - case ItemID.TRIDENT_OF_THE_SEAS_E: - case ItemID.TRIDENT_OF_THE_SEAS: - case ItemID.TRIDENT_OF_THE_SWAMP_E: - case ItemID.KODAI_WAND: - case ItemID.MASTER_WAND: - case ItemID.MASTER_WAND_20560: - attackType = 3; - break; - } - if (attackType != 0) - { - break; - } - - } - - if (!pOptionToReplace.equals("ATTACK")) - { - return; - } - int Id = 0; - if (BossNylo != null) - { - Id = BossNylo.getId(); - } - String target = Text.removeTags(event.getTarget()).toLowerCase(); - if (attackType != 0) - { - stripEntries(attackType, target, Id); - } - - } - - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) - { - - NPC npc = npcSpawned.getNpc(); - switch (npc.getId()) - { - case NpcID.THE_MAIDEN_OF_SUGADINTI: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8363: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8364: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8365: - runMaiden = true; - break; - case NpcID.BLOOD_SPAWN: - Maiden_Spawns.add(npc); - break; - case NpcID.PESTILENT_BLOAT: - runBloat = true; - Bloat_NPC = npc; - bloatTimer = 0; - bloatFlag = false; - break; - case NpcID.NYLOCAS_VASILIAS: - case NpcID.NYLOCAS_VASILIAS_8355: - case NpcID.NYLOCAS_VASILIAS_8356: - case NpcID.NYLOCAS_VASILIAS_8357: - BossNylo = npc; - break; - case NPCID_NYLOCAS_PILLAR: - runNylocas = true; - if (!Nylocas_Pillars.keySet().contains(npc)) - { - Nylocas_Pillars.put(npc, 100); - } - break; - case 8342: - case 8343: - case 8344: - case 8345: - case 8346: - case 8347: - case 8348: - case 8349: - case 8350: - case 8351: - case 8352: - case 8353: - if (runNylocas) - { - Nylocas_Map.put(npc, 52); - } - break; - case NpcID.SOTETSEG: - case NpcID.SOTETSEG_8388: - runSotetseg = true; - RedTiles.clear(); - break; - case NpcID.XARPUS: - case NpcID.XARPUS_8339: - case NpcID.XARPUS_8340: - case NpcID.XARPUS_8341: - runXarpus = true; - exhumecount = 25; - Xarpus_NPC = npc; - Xarpus_Stare = false; - Xarpus_TicksUntilShoot = 9; - Xarpus_previousAnimation = -1; - break; - case NpcID.VERZIK_VITUR_8369: - case NpcID.VERZIK_VITUR_8370: - case NpcID.VERZIK_VITUR_8371: - case NpcID.VERZIK_VITUR_8372: - case NpcID.VERZIK_VITUR_8373: - case NpcID.VERZIK_VITUR_8374: - case NpcID.VERZIK_VITUR_8375: - P3_TicksUntilAttack = -1; - P3_attacksLeft = 9; - redCrabsTimer = 13; - Verzik_NPC = npc; - runVerzik = true; - tornadoList = new ArrayList<>(); - crabList = new ArrayList<>(); - break; - } - } - - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) - { - NPC npc = npcDespawned.getNpc(); - switch (npc.getId()) - { - case NpcID.THE_MAIDEN_OF_SUGADINTI: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8363: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8364: - case NpcID.THE_MAIDEN_OF_SUGADINTI_8365: - runMaiden = false; - Maiden_Spawns.clear(); - break; - case NpcID.BLOOD_SPAWN: - Maiden_Spawns.remove(npc); - break; - case NpcID.PESTILENT_BLOAT: - runBloat = false; - Bloat_NPC = null; - bloatTimer = 0; - break; - case NPCID_NYLOCAS_PILLAR: - if (Nylocas_Pillars.keySet().contains(npc)) - { - Nylocas_Pillars.remove(npc); - } - break; - case 8342: - case 8343: - case 8344: - case 8345: - case 8346: - case 8347: - case 8348: - case 8349: - case 8350: - case 8351: - case 8352: - case 8353: - if (Nylocas_Map.keySet().contains(npc)) - { - Nylocas_Map.remove(npc); - } - break; - case NpcID.SOTETSEG: - case NpcID.SOTETSEG_8388: - RedTiles.clear(); - if (client.getPlane() != 3) - { - runSotetseg = false; - } - break; - case NpcID.XARPUS: - case NpcID.XARPUS_8339: - case NpcID.XARPUS_8340: - case NpcID.XARPUS_8341: - runXarpus = false; - Xarpus_NPC = null; - Xarpus_Stare = false; - Xarpus_TicksUntilShoot = 9; - Xarpus_previousAnimation = -1; - Xarpus_Exhumeds.clear(); - exhumecount = 0; - break; - case NpcID.VERZIK_VITUR_8369: - case NpcID.VERZIK_VITUR_8370: - case NpcID.VERZIK_VITUR_8371: - case NpcID.VERZIK_VITUR_8372: - case NpcID.VERZIK_VITUR_8373: - case NpcID.VERZIK_VITUR_8374: - case NpcID.VERZIK_VITUR_8375: - runVerzik = false; - redCrabsTimer = 0; - Verzik_NPC = null; - break; - } - - } - - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) - { - if (runSotetseg) - { - GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_BLACKMAZE) - { - Tile t = event.getTile(); - WorldPoint p = t.getWorldLocation(); - if (t.getPlane() == 0) - { - if (!BlackTilesOverworld.contains(p)) - { - BlackTilesOverworld.add(p); - } - } - else - { - if (!BlackTilesUnderworld.contains(p)) - { - BlackTilesUnderworld.add(p); - } - } - } - - if (o.getId() == GROUNDOBJECT_ID_REDMAZE) - { - Tile t = event.getTile(); - WorldPoint p = t.getWorldLocation(); - if (p.getPlane() == 0) - { - if (!RedTiles.containsValue(t)) - { - RedTiles.put(o, t); - } - } - else - { - if (!RedTilesUnderworld.contains(p)) - { - RedTilesUnderworld.add(p); - } - } - } - } - - if (runXarpus) - { - GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_EXHUMED) - { - - xarpusExhumedsTimer.put(o, 11); - - Xarpus_Exhumeds.put(o, 11); - - } - - } - } - - @Subscribe - public void onProjectileMoved(ProjectileMoved event) - { - if (runVerzik) - { - Projectile projectile = event.getProjectile(); - if (projectile.getId() == PROJECTILE_ID_P2RANGE) - { - WorldPoint p = WorldPoint.fromLocal(client, event.getPosition()); - Verzik_RangeProjectiles.put(projectile, p); - } - } - if (runSotetseg) - { - Projectile projectile = event.getProjectile(); - if (projectile.getId() == 1606) - { - Sotetseg_MageProjectiles.add(projectile); - } - if (projectile.getId() == 1607) - { - Sotetseg_RangeProjectiles.add(projectile); - } - } - } - - @Subscribe - public void onAnimationChanged(AnimationChanged event) - { - if (runVerzik) - { - if (event.getActor().getAnimation() == 8117) - { - redCrabsTimer = 11; - } - } - } - - @Subscribe - public void onVarbitChanged(VarbitChanged event) - { - if (runBloat) - { - - if (client.getVar(Varbits.BLOAT_ENTERED_ROOM) == 1) - { - if (!bloatFlag) - { - bloatTimer = 0; - bloatFlag = true; - } - } - } - } - - @Subscribe - public void onGraphicsObjectCreated(GraphicsObjectCreated event) - { - GraphicsObject obj = event.getGraphicsObject(); - if (obj.getId() == 1570 || obj.getId() == 1571 || obj.getId() == 1572 || obj.getId() == 1573 || obj.getId() == 1574 || obj.getId() == 1575 || obj.getId() == 1576) - { - WorldPoint p = WorldPoint.fromLocal(client, obj.getLocation()); - if (temp.size() == 0) - { -// TODO: ??? - } - else - { - - } - } - } - - - @Subscribe - public void onGameTick(GameTick event) - { - if (runMaiden) - { - Maiden_BloodSpatters.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_MAIDEN) - { - Maiden_BloodSpatters.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - - Maiden_SpawnLocations2.clear(); - Maiden_SpawnLocations2.addAll(Maiden_SpawnLocations); - Maiden_SpawnLocations.clear(); - for (NPC spawn : Maiden_Spawns) - { - Maiden_SpawnLocations.add(spawn.getWorldLocation()); - } - } - - if (runBloat) - { - - localTemp.clear(); - - //System.out.println("Temp flag" + tempFlag); - //System.out.println("Temp2 flag" + temp2Flag); - - - for (GraphicsObject obj : client.getGraphicsObjects()) - { - if (obj.getId() == 1570 || obj.getId() == 1571 || obj.getId() == 1572 || obj.getId() == 1573 || obj.getId() == 1574 || obj.getId() == 1575 || obj.getId() == 1576) - { - WorldPoint p = WorldPoint.fromLocal(client, obj.getLocation()); - //Already have some feet in temp Set - if (temp.size() > 0) - { - //System.out.println("temp size > 0, tempflag set false, tempflag2 set true"); - tempFlag = false; - temp2Flag = true; - } - else - { - //System.out.println("temp size 0, tempflag set true, tempflag2 set false"); - tempFlag = true; - temp2Flag = false; - - } - localTemp.add(p); - } - } - - if (tempFlag) - { - temp2.clear(); - temp2Flag = false; - temp.addAll(localTemp); - - - //System.out.println("temp2 cleared, temp2flag set false, added to temp set"); - } - else if (temp2Flag) - { - temp.clear(); - tempFlag = false; - temp2.addAll(localTemp); - //System.out.println("temp cleared, tempflag set false, added to temp2 set"); - - } - - Bloat_downCount++; - - if (Bloat_NPC.getAnimation() == -1) //1 = up; 2 = down; 3 = warn; - { - bloatTimer++; - Bloat_downCount = 0; - if (Bloat_NPC.getHealth() == 0) - { - Bloat_State = 2; - } - else - { - Bloat_State = 1; - } - } - else - { - if (25 < Bloat_downCount && Bloat_downCount < 35) - { - Bloat_State = 3; - } - else if (Bloat_downCount < 26) - { - tempFlag = false; - temp2Flag = false; - temp2.clear(); - temp.clear(); - Bloat_State = 2; - bloatTimer = 0; - } - else if (Bloat_NPC.getModelHeight() == 568) - { - tempFlag = false; - temp2Flag = false; - temp2.clear(); - temp.clear(); - Bloat_State = 2; - } - else - { - Bloat_State = 1; - } - - - } - } - - if (runNylocas) - { - for (Iterator it = Nylocas_Map.keySet().iterator(); it.hasNext(); ) - { - NPC npc = it.next(); - int ticksLeft = Nylocas_Map.get(npc); - - if (ticksLeft < 0) - { - it.remove(); - continue; - } - Nylocas_Map.replace(npc, ticksLeft - 1); - } - - for (NPC pillar : Nylocas_Pillars.keySet()) - { - int healthPercent = pillar.getHealthRatio(); - if (healthPercent > -1) - { - Nylocas_Pillars.replace(pillar, healthPercent); - } - } - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == 8358) - { - runNylocas = true; - break; - } - runNylocas = false; - BossNylo = null; - } - } - - if (runSotetseg) - { - boolean sotetsegFighting = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NpcID.SOTETSEG_8388) - { - BlackTilesUnderworld.clear(); - BlackTilesOverworld.clear(); - RedTilesOverworld.clear(); - RedTilesUnderworld.clear(); - GridPath.clear(); - sotetsegFighting = true; - RedTiles.clear(); - break; - } - } - - if (!getSotetseg_MageProjectiles().isEmpty()) - { - for (Iterator it = Sotetseg_MageProjectiles.iterator(); it.hasNext(); ) - { - Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { - it.remove(); - } - } - } - - if (!getSotetseg_RangeProjectiles().isEmpty()) - { - for (Iterator it = Sotetseg_RangeProjectiles.iterator(); it.hasNext(); ) - { - Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { - it.remove(); - } - } - } - - if (!sotetsegFighting) - { - if (!BlackTilesUnderworld.isEmpty() && !RedTilesUnderworld.isEmpty() && GridPath.isEmpty()) - { - int minX = 99999; - int minY = 99999; - for (WorldPoint p : BlackTilesUnderworld) - { - int x = p.getX(); - int y = p.getY(); - if (x < minX) - { - minX = x; - } - if (y < minY) - { - minY = y; - } - } - - - boolean messageSent = false; - for (WorldPoint p : RedTilesUnderworld) - { - WorldPoint pN = new WorldPoint(p.getX(), p.getY() + 1, p.getPlane()); - WorldPoint pS = new WorldPoint(p.getX(), p.getY() - 1, p.getPlane()); - WorldPoint pE = new WorldPoint(p.getX() + 1, p.getY(), p.getPlane()); - WorldPoint pW = new WorldPoint(p.getX() - 1, p.getY(), p.getPlane()); - - if (!((RedTilesUnderworld.contains(pN) && RedTilesUnderworld.contains(pS)) || - (RedTilesUnderworld.contains(pE) && RedTilesUnderworld.contains(pW)))) - { - GridPath.add(new Point(p.getX() - minX, p.getY() - minY)); - if (!messageSent) - { - //client.addChatMessage(ChatMessageType.SERVER, "", "Maze path acquired.", null); - messageSent = true; - } - } - - } - } - - if (!BlackTilesOverworld.isEmpty() && !GridPath.isEmpty() && RedTilesOverworld.isEmpty()) - { - int minX = 99999; - int minY = 99999; - for (WorldPoint p : BlackTilesOverworld) - { - int x = p.getX(); - int y = p.getY(); - if (x < minX) - { - minX = x; - } - if (y < minY) - { - minY = y; - } - } - for (Point p : GridPath) - { - RedTilesOverworld.add(new WorldPoint(minX + p.getX(), minY + p.getY(), 0)); - } - } - } - } - - if (runXarpus) - { - int size = xarpusExhumedsTimer.size(); - for (Map.Entry exhumes : xarpusExhumedsTimer.entrySet()) - { - if (size > 0) - { - exhumes.setValue(exhumes.getValue() - 1); - } - - } - for (Iterator it = Xarpus_Exhumeds.keySet().iterator(); it.hasNext(); ) - { - GroundObject key = it.next(); - Xarpus_Exhumeds.replace(key, Xarpus_Exhumeds.get(key) - 1); - if (Xarpus_Exhumeds.get(key) < 0) - { - it.remove(); - exhumecount--; - } - } - if ((Xarpus_NPC.getComposition().getOverheadIcon() != null)) - { - Xarpus_Stare = true; - } - if (Xarpus_Stare) - { - //dont hit xarpus if it looking at u - } - else if (Xarpus_NPC.getId() == NpcID.XARPUS_8340) - { - Xarpus_TicksUntilShoot--; - //if (Xarpus_NPC.getAnimation() == ANIMATION_ID_XARPUS && Xarpus_previousAnimation != ANIMATION_ID_XARPUS) - //{ - //Xarpus_TicksUntilShoot = 3; - //} - //Xarpus_previousAnimation = Xarpus_NPC.getAnimation(); - } - - } - - if (runVerzik) - { - crabList.clear(); - for (NPC npc : client.getNpcs()) - { - - if (npc.getName().toLowerCase().contains("nylo")) - { - crabList.add(npc); - } - } - - if (Verzik_NPC.getAnimation() == 8117) - { - redCrabsTimer = redCrabsTimer - 1; - } - if (!Verzik_RangeProjectiles.isEmpty()) - { - for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext(); ) - { - Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { - it.remove(); - } - } - } - - Verzik_YellowBall = null; - Verzik_YellowTiles.clear(); - - for (Projectile projectile : client.getProjectiles()) - { - if (projectile.getId() == PROJECTILE_ID_YELLOW) - { - Verzik_YellowBall = projectile; - break; - } - } - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_YELLOW) - { - - Verzik_YellowTiles.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - - if (Verzik_NPC.getId() == VERZIK_ID_P3) - { - boolean tornadosActive = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NPC_ID_TORNADO) - { - tornadoList.add(npc); - tornadosActive = true; - break; - } - } - - boolean isGreenBall = false; - for (Projectile projectile : client.getProjectiles()) - { - if (projectile.getId() == PROJECTILE_ID_P3_GREEN) - { - isGreenBall = projectile.getRemainingCycles() > 210; - break; - } - } - - P3_TicksUntilAttack--; - - switch (Verzik_NPC.getAnimation()) - { - case ANIMATION_ID_P3_MAGE: - if (P3_TicksUntilAttack < 2) - { - P3_attacksLeft--; - if (tornadosActive) - { - P3_TicksUntilAttack = 5; - } - else - { - P3_TicksUntilAttack = 7; - } - if (P3_attacksLeft < 1) - { - P3_TicksUntilAttack = 24; - } - } - break; - case ANIMATION_ID_P3_RANGE: - if (P3_TicksUntilAttack < 2) - { - P3_attacksLeft--; - if (tornadosActive) - { - P3_TicksUntilAttack = 5; - } - else - { - P3_TicksUntilAttack = 7; - } - if (P3_attacksLeft < 1) - { - P3_TicksUntilAttack = 30; - } - if (isGreenBall) - { - P3_TicksUntilAttack = 12; - } - } - break; - case ANIMATION_ID_P3_MELEE: - if (P3_TicksUntilAttack < 2) - { - P3_attacksLeft--; - if (tornadosActive) - { - P3_TicksUntilAttack = 5; - } - else - { - P3_TicksUntilAttack = 7; - } - if (P3_attacksLeft < 1) - { - P3_TicksUntilAttack = 24; - } - } - break; - case ANIMATION_ID_P3_WEB: - P3_attacksLeft = 4; - P3_TicksUntilAttack = 11; // - break; - case ANIMATION_ID_P3_YELLOW: - P3_attacksLeft = 14; - P3_TicksUntilAttack = 11; - break; - } - } - - } - - - } - - private void stripEntries(int style, String target, int NyloID) - { - String Keep = null; - if (NyloID == 0) - { - switch (style) - { - case 1: - Keep = "Nylocas Ischyros"; - break; - case 2: - Keep = "Nylocas Toxobolos"; - break; - case 3: - Keep = "Nylocas Hagios"; - break; - } - } - else - { - Keep = "fuckaadamhypocrticalpos"; - switch (NyloID) - { - case 8356://0=idk 1= melee 2= range 3= mage - if (style == 3) - { - - Keep = "Nylocas Vasilias"; - } - break; - case 8357: - if (style == 2) - { - Keep = "Nylocas Vasilias"; - } - break; - default: - if (style == 1) - { - Keep = "Nylocas Vasilias"; - } - } - - } - int entryLength = 0; - List entryList = new ArrayList<>(); - for (MenuEntry entry : client.getMenuEntries()) - { - if (Text.removeTags(entry.getTarget()).contains(Keep) && entry.getOption().equals("Attack")) - { - - entryList.add(entry); - entryLength++; - } - if (entry.getOption().equalsIgnoreCase("walk here") || entry.getOption().equalsIgnoreCase("pass") || entry.getOption().equalsIgnoreCase("take")) - { - entryList.add(entry); - entryLength++; - } - } - - //System.out.println("i see " + entryLength + " good options using style" + style); - if (entryLength != 0) - { - MenuEntry[] newEntries = new MenuEntry[entryLength]; - - - for (int i = 0; i < (entryLength); i++) - { - newEntries[i] = entryList.get(i); - } - client.setMenuEntries(newEntries); - } - - - } - - private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) - { - for (int i = entries.length - 1; i >= 0; i--) - { - MenuEntry entry = entries[i]; - String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); - String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); - - if (strict) - { - if (entryOption.equals(option) && entryTarget.equals(target)) - { - return i; - } - } - else - { - if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target)) - { - return i; - } - } - } - - return -1; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java deleted file mode 100644 index a9aad8eaf9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.runelite.client.plugins.ztob; - -import com.google.inject.Inject; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; -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.components.LineComponent; -import net.runelite.client.ui.overlay.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; - -public class TheatreXarpusOverlay extends Overlay -{ - private final TheatrePlugin plugin; - private final TheatreConfig config; - PanelComponent panelComponent = new PanelComponent(); - - @Inject - private TheatreXarpusOverlay(TheatrePlugin plugin, TheatreConfig config) - { - super(plugin); - setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); - setPosition(OverlayPosition.DYNAMIC); - setPosition(OverlayPosition.DETACHED); - this.plugin = plugin; - this.config = config; - getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Theatre xarpus overlay")); - - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (plugin.isRunXarpus()) - { - if (config.XarpusExhumeOverlay()) - { - if (plugin.getXarpus_NPC().getId() == 8339) - { - panelComponent.getChildren().clear(); - String overlayTitle = "Exhume Counter"; - - - // Build overlay title - panelComponent.getChildren().add(TitleComponent.builder() - .text(overlayTitle) - .color(Color.GREEN) - .build()); - - //Set the size of overlay - panelComponent.setPreferredSize(new Dimension( - graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0 - )); - - panelComponent.getChildren().add(LineComponent.builder() - .left("Exhumes: ") - .right(String.valueOf(plugin.getExhumecount())) - .build()); - } - } - return panelComponent.render(graphics); - } - - return null; - - } - - -} - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java deleted file mode 100644 index dc3cfc9d31..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java +++ /dev/null @@ -1,104 +0,0 @@ -package net.runelite.client.plugins.ztob; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -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; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; - -public class VerzikNyloOverlay extends Overlay -{ - - private final Client client; - private final TheatrePlugin plugin; - private final TheatreConfig config; - - @Inject - private VerzikNyloOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) - { - this.client = client; - this.plugin = plugin; - this.config = config; - setPosition(OverlayPosition.DYNAMIC); - setPriority(OverlayPriority.HIGH); - setLayer(OverlayLayer.ABOVE_SCENE); - } - - public Dimension render(Graphics2D graphics) - { - - if (plugin.isRunVerzik()) - { - if (config.NyloTargetOverlay()) - { - if (plugin.getCrabList().size() > 0) - { - - for (NPC npc : plugin.getCrabList()) - { - if (npc.isDead()) - { - continue; - } - String renderText = ""; - if (npc.getInteracting() != null) - { - - renderText = npc.getInteracting().getName(); - Point point = npc.getCanvasTextLocation(graphics, npc.getInteracting().getName(), 0); - - - if (npc.getInteracting().getName().toLowerCase().equals(client.getLocalPlayer().getName().toLowerCase())) - { - point = npc.getCanvasTextLocation(graphics, client.getLocalPlayer().getName(), 0); - renderText = "YOU NIGGA RUN!"; - - } - else if (npc.getInteracting().getName().toLowerCase().equals("afyy")) - { - point = npc.getCanvasTextLocation(graphics, "Ricecup", 0); - renderText = "Ricecup"; - } - if (renderText.equals("YOU NIGGA RUN!")) - { - renderTextLocation(graphics, renderText, 12, Font.BOLD, Color.RED, point); - } - else - { - renderTextLocation(graphics, renderText, 12, Font.BOLD, Color.GREEN, point); - } - } - - } - } - - } - } - - return null; - } - - private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) - { - graphics.setFont(new Font("Arial", fontStyle, fontSize)); - if (canvasPoint != null) - { - final Point canvasCenterPoint = new Point( - canvasPoint.getX(), - canvasPoint.getY()); - final Point canvasCenterPoint_shadow = new Point( - canvasPoint.getX() + 1, - canvasPoint.getY() + 1); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); - OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); - } - } -}