Lyzrd features

Music track unlock indication

new and improved TOB

combat counter

spawn timer indicator

all of these are credit to Lyzrd, LyzrdLite & Nagi
This commit is contained in:
Kyleeld
2019-05-30 16:10:29 +01:00
parent a07fbb0aca
commit a6207048d3
33 changed files with 5268 additions and 2291 deletions

View File

@@ -0,0 +1,608 @@
/*
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
* 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<String, Long> counter = new HashMap<String, Long>();
private long BLOWPIPE_ID = 5061;
private Map<String, Long> blowpipe = new HashMap<>();
public Map<NPC, NPCDamageCounter> npcDamageMap = new HashMap<NPC, NPCDamageCounter>();
public Map<String, Double> playerDamage = new HashMap<String, Double>();
@Provides
CombatCounterConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(CombatCounterConfig.class);
}
private Map<Integer, Integer> variables = new HashMap<Integer, Integer>()
{
{
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<Integer> MELEE_ANIMATIONS = new ArrayList<Integer>()
{
{
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<Integer> RANGE_ANIMATIONS = new ArrayList<Integer>()
{
{
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<Integer> MAGE_ANIMATIONS = new ArrayList<Integer>()
{
{
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<NPC> actives = new ArrayList<NPC>();
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<Integer> ticksToAdd = new ArrayList<Integer>();
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<String> attackers = new ArrayList<String>();
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<String, Player> visible = new HashMap<String, Player>();
for (Player p : this.client.getPlayers())
{
if (p.getName() != null)
visible.put(p.getName(), p);
}
for (NPC npc : new ArrayList<NPC>(this.npcDamageMap.keySet()))
{
NPCDamageCounter counter = this.npcDamageMap.get(npc);
Map<Integer, List<String>> attackers = counter.attackers;
for (Integer i : new ArrayList<Integer>(attackers.keySet()))
{
List<String> 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<String> 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<Integer>(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<String>(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<Integer> counts = new ArrayList<Integer>();
counts.add(delay);
if(delay > 2)
counts.add(delay - 1);
for(int tick : counts)
{
List<String> attackers = new ArrayList<String>();
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 <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map)
{
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.comparingByValue());
Map<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> 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);
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
* 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<String, Long> 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<String, Long> 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;
}
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
* 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<String, Double> 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;
}
}
}

View File

@@ -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<Integer, List<String>> attackers;
public List<Integer> damage;
public NPCDamageCounter()
{
this.attackers = new TreeMap<Integer, List<String>>();
this.damage = new ArrayList<Integer>();
}
}

View File

@@ -0,0 +1,206 @@
/*
* Copyright (c) 2019, Shaun Dreclin <https://github.com/ShaunDreclin>
* 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<VarPlayer> 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<Integer, VarPlayer> 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<VarPlayer, Integer> 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());
}
}

View File

@@ -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;
}
}

View File

@@ -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<String> 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);
}
}
}

View File

@@ -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<NPC> highlightedNpcs = new HashSet<>();
@Getter(AccessLevel.PACKAGE)
Set<thing> 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<thing> iterator = ticks.iterator(); iterator.hasNext();)
{
thing t = iterator.next();
if (t.getNpc() == npc)
{
iterator.remove();
}
//currentTick = 0;
}
}
}
@VisibleForTesting
public List<String> getHighlights()
{
final String configNpcs = config.getNpcToHighlight().toLowerCase();
if (configNpcs.isEmpty())
{
return Collections.emptyList();
}
return Text.fromCSV(configNpcs);
}
}

View File

@@ -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;
}
}

View File

@@ -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<Projectile, String> projectiles)
{
Iterator<Map.Entry<Projectile, String>> itr = projectiles.entrySet().iterator();
while (itr.hasNext())
{
Map.Entry<Projectile, String> 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<WorldPoint> getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder)
{
List<WorldPoint> little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList();
List<WorldPoint> big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList();
if (!includeUnder)
{
for (Iterator<WorldPoint> 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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,12 @@
package net.runelite.client.plugins.theatre;
public enum TheatreRoom
{
MAIDEN,
BLOAT,
NYLOCAS,
SOTETSEG,
XARPUS,
VERSIK,
UNKNOWN;
}

View File

@@ -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;
}
}
}
}

View File

@@ -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<WorldPoint> bloodThrows = new ArrayList<>();
@Getter(AccessLevel.PACKAGE)
private List<NPC> bloodSpawns = new ArrayList<>();
@Getter(AccessLevel.PACKAGE)
private List<WorldPoint> bloodSpawnLocation = new ArrayList<>();
@Getter(AccessLevel.PACKAGE)
private List<WorldPoint> bloodSpawnTarget = new ArrayList<>();
private List<NPC> 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: <col=ff0000>" + minutes + ":" + twoDigitString(seconds), null);
}
}
}

View File

@@ -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<GroundObject, Tile> redTiles = new LinkedHashMap<>();
@Getter(AccessLevel.PUBLIC)
private List<WorldPoint> redOverworld = new ArrayList<>();
private List<WorldPoint> blackOverworld = new ArrayList<>();
private List<WorldPoint> blackUnderworld = new ArrayList<>();
private List<WorldPoint> redUnderworld = new ArrayList<>();
private List<Point> gridPath = new ArrayList<>();
//My variables
int playerX;
int playerY;
private Map<Projectile, WorldPoint> 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<Projectile, String> 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<Projectile> 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));
}
}
}
}
}

View File

@@ -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<Projectile, WorldPoint> 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<Projectile> 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: <col=ff0000>" + 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: <col=ff0000>" + 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;
}
}
}
}

View File

@@ -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<NPC, Integer> pillars = new HashMap<>();
@Getter(AccessLevel.PUBLIC)
private Map<NPC, Integer> 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<NPC> waveSpawns = new ArrayList<NPC>();
public ArrayList<NPC> waveAgros = new ArrayList<NPC>();
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: <col=ff0000>" + 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<NPC> toHighlight = new HashSet<NPC>();
/**
if (config.highlightNyloParents())
{
for (NPC npc : new ArrayList<NPC>(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<NPC>(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;
}
}
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
* 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);
}
}

View File

@@ -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<Nylocas, NPC> currentSpawns = new HashMap<Nylocas, NPC>();
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<Nylocas> queue = new ArrayList<>(currentSpawns.keySet());
HashMap<NPC, Nylocas> npcs = new HashMap<NPC, Nylocas>();
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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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<GroundObject, Integer> 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: <col=ff0000>" + 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: <col=ff0000>" + 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();
}
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,8 @@
package net.runelite.client.plugins.theatre.timers;
import java.util.HashMap;
public interface Timeable
{
public abstract HashMap<String, Long> getTimes();
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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<NPC, Integer> 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<NPC, Integer> 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<GroundObject, Integer> 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<WorldPoint> 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<WorldPoint> getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder)
{
List<WorldPoint> little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList();
List<WorldPoint> big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList();
if (!includeUnder)
{
for (Iterator<WorldPoint> it = big.iterator(); it.hasNext(); )
{
WorldPoint p = it.next();
if (little.contains(p))
{
it.remove();
}
}
}
return big;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}