Merge branch 'master' into rr

This commit is contained in:
Tyler Bochard
2019-05-20 14:25:57 -04:00
committed by GitHub
535 changed files with 61904 additions and 55246 deletions

View File

@@ -33,11 +33,11 @@ public class MethodGarbageValue
public MethodGarbageValue(int value) public MethodGarbageValue(int value)
{ {
if(value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE)
{ {
type = "B"; type = "B";
} }
else if(value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE)
{ {
type = "S"; type = "S";
} }
@@ -60,6 +60,6 @@ public class MethodGarbageValue
public String toString() public String toString()
{ {
return "MethodGarbageValue[type="+getType()+",value="+getValue()+"]"; return "MethodGarbageValue[type=" + getType() + ",value=" + getValue() + "]";
} }
} }

View File

@@ -33,10 +33,6 @@ import io.sigpipe.jbsdiff.Patch;
import javassist.ClassPool; import javassist.ClassPool;
import javassist.CtClass; import javassist.CtClass;
import javassist.LoaderClassPath; import javassist.LoaderClassPath;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import us.runelitepl.mixinprocessor.generators.AnnotationProcessor; import us.runelitepl.mixinprocessor.generators.AnnotationProcessor;
import us.runelitepl.mixinprocessor.generators.PatchGenerator; import us.runelitepl.mixinprocessor.generators.PatchGenerator;
@@ -50,14 +46,11 @@ import us.runelitepl.mixinprocessor.util.JavassistUtils;
import us.runelitepl.mixinprocessor.util.RefUtils; import us.runelitepl.mixinprocessor.util.RefUtils;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
@@ -111,9 +104,9 @@ public class MixinProcessorMojo
public static HashMap<String, MethodGarbageValue> methodGarbageValues = new HashMap<>(); public static HashMap<String, MethodGarbageValue> methodGarbageValues = new HashMap<>();
public static HashMap<String, byte[]> gamepack = new HashMap<>(); private static HashMap<String, byte[]> gamepack = new HashMap<>();
public static final int BUFFER_SIZE = 1024 * 1024 * 4; private static final int BUFFER_SIZE = 1024 * 1024 * 4;
public void execute() public void execute()
throws MojoExecutionException throws MojoExecutionException
@@ -257,7 +250,7 @@ public class MixinProcessorMojo
} }
public void stderr(String s, Object... format) private void stderr(String s, Object... format)
{ {
getLog().info(String.format(s, format)); getLog().info(String.format(s, format));
} }
@@ -267,7 +260,7 @@ public class MixinProcessorMojo
INST.stderr(s, format); INST.stderr(s, format);
} }
static void deleteDir(File file) throws IOException private static void deleteDir(File file) throws IOException
{ {
if (!file.exists()) if (!file.exists())
{ {

View File

@@ -31,5 +31,5 @@ public enum InjectionType
APPEND, APPEND,
OVERWRITE, OVERWRITE,
PREPEND, PREPEND,
PROVIDED; PROVIDED
} }

View File

@@ -26,8 +26,6 @@
package us.runelitepl.mixinprocessor.generators; package us.runelitepl.mixinprocessor.generators;
import us.runelitepl.mixinprocessor.transformers.AnnotationRemoverTransformer; import us.runelitepl.mixinprocessor.transformers.AnnotationRemoverTransformer;
import us.runelitepl.mixinprocessor.transformers.AsmMethodGarbageTransformer;
import us.runelitepl.mixinprocessor.transformers.AsmMethodSignatureTransformer;
import us.runelitepl.mixinprocessor.transformers.AsmNameTransformer; import us.runelitepl.mixinprocessor.transformers.AsmNameTransformer;
import us.runelitepl.mixinprocessor.transformers.AsmStaticUsageTransformer; import us.runelitepl.mixinprocessor.transformers.AsmStaticUsageTransformer;
import us.runelitepl.mixinprocessor.transformers.DoNothingTransformer; import us.runelitepl.mixinprocessor.transformers.DoNothingTransformer;

View File

@@ -25,18 +25,12 @@
package us.runelitepl.mixinprocessor.generators; package us.runelitepl.mixinprocessor.generators;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.NotFoundException;
import us.runelitepl.mixinprocessor.MixinProcessorMojo; import us.runelitepl.mixinprocessor.MixinProcessorMojo;
import us.runelitepl.mixinprocessor.util.JavassistUtils;
import us.runelitepl.mixinprocessor.util.RefUtils; import us.runelitepl.mixinprocessor.util.RefUtils;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -45,11 +39,11 @@ import java.util.Set;
public class StaticGenerator public class StaticGenerator
{ {
public static HashMap<String, ArrayList<MethodNode>> staticMethods = new HashMap<>(); static HashMap<String, ArrayList<MethodNode>> staticMethods = new HashMap<>();
public static HashMap<String, ArrayList<FieldNode>> staticFields = new HashMap<>(); static HashMap<String, ArrayList<FieldNode>> staticFields = new HashMap<>();
public static Set<String> modifiedClasses = new HashSet<>(); static Set<String> modifiedClasses = new HashSet<>();
public void run(byte[] bytecode) throws NotFoundException, IOException, CannotCompileException public void run(byte[] bytecode)
{ {
ClassReader cr = new ClassReader(bytecode); ClassReader cr = new ClassReader(bytecode);
@@ -68,7 +62,7 @@ public class StaticGenerator
continue; continue;
} }
String reobbed = RefUtils.reobMethodName(RefUtils.STATICS_STRING, methodName, method.desc); String reobbed = RefUtils.reobMethodName(RefUtils.STATICS_STRING, methodName, method.desc);
if(reobbed == null) if (reobbed == null)
{ {
MixinProcessorMojo.log("Failed to reob static method: %s %s", methodName, method.desc); MixinProcessorMojo.log("Failed to reob static method: %s %s", methodName, method.desc);
throw new RuntimeException(); throw new RuntimeException();
@@ -93,7 +87,7 @@ public class StaticGenerator
continue; continue;
} }
String reobbed = RefUtils.reobFieldName(RefUtils.STATICS_STRING, fieldName, field.desc); String reobbed = RefUtils.reobFieldName(RefUtils.STATICS_STRING, fieldName, field.desc);
if(reobbed == null) if (reobbed == null)
{ {
MixinProcessorMojo.log("Failed to reob static field: %s %s", fieldName, field.desc); MixinProcessorMojo.log("Failed to reob static field: %s %s", fieldName, field.desc);
throw new RuntimeException(); throw new RuntimeException();

View File

@@ -36,7 +36,6 @@ import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeAnnotationNode; import org.objectweb.asm.tree.TypeAnnotationNode;
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
import us.runelitepl.mixinprocessor.parsers.MethodReflector; import us.runelitepl.mixinprocessor.parsers.MethodReflector;
import java.util.HashMap; import java.util.HashMap;

View File

@@ -48,7 +48,7 @@ public class GamepackDownloader
ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(gamepackJarAry)); ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(gamepackJarAry));
byte[] buffer = new byte[2048]; byte[] buffer = new byte[2048];
ZipEntry entry; ZipEntry entry;
ByteArrayOutputStream fileContent = new ByteArrayOutputStream(1024*1024*4); ByteArrayOutputStream fileContent = new ByteArrayOutputStream(1024 * 1024 * 4);
while ((entry = zipInputStream.getNextEntry()) != null) while ((entry = zipInputStream.getNextEntry()) != null)
{ {
if (entry.getName().startsWith("META-INF")) if (entry.getName().startsWith("META-INF"))
@@ -56,8 +56,8 @@ public class GamepackDownloader
continue; continue;
} }
String key = entry.getName().replace(".class", ""); String key = entry.getName().replace(".class", "");
int len = 0; int len;
while((len = zipInputStream.read(buffer)) > 0) while ((len = zipInputStream.read(buffer)) > 0)
{ {
fileContent.write(buffer, 0, len); fileContent.write(buffer, 0, len);
} }
@@ -83,7 +83,7 @@ public class GamepackDownloader
} }
} }
public static String getGamepackUrl() private static String getGamepackUrl()
{ {
return codebase + initial_jar; return codebase + initial_jar;
} }

View File

@@ -71,7 +71,7 @@ public class HooksParser
String f_owner = (String) field.get("owner"); String f_owner = (String) field.get("owner");
long f_decoder = (long) field.getOrDefault("decoder", (long) 1); long f_decoder = (long) field.getOrDefault("decoder", (long) 1);
String f_deobbedOwner = null; String f_deobbedOwner = null;
if(f_deobbedName.startsWith("__")) if (f_deobbedName.startsWith("__"))
{ {
continue; continue;
} }
@@ -104,7 +104,7 @@ public class HooksParser
String m_deobbedOwner = null; String m_deobbedOwner = null;
String m_obbedName = (String) method.get("name"); String m_obbedName = (String) method.get("name");
String m_descriptor = (String) method.get("descriptor"); String m_descriptor = (String) method.get("descriptor");
if(m_deobbedName.startsWith("__")) if (m_deobbedName.startsWith("__"))
{ {
continue; continue;
} }

View File

@@ -51,7 +51,7 @@ public class MethodAnnotationParser
public void run() throws ClassNotFoundException public void run() throws ClassNotFoundException
{ {
for(CtMethod method : patch.getDeclaredMethods()) for (CtMethod method : patch.getDeclaredMethods())
{ {
Object[] annotations = method.getAnnotations(); Object[] annotations = method.getAnnotations();
@@ -112,7 +112,7 @@ public class MethodAnnotationParser
} }
} }
if(reobfuscate) if (reobfuscate)
{ {
MixinProcessorMojo.log("Marking: %s %s %s", method.getDeclaringClass().getSimpleName(), methodName, MixinProcessorMojo.log("Marking: %s %s %s", method.getDeclaringClass().getSimpleName(), methodName,
RefUtils.reobMethodDescriptor(method.getSignature())); RefUtils.reobMethodDescriptor(method.getSignature()));

View File

@@ -96,7 +96,7 @@ public class AnnotationRemoverTransformer extends AsmBaseTransformer
return cw.toByteArray(); return cw.toByteArray();
} }
public static String makeAnnotationDescriptor(String s) static String makeAnnotationDescriptor(String s)
{ {
return "Lus/runelitepl/mixinprocessor/annotations/" + s + ";"; return "Lus/runelitepl/mixinprocessor/annotations/" + s + ";";
} }

View File

@@ -34,11 +34,12 @@ public abstract class AsmBaseTransformer implements Opcodes
protected final ArrayList<String> validMethods = new ArrayList<>(); protected final ArrayList<String> validMethods = new ArrayList<>();
protected final ArrayList<String> validFields = new ArrayList<>(); protected final ArrayList<String> validFields = new ArrayList<>();
// CHECKSTYLE:OFF
protected void buildMethodList(){} protected void buildMethodList(){}
protected void buildFieldList(){} protected void buildFieldList(){}
// CHECKSTYLE:ON
public abstract byte[] transform(); public abstract byte[] transform();
} }

View File

@@ -32,8 +32,6 @@ import org.objectweb.asm.MethodVisitor;
import us.runelitepl.mixinprocessor.MethodGarbageValue; import us.runelitepl.mixinprocessor.MethodGarbageValue;
import us.runelitepl.mixinprocessor.MixinProcessorMojo; import us.runelitepl.mixinprocessor.MixinProcessorMojo;
import us.runelitepl.mixinprocessor.util.RefUtils; import us.runelitepl.mixinprocessor.util.RefUtils;
import java.sql.Ref;
import java.util.HashMap; import java.util.HashMap;
public class AsmMethodGarbageTransformer extends AsmBaseTransformer public class AsmMethodGarbageTransformer extends AsmBaseTransformer
@@ -74,13 +72,13 @@ public class AsmMethodGarbageTransformer extends AsmBaseTransformer
// mv.visitLdcInsn(BIPUSH, constant); // mv.visitLdcInsn(BIPUSH, constant);
// call super method with new descriptor // call super method with new descriptor
if(RefUtils.shouldReobMethod(owner, name, desc)) if (RefUtils.shouldReobMethod(owner, name, desc))
{ {
String nc = RefUtils.reobMethodName(owner, name, desc).split(" ")[0]; String nc = RefUtils.reobMethodName(owner, name, desc).split(" ")[0];
String nn = RefUtils.reobMethodName(owner, name, desc).split(" ")[1]; String nn = RefUtils.reobMethodName(owner, name, desc).split(" ")[1];
String nd = RefUtils.reobMethodDescriptor(desc); String nd = RefUtils.reobMethodDescriptor(desc);
MethodGarbageValue value; MethodGarbageValue value;
if((value = MixinProcessorMojo.methodGarbageValues.getOrDefault(String.format("%s.%s%s", if ((value = MixinProcessorMojo.methodGarbageValues.getOrDefault(String.format("%s.%s%s",
nc, nn, nd), null)) != null) nc, nn, nd), null)) != null)
{ {
switch (value.getType()) switch (value.getType())

View File

@@ -72,7 +72,7 @@ public class AsmMethodSignatureTransformer extends AsmBaseTransformer
private String fixMethodDesc(String className, String name, String desc) private String fixMethodDesc(String className, String name, String desc)
{ {
if(className.startsWith(RefUtils.TYPE_PREFIX)) if (className.startsWith(RefUtils.TYPE_PREFIX))
{ {
className = className.substring(RefUtils.TYPE_PREFIX.length()); className = className.substring(RefUtils.TYPE_PREFIX.length());
} }

View File

@@ -32,11 +32,6 @@ import org.objectweb.asm.MethodVisitor;
import us.runelitepl.mixinprocessor.MixinProcessorMojo; import us.runelitepl.mixinprocessor.MixinProcessorMojo;
import us.runelitepl.mixinprocessor.util.RefUtils; import us.runelitepl.mixinprocessor.util.RefUtils;
import static org.objectweb.asm.Opcodes.ASM6;
import static org.objectweb.asm.Opcodes.GETSTATIC;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.PUTSTATIC;
public class AsmStaticUsageTransformer extends AsmBaseTransformer public class AsmStaticUsageTransformer extends AsmBaseTransformer
{ {
@@ -89,7 +84,7 @@ public class AsmStaticUsageTransformer extends AsmBaseTransformer
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface)
{ {
if(opcode == INVOKESTATIC && owner.endsWith(RefUtils.STATICS_STRING)) if (opcode == INVOKESTATIC && owner.endsWith(RefUtils.STATICS_STRING))
{ {
String originalOwner = owner.replace(TYPE_PREFIX, ""); String originalOwner = owner.replace(TYPE_PREFIX, "");
String temp = RefUtils.reobMethodName(RefUtils.STATICS_STRING, name, descriptor); String temp = RefUtils.reobMethodName(RefUtils.STATICS_STRING, name, descriptor);

View File

@@ -47,10 +47,10 @@ public class DoNothingTransformer extends AsmBaseTransformer
ClassReader cr = new ClassReader(bytecode); ClassReader cr = new ClassReader(bytecode);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
// CHECKSTYLE:OFF
cr.accept(new ClassVisitor(ASM6, cw) cr.accept(new ClassVisitor(ASM6, cw)
{}, 0); {}, 0);
//CHECKSTYLE:ON
return cw.toByteArray(); return cw.toByteArray();
} }
} }

View File

@@ -53,22 +53,22 @@ public class ProvidedRemoverTransformer extends AsmBaseTransformer
ClassNode node = new ClassNode(); ClassNode node = new ClassNode();
cr.accept(node, 0); cr.accept(node, 0);
for(Object obj : node.methods) for (Object obj : node.methods)
{ {
MethodNode method = (MethodNode) obj; MethodNode method = (MethodNode) obj;
if(method == null) if (method == null)
{ {
MixinProcessorMojo.log("ProvidedRemoverTransformer: Method null?"); MixinProcessorMojo.log("ProvidedRemoverTransformer: Method null?");
continue; continue;
} }
if(method.visibleAnnotations == null) if (method.visibleAnnotations == null)
{ {
continue; continue;
} }
for(Object obj2 : method.visibleAnnotations) for (Object obj2 : method.visibleAnnotations)
{ {
AnnotationNode annot = (AnnotationNode) obj2; AnnotationNode annot = (AnnotationNode) obj2;
if(annot.desc.equals(AnnotationRemoverTransformer.makeAnnotationDescriptor("Provided"))) if (annot.desc.equals(AnnotationRemoverTransformer.makeAnnotationDescriptor("Provided")))
{ {
validMethods.add(method.access + " " + method.desc + " " + method.name); validMethods.add(method.access + " " + method.desc + " " + method.name);
} }
@@ -88,7 +88,7 @@ public class ProvidedRemoverTransformer extends AsmBaseTransformer
public MethodVisitor visitMethod(int access, String name, String desc, String signature, public MethodVisitor visitMethod(int access, String name, String desc, String signature,
String[] exceptions) String[] exceptions)
{ {
if(validMethods.contains(access + " " + desc + " " + name)) if (validMethods.contains(access + " " + desc + " " + name))
{ {
return null; return null;
} }

View File

@@ -125,7 +125,7 @@ public class RefUtils
public static String reobMethodName(String owner, String deob, String signature) public static String reobMethodName(String owner, String deob, String signature)
{ {
String prefix = ""; String prefix = "";
if(owner.startsWith(RefUtils.TYPE_PREFIX)) if (owner.startsWith(RefUtils.TYPE_PREFIX))
{ {
owner = owner.substring(RefUtils.TYPE_PREFIX.length()); owner = owner.substring(RefUtils.TYPE_PREFIX.length());
} }
@@ -169,11 +169,7 @@ public class RefUtils
i++; i++;
} }
} }
if (i == 1) return i == 1;
{
return true;
}
return false;
} }
@Deprecated @Deprecated
@@ -187,11 +183,7 @@ public class RefUtils
i++; i++;
} }
} }
if (i == 1) return i == 1;
{
return true;
}
return false;
} }
public static boolean shouldReobField(String owner, String deob, String desc) public static boolean shouldReobField(String owner, String deob, String desc)
@@ -205,7 +197,7 @@ public class RefUtils
public static boolean shouldReobMethod(String owner, String deob, String desc) public static boolean shouldReobMethod(String owner, String deob, String desc)
{ {
if(owner.startsWith(RefUtils.TYPE_PREFIX)) if (owner.startsWith(RefUtils.TYPE_PREFIX))
{ {
owner = owner.substring(RefUtils.TYPE_PREFIX.length()); owner = owner.substring(RefUtils.TYPE_PREFIX.length());
} }
@@ -275,7 +267,7 @@ public class RefUtils
{ {
obbedName = className; obbedName = className;
} }
deobbed.append("L" + obbedName + ";"); deobbed.append("L").append(obbedName ).append(";");
strIndex += sigPart.length(); strIndex += sigPart.length();
} }
catch (StringIndexOutOfBoundsException ex) catch (StringIndexOutOfBoundsException ex)

View File

@@ -50,14 +50,17 @@ public class WebUtils
return pageText; return pageText;
} }
public static byte[] downloadFile(String urlText) throws IOException { public static byte[] downloadFile(String urlText) throws IOException
{
URL url = new URL(urlText); URL url = new URL(urlText);
ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream();
try (InputStream inputStream = url.openStream()) { try (InputStream inputStream = url.openStream())
int n = 0; {
int n;
byte [] buffer = new byte[ 1024 ]; byte [] buffer = new byte[ 1024 ];
while (-1 != (n = inputStream.read(buffer))) { while (-1 != (n = inputStream.read(buffer)))
{
output.write(buffer, 0, n); output.write(buffer, 0, n);
} }
} }

View File

@@ -41,170 +41,170 @@ import java.util.List;
public class Client public class Client
{ {
@Provided @Provided
public static boolean isHidingEntities; public static boolean isHidingEntities;
@Provided @Provided
public static boolean hideLocalPlayer2D; public static boolean hideLocalPlayer2D;
@Provided @Provided
public static boolean hideLocalPlayer; public static boolean hideLocalPlayer;
@Provided @Provided
public static boolean hidePlayers2D; public static boolean hidePlayers2D;
@Provided @Provided
public static boolean hidePlayers; public static boolean hidePlayers;
@Provided @Provided
public static boolean hideAttackers; public static boolean hideAttackers;
@Provided @Provided
public static boolean hideProjectiles; public static boolean hideProjectiles;
@Provided @Provided
public static boolean hideNPCs2D; public static boolean hideNPCs2D;
@Provided @Provided
public static boolean hideNPCs; public static boolean hideNPCs;
@Provided @Provided
public static boolean hideFriends; public static boolean hideFriends;
@Provided @Provided
public static boolean hideClanMates; public static boolean hideClanMates;
@Inject @Inject
public static Client INSTANCE; public static Client INSTANCE;
@Inject @Inject
public static boolean printMenuActions; public static boolean printMenuActions;
@Provided @Provided
public static int oldMenuEntryCount; public static int oldMenuEntryCount;
@Reobfuscate @Reobfuscate
@Provided @Provided
static boolean renderSelf; static boolean renderSelf;
@Provided @Provided
public static final int[] rl$modelViewportXs = new int[0]; public static final int[] rl$modelViewportXs = new int[0];
@Provided @Provided
public static final int[] rl$modelViewportYs = new int[0]; public static final int[] rl$modelViewportYs = new int[0];
@Prepend @Prepend
private void prepend$rl$$init() private void prepend$rl$$init()
{ {
INSTANCE = this; INSTANCE = this;
printMenuActions = false; printMenuActions = false;
} }
@Inject @Inject
public void toggleRenderSelf() public void toggleRenderSelf()
{ {
renderSelf = !renderSelf; renderSelf = !renderSelf;
} }
@Provided @Provided
public int getMenuOptionCount() public int getMenuOptionCount()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public String[] getMenuOptions() public String[] getMenuOptions()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public String[] getMenuTargets() public String[] getMenuTargets()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int[] getMenuIdentifiers() public int[] getMenuIdentifiers()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int[] getMenuTypes() public int[] getMenuTypes()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int[] getMenuActionParams0() public int[] getMenuActionParams0()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int[] getMenuActionParams1() public int[] getMenuActionParams1()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public boolean[] getMenuForceLeftClick() public boolean[] getMenuForceLeftClick()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public void setMenuOptionCount(int i) public void setMenuOptionCount(int i)
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public Callbacks getCallbacks() public Callbacks getCallbacks()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public RSCollisionData[] getRsCollisionMaps() public RSCollisionData[] getRsCollisionMaps()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public RSDeque getProjectilesDeque() public RSDeque getProjectilesDeque()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Overwrite @Overwrite
public List getProjectiles() public List getProjectiles()
{ {
List list = new java.util.ArrayList(); List list = new java.util.ArrayList();
RSNode head = getProjectilesDeque().getHead(); RSNode head = getProjectilesDeque().getHead();
for (Node node = ((Node) head).getNext(); for (Node node = ((Node) head).getNext();
node != head; node != head;
node = node.getNext()) node = node.getNext())
{ {
list.add(node); list.add(node);
} }
return list; return list;
} }
@Inject @Inject
public void setPrintMenuActions(boolean b) public void setPrintMenuActions(boolean b)
{ {
printMenuActions = b; printMenuActions = b;
} }
@Overwrite @Overwrite
public RSCollisionData[] getCollisionMaps() public RSCollisionData[] getCollisionMaps()
{ {
return getRsCollisionMaps(); return getRsCollisionMaps();
} }
@Overwrite @Overwrite
public void setMenuEntries(MenuEntry[] arrmenuEntry) public void setMenuEntries(MenuEntry[] arrmenuEntry)
{ {
@@ -242,7 +242,7 @@ public class Client
} }
while (true); while (true);
} }
@Overwrite @Overwrite
public static void onMenuOptionsChanged(int n2) public static void onMenuOptionsChanged(int n2)
{ {
@@ -254,28 +254,28 @@ public class Client
return; return;
} }
net.runelite.api.events.MenuEntryAdded menuEntryAdded = net.runelite.api.events.MenuEntryAdded menuEntryAdded =
new net.runelite.api.events.MenuEntryAdded(INSTANCE.getMenuOptions()[n3 - 1], new net.runelite.api.events.MenuEntryAdded(INSTANCE.getMenuOptions()[n3 - 1],
INSTANCE.getMenuTargets()[n3 - 1], INSTANCE.getMenuTargets()[n3 - 1],
INSTANCE.getMenuTypes()[n3 - 1], INSTANCE.getMenuTypes()[n3 - 1],
INSTANCE.getMenuIdentifiers()[n3 - 1], INSTANCE.getMenuIdentifiers()[n3 - 1],
INSTANCE.getMenuActionParams0()[n3 - 1], INSTANCE.getMenuActionParams0()[n3 - 1],
INSTANCE.getMenuActionParams1()[n3 - 1]); INSTANCE.getMenuActionParams1()[n3 - 1]);
INSTANCE.getCallbacks().post(menuEntryAdded); INSTANCE.getCallbacks().post(menuEntryAdded);
} }
@Overwrite @Overwrite
public static void copy$processClientError(String s, Throwable e, byte b) public static void copy$processClientError(String s, Throwable e, byte b)
{ {
System.err.println("[RL+] Error thrown: " + s); System.err.println("[RL+] Error thrown: " + s);
e.printStackTrace(); e.printStackTrace();
} }
@Inject @Inject
public net.runelite.api.MouseRecorder getMouseRecorder() public net.runelite.api.MouseRecorder getMouseRecorder()
{ {
return _Statics_.mouseRecorder; return _Statics_.mouseRecorder;
} }
@Inject @Inject
public boolean boundingboxCheck2(net.runelite.api.Model model, int n2, int n3, int n4) public boolean boundingboxCheck2(net.runelite.api.Model model, int n2, int n3, int n4)
{ {
@@ -349,7 +349,7 @@ public class Client
} }
return false; return false;
} }
@Overwrite @Overwrite
public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2) public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2)
{ {
@@ -441,10 +441,10 @@ public class Client
int n29 = rl$modelViewportXs[n10]; int n29 = rl$modelViewportXs[n10];
int n30 = rl$modelViewportXs[n24]; int n30 = rl$modelViewportXs[n24];
if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = (n23 = (n22 = rSModel.isClickable() ? 20 if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = (n23 = (n22 = rSModel.isClickable() ? 20
: 5) + n11) < n28 && n23 < n29 && n23 < n30 ? false : 5) + n11) < n28 && n23 < n29 && n23 < n30 ? false
: ((n23 = n11 - n22) > n28 && n23 > n29 && n23 > n30 ? false : ((n23 = n11 - n22) > n28 && n23 > n29 && n23 > n30 ? false
: ((n23 = n22 + n14) < n25 && n23 < n26 && n23 < n27 ? false : ((n23 = n22 + n14) < n25 && n23 < n26 && n23 < n27 ? false
: (n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27)))) : (n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27))))
{ {
this.addHashAtMouse(l2); this.addHashAtMouse(l2);
return; return;
@@ -453,91 +453,90 @@ public class Client
++n13; ++n13;
} }
} }
@Provided @Provided
public boolean getViewportContainsMouse() public boolean getViewportContainsMouse()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public void addHashAtMouse(long l) public void addHashAtMouse(long l)
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int getCameraPitch() public int getCameraPitch()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int getCameraYaw() public int getCameraYaw()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int getCenterX() public int getCenterX()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int getCenterY() public int getCenterY()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int getViewportMouseX() public int getViewportMouseX()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int getViewportMouseY() public int getViewportMouseY()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public int get3dZoom() public int get3dZoom()
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public static int rl$rot1(int a, int b, int c, int d) public static int rl$rot1(int a, int b, int c, int d)
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public static int rl$rot2(int a, int b, int c, int d) public static int rl$rot2(int a, int b, int c, int d)
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public static int rl$rot3(int a, int b, int c, int d) public static int rl$rot3(int a, int b, int c, int d)
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Provided @Provided
public static int rl$rot4(int a, int b, int c, int d) public static int rl$rot4(int a, int b, int c, int d)
{ {
throw new RuntimeException(); throw new RuntimeException();
} }
@Inject @Inject
public void invokeMenuAction(int actionParam, int widgetId, int opcode, int targetId, String menuOption, public void invokeMenuAction(int actionParam, int widgetId, int opcode, int targetId, String menuOption, String menuTarget, int mouseX, int mouseY)
String menuTarget, int mouseX, int mouseY)
{ {
_Statics_.menuAction(actionParam, widgetId, opcode, targetId, menuOption, _Statics_.menuAction(actionParam, widgetId, opcode, targetId, menuOption,
menuTarget, mouseX, mouseY); menuTarget, mouseX, mouseY);
} }
} }

View File

@@ -51,7 +51,7 @@ public class Player
@Overwrite @Overwrite
public SkullIcon getSkullIcon() public SkullIcon getSkullIcon()
{ {
switch(getHeadIconPk()) switch (getHeadIconPk())
{ {
case 0: case 0:
return SkullIcon.SKULL; return SkullIcon.SKULL;

View File

@@ -43,10 +43,10 @@ public class Scene
return true; return true;
} }
if(renderable instanceof RSPlayer) if (renderable instanceof RSPlayer)
{ {
RSPlayer p = (RSPlayer) renderable; RSPlayer p = (RSPlayer) renderable;
if(Client.hideClanMates && p.isClanMember()) if (Client.hideClanMates && p.isClanMember())
{ {
return false; return false;
} }

View File

@@ -41,10 +41,10 @@ public class _Statics_
static final void prepend$menuAction(int actionParam, int widgetId, int opcode, int targetId, String menuOption, static final void prepend$menuAction(int actionParam, int widgetId, int opcode, int targetId, String menuOption,
String menuTarget, int mouseX, int mouseY) String menuTarget, int mouseX, int mouseY)
{ {
if(Client.printMenuActions) if (Client.printMenuActions)
{ {
int printOpcode = opcode; int printOpcode = opcode;
if(opcode >= 2000) if (opcode >= 2000)
{ {
printOpcode -= 2000; printOpcode -= 2000;
} }

View File

@@ -175,7 +175,7 @@ public final class AnimationID
public static final int VORKATH_ACID_ATTACK = 7957; public static final int VORKATH_ACID_ATTACK = 7957;
public static final int BLACKJACK_KO = 838; public static final int BLACKJACK_KO = 838;
public static final int VETION_EARTHQUAKE = 5507; public static final int VETION_EARTHQUAKE = 5507;
public static final int ZULRAH_DEATH = 5804; public static final int ZULRAH_DEATH = 5804;
// Farming // Farming
public static final int FARMING_HARVEST_FRUIT_TREE = 2280; public static final int FARMING_HARVEST_FRUIT_TREE = 2280;
@@ -214,8 +214,8 @@ public final class AnimationID
// POH Animations // POH Animations
public static final int INCENSE_BURNER = 3687; public static final int INCENSE_BURNER = 3687;
public static final int LOW_LEVEL_MAGIC_ATTACK = 1162; public static final int LOW_LEVEL_MAGIC_ATTACK = 1162;
public static final int HIGH_LEVEL_MAGIC_ATTACK = 1167; public static final int HIGH_LEVEL_MAGIC_ATTACK = 1167;
public static final int BLOWPIPE_ATTACK = 5061; public static final int BLOWPIPE_ATTACK = 5061;
// Hydra // Hydra
public static final int HYDRA_POISON_1 = 8234; public static final int HYDRA_POISON_1 = 8234;
@@ -238,4 +238,4 @@ public final class AnimationID
public static final int HYDRA_RANGED_4 = 8255; public static final int HYDRA_RANGED_4 = 8255;
public static final int HYDRA_4_1 = 8257; public static final int HYDRA_4_1 = 8257;
public static final int HYDRA_4_2 = 8258; public static final int HYDRA_4_2 = 8258;
} }

View File

@@ -1614,7 +1614,18 @@ public interface Client extends GameEngine
void toggleRenderSelf(); void toggleRenderSelf();
void invokeMenuAction(int var1, int var2, int var3, int var4, String var5, String var6, int var7, int var8); /**
*
* @param param0 This is SceneX for gameObject, index for items, and 0 for npc.
* @param param1 This is SceneY for gameObject, static for items, and 0 for npc.
* @param type Menu entry Action type.
* @param id Targets ID
* @param menuEntry Do these actually matter?
* @param targetString Do these actually matter?
* @param canvasX Canvas X Point
* @param canvasY Canvas Y Point
*/
void invokeMenuAction(int param0, int param1, int type, int id, String menuEntry, String targetString, int canvasX, int canvasY);
MouseRecorder getMouseRecorder(); MouseRecorder getMouseRecorder();

View File

@@ -49,7 +49,9 @@ public class ProjectileID
public static final int OLM_FALLING_CRYSTAL_TRAIL = 1352; public static final int OLM_FALLING_CRYSTAL_TRAIL = 1352;
public static final int OLM_ACID_TRAIL = 1354; public static final int OLM_ACID_TRAIL = 1354;
public static final int OLM_FIRE_LINE = 1347; public static final int OLM_FIRE_LINE = 1347;
public static final int OLM_MAGE_ATTACK = 1339;
public static final int OLM_RANGE_ATTACK = 1340;
public static final int VORKATH_BOMB_AOE = 1481; public static final int VORKATH_BOMB_AOE = 1481;
public static final int VORKATH_POISON_POOL_AOE = 1483; public static final int VORKATH_POISON_POOL_AOE = 1483;
public static final int VORKATH_TICK_FIRE_AOE = 1482; public static final int VORKATH_TICK_FIRE_AOE = 1482;
@@ -98,5 +100,5 @@ public class ProjectileID
public static final int HYDRA_POISON = 1644; public static final int HYDRA_POISON = 1644;
public static final int HYDRA_LIGHTNING = 1664; public static final int HYDRA_LIGHTNING = 1664;
public static final int HYDRA_LIGHTNING_2 = 1665; public static final int HYDRA_LIGHTNING_2 = 1665;
public static final int DRAKE_BREATH = 1637; public static final int DRAKE_BREATH = 1637;
} }

View File

@@ -36,20 +36,20 @@ public enum VarClientInt
{ {
TOOLTIP_TIMEOUT(1), TOOLTIP_TIMEOUT(1),
/** /**
* 0 = no tooltip displayed * 0 = no tooltip displayed
* 1 = tooltip displaying * 1 = tooltip displaying
*/ */
TOOLTIP_VISIBLE(2), TOOLTIP_VISIBLE(2),
INPUT_TYPE(5), INPUT_TYPE(5),
MEMBERSHIP_STATUS(103), MEMBERSHIP_STATUS(103),
/** /**
* -1 = player inventory closed * -1 = player inventory closed
* 3 = player inventory opened * 3 = player inventory opened
*/ */
PLAYER_INVENTORY_OPENED(171), PLAYER_INVENTORY_OPENED(171),
INVENTORY_TAB(171), INVENTORY_TAB(171),

View File

@@ -523,6 +523,14 @@ public enum Varbits
*/ */
QUEST_TAB(8168), QUEST_TAB(8168),
/**
* Explorer ring
*/
EXPLORER_RING_ALCHTYPE(5398),
EXPLORER_RING_TELEPORTS(4552),
EXPLORER_RING_ALCHS(4554),
EXPLORER_RING_RUNENERGY(4553),
/** /**
* Temple Trekking * Temple Trekking
*/ */
@@ -559,7 +567,7 @@ public enum Varbits
QUEST_THE_EYES_OF_GLOUPHRIE(2497), QUEST_THE_EYES_OF_GLOUPHRIE(2497),
QUEST_FAIRYTALE_I_GROWING_PAINS(1803), QUEST_FAIRYTALE_I_GROWING_PAINS(1803),
QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326), QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326),
QUEST_THE_FEUD(334), QUEST_THE_FEUD(334), // 14 = able to pickpocket
QUEST_FORGETTABLE_TALE(822), QUEST_FORGETTABLE_TALE(822),
QUEST_GARDEN_OF_TRANQUILLITY(961), QUEST_GARDEN_OF_TRANQUILLITY(961),
QUEST_GHOSTS_AHOY(217), QUEST_GHOSTS_AHOY(217),
@@ -628,7 +636,12 @@ public enum Varbits
/** /**
* Spellbook filtering (1 = unfiltered, 0 = filtered) * Spellbook filtering (1 = unfiltered, 0 = filtered)
*/ */
FILTER_SPELLBOOK(6718); FILTER_SPELLBOOK(6718),
/**
* POH Building mode (1 = yes, 0 = no)
*/
BUILDING_MODE(2176);
/** /**
* The raw varbit ID. * The raw varbit ID.

View File

@@ -30,5 +30,5 @@ import net.runelite.api.Actor;
@Data @Data
public class InteractChanged public class InteractChanged
{ {
private Actor actor; private Actor actor;
} }

View File

@@ -41,6 +41,7 @@ public class WidgetID
public static final int LOGOUT_PANEL_ID = 182; public static final int LOGOUT_PANEL_ID = 182;
public static final int BANK_GROUP_ID = 12; public static final int BANK_GROUP_ID = 12;
public static final int BANK_INVENTORY_GROUP_ID = 15; public static final int BANK_INVENTORY_GROUP_ID = 15;
public static final int BANK_PIN_GROUP_ID = 213;
public static final int GRAND_EXCHANGE_INVENTORY_GROUP_ID = 467; public static final int GRAND_EXCHANGE_INVENTORY_GROUP_ID = 467;
public static final int GRAND_EXCHANGE_GROUP_ID = 465; public static final int GRAND_EXCHANGE_GROUP_ID = 465;
public static final int DEPOSIT_BOX_GROUP_ID = 192; public static final int DEPOSIT_BOX_GROUP_ID = 192;
@@ -353,6 +354,7 @@ public class WidgetID
static final int MINIMAP = 3; static final int MINIMAP = 3;
static final int MINIMAP_DRAW_AREA = 8; static final int MINIMAP_DRAW_AREA = 8;
static final int MULTICOMBAT_INDICATOR = 20; static final int MULTICOMBAT_INDICATOR = 20;
static final int BANK_PIN = 21;
static final int CLAN_CHAT_TAB = 31; static final int CLAN_CHAT_TAB = 31;
static final int FRIENDS_TAB = 33; static final int FRIENDS_TAB = 33;
static final int IGNORES_TAB = 32; static final int IGNORES_TAB = 32;
@@ -390,6 +392,7 @@ public class WidgetID
static class ResizableViewport static class ResizableViewport
{ {
static final int ITEMS_KEPT_ON_DEATH = 13; static final int ITEMS_KEPT_ON_DEATH = 13;
static final int BANK_PIN = 13;
static final int MULTICOMBAT_INDICATOR = 16; static final int MULTICOMBAT_INDICATOR = 16;
static final int CLAN_CHAT_TAB = 35; static final int CLAN_CHAT_TAB = 35;
static final int FRIENDS_TAB = 37; static final int FRIENDS_TAB = 37;
@@ -425,6 +428,7 @@ public class WidgetID
static class ResizableViewportBottomLine static class ResizableViewportBottomLine
{ {
static final int BANK_PIN = 13;
static final int LOGOUT_BUTTON_OVERLAY = 29; static final int LOGOUT_BUTTON_OVERLAY = 29;
static final int CMB_TAB = 50; static final int CMB_TAB = 50;
static final int CMB_ICON = 57; static final int CMB_ICON = 57;
@@ -930,7 +934,7 @@ public class WidgetID
static final int OURANIA_TELEPORT = 142; static final int OURANIA_TELEPORT = 142;
// ARCEUUS SPELLS // ARCEUUS SPELLS
static final int ARCEUUS_HOME_TELEPORT = 143; static final int ARCEUUS_HOME_TELEPORT = 143;
} }
static class Pvp static class Pvp
@@ -1034,7 +1038,8 @@ public class WidgetID
static final int CUSTOM_TEXT_CONTAINER = 33; static final int CUSTOM_TEXT_CONTAINER = 33;
} }
public static class TradeScreen { public static class TradeScreen
{
public static final int SECOND_GROUP_ID = 334; public static final int SECOND_GROUP_ID = 334;
public static final int SECOND_TRADING_WITH = 30; public static final int SECOND_TRADING_WITH = 30;
public static final int SECOND_MY_OFFER = 23; public static final int SECOND_MY_OFFER = 23;
@@ -1043,7 +1048,8 @@ public class WidgetID
public static final int SECOND_ACCEPT_TEXT = 25; public static final int SECOND_ACCEPT_TEXT = 25;
} }
public static class DuelConfig { public static class DuelConfig
{
public static final int CONFIG_GROUP_IP = 482; public static final int CONFIG_GROUP_IP = 482;
public static final int TITLE = 35; public static final int TITLE = 35;
public static final int OPPONENT_ATT = 9; public static final int OPPONENT_ATT = 9;
@@ -1052,11 +1058,26 @@ public class WidgetID
public static final int OPPONENT_HP = 21; public static final int OPPONENT_HP = 21;
} }
public static class DuelResult { public static class DuelResult
{
public static final int RESULT_GROUP_ID = 372; public static final int RESULT_GROUP_ID = 372;
public static final int TITLE = 16; public static final int TITLE = 16;
public static final int TOTAL_STAKED = 32; public static final int TOTAL_STAKED = 32;
public static final int TOTAL_TAX = 39; public static final int TOTAL_TAX = 39;
public static final int WINNINGS = 40; public static final int WINNINGS = 40;
} }
public static class BankPin
{
public static final int BUTTON_1 = 16;
public static final int BUTTON_2 = 18;
public static final int BUTTON_3 = 20;
public static final int BUTTON_4 = 22;
public static final int BUTTON_5 = 24;
public static final int BUTTON_6 = 26;
public static final int BUTTON_7 = 28;
public static final int BUTTON_8 = 30;
public static final int BUTTON_9 = 32;
public static final int BUTTON_0 = 34;
}
} }

View File

@@ -502,8 +502,8 @@ public enum WidgetInfo
PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO), PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO),
PVP_KILLDEATH_COUNTER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.KILLDEATH_RATIO), PVP_KILLDEATH_COUNTER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.KILLDEATH_RATIO),
SPELLBOOK_FILTERED_BOUNDS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FILTERED_SPELLS_BOUNDS), SPELLBOOK_FILTERED_BOUNDS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FILTERED_SPELLS_BOUNDS),
/* STANDARD SPELL BOOK WIDGETS*/ /* STANDARD SPELL BOOK WIDGETS*/
SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUMBRIDGE_HOME_TELEPORT), SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUMBRIDGE_HOME_TELEPORT),
SPELL_WIND_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_STRIKE), SPELL_WIND_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_STRIKE),
@@ -705,7 +705,21 @@ public enum WidgetInfo
ITEMS_KEPT_SAFE_ZONE_CONTAINER(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.SAFE_ZONE_CONTAINER), ITEMS_KEPT_SAFE_ZONE_CONTAINER(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.SAFE_ZONE_CONTAINER),
ITEMS_KEPT_CUSTOM_TEXT_CONTAINER(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.CUSTOM_TEXT_CONTAINER), ITEMS_KEPT_CUSTOM_TEXT_CONTAINER(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.CUSTOM_TEXT_CONTAINER),
ITEMS_LOST_VALUE(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.LOST_ITEMS_VALUE), ITEMS_LOST_VALUE(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.LOST_ITEMS_VALUE),
ITEMS_KEPT_MAX(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.MAX_ITEMS_KEPT_ON_DEATH); ITEMS_KEPT_MAX(WidgetID.KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.MAX_ITEMS_KEPT_ON_DEATH),
FIXED_BANK_PIN(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.BANK_PIN),
RESIZABLE_BANK_PIN(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.BANK_PIN),
RESIZABLE_BOTTOM_LINE_BANK_PIN(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.BANK_PIN),
BANK_PIN_1(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_1),
BANK_PIN_2(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_2),
BANK_PIN_3(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_3),
BANK_PIN_4(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_4),
BANK_PIN_5(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_5),
BANK_PIN_6(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_6),
BANK_PIN_7(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_7),
BANK_PIN_8(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_8),
BANK_PIN_9(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_9),
BANK_PIN_0(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_0);
private final int groupId; private final int groupId;
private final int childId; private final int childId;

View File

@@ -79,7 +79,7 @@ public class ClientSessionManager
} }
sessionId = null; sessionId = null;
} }
scheduledFuture.cancel(true); scheduledFuture.cancel(true);
} }

View File

@@ -100,7 +100,7 @@ public class Notifier
// First check if we are running in launcher // First check if we are running in launcher
this.terminalNotifierAvailable = this.terminalNotifierAvailable =
!Strings.isNullOrEmpty(RuneLiteProperties.getLauncherVersion()) !Strings.isNullOrEmpty(RuneLiteProperties.getLauncherVersion())
&& isTerminalNotifierAvailable(); && isTerminalNotifierAvailable();
storeIcon(); storeIcon();
} }

View File

@@ -59,7 +59,6 @@ import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginInstantiationException;
import net.runelite.client.plugins.PluginManager; import net.runelite.client.plugins.PluginManager;
import net.runelite.client.plugins.config.ConfigPanel;
import net.runelite.client.rs.ClientUpdateCheckMode; import net.runelite.client.rs.ClientUpdateCheckMode;
import net.runelite.client.task.Scheduler; import net.runelite.client.task.Scheduler;
import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ClientUI;
@@ -86,10 +85,10 @@ public class RuneLite
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles"); public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins"); public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots"); public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
public static RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen(); static final RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen();
@Getter @Getter
private static Injector injector; private static Injector injector;
@Inject @Inject
@@ -242,7 +241,7 @@ public class RuneLite
// The submessage is shown in case the connection is slow // The submessage is shown in case the connection is slow
splashScreen.setMessage("Starting RuneLite Injector"); splashScreen.setMessage("Starting RuneLite Injector");
splashScreen.setSubMessage( " "); splashScreen.setSubMessage(" ");
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();

View File

@@ -80,9 +80,12 @@ public class RuneLiteProperties
public String getDiscordAppId() public String getDiscordAppId()
{ {
if (RuneLitePlusPlugin.customPresenceEnabled) { if (RuneLitePlusPlugin.customPresenceEnabled)
{
return properties.getProperty(RuneLitePlusPlugin.rlPlusDiscordApp); return properties.getProperty(RuneLitePlusPlugin.rlPlusDiscordApp);
} else { }
else
{
return properties.getProperty(DISCORD_APP_ID); return properties.getProperty(DISCORD_APP_ID);
} }
} }

View File

@@ -50,7 +50,7 @@ class SessionClient
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
{ {
ResponseBody body = response.body(); ResponseBody body = response.body();
InputStream in = body.byteStream(); InputStream in = body.byteStream();
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), UUID.class); return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), UUID.class);
} }

View File

@@ -1,232 +1,232 @@
/* /*
* Copyright (c) 2017, Adam <Adam@sigterm.info> * Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.account; package net.runelite.client.account;
import com.google.gson.Gson; import com.google.gson.Gson;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.time.Instant; import java.time.Instant;
import java.util.UUID; import java.util.UUID;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.events.SessionClose; import net.runelite.client.RuneLite;
import net.runelite.client.events.SessionOpen; import net.runelite.client.config.ConfigManager;
import net.runelite.client.RuneLite; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.SessionClose;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.SessionOpen;
import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.LinkBrowser;
import net.runelite.client.ws.WSClient; import net.runelite.client.ws.WSClient;
import net.runelite.http.api.account.AccountClient; import net.runelite.http.api.account.AccountClient;
import net.runelite.http.api.account.OAuthResponse; import net.runelite.http.api.account.OAuthResponse;
import net.runelite.http.api.ws.messages.LoginResponse; import net.runelite.http.api.ws.messages.LoginResponse;
@Singleton @Singleton
@Slf4j @Slf4j
public class SessionManager public class SessionManager
{ {
private static final File SESSION_FILE = new File(RuneLite.RUNELITE_DIR, "session"); private static final File SESSION_FILE = new File(RuneLite.RUNELITE_DIR, "session");
@Getter @Getter
private AccountSession accountSession; private AccountSession accountSession;
private final EventBus eventBus; private final EventBus eventBus;
private final ConfigManager configManager; private final ConfigManager configManager;
private final WSClient wsClient; private final WSClient wsClient;
@Inject @Inject
private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient) private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient)
{ {
this.configManager = configManager; this.configManager = configManager;
this.eventBus = eventBus; this.eventBus = eventBus;
this.wsClient = wsClient; this.wsClient = wsClient;
eventBus.register(this); eventBus.register(this);
} }
public void loadSession() public void loadSession()
{ {
if (!SESSION_FILE.exists()) if (!SESSION_FILE.exists())
{ {
log.info("No session file exists"); log.info("No session file exists");
return; return;
} }
AccountSession session; AccountSession session;
try (FileInputStream in = new FileInputStream(SESSION_FILE)) try (FileInputStream in = new FileInputStream(SESSION_FILE))
{ {
session = new Gson().fromJson(new InputStreamReader(in), AccountSession.class); session = new Gson().fromJson(new InputStreamReader(in), AccountSession.class);
log.debug("Loaded session for {}", session.getUsername()); log.debug("Loaded session for {}", session.getUsername());
} }
catch (Exception ex) catch (Exception ex)
{ {
log.warn("Unable to load session file", ex); log.warn("Unable to load session file", ex);
return; return;
} }
// Check if session is still valid // Check if session is still valid
AccountClient accountClient = new AccountClient(session.getUuid()); AccountClient accountClient = new AccountClient(session.getUuid());
if (!accountClient.sesssionCheck()) if (!accountClient.sesssionCheck())
{ {
log.debug("Loaded session {} is invalid", session.getUuid()); log.debug("Loaded session {} is invalid", session.getUuid());
return; return;
} }
openSession(session, false); openSession(session, false);
} }
private void saveSession() private void saveSession()
{ {
if (accountSession == null) if (accountSession == null)
{ {
return; return;
} }
try (FileWriter fw = new FileWriter(SESSION_FILE)) try (FileWriter fw = new FileWriter(SESSION_FILE))
{ {
new Gson().toJson(accountSession, fw); new Gson().toJson(accountSession, fw);
log.debug("Saved session to {}", SESSION_FILE); log.debug("Saved session to {}", SESSION_FILE);
} }
catch (IOException ex) catch (IOException ex)
{ {
log.warn("Unable to save session file", ex); log.warn("Unable to save session file", ex);
} }
} }
private void deleteSession() private void deleteSession()
{ {
SESSION_FILE.delete(); SESSION_FILE.delete();
} }
/** /**
* Set the given session as the active session and open a socket to the * Set the given session as the active session and open a socket to the
* server with the given session * server with the given session
* *
* @param session session * @param session session
*/ */
private void openSession(AccountSession session, boolean openSocket) private void openSession(AccountSession session, boolean openSocket)
{ {
// Change session on the websocket // Change session on the websocket
if (openSocket) if (openSocket)
{ {
wsClient.changeSession(session.getUuid()); wsClient.changeSession(session.getUuid());
} }
accountSession = session; accountSession = session;
if (session.getUsername() != null) if (session.getUsername() != null)
{ {
// Initialize config for new session // Initialize config for new session
// If the session isn't logged in yet, don't switch to the new config // If the session isn't logged in yet, don't switch to the new config
configManager.switchSession(session); configManager.switchSession();
} }
eventBus.post(new SessionOpen()); eventBus.post(new SessionOpen());
} }
private void closeSession() private void closeSession()
{ {
wsClient.changeSession(null); wsClient.changeSession(null);
if (accountSession == null) if (accountSession == null)
{ {
return; return;
} }
log.debug("Logging out of account {}", accountSession.getUsername()); log.debug("Logging out of account {}", accountSession.getUsername());
AccountClient client = new AccountClient(accountSession.getUuid()); AccountClient client = new AccountClient(accountSession.getUuid());
try try
{ {
client.logout(); client.logout();
} }
catch (IOException ex) catch (IOException ex)
{ {
log.warn("Unable to logout of session", ex); log.warn("Unable to logout of session", ex);
} }
accountSession = null; // No more account accountSession = null; // No more account
// Restore config // Restore config
configManager.switchSession(null); configManager.switchSession();
eventBus.post(new SessionClose()); eventBus.post(new SessionClose());
} }
public void login() public void login()
{ {
// If a session is already open, use that id. Otherwise generate a new id. // If a session is already open, use that id. Otherwise generate a new id.
UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID(); UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID();
AccountClient loginClient = new AccountClient(uuid); AccountClient loginClient = new AccountClient(uuid);
final OAuthResponse login; final OAuthResponse login;
try try
{ {
login = loginClient.login(); login = loginClient.login();
} }
catch (IOException ex) catch (IOException ex)
{ {
log.warn("Unable to get oauth url", ex); log.warn("Unable to get oauth url", ex);
return; return;
} }
// Create new session // Create new session
openSession(new AccountSession(login.getUid(), Instant.now()), true); openSession(new AccountSession(login.getUid(), Instant.now()), true);
// Navigate to login link // Navigate to login link
LinkBrowser.browse(login.getOauthUrl()); LinkBrowser.browse(login.getOauthUrl());
} }
@Subscribe @Subscribe
public void onLoginResponse(LoginResponse loginResponse) public void onLoginResponse(LoginResponse loginResponse)
{ {
log.debug("Now logged in as {}", loginResponse.getUsername()); log.debug("Now logged in as {}", loginResponse.getUsername());
AccountSession session = getAccountSession(); AccountSession session = getAccountSession();
session.setUsername(loginResponse.getUsername()); session.setUsername(loginResponse.getUsername());
// Open session, again, now that we have a username // Open session, again, now that we have a username
// This triggers onSessionOpen // This triggers onSessionOpen
// The socket is already opened here anyway so we pass true for openSocket // The socket is already opened here anyway so we pass true for openSocket
openSession(session, true); openSession(session, true);
// Save session to disk // Save session to disk
saveSession(); saveSession();
} }
public void logout() public void logout()
{ {
closeSession(); closeSession();
deleteSession(); deleteSession();
} }
} }

View File

@@ -45,6 +45,7 @@ import net.runelite.api.Client;
import net.runelite.api.Constants; import net.runelite.api.Constants;
import net.runelite.api.MainBufferProvider; import net.runelite.api.MainBufferProvider;
import net.runelite.api.NullItemID; import net.runelite.api.NullItemID;
import net.runelite.api.Point;
import net.runelite.api.RenderOverview; import net.runelite.api.RenderOverview;
import net.runelite.api.Renderable; import net.runelite.api.Renderable;
import net.runelite.api.WorldMapManager; import net.runelite.api.WorldMapManager;
@@ -374,6 +375,7 @@ public class Hooks implements Callbacks
/** /**
* Copy an image * Copy an image
*
* @param src * @param src
* @return * @return
*/ */
@@ -395,6 +397,18 @@ public class Hooks implements Callbacks
BufferedImage image = (BufferedImage) bufferProvider.getImage(); BufferedImage image = (BufferedImage) bufferProvider.getImage();
Graphics2D graphics2d = image.createGraphics(); Graphics2D graphics2d = image.createGraphics();
// Update selected scene tile
if (!client.isMenuOpen())
{
Point p = client.getMouseCanvasPosition();
p = new Point(
p.getX() - client.getViewportXOffset(),
p.getY() - client.getViewportYOffset());
client.setCheckClick(true);
client.setMouseCanvasHoverPosition(p);
}
try try
{ {
renderer.render(graphics2d, OverlayLayer.ABOVE_SCENE); renderer.render(graphics2d, OverlayLayer.ABOVE_SCENE);

View File

@@ -1,153 +1,153 @@
/* /*
* Copyright (c) 2017, Adam <Adam@sigterm.info> * Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.config; package net.runelite.client.config;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Objects; import java.util.Objects;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
class ConfigInvocationHandler implements InvocationHandler class ConfigInvocationHandler implements InvocationHandler
{ {
private final ConfigManager manager; private final ConfigManager manager;
public ConfigInvocationHandler(ConfigManager manager) public ConfigInvocationHandler(ConfigManager manager)
{ {
this.manager = manager; this.manager = manager;
} }
@Override @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{ {
Class<?> iface = proxy.getClass().getInterfaces()[0]; Class<?> iface = proxy.getClass().getInterfaces()[0];
ConfigGroup group = iface.getAnnotation(ConfigGroup.class); ConfigGroup group = iface.getAnnotation(ConfigGroup.class);
ConfigItem item = method.getAnnotation(ConfigItem.class); ConfigItem item = method.getAnnotation(ConfigItem.class);
if (group == null) if (group == null)
{ {
log.warn("Configuration proxy class {} has no @ConfigGroup!", proxy.getClass()); log.warn("Configuration proxy class {} has no @ConfigGroup!", proxy.getClass());
return null; return null;
} }
if (item == null) if (item == null)
{ {
log.warn("Configuration method {} has no @ConfigItem!", method); log.warn("Configuration method {} has no @ConfigItem!", method);
return null; return null;
} }
if (args == null) if (args == null)
{ {
// Getting configuration item // Getting configuration item
String value = manager.getConfiguration(group.value(), item.keyName()); String value = manager.getConfiguration(group.value(), item.keyName());
if (value == null) if (value == null)
{ {
if (method.isDefault()) if (method.isDefault())
{ {
return callDefaultMethod(proxy, method, null); return callDefaultMethod(proxy, method, null);
} }
return null; return null;
} }
// Convert value to return type // Convert value to return type
Class<?> returnType = method.getReturnType(); Class<?> returnType = method.getReturnType();
try try
{ {
return ConfigManager.stringToObject(value, returnType); return ConfigManager.stringToObject(value, returnType);
} }
catch (Exception e) catch (Exception e)
{ {
log.warn("Unable to unmarshal {}.{} ", group.value(), item.keyName(), e); log.warn("Unable to unmarshal {}.{} ", group.value(), item.keyName(), e);
if (method.isDefault()) if (method.isDefault())
{ {
return callDefaultMethod(proxy, method, null); return callDefaultMethod(proxy, method, null);
} }
return null; return null;
} }
} }
else else
{ {
// Setting a configuration value // Setting a configuration value
if (args.length != 1) if (args.length != 1)
{ {
throw new RuntimeException("Invalid number of arguents to configuration method"); throw new RuntimeException("Invalid number of arguents to configuration method");
} }
Object newValue = args[0]; Object newValue = args[0];
Class<?> type = method.getParameterTypes()[0]; Class<?> type = method.getParameterTypes()[0];
Object oldValue = manager.getConfiguration(group.value(), item.keyName(), type); Object oldValue = manager.getConfiguration(group.value(), item.keyName(), type);
if (Objects.equals(oldValue, newValue)) if (Objects.equals(oldValue, newValue))
{ {
// nothing to do // nothing to do
return null; return null;
} }
if (method.isDefault()) if (method.isDefault())
{ {
Object defaultValue = callDefaultMethod(proxy, method, args); Object defaultValue = callDefaultMethod(proxy, method, args);
if (Objects.equals(newValue, defaultValue)) if (Objects.equals(newValue, defaultValue))
{ {
// Just unset if it goes back to the default // Just unset if it goes back to the default
manager.unsetConfiguration(group.value(), item.keyName()); manager.unsetConfiguration(group.value(), item.keyName());
return null; return null;
} }
} }
if (newValue == null) if (newValue == null)
{ {
manager.unsetConfiguration(group.value(), item.keyName()); manager.unsetConfiguration(group.value(), item.keyName());
} }
else else
{ {
String newValueStr = ConfigManager.objectToString(newValue); String newValueStr = ConfigManager.objectToString(newValue);
manager.setConfiguration(group.value(), item.keyName(), newValueStr); manager.setConfiguration(group.value(), item.keyName(), newValueStr);
} }
return null; return null;
} }
} }
static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable
{ {
// Call the default method implementation - https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/ // Call the default method implementation - https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/
Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class); Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true); constructor.setAccessible(true);
Class<?> declaringClass = method.getDeclaringClass(); Class<?> declaringClass = method.getDeclaringClass();
return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE) return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE)
.unreflectSpecial(method, declaringClass) .unreflectSpecial(method, declaringClass)
.bindTo(proxy) .bindTo(proxy)
.invokeWithArguments(args); .invokeWithArguments(args);
} }
} }

View File

@@ -49,4 +49,7 @@ public @interface ConfigItem
String group() default ""; String group() default "";
String unhide() default "";
String parent() default "";
} }

View File

@@ -1,52 +1,52 @@
/* /*
* Copyright (c) 2018, Craftiii4 <craftiii4@gmail.com> * Copyright (c) 2018, Craftiii4 <craftiii4@gmail.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.config; package net.runelite.client.config;
import lombok.AccessLevel; import java.util.ArrayList;
import lombok.Getter; import java.util.Collection;
import java.util.ArrayList; import lombok.AccessLevel;
import java.util.Collection; import lombok.Getter;
public class ConfigItemsGroup public class ConfigItemsGroup
{ {
@Getter(AccessLevel.PUBLIC) @Getter(AccessLevel.PUBLIC)
private final String group; private final String group;
@Getter(AccessLevel.PUBLIC) @Getter(AccessLevel.PUBLIC)
private Collection<ConfigItemDescriptor> items; private Collection<ConfigItemDescriptor> items;
public ConfigItemsGroup(String group) public ConfigItemsGroup(String group)
{ {
this.group = group; this.group = group;
this.items = new ArrayList<>(); this.items = new ArrayList<>();
} }
public void addItem(ConfigItemDescriptor item) public void addItem(ConfigItemDescriptor item)
{ {
items.add(item); items.add(item);
} }
} }

View File

@@ -62,7 +62,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.client.RuneLite; import net.runelite.client.RuneLite;
import net.runelite.client.account.AccountSession; import static net.runelite.client.RuneLite.PROFILES_DIR;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
@@ -71,14 +71,14 @@ import net.runelite.client.util.ColorUtil;
public class ConfigManager public class ConfigManager
{ {
private static final String SETTINGS_FILE_NAME = "runeliteplus.properties"; private static final String SETTINGS_FILE_NAME = "runeliteplus.properties";
private static final String STANDARD_SETTINGS_FILE_NAME = "settings.properties";
private static final File SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME); private static final File SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME);
private static final File STANDARD_SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, "settings.properties"); private static final File STANDARD_SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, STANDARD_SETTINGS_FILE_NAME);
@Inject @Inject
EventBus eventBus; EventBus eventBus;
private final ScheduledExecutorService executor; private final ScheduledExecutorService executor;
private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this); private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this);
private final Properties properties = new Properties(); private final Properties properties = new Properties();
private final Map<String, String> pendingChanges = new HashMap<>(); private final Map<String, String> pendingChanges = new HashMap<>();
@@ -91,7 +91,7 @@ public class ConfigManager
executor.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS); executor.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
} }
public final void switchSession(AccountSession session) public final void switchSession()
{ {
// Ensure existing config is saved // Ensure existing config is saved
load(); load();
@@ -164,7 +164,7 @@ public class ConfigManager
catch (FileNotFoundException ex) catch (FileNotFoundException ex)
{ {
log.debug("Unable to load settings - no such file, syncing from standard settings"); log.debug("Unable to load settings - no such file, syncing from standard settings");
syncPropertiesFromFile(STANDARD_SETTINGS_FILE); syncLastModified();
} }
catch (IllegalArgumentException | IOException ex) catch (IllegalArgumentException | IOException ex)
{ {
@@ -201,11 +201,11 @@ public class ConfigManager
} }
} }
private void saveToFile(final File propertiesFile) throws IOException private void saveToFile() throws IOException
{ {
propertiesFile.getParentFile().mkdirs(); ConfigManager.SETTINGS_FILE.getParentFile().mkdirs();
try (FileOutputStream out = new FileOutputStream(propertiesFile)) try (FileOutputStream out = new FileOutputStream(ConfigManager.SETTINGS_FILE))
{ {
final FileLock lock = out.getChannel().lock(); final FileLock lock = out.getChannel().lock();
@@ -364,9 +364,9 @@ public class ConfigManager
} }
itemGroups = itemGroups.stream().sorted((a, b) -> ComparisonChain.start() itemGroups = itemGroups.stream().sorted((a, b) -> ComparisonChain.start()
.compare(a.getGroup(), b.getGroup()) .compare(a.getGroup(), b.getGroup())
.result()) .result())
.collect(Collectors.toList()); .collect(Collectors.toList());
return new ConfigDescriptor(group, itemGroups); return new ConfigDescriptor(group, itemGroups);
} }
@@ -511,22 +511,22 @@ public class ConfigManager
{ {
return Duration.ofMillis(Long.parseLong(str)); return Duration.ofMillis(Long.parseLong(str));
} }
if (type == Map.class) if (type == Map.class)
{ {
Map<String, String> output = new HashMap<>(); Map<String, String> output = new HashMap<>();
str = str.substring(1, str.length() - 1); str = str.substring(1, str.length() - 1);
String[] splitStr = str.split(", "); String[] splitStr = str.split(", ");
for (String s : splitStr) for (String s : splitStr)
{ {
String[] keyVal = s.split("="); String[] keyVal = s.split("=");
if (keyVal.length > 1) if (keyVal.length > 1)
{ {
output.put(keyVal[0], keyVal[1]); output.put(keyVal[0], keyVal[1]);
} }
} }
return output; return output;
} }
return str; return str;
} }
@@ -589,7 +589,7 @@ public class ConfigManager
{ {
try try
{ {
saveToFile(SETTINGS_FILE); saveToFile();
} }
catch (IOException ex) catch (IOException ex)
{ {
@@ -597,4 +597,32 @@ public class ConfigManager
} }
} }
} }
}
private void syncLastModified()
{
File newestFile;
newestFile = STANDARD_SETTINGS_FILE;
for (File profileDir : PROFILES_DIR.listFiles())
{
if (!profileDir.isDirectory())
{
continue;
}
for (File settings : profileDir.listFiles())
{
if (!settings.getName().equals(STANDARD_SETTINGS_FILE_NAME) ||
settings.lastModified() < newestFile.lastModified())
{
continue;
}
newestFile = settings;
}
}
syncPropertiesFromFile(newestFile);
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2018, Craftiii4 <craftiii4@gmail.com>
* 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.config;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
public class ConfigPanelItem
{
@Getter(AccessLevel.PUBLIC)
private ConfigPanelItem parent;
@Getter(AccessLevel.PUBLIC)
private List<ConfigPanelItem> children;
@Getter(AccessLevel.PUBLIC)
private ConfigItemDescriptor item;
public ConfigPanelItem(ConfigPanelItem parent, ConfigItemDescriptor item)
{
this.parent = parent;
this.children = new ArrayList<>();
this.item = item;
}
public List<ConfigPanelItem> getItemsAsList()
{
List<ConfigPanelItem> items = new ArrayList<>();
items.add(this);
for (ConfigPanelItem child : children)
{
items.addAll(child.getItemsAsList());
}
return items;
}
public int getDepth()
{
return (parent == null ? 0 : parent.getDepth() + 1);
}
public boolean addChildIfMatchParent(ConfigItemDescriptor cid)
{
if (item != null && item.getItem().keyName().equals(cid.getItem().parent()))
{
children.add(new ConfigPanelItem(this, cid));
return true;
}
else
{
for (ConfigPanelItem child : children)
{
if (child.addChildIfMatchParent(cid))
{
return true;
}
}
return false;
}
}
}

View File

@@ -1,49 +1,48 @@
/* /*
* Copyright (c) 2018, Tanner <https://github.com/Reasel> * Copyright (c) 2018, Tanner <https://github.com/Reasel>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.config; package net.runelite.client.config;
import lombok.RequiredArgsConstructor; import java.awt.Font;
import lombok.Getter; import lombok.Getter;
import net.runelite.client.ui.FontManager; import lombok.RequiredArgsConstructor;
import net.runelite.client.ui.FontManager;
import java.awt.Font;
@Getter
@Getter @RequiredArgsConstructor
@RequiredArgsConstructor public enum FontType
public enum FontType {
{ REGULAR("Regular", FontManager.getRunescapeFont()),
REGULAR("Regular", FontManager.getRunescapeFont()), BOLD("Bold", FontManager.getRunescapeBoldFont()),
BOLD("Bold", FontManager.getRunescapeBoldFont()), SMALL("Small", FontManager.getRunescapeSmallFont());
SMALL("Small", FontManager.getRunescapeSmallFont());
private final String name;
private final String name; private final Font font;
private final Font font;
@Override
@Override public String toString()
public String toString() {
{ return name;
return name; }
} }
}

View File

@@ -67,7 +67,7 @@ public interface RuneLiteConfig extends Config
keyName = "enablePlugins", keyName = "enablePlugins",
name = "Enable loading of external plugins", name = "Enable loading of external plugins",
description = "Enable loading of external plugins", description = "Enable loading of external plugins",
position = 10 position = 10
) )
default boolean enablePlugins() default boolean enablePlugins()
{ {

View File

@@ -0,0 +1,5 @@
package net.runelite.client.config;
public class Stub
{
}

View File

@@ -106,7 +106,7 @@ public class DiscordService implements AutoCloseable
discordEventHandlers.joinGame = this::joinGame; discordEventHandlers.joinGame = this::joinGame;
discordEventHandlers.spectateGame = this::spectateGame; discordEventHandlers.spectateGame = this::spectateGame;
discordEventHandlers.joinRequest = this::joinRequest; discordEventHandlers.joinRequest = this::joinRequest;
discordRPC.Discord_Initialize(runeLiteProperties.discordAppID, discordEventHandlers, true, null); discordRPC.Discord_Initialize(RuneLiteProperties.discordAppID, discordEventHandlers, true, null);
executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS); executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS);
} }

View File

@@ -35,248 +35,307 @@ for mouse motion.
package net.runelite.client.flexo; package net.runelite.client.flexo;
import com.github.joonasvali.naturalmouse.api.MouseMotionFactory; import com.github.joonasvali.naturalmouse.api.MouseMotionFactory;
import net.runelite.api.Client; import java.awt.AWTException;
import net.runelite.client.ui.ClientUI; import java.awt.Color;
import sun.awt.ComponentFactory; import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.swing.*; import java.awt.Point;
import java.awt.*; import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.peer.RobotPeer; import java.awt.peer.RobotPeer;
import java.util.Random; import java.util.Random;
import java.util.logging.Logger; import java.util.logging.Logger;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.client.ui.ClientUI;
import sun.awt.ComponentFactory;
public class Flexo extends Robot { public class Flexo extends Robot
public ThreadGroup flexoThreads = new ThreadGroup("flexo"); {
public static boolean isActive; public ThreadGroup flexoThreads = new ThreadGroup("flexo");
public static double scale; public static boolean isActive;
public static Client client; public static double scale;
public static ClientUI clientUI; public static Client client;
public static int fixedWidth = 765; public static ClientUI clientUI;
public static int fixedHeight = 503; public static int fixedWidth = Constants.GAME_FIXED_WIDTH;
public static boolean isStretched; public static int fixedHeight = Constants.GAME_FIXED_HEIGHT;
public static int minDelay = 45; public static boolean isStretched;
public static MouseMotionFactory currentMouseMotionFactory; public static int minDelay = 45;
public boolean pausedIndefinitely = false; public static MouseMotionFactory currentMouseMotionFactory;
private Thread holdKeyThread; public boolean pausedIndefinitely = false;
private RobotPeer peer; private Thread holdKeyThread;
private RobotPeer peer;
public Flexo() throws AWTException { public Flexo() throws AWTException
if (GraphicsEnvironment.isHeadless()) { {
throw new AWTException("headless environment"); if (GraphicsEnvironment.isHeadless())
} {
init(GraphicsEnvironment.getLocalGraphicsEnvironment() throw new AWTException("headless environment");
.getDefaultScreenDevice()); }
} init(GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice());
}
private void init(GraphicsDevice screen) throws AWTException { private void init(GraphicsDevice screen) throws AWTException
Toolkit toolkit = Toolkit.getDefaultToolkit(); {
if (toolkit instanceof ComponentFactory) { Toolkit toolkit = Toolkit.getDefaultToolkit();
peer = ((ComponentFactory)toolkit).createRobot(this, screen); if (toolkit instanceof ComponentFactory)
RobotDisposer disposer = new RobotDisposer(peer); {
sun.java2d.Disposer.addRecord(anchor, disposer); peer = ((ComponentFactory) toolkit).createRobot(this, screen);
} RobotDisposer disposer = new RobotDisposer(peer);
} sun.java2d.Disposer.addRecord(anchor, disposer);
}
}
private transient Object anchor = new Object(); private transient Object anchor = new Object();
static class RobotDisposer implements sun.java2d.DisposerRecord { static class RobotDisposer implements sun.java2d.DisposerRecord
private final RobotPeer peer; {
private RobotDisposer(RobotPeer peer) { private final RobotPeer peer;
this.peer = peer;
}
public void dispose() {
if (peer != null) {
peer.dispose();
}
}
}
private void pauseMS(int delayMS) { private RobotDisposer(RobotPeer peer)
long initialMS = System.currentTimeMillis(); {
while (System.currentTimeMillis()<initialMS+delayMS) { this.peer = peer;
try { }
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
isActive = false;
}
@Override public void dispose()
public synchronized void mouseMove(int x, int y) { {
try { if (peer != null)
//TODO: Must be better way to determine titlebar width {
currentMouseMotionFactory.build(ClientUI.frame.getX()+x+determineHorizontalOffset(), ClientUI.frame.getY()+y+determineVerticalOffset()).move(); peer.dispose();
this.delay(getMinDelay()); }
} catch (InterruptedException e) { }
e.printStackTrace(); }
}
}
public synchronized void mouseMove(Point p) { private void pauseMS(int delayMS)
Point p2 = p; {
mouseMove((int)p.getX(), (int)p.getY()); long initialMS = System.currentTimeMillis();
try { while (System.currentTimeMillis() < initialMS + delayMS)
Thread.sleep(150); {
} catch (InterruptedException e) { try
e.printStackTrace(); {
} Thread.sleep(10);
} }
catch (Exception e)
{
e.printStackTrace();
}
}
isActive = false;
}
@Override @Override
public synchronized void mousePress(int buttonID) { public synchronized void mouseMove(int x, int y)
if (buttonID<1 || buttonID >5) { {
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5."); try
return; {
} //TODO: Must be better way to determine titlebar width
peer.mousePress(InputEvent.getMaskForButton(buttonID)); currentMouseMotionFactory.build(ClientUI.frame.getX() + x + determineHorizontalOffset(), ClientUI.frame.getY() + y + determineVerticalOffset()).move();
this.delay(getMinDelay()); this.delay(getMinDelay());
} }
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public synchronized void mousePressAndRelease(int buttonID) { public synchronized void mouseMove(Point p)
if (buttonID<1 || buttonID >5) { {
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5."); Point p2 = p;
return; mouseMove((int) p.getX(), (int) p.getY());
} try
peer.mousePress(InputEvent.getMaskForButton(buttonID)); {
this.delay(getMinDelay()); Thread.sleep(150);
peer.mouseRelease(InputEvent.getMaskForButton(buttonID)); }
this.delay(getMinDelay()); catch (InterruptedException e)
} {
e.printStackTrace();
}
}
//TODO: Symbols are nut supported at this time @Override
public synchronized void typeMessage(String message) { public synchronized void mousePress(int buttonID)
{
if (buttonID < 1 || buttonID > 5)
{
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
return;
}
peer.mousePress(InputEvent.getMaskForButton(buttonID));
this.delay(getMinDelay());
}
Random r = new Random(); public synchronized void mousePressAndRelease(int buttonID)
char[] charArray = message.toCharArray(); {
for (char c : charArray) { if (buttonID < 1 || buttonID > 5)
keyPress(KeyEvent.getExtendedKeyCodeForChar(c)); {
this.delay(93+r.nextInt(getMinDelay())); Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
} return;
keyPress(KeyEvent.VK_ENTER); }
this.delay(93+r.nextInt(getMinDelay())); peer.mousePress(InputEvent.getMaskForButton(buttonID));
ClientUI.allowInput = true; this.delay(getMinDelay());
} peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
this.delay(getMinDelay());
}
//TODO: Symbols are nut supported at this time
public synchronized void typeMessage(String message)
{
Random r = new Random();
char[] charArray = message.toCharArray();
for (char c : charArray)
{
keyPress(KeyEvent.getExtendedKeyCodeForChar(c));
this.delay(93 + r.nextInt(getMinDelay()));
}
keyPress(KeyEvent.VK_ENTER);
this.delay(93 + r.nextInt(getMinDelay()));
ClientUI.allowInput = true;
}
@Override
public synchronized void mouseRelease(int buttonID)
{
if (buttonID < 1 || buttonID > 5)
{
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
return;
}
peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
this.delay(getMinDelay());
}
@Override private int getMinDelay()
public synchronized void mouseRelease(int buttonID) { {
if (buttonID<1 || buttonID >5) { Random random = new Random();
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5."); int random1 = random.nextInt(minDelay);
return; if (random1 < minDelay / 2)
} {
peer.mouseRelease(InputEvent.getMaskForButton(buttonID)); random1 = random.nextInt(minDelay / 2) + minDelay / 2 + random.nextInt(minDelay / 2);
this.delay(getMinDelay()); }
} return random1;
}
private int getMinDelay() { private int getWheelDelay()
Random random = new Random(); {
int random1 = random.nextInt(minDelay); Random random = new Random();
if (random1 < minDelay/2) int random1 = random.nextInt(minDelay);
random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2); if (random1 < minDelay / 2)
return random1; {
} random1 = random.nextInt(minDelay / 2) + minDelay / 2 + random.nextInt(minDelay / 2);
}
return random1;
}
private int getWheelDelay() { /**
Random random = new Random(); * Rotates the scroll wheel on wheel-equipped mice.
int random1 = random.nextInt(minDelay); *
if (random1 < minDelay/2) * @param wheelAmt number of "notches" to move the mouse wheel
random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2); * Negative values indicate movement up/away from the user,
return random1; * positive values indicate movement down/towards the user.
} * @since 1.4
*/
@Override
public synchronized void mouseWheel(int wheelAmt)
{
for (int i : new int[wheelAmt])
{
peer.mouseWheel(wheelAmt);
this.delay(getWheelDelay());
}
}
/** /**
* Rotates the scroll wheel on wheel-equipped mice. * Presses a given key. The key should be released using the
* * <code>keyRelease</code> method.
* @param wheelAmt number of "notches" to move the mouse wheel * <p>
* Negative values indicate movement up/away from the user, * Key codes that have more than one physical key associated with them
* positive values indicate movement down/towards the user. * (e.g. <code>KeyEvent.VK_SHIFT</code> could mean either the
* * left or right shift key) will map to the left key.
* @since 1.4 *
*/ * @param keycode Key to press (e.g. <code>KeyEvent.VK_A</code>)
@Override * @throws IllegalArgumentException if <code>keycode</code> is not
public synchronized void mouseWheel(int wheelAmt) { * a valid key
for (int i : new int[wheelAmt]) { * @see #keyRelease(int)
peer.mouseWheel(wheelAmt); * @see java.awt.event.KeyEvent
this.delay(getWheelDelay()); */
} @Override
} public synchronized void keyPress(int keycode)
{
peer.keyPress(keycode);
this.delay(getMinDelay());
}
/** @Override
* Presses a given key. The key should be released using the public synchronized void keyRelease(int keycode)
* <code>keyRelease</code> method. {
* <p> peer.keyRelease(keycode);
* Key codes that have more than one physical key associated with them this.delay(getMinDelay());
* (e.g. <code>KeyEvent.VK_SHIFT</code> could mean either the }
* left or right shift key) will map to the left key.
*
* @param keycode Key to press (e.g. <code>KeyEvent.VK_A</code>)
* @throws IllegalArgumentException if <code>keycode</code> is not
* a valid key
* @see #keyRelease(int)
* @see java.awt.event.KeyEvent
*/
@Override
public synchronized void keyPress(int keycode) {
peer.keyPress(keycode);
this.delay(getMinDelay());
}
@Override public synchronized void holdKey(int keycode, int timeMS)
public synchronized void keyRelease(int keycode) { {
peer.keyRelease(keycode); new Thread(() ->
this.delay(getMinDelay()); {
} peer.keyPress(keycode);
long startTime = System.currentTimeMillis();
while ((startTime + timeMS) > System.currentTimeMillis())
{
}
peer.keyRelease(keycode);
this.delay(getMinDelay());
}).start();
}
public synchronized void holdKey(int keycode, int timeMS) { public synchronized void holdKeyIndefinitely(int keycode)
new Thread(() -> { {
peer.keyPress(keycode); holdKeyThread = new Thread(() ->
long startTime = System.currentTimeMillis(); {
while ((startTime + timeMS) > System.currentTimeMillis()) { } pausedIndefinitely = true;
peer.keyRelease(keycode); peer.keyPress(keycode);
this.delay(getMinDelay()); while (pausedIndefinitely)
}).start(); {
} try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
peer.keyRelease(keycode);
this.delay(getMinDelay());
});
holdKeyThread.start();
public synchronized void holdKeyIndefinitely(int keycode) { }
holdKeyThread = new Thread(() -> {
pausedIndefinitely = true;
peer.keyPress(keycode);
while (pausedIndefinitely) {
try {
holdKeyThread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
peer.keyRelease(keycode);
this.delay(getMinDelay());
});
holdKeyThread.start();
} @Override
public Color getPixelColor(int x, int y)
{
Color color = new Color(peer.getRGBPixel(x, y));
return color;
}
@Override @Override
public Color getPixelColor(int x, int y) { public void delay(int ms)
Color color = new Color(peer.getRGBPixel(x, y)); {
return color; pauseMS(ms);
} }
@Override public int determineHorizontalOffset()
public void delay(int ms) { {
pauseMS(ms); return clientUI.getCanvasOffset().getX();
} }
public int determineHorizontalOffset() { public int determineVerticalOffset()
return clientUI.getCanvasOffset().getX(); {
} return clientUI.getCanvasOffset().getY();
}
public int determineVerticalOffset() {
return clientUI.getCanvasOffset().getY();
}
} }

View File

@@ -28,163 +28,198 @@
package net.runelite.client.flexo; package net.runelite.client.flexo;
import net.runelite.client.ui.ClientUI; import java.awt.Point;
import java.awt.Rectangle;
import java.awt.*;
import java.util.Random; import java.util.Random;
import java.util.logging.Logger; import java.util.logging.Logger;
import net.runelite.api.Constants;
import net.runelite.client.ui.ClientUI;
public class FlexoMouse { public class FlexoMouse
{
/* /*
Should pass unstretched coords, handles all conversions here. Should pass unstretched coords, handles all conversions here.
*/ */
public static Point getClickPoint(Rectangle rect) public static Point getClickPoint(Rectangle rect)
{ {
if (rect!=null) { if (rect != null)
Random r = new Random(); {
int x = -1; Random r = new Random();
int y = -1; int x = -1;
x = rect.x+r.nextInt(rect.width); int y = -1;
y = rect.y+r.nextInt(rect.height); x = rect.x + r.nextInt(rect.width);
y = rect.y + r.nextInt(rect.height);
if (Flexo.isStretched) { if (Flexo.isStretched)
double wScale; {
double hScale; double wScale;
double hScale;
if (Flexo.client.isResized()) { if (Flexo.client.isResized())
wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width); {
hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height); wScale = (Flexo.client.getStretchedDimensions().width / (double) Flexo.client.getRealDimensions().width);
int newX = (int)(x*wScale); hScale = (Flexo.client.getStretchedDimensions().height / (double) Flexo.client.getRealDimensions().height);
int newY = (int)(y*hScale); int newX = (int) (x * wScale);
if (newX>0 && newX< ClientUI.frame.getWidth()) { int newY = (int) (y * hScale);
if (newY>0 && newY< ClientUI.frame.getHeight()) { if (newX > 0 && newX < ClientUI.frame.getWidth())
return new Point(newX, newY); {
} if (newY > 0 && newY < ClientUI.frame.getHeight())
} {
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen."); return new Point(newX, newY);
return null; }
} else { }
if (x>0 && x< ClientUI.frame.getWidth()) { Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
if (y>0 && y< ClientUI.frame.getHeight()) { return null;
return new Point(x, y); }
} else
} {
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen."); if (x > 0 && x < ClientUI.frame.getWidth())
return null; {
} if (y > 0 && y < ClientUI.frame.getHeight())
{
return new Point(x, y);
}
}
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
return null;
}
} else if (!Flexo.client.isResized()) { }
int fixedWidth = 765; else if (!Flexo.client.isResized())
int widthDif = ClientUI.frame.getWidth(); {
final int fixedWidth = Constants.GAME_FIXED_WIDTH;
int widthDif = ClientUI.frame.getWidth();
if (ClientUI.pluginToolbar.isVisible()) { if (ClientUI.pluginToolbar.isVisible())
widthDif -= ClientUI.pluginToolbar.getWidth(); {
} widthDif -= ClientUI.pluginToolbar.getWidth();
if (ClientUI.pluginPanel!=null) }
widthDif -= ClientUI.pluginPanel.getWidth(); if (ClientUI.pluginPanel != null)
{
widthDif -= ClientUI.pluginPanel.getWidth();
}
widthDif -= fixedWidth; widthDif -= fixedWidth;
if (x+(widthDif/2)>0 && x+(widthDif/2)< ClientUI.frame.getWidth()) { if (x + (widthDif / 2) > 0 && x + (widthDif / 2) < ClientUI.frame.getWidth())
if (y>0 && y< ClientUI.frame.getHeight()) { {
return new Point(x, y); if (y > 0 && y < ClientUI.frame.getHeight())
} {
} return new Point(x, y);
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen."); }
return null; }
} Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
else { return null;
if (x>0 && x< ClientUI.frame.getWidth()) { }
if (y>0 && y< ClientUI.frame.getHeight()) { else
return new Point(x, y); {
} if (x > 0 && x < ClientUI.frame.getWidth())
} {
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen."); if (y > 0 && y < ClientUI.frame.getHeight())
return null; {
} return new Point(x, y);
} }
return null; }
} Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
return null;
}
}
return null;
}
public static Rectangle getClickArea(Rectangle rect) public static Rectangle getClickArea(Rectangle rect)
{ {
if (Flexo.isStretched) if (Flexo.isStretched)
{ {
double wScale; double wScale;
double hScale; double hScale;
if (Flexo.client.isResized()) { if (Flexo.client.isResized())
wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width); {
hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height); wScale = (Flexo.client.getStretchedDimensions().width / (double) Flexo.client.getRealDimensions().width);
} else { hScale = (Flexo.client.getStretchedDimensions().height / (double) Flexo.client.getRealDimensions().height);
wScale = ((double) Flexo.client.getStretchedDimensions().width) / Flexo.fixedWidth; }
hScale = ((double) Flexo.client.getStretchedDimensions().height) / Flexo.fixedHeight; else
} {
wScale = (Flexo.client.getStretchedDimensions().width) / (double) Flexo.fixedWidth;
hScale = (Flexo.client.getStretchedDimensions().height) / (double) Flexo.fixedHeight;
}
int xPadding = (int)rect.getWidth()/5; int xPadding = (int) rect.getWidth() / 5;
int yPadding = (int)rect.getHeight()/5; int yPadding = (int) rect.getHeight() / 5;
Random r = new Random(); Random r = new Random();
Rectangle clickRect = new Rectangle(); Rectangle clickRect = new Rectangle();
clickRect.width = rect.width-xPadding*2; clickRect.width = rect.width - xPadding * 2;
clickRect.height = rect.height-yPadding*2; clickRect.height = rect.height - yPadding * 2;
clickRect.x = rect.x+xPadding; clickRect.x = rect.x + xPadding;
clickRect.y = rect.y+yPadding; clickRect.y = rect.y + yPadding;
if (clickRect.width>0&&clickRect.height>0) { if (clickRect.width > 0 && clickRect.height > 0)
int x = clickRect.x+r.nextInt(clickRect.width); {
int y = clickRect.y+r.nextInt(clickRect.height); int x = clickRect.x + r.nextInt(clickRect.width);
double tScale = 1 + (Flexo.scale / 100); int y = clickRect.y + r.nextInt(clickRect.height);
double tScale = 1 + (Flexo.scale / 100);
if (Flexo.client.isResized()) { if (Flexo.client.isResized())
return new Rectangle((int)(clickRect.x * wScale), (int)(clickRect.y * wScale), (int)(clickRect.width * wScale), (int)(clickRect.getHeight()*hScale)); {
} else { return new Rectangle((int) (clickRect.x * wScale), (int) (clickRect.y * wScale), (int) (clickRect.width * wScale), (int) (clickRect.getHeight() * hScale));
return new Rectangle((int)(clickRect.x), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight())); }
} else
} {
return new Rectangle(clickRect.x, clickRect.y, clickRect.width, (int) (clickRect.getHeight()));
}
}
} }
//Fixed, not stretched //Fixed, not stretched
else if (!Flexo.client.isResized()) { else if (!Flexo.client.isResized())
int fixedWidth = 765; {
int widthDif = ClientUI.frame.getWidth(); int fixedWidth = 765;
int widthDif = ClientUI.frame.getWidth();
if (ClientUI.pluginToolbar.isVisible()) { if (ClientUI.pluginToolbar.isVisible())
widthDif -= ClientUI.pluginToolbar.getWidth(); {
} widthDif -= ClientUI.pluginToolbar.getWidth();
if (ClientUI.pluginPanel!=null) }
widthDif -= ClientUI.pluginPanel.getWidth(); if (ClientUI.pluginPanel != null)
{
widthDif -= ClientUI.pluginPanel.getWidth();
}
widthDif -= fixedWidth; widthDif -= fixedWidth;
int xPadding = (int)rect.getWidth()/5; int xPadding = (int) rect.getWidth() / 5;
int yPadding = (int)rect.getHeight()/5; int yPadding = (int) rect.getHeight() / 5;
Random r = new Random(); Random r = new Random();
Rectangle clickRect = new Rectangle(); Rectangle clickRect = new Rectangle();
clickRect.width = rect.width-xPadding; clickRect.width = rect.width - xPadding;
clickRect.height = rect.height-yPadding; clickRect.height = rect.height - yPadding;
clickRect.x = rect.x+xPadding; clickRect.x = rect.x + xPadding;
clickRect.y = rect.y+yPadding; clickRect.y = rect.y + yPadding;
if (clickRect.height>0&&clickRect.width>0) { if (clickRect.height > 0 && clickRect.width > 0)
int x = clickRect.x + r.nextInt(clickRect.width); {
int y = clickRect.y + r.nextInt(clickRect.height); int x = clickRect.x + r.nextInt(clickRect.width);
return new Rectangle((int) (clickRect.x), (int) (clickRect.y), (int) (clickRect.width), (int) (clickRect.getHeight())); int y = clickRect.y + r.nextInt(clickRect.height);
} return new Rectangle(clickRect.x, clickRect.y, clickRect.width, (int) (clickRect.getHeight()));
} }
//Resizable, not stretched }
else { //Resizable, not stretched
int xPadding = (int)rect.getWidth()/5; else
int yPadding = (int)rect.getHeight()/5; {
Random r = new Random(); int xPadding = (int) rect.getWidth() / 5;
Rectangle clickRect = new Rectangle(); int yPadding = (int) rect.getHeight() / 5;
clickRect.width = rect.width-xPadding*2; Random r = new Random();
clickRect.height = rect.height-yPadding*2; Rectangle clickRect = new Rectangle();
clickRect.x = rect.x+xPadding; clickRect.width = rect.width - xPadding * 2;
clickRect.y = rect.y+yPadding; clickRect.height = rect.height - yPadding * 2;
if (clickRect.height>0&&clickRect.width>0) { clickRect.x = rect.x + xPadding;
int x = clickRect.x+r.nextInt(clickRect.width); clickRect.y = rect.y + yPadding;
int y = clickRect.y+r.nextInt(clickRect.height); if (clickRect.height > 0 && clickRect.width > 0)
return new Rectangle((int)(clickRect.x), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight())); {
} int x = clickRect.x + r.nextInt(clickRect.width);
} int y = clickRect.y + r.nextInt(clickRect.height);
return new Rectangle(clickRect.x, clickRect.y, clickRect.width, (int) (clickRect.getHeight()));
}
}
return null; return null;
} }
} }

View File

@@ -26,54 +26,258 @@
package net.runelite.client.game; package net.runelite.client.game;
import lombok.Getter; import lombok.Getter;
import static net.runelite.api.NullObjectID.*; import static net.runelite.api.NullObjectID.NULL_25337;
import static net.runelite.api.ObjectID.*; import static net.runelite.api.NullObjectID.NULL_26371;
import static net.runelite.api.NullObjectID.NULL_26375;
import static net.runelite.api.NullObjectID.NULL_26884;
import static net.runelite.api.NullObjectID.NULL_26886;
import static net.runelite.api.NullObjectID.NULL_29868;
import static net.runelite.api.NullObjectID.NULL_29869;
import static net.runelite.api.NullObjectID.NULL_29870;
import static net.runelite.api.NullObjectID.NULL_31823;
import static net.runelite.api.NullObjectID.NULL_31849;
import static net.runelite.api.NullObjectID.NULL_33327;
import static net.runelite.api.NullObjectID.NULL_33328;
import static net.runelite.api.ObjectID.A_WOODEN_LOG;
import static net.runelite.api.ObjectID.BALANCING_LEDGE_23548;
import static net.runelite.api.ObjectID.BIG_WINDOW;
import static net.runelite.api.ObjectID.BOULDER_27990;
import static net.runelite.api.ObjectID.BROKEN_FENCE;
import static net.runelite.api.ObjectID.BROKEN_FENCE_2618;
import static net.runelite.api.ObjectID.BROKEN_RAFT;
import static net.runelite.api.ObjectID.BROKEN_WALL_33344;
import static net.runelite.api.ObjectID.CASTLE_WALL;
import static net.runelite.api.ObjectID.CLIMBING_ROCKS;
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_11948;
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_11949;
import static net.runelite.api.ObjectID.CREVICE_16465;
import static net.runelite.api.ObjectID.CREVICE_16539;
import static net.runelite.api.ObjectID.CREVICE_16543;
import static net.runelite.api.ObjectID.CREVICE_19043;
import static net.runelite.api.ObjectID.CREVICE_30198;
import static net.runelite.api.ObjectID.CREVICE_9739;
import static net.runelite.api.ObjectID.CREVICE_9740;
import static net.runelite.api.ObjectID.CROSSBOW_TREE_17062;
import static net.runelite.api.ObjectID.CRUMBLING_WALL_24222;
import static net.runelite.api.ObjectID.DARK_TUNNEL_10047;
import static net.runelite.api.ObjectID.DENSE_FOREST;
import static net.runelite.api.ObjectID.DENSE_FOREST_3938;
import static net.runelite.api.ObjectID.DENSE_FOREST_3939;
import static net.runelite.api.ObjectID.DENSE_FOREST_3998;
import static net.runelite.api.ObjectID.DENSE_FOREST_3999;
import static net.runelite.api.ObjectID.FALLEN_TREE_33192;
import static net.runelite.api.ObjectID.FENCE_16518;
import static net.runelite.api.ObjectID.GAP;
import static net.runelite.api.ObjectID.GAP_2831;
import static net.runelite.api.ObjectID.GAP_29326;
import static net.runelite.api.ObjectID.HOLE_16520;
import static net.runelite.api.ObjectID.HOLE_30966;
import static net.runelite.api.ObjectID.HOLE_31481;
import static net.runelite.api.ObjectID.HOLE_31482;
import static net.runelite.api.ObjectID.ICE_CHUNKS_31822;
import static net.runelite.api.ObjectID.ICE_CHUNKS_31990;
import static net.runelite.api.ObjectID.JUTTING_WALL_17002;
import static net.runelite.api.ObjectID.LADDER_30938;
import static net.runelite.api.ObjectID.LADDER_30939;
import static net.runelite.api.ObjectID.LADDER_30940;
import static net.runelite.api.ObjectID.LADDER_30941;
import static net.runelite.api.ObjectID.LEAVES;
import static net.runelite.api.ObjectID.LEAVES_3924;
import static net.runelite.api.ObjectID.LEAVES_3925;
import static net.runelite.api.ObjectID.LEDGE_33190;
import static net.runelite.api.ObjectID.LITTLE_BOULDER;
import static net.runelite.api.ObjectID.LOG_BALANCE_16540;
import static net.runelite.api.ObjectID.LOG_BALANCE_16541;
import static net.runelite.api.ObjectID.LOG_BALANCE_16542;
import static net.runelite.api.ObjectID.LOG_BALANCE_16546;
import static net.runelite.api.ObjectID.LOG_BALANCE_16547;
import static net.runelite.api.ObjectID.LOG_BALANCE_16548;
import static net.runelite.api.ObjectID.LOG_BALANCE_20882;
import static net.runelite.api.ObjectID.LOG_BALANCE_20884;
import static net.runelite.api.ObjectID.LOG_BALANCE_23274;
import static net.runelite.api.ObjectID.LOG_BALANCE_3929;
import static net.runelite.api.ObjectID.LOG_BALANCE_3930;
import static net.runelite.api.ObjectID.LOG_BALANCE_3931;
import static net.runelite.api.ObjectID.LOG_BALANCE_3932;
import static net.runelite.api.ObjectID.LOG_BALANCE_3933;
import static net.runelite.api.ObjectID.LOOSE_RAILING;
import static net.runelite.api.ObjectID.LOOSE_RAILING_2186;
import static net.runelite.api.ObjectID.LOOSE_RAILING_28849;
import static net.runelite.api.ObjectID.LOW_FENCE;
import static net.runelite.api.ObjectID.MONKEYBARS_23566;
import static net.runelite.api.ObjectID.MONKEYBARS_23567;
import static net.runelite.api.ObjectID.MYSTERIOUS_PIPE;
import static net.runelite.api.ObjectID.OBSTACLE;
import static net.runelite.api.ObjectID.OBSTACLE_30767;
import static net.runelite.api.ObjectID.OBSTACLE_30962;
import static net.runelite.api.ObjectID.OBSTACLE_30964;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_16509;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_16511;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23140;
import static net.runelite.api.ObjectID.ORNATE_RAILING;
import static net.runelite.api.ObjectID.ORNATE_RAILING_17000;
import static net.runelite.api.ObjectID.PILE_OF_RUBBLE_23563;
import static net.runelite.api.ObjectID.PILE_OF_RUBBLE_23564;
import static net.runelite.api.ObjectID.PILLAR_31561;
import static net.runelite.api.ObjectID.PILLAR_31809;
import static net.runelite.api.ObjectID.PIPE_21727;
import static net.runelite.api.ObjectID.PIPE_21728;
import static net.runelite.api.ObjectID.ROCKS;
import static net.runelite.api.ObjectID.ROCKSLIDE_33184;
import static net.runelite.api.ObjectID.ROCKSLIDE_33185;
import static net.runelite.api.ObjectID.ROCKSLIDE_33191;
import static net.runelite.api.ObjectID.ROCKS_14106;
import static net.runelite.api.ObjectID.ROCKS_16464;
import static net.runelite.api.ObjectID.ROCKS_16514;
import static net.runelite.api.ObjectID.ROCKS_16515;
import static net.runelite.api.ObjectID.ROCKS_16521;
import static net.runelite.api.ObjectID.ROCKS_16522;
import static net.runelite.api.ObjectID.ROCKS_16523;
import static net.runelite.api.ObjectID.ROCKS_16524;
import static net.runelite.api.ObjectID.ROCKS_16534;
import static net.runelite.api.ObjectID.ROCKS_16535;
import static net.runelite.api.ObjectID.ROCKS_16545;
import static net.runelite.api.ObjectID.ROCKS_16549;
import static net.runelite.api.ObjectID.ROCKS_16550;
import static net.runelite.api.ObjectID.ROCKS_16998;
import static net.runelite.api.ObjectID.ROCKS_16999;
import static net.runelite.api.ObjectID.ROCKS_17042;
import static net.runelite.api.ObjectID.ROCKS_19849;
import static net.runelite.api.ObjectID.ROCKS_2231;
import static net.runelite.api.ObjectID.ROCKS_27984;
import static net.runelite.api.ObjectID.ROCKS_27985;
import static net.runelite.api.ObjectID.ROCKS_27987;
import static net.runelite.api.ObjectID.ROCKS_27988;
import static net.runelite.api.ObjectID.ROCKS_31757;
import static net.runelite.api.ObjectID.ROCKS_31758;
import static net.runelite.api.ObjectID.ROCKS_31759;
import static net.runelite.api.ObjectID.ROCKS_34396;
import static net.runelite.api.ObjectID.ROCKS_34397;
import static net.runelite.api.ObjectID.ROCKS_34741;
import static net.runelite.api.ObjectID.ROCKS_3748;
import static net.runelite.api.ObjectID.ROCKS_3790;
import static net.runelite.api.ObjectID.ROCKS_3791;
import static net.runelite.api.ObjectID.ROCKS_3803;
import static net.runelite.api.ObjectID.ROCKS_3804;
import static net.runelite.api.ObjectID.ROCKS_6673;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26400;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26401;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26402;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26404;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26405;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26406;
import static net.runelite.api.ObjectID.ROCK_16115;
import static net.runelite.api.ObjectID.ROPESWING_23568;
import static net.runelite.api.ObjectID.ROPESWING_23569;
import static net.runelite.api.ObjectID.ROPE_ANCHOR;
import static net.runelite.api.ObjectID.ROPE_ANCHOR_30917;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21306;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21307;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21308;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21309;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21310;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21311;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21312;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21313;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21314;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21315;
import static net.runelite.api.ObjectID.RUBBER_CAP_MUSHROOM;
import static net.runelite.api.ObjectID.SPIKEY_CHAIN;
import static net.runelite.api.ObjectID.SPIKEY_CHAIN_16538;
import static net.runelite.api.ObjectID.STAIRS_31485;
import static net.runelite.api.ObjectID.STEPPING_STONES;
import static net.runelite.api.ObjectID.STEPPING_STONES_23646;
import static net.runelite.api.ObjectID.STEPPING_STONES_23647;
import static net.runelite.api.ObjectID.STEPPING_STONE_10663;
import static net.runelite.api.ObjectID.STEPPING_STONE_11768;
import static net.runelite.api.ObjectID.STEPPING_STONE_13504;
import static net.runelite.api.ObjectID.STEPPING_STONE_14917;
import static net.runelite.api.ObjectID.STEPPING_STONE_14918;
import static net.runelite.api.ObjectID.STEPPING_STONE_16466;
import static net.runelite.api.ObjectID.STEPPING_STONE_16513;
import static net.runelite.api.ObjectID.STEPPING_STONE_16533;
import static net.runelite.api.ObjectID.STEPPING_STONE_19040;
import static net.runelite.api.ObjectID.STEPPING_STONE_19042;
import static net.runelite.api.ObjectID.STEPPING_STONE_21738;
import static net.runelite.api.ObjectID.STEPPING_STONE_21739;
import static net.runelite.api.ObjectID.STEPPING_STONE_29728;
import static net.runelite.api.ObjectID.STEPPING_STONE_29729;
import static net.runelite.api.ObjectID.STEPPING_STONE_29730;
import static net.runelite.api.ObjectID.STEPPING_STONE_5948;
import static net.runelite.api.ObjectID.STEPPING_STONE_5949;
import static net.runelite.api.ObjectID.STEPS;
import static net.runelite.api.ObjectID.STEPS_29993;
import static net.runelite.api.ObjectID.STICKS;
import static net.runelite.api.ObjectID.STILE;
import static net.runelite.api.ObjectID.STILE_12982;
import static net.runelite.api.ObjectID.STRANGE_FLOOR;
import static net.runelite.api.ObjectID.STRANGE_FLOOR_16544;
import static net.runelite.api.ObjectID.STRONG_TREE_17074;
import static net.runelite.api.ObjectID.TIGHTGAP;
import static net.runelite.api.ObjectID.TRELLIS_20056;
import static net.runelite.api.ObjectID.TRIPWIRE;
import static net.runelite.api.ObjectID.TUNNEL_30174;
import static net.runelite.api.ObjectID.TUNNEL_30175;
import static net.runelite.api.ObjectID.TUNNEL_30959;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16528;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16529;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16530;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_19032;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_19036;
import static net.runelite.api.ObjectID.VINE_26880;
import static net.runelite.api.ObjectID.VINE_26882;
import static net.runelite.api.ObjectID.WALL_17047;
import static net.runelite.api.ObjectID.WALL_17049;
import static net.runelite.api.ObjectID.WALL_17050;
import static net.runelite.api.ObjectID.WEATHERED_WALL;
import static net.runelite.api.ObjectID.WEATHERED_WALL_16526;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@Getter @Getter
public enum AgilityShortcut public enum AgilityShortcut
{ {
GENERIC_SHORTCUT(1, "Shortcut", null, GENERIC_SHORTCUT(1, "Shortcut", null,
// Trollheim // Trollheim
ROCKS_3790, ROCKS_3791, ROCKS_3790, ROCKS_3791,
// Fremennik Slayer Cave // Fremennik Slayer Cave
STEPS_29993, STEPS_29993,
// Fossil Island // Fossil Island
LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM, LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM,
// Brimhaven dungeon // Brimhaven dungeon
CREVICE_30198, CREVICE_30198,
// Lumbridge // Lumbridge
STILE_12982, STILE_12982,
// Gu'Tanoth Bridge // Gu'Tanoth Bridge
GAP, GAP_2831, GAP, GAP_2831,
// Lumbridge Swamp Caves // Lumbridge Swamp Caves
STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673, STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673,
// Morytania Pirate Ship // Morytania Pirate Ship
ROCK_16115, ROCK_16115,
// Lumber Yard // Lumber Yard
BROKEN_FENCE_2618, BROKEN_FENCE_2618,
// McGrubor's Wood // McGrubor's Wood
LOOSE_RAILING, LOOSE_RAILING,
// Underwater Area Fossil Island // Underwater Area Fossil Island
TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962, TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962,
// Tree Gnome Village // Tree Gnome Village
LOOSE_RAILING_2186, LOOSE_RAILING_2186,
// Burgh de Rott // Burgh de Rott
LOW_FENCE, LOW_FENCE,
// Taverley // Taverley
STILE, STILE,
// Asgarnian Ice Dungeon // Asgarnian Ice Dungeon
STEPS, STEPS,
// Fossil Island Wyvern Cave // Fossil Island Wyvern Cave
STAIRS_31485), STAIRS_31485),
BRIMHAVEN_DUNGEON_MEDIUM_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2698, 9491, 0), PIPE_21727), BRIMHAVEN_DUNGEON_MEDIUM_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2698, 9491, 0), PIPE_21727),
BRIMHAVEN_DUNGEON_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2655, 9573, 0), PIPE_21728), BRIMHAVEN_DUNGEON_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2655, 9573, 0), PIPE_21728),
BRIMHAVEN_DUNGEON_STEPPING_STONES_RETURN(1, "Pipe Squeeze", null, STEPPING_STONE_21739), BRIMHAVEN_DUNGEON_STEPPING_STONES_RETURN(1, "Pipe Squeeze", null, STEPPING_STONE_21739),
BRIMHAVEN_DUNGEON_LOG_BALANCE_RETURN(1, "Log Balance", null, LOG_BALANCE_20884), BRIMHAVEN_DUNGEON_LOG_BALANCE_RETURN(1, "Log Balance", null, LOG_BALANCE_20884),
AGILITY_PYRAMID_ROCKS_WEST(1, "Rocks", null, CLIMBING_ROCKS_11948), AGILITY_PYRAMID_ROCKS_WEST(1, "Rocks", null, CLIMBING_ROCKS_11948),
CAIRN_ISLE_CLIMBING_ROCKS(1, "Rocks", null, CLIMBING_ROCKS), CAIRN_ISLE_CLIMBING_ROCKS(1, "Rocks", null, CLIMBING_ROCKS),
KARAMJA_GLIDER_LOG(1, "Log Balance", new WorldPoint(2906, 3050, 0), A_WOODEN_LOG ), KARAMJA_GLIDER_LOG(1, "Log Balance", new WorldPoint(2906, 3050, 0), A_WOODEN_LOG),
FALADOR_CRUMBLING_WALL(5, "Crumbling Wall", new WorldPoint(2936, 3357, 0), CRUMBLING_WALL_24222 ), FALADOR_CRUMBLING_WALL(5, "Crumbling Wall", new WorldPoint(2936, 3357, 0), CRUMBLING_WALL_24222),
RIVER_LUM_GRAPPLE_WEST(8, "Grapple Broken Raft", new WorldPoint(3245, 3179, 0), BROKEN_RAFT), RIVER_LUM_GRAPPLE_WEST(8, "Grapple Broken Raft", new WorldPoint(3245, 3179, 0), BROKEN_RAFT),
RIVER_LUM_GRAPPLE_EAST(8, "Grapple Broken Raft", new WorldPoint(3258, 3179, 0), BROKEN_RAFT), RIVER_LUM_GRAPPLE_EAST(8, "Grapple Broken Raft", new WorldPoint(3258, 3179, 0), BROKEN_RAFT),
CORSAIR_COVE_ROCKS(10, "Rocks", new WorldPoint(2545, 2871, 0), ROCKS_31757), CORSAIR_COVE_ROCKS(10, "Rocks", new WorldPoint(2545, 2871, 0), ROCKS_31757),
@@ -84,7 +288,7 @@ public enum AgilityShortcut
GOBLIN_VILLAGE_WALL(14, "Wall", new WorldPoint(2925, 3523, 0), TIGHTGAP), GOBLIN_VILLAGE_WALL(14, "Wall", new WorldPoint(2925, 3523, 0), TIGHTGAP),
CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809), CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809),
EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566), EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566),
TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15 TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15
YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, CASTLE_WALL), YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, CASTLE_WALL),
YANILLE_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056), YANILLE_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056),
COAL_TRUCKS_LOG_BALANCE(20, "Log Balance", new WorldPoint(2598, 3475, 0), LOG_BALANCE_23274), COAL_TRUCKS_LOG_BALANCE(20, "Log Balance", new WorldPoint(2598, 3475, 0), LOG_BALANCE_23274),
@@ -128,7 +332,7 @@ public enum AgilityShortcut
DEEP_WILDERNESS_DUNGEON_CREVICE_SOUTH(46, "Narrow Crevice", new WorldPoint(3045, 10327, 0), CREVICE_19043), DEEP_WILDERNESS_DUNGEON_CREVICE_SOUTH(46, "Narrow Crevice", new WorldPoint(3045, 10327, 0), CREVICE_19043),
TROLLHEIM_HARD_CLIFF_SCRAMBLE(47, "Rocks", new WorldPoint(2902, 3680, 0), ROCKS_16524), TROLLHEIM_HARD_CLIFF_SCRAMBLE(47, "Rocks", new WorldPoint(2902, 3680, 0), ROCKS_16524),
FREMENNIK_LOG_BALANCE(48, "Log Balance", new WorldPoint(2721, 3591, 0), LOG_BALANCE_16540, LOG_BALANCE_16541, LOG_BALANCE_16542), FREMENNIK_LOG_BALANCE(48, "Log Balance", new WorldPoint(2721, 3591, 0), LOG_BALANCE_16540, LOG_BALANCE_16541, LOG_BALANCE_16542),
YANILLE_DUNGEON_PIPE_SQUEEZE(49, "Pipe Squeeze", null, OBSTACLE_PIPE_23140), YANILLE_DUNGEON_PIPE_SQUEEZE(49, "Pipe Squeeze", null, OBSTACLE_PIPE_23140),
ARCEUUS_ESSENCE_MINE_BOULDER(49, "Boulder", new WorldPoint(1774, 3888, 0), BOULDER_27990), ARCEUUS_ESSENCE_MINE_BOULDER(49, "Boulder", new WorldPoint(1774, 3888, 0), BOULDER_27990),
MORYTANIA_STEPPING_STONE(50, "Stepping Stone", new WorldPoint(3418, 3326, 0), STEPPING_STONE_13504), MORYTANIA_STEPPING_STONE(50, "Stepping Stone", new WorldPoint(3418, 3326, 0), STEPPING_STONE_13504),
VARROCK_SEWERS_PIPE_SQUEEZE(51, "Pipe Squeeze", new WorldPoint(3152, 9905, 0), OBSTACLE_PIPE_16511), VARROCK_SEWERS_PIPE_SQUEEZE(51, "Pipe Squeeze", new WorldPoint(3152, 9905, 0), OBSTACLE_PIPE_16511),
@@ -141,7 +345,7 @@ public enum AgilityShortcut
ISAFDAR_FOREST_OBSTACLES(56, "Trap", null, DENSE_FOREST_3938, DENSE_FOREST_3939, DENSE_FOREST_3998, DENSE_FOREST_3999, DENSE_FOREST, LEAVES, LEAVES_3924, LEAVES_3925, STICKS, TRIPWIRE), ISAFDAR_FOREST_OBSTACLES(56, "Trap", null, DENSE_FOREST_3938, DENSE_FOREST_3939, DENSE_FOREST_3998, DENSE_FOREST_3999, DENSE_FOREST, LEAVES, LEAVES_3924, LEAVES_3925, STICKS, TRIPWIRE),
RELEKKA_EAST_FENCE(57, "Fence", new WorldPoint(2688, 3697, 0), BROKEN_FENCE), RELEKKA_EAST_FENCE(57, "Fence", new WorldPoint(2688, 3697, 0), BROKEN_FENCE),
YANILLE_DUNGEON_MONKEY_BARS(57, "Monkey Bars", null, MONKEYBARS_23567), YANILLE_DUNGEON_MONKEY_BARS(57, "Monkey Bars", null, MONKEYBARS_23567),
PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null , WEATHERED_WALL, WEATHERED_WALL_16526), PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null, WEATHERED_WALL, WEATHERED_WALL_16526),
ELVEN_OVERPASS_CLIFF_SCRAMBLE(59, "Rocks", new WorldPoint(2345, 3300, 0), ROCKS_16514, ROCKS_16515), ELVEN_OVERPASS_CLIFF_SCRAMBLE(59, "Rocks", new WorldPoint(2345, 3300, 0), ROCKS_16514, ROCKS_16515),
WILDERNESS_GWD_CLIMB_EAST(60, "Rocks", new WorldPoint(2943, 3770, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406), WILDERNESS_GWD_CLIMB_EAST(60, "Rocks", new WorldPoint(2943, 3770, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406),
WILDERNESS_GWD_CLIMB_WEST(60, "Rocks", new WorldPoint(2928, 3760, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406), WILDERNESS_GWD_CLIMB_WEST(60, "Rocks", new WorldPoint(2928, 3760, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406),
@@ -169,22 +373,22 @@ public enum AgilityShortcut
TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON(70, "Pipe Squeeze", new WorldPoint(2886, 9798, 0), OBSTACLE_PIPE_16509), TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON(70, "Pipe Squeeze", new WorldPoint(2886, 9798, 0), OBSTACLE_PIPE_16509),
TAVERLEY_DUNGEON_ROCKS_NORTH(70, "Rocks", new WorldPoint(2887, 9823, 0), ROCKS, ROCKS_14106), TAVERLEY_DUNGEON_ROCKS_NORTH(70, "Rocks", new WorldPoint(2887, 9823, 0), ROCKS, ROCKS_14106),
TAVERLEY_DUNGEON_ROCKS_SOUTH(70, "Rocks", new WorldPoint(2887, 9631, 0), ROCKS, ROCKS_14106), TAVERLEY_DUNGEON_ROCKS_SOUTH(70, "Rocks", new WorldPoint(2887, 9631, 0), ROCKS, ROCKS_14106),
FOSSIL_ISLAND_HARDWOOD_NORTH(70, "Hole" , new WorldPoint(3713, 3827, 0), HOLE_31481, HOLE_31482), FOSSIL_ISLAND_HARDWOOD_NORTH(70, "Hole", new WorldPoint(3713, 3827, 0), HOLE_31481, HOLE_31482),
FOSSIL_ISLAND_HARDWOOD_SOUTH(70, "Hole" , new WorldPoint(3715, 3817, 0), HOLE_31481, HOLE_31482), FOSSIL_ISLAND_HARDWOOD_SOUTH(70, "Hole", new WorldPoint(3715, 3817, 0), HOLE_31481, HOLE_31482),
AL_KHARID_WINDOW(70, "Window", new WorldPoint(3293, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW), AL_KHARID_WINDOW(70, "Window", new WorldPoint(3293, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW),
GWD_SARADOMIN_ROPE_NORTH(70, "Rope Descent", new WorldPoint(2912, 5300, 0), NULL_26371), GWD_SARADOMIN_ROPE_NORTH(70, "Rope Descent", new WorldPoint(2912, 5300, 0), NULL_26371),
GWD_SARADOMIN_ROPE_SOUTH(70, "Rope Descent", new WorldPoint(2951, 5267, 0), NULL_26375), GWD_SARADOMIN_ROPE_SOUTH(70, "Rope Descent", new WorldPoint(2951, 5267, 0), NULL_26375),
SLAYER_TOWER_ADVANCED_CHAIN_FIRST(71, "Spiked Chain (Floor 2)", new WorldPoint(3447, 3578, 0), SPIKEY_CHAIN ), SLAYER_TOWER_ADVANCED_CHAIN_FIRST(71, "Spiked Chain (Floor 2)", new WorldPoint(3447, 3578, 0), SPIKEY_CHAIN),
SLAYER_TOWER_ADVANCED_CHAIN_SECOND(71, "Spiked Chain (Floor 3)", new WorldPoint(3446, 3576, 0), SPIKEY_CHAIN_16538), SLAYER_TOWER_ADVANCED_CHAIN_SECOND(71, "Spiked Chain (Floor 3)", new WorldPoint(3446, 3576, 0), SPIKEY_CHAIN_16538),
STRONGHOLD_SLAYER_CAVE_TUNNEL(72, "Tunnel", new WorldPoint(2431, 9806, 0), TUNNEL_30174, TUNNEL_30175), STRONGHOLD_SLAYER_CAVE_TUNNEL(72, "Tunnel", new WorldPoint(2431, 9806, 0), TUNNEL_30174, TUNNEL_30175),
TROLL_STRONGHOLD_WALL_CLIMB(73, "Rocks", new WorldPoint(2841, 3694, 0), ROCKS_16464), TROLL_STRONGHOLD_WALL_CLIMB(73, "Rocks", new WorldPoint(2841, 3694, 0), ROCKS_16464),
ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985 ), ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985),
LAVA_DRAGON_ISLE_JUMP(74, "Stepping Stone", new WorldPoint(3200, 3807, 0), STEPPING_STONE_14918), LAVA_DRAGON_ISLE_JUMP(74, "Stepping Stone", new WorldPoint(3200, 3807, 0), STEPPING_STONE_14918),
REVENANT_CAVES_DEMONS_JUMP(75, "Jump", new WorldPoint(3199, 10135, 0), PILLAR_31561), REVENANT_CAVES_DEMONS_JUMP(75, "Jump", new WorldPoint(3199, 10135, 0), PILLAR_31561),
REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561), REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561),
REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561), REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561),
ZUL_ANDRA_ISLAND_CROSSING(76, "Stepping Stone", new WorldPoint(2156, 3073, 0), STEPPING_STONE_10663), ZUL_ANDRA_ISLAND_CROSSING(76, "Stepping Stone", new WorldPoint(2156, 3073, 0), STEPPING_STONE_10663),
SHILO_VILLAGE_STEPPING_STONES( 77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466), SHILO_VILLAGE_STEPPING_STONES(77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466),
KHARAZI_JUNGLE_VINE_CLIMB(79, "Vine", new WorldPoint(2897, 2939, 0), NULL_26884, NULL_26886), KHARAZI_JUNGLE_VINE_CLIMB(79, "Vine", new WorldPoint(2897, 2939, 0), NULL_26884, NULL_26886),
TAVERLEY_DUNGEON_SPIKED_BLADES(80, "Strange Floor", new WorldPoint(2877, 9813, 0), STRANGE_FLOOR), TAVERLEY_DUNGEON_SPIKED_BLADES(80, "Strange Floor", new WorldPoint(2877, 9813, 0), STRANGE_FLOOR),
SLAYER_DUNGEON_CHASM_JUMP(81, "Spiked Blades", new WorldPoint(2770, 10003, 0), STRANGE_FLOOR_16544), SLAYER_DUNGEON_CHASM_JUMP(81, "Spiked Blades", new WorldPoint(2770, 10003, 0), STRANGE_FLOOR_16544),

View File

@@ -1,84 +1,85 @@
/* /*
* Copyright (c) 2018 Abex * Copyright (c) 2018 Abex
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.game; package net.runelite.client.game;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
public class AsyncBufferedImage extends BufferedImage public class AsyncBufferedImage extends BufferedImage
{ {
private final List<Runnable> listeners = new CopyOnWriteArrayList<>(); private final List<Runnable> listeners = new CopyOnWriteArrayList<>();
public AsyncBufferedImage(int width, int height, int imageType)
{ public AsyncBufferedImage(int width, int height, int imageType)
super(width, height, imageType); {
} super(width, height, imageType);
}
/**
* Call when the buffer has been changed /**
*/ * Call when the buffer has been changed
public void changed() */
{ public void changed()
for (Runnable r : listeners) {
{ for (Runnable r : listeners)
r.run(); {
} r.run();
} }
}
/**
* Register a function to be ran when the buffer has changed /**
*/ * Register a function to be ran when the buffer has changed
public void onChanged(Runnable r) */
{ public void onChanged(Runnable r)
listeners.add(r); {
} listeners.add(r);
}
/**
* Calls setIcon on c, ensuring it is repainted when this changes /**
*/ * Calls setIcon on c, ensuring it is repainted when this changes
public void addTo(JButton c) */
{ public void addTo(JButton c)
c.setIcon(makeIcon(c)); {
} c.setIcon(makeIcon(c));
}
/**
* Calls setIcon on c, ensuring it is repainted when this changes /**
*/ * Calls setIcon on c, ensuring it is repainted when this changes
public void addTo(JLabel c) */
{ public void addTo(JLabel c)
c.setIcon(makeIcon(c)); {
} c.setIcon(makeIcon(c));
}
private ImageIcon makeIcon(JComponent c)
{ private ImageIcon makeIcon(JComponent c)
listeners.add(c::repaint); {
return new ImageIcon(this); listeners.add(c::repaint);
} return new ImageIcon(this);
} }
}

View File

@@ -1,271 +1,675 @@
/* /*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com> * Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com> * Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.game; package net.runelite.client.game;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import static net.runelite.api.ItemID.*; import static net.runelite.api.ItemID.ABYSSAL_TENTACLE;
import static net.runelite.api.ItemID.ABYSSAL_WHIP;
/** import static net.runelite.api.ItemID.AHRIMS_HOOD;
* Converts untradeable items to it's tradeable counterparts import static net.runelite.api.ItemID.AHRIMS_HOOD_100;
*/ import static net.runelite.api.ItemID.AHRIMS_HOOD_25;
public enum ItemMapping import static net.runelite.api.ItemID.AHRIMS_HOOD_50;
{ import static net.runelite.api.ItemID.AHRIMS_HOOD_75;
// Barrows equipment import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT;
ITEM_AHRIMS_HOOD(AHRIMS_HOOD, AHRIMS_HOOD_25, AHRIMS_HOOD_50, AHRIMS_HOOD_75, AHRIMS_HOOD_100), import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_100;
ITEM_AHRIMS_ROBETOP(AHRIMS_ROBETOP, AHRIMS_ROBETOP_25, AHRIMS_ROBETOP_50, AHRIMS_ROBETOP_75, AHRIMS_ROBETOP_100), import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_25;
ITEM_AHRIMS_ROBEBOTTOM(AHRIMS_ROBESKIRT, AHRIMS_ROBESKIRT_25, AHRIMS_ROBESKIRT_50, AHRIMS_ROBESKIRT_75, AHRIMS_ROBESKIRT_100), import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_50;
ITEM_AHRIMS_STAFF(AHRIMS_STAFF, AHRIMS_STAFF_25, AHRIMS_STAFF_50, AHRIMS_STAFF_75, AHRIMS_STAFF_100), import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_75;
ITEM_KARILS_COIF(KARILS_COIF, KARILS_COIF_25, KARILS_COIF_50, KARILS_COIF_75, KARILS_COIF_100), import static net.runelite.api.ItemID.AHRIMS_ROBETOP;
ITEM_KARILS_LEATHERTOP(KARILS_LEATHERTOP, KARILS_LEATHERTOP_25, KARILS_LEATHERTOP_50, KARILS_LEATHERTOP_75, KARILS_LEATHERTOP_100), import static net.runelite.api.ItemID.AHRIMS_ROBETOP_100;
ITEM_KARILS_LEATHERSKIRT(KARILS_LEATHERSKIRT, KARILS_LEATHERSKIRT_25, KARILS_LEATHERSKIRT_50, KARILS_LEATHERSKIRT_75, KARILS_LEATHERSKIRT_100), import static net.runelite.api.ItemID.AHRIMS_ROBETOP_25;
ITEM_KARILS_CROSSBOW(KARILS_CROSSBOW, KARILS_CROSSBOW_25, KARILS_CROSSBOW_50, KARILS_CROSSBOW_75, KARILS_CROSSBOW_100), import static net.runelite.api.ItemID.AHRIMS_ROBETOP_50;
ITEM_DHAROKS_HELM(DHAROKS_HELM, DHAROKS_HELM_25, DHAROKS_HELM_50, DHAROKS_HELM_75, DHAROKS_HELM_100), import static net.runelite.api.ItemID.AHRIMS_ROBETOP_75;
ITEM_DHAROKS_PLATEBODY(DHAROKS_PLATEBODY, DHAROKS_PLATEBODY_25, DHAROKS_PLATEBODY_50, DHAROKS_PLATEBODY_75, DHAROKS_PLATEBODY_100), import static net.runelite.api.ItemID.AHRIMS_STAFF;
ITEM_DHAROKS_PLATELEGS(DHAROKS_PLATELEGS, DHAROKS_PLATELEGS_25, DHAROKS_PLATELEGS_50, DHAROKS_PLATELEGS_75, DHAROKS_PLATELEGS_100), import static net.runelite.api.ItemID.AHRIMS_STAFF_100;
ITEM_DHARKS_GREATEAXE(DHAROKS_GREATAXE, DHAROKS_GREATAXE_25, DHAROKS_GREATAXE_50, DHAROKS_GREATAXE_75, DHAROKS_GREATAXE_100), import static net.runelite.api.ItemID.AHRIMS_STAFF_25;
ITEM_GUTHANS_HELM(GUTHANS_HELM, GUTHANS_HELM_25, GUTHANS_HELM_50, GUTHANS_HELM_75, GUTHANS_HELM_100), import static net.runelite.api.ItemID.AHRIMS_STAFF_50;
ITEM_GUTHANS_PLATEBODY(GUTHANS_PLATEBODY, GUTHANS_PLATEBODY_25, GUTHANS_PLATEBODY_50, GUTHANS_PLATEBODY_75, GUTHANS_PLATEBODY_100), import static net.runelite.api.ItemID.AHRIMS_STAFF_75;
ITEM_GUTHANS_CHAINSKIRT(GUTHANS_CHAINSKIRT, GUTHANS_CHAINSKIRT_25, GUTHANS_CHAINSKIRT_50, GUTHANS_CHAINSKIRT_75, GUTHANS_CHAINSKIRT_100), import static net.runelite.api.ItemID.AMULET_OF_FURY;
ITEM_GUTHANS_WARSPEAR(GUTHANS_WARSPEAR, GUTHANS_WARSPEAR_25, GUTHANS_WARSPEAR_50, GUTHANS_WARSPEAR_75, GUTHANS_WARSPEAR_100), import static net.runelite.api.ItemID.AMULET_OF_FURY_OR;
ITEM_TORAGS_HELM(TORAGS_HELM, TORAGS_HELM_25, TORAGS_HELM_50, TORAGS_HELM_75, TORAGS_HELM_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY;
ITEM_TORAGS_PLATEBODY(TORAGS_PLATEBODY, TORAGS_PLATEBODY_25, TORAGS_PLATEBODY_50, TORAGS_PLATEBODY_75, TORAGS_PLATEBODY_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY1;
ITEM_TORAGS_PLATELEGS(TORAGS_PLATELEGS, TORAGS_PLATELEGS_25, TORAGS_PLATELEGS_50, TORAGS_PLATELEGS_75, TORAGS_PLATELEGS_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY2;
ITEM_TORAGS_HAMMERS(TORAGS_HAMMERS, TORAGS_HAMMERS_25, TORAGS_HAMMERS_50, TORAGS_HAMMERS_75, TORAGS_HAMMERS_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY3;
ITEM_VERACS_HELM(VERACS_HELM, VERACS_HELM_25, VERACS_HELM_50, VERACS_HELM_75, VERACS_HELM_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY5;
ITEM_VERACS_BRASSARD(VERACS_BRASSARD, VERACS_BRASSARD_25, VERACS_BRASSARD_50, VERACS_BRASSARD_75, VERACS_BRASSARD_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY_T;
ITEM_VERACS_PLATESKIRT(VERACS_PLATESKIRT, VERACS_PLATESKIRT_25, VERACS_PLATESKIRT_50, VERACS_PLATESKIRT_75, VERACS_PLATESKIRT_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY_T1;
ITEM_VERACS_FLAIL(VERACS_FLAIL, VERACS_FLAIL_25, VERACS_FLAIL_50, VERACS_FLAIL_75, VERACS_FLAIL_100), import static net.runelite.api.ItemID.AMULET_OF_GLORY_T2;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T3;
// Dragon equipment ornament kits import static net.runelite.api.ItemID.AMULET_OF_GLORY_T5;
ITEM_DRAGON_SCIMITAR(DRAGON_SCIMITAR, DRAGON_SCIMITAR_OR), import static net.runelite.api.ItemID.AMULET_OF_TORTURE;
ITEM_DRAGON_SCIMITAR_ORNAMENT_KIT(DRAGON_SCIMITAR_ORNAMENT_KIT, DRAGON_SCIMITAR_OR), import static net.runelite.api.ItemID.AMULET_OF_TORTURE_OR;
ITEM_DRAGON_DEFENDER(DRAGON_DEFENDER_ORNAMENT_KIT, DRAGON_DEFENDER_T), import static net.runelite.api.ItemID.ANCIENT_WYVERN_SHIELD;
ITEM_DRAGON_PICKAXE(DRAGON_PICKAXE, DRAGON_PICKAXE_12797), import static net.runelite.api.ItemID.ANCIENT_WYVERN_SHIELD_21634;
ITEM_DRAGON_KITESHIELD(DRAGON_KITESHIELD, DRAGON_KITESHIELD_G), import static net.runelite.api.ItemID.ANGUISH_ORNAMENT_KIT;
ITEM_DRAGON_KITESHIELD_ORNAMENT_KIT(DRAGON_KITESHIELD_ORNAMENT_KIT, DRAGON_KITESHIELD_G), import static net.runelite.api.ItemID.ARCHERS_RING;
ITEM_DRAGON_FULL_HELM(DRAGON_FULL_HELM, DRAGON_FULL_HELM_G), import static net.runelite.api.ItemID.ARCHERS_RING_I;
ITEM_DRAGON_FULL_HELM_ORNAMENT_KIT(DRAGON_FULL_HELM_ORNAMENT_KIT, DRAGON_FULL_HELM_G), import static net.runelite.api.ItemID.ARMADYL_GODSWORD;
ITEM_DRAGON_CHAINBODY(DRAGON_CHAINBODY_3140, DRAGON_CHAINBODY_G), import static net.runelite.api.ItemID.ARMADYL_GODSWORD_OR;
ITEM_DRAGON_CHAINBODY_ORNAMENT_KIT(DRAGON_CHAINBODY_ORNAMENT_KIT, DRAGON_CHAINBODY_G), import static net.runelite.api.ItemID.ARMADYL_GODSWORD_ORNAMENT_KIT;
ITEM_DRAGON_PLATEBODY(DRAGON_PLATEBODY, DRAGON_PLATEBODY_G), import static net.runelite.api.ItemID.BANDOS_GODSWORD;
ITEM_DRAGON_PLATEBODY_ORNAMENT_KIT(DRAGON_PLATEBODY_ORNAMENT_KIT, DRAGON_PLATEBODY_G), import static net.runelite.api.ItemID.BANDOS_GODSWORD_OR;
ITEM_DRAGON_PLATESKIRT(DRAGON_PLATESKIRT, DRAGON_PLATESKIRT_G), import static net.runelite.api.ItemID.BANDOS_GODSWORD_ORNAMENT_KIT;
ITEM_DRAGON_SKIRT_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATESKIRT_G), import static net.runelite.api.ItemID.BERSERKER_RING;
ITEM_DRAGON_PLATELEGS(DRAGON_PLATELEGS, DRAGON_PLATELEGS_G), import static net.runelite.api.ItemID.BERSERKER_RING_I;
ITEM_DRAGON_LEGS_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATELEGS_G), import static net.runelite.api.ItemID.BLACK_MASK;
ITEM_DRAGON_SQ_SHIELD(DRAGON_SQ_SHIELD, DRAGON_SQ_SHIELD_G), import static net.runelite.api.ItemID.BLACK_MASK_1;
ITEM_DRAGON_SQ_SHIELD_ORNAMENT_KIT(DRAGON_SQ_SHIELD_ORNAMENT_KIT, DRAGON_SQ_SHIELD_G), import static net.runelite.api.ItemID.BLACK_MASK_10_I;
ITEM_DRAGON_BOOTS(DRAGON_BOOTS, DRAGON_BOOTS_G), import static net.runelite.api.ItemID.BLACK_MASK_1_I;
ITEM_DRAGON_BOOTS_ORNAMENT_KIT(DRAGON_BOOTS_ORNAMENT_KIT, DRAGON_BOOTS_G), import static net.runelite.api.ItemID.BLACK_MASK_2;
import static net.runelite.api.ItemID.BLACK_MASK_2_I;
// Godsword ornament kits import static net.runelite.api.ItemID.BLACK_MASK_3;
ITEM_ARMADYL_GODSWORD(ARMADYL_GODSWORD, ARMADYL_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_3_I;
ITEM_ARMADYL_GODSWORD_ORNAMENT_KIT(ARMADYL_GODSWORD_ORNAMENT_KIT, ARMADYL_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_4;
ITEM_BANDOS_GODSWORD(BANDOS_GODSWORD, BANDOS_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_4_I;
ITEM_BANDOS_GODSWORD_ORNAMENT_KIT(BANDOS_GODSWORD_ORNAMENT_KIT, BANDOS_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_5;
ITEM_ZAMORAK_GODSWORD(ZAMORAK_GODSWORD, ZAMORAK_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_5_I;
ITEM_ZAMORAK_GODSWORD_ORNAMENT_KIT(ZAMORAK_GODSWORD_ORNAMENT_KIT, ZAMORAK_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_6;
ITEM_SARADOMIN_GODSWORD(SARADOMIN_GODSWORD, SARADOMIN_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_6_I;
ITEM_SARADOMIN_GODSWORD_ORNAMENT_KIT(SARADOMIN_GODSWORD_ORNAMENT_KIT, SARADOMIN_GODSWORD_OR), import static net.runelite.api.ItemID.BLACK_MASK_7;
import static net.runelite.api.ItemID.BLACK_MASK_7_I;
// Jewellery ornament kits import static net.runelite.api.ItemID.BLACK_MASK_8;
ITEM_AMULET_OF_TORTURE(AMULET_OF_TORTURE, AMULET_OF_TORTURE_OR), import static net.runelite.api.ItemID.BLACK_MASK_8_I;
ITEM_TORTURE_ORNAMENT_KIT(TORTURE_ORNAMENT_KIT, AMULET_OF_TORTURE_OR), import static net.runelite.api.ItemID.BLACK_MASK_9;
ITEM_NECKLACE_OF_ANGUISH(NECKLACE_OF_ANGUISH, NECKLACE_OF_ANGUISH_OR), import static net.runelite.api.ItemID.BLACK_MASK_9_I;
ITEM_ANGUISH_ORNAMENT_KIT(ANGUISH_ORNAMENT_KIT, NECKLACE_OF_ANGUISH_OR), import static net.runelite.api.ItemID.BLACK_MASK_I;
ITEM_OCCULT_NECKLACE(OCCULT_NECKLACE, OCCULT_NECKLACE_OR), import static net.runelite.api.ItemID.BLACK_SLAYER_HELMET;
ITEM_OCCULT_ORNAMENT_KIT(OCCULT_ORNAMENT_KIT, OCCULT_NECKLACE_OR), import static net.runelite.api.ItemID.BLACK_SLAYER_HELMET_I;
ITE_AMULET_OF_FURY(AMULET_OF_FURY, AMULET_OF_FURY_OR), import static net.runelite.api.ItemID.BONECRUSHER_NECKLACE;
ITE_FURY_ORNAMENT_KIT(FURY_ORNAMENT_KIT, AMULET_OF_FURY_OR), import static net.runelite.api.ItemID.BOTTOMLESS_COMPOST_BUCKET;
import static net.runelite.api.ItemID.BOTTOMLESS_COMPOST_BUCKET_22997;
// Ensouled heads import static net.runelite.api.ItemID.CRAWS_BOW;
ITEM_ENSOULED_GOBLIN_HEAD(ENSOULED_GOBLIN_HEAD_13448, ENSOULED_GOBLIN_HEAD), import static net.runelite.api.ItemID.CRAWS_BOW_U;
ITEM_ENSOULED_MONKEY_HEAD(ENSOULED_MONKEY_HEAD_13451, ENSOULED_MONKEY_HEAD), import static net.runelite.api.ItemID.DARK_BOW;
ITEM_ENSOULED_IMP_HEAD(ENSOULED_IMP_HEAD_13454, ENSOULED_IMP_HEAD), import static net.runelite.api.ItemID.DARK_BOW_12765;
ITEM_ENSOULED_MINOTAUR_HEAD(ENSOULED_MINOTAUR_HEAD_13457, ENSOULED_MINOTAUR_HEAD), import static net.runelite.api.ItemID.DARK_BOW_12766;
ITEM_ENSOULED_SCORPION_HEAD(ENSOULED_SCORPION_HEAD_13460, ENSOULED_SCORPION_HEAD), import static net.runelite.api.ItemID.DARK_BOW_12767;
ITEM_ENSOULED_BEAR_HEAD(ENSOULED_BEAR_HEAD_13463, ENSOULED_BEAR_HEAD), import static net.runelite.api.ItemID.DARK_BOW_12768;
ITEM_ENSOULED_UNICORN_HEAD(ENSOULED_UNICORN_HEAD_13466, ENSOULED_UNICORN_HEAD), import static net.runelite.api.ItemID.DARK_BOW_20408;
ITEM_ENSOULED_DOG_HEAD(ENSOULED_DOG_HEAD_13469, ENSOULED_DOG_HEAD), import static net.runelite.api.ItemID.DARK_INFINITY_BOTTOMS;
ITEM_ENSOULED_CHAOS_DRUID_HEAD(ENSOULED_CHAOS_DRUID_HEAD_13472, ENSOULED_CHAOS_DRUID_HEAD), import static net.runelite.api.ItemID.DARK_INFINITY_COLOUR_KIT;
ITEM_ENSOULED_GIANT_HEAD(ENSOULED_GIANT_HEAD_13475, ENSOULED_GIANT_HEAD), import static net.runelite.api.ItemID.DARK_INFINITY_HAT;
ITEM_ENSOULED_OGRE_HEAD(ENSOULED_OGRE_HEAD_13478, ENSOULED_OGRE_HEAD), import static net.runelite.api.ItemID.DARK_INFINITY_TOP;
ITEM_ENSOULED_ELF_HEAD(ENSOULED_ELF_HEAD_13481, ENSOULED_ELF_HEAD), import static net.runelite.api.ItemID.DHAROKS_GREATAXE;
ITEM_ENSOULED_TROLL_HEAD(ENSOULED_TROLL_HEAD_13484, ENSOULED_TROLL_HEAD), import static net.runelite.api.ItemID.DHAROKS_GREATAXE_100;
ITEM_ENSOULED_HORROR_HEAD(ENSOULED_HORROR_HEAD_13487, ENSOULED_HORROR_HEAD), import static net.runelite.api.ItemID.DHAROKS_GREATAXE_25;
ITEM_ENSOULED_KALPHITE_HEAD(ENSOULED_KALPHITE_HEAD_13490, ENSOULED_KALPHITE_HEAD), import static net.runelite.api.ItemID.DHAROKS_GREATAXE_50;
ITEM_ENSOULED_DAGANNOTH_HEAD(ENSOULED_DAGANNOTH_HEAD_13493, ENSOULED_DAGANNOTH_HEAD), import static net.runelite.api.ItemID.DHAROKS_GREATAXE_75;
ITEM_ENSOULED_BLOODVELD_HEAD(ENSOULED_BLOODVELD_HEAD_13496, ENSOULED_BLOODVELD_HEAD), import static net.runelite.api.ItemID.DHAROKS_HELM;
ITEM_ENSOULED_TZHAAR_HEAD(ENSOULED_TZHAAR_HEAD_13499, ENSOULED_TZHAAR_HEAD), import static net.runelite.api.ItemID.DHAROKS_HELM_100;
ITEM_ENSOULED_DEMON_HEAD(ENSOULED_DEMON_HEAD_13502, ENSOULED_DEMON_HEAD), import static net.runelite.api.ItemID.DHAROKS_HELM_25;
ITEM_ENSOULED_AVIANSIE_HEAD(ENSOULED_AVIANSIE_HEAD_13505, ENSOULED_AVIANSIE_HEAD), import static net.runelite.api.ItemID.DHAROKS_HELM_50;
ITEM_ENSOULED_ABYSSAL_HEAD(ENSOULED_ABYSSAL_HEAD_13508, ENSOULED_ABYSSAL_HEAD), import static net.runelite.api.ItemID.DHAROKS_HELM_75;
ITEM_ENSOULED_DRAGON_HEAD(ENSOULED_DRAGON_HEAD_13511, ENSOULED_DRAGON_HEAD), import static net.runelite.api.ItemID.DHAROKS_PLATEBODY;
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_100;
// Imbued rings import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_25;
ITEM_BERSERKER_RING(BERSERKER_RING, BERSERKER_RING_I), import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_50;
ITEM_SEERS_RING(SEERS_RING, SEERS_RING_I), import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_75;
ITEM_WARRIOR_RING(WARRIOR_RING, WARRIOR_RING_I), import static net.runelite.api.ItemID.DHAROKS_PLATELEGS;
ITEM_ARCHERS_RING(ARCHERS_RING, ARCHERS_RING_I), import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_100;
ITEM_TREASONOUS_RING(TREASONOUS_RING, TREASONOUS_RING_I), import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_25;
ITEM_TYRANNICAL_RING(TYRANNICAL_RING, TYRANNICAL_RING_I), import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_50;
ITEM_RING_OF_THE_GODS(RING_OF_THE_GODS, RING_OF_THE_GODS_I), import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_75;
ITEM_RING_OF_SUFFERING(RING_OF_SUFFERING, RING_OF_SUFFERING_I, RING_OF_SUFFERING_R, RING_OF_SUFFERING_RI), import static net.runelite.api.ItemID.DRAGONBONE_NECKLACE;
ITEM_GRANITE_RING(GRANITE_RING, GRANITE_RING_I), import static net.runelite.api.ItemID.DRAGONFIRE_SHIELD;
import static net.runelite.api.ItemID.DRAGONFIRE_SHIELD_11284;
// Bounty hunter import static net.runelite.api.ItemID.DRAGONFIRE_WARD;
ITEM_GRANITE_MAUL(GRANITE_MAUL, GRANITE_MAUL_12848), import static net.runelite.api.ItemID.DRAGONFIRE_WARD_22003;
ITEM_MAGIC_SHORTBOW(MAGIC_SHORTBOW, MAGIC_SHORTBOW_I), import static net.runelite.api.ItemID.DRAGON_BOOTS;
ITEM_SARADOMINS_BLESSED_SWORD(SARADOMINS_TEAR, SARADOMINS_BLESSED_SWORD), import static net.runelite.api.ItemID.DRAGON_BOOTS_G;
import static net.runelite.api.ItemID.DRAGON_BOOTS_ORNAMENT_KIT;
// Jewellery with charges import static net.runelite.api.ItemID.DRAGON_CHAINBODY_3140;
ITEM_RING_OF_WEALTH(RING_OF_WEALTH, RING_OF_WEALTH_I, RING_OF_WEALTH_1, RING_OF_WEALTH_I1, RING_OF_WEALTH_2, RING_OF_WEALTH_I2, RING_OF_WEALTH_3, RING_OF_WEALTH_I3, RING_OF_WEALTH_4, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5), import static net.runelite.api.ItemID.DRAGON_CHAINBODY_G;
ITEM_AMULET_OF_GLORY(AMULET_OF_GLORY, AMULET_OF_GLORY1, AMULET_OF_GLORY2, AMULET_OF_GLORY3, AMULET_OF_GLORY5), import static net.runelite.api.ItemID.DRAGON_CHAINBODY_ORNAMENT_KIT;
ITEM_AMULET_OF_GLORY_T(AMULET_OF_GLORY_T, AMULET_OF_GLORY_T1, AMULET_OF_GLORY_T2, AMULET_OF_GLORY_T3, AMULET_OF_GLORY_T5), import static net.runelite.api.ItemID.DRAGON_DEFENDER_ORNAMENT_KIT;
ITEM_SKILLS_NECKLACE(SKILLS_NECKLACE, SKILLS_NECKLACE1, SKILLS_NECKLACE2, SKILLS_NECKLACE3, SKILLS_NECKLACE5), import static net.runelite.api.ItemID.DRAGON_DEFENDER_T;
ITEM_RING_OF_DUELING(RING_OF_DUELING8, RING_OF_DUELING1, RING_OF_DUELING2, RING_OF_DUELING3, RING_OF_DUELING4, RING_OF_DUELING5, RING_OF_DUELING6, RING_OF_DUELING7), import static net.runelite.api.ItemID.DRAGON_FULL_HELM;
ITEM_GAMES_NECKLACE(GAMES_NECKLACE8, GAMES_NECKLACE1, GAMES_NECKLACE2, GAMES_NECKLACE3, GAMES_NECKLACE4, GAMES_NECKLACE5, GAMES_NECKLACE6, GAMES_NECKLACE7), import static net.runelite.api.ItemID.DRAGON_FULL_HELM_G;
import static net.runelite.api.ItemID.DRAGON_FULL_HELM_ORNAMENT_KIT;
// Degradable/charged weaponry/armour import static net.runelite.api.ItemID.DRAGON_KITESHIELD;
ITEM_ABYSSAL_WHIP(ABYSSAL_WHIP, VOLCANIC_ABYSSAL_WHIP, FROZEN_ABYSSAL_WHIP), import static net.runelite.api.ItemID.DRAGON_KITESHIELD_G;
ITEM_KRAKEN_TENTACLE(KRAKEN_TENTACLE, ABYSSAL_TENTACLE), import static net.runelite.api.ItemID.DRAGON_KITESHIELD_ORNAMENT_KIT;
ITEM_TRIDENT_OF_THE_SEAS(UNCHARGED_TRIDENT, TRIDENT_OF_THE_SEAS), import static net.runelite.api.ItemID.DRAGON_LEGSSKIRT_ORNAMENT_KIT;
ITEM_TRIDENT_OF_THE_SEAS_E(UNCHARGED_TRIDENT_E, TRIDENT_OF_THE_SEAS_E), import static net.runelite.api.ItemID.DRAGON_PICKAXE;
ITEM_TRIDENT_OF_THE_SWAMP(UNCHARGED_TOXIC_TRIDENT, TRIDENT_OF_THE_SWAMP), import static net.runelite.api.ItemID.DRAGON_PICKAXE_12797;
ITEM_TRIDENT_OF_THE_SWAMP_E(UNCHARGED_TOXIC_TRIDENT_E, TRIDENT_OF_THE_SWAMP_E), import static net.runelite.api.ItemID.DRAGON_PLATEBODY;
ITEM_TOXIC_BLOWPIPE(TOXIC_BLOWPIPE_EMPTY, TOXIC_BLOWPIPE), import static net.runelite.api.ItemID.DRAGON_PLATEBODY_G;
ITEM_TOXIC_STAFF_OFF_THE_DEAD(TOXIC_STAFF_UNCHARGED, TOXIC_STAFF_OF_THE_DEAD), import static net.runelite.api.ItemID.DRAGON_PLATEBODY_ORNAMENT_KIT;
ITEM_SERPENTINE_HELM(SERPENTINE_HELM_UNCHARGED, SERPENTINE_HELM, TANZANITE_HELM_UNCHARGED, TANZANITE_HELM, MAGMA_HELM_UNCHARGED, MAGMA_HELM), import static net.runelite.api.ItemID.DRAGON_PLATELEGS;
ITEM_DRAGONFIRE_SHIELD(DRAGONFIRE_SHIELD_11284, DRAGONFIRE_SHIELD), import static net.runelite.api.ItemID.DRAGON_PLATELEGS_G;
ITEM_DRAGONFIRE_WARD(DRAGONFIRE_WARD_22003, DRAGONFIRE_WARD), import static net.runelite.api.ItemID.DRAGON_PLATESKIRT;
ITEM_ANCIENT_WYVERN_SHIELD(ANCIENT_WYVERN_SHIELD_21634, ANCIENT_WYVERN_SHIELD), import static net.runelite.api.ItemID.DRAGON_PLATESKIRT_G;
ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF), import static net.runelite.api.ItemID.DRAGON_SCIMITAR;
ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR), import static net.runelite.api.ItemID.DRAGON_SCIMITAR_OR;
ITEM_TOME_OF_FIRE(TOME_OF_FIRE_EMPTY, TOME_OF_FIRE), import static net.runelite.api.ItemID.DRAGON_SCIMITAR_ORNAMENT_KIT;
ITEM_CRAWS_BOW(CRAWS_BOW_U, CRAWS_BOW), import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD;
ITEM_VIGGORAS_CHAINMACE(VIGGORAS_CHAINMACE_U, VIGGORAS_CHAINMACE), import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD_G;
ITEM_THAMMARONS_SCEPTRE(THAMMARONS_SCEPTRE_U, THAMMARONS_SCEPTRE), import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD_ORNAMENT_KIT;
import static net.runelite.api.ItemID.ENSOULED_ABYSSAL_HEAD;
// Infinity colour kits import static net.runelite.api.ItemID.ENSOULED_ABYSSAL_HEAD_13508;
ITEM_INFINITY_TOP(INFINITY_TOP, INFINITY_TOP_10605, INFINITY_TOP_20574, DARK_INFINITY_TOP, LIGHT_INFINITY_TOP), import static net.runelite.api.ItemID.ENSOULED_AVIANSIE_HEAD;
ITEM_INFINITY_TOP_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_TOP), import static net.runelite.api.ItemID.ENSOULED_AVIANSIE_HEAD_13505;
ITEM_INFINITY_TOP_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_TOP), import static net.runelite.api.ItemID.ENSOULED_BEAR_HEAD;
ITEM_INFINITY_BOTTOMS(INFINITY_BOTTOMS, INFINITY_BOTTOMS_20575, DARK_INFINITY_BOTTOMS, LIGHT_INFINITY_BOTTOMS), import static net.runelite.api.ItemID.ENSOULED_BEAR_HEAD_13463;
ITEM_INFINITY_BOTTOMS_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_BOTTOMS), import static net.runelite.api.ItemID.ENSOULED_BLOODVELD_HEAD;
ITEM_INFINITY_BOTTOMS_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_BOTTOMS), import static net.runelite.api.ItemID.ENSOULED_BLOODVELD_HEAD_13496;
ITEM_INFINITY_HAT(INFINITY_HAT, DARK_INFINITY_HAT, LIGHT_INFINITY_HAT), import static net.runelite.api.ItemID.ENSOULED_CHAOS_DRUID_HEAD;
ITEM_INFINITY_HAT_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_HAT), import static net.runelite.api.ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472;
ITEM_INFINITY_HAT_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_HAT), import static net.runelite.api.ItemID.ENSOULED_DAGANNOTH_HEAD;
import static net.runelite.api.ItemID.ENSOULED_DAGANNOTH_HEAD_13493;
// Miscellaneous ornament kits import static net.runelite.api.ItemID.ENSOULED_DEMON_HEAD;
ITEM_DARK_BOW(DARK_BOW, DARK_BOW_12765, DARK_BOW_12766, DARK_BOW_12767, DARK_BOW_12768, DARK_BOW_20408), import static net.runelite.api.ItemID.ENSOULED_DEMON_HEAD_13502;
ITEM_ODIUM_WARD(ODIUM_WARD, ODIUM_WARD_12807), import static net.runelite.api.ItemID.ENSOULED_DOG_HEAD;
ITEM_MALEDICTION_WARD(MALEDICTION_WARD, MALEDICTION_WARD_12806), import static net.runelite.api.ItemID.ENSOULED_DOG_HEAD_13469;
ITEM_STEAM_BATTLESTAFF(STEAM_BATTLESTAFF, STEAM_BATTLESTAFF_12795), import static net.runelite.api.ItemID.ENSOULED_DRAGON_HEAD;
ITEM_LAVA_BATTLESTAFF(LAVA_BATTLESTAFF, LAVA_BATTLESTAFF_21198), import static net.runelite.api.ItemID.ENSOULED_DRAGON_HEAD_13511;
import static net.runelite.api.ItemID.ENSOULED_ELF_HEAD;
// Slayer helm/black mask import static net.runelite.api.ItemID.ENSOULED_ELF_HEAD_13481;
ITEM_BLACK_MASK( import static net.runelite.api.ItemID.ENSOULED_GIANT_HEAD;
BLACK_MASK, BLACK_MASK_I, BLACK_MASK_1, BLACK_MASK_1_I, BLACK_MASK_2, BLACK_MASK_2_I, BLACK_MASK_3, BLACK_MASK_3_I, BLACK_MASK_4, BLACK_MASK_4_I, BLACK_MASK_5, import static net.runelite.api.ItemID.ENSOULED_GIANT_HEAD_13475;
BLACK_MASK_5_I, BLACK_MASK_6, BLACK_MASK_6_I, BLACK_MASK_7, BLACK_MASK_7_I, BLACK_MASK_8, BLACK_MASK_8_I, BLACK_MASK_9, BLACK_MASK_9_I, BLACK_MASK_10_I, import static net.runelite.api.ItemID.ENSOULED_GOBLIN_HEAD;
SLAYER_HELMET, SLAYER_HELMET_I, BLACK_SLAYER_HELMET, BLACK_SLAYER_HELMET_I, PURPLE_SLAYER_HELMET, PURPLE_SLAYER_HELMET_I, RED_SLAYER_HELMET, RED_SLAYER_HELMET_I, import static net.runelite.api.ItemID.ENSOULED_GOBLIN_HEAD_13448;
GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I, HYDRA_SLAYER_HELMET, HYDRA_SLAYER_HELMET_I), import static net.runelite.api.ItemID.ENSOULED_HORROR_HEAD;
import static net.runelite.api.ItemID.ENSOULED_HORROR_HEAD_13487;
// Pharaoh's Sceptres import static net.runelite.api.ItemID.ENSOULED_IMP_HEAD;
ITEM_PHARAOHS_SCEPTRE_1(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_1), import static net.runelite.api.ItemID.ENSOULED_IMP_HEAD_13454;
ITEM_PHARAOHS_SCEPTRE_2(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_2), import static net.runelite.api.ItemID.ENSOULED_KALPHITE_HEAD;
ITEM_PHARAOHS_SCEPTRE_4(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_4), import static net.runelite.api.ItemID.ENSOULED_KALPHITE_HEAD_13490;
ITEM_PHARAOHS_SCEPTRE_5(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_5), import static net.runelite.api.ItemID.ENSOULED_MINOTAUR_HEAD;
ITEM_PHARAOHS_SCEPTRE_6(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_6), import static net.runelite.api.ItemID.ENSOULED_MINOTAUR_HEAD_13457;
ITEM_PHARAOHS_SCEPTRE_7(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_7), import static net.runelite.api.ItemID.ENSOULED_MONKEY_HEAD;
ITEM_PHARAOHS_SCEPTRE_8(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_8), import static net.runelite.api.ItemID.ENSOULED_MONKEY_HEAD_13451;
import static net.runelite.api.ItemID.ENSOULED_OGRE_HEAD;
// Revertible items import static net.runelite.api.ItemID.ENSOULED_OGRE_HEAD_13478;
ITEM_HYDRA_LEATHER(HYDRA_LEATHER, FEROCIOUS_GLOVES), import static net.runelite.api.ItemID.ENSOULED_SCORPION_HEAD;
ITEM_HYDRA_TAIL(HYDRA_TAIL, BONECRUSHER_NECKLACE), import static net.runelite.api.ItemID.ENSOULED_SCORPION_HEAD_13460;
ITEM_DRAGONBONE_NECKLACE(DRAGONBONE_NECKLACE, BONECRUSHER_NECKLACE), import static net.runelite.api.ItemID.ENSOULED_TROLL_HEAD;
ITEM_BOTTOMLESS_COMPOST_BUCKET(BOTTOMLESS_COMPOST_BUCKET, BOTTOMLESS_COMPOST_BUCKET_22997); import static net.runelite.api.ItemID.ENSOULED_TROLL_HEAD_13484;
import static net.runelite.api.ItemID.ENSOULED_TZHAAR_HEAD;
private static final Multimap<Integer, Integer> MAPPINGS = HashMultimap.create(); import static net.runelite.api.ItemID.ENSOULED_TZHAAR_HEAD_13499;
private final int tradeableItem; import static net.runelite.api.ItemID.ENSOULED_UNICORN_HEAD;
private final int[] untradableItems; import static net.runelite.api.ItemID.ENSOULED_UNICORN_HEAD_13466;
import static net.runelite.api.ItemID.FEROCIOUS_GLOVES;
static import static net.runelite.api.ItemID.FROZEN_ABYSSAL_WHIP;
{ import static net.runelite.api.ItemID.FURY_ORNAMENT_KIT;
for (final ItemMapping item : values()) import static net.runelite.api.ItemID.GAMES_NECKLACE1;
{ import static net.runelite.api.ItemID.GAMES_NECKLACE2;
for (int itemId : item.untradableItems) import static net.runelite.api.ItemID.GAMES_NECKLACE3;
{ import static net.runelite.api.ItemID.GAMES_NECKLACE4;
MAPPINGS.put(itemId, item.tradeableItem); import static net.runelite.api.ItemID.GAMES_NECKLACE5;
} import static net.runelite.api.ItemID.GAMES_NECKLACE6;
} import static net.runelite.api.ItemID.GAMES_NECKLACE7;
} import static net.runelite.api.ItemID.GAMES_NECKLACE8;
import static net.runelite.api.ItemID.GRANITE_MAUL;
ItemMapping(int tradeableItem, int... untradableItems) import static net.runelite.api.ItemID.GRANITE_MAUL_12848;
{ import static net.runelite.api.ItemID.GRANITE_RING;
this.tradeableItem = tradeableItem; import static net.runelite.api.ItemID.GRANITE_RING_I;
this.untradableItems = untradableItems; import static net.runelite.api.ItemID.GREEN_SLAYER_HELMET;
} import static net.runelite.api.ItemID.GREEN_SLAYER_HELMET_I;
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT;
/** import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_100;
* Get collection of items that are mapped from single item id. import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_25;
* import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_50;
* @param itemId the item id import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_75;
* @return the collection import static net.runelite.api.ItemID.GUTHANS_HELM;
*/ import static net.runelite.api.ItemID.GUTHANS_HELM_100;
public static Collection<Integer> map(int itemId) import static net.runelite.api.ItemID.GUTHANS_HELM_25;
{ import static net.runelite.api.ItemID.GUTHANS_HELM_50;
final Collection<Integer> mapping = MAPPINGS.get(itemId); import static net.runelite.api.ItemID.GUTHANS_HELM_75;
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY;
if (mapping == null || mapping.isEmpty()) import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_100;
{ import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_25;
return Collections.singleton(itemId); import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_50;
} import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_75;
import static net.runelite.api.ItemID.GUTHANS_WARSPEAR;
return mapping; import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_100;
} import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_25;
import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_50;
/** import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_75;
* Map an item from its untradeable version to its tradeable version import static net.runelite.api.ItemID.HYDRA_LEATHER;
* import static net.runelite.api.ItemID.HYDRA_SLAYER_HELMET;
* @param itemId import static net.runelite.api.ItemID.HYDRA_SLAYER_HELMET_I;
* @return import static net.runelite.api.ItemID.HYDRA_TAIL;
*/ import static net.runelite.api.ItemID.INFINITY_BOTTOMS;
public static int mapFirst(int itemId) import static net.runelite.api.ItemID.INFINITY_BOTTOMS_20575;
{ import static net.runelite.api.ItemID.INFINITY_HAT;
final Collection<Integer> mapping = MAPPINGS.get(itemId); import static net.runelite.api.ItemID.INFINITY_TOP;
import static net.runelite.api.ItemID.INFINITY_TOP_10605;
if (mapping == null || mapping.isEmpty()) import static net.runelite.api.ItemID.INFINITY_TOP_20574;
{ import static net.runelite.api.ItemID.KARILS_COIF;
return itemId; import static net.runelite.api.ItemID.KARILS_COIF_100;
} import static net.runelite.api.ItemID.KARILS_COIF_25;
import static net.runelite.api.ItemID.KARILS_COIF_50;
return mapping.iterator().next(); import static net.runelite.api.ItemID.KARILS_COIF_75;
} import static net.runelite.api.ItemID.KARILS_CROSSBOW;
} import static net.runelite.api.ItemID.KARILS_CROSSBOW_100;
import static net.runelite.api.ItemID.KARILS_CROSSBOW_25;
import static net.runelite.api.ItemID.KARILS_CROSSBOW_50;
import static net.runelite.api.ItemID.KARILS_CROSSBOW_75;
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT;
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_100;
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_25;
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_50;
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_75;
import static net.runelite.api.ItemID.KARILS_LEATHERTOP;
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_100;
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_25;
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_50;
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_75;
import static net.runelite.api.ItemID.KRAKEN_TENTACLE;
import static net.runelite.api.ItemID.LAVA_BATTLESTAFF;
import static net.runelite.api.ItemID.LAVA_BATTLESTAFF_21198;
import static net.runelite.api.ItemID.LIGHT_INFINITY_BOTTOMS;
import static net.runelite.api.ItemID.LIGHT_INFINITY_COLOUR_KIT;
import static net.runelite.api.ItemID.LIGHT_INFINITY_HAT;
import static net.runelite.api.ItemID.LIGHT_INFINITY_TOP;
import static net.runelite.api.ItemID.MAGIC_SHORTBOW;
import static net.runelite.api.ItemID.MAGIC_SHORTBOW_I;
import static net.runelite.api.ItemID.MAGMA_HELM;
import static net.runelite.api.ItemID.MAGMA_HELM_UNCHARGED;
import static net.runelite.api.ItemID.MALEDICTION_WARD;
import static net.runelite.api.ItemID.MALEDICTION_WARD_12806;
import static net.runelite.api.ItemID.NECKLACE_OF_ANGUISH;
import static net.runelite.api.ItemID.NECKLACE_OF_ANGUISH_OR;
import static net.runelite.api.ItemID.OCCULT_NECKLACE;
import static net.runelite.api.ItemID.OCCULT_NECKLACE_OR;
import static net.runelite.api.ItemID.OCCULT_ORNAMENT_KIT;
import static net.runelite.api.ItemID.ODIUM_WARD;
import static net.runelite.api.ItemID.ODIUM_WARD_12807;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_1;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_2;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_4;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_5;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_6;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_7;
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_8;
import static net.runelite.api.ItemID.PURPLE_SLAYER_HELMET;
import static net.runelite.api.ItemID.PURPLE_SLAYER_HELMET_I;
import static net.runelite.api.ItemID.RED_SLAYER_HELMET;
import static net.runelite.api.ItemID.RED_SLAYER_HELMET_I;
import static net.runelite.api.ItemID.RING_OF_DUELING1;
import static net.runelite.api.ItemID.RING_OF_DUELING2;
import static net.runelite.api.ItemID.RING_OF_DUELING3;
import static net.runelite.api.ItemID.RING_OF_DUELING4;
import static net.runelite.api.ItemID.RING_OF_DUELING5;
import static net.runelite.api.ItemID.RING_OF_DUELING6;
import static net.runelite.api.ItemID.RING_OF_DUELING7;
import static net.runelite.api.ItemID.RING_OF_DUELING8;
import static net.runelite.api.ItemID.RING_OF_SUFFERING;
import static net.runelite.api.ItemID.RING_OF_SUFFERING_I;
import static net.runelite.api.ItemID.RING_OF_SUFFERING_R;
import static net.runelite.api.ItemID.RING_OF_SUFFERING_RI;
import static net.runelite.api.ItemID.RING_OF_THE_GODS;
import static net.runelite.api.ItemID.RING_OF_THE_GODS_I;
import static net.runelite.api.ItemID.RING_OF_WEALTH;
import static net.runelite.api.ItemID.RING_OF_WEALTH_1;
import static net.runelite.api.ItemID.RING_OF_WEALTH_2;
import static net.runelite.api.ItemID.RING_OF_WEALTH_3;
import static net.runelite.api.ItemID.RING_OF_WEALTH_4;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I1;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I2;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I3;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I4;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I5;
import static net.runelite.api.ItemID.SANGUINESTI_STAFF;
import static net.runelite.api.ItemID.SANGUINESTI_STAFF_UNCHARGED;
import static net.runelite.api.ItemID.SARADOMINS_BLESSED_SWORD;
import static net.runelite.api.ItemID.SARADOMINS_TEAR;
import static net.runelite.api.ItemID.SARADOMIN_GODSWORD;
import static net.runelite.api.ItemID.SARADOMIN_GODSWORD_OR;
import static net.runelite.api.ItemID.SARADOMIN_GODSWORD_ORNAMENT_KIT;
import static net.runelite.api.ItemID.SCYTHE_OF_VITUR;
import static net.runelite.api.ItemID.SCYTHE_OF_VITUR_UNCHARGED;
import static net.runelite.api.ItemID.SEERS_RING;
import static net.runelite.api.ItemID.SEERS_RING_I;
import static net.runelite.api.ItemID.SERPENTINE_HELM;
import static net.runelite.api.ItemID.SERPENTINE_HELM_UNCHARGED;
import static net.runelite.api.ItemID.SKILLS_NECKLACE;
import static net.runelite.api.ItemID.SKILLS_NECKLACE1;
import static net.runelite.api.ItemID.SKILLS_NECKLACE2;
import static net.runelite.api.ItemID.SKILLS_NECKLACE3;
import static net.runelite.api.ItemID.SKILLS_NECKLACE5;
import static net.runelite.api.ItemID.SLAYER_HELMET;
import static net.runelite.api.ItemID.SLAYER_HELMET_I;
import static net.runelite.api.ItemID.STEAM_BATTLESTAFF;
import static net.runelite.api.ItemID.STEAM_BATTLESTAFF_12795;
import static net.runelite.api.ItemID.TANZANITE_HELM;
import static net.runelite.api.ItemID.TANZANITE_HELM_UNCHARGED;
import static net.runelite.api.ItemID.THAMMARONS_SCEPTRE;
import static net.runelite.api.ItemID.THAMMARONS_SCEPTRE_U;
import static net.runelite.api.ItemID.TOME_OF_FIRE;
import static net.runelite.api.ItemID.TOME_OF_FIRE_EMPTY;
import static net.runelite.api.ItemID.TORAGS_HAMMERS;
import static net.runelite.api.ItemID.TORAGS_HAMMERS_100;
import static net.runelite.api.ItemID.TORAGS_HAMMERS_25;
import static net.runelite.api.ItemID.TORAGS_HAMMERS_50;
import static net.runelite.api.ItemID.TORAGS_HAMMERS_75;
import static net.runelite.api.ItemID.TORAGS_HELM;
import static net.runelite.api.ItemID.TORAGS_HELM_100;
import static net.runelite.api.ItemID.TORAGS_HELM_25;
import static net.runelite.api.ItemID.TORAGS_HELM_50;
import static net.runelite.api.ItemID.TORAGS_HELM_75;
import static net.runelite.api.ItemID.TORAGS_PLATEBODY;
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_100;
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_25;
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_50;
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_75;
import static net.runelite.api.ItemID.TORAGS_PLATELEGS;
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_100;
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_25;
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_50;
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_75;
import static net.runelite.api.ItemID.TORTURE_ORNAMENT_KIT;
import static net.runelite.api.ItemID.TOXIC_BLOWPIPE;
import static net.runelite.api.ItemID.TOXIC_BLOWPIPE_EMPTY;
import static net.runelite.api.ItemID.TOXIC_STAFF_OF_THE_DEAD;
import static net.runelite.api.ItemID.TOXIC_STAFF_UNCHARGED;
import static net.runelite.api.ItemID.TREASONOUS_RING;
import static net.runelite.api.ItemID.TREASONOUS_RING_I;
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SEAS;
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SEAS_E;
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SWAMP;
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SWAMP_E;
import static net.runelite.api.ItemID.TURQUOISE_SLAYER_HELMET;
import static net.runelite.api.ItemID.TURQUOISE_SLAYER_HELMET_I;
import static net.runelite.api.ItemID.TYRANNICAL_RING;
import static net.runelite.api.ItemID.TYRANNICAL_RING_I;
import static net.runelite.api.ItemID.UNCHARGED_TOXIC_TRIDENT;
import static net.runelite.api.ItemID.UNCHARGED_TOXIC_TRIDENT_E;
import static net.runelite.api.ItemID.UNCHARGED_TRIDENT;
import static net.runelite.api.ItemID.UNCHARGED_TRIDENT_E;
import static net.runelite.api.ItemID.VERACS_BRASSARD;
import static net.runelite.api.ItemID.VERACS_BRASSARD_100;
import static net.runelite.api.ItemID.VERACS_BRASSARD_25;
import static net.runelite.api.ItemID.VERACS_BRASSARD_50;
import static net.runelite.api.ItemID.VERACS_BRASSARD_75;
import static net.runelite.api.ItemID.VERACS_FLAIL;
import static net.runelite.api.ItemID.VERACS_FLAIL_100;
import static net.runelite.api.ItemID.VERACS_FLAIL_25;
import static net.runelite.api.ItemID.VERACS_FLAIL_50;
import static net.runelite.api.ItemID.VERACS_FLAIL_75;
import static net.runelite.api.ItemID.VERACS_HELM;
import static net.runelite.api.ItemID.VERACS_HELM_100;
import static net.runelite.api.ItemID.VERACS_HELM_25;
import static net.runelite.api.ItemID.VERACS_HELM_50;
import static net.runelite.api.ItemID.VERACS_HELM_75;
import static net.runelite.api.ItemID.VERACS_PLATESKIRT;
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_100;
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_25;
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_50;
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_75;
import static net.runelite.api.ItemID.VIGGORAS_CHAINMACE;
import static net.runelite.api.ItemID.VIGGORAS_CHAINMACE_U;
import static net.runelite.api.ItemID.VOLCANIC_ABYSSAL_WHIP;
import static net.runelite.api.ItemID.WARRIOR_RING;
import static net.runelite.api.ItemID.WARRIOR_RING_I;
import static net.runelite.api.ItemID.ZAMORAK_GODSWORD;
import static net.runelite.api.ItemID.ZAMORAK_GODSWORD_OR;
import static net.runelite.api.ItemID.ZAMORAK_GODSWORD_ORNAMENT_KIT;
/**
* Converts untradeable items to it's tradeable counterparts
*/
public enum ItemMapping
{
// Barrows equipment
ITEM_AHRIMS_HOOD(AHRIMS_HOOD, AHRIMS_HOOD_25, AHRIMS_HOOD_50, AHRIMS_HOOD_75, AHRIMS_HOOD_100),
ITEM_AHRIMS_ROBETOP(AHRIMS_ROBETOP, AHRIMS_ROBETOP_25, AHRIMS_ROBETOP_50, AHRIMS_ROBETOP_75, AHRIMS_ROBETOP_100),
ITEM_AHRIMS_ROBEBOTTOM(AHRIMS_ROBESKIRT, AHRIMS_ROBESKIRT_25, AHRIMS_ROBESKIRT_50, AHRIMS_ROBESKIRT_75, AHRIMS_ROBESKIRT_100),
ITEM_AHRIMS_STAFF(AHRIMS_STAFF, AHRIMS_STAFF_25, AHRIMS_STAFF_50, AHRIMS_STAFF_75, AHRIMS_STAFF_100),
ITEM_KARILS_COIF(KARILS_COIF, KARILS_COIF_25, KARILS_COIF_50, KARILS_COIF_75, KARILS_COIF_100),
ITEM_KARILS_LEATHERTOP(KARILS_LEATHERTOP, KARILS_LEATHERTOP_25, KARILS_LEATHERTOP_50, KARILS_LEATHERTOP_75, KARILS_LEATHERTOP_100),
ITEM_KARILS_LEATHERSKIRT(KARILS_LEATHERSKIRT, KARILS_LEATHERSKIRT_25, KARILS_LEATHERSKIRT_50, KARILS_LEATHERSKIRT_75, KARILS_LEATHERSKIRT_100),
ITEM_KARILS_CROSSBOW(KARILS_CROSSBOW, KARILS_CROSSBOW_25, KARILS_CROSSBOW_50, KARILS_CROSSBOW_75, KARILS_CROSSBOW_100),
ITEM_DHAROKS_HELM(DHAROKS_HELM, DHAROKS_HELM_25, DHAROKS_HELM_50, DHAROKS_HELM_75, DHAROKS_HELM_100),
ITEM_DHAROKS_PLATEBODY(DHAROKS_PLATEBODY, DHAROKS_PLATEBODY_25, DHAROKS_PLATEBODY_50, DHAROKS_PLATEBODY_75, DHAROKS_PLATEBODY_100),
ITEM_DHAROKS_PLATELEGS(DHAROKS_PLATELEGS, DHAROKS_PLATELEGS_25, DHAROKS_PLATELEGS_50, DHAROKS_PLATELEGS_75, DHAROKS_PLATELEGS_100),
ITEM_DHARKS_GREATEAXE(DHAROKS_GREATAXE, DHAROKS_GREATAXE_25, DHAROKS_GREATAXE_50, DHAROKS_GREATAXE_75, DHAROKS_GREATAXE_100),
ITEM_GUTHANS_HELM(GUTHANS_HELM, GUTHANS_HELM_25, GUTHANS_HELM_50, GUTHANS_HELM_75, GUTHANS_HELM_100),
ITEM_GUTHANS_PLATEBODY(GUTHANS_PLATEBODY, GUTHANS_PLATEBODY_25, GUTHANS_PLATEBODY_50, GUTHANS_PLATEBODY_75, GUTHANS_PLATEBODY_100),
ITEM_GUTHANS_CHAINSKIRT(GUTHANS_CHAINSKIRT, GUTHANS_CHAINSKIRT_25, GUTHANS_CHAINSKIRT_50, GUTHANS_CHAINSKIRT_75, GUTHANS_CHAINSKIRT_100),
ITEM_GUTHANS_WARSPEAR(GUTHANS_WARSPEAR, GUTHANS_WARSPEAR_25, GUTHANS_WARSPEAR_50, GUTHANS_WARSPEAR_75, GUTHANS_WARSPEAR_100),
ITEM_TORAGS_HELM(TORAGS_HELM, TORAGS_HELM_25, TORAGS_HELM_50, TORAGS_HELM_75, TORAGS_HELM_100),
ITEM_TORAGS_PLATEBODY(TORAGS_PLATEBODY, TORAGS_PLATEBODY_25, TORAGS_PLATEBODY_50, TORAGS_PLATEBODY_75, TORAGS_PLATEBODY_100),
ITEM_TORAGS_PLATELEGS(TORAGS_PLATELEGS, TORAGS_PLATELEGS_25, TORAGS_PLATELEGS_50, TORAGS_PLATELEGS_75, TORAGS_PLATELEGS_100),
ITEM_TORAGS_HAMMERS(TORAGS_HAMMERS, TORAGS_HAMMERS_25, TORAGS_HAMMERS_50, TORAGS_HAMMERS_75, TORAGS_HAMMERS_100),
ITEM_VERACS_HELM(VERACS_HELM, VERACS_HELM_25, VERACS_HELM_50, VERACS_HELM_75, VERACS_HELM_100),
ITEM_VERACS_BRASSARD(VERACS_BRASSARD, VERACS_BRASSARD_25, VERACS_BRASSARD_50, VERACS_BRASSARD_75, VERACS_BRASSARD_100),
ITEM_VERACS_PLATESKIRT(VERACS_PLATESKIRT, VERACS_PLATESKIRT_25, VERACS_PLATESKIRT_50, VERACS_PLATESKIRT_75, VERACS_PLATESKIRT_100),
ITEM_VERACS_FLAIL(VERACS_FLAIL, VERACS_FLAIL_25, VERACS_FLAIL_50, VERACS_FLAIL_75, VERACS_FLAIL_100),
// Dragon equipment ornament kits
ITEM_DRAGON_SCIMITAR(DRAGON_SCIMITAR, DRAGON_SCIMITAR_OR),
ITEM_DRAGON_SCIMITAR_ORNAMENT_KIT(DRAGON_SCIMITAR_ORNAMENT_KIT, DRAGON_SCIMITAR_OR),
ITEM_DRAGON_DEFENDER(DRAGON_DEFENDER_ORNAMENT_KIT, DRAGON_DEFENDER_T),
ITEM_DRAGON_PICKAXE(DRAGON_PICKAXE, DRAGON_PICKAXE_12797),
ITEM_DRAGON_KITESHIELD(DRAGON_KITESHIELD, DRAGON_KITESHIELD_G),
ITEM_DRAGON_KITESHIELD_ORNAMENT_KIT(DRAGON_KITESHIELD_ORNAMENT_KIT, DRAGON_KITESHIELD_G),
ITEM_DRAGON_FULL_HELM(DRAGON_FULL_HELM, DRAGON_FULL_HELM_G),
ITEM_DRAGON_FULL_HELM_ORNAMENT_KIT(DRAGON_FULL_HELM_ORNAMENT_KIT, DRAGON_FULL_HELM_G),
ITEM_DRAGON_CHAINBODY(DRAGON_CHAINBODY_3140, DRAGON_CHAINBODY_G),
ITEM_DRAGON_CHAINBODY_ORNAMENT_KIT(DRAGON_CHAINBODY_ORNAMENT_KIT, DRAGON_CHAINBODY_G),
ITEM_DRAGON_PLATEBODY(DRAGON_PLATEBODY, DRAGON_PLATEBODY_G),
ITEM_DRAGON_PLATEBODY_ORNAMENT_KIT(DRAGON_PLATEBODY_ORNAMENT_KIT, DRAGON_PLATEBODY_G),
ITEM_DRAGON_PLATESKIRT(DRAGON_PLATESKIRT, DRAGON_PLATESKIRT_G),
ITEM_DRAGON_SKIRT_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATESKIRT_G),
ITEM_DRAGON_PLATELEGS(DRAGON_PLATELEGS, DRAGON_PLATELEGS_G),
ITEM_DRAGON_LEGS_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATELEGS_G),
ITEM_DRAGON_SQ_SHIELD(DRAGON_SQ_SHIELD, DRAGON_SQ_SHIELD_G),
ITEM_DRAGON_SQ_SHIELD_ORNAMENT_KIT(DRAGON_SQ_SHIELD_ORNAMENT_KIT, DRAGON_SQ_SHIELD_G),
ITEM_DRAGON_BOOTS(DRAGON_BOOTS, DRAGON_BOOTS_G),
ITEM_DRAGON_BOOTS_ORNAMENT_KIT(DRAGON_BOOTS_ORNAMENT_KIT, DRAGON_BOOTS_G),
// Godsword ornament kits
ITEM_ARMADYL_GODSWORD(ARMADYL_GODSWORD, ARMADYL_GODSWORD_OR),
ITEM_ARMADYL_GODSWORD_ORNAMENT_KIT(ARMADYL_GODSWORD_ORNAMENT_KIT, ARMADYL_GODSWORD_OR),
ITEM_BANDOS_GODSWORD(BANDOS_GODSWORD, BANDOS_GODSWORD_OR),
ITEM_BANDOS_GODSWORD_ORNAMENT_KIT(BANDOS_GODSWORD_ORNAMENT_KIT, BANDOS_GODSWORD_OR),
ITEM_ZAMORAK_GODSWORD(ZAMORAK_GODSWORD, ZAMORAK_GODSWORD_OR),
ITEM_ZAMORAK_GODSWORD_ORNAMENT_KIT(ZAMORAK_GODSWORD_ORNAMENT_KIT, ZAMORAK_GODSWORD_OR),
ITEM_SARADOMIN_GODSWORD(SARADOMIN_GODSWORD, SARADOMIN_GODSWORD_OR),
ITEM_SARADOMIN_GODSWORD_ORNAMENT_KIT(SARADOMIN_GODSWORD_ORNAMENT_KIT, SARADOMIN_GODSWORD_OR),
// Jewellery ornament kits
ITEM_AMULET_OF_TORTURE(AMULET_OF_TORTURE, AMULET_OF_TORTURE_OR),
ITEM_TORTURE_ORNAMENT_KIT(TORTURE_ORNAMENT_KIT, AMULET_OF_TORTURE_OR),
ITEM_NECKLACE_OF_ANGUISH(NECKLACE_OF_ANGUISH, NECKLACE_OF_ANGUISH_OR),
ITEM_ANGUISH_ORNAMENT_KIT(ANGUISH_ORNAMENT_KIT, NECKLACE_OF_ANGUISH_OR),
ITEM_OCCULT_NECKLACE(OCCULT_NECKLACE, OCCULT_NECKLACE_OR),
ITEM_OCCULT_ORNAMENT_KIT(OCCULT_ORNAMENT_KIT, OCCULT_NECKLACE_OR),
ITE_AMULET_OF_FURY(AMULET_OF_FURY, AMULET_OF_FURY_OR),
ITE_FURY_ORNAMENT_KIT(FURY_ORNAMENT_KIT, AMULET_OF_FURY_OR),
// Ensouled heads
ITEM_ENSOULED_GOBLIN_HEAD(ENSOULED_GOBLIN_HEAD_13448, ENSOULED_GOBLIN_HEAD),
ITEM_ENSOULED_MONKEY_HEAD(ENSOULED_MONKEY_HEAD_13451, ENSOULED_MONKEY_HEAD),
ITEM_ENSOULED_IMP_HEAD(ENSOULED_IMP_HEAD_13454, ENSOULED_IMP_HEAD),
ITEM_ENSOULED_MINOTAUR_HEAD(ENSOULED_MINOTAUR_HEAD_13457, ENSOULED_MINOTAUR_HEAD),
ITEM_ENSOULED_SCORPION_HEAD(ENSOULED_SCORPION_HEAD_13460, ENSOULED_SCORPION_HEAD),
ITEM_ENSOULED_BEAR_HEAD(ENSOULED_BEAR_HEAD_13463, ENSOULED_BEAR_HEAD),
ITEM_ENSOULED_UNICORN_HEAD(ENSOULED_UNICORN_HEAD_13466, ENSOULED_UNICORN_HEAD),
ITEM_ENSOULED_DOG_HEAD(ENSOULED_DOG_HEAD_13469, ENSOULED_DOG_HEAD),
ITEM_ENSOULED_CHAOS_DRUID_HEAD(ENSOULED_CHAOS_DRUID_HEAD_13472, ENSOULED_CHAOS_DRUID_HEAD),
ITEM_ENSOULED_GIANT_HEAD(ENSOULED_GIANT_HEAD_13475, ENSOULED_GIANT_HEAD),
ITEM_ENSOULED_OGRE_HEAD(ENSOULED_OGRE_HEAD_13478, ENSOULED_OGRE_HEAD),
ITEM_ENSOULED_ELF_HEAD(ENSOULED_ELF_HEAD_13481, ENSOULED_ELF_HEAD),
ITEM_ENSOULED_TROLL_HEAD(ENSOULED_TROLL_HEAD_13484, ENSOULED_TROLL_HEAD),
ITEM_ENSOULED_HORROR_HEAD(ENSOULED_HORROR_HEAD_13487, ENSOULED_HORROR_HEAD),
ITEM_ENSOULED_KALPHITE_HEAD(ENSOULED_KALPHITE_HEAD_13490, ENSOULED_KALPHITE_HEAD),
ITEM_ENSOULED_DAGANNOTH_HEAD(ENSOULED_DAGANNOTH_HEAD_13493, ENSOULED_DAGANNOTH_HEAD),
ITEM_ENSOULED_BLOODVELD_HEAD(ENSOULED_BLOODVELD_HEAD_13496, ENSOULED_BLOODVELD_HEAD),
ITEM_ENSOULED_TZHAAR_HEAD(ENSOULED_TZHAAR_HEAD_13499, ENSOULED_TZHAAR_HEAD),
ITEM_ENSOULED_DEMON_HEAD(ENSOULED_DEMON_HEAD_13502, ENSOULED_DEMON_HEAD),
ITEM_ENSOULED_AVIANSIE_HEAD(ENSOULED_AVIANSIE_HEAD_13505, ENSOULED_AVIANSIE_HEAD),
ITEM_ENSOULED_ABYSSAL_HEAD(ENSOULED_ABYSSAL_HEAD_13508, ENSOULED_ABYSSAL_HEAD),
ITEM_ENSOULED_DRAGON_HEAD(ENSOULED_DRAGON_HEAD_13511, ENSOULED_DRAGON_HEAD),
// Imbued rings
ITEM_BERSERKER_RING(BERSERKER_RING, BERSERKER_RING_I),
ITEM_SEERS_RING(SEERS_RING, SEERS_RING_I),
ITEM_WARRIOR_RING(WARRIOR_RING, WARRIOR_RING_I),
ITEM_ARCHERS_RING(ARCHERS_RING, ARCHERS_RING_I),
ITEM_TREASONOUS_RING(TREASONOUS_RING, TREASONOUS_RING_I),
ITEM_TYRANNICAL_RING(TYRANNICAL_RING, TYRANNICAL_RING_I),
ITEM_RING_OF_THE_GODS(RING_OF_THE_GODS, RING_OF_THE_GODS_I),
ITEM_RING_OF_SUFFERING(RING_OF_SUFFERING, RING_OF_SUFFERING_I, RING_OF_SUFFERING_R, RING_OF_SUFFERING_RI),
ITEM_GRANITE_RING(GRANITE_RING, GRANITE_RING_I),
// Bounty hunter
ITEM_GRANITE_MAUL(GRANITE_MAUL, GRANITE_MAUL_12848),
ITEM_MAGIC_SHORTBOW(MAGIC_SHORTBOW, MAGIC_SHORTBOW_I),
ITEM_SARADOMINS_BLESSED_SWORD(SARADOMINS_TEAR, SARADOMINS_BLESSED_SWORD),
// Jewellery with charges
ITEM_RING_OF_WEALTH(RING_OF_WEALTH, RING_OF_WEALTH_I, RING_OF_WEALTH_1, RING_OF_WEALTH_I1, RING_OF_WEALTH_2, RING_OF_WEALTH_I2, RING_OF_WEALTH_3, RING_OF_WEALTH_I3, RING_OF_WEALTH_4, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5),
ITEM_AMULET_OF_GLORY(AMULET_OF_GLORY, AMULET_OF_GLORY1, AMULET_OF_GLORY2, AMULET_OF_GLORY3, AMULET_OF_GLORY5),
ITEM_AMULET_OF_GLORY_T(AMULET_OF_GLORY_T, AMULET_OF_GLORY_T1, AMULET_OF_GLORY_T2, AMULET_OF_GLORY_T3, AMULET_OF_GLORY_T5),
ITEM_SKILLS_NECKLACE(SKILLS_NECKLACE, SKILLS_NECKLACE1, SKILLS_NECKLACE2, SKILLS_NECKLACE3, SKILLS_NECKLACE5),
ITEM_RING_OF_DUELING(RING_OF_DUELING8, RING_OF_DUELING1, RING_OF_DUELING2, RING_OF_DUELING3, RING_OF_DUELING4, RING_OF_DUELING5, RING_OF_DUELING6, RING_OF_DUELING7),
ITEM_GAMES_NECKLACE(GAMES_NECKLACE8, GAMES_NECKLACE1, GAMES_NECKLACE2, GAMES_NECKLACE3, GAMES_NECKLACE4, GAMES_NECKLACE5, GAMES_NECKLACE6, GAMES_NECKLACE7),
// Degradable/charged weaponry/armour
ITEM_ABYSSAL_WHIP(ABYSSAL_WHIP, VOLCANIC_ABYSSAL_WHIP, FROZEN_ABYSSAL_WHIP),
ITEM_KRAKEN_TENTACLE(KRAKEN_TENTACLE, ABYSSAL_TENTACLE),
ITEM_TRIDENT_OF_THE_SEAS(UNCHARGED_TRIDENT, TRIDENT_OF_THE_SEAS),
ITEM_TRIDENT_OF_THE_SEAS_E(UNCHARGED_TRIDENT_E, TRIDENT_OF_THE_SEAS_E),
ITEM_TRIDENT_OF_THE_SWAMP(UNCHARGED_TOXIC_TRIDENT, TRIDENT_OF_THE_SWAMP),
ITEM_TRIDENT_OF_THE_SWAMP_E(UNCHARGED_TOXIC_TRIDENT_E, TRIDENT_OF_THE_SWAMP_E),
ITEM_TOXIC_BLOWPIPE(TOXIC_BLOWPIPE_EMPTY, TOXIC_BLOWPIPE),
ITEM_TOXIC_STAFF_OFF_THE_DEAD(TOXIC_STAFF_UNCHARGED, TOXIC_STAFF_OF_THE_DEAD),
ITEM_SERPENTINE_HELM(SERPENTINE_HELM_UNCHARGED, SERPENTINE_HELM, TANZANITE_HELM_UNCHARGED, TANZANITE_HELM, MAGMA_HELM_UNCHARGED, MAGMA_HELM),
ITEM_DRAGONFIRE_SHIELD(DRAGONFIRE_SHIELD_11284, DRAGONFIRE_SHIELD),
ITEM_DRAGONFIRE_WARD(DRAGONFIRE_WARD_22003, DRAGONFIRE_WARD),
ITEM_ANCIENT_WYVERN_SHIELD(ANCIENT_WYVERN_SHIELD_21634, ANCIENT_WYVERN_SHIELD),
ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF),
ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR),
ITEM_TOME_OF_FIRE(TOME_OF_FIRE_EMPTY, TOME_OF_FIRE),
ITEM_CRAWS_BOW(CRAWS_BOW_U, CRAWS_BOW),
ITEM_VIGGORAS_CHAINMACE(VIGGORAS_CHAINMACE_U, VIGGORAS_CHAINMACE),
ITEM_THAMMARONS_SCEPTRE(THAMMARONS_SCEPTRE_U, THAMMARONS_SCEPTRE),
// Infinity colour kits
ITEM_INFINITY_TOP(INFINITY_TOP, INFINITY_TOP_10605, INFINITY_TOP_20574, DARK_INFINITY_TOP, LIGHT_INFINITY_TOP),
ITEM_INFINITY_TOP_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_TOP),
ITEM_INFINITY_TOP_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_TOP),
ITEM_INFINITY_BOTTOMS(INFINITY_BOTTOMS, INFINITY_BOTTOMS_20575, DARK_INFINITY_BOTTOMS, LIGHT_INFINITY_BOTTOMS),
ITEM_INFINITY_BOTTOMS_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_BOTTOMS),
ITEM_INFINITY_BOTTOMS_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_BOTTOMS),
ITEM_INFINITY_HAT(INFINITY_HAT, DARK_INFINITY_HAT, LIGHT_INFINITY_HAT),
ITEM_INFINITY_HAT_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_HAT),
ITEM_INFINITY_HAT_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_HAT),
// Miscellaneous ornament kits
ITEM_DARK_BOW(DARK_BOW, DARK_BOW_12765, DARK_BOW_12766, DARK_BOW_12767, DARK_BOW_12768, DARK_BOW_20408),
ITEM_ODIUM_WARD(ODIUM_WARD, ODIUM_WARD_12807),
ITEM_MALEDICTION_WARD(MALEDICTION_WARD, MALEDICTION_WARD_12806),
ITEM_STEAM_BATTLESTAFF(STEAM_BATTLESTAFF, STEAM_BATTLESTAFF_12795),
ITEM_LAVA_BATTLESTAFF(LAVA_BATTLESTAFF, LAVA_BATTLESTAFF_21198),
// Slayer helm/black mask
ITEM_BLACK_MASK(
BLACK_MASK, BLACK_MASK_I, BLACK_MASK_1, BLACK_MASK_1_I, BLACK_MASK_2, BLACK_MASK_2_I, BLACK_MASK_3, BLACK_MASK_3_I, BLACK_MASK_4, BLACK_MASK_4_I, BLACK_MASK_5,
BLACK_MASK_5_I, BLACK_MASK_6, BLACK_MASK_6_I, BLACK_MASK_7, BLACK_MASK_7_I, BLACK_MASK_8, BLACK_MASK_8_I, BLACK_MASK_9, BLACK_MASK_9_I, BLACK_MASK_10_I,
SLAYER_HELMET, SLAYER_HELMET_I, BLACK_SLAYER_HELMET, BLACK_SLAYER_HELMET_I, PURPLE_SLAYER_HELMET, PURPLE_SLAYER_HELMET_I, RED_SLAYER_HELMET, RED_SLAYER_HELMET_I,
GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I, HYDRA_SLAYER_HELMET, HYDRA_SLAYER_HELMET_I),
// Pharaoh's Sceptres
ITEM_PHARAOHS_SCEPTRE_1(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_1),
ITEM_PHARAOHS_SCEPTRE_2(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_2),
ITEM_PHARAOHS_SCEPTRE_4(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_4),
ITEM_PHARAOHS_SCEPTRE_5(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_5),
ITEM_PHARAOHS_SCEPTRE_6(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_6),
ITEM_PHARAOHS_SCEPTRE_7(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_7),
ITEM_PHARAOHS_SCEPTRE_8(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_8),
// Revertible items
ITEM_HYDRA_LEATHER(HYDRA_LEATHER, FEROCIOUS_GLOVES),
ITEM_HYDRA_TAIL(HYDRA_TAIL, BONECRUSHER_NECKLACE),
ITEM_DRAGONBONE_NECKLACE(DRAGONBONE_NECKLACE, BONECRUSHER_NECKLACE),
ITEM_BOTTOMLESS_COMPOST_BUCKET(BOTTOMLESS_COMPOST_BUCKET, BOTTOMLESS_COMPOST_BUCKET_22997);
private static final Multimap<Integer, Integer> MAPPINGS = HashMultimap.create();
private final int tradeableItem;
private final int[] untradableItems;
static
{
for (final ItemMapping item : values())
{
for (int itemId : item.untradableItems)
{
MAPPINGS.put(itemId, item.tradeableItem);
}
}
}
ItemMapping(int tradeableItem, int... untradableItems)
{
this.tradeableItem = tradeableItem;
this.untradableItems = untradableItems;
}
/**
* Get collection of items that are mapped from single item id.
*
* @param itemId the item id
* @return the collection
*/
public static Collection<Integer> map(int itemId)
{
final Collection<Integer> mapping = MAPPINGS.get(itemId);
if (mapping == null || mapping.isEmpty())
{
return Collections.singleton(itemId);
}
return mapping;
}
/**
* Map an item from its untradeable version to its tradeable version
*
* @param itemId
* @return
*/
public static int mapFirst(int itemId)
{
final Collection<Integer> mapping = MAPPINGS.get(itemId);
if (mapping == null || mapping.isEmpty())
{
return itemId;
}
return mapping.iterator().next();
}
}

View File

@@ -1,65 +1,66 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.game; package net.runelite.client.game;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@Singleton @Singleton
public class NPCManager public class NPCManager
{ {
private final Map<String, Integer> healthMap; private final Map<String, Integer> healthMap;
@Inject @Inject
private NPCManager() private NPCManager()
{ {
final Gson gson = new Gson(); final Gson gson = new Gson();
final Type typeToken = new TypeToken<Map<String, Integer>>() final Type typeToken = new TypeToken<Map<String, Integer>>()
{ {
}.getType(); }.getType();
final InputStream healthFile = getClass().getResourceAsStream("/npc_health.json"); final InputStream healthFile = getClass().getResourceAsStream("/npc_health.json");
healthMap = gson.fromJson(new InputStreamReader(healthFile), typeToken); healthMap = gson.fromJson(new InputStreamReader(healthFile), typeToken);
} }
/** /**
* Returns health for target NPC based on it's combat level and name * Returns health for target NPC based on it's combat level and name
* @param name npc name *
* @param combatLevel npc combat level * @param name npc name
* @return health or null if HP is unknown * @param combatLevel npc combat level
*/ * @return health or null if HP is unknown
@Nullable */
public Integer getHealth(final String name, final int combatLevel) @Nullable
{ public Integer getHealth(final String name, final int combatLevel)
return healthMap.get(name + "_" + combatLevel); {
} return healthMap.get(name + "_" + combatLevel);
} }
}

View File

@@ -1,202 +1,202 @@
/* /*
* Copyright (c) 2018 Abex * Copyright (c) 2018 Abex
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.game.chatbox; package net.runelite.client.game.chatbox;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.ScriptID; import net.runelite.api.ScriptID;
import net.runelite.api.VarClientInt; import net.runelite.api.VarClientInt;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.vars.InputType; import net.runelite.api.vars.InputType;
import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseListener; import net.runelite.client.input.MouseListener;
import net.runelite.client.input.MouseManager; import net.runelite.client.input.MouseManager;
import net.runelite.client.input.MouseWheelListener; import net.runelite.client.input.MouseWheelListener;
@Singleton @Singleton
@Slf4j @Slf4j
public class ChatboxPanelManager public class ChatboxPanelManager
{ {
private final Client client; private final Client client;
private final ClientThread clientThread; private final ClientThread clientThread;
private final EventBus eventBus; private final EventBus eventBus;
private final KeyManager keyManager; private final KeyManager keyManager;
private final MouseManager mouseManager; private final MouseManager mouseManager;
private final Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider; private final Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider;
private final Provider<ChatboxTextInput> chatboxTextInputProvider; private final Provider<ChatboxTextInput> chatboxTextInputProvider;
@Getter @Getter
private ChatboxInput currentInput = null; private ChatboxInput currentInput = null;
@Inject @Inject
private ChatboxPanelManager(EventBus eventBus, Client client, ClientThread clientThread, private ChatboxPanelManager(EventBus eventBus, Client client, ClientThread clientThread,
KeyManager keyManager, MouseManager mouseManager, KeyManager keyManager, MouseManager mouseManager,
Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider, Provider<ChatboxTextInput> chatboxTextInputProvider) Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider, Provider<ChatboxTextInput> chatboxTextInputProvider)
{ {
this.client = client; this.client = client;
this.clientThread = clientThread; this.clientThread = clientThread;
this.eventBus = eventBus; this.eventBus = eventBus;
this.keyManager = keyManager; this.keyManager = keyManager;
this.mouseManager = mouseManager; this.mouseManager = mouseManager;
this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider; this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider;
this.chatboxTextInputProvider = chatboxTextInputProvider; this.chatboxTextInputProvider = chatboxTextInputProvider;
} }
public void close() public void close()
{ {
clientThread.invokeLater(this::unsafeCloseInput); clientThread.invokeLater(this::unsafeCloseInput);
} }
private void unsafeCloseInput() private void unsafeCloseInput()
{ {
client.runScript( client.runScript(
ScriptID.RESET_CHATBOX_INPUT, ScriptID.RESET_CHATBOX_INPUT,
0, 0,
1 1
); );
if (currentInput != null) if (currentInput != null)
{ {
killCurrentPanel(); killCurrentPanel();
} }
} }
private void unsafeOpenInput(ChatboxInput input) private void unsafeOpenInput(ChatboxInput input)
{ {
client.runScript(ScriptID.CLEAR_CHATBOX_PANEL); client.runScript(ScriptID.CLEAR_CHATBOX_PANEL);
eventBus.register(input); eventBus.register(input);
if (input instanceof KeyListener) if (input instanceof KeyListener)
{ {
keyManager.registerKeyListener((KeyListener) input); keyManager.registerKeyListener((KeyListener) input);
} }
if (input instanceof MouseListener) if (input instanceof MouseListener)
{ {
mouseManager.registerMouseListener((MouseListener) input); mouseManager.registerMouseListener((MouseListener) input);
} }
if (input instanceof MouseWheelListener) if (input instanceof MouseWheelListener)
{ {
mouseManager.registerMouseWheelListener((MouseWheelListener) input); mouseManager.registerMouseWheelListener((MouseWheelListener) input);
} }
if (currentInput != null) if (currentInput != null)
{ {
killCurrentPanel(); killCurrentPanel();
} }
currentInput = input; currentInput = input;
client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType()); client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType());
client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true); client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true);
client.getWidget(WidgetInfo.CHATBOX_FULL_INPUT).setHidden(true); client.getWidget(WidgetInfo.CHATBOX_FULL_INPUT).setHidden(true);
Widget c = getContainerWidget(); Widget c = getContainerWidget();
c.deleteAllChildren(); c.deleteAllChildren();
c.setOnDialogAbortListener((JavaScriptCallback) ev -> this.unsafeCloseInput()); c.setOnDialogAbortListener((JavaScriptCallback) ev -> this.unsafeCloseInput());
input.open(); input.open();
} }
public void openInput(ChatboxInput input) public void openInput(ChatboxInput input)
{ {
clientThread.invokeLater(() -> unsafeOpenInput(input)); clientThread.invokeLater(() -> unsafeOpenInput(input));
} }
public ChatboxTextMenuInput openTextMenuInput(String title) public ChatboxTextMenuInput openTextMenuInput(String title)
{ {
return chatboxTextMenuInputProvider.get() return chatboxTextMenuInputProvider.get()
.title(title); .title(title);
} }
public ChatboxTextInput openTextInput(String prompt) public ChatboxTextInput openTextInput(String prompt)
{ {
return chatboxTextInputProvider.get() return chatboxTextInputProvider.get()
.prompt(prompt); .prompt(prompt);
} }
@Subscribe @Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent ev) public void onScriptCallbackEvent(ScriptCallbackEvent ev)
{ {
if (currentInput != null && "resetChatboxInput".equals(ev.getEventName())) if (currentInput != null && "resetChatboxInput".equals(ev.getEventName()))
{ {
killCurrentPanel(); killCurrentPanel();
} }
} }
@Subscribe @Subscribe
private void onGameStateChanged(GameStateChanged ev) private void onGameStateChanged(GameStateChanged ev)
{ {
if (currentInput != null && ev.getGameState() == GameState.LOGIN_SCREEN) if (currentInput != null && ev.getGameState() == GameState.LOGIN_SCREEN)
{ {
killCurrentPanel(); killCurrentPanel();
} }
} }
private void killCurrentPanel() private void killCurrentPanel()
{ {
try try
{ {
currentInput.close(); currentInput.close();
} }
catch (Exception e) catch (Exception e)
{ {
log.warn("Exception closing {}", currentInput.getClass(), e); log.warn("Exception closing {}", currentInput.getClass(), e);
} }
eventBus.unregister(currentInput); eventBus.unregister(currentInput);
if (currentInput instanceof KeyListener) if (currentInput instanceof KeyListener)
{ {
keyManager.unregisterKeyListener((KeyListener) currentInput); keyManager.unregisterKeyListener((KeyListener) currentInput);
} }
if (currentInput instanceof MouseListener) if (currentInput instanceof MouseListener)
{ {
mouseManager.unregisterMouseListener((MouseListener) currentInput); mouseManager.unregisterMouseListener((MouseListener) currentInput);
} }
if (currentInput instanceof MouseWheelListener) if (currentInput instanceof MouseWheelListener)
{ {
mouseManager.unregisterMouseWheelListener((MouseWheelListener) currentInput); mouseManager.unregisterMouseWheelListener((MouseWheelListener) currentInput);
} }
currentInput = null; currentInput = null;
} }
public Widget getContainerWidget() public Widget getContainerWidget()
{ {
return client.getWidget(WidgetInfo.CHATBOX_CONTAINER); return client.getWidget(WidgetInfo.CHATBOX_CONTAINER);
} }
} }

View File

@@ -1,213 +1,213 @@
/* /*
* Copyright (c) 2018 Abex * Copyright (c) 2018 Abex
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.game.chatbox; package net.runelite.client.game.chatbox;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.FontID; import net.runelite.api.FontID;
import net.runelite.api.widgets.WidgetType; import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetSizeMode; import net.runelite.api.widgets.WidgetTextAlignment;
import net.runelite.api.widgets.WidgetTextAlignment; import net.runelite.api.widgets.WidgetType;
import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyListener;
@Slf4j @Slf4j
public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener
{ {
@Data @Data
@AllArgsConstructor @AllArgsConstructor
private static final class Entry private static final class Entry
{ {
private String text; private String text;
private Runnable callback; private Runnable callback;
} }
private final ChatboxPanelManager chatboxPanelManager; private final ChatboxPanelManager chatboxPanelManager;
@Getter @Getter
private String title; private String title;
@Getter @Getter
private List<Entry> options = new ArrayList<>(); private List<Entry> options = new ArrayList<>();
@Getter @Getter
private Runnable onClose; private Runnable onClose;
@Inject @Inject
protected ChatboxTextMenuInput(ChatboxPanelManager chatboxPanelManager) protected ChatboxTextMenuInput(ChatboxPanelManager chatboxPanelManager)
{ {
this.chatboxPanelManager = chatboxPanelManager; this.chatboxPanelManager = chatboxPanelManager;
} }
public ChatboxTextMenuInput title(String title) public ChatboxTextMenuInput title(String title)
{ {
this.title = title; this.title = title;
return this; return this;
} }
public ChatboxTextMenuInput option(String text, Runnable callback) public ChatboxTextMenuInput option(String text, Runnable callback)
{ {
options.add(new Entry(text, callback)); options.add(new Entry(text, callback));
return this; return this;
} }
public ChatboxTextMenuInput onClose(Runnable onClose) public ChatboxTextMenuInput onClose(Runnable onClose)
{ {
this.onClose = onClose; this.onClose = onClose;
return this; return this;
} }
public ChatboxTextMenuInput build() public ChatboxTextMenuInput build()
{ {
if (title == null) if (title == null)
{ {
throw new IllegalStateException("Title must be set"); throw new IllegalStateException("Title must be set");
} }
if (options.size() < 1) if (options.size() < 1)
{ {
throw new IllegalStateException("You must have atleast 1 option"); throw new IllegalStateException("You must have atleast 1 option");
} }
chatboxPanelManager.openInput(this); chatboxPanelManager.openInput(this);
return this; return this;
} }
@Override @Override
protected void open() protected void open()
{ {
Widget container = chatboxPanelManager.getContainerWidget(); Widget container = chatboxPanelManager.getContainerWidget();
Widget prompt = container.createChild(-1, WidgetType.TEXT); Widget prompt = container.createChild(-1, WidgetType.TEXT);
prompt.setText(title); prompt.setText(title);
prompt.setTextColor(0x800000); prompt.setTextColor(0x800000);
prompt.setFontId(FontID.QUILL_8); prompt.setFontId(FontID.QUILL_8);
prompt.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER); prompt.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
prompt.setOriginalX(0); prompt.setOriginalX(0);
prompt.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP); prompt.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
prompt.setOriginalY(8); prompt.setOriginalY(8);
prompt.setOriginalHeight(24); prompt.setOriginalHeight(24);
prompt.setXTextAlignment(WidgetTextAlignment.CENTER); prompt.setXTextAlignment(WidgetTextAlignment.CENTER);
prompt.setYTextAlignment(WidgetTextAlignment.CENTER); prompt.setYTextAlignment(WidgetTextAlignment.CENTER);
prompt.setWidthMode(WidgetSizeMode.MINUS); prompt.setWidthMode(WidgetSizeMode.MINUS);
prompt.revalidate(); prompt.revalidate();
int y = prompt.getRelativeX() + prompt.getHeight() + 6; int y = prompt.getRelativeX() + prompt.getHeight() + 6;
int height = container.getHeight() - y - 8; int height = container.getHeight() - y - 8;
int step = height / options.size(); int step = height / options.size();
int maxStep = options.size() >= 3 ? 25 : 30; int maxStep = options.size() >= 3 ? 25 : 30;
if (step > maxStep) if (step > maxStep)
{ {
int ds = step - maxStep; int ds = step - maxStep;
step = maxStep; step = maxStep;
y += (ds * options.size()) / 2; y += (ds * options.size()) / 2;
} }
for (Entry option : options) for (Entry option : options)
{ {
Widget optWidget = container.createChild(-1, WidgetType.TEXT); Widget optWidget = container.createChild(-1, WidgetType.TEXT);
optWidget.setText(option.text); optWidget.setText(option.text);
optWidget.setFontId(FontID.QUILL_8); optWidget.setFontId(FontID.QUILL_8);
optWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER); optWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
optWidget.setOriginalX(0); optWidget.setOriginalX(0);
optWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP); optWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
optWidget.setOriginalY(y); optWidget.setOriginalY(y);
optWidget.setOriginalHeight(24); optWidget.setOriginalHeight(24);
optWidget.setXTextAlignment(WidgetTextAlignment.CENTER); optWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
optWidget.setYTextAlignment(WidgetTextAlignment.CENTER); optWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
optWidget.setWidthMode(WidgetSizeMode.MINUS); optWidget.setWidthMode(WidgetSizeMode.MINUS);
optWidget.setAction(0, "Continue"); optWidget.setAction(0, "Continue");
optWidget.setOnOpListener((JavaScriptCallback) ev -> callback(option)); optWidget.setOnOpListener((JavaScriptCallback) ev -> callback(option));
optWidget.setOnMouseOverListener((JavaScriptCallback) ev -> optWidget.setTextColor(0xFFFFFF)); optWidget.setOnMouseOverListener((JavaScriptCallback) ev -> optWidget.setTextColor(0xFFFFFF));
optWidget.setOnMouseLeaveListener((JavaScriptCallback) ev -> optWidget.setTextColor(0)); optWidget.setOnMouseLeaveListener((JavaScriptCallback) ev -> optWidget.setTextColor(0));
optWidget.setHasListener(true); optWidget.setHasListener(true);
optWidget.revalidate(); optWidget.revalidate();
y += step; y += step;
} }
} }
private void callback(Entry entry) private void callback(Entry entry)
{ {
Widget container = chatboxPanelManager.getContainerWidget(); Widget container = chatboxPanelManager.getContainerWidget();
container.setOnKeyListener((Object[]) null); container.setOnKeyListener((Object[]) null);
chatboxPanelManager.close(); chatboxPanelManager.close();
entry.callback.run(); entry.callback.run();
} }
@Override @Override
protected void close() protected void close()
{ {
if (onClose != null) if (onClose != null)
{ {
onClose.run(); onClose.run();
} }
} }
@Override @Override
public void keyTyped(KeyEvent e) public void keyTyped(KeyEvent e)
{ {
char c = e.getKeyChar(); char c = e.getKeyChar();
if (c == '\033') if (c == '\033')
{ {
chatboxPanelManager.close(); chatboxPanelManager.close();
e.consume(); e.consume();
return; return;
} }
int n = c - '1'; int n = c - '1';
if (n >= 0 && n < options.size()) if (n >= 0 && n < options.size())
{ {
callback(options.get(n)); callback(options.get(n));
e.consume(); e.consume();
} }
} }
@Override @Override
public void keyPressed(KeyEvent e) public void keyPressed(KeyEvent e)
{ {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
{ {
e.consume(); e.consume();
} }
} }
@Override @Override
public void keyReleased(KeyEvent e) public void keyReleased(KeyEvent e)
{ {
} }
} }

View File

@@ -743,7 +743,7 @@ public class ModelOutlineRenderer
* @param outerColor The color of the pixels of the outline furthest away from the model * @param outerColor The color of the pixels of the outline furthest away from the model
*/ */
private void renderOutline(BufferedImage image, int outlineWidth, private void renderOutline(BufferedImage image, int outlineWidth,
Color innerColor, Color outerColor) Color innerColor, Color outerColor)
{ {
int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
List<PixelDistanceAlpha> ps = getPriorityList(outlineWidth); List<PixelDistanceAlpha> ps = getPriorityList(outlineWidth);
@@ -887,8 +887,8 @@ public class ModelOutlineRenderer
* @param outerColor The color of the pixels of the outline furthest away from the model * @param outerColor The color of the pixels of the outline furthest away from the model
*/ */
private void drawModelOutline(Model model, private void drawModelOutline(Model model,
int localX, int localY, int localZ, int orientation, int localX, int localY, int localZ, int orientation,
int outlineWidth, Color innerColor, Color outerColor) int outlineWidth, Color innerColor, Color outerColor)
{ {
if (outlineWidth <= 0) if (outlineWidth <= 0)
{ {

View File

@@ -0,0 +1,102 @@
package net.runelite.client.menus;
import joptsimple.internal.Strings;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import net.runelite.api.MenuEntry;
import static net.runelite.client.menus.MenuManager.LEVEL_PATTERN;
import net.runelite.client.util.Text;
@EqualsAndHashCode
public class AbstractMenuEntry
{
@Getter
private String option;
@Getter
private String target;
@Getter
private int id;
@Getter
private int type;
@Getter
private boolean strictOption;
@Getter
private boolean strictTarget;
public AbstractMenuEntry(String option, String target)
{
this(option, target, -1, -1, true, true);
}
public AbstractMenuEntry(String option, String target, boolean strictTarget)
{
this(option, target, -1, -1, true, strictTarget);
}
public AbstractMenuEntry(String option, String target, int id, int type, boolean strictOption, boolean strictTarget)
{
this.option = option;
this.target = target;
this.id = id;
this.type = type;
this.strictOption = strictOption;
this.strictTarget = strictTarget;
}
boolean matches(MenuEntry entry)
{
String opt = Text.standardize(entry.getOption());
if (strictOption && !opt.equals(option) || !strictOption && !opt.contains(option))
{
return false;
}
if (strictTarget || !Strings.isNullOrEmpty(target))
{
String tgt = Text.standardize(LEVEL_PATTERN.matcher(entry.getTarget()).replaceAll(""));
if (strictTarget && !tgt.equals(target) || !strictTarget && !tgt.contains(target))
{
return false;
}
}
if (id != -1)
{
int id = entry.getIdentifier();
if (this.id != id)
{
return false;
}
}
if (type != -1)
{
int type = entry.getType();
if (this.type != type)
{
return false;
}
}
return true;
}
/*boolean equals(AbstractMenuEntry other)
{
return target.equals(other.getTarget())
&& option.equals(other.getOption())
&& id == other.getId()
&& type == other.getType()
&& strictOption == other.isStrictOption()
&& strictTarget == other.isStrictTarget();
}*/
}

View File

@@ -26,13 +26,17 @@ package net.runelite.client.menus;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -60,6 +64,20 @@ public class MenuManager
*/ */
private static final int IDX_LOWER = 4; private static final int IDX_LOWER = 4;
private static final int IDX_UPPER = 8; private static final int IDX_UPPER = 8;
static final Pattern LEVEL_PATTERN = Pattern.compile("\\(level-[0-9]*\\)");
private static MenuEntry CANCEL()
{
MenuEntry cancel = new MenuEntry();
cancel.setOption("Cancel");
cancel.setTarget("");
cancel.setIdentifier(0);
cancel.setType(MenuAction.CANCEL.getId());
cancel.setParam0(0);
cancel.setParam1(0);
return cancel;
}
private final Client client; private final Client client;
private final EventBus eventBus; private final EventBus eventBus;
@@ -70,6 +88,11 @@ public class MenuManager
private final Multimap<Integer, WidgetMenuOption> managedMenuOptions = HashMultimap.create(); private final Multimap<Integer, WidgetMenuOption> managedMenuOptions = HashMultimap.create();
private final Set<String> npcMenuOptions = new HashSet<>(); private final Set<String> npcMenuOptions = new HashSet<>();
private final Set<AbstractMenuEntry> priorityEntries = new HashSet<>();
private final Set<MenuEntry> currentPriorityEntries = new HashSet<>();
private final Map<AbstractMenuEntry, AbstractMenuEntry> swaps = new HashMap<>();
@Inject @Inject
private MenuManager(Client client, EventBus eventBus) private MenuManager(Client client, EventBus eventBus)
{ {
@@ -119,12 +142,18 @@ public class MenuManager
{ {
int widgetId = event.getActionParam1(); int widgetId = event.getActionParam1();
Collection<WidgetMenuOption> options = managedMenuOptions.get(widgetId); Collection<WidgetMenuOption> options = managedMenuOptions.get(widgetId);
MenuEntry[] menuEntries = client.getMenuEntries();
if (menuEntries.length == 1)
{
// Menu entries reset, so priority entries should reset as well
currentPriorityEntries.clear();
}
for (WidgetMenuOption currentMenu : options) for (WidgetMenuOption currentMenu : options)
{ {
if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget
{ {
MenuEntry[] menuEntries = client.getMenuEntries();
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry();
@@ -136,6 +165,74 @@ public class MenuManager
client.setMenuEntries(menuEntries); client.setMenuEntries(menuEntries);
} }
} }
MenuEntry newestEntry = menuEntries[menuEntries.length - 1];
boolean isPrio = false;
for (AbstractMenuEntry p : priorityEntries)
{
if (p.matches(newestEntry))
{
isPrio = true;
break;
}
}
// If the last entry was a priority entry, keep track of it
if (isPrio)
{
currentPriorityEntries.add(newestEntry);
}
// Make a copy of the menu entries, cause you can't remove from Arrays.asList()
List<MenuEntry> copy = new ArrayList<>(Arrays.asList(menuEntries));
// If there are entries we want to prioritize, we have to remove the rest
if (!currentPriorityEntries.isEmpty())
{
copy.retainAll(currentPriorityEntries);
copy.add(CANCEL());
}
// Find the current entry in the swaps map
AbstractMenuEntry swapEntry = null;
for (AbstractMenuEntry e : swaps.keySet())
{
if (e.matches(newestEntry))
{
swapEntry = e;
break;
}
}
if (swapEntry != null)
{
AbstractMenuEntry swapTarget = swaps.get(swapEntry);
// Find the target for the swap in current menu entries
MenuEntry foundSwap = null;
for (MenuEntry entry : Lists.reverse(copy))
{
if (swapTarget.matches(entry))
{
foundSwap = entry;
break;
}
}
if (foundSwap != null)
{
// Swap
int index = copy.indexOf(foundSwap);
int newIndex = copy.indexOf(newestEntry);
copy.set(index, newestEntry);
copy.set(newIndex, foundSwap);
}
}
client.setMenuEntries(copy.toArray(new MenuEntry[0]));
} }
public void addPlayerMenuItem(String menuText) public void addPlayerMenuItem(String menuText)
@@ -307,4 +404,142 @@ public class MenuManager
return index; return index;
} }
/**
* Adds to the set of menu entries which when present, will remove all entries except for this one
*/
public void addPriorityEntry(String option, String target)
{
option = Text.standardize(option);
target = Text.standardize(target);
AbstractMenuEntry entry = new AbstractMenuEntry(option, target);
priorityEntries.add(entry);
}
public void removePriorityEntry(String option, String target)
{
option = Text.standardize(option);
target = Text.standardize(target);
AbstractMenuEntry entry = new AbstractMenuEntry(option, target);
Set<AbstractMenuEntry> toRemove = new HashSet<>();
for (AbstractMenuEntry priorityEntry : priorityEntries)
{
if (entry.equals(priorityEntry))
{
toRemove.add(entry);
}
}
for (AbstractMenuEntry e : toRemove)
{
priorityEntries.remove(e);
}
}
/**
* Adds to the set of menu entries which when present, will remove all entries except for this one
* This method will add one with strict option, but not-strict target (contains for target, equals for option)
*/
public void addPriorityEntry(String option)
{
option = Text.standardize(option);
AbstractMenuEntry entry = new AbstractMenuEntry(option, "", false);
priorityEntries.add(entry);
}
public void removePriorityEntry(String option)
{
option = Text.standardize(option);
AbstractMenuEntry entry = new AbstractMenuEntry(option, "", false);
Set<AbstractMenuEntry> toRemove = new HashSet<>();
for (AbstractMenuEntry priorityEntry : priorityEntries)
{
if (entry.equals(priorityEntry))
{
toRemove.add(entry);
}
}
for (AbstractMenuEntry e : toRemove)
{
priorityEntries.remove(e);
}
}
/**
* Adds to the map of swaps. - Strict option + target
*/
public void addSwap(String option, String target, String option2, String target2)
{
option = Text.standardize(option);
target = Text.standardize(target);
option2 = Text.standardize(option2);
target2 = Text.standardize(target2);
AbstractMenuEntry swapFrom = new AbstractMenuEntry(option, target);
AbstractMenuEntry swapTo = new AbstractMenuEntry(option2, target2);
if (swapTo.equals(swapFrom))
{
log.warn("You shouldn't try swapping an entry for itself");
return;
}
swaps.put(swapFrom, swapTo);
}
/**
* Adds to the map of swaps - Pre-baked Abstract entry
*/
public void addSwap(AbstractMenuEntry swapFrom, AbstractMenuEntry swapTo)
{
if (swapTo.equals(swapFrom))
{
log.warn("You shouldn't try swapping an entry for itself");
return;
}
swaps.put(swapFrom, swapTo);
}
public void removeSwap(String option, String target, String option2, String target2)
{
option = Text.standardize(option);
target = Text.standardize(target);
option2 = Text.standardize(option2);
target2 = Text.standardize(target2);
AbstractMenuEntry swapFrom = new AbstractMenuEntry(option, target);
AbstractMenuEntry swapTo = new AbstractMenuEntry(option2, target2);
removeSwap(swapFrom, swapTo);
}
public void removeSwap(AbstractMenuEntry swapFrom, AbstractMenuEntry swapTo)
{
Set<AbstractMenuEntry> toRemove = new HashSet<>();
for (Map.Entry<AbstractMenuEntry, AbstractMenuEntry> e : swaps.entrySet())
{
if (e.getKey().equals(swapFrom) && e.getValue().equals(swapTo))
{
toRemove.add(e.getKey());
}
}
for (AbstractMenuEntry entry : toRemove)
{
swaps.remove(entry);
}
}
} }

View File

@@ -1,106 +1,105 @@
/* /*
* Copyright (c) 2017, Robin <robin.weymans@gmail.com> * Copyright (c) 2017, Robin <robin.weymans@gmail.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.menus; package net.runelite.client.menus;
import net.runelite.api.widgets.WidgetInfo; import java.awt.Color;
import net.runelite.api.widgets.WidgetInfo;
import java.awt.Color; import net.runelite.client.ui.JagexColors;
import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.ColorUtil;
public final class WidgetMenuOption
public final class WidgetMenuOption {
{ /**
/** * The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop"
* The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop" */
*/ private String menuOption;
private String menuOption; /**
/** * The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones"
* The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones" */
*/ private String menuTarget;
private String menuTarget; /**
/** * The color that the menuTarget should be. Defaults to the brownish color that most menu options have.
* The color that the menuTarget should be. Defaults to the brownish color that most menu options have. */
*/ private Color color = JagexColors.MENU_TARGET;
private Color color = JagexColors.MENU_TARGET;
/**
/** * The widget to add the option to
* The widget to add the option to */
*/ private final WidgetInfo widget;
private final WidgetInfo widget;
/**
/** * Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options
* Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options *
* * @param menuOption Option text of this right click option
* @param menuOption Option text of this right click option * @param menuTarget Target text of this right click option
* @param menuTarget Target text of this right click option * @param widget The widget to attach this option to
* @param widget The widget to attach this option to */
*/ public WidgetMenuOption(String menuOption, String menuTarget, WidgetInfo widget)
public WidgetMenuOption(String menuOption, String menuTarget, WidgetInfo widget) {
{ this.menuOption = menuOption;
this.menuOption = menuOption; setMenuTarget(menuTarget);
setMenuTarget(menuTarget); this.widget = widget;
this.widget = widget; }
}
public void setMenuOption(String option)
public void setMenuOption(String option) {
{ menuOption = option;
menuOption = option; }
}
/**
/** * Sets the target of the menu option. Color code will be added on to target
* Sets the target of the menu option. Color code will be added on to target *
* * @param target The target text without color code.
* @param target The target text without color code. */
*/ public void setMenuTarget(String target)
public void setMenuTarget(String target) {
{ menuTarget = ColorUtil.wrapWithColorTag(target, color);
menuTarget = ColorUtil.wrapWithColorTag(target, color); }
}
public String getMenuOption()
public String getMenuOption() {
{ return menuOption;
return menuOption; }
}
public String getMenuTarget()
public String getMenuTarget() {
{ return menuTarget;
return menuTarget; }
}
public WidgetInfo getWidget()
public WidgetInfo getWidget() {
{ return widget;
return widget; }
}
public Color getColor()
public Color getColor() {
{ return color;
return color; }
}
public void setColor(Color col)
public void setColor(Color col) {
{ color = col;
color = col; }
} }
}

View File

@@ -1,57 +1,56 @@
/* /*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info> * Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins; package net.runelite.client.plugins;
import com.google.inject.Binder; import com.google.inject.Binder;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
import java.io.File;
import java.io.File;
public abstract class Plugin implements Module
public abstract class Plugin implements Module {
{ protected Injector injector;
protected Injector injector;
public File file;
public File file; public PluginClassLoader loader;
public PluginClassLoader loader;
@Override
@Override public void configure(Binder binder)
public void configure(Binder binder) {
{ }
}
protected void startUp() throws Exception
protected void startUp() throws Exception {
{ }
}
protected void shutDown() throws Exception
protected void shutDown() throws Exception {
{ }
}
public final Injector getInjector()
public final Injector getInjector() {
{ return injector;
return injector; }
} }
}

View File

@@ -1,63 +1,63 @@
/* /*
* Copyright (c) 2017, Adam <Adam@sigterm.info> * Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins; package net.runelite.client.plugins;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Documented @Documented
public @interface PluginDescriptor public @interface PluginDescriptor
{ {
String name(); String name();
/** /**
* A short, one-line summary of the plugin. * A short, one-line summary of the plugin.
*/ */
String description() default ""; String description() default "";
/** /**
* A list of plugin keywords, used (together with the name) when searching for plugins. * A list of plugin keywords, used (together with the name) when searching for plugins.
* Each tag should not contain any spaces, and should be fully lowercase. * Each tag should not contain any spaces, and should be fully lowercase.
*/ */
String[] tags() default {}; String[] tags() default {};
boolean enabledByDefault() default true; boolean enabledByDefault() default true;
/** /**
* Whether or not plugin is hidden from configuration panel * Whether or not plugin is hidden from configuration panel
*/ */
boolean hidden() default false; boolean hidden() default false;
boolean developerPlugin() default false; boolean developerPlugin() default false;
boolean loadWhenOutdated() default false; boolean loadWhenOutdated() default false;
PluginType type() default PluginType.GENERAL_USE; PluginType type() default PluginType.GENERAL_USE;
} }

View File

@@ -1,15 +1,16 @@
package net.runelite.client.plugins; package net.runelite.client.plugins;
public enum PluginType { public enum PluginType
{
PVM,
PVP, PVM,
PVP,
UTILITY,
GENERAL_USE, UTILITY,
GENERAL_USE,
EXTERNAL,
EXTERNAL,
PLUGIN_ORGANIZER
PLUGIN_ORGANIZER
}
}

View File

@@ -1,273 +1,273 @@
/* /*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info> * Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins; package net.runelite.client.plugins;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Key; import com.google.inject.Key;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.nio.file.FileSystems; import java.nio.file.FileSystems;
import java.nio.file.Path; import java.nio.file.Path;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind; import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey; import java.nio.file.WatchKey;
import java.nio.file.WatchService; import java.nio.file.WatchService;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLite; import net.runelite.client.RuneLite;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
@Singleton @Singleton
@Slf4j @Slf4j
public class PluginWatcher extends Thread public class PluginWatcher extends Thread
{ {
private static final File BASE = RuneLite.PLUGIN_DIR; private static final File BASE = RuneLite.PLUGIN_DIR;
private final RuneLiteConfig runeliteConfig; private final RuneLiteConfig runeliteConfig;
private final PluginManager pluginManager; private final PluginManager pluginManager;
private final WatchService watchService; private final WatchService watchService;
private final WatchKey watchKey; private final WatchKey watchKey;
@Inject @Inject
private ConfigManager configManager; private ConfigManager configManager;
@Inject @Inject
public PluginWatcher(RuneLiteConfig runeliteConfig, PluginManager pluginManager) throws IOException public PluginWatcher(RuneLiteConfig runeliteConfig, PluginManager pluginManager) throws IOException
{ {
this.runeliteConfig = runeliteConfig; this.runeliteConfig = runeliteConfig;
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
setName("Plugin Watcher"); setName("Plugin Watcher");
setDaemon(true); setDaemon(true);
watchService = FileSystems.getDefault().newWatchService(); watchService = FileSystems.getDefault().newWatchService();
BASE.mkdirs(); BASE.mkdirs();
Path dir = BASE.toPath(); Path dir = BASE.toPath();
watchKey = dir.register(watchService, ENTRY_MODIFY, ENTRY_DELETE); watchKey = dir.register(watchService, ENTRY_MODIFY, ENTRY_DELETE);
} }
public void cancel() public void cancel()
{ {
watchKey.cancel(); watchKey.cancel();
} }
@Override @Override
public void run() public void run()
{ {
if (runeliteConfig.enablePlugins()) if (runeliteConfig.enablePlugins())
{ {
scan(); scan();
} }
for (;;) for (; ; )
{ {
try try
{ {
WatchKey key = watchService.take(); WatchKey key = watchService.take();
Thread.sleep(50); Thread.sleep(50);
if (!runeliteConfig.enablePlugins()) if (!runeliteConfig.enablePlugins())
{ {
key.reset(); key.reset();
continue; continue;
} }
for (WatchEvent<?> event : key.pollEvents()) for (WatchEvent<?> event : key.pollEvents())
{ {
Kind<?> kind = event.kind(); Kind<?> kind = event.kind();
Path path = (Path) event.context(); Path path = (Path) event.context();
File file = new File(BASE, path.toFile().getName()); File file = new File(BASE, path.toFile().getName());
log.debug("Event {} file {}", kind, file); log.debug("Event {} file {}", kind, file);
if (kind == ENTRY_MODIFY) if (kind == ENTRY_MODIFY)
{ {
Plugin existing = findPluginForFile(file); Plugin existing = findPluginForFile(file);
if (existing != null) if (existing != null)
{ {
log.info("Reloading plugin {}", file); log.info("Reloading plugin {}", file);
unload(existing); unload(existing);
} }
else else
{ {
log.info("Loading plugin {}", file); log.info("Loading plugin {}", file);
} }
load(file); load(file);
} }
else if (kind == ENTRY_DELETE) else if (kind == ENTRY_DELETE)
{ {
Plugin existing = findPluginForFile(file); Plugin existing = findPluginForFile(file);
if (existing != null) if (existing != null)
{ {
log.info("Unloading plugin {}", file); log.info("Unloading plugin {}", file);
unload(existing); unload(existing);
} }
} }
} }
key.reset(); key.reset();
} }
catch (InterruptedException ex) catch (InterruptedException ex)
{ {
log.warn("error polling for plugins", ex); log.warn("error polling for plugins", ex);
} }
} }
} }
private void scan() private void scan()
{ {
for (File file : BASE.listFiles()) for (File file : BASE.listFiles())
{ {
if (!file.getName().endsWith(".jar")) if (!file.getName().endsWith(".jar"))
{ {
continue; continue;
} }
log.info("Loading plugin from {}", file); log.info("Loading plugin from {}", file);
load(file); load(file);
} }
} }
private Plugin findPluginForFile(File file) private Plugin findPluginForFile(File file)
{ {
for (Plugin plugin : pluginManager.getPlugins()) for (Plugin plugin : pluginManager.getPlugins())
{ {
if (plugin.file != null && plugin.file.equals(file)) if (plugin.file != null && plugin.file.equals(file))
{ {
return plugin; return plugin;
} }
} }
return null; return null;
} }
private void load(File pluginFile) private void load(File pluginFile)
{ {
PluginClassLoader loader; PluginClassLoader loader;
try try
{ {
loader = new PluginClassLoader(pluginFile, getClass().getClassLoader()); loader = new PluginClassLoader(pluginFile, getClass().getClassLoader());
} }
catch (MalformedURLException ex) catch (MalformedURLException ex)
{ {
log.warn("Error loading plugin", ex); log.warn("Error loading plugin", ex);
return; return;
} }
List<Plugin> loadedPlugins; List<Plugin> loadedPlugins;
try try
{ {
loadedPlugins = pluginManager.scanAndInstantiate(loader, null); loadedPlugins = pluginManager.scanAndInstantiate(loader, null);
} }
catch (IOException ex) catch (IOException ex)
{ {
close(loader); close(loader);
log.warn("Error loading plugin", ex); log.warn("Error loading plugin", ex);
return; return;
} }
if (loadedPlugins.isEmpty()) if (loadedPlugins.isEmpty())
{ {
close(loader); close(loader);
log.warn("No plugin found in plugin {}", pluginFile); log.warn("No plugin found in plugin {}", pluginFile);
return; return;
} }
if (loadedPlugins.size() != 1) if (loadedPlugins.size() != 1)
{ {
close(loader); close(loader);
log.warn("You can not have more than one plugin per jar"); log.warn("You can not have more than one plugin per jar");
return; return;
} }
Plugin plugin = loadedPlugins.get(0); Plugin plugin = loadedPlugins.get(0);
plugin.file = pluginFile; plugin.file = pluginFile;
plugin.loader = loader; plugin.loader = loader;
// Initialize default configuration // Initialize default configuration
Injector injector = plugin.getInjector(); Injector injector = plugin.getInjector();
for (Key<?> key : injector.getAllBindings().keySet()) for (Key<?> key : injector.getAllBindings().keySet())
{ {
Class<?> type = key.getTypeLiteral().getRawType(); Class<?> type = key.getTypeLiteral().getRawType();
if (Config.class.isAssignableFrom(type)) if (Config.class.isAssignableFrom(type))
{ {
Config config = (Config) injector.getInstance(key); Config config = (Config) injector.getInstance(key);
configManager.setDefaultConfiguration(config, false); configManager.setDefaultConfiguration(config, false);
} }
} }
try try
{ {
pluginManager.startPlugin(plugin); pluginManager.startPlugin(plugin);
} }
catch (PluginInstantiationException ex) catch (PluginInstantiationException ex)
{ {
close(loader); close(loader);
log.warn("unable to start plugin", ex); log.warn("unable to start plugin", ex);
return; return;
} }
// Plugin is now running // Plugin is now running
pluginManager.add(plugin); pluginManager.add(plugin);
} }
private void unload(Plugin plugin) private void unload(Plugin plugin)
{ {
try try
{ {
pluginManager.stopPlugin(plugin); pluginManager.stopPlugin(plugin);
} }
catch (PluginInstantiationException ex) catch (PluginInstantiationException ex)
{ {
log.warn("unable to stop plugin", ex); log.warn("unable to stop plugin", ex);
} }
pluginManager.remove(plugin); // remove it regardless pluginManager.remove(plugin); // remove it regardless
close(plugin.loader); close(plugin.loader);
} }
private void close(URLClassLoader classLoader) private void close(URLClassLoader classLoader)
{ {
try try
{ {
classLoader.close(); classLoader.close();
} }
catch (IOException ex1) catch (IOException ex1)
{ {
log.warn(null, ex1); log.warn(null, ex1);
} }
} }
} }

View File

@@ -1,28 +1,29 @@
/* /*
* Copyright (c) 2019 Abex * Copyright (c) 2019 Abex
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/package net.runelite.client.plugins.achievementdiary; */
package net.runelite.client.plugins.achievementdiary;
public interface Requirement
{ public interface Requirement
} {
}

View File

@@ -1,136 +1,136 @@
/* /*
* Copyright (c) 2019 William <https://github.com/monsterxsync> * Copyright (c) 2019 William <https://github.com/monsterxsync>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.achievementdiary.diaries; package net.runelite.client.plugins.achievementdiary.diaries;
import net.runelite.api.Favour; import net.runelite.api.Favour;
import net.runelite.api.Quest; import net.runelite.api.Quest;
import net.runelite.api.Skill; import net.runelite.api.Skill;
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement; import net.runelite.client.plugins.achievementdiary.FavourRequirement;
import net.runelite.client.plugins.achievementdiary.SkillRequirement; import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
import net.runelite.client.plugins.achievementdiary.QuestRequirement; import net.runelite.client.plugins.achievementdiary.QuestRequirement;
import net.runelite.client.plugins.achievementdiary.FavourRequirement; import net.runelite.client.plugins.achievementdiary.SkillRequirement;
public class KourendDiaryRequirement extends GenericDiaryRequirement public class KourendDiaryRequirement extends GenericDiaryRequirement
{ {
public KourendDiaryRequirement() public KourendDiaryRequirement()
{ {
//EASY //EASY
add("Mine some Iron at the Mount Karuulm mine.", add("Mine some Iron at the Mount Karuulm mine.",
new SkillRequirement(Skill.MINING, 15)); new SkillRequirement(Skill.MINING, 15));
add("Steal from a Hosidius Food Stall.", add("Steal from a Hosidius Food Stall.",
new SkillRequirement(Skill.THIEVING, 25), new SkillRequirement(Skill.THIEVING, 25),
new FavourRequirement(Favour.HOSIDIUS, 15)); new FavourRequirement(Favour.HOSIDIUS, 15));
add("Browse the Warrens General Store.", add("Browse the Warrens General Store.",
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES, true)); new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES, true));
add("Enter your Player Owned House from Hosidius.", add("Enter your Player Owned House from Hosidius.",
new SkillRequirement(Skill.CONSTRUCTION, 25)); new SkillRequirement(Skill.CONSTRUCTION, 25));
add("Create a Strength potion in the Lovakengj Pub.", add("Create a Strength potion in the Lovakengj Pub.",
new SkillRequirement(Skill.HERBLORE, 12)); new SkillRequirement(Skill.HERBLORE, 12));
add("Fish a Trout from the River Molch.", add("Fish a Trout from the River Molch.",
new SkillRequirement(Skill.FISHING, 20)); new SkillRequirement(Skill.FISHING, 20));
//MEDIUM //MEDIUM
add("Travel to the Fairy Ring south of Mount Karuulm.", add("Travel to the Fairy Ring south of Mount Karuulm.",
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true)); new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
add("Use Kharedst's memoirs to teleport to all five cities in Great Kourend.", add("Use Kharedst's memoirs to teleport to all five cities in Great Kourend.",
new QuestRequirement(Quest.THE_DEPTHS_OF_DESPAIR), new QuestRequirement(Quest.THE_DEPTHS_OF_DESPAIR),
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES), new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES),
new QuestRequirement(Quest.TALE_OF_THE_RIGHTEOUS), new QuestRequirement(Quest.TALE_OF_THE_RIGHTEOUS),
new QuestRequirement(Quest.THE_FORSAKEN_TOWER), new QuestRequirement(Quest.THE_FORSAKEN_TOWER),
new QuestRequirement(Quest.THE_ASCENT_OF_ARCEUUS)); new QuestRequirement(Quest.THE_ASCENT_OF_ARCEUUS));
add("Mine some Volcanic sulphur.", add("Mine some Volcanic sulphur.",
new SkillRequirement(Skill.MINING, 42)); new SkillRequirement(Skill.MINING, 42));
add("Enter the Farming Guild.", add("Enter the Farming Guild.",
new SkillRequirement(Skill.FARMING, 45)); new SkillRequirement(Skill.FARMING, 45));
add("Switch to the Necromancy Spellbook at Tyss.", add("Switch to the Necromancy Spellbook at Tyss.",
new FavourRequirement(Favour.ARCEUUS, 60)); new FavourRequirement(Favour.ARCEUUS, 60));
add("Repair a Piscarilius crane.", add("Repair a Piscarilius crane.",
new SkillRequirement(Skill.CRAFTING, 30)); new SkillRequirement(Skill.CRAFTING, 30));
add("Deliver some intelligence to Captain Ginea.", add("Deliver some intelligence to Captain Ginea.",
new FavourRequirement(Favour.SHAYZIEN, 40)); new FavourRequirement(Favour.SHAYZIEN, 40));
add("Catch a Bluegill on Molch Island.", add("Catch a Bluegill on Molch Island.",
new SkillRequirement(Skill.FISHING, 43), new SkillRequirement(Skill.FISHING, 43),
new SkillRequirement(Skill.HUNTER, 35)); new SkillRequirement(Skill.HUNTER, 35));
add("Use the boulder leap in the Arceuus essence mine.", add("Use the boulder leap in the Arceuus essence mine.",
new SkillRequirement(Skill.AGILITY, 49)); new SkillRequirement(Skill.AGILITY, 49));
add("Subdue the Wintertodt.", add("Subdue the Wintertodt.",
new SkillRequirement(Skill.FIREMAKING, 50)); new SkillRequirement(Skill.FIREMAKING, 50));
add("Catch a Chinchompa in the Kourend Woodland.", add("Catch a Chinchompa in the Kourend Woodland.",
new SkillRequirement(Skill.HUNTER, 53), new SkillRequirement(Skill.HUNTER, 53),
new QuestRequirement(Quest.EAGLES_PEAK)); new QuestRequirement(Quest.EAGLES_PEAK));
add("Chop some Mahogany logs north of the Farming Guild.", add("Chop some Mahogany logs north of the Farming Guild.",
new SkillRequirement(Skill.WOODCUTTING, 50)); new SkillRequirement(Skill.WOODCUTTING, 50));
//HARD //HARD
add("Enter the Woodcutting Guild.", add("Enter the Woodcutting Guild.",
new SkillRequirement(Skill.WOODCUTTING, 60), new SkillRequirement(Skill.WOODCUTTING, 60),
new FavourRequirement(Favour.HOSIDIUS, 75)); new FavourRequirement(Favour.HOSIDIUS, 75));
add("Smelt an Adamantite bar in The Forsaken Tower.", add("Smelt an Adamantite bar in The Forsaken Tower.",
new SkillRequirement(Skill.SMITHING, 70), new SkillRequirement(Skill.SMITHING, 70),
new QuestRequirement(Quest.THE_FORSAKEN_TOWER, true)); new QuestRequirement(Quest.THE_FORSAKEN_TOWER, true));
add("Kill a Lizardman Shaman in Molch.", add("Kill a Lizardman Shaman in Molch.",
new FavourRequirement(Favour.SHAYZIEN, 100)); new FavourRequirement(Favour.SHAYZIEN, 100));
add("Mine some Lovakite.", add("Mine some Lovakite.",
new SkillRequirement(Skill.MINING, 65), new SkillRequirement(Skill.MINING, 65),
new FavourRequirement(Favour.LOVAKENGJ, 30)); new FavourRequirement(Favour.LOVAKENGJ, 30));
add("Plant some Logavano seeds at the Tithe Farm.", add("Plant some Logavano seeds at the Tithe Farm.",
new SkillRequirement(Skill.FARMING, 74), new SkillRequirement(Skill.FARMING, 74),
new FavourRequirement(Favour.HOSIDIUS, 100)); new FavourRequirement(Favour.HOSIDIUS, 100));
add("Teleport to Xeric's Heart using Xeric's Talisman.", add("Teleport to Xeric's Heart using Xeric's Talisman.",
new QuestRequirement(Quest.ARCHITECTURAL_ALLIANCE)); new QuestRequirement(Quest.ARCHITECTURAL_ALLIANCE));
add("Deliver an artefact to Captain Khaled.", add("Deliver an artefact to Captain Khaled.",
new SkillRequirement(Skill.THIEVING, 49), new SkillRequirement(Skill.THIEVING, 49),
new FavourRequirement(Favour.PISCARILIUS, 75)); new FavourRequirement(Favour.PISCARILIUS, 75));
add("Kill a Wyrm in the Karuulm Slayer Dungeon.", add("Kill a Wyrm in the Karuulm Slayer Dungeon.",
new SkillRequirement(Skill.SLAYER, 62)); new SkillRequirement(Skill.SLAYER, 62));
add("Cast Monster Examine on a Troll south of Mount Quidamortem.", add("Cast Monster Examine on a Troll south of Mount Quidamortem.",
new SkillRequirement(Skill.MAGIC, 66), new SkillRequirement(Skill.MAGIC, 66),
new QuestRequirement(Quest.DREAM_MENTOR)); new QuestRequirement(Quest.DREAM_MENTOR));
//ELITE //ELITE
add("Craft one or more Blood runes.", add("Craft one or more Blood runes.",
new SkillRequirement(Skill.RUNECRAFT, 77), new SkillRequirement(Skill.RUNECRAFT, 77),
new SkillRequirement(Skill.MINING, 38), new SkillRequirement(Skill.MINING, 38),
new SkillRequirement(Skill.CRAFTING, 38), new SkillRequirement(Skill.CRAFTING, 38),
new FavourRequirement(Favour.ARCEUUS, 100)); new FavourRequirement(Favour.ARCEUUS, 100));
add("Chop some Redwood logs.", add("Chop some Redwood logs.",
new SkillRequirement(Skill.WOODCUTTING, 90), new SkillRequirement(Skill.WOODCUTTING, 90),
new FavourRequirement(Favour.HOSIDIUS, 75)); new FavourRequirement(Favour.HOSIDIUS, 75));
add("Catch an Anglerfish and cook it whilst in Great Kourend.", add("Catch an Anglerfish and cook it whilst in Great Kourend.",
new SkillRequirement(Skill.FISHING, 82), new SkillRequirement(Skill.FISHING, 82),
new SkillRequirement(Skill.COOKING, 84), new SkillRequirement(Skill.COOKING, 84),
new FavourRequirement(Favour.PISCARILIUS, 100)); new FavourRequirement(Favour.PISCARILIUS, 100));
add("Kill a Hydra in the Karuulm Slayer Dungeon.", add("Kill a Hydra in the Karuulm Slayer Dungeon.",
new SkillRequirement(Skill.SLAYER, 95)); new SkillRequirement(Skill.SLAYER, 95));
add("Create an Ape Atoll teleport tablet.", add("Create an Ape Atoll teleport tablet.",
new SkillRequirement(Skill.MAGIC, 90), new SkillRequirement(Skill.MAGIC, 90),
new SkillRequirement(Skill.MINING, 38), new SkillRequirement(Skill.MINING, 38),
new SkillRequirement(Skill.CRAFTING, 38), new SkillRequirement(Skill.CRAFTING, 38),
new FavourRequirement(Favour.ARCEUUS, 100)); new FavourRequirement(Favour.ARCEUUS, 100));
add("Create your own Battlestaff from scratch within the Farming Guild.", add("Create your own Battlestaff from scratch within the Farming Guild.",
new SkillRequirement(Skill.FARMING, 85), new SkillRequirement(Skill.FARMING, 85),
new SkillRequirement(Skill.FLETCHING, 40)); new SkillRequirement(Skill.FLETCHING, 40));
} }
} }

View File

@@ -1,141 +1,141 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Cas <https://github.com/casvandongen> * Copyright (c) 2018, Cas <https://github.com/casvandongen>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.agility; package net.runelite.client.plugins.agility;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Polygon; import java.awt.Polygon;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.client.game.AgilityShortcut; import net.runelite.client.game.AgilityShortcut;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.OverlayUtil;
class AgilityOverlay extends Overlay class AgilityOverlay extends Overlay
{ {
private static final int MAX_DISTANCE = 2350; private static final int MAX_DISTANCE = 2350;
private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE; private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE;
private final Client client; private final Client client;
private final AgilityPlugin plugin; private final AgilityPlugin plugin;
private final AgilityConfig config; private final AgilityConfig config;
@Inject @Inject
private AgilityOverlay(Client client, AgilityPlugin plugin, AgilityConfig config) private AgilityOverlay(Client client, AgilityPlugin plugin, AgilityConfig config)
{ {
super(plugin); super(plugin);
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE); setLayer(OverlayLayer.ABOVE_SCENE);
this.client = client; this.client = client;
this.plugin = plugin; this.plugin = plugin;
this.config = config; this.config = config;
} }
@Override @Override
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation(); LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation();
Point mousePosition = client.getMouseCanvasPosition(); Point mousePosition = client.getMouseCanvasPosition();
final List<Tile> marksOfGrace = plugin.getMarksOfGrace(); final List<Tile> marksOfGrace = plugin.getMarksOfGrace();
plugin.getObstacles().forEach((object, obstacle) -> plugin.getObstacles().forEach((object, obstacle) ->
{ {
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !config.highlightShortcuts() || if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !config.highlightShortcuts() ||
Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.showTrapOverlay()) Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.showTrapOverlay())
{ {
return; return;
} }
Tile tile = obstacle.getTile(); Tile tile = obstacle.getTile();
if (tile.getPlane() == client.getPlane() if (tile.getPlane() == client.getPlane()
&& object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE) && object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
{ {
// This assumes that the obstacle is not clickable. // This assumes that the obstacle is not clickable.
if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId())) if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()))
{ {
Polygon polygon = object.getCanvasTilePoly(); Polygon polygon = object.getCanvasTilePoly();
if (polygon != null) if (polygon != null)
{ {
OverlayUtil.renderPolygon(graphics, polygon, config.getTrapColor()); OverlayUtil.renderPolygon(graphics, polygon, config.getTrapColor());
} }
return; return;
} }
Area objectClickbox = object.getClickbox(); Area objectClickbox = object.getClickbox();
if (objectClickbox != null) if (objectClickbox != null)
{ {
AgilityShortcut agilityShortcut = obstacle.getShortcut(); AgilityShortcut agilityShortcut = obstacle.getShortcut();
Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? config.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR; Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? config.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR;
if (config.highlightMarks() && !marksOfGrace.isEmpty()) if (config.highlightMarks() && !marksOfGrace.isEmpty())
{ {
configColor = config.getMarkColor(); configColor = config.getMarkColor();
} }
if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY())) if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY()))
{ {
graphics.setColor(configColor.darker()); graphics.setColor(configColor.darker());
} }
else else
{ {
graphics.setColor(configColor); graphics.setColor(configColor);
} }
graphics.draw(objectClickbox); graphics.draw(objectClickbox);
graphics.setColor(new Color(configColor.getRed(), configColor.getGreen(), configColor.getBlue(), 50)); graphics.setColor(new Color(configColor.getRed(), configColor.getGreen(), configColor.getBlue(), 50));
graphics.fill(objectClickbox); graphics.fill(objectClickbox);
} }
} }
}); });
if (config.highlightMarks() && !marksOfGrace.isEmpty()) if (config.highlightMarks() && !marksOfGrace.isEmpty())
{ {
for (Tile markOfGraceTile : marksOfGrace) for (Tile markOfGraceTile : marksOfGrace)
{ {
if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null
&& markOfGraceTile.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE) && markOfGraceTile.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
{ {
final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly(); final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly();
if (poly == null) if (poly == null)
{ {
continue; continue;
} }
OverlayUtil.renderPolygon(graphics, poly, config.getMarkColor()); OverlayUtil.renderPolygon(graphics, poly, config.getMarkColor());
} }
} }
} }
return null; return null;
} }
} }

View File

@@ -1,462 +1,463 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.agility; package net.runelite.client.plugins.agility;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.util.ArrayList; import java.awt.Color;
import java.util.Arrays; import java.util.ArrayList;
import java.util.HashMap; import java.util.Arrays;
import java.util.List; import java.util.HashMap;
import java.util.Map; import java.util.List;
import javax.inject.Inject; import java.util.Map;
import lombok.Getter; import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j; import lombok.Getter;
import net.runelite.api.Client; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Item; import net.runelite.api.Client;
import net.runelite.api.ItemID; import net.runelite.api.Item;
import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET; import net.runelite.api.ItemID;
import net.runelite.api.Player; import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET;
import net.runelite.api.Skill; import net.runelite.api.MenuAction;
import static net.runelite.api.Skill.AGILITY; import net.runelite.api.MenuEntry;
import net.runelite.api.Tile; import net.runelite.api.Player;
import net.runelite.api.TileObject; import net.runelite.api.Skill;
import net.runelite.api.coords.WorldPoint; import static net.runelite.api.Skill.AGILITY;
import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.Tile;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.TileObject;
import net.runelite.api.events.DecorativeObjectChanged; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.DecorativeObjectDespawned; import net.runelite.api.events.BoostedLevelChanged;
import net.runelite.api.events.DecorativeObjectSpawned; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.DecorativeObjectChanged;
import net.runelite.api.events.GameObjectChanged; import net.runelite.api.events.DecorativeObjectDespawned;
import net.runelite.api.events.GameObjectDespawned; import net.runelite.api.events.DecorativeObjectSpawned;
import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.ExperienceChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameObjectChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameObjectDespawned;
import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GameObjectSpawned;
import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.GameTick;
import net.runelite.api.events.ItemDespawned; import net.runelite.api.events.GroundObjectChanged;
import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.GroundObjectDespawned;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.GroundObjectSpawned;
import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.ItemDespawned;
import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.ItemSpawned;
import net.runelite.api.events.WallObjectSpawned; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.client.Notifier; import net.runelite.api.events.WallObjectChanged;
import net.runelite.client.config.ConfigManager; import net.runelite.api.events.WallObjectDespawned;
import net.runelite.client.eventbus.Subscribe; import net.runelite.api.events.WallObjectSpawned;
import net.runelite.client.game.AgilityShortcut; import net.runelite.client.Notifier;
import net.runelite.client.game.ItemManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.game.AgilityShortcut;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.plugins.Plugin;
import net.runelite.api.MenuEntry; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.ColorUtil; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.api.MenuAction; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import java.awt.Color; import net.runelite.client.util.ColorUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Agility", name = "Agility",
description = "Show helpful information about agility courses and obstacles", description = "Show helpful information about agility courses and obstacles",
tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"} tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"}
) )
@Slf4j @Slf4j
public class AgilityPlugin extends Plugin public class AgilityPlugin extends Plugin
{ {
private static final int AGILITY_ARENA_REGION_ID = 11157; private static final int AGILITY_ARENA_REGION_ID = 11157;
@Getter @Getter
private final Map<TileObject, Obstacle> obstacles = new HashMap<>(); private final Map<TileObject, Obstacle> obstacles = new HashMap<>();
@Getter @Getter
private final List<Tile> marksOfGrace = new ArrayList<>(); private final List<Tile> marksOfGrace = new ArrayList<>();
@Inject @Inject
private OverlayManager overlayManager; private OverlayManager overlayManager;
@Inject @Inject
private AgilityOverlay agilityOverlay; private AgilityOverlay agilityOverlay;
@Inject @Inject
private LapCounterOverlay lapCounterOverlay; private LapCounterOverlay lapCounterOverlay;
@Inject @Inject
private Notifier notifier; private Notifier notifier;
@Inject @Inject
private Client client; private Client client;
@Inject @Inject
private InfoBoxManager infoBoxManager; private InfoBoxManager infoBoxManager;
@Inject @Inject
private AgilityConfig config; private AgilityConfig config;
@Inject @Inject
private ItemManager itemManager; private ItemManager itemManager;
@Getter @Getter
private AgilitySession session; private AgilitySession session;
private int lastAgilityXp; private int lastAgilityXp;
private WorldPoint lastArenaTicketPosition; private WorldPoint lastArenaTicketPosition;
@Getter @Getter
private int agilityLevel; private int agilityLevel;
@Provides @Provides
AgilityConfig getConfig(ConfigManager configManager) AgilityConfig getConfig(ConfigManager configManager)
{ {
return configManager.getConfig(AgilityConfig.class); return configManager.getConfig(AgilityConfig.class);
} }
@Override @Override
protected void startUp() throws Exception protected void startUp() throws Exception
{ {
overlayManager.add(agilityOverlay); overlayManager.add(agilityOverlay);
overlayManager.add(lapCounterOverlay); overlayManager.add(lapCounterOverlay);
agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY); agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY);
} }
@Override @Override
protected void shutDown() throws Exception protected void shutDown() throws Exception
{ {
overlayManager.remove(agilityOverlay); overlayManager.remove(agilityOverlay);
overlayManager.remove(lapCounterOverlay); overlayManager.remove(lapCounterOverlay);
marksOfGrace.clear(); marksOfGrace.clear();
obstacles.clear(); obstacles.clear();
session = null; session = null;
agilityLevel = 0; agilityLevel = 0;
} }
@Subscribe @Subscribe
public void onGameStateChanged(GameStateChanged event) public void onGameStateChanged(GameStateChanged event)
{ {
switch (event.getGameState()) switch (event.getGameState())
{ {
case HOPPING: case HOPPING:
case LOGIN_SCREEN: case LOGIN_SCREEN:
session = null; session = null;
lastArenaTicketPosition = null; lastArenaTicketPosition = null;
removeAgilityArenaTimer(); removeAgilityArenaTimer();
break; break;
case LOADING: case LOADING:
marksOfGrace.clear(); marksOfGrace.clear();
obstacles.clear(); obstacles.clear();
break; break;
case LOGGED_IN: case LOGGED_IN:
if (!isInAgilityArena()) if (!isInAgilityArena())
{ {
lastArenaTicketPosition = null; lastArenaTicketPosition = null;
removeAgilityArenaTimer(); removeAgilityArenaTimer();
} }
break; break;
} }
} }
@Subscribe @Subscribe
public void onConfigChanged(ConfigChanged event) public void onConfigChanged(ConfigChanged event)
{ {
if (!config.showAgilityArenaTimer()) if (!config.showAgilityArenaTimer())
{ {
removeAgilityArenaTimer(); removeAgilityArenaTimer();
} }
} }
@Subscribe @Subscribe
public void onExperienceChanged(ExperienceChanged event) public void onExperienceChanged(ExperienceChanged event)
{ {
if (event.getSkill() != AGILITY || !config.showLapCount()) if (event.getSkill() != AGILITY || !config.showLapCount())
{ {
return; return;
} }
// Determine how much EXP was actually gained // Determine how much EXP was actually gained
int agilityXp = client.getSkillExperience(AGILITY); int agilityXp = client.getSkillExperience(AGILITY);
int skillGained = agilityXp - lastAgilityXp; int skillGained = agilityXp - lastAgilityXp;
lastAgilityXp = agilityXp; lastAgilityXp = agilityXp;
// Get course // Get course
Courses course = Courses.getCourse(client.getLocalPlayer().getWorldLocation().getRegionID()); Courses course = Courses.getCourse(client.getLocalPlayer().getWorldLocation().getRegionID());
if (course == null if (course == null
|| (course.getCourseEndWorldPoints().length == 0 || (course.getCourseEndWorldPoints().length == 0
? Math.abs(course.getLastObstacleXp() - skillGained) > 1 ? Math.abs(course.getLastObstacleXp() - skillGained) > 1
: Arrays.stream(course.getCourseEndWorldPoints()).noneMatch(wp -> wp.equals(client.getLocalPlayer().getWorldLocation())))) : Arrays.stream(course.getCourseEndWorldPoints()).noneMatch(wp -> wp.equals(client.getLocalPlayer().getWorldLocation()))))
{ {
return; return;
} }
if (session != null && session.getCourse() == course) if (session != null && session.getCourse() == course)
{ {
session.incrementLapCount(client); session.incrementLapCount(client);
} }
else else
{ {
session = new AgilitySession(course); session = new AgilitySession(course);
// New course found, reset lap count and set new course // New course found, reset lap count and set new course
session.resetLapCount(); session.resetLapCount();
session.incrementLapCount(client); session.incrementLapCount(client);
} }
} }
@Subscribe @Subscribe
public void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged) public void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged)
{ {
Skill skill = boostedLevelChanged.getSkill(); Skill skill = boostedLevelChanged.getSkill();
if (skill == AGILITY) if (skill == AGILITY)
{ {
agilityLevel = client.getBoostedSkillLevel(skill); agilityLevel = client.getBoostedSkillLevel(skill);
} }
} }
@Subscribe @Subscribe
public void onItemSpawned(ItemSpawned itemSpawned) public void onItemSpawned(ItemSpawned itemSpawned)
{ {
if (obstacles.isEmpty()) if (obstacles.isEmpty())
{ {
return; return;
} }
final Item item = itemSpawned.getItem(); final Item item = itemSpawned.getItem();
final Tile tile = itemSpawned.getTile(); final Tile tile = itemSpawned.getTile();
if (item.getId() == ItemID.MARK_OF_GRACE) if (item.getId() == ItemID.MARK_OF_GRACE)
{ {
marksOfGrace.add(tile); marksOfGrace.add(tile);
} }
} }
@Subscribe @Subscribe
public void onItemDespawned(ItemDespawned itemDespawned) public void onItemDespawned(ItemDespawned itemDespawned)
{ {
final Tile tile = itemDespawned.getTile(); final Tile tile = itemDespawned.getTile();
marksOfGrace.remove(tile); marksOfGrace.remove(tile);
} }
@Subscribe @Subscribe
public void onGameTick(GameTick tick) public void onGameTick(GameTick tick)
{ {
if (isInAgilityArena()) if (isInAgilityArena())
{ {
// Hint arrow has no plane, and always returns the current plane // Hint arrow has no plane, and always returns the current plane
WorldPoint newTicketPosition = client.getHintArrowPoint(); WorldPoint newTicketPosition = client.getHintArrowPoint();
WorldPoint oldTickPosition = lastArenaTicketPosition; WorldPoint oldTickPosition = lastArenaTicketPosition;
lastArenaTicketPosition = newTicketPosition; lastArenaTicketPosition = newTicketPosition;
if (oldTickPosition != null && newTicketPosition != null if (oldTickPosition != null && newTicketPosition != null
&& (oldTickPosition.getX() != newTicketPosition.getX() || oldTickPosition.getY() != newTicketPosition.getY())) && (oldTickPosition.getX() != newTicketPosition.getX() || oldTickPosition.getY() != newTicketPosition.getY()))
{ {
log.debug("Ticked position moved from {} to {}", oldTickPosition, newTicketPosition); log.debug("Ticked position moved from {} to {}", oldTickPosition, newTicketPosition);
if (config.notifyAgilityArena()) if (config.notifyAgilityArena())
{ {
notifier.notify("Ticket location changed"); notifier.notify("Ticket location changed");
} }
if (config.showAgilityArenaTimer()) if (config.showAgilityArenaTimer())
{ {
showNewAgilityArenaTimer(); showNewAgilityArenaTimer();
} }
} }
} }
} }
private boolean isInAgilityArena() private boolean isInAgilityArena()
{ {
Player local = client.getLocalPlayer(); Player local = client.getLocalPlayer();
if (local == null) if (local == null)
{ {
return false; return false;
} }
WorldPoint location = local.getWorldLocation(); WorldPoint location = local.getWorldLocation();
return location.getRegionID() == AGILITY_ARENA_REGION_ID; return location.getRegionID() == AGILITY_ARENA_REGION_ID;
} }
private void removeAgilityArenaTimer() private void removeAgilityArenaTimer()
{ {
infoBoxManager.removeIf(infoBox -> infoBox instanceof AgilityArenaTimer); infoBoxManager.removeIf(infoBox -> infoBox instanceof AgilityArenaTimer);
} }
private void showNewAgilityArenaTimer() private void showNewAgilityArenaTimer()
{ {
removeAgilityArenaTimer(); removeAgilityArenaTimer();
infoBoxManager.addInfoBox(new AgilityArenaTimer(this, itemManager.getImage(AGILITY_ARENA_TICKET))); infoBoxManager.addInfoBox(new AgilityArenaTimer(this, itemManager.getImage(AGILITY_ARENA_TICKET)));
} }
@Subscribe @Subscribe
public void onGameObjectSpawned(GameObjectSpawned event) public void onGameObjectSpawned(GameObjectSpawned event)
{ {
onTileObject(event.getTile(), null, event.getGameObject()); onTileObject(event.getTile(), null, event.getGameObject());
} }
@Subscribe @Subscribe
public void onGameObjectChanged(GameObjectChanged event) public void onGameObjectChanged(GameObjectChanged event)
{ {
onTileObject(event.getTile(), event.getPrevious(), event.getGameObject()); onTileObject(event.getTile(), event.getPrevious(), event.getGameObject());
} }
@Subscribe @Subscribe
public void onGameObjectDespawned(GameObjectDespawned event) public void onGameObjectDespawned(GameObjectDespawned event)
{ {
onTileObject(event.getTile(), event.getGameObject(), null); onTileObject(event.getTile(), event.getGameObject(), null);
} }
@Subscribe @Subscribe
public void onGroundObjectSpawned(GroundObjectSpawned event) public void onGroundObjectSpawned(GroundObjectSpawned event)
{ {
onTileObject(event.getTile(), null, event.getGroundObject()); onTileObject(event.getTile(), null, event.getGroundObject());
} }
@Subscribe @Subscribe
public void onGroundObjectChanged(GroundObjectChanged event) public void onGroundObjectChanged(GroundObjectChanged event)
{ {
onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject()); onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject());
} }
@Subscribe @Subscribe
public void onGroundObjectDespawned(GroundObjectDespawned event) public void onGroundObjectDespawned(GroundObjectDespawned event)
{ {
onTileObject(event.getTile(), event.getGroundObject(), null); onTileObject(event.getTile(), event.getGroundObject(), null);
} }
@Subscribe @Subscribe
public void onWallObjectSpawned(WallObjectSpawned event) public void onWallObjectSpawned(WallObjectSpawned event)
{ {
onTileObject(event.getTile(), null, event.getWallObject()); onTileObject(event.getTile(), null, event.getWallObject());
} }
@Subscribe @Subscribe
public void onWallObjectChanged(WallObjectChanged event) public void onWallObjectChanged(WallObjectChanged event)
{ {
onTileObject(event.getTile(), event.getPrevious(), event.getWallObject()); onTileObject(event.getTile(), event.getPrevious(), event.getWallObject());
} }
@Subscribe @Subscribe
public void onWallObjectDespawned(WallObjectDespawned event) public void onWallObjectDespawned(WallObjectDespawned event)
{ {
onTileObject(event.getTile(), event.getWallObject(), null); onTileObject(event.getTile(), event.getWallObject(), null);
} }
@Subscribe @Subscribe
public void onDecorativeObjectSpawned(DecorativeObjectSpawned event) public void onDecorativeObjectSpawned(DecorativeObjectSpawned event)
{ {
onTileObject(event.getTile(), null, event.getDecorativeObject()); onTileObject(event.getTile(), null, event.getDecorativeObject());
} }
@Subscribe @Subscribe
public void onDecorativeObjectChanged(DecorativeObjectChanged event) public void onDecorativeObjectChanged(DecorativeObjectChanged event)
{ {
onTileObject(event.getTile(), event.getPrevious(), event.getDecorativeObject()); onTileObject(event.getTile(), event.getPrevious(), event.getDecorativeObject());
} }
@Subscribe @Subscribe
public void onDecorativeObjectDespawned(DecorativeObjectDespawned event) public void onDecorativeObjectDespawned(DecorativeObjectDespawned event)
{ {
onTileObject(event.getTile(), event.getDecorativeObject(), null); onTileObject(event.getTile(), event.getDecorativeObject(), null);
} }
private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject) private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject)
{ {
obstacles.remove(oldObject); obstacles.remove(oldObject);
if (newObject == null) if (newObject == null)
{ {
return; return;
} }
if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) || if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) ||
(Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId()) (Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId())
&& Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID()))) && Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID())))
{ {
obstacles.put(newObject, new Obstacle(tile, null)); obstacles.put(newObject, new Obstacle(tile, null));
} }
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(newObject.getId())) if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(newObject.getId()))
{ {
AgilityShortcut closestShortcut = null; AgilityShortcut closestShortcut = null;
int distance = -1; int distance = -1;
// Find the closest shortcut to this object // Find the closest shortcut to this object
for (AgilityShortcut shortcut : Obstacles.SHORTCUT_OBSTACLE_IDS.get(newObject.getId())) for (AgilityShortcut shortcut : Obstacles.SHORTCUT_OBSTACLE_IDS.get(newObject.getId()))
{ {
if (shortcut.getWorldLocation() == null) if (shortcut.getWorldLocation() == null)
{ {
closestShortcut = shortcut; closestShortcut = shortcut;
break; break;
} }
else else
{ {
int newDistance = shortcut.getWorldLocation().distanceTo2D(newObject.getWorldLocation()); int newDistance = shortcut.getWorldLocation().distanceTo2D(newObject.getWorldLocation());
if (closestShortcut == null || newDistance < distance) if (closestShortcut == null || newDistance < distance)
{ {
closestShortcut = shortcut; closestShortcut = shortcut;
distance = newDistance; distance = newDistance;
} }
} }
} }
if (closestShortcut != null) if (closestShortcut != null)
{ {
obstacles.put(newObject, new Obstacle(tile, closestShortcut)); obstacles.put(newObject, new Obstacle(tile, closestShortcut));
} }
} }
} }
@Subscribe @Subscribe
public void onMenuEntryAdded(MenuEntryAdded event) public void onMenuEntryAdded(MenuEntryAdded event)
{ {
if (!config.showShortcutLevel()) if (!config.showShortcutLevel())
{ {
return; return;
} }
//Guarding against non-first option because agility shortcuts are always that type of event. //Guarding against non-first option because agility shortcuts are always that type of event.
if (event.getType() != MenuAction.GAME_OBJECT_FIRST_OPTION.getId()) if (event.getType() != MenuAction.GAME_OBJECT_FIRST_OPTION.getId())
{ {
return; return;
} }
final int entryId = event.getIdentifier(); final int entryId = event.getIdentifier();
MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry[] menuEntries = client.getMenuEntries();
for (Obstacle nearbyObstacle : getObstacles().values()) for (Obstacle nearbyObstacle : getObstacles().values())
{ {
AgilityShortcut shortcut = nearbyObstacle.getShortcut(); AgilityShortcut shortcut = nearbyObstacle.getShortcut();
if (shortcut != null && Arrays.stream(shortcut.getObstacleIds()).anyMatch(i -> i == entryId)) { if (shortcut != null && Arrays.stream(shortcut.getObstacleIds()).anyMatch(i -> i == entryId))
MenuEntry entry = menuEntries[menuEntries.length - 1]; {
int level = shortcut.getLevel(); MenuEntry entry = menuEntries[menuEntries.length - 1];
Color color = level <= getAgilityLevel() ? Color.GREEN : Color.RED; int level = shortcut.getLevel();
String requirementText = " (level-" + level + ")"; Color color = level <= getAgilityLevel() ? Color.GREEN : Color.RED;
String requirementText = " (level-" + level + ")";
entry.setTarget(event.getTarget() + ColorUtil.prependColorTag(requirementText, color));
client.setMenuEntries(menuEntries); entry.setTarget(event.getTarget() + ColorUtil.prependColorTag(requirementText, color));
return; client.setMenuEntries(menuEntries);
} return;
} }
} }
} }
}

View File

@@ -1,131 +1,334 @@
/* /*
* Copyright (c) 2018, SomeoneWithAnInternetConnection * Copyright (c) 2018, SomeoneWithAnInternetConnection
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.agility; package net.runelite.client.plugins.agility;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static net.runelite.api.NullObjectID.NULL_10872; import static net.runelite.api.NullObjectID.NULL_10872;
import static net.runelite.api.NullObjectID.NULL_10873; import static net.runelite.api.NullObjectID.NULL_10873;
import static net.runelite.api.NullObjectID.NULL_12945; import static net.runelite.api.NullObjectID.NULL_12945;
import static net.runelite.api.NullObjectID.NULL_18083; import static net.runelite.api.NullObjectID.NULL_18083;
import static net.runelite.api.NullObjectID.NULL_18116; import static net.runelite.api.NullObjectID.NULL_18116;
import static net.runelite.api.NullObjectID.NULL_18122; import static net.runelite.api.NullObjectID.NULL_18122;
import static net.runelite.api.NullObjectID.NULL_18124; import static net.runelite.api.NullObjectID.NULL_18124;
import static net.runelite.api.NullObjectID.NULL_18129; import static net.runelite.api.NullObjectID.NULL_18129;
import static net.runelite.api.NullObjectID.NULL_18130; import static net.runelite.api.NullObjectID.NULL_18130;
import static net.runelite.api.NullObjectID.NULL_18132; import static net.runelite.api.NullObjectID.NULL_18132;
import static net.runelite.api.NullObjectID.NULL_18133; import static net.runelite.api.NullObjectID.NULL_18133;
import static net.runelite.api.NullObjectID.NULL_18135; import static net.runelite.api.NullObjectID.NULL_18135;
import static net.runelite.api.NullObjectID.NULL_18136; import static net.runelite.api.NullObjectID.NULL_18136;
import static net.runelite.api.NullObjectID.NULL_3550; import static net.runelite.api.NullObjectID.NULL_3550;
import static net.runelite.api.ObjectID.*; import static net.runelite.api.ObjectID.BALANCING_LEDGE;
import net.runelite.client.game.AgilityShortcut; import static net.runelite.api.ObjectID.BALANCING_LEDGE_23547;
import static net.runelite.api.ObjectID.BALANCING_LEDGE_3561;
class Obstacles import static net.runelite.api.ObjectID.BALANCING_ROPE;
{ import static net.runelite.api.ObjectID.BALANCING_ROPE_23557;
static final Set<Integer> COURSE_OBSTACLE_IDS = ImmutableSet.of( import static net.runelite.api.ObjectID.BANNER_11382;
// Gnome import static net.runelite.api.ObjectID.BASKET_11380;
OBSTACLE_NET_23134, TREE_BRANCH_23559, TREE_BRANCH_23560, OBSTACLE_NET_23135, OBSTACLE_PIPE_23138, import static net.runelite.api.ObjectID.BOAT_17961;
OBSTACLE_PIPE_23139, LOG_BALANCE_23145, BALANCING_ROPE_23557, import static net.runelite.api.ObjectID.BOILER_22635;
// Brimhaven import static net.runelite.api.ObjectID.CABLE;
PLANK_3572, PLANK_3571, PLANK_3570, ROPE_SWING, PILLAR_3578, LOW_WALL, LOG_BALANCE, LOG_BALANCE_3557, import static net.runelite.api.ObjectID.CABLE_22569;
BALANCING_LEDGE_3561, BALANCING_LEDGE, MONKEY_BARS_3564, BALANCING_ROPE, HAND_HOLDS_3583, import static net.runelite.api.ObjectID.CABLE_22572;
// Draynor import static net.runelite.api.ObjectID.CLIMBING_ROCKS_10851;
ROUGH_WALL, TIGHTROPE, TIGHTROPE_10075, NARROW_WALL, WALL_10084, GAP_10085, CRATE_10086, STILE_7527, import static net.runelite.api.ObjectID.CLOTHES_LINE;
// Al-Kharid import static net.runelite.api.ObjectID.CONSOLE;
ROUGH_WALL_10093, TIGHTROPE_10284, CABLE, ZIP_LINE, TROPICAL_TREE_10357, ROOF_TOP_BEAMS, import static net.runelite.api.ObjectID.CRATE_10086;
TIGHTROPE_10583, GAP_10352, import static net.runelite.api.ObjectID.CRUMBLING_WALL_1948;
// Pyramid import static net.runelite.api.ObjectID.DOORWAY_10855;
STAIRS_10857, LOW_WALL_10865, LEDGE_10860, PLANK_10868, GAP_10882, LEDGE_10886, STAIRS_10857, GAP_10884, import static net.runelite.api.ObjectID.DOOR_18091;
GAP_10859, GAP_10861, LOW_WALL_10865, GAP_10859, LEDGE_10888, PLANK_10868, CLIMBING_ROCKS_10851, DOORWAY_10855, import static net.runelite.api.ObjectID.DRYING_LINE;
// Varrock import static net.runelite.api.ObjectID.EDGE;
ROUGH_WALL_10586, CLOTHES_LINE, GAP_10642, WALL_10777, GAP_10778, GAP_10779, GAP_10780, LEDGE_10781, EDGE, import static net.runelite.api.ObjectID.EDGE_11371;
// Penguin import static net.runelite.api.ObjectID.EDGE_11377;
STEPPING_STONE_21120, STEPPING_STONE_21126, STEPPING_STONE_21128, STEPPING_STONE_21129, import static net.runelite.api.ObjectID.FLOORBOARDS;
STEPPING_STONE_21130, STEPPING_STONE_21131, STEPPING_STONE_21132, STEPPING_STONE_21133, import static net.runelite.api.ObjectID.FLOORBOARDS_18071;
ICICLES, ICE, ICE_21149, ICE_21150, ICE_21151, ICE_21152, ICE_21153, ICE_21154, ICE_21155, ICE_21156, import static net.runelite.api.ObjectID.FLOORBOARDS_18072;
// Barbarian import static net.runelite.api.ObjectID.FLOORBOARDS_18073;
ROPESWING_23131, LOG_BALANCE_23144, OBSTACLE_NET_20211, BALANCING_LEDGE_23547, LADDER_16682, CRUMBLING_WALL_1948, import static net.runelite.api.ObjectID.FLOORBOARDS_18089;
// Canifis import static net.runelite.api.ObjectID.FLOORBOARDS_18090;
TALL_TREE_10819, GAP_10820, GAP_10821, GAP_10828, GAP_10822, POLEVAULT, GAP_10823, GAP_10832, import static net.runelite.api.ObjectID.FLOORBOARDS_18093;
// Ape atoll import static net.runelite.api.ObjectID.FLOORBOARDS_18094;
STEPPING_STONE_15412, TROPICAL_TREE_15414, MONKEYBARS_15417, SKULL_SLOPE_15483, ROPE_15487, TROPICAL_TREE_16062, import static net.runelite.api.ObjectID.FLOORBOARDS_18097;
// Falador import static net.runelite.api.ObjectID.FLOORBOARDS_18098;
ROUGH_WALL_10833, TIGHTROPE_10834, HAND_HOLDS_10836, GAP_11161, GAP_11360, TIGHTROPE_11361, import static net.runelite.api.ObjectID.FLOORBOARDS_18109;
TIGHTROPE_11364, GAP_11365, LEDGE_11366, LEDGE_11367, LEDGE_11369, LEDGE_11370, EDGE_11371, import static net.runelite.api.ObjectID.FLOORBOARDS_18110;
// Wilderness import static net.runelite.api.ObjectID.FLOORBOARDS_18111;
OBSTACLE_PIPE_23137, ROPESWING_23132, STEPPING_STONE_23556, LOG_BALANCE_23542, ROCKS_23640, import static net.runelite.api.ObjectID.FLOORBOARDS_18112;
// Seers import static net.runelite.api.ObjectID.FLOORBOARDS_18113;
WALL_11373, GAP_11374, TIGHTROPE_11378, GAP_11375, GAP_11376, EDGE_11377, import static net.runelite.api.ObjectID.FLOORBOARDS_18114;
// Dorgesh-Kaan import static net.runelite.api.ObjectID.FLOORBOARDS_18117;
CABLE_22569, CABLE_22572, LADDER_22564, JUTTING_WALL_22552, TUNNEL_22557, PYLON_22664, import static net.runelite.api.ObjectID.FLOORBOARDS_18118;
CONSOLE, BOILER_22635, STAIRS_22650, STAIRS_22651, STAIRS_22609, STAIRS_22608, import static net.runelite.api.ObjectID.GAP_10085;
// Pollniveach import static net.runelite.api.ObjectID.GAP_10352;
BASKET_11380, MARKET_STALL_11381, BANNER_11382, GAP_11383, TREE_11384, ROUGH_WALL_11385, import static net.runelite.api.ObjectID.GAP_10642;
MONKEYBARS, TREE_11389, DRYING_LINE, import static net.runelite.api.ObjectID.GAP_10778;
// Rellaka import static net.runelite.api.ObjectID.GAP_10779;
ROUGH_WALL_11391, GAP_11392, TIGHTROPE_11393, GAP_11395, GAP_11396, TIGHTROPE_11397, PILE_OF_FISH, import static net.runelite.api.ObjectID.GAP_10780;
// Ardougne import static net.runelite.api.ObjectID.GAP_10820;
GAP_11406, GAP_11429, GAP_11430, STEEP_ROOF, GAP_11630, PLANK_11631, WOODEN_BEAMS, import static net.runelite.api.ObjectID.GAP_10821;
// Meiyerditch import static net.runelite.api.ObjectID.GAP_10822;
NULL_12945, ROCK_17958, ROCK_17959, ROCK_17960, BOAT_17961, NULL_18122, NULL_18124, WALL_RUBBLE, import static net.runelite.api.ObjectID.GAP_10823;
WALL_RUBBLE_18038, FLOORBOARDS, FLOORBOARDS_18071, FLOORBOARDS_18072, FLOORBOARDS_18073, NULL_18129, NULL_18130, import static net.runelite.api.ObjectID.GAP_10828;
WALL_18078, NULL_18132, NULL_18133, NULL_18083, TUNNEL_18085, SHELF_18086, SHELF_18087, WALL_18088, import static net.runelite.api.ObjectID.GAP_10832;
FLOORBOARDS_18089, FLOORBOARDS_18090, DOOR_18091, FLOORBOARDS_18093, FLOORBOARDS_18094, SHELF_18095, import static net.runelite.api.ObjectID.GAP_10859;
SHELF_18096, FLOORBOARDS_18097, FLOORBOARDS_18098, WASHING_LINE_18099, WASHING_LINE_18100, import static net.runelite.api.ObjectID.GAP_10861;
NULL_18135, NULL_18136, SHELF_18105, SHELF_18106, SHELF_18107, SHELF_18108, FLOORBOARDS_18109, import static net.runelite.api.ObjectID.GAP_10882;
FLOORBOARDS_18110, FLOORBOARDS_18112, FLOORBOARDS_18111, FLOORBOARDS_18114, FLOORBOARDS_18113, import static net.runelite.api.ObjectID.GAP_10884;
NULL_18116, FLOORBOARDS_18117, FLOORBOARDS_18118, STAIRS_DOWN, WALL_17980, import static net.runelite.api.ObjectID.GAP_11161;
// Werewolf import static net.runelite.api.ObjectID.GAP_11360;
STEPPING_STONE_11643, HURDLE, HURDLE_11639, HURDLE_11640, PIPE_11657, SKULL_SLOPE, ZIP_LINE_11644, import static net.runelite.api.ObjectID.GAP_11365;
ZIP_LINE_11645, ZIP_LINE_11646 import static net.runelite.api.ObjectID.GAP_11374;
); import static net.runelite.api.ObjectID.GAP_11375;
import static net.runelite.api.ObjectID.GAP_11376;
static final Multimap<Integer, AgilityShortcut> SHORTCUT_OBSTACLE_IDS; import static net.runelite.api.ObjectID.GAP_11383;
import static net.runelite.api.ObjectID.GAP_11392;
static final Set<Integer> TRAP_OBSTACLE_IDS = ImmutableSet.of( import static net.runelite.api.ObjectID.GAP_11395;
// Agility pyramid import static net.runelite.api.ObjectID.GAP_11396;
NULL_3550, NULL_10872, NULL_10873 import static net.runelite.api.ObjectID.GAP_11406;
); import static net.runelite.api.ObjectID.GAP_11429;
import static net.runelite.api.ObjectID.GAP_11430;
static final List<Integer> TRAP_OBSTACLE_REGIONS = ImmutableList.of(12105, 13356); import static net.runelite.api.ObjectID.GAP_11630;
import static net.runelite.api.ObjectID.HAND_HOLDS_10836;
static import static net.runelite.api.ObjectID.HAND_HOLDS_3583;
{ import static net.runelite.api.ObjectID.HURDLE;
final ImmutableMultimap.Builder<Integer, AgilityShortcut> builder = ImmutableMultimap.builder(); import static net.runelite.api.ObjectID.HURDLE_11639;
for (final AgilityShortcut item : AgilityShortcut.values()) import static net.runelite.api.ObjectID.HURDLE_11640;
{ import static net.runelite.api.ObjectID.ICE;
for (int obstacle : item.getObstacleIds()) import static net.runelite.api.ObjectID.ICE_21149;
{ import static net.runelite.api.ObjectID.ICE_21150;
builder.put(obstacle, item); import static net.runelite.api.ObjectID.ICE_21151;
} import static net.runelite.api.ObjectID.ICE_21152;
} import static net.runelite.api.ObjectID.ICE_21153;
SHORTCUT_OBSTACLE_IDS = builder.build(); import static net.runelite.api.ObjectID.ICE_21154;
} import static net.runelite.api.ObjectID.ICE_21155;
} import static net.runelite.api.ObjectID.ICE_21156;
import static net.runelite.api.ObjectID.ICICLES;
import static net.runelite.api.ObjectID.JUTTING_WALL_22552;
import static net.runelite.api.ObjectID.LADDER_16682;
import static net.runelite.api.ObjectID.LADDER_22564;
import static net.runelite.api.ObjectID.LEDGE_10781;
import static net.runelite.api.ObjectID.LEDGE_10860;
import static net.runelite.api.ObjectID.LEDGE_10886;
import static net.runelite.api.ObjectID.LEDGE_10888;
import static net.runelite.api.ObjectID.LEDGE_11366;
import static net.runelite.api.ObjectID.LEDGE_11367;
import static net.runelite.api.ObjectID.LEDGE_11369;
import static net.runelite.api.ObjectID.LEDGE_11370;
import static net.runelite.api.ObjectID.LOG_BALANCE;
import static net.runelite.api.ObjectID.LOG_BALANCE_23144;
import static net.runelite.api.ObjectID.LOG_BALANCE_23145;
import static net.runelite.api.ObjectID.LOG_BALANCE_23542;
import static net.runelite.api.ObjectID.LOG_BALANCE_3557;
import static net.runelite.api.ObjectID.LOW_WALL;
import static net.runelite.api.ObjectID.LOW_WALL_10865;
import static net.runelite.api.ObjectID.MARKET_STALL_11381;
import static net.runelite.api.ObjectID.MONKEYBARS;
import static net.runelite.api.ObjectID.MONKEYBARS_15417;
import static net.runelite.api.ObjectID.MONKEY_BARS_3564;
import static net.runelite.api.ObjectID.NARROW_WALL;
import static net.runelite.api.ObjectID.OBSTACLE_NET_20211;
import static net.runelite.api.ObjectID.OBSTACLE_NET_23134;
import static net.runelite.api.ObjectID.OBSTACLE_NET_23135;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23137;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23138;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23139;
import static net.runelite.api.ObjectID.PILE_OF_FISH;
import static net.runelite.api.ObjectID.PILLAR_3578;
import static net.runelite.api.ObjectID.PIPE_11657;
import static net.runelite.api.ObjectID.PLANK_10868;
import static net.runelite.api.ObjectID.PLANK_11631;
import static net.runelite.api.ObjectID.PLANK_3570;
import static net.runelite.api.ObjectID.PLANK_3571;
import static net.runelite.api.ObjectID.PLANK_3572;
import static net.runelite.api.ObjectID.POLEVAULT;
import static net.runelite.api.ObjectID.PYLON_22664;
import static net.runelite.api.ObjectID.ROCKS_23640;
import static net.runelite.api.ObjectID.ROCK_17958;
import static net.runelite.api.ObjectID.ROCK_17959;
import static net.runelite.api.ObjectID.ROCK_17960;
import static net.runelite.api.ObjectID.ROOF_TOP_BEAMS;
import static net.runelite.api.ObjectID.ROPESWING_23131;
import static net.runelite.api.ObjectID.ROPESWING_23132;
import static net.runelite.api.ObjectID.ROPE_15487;
import static net.runelite.api.ObjectID.ROPE_SWING;
import static net.runelite.api.ObjectID.ROUGH_WALL;
import static net.runelite.api.ObjectID.ROUGH_WALL_10093;
import static net.runelite.api.ObjectID.ROUGH_WALL_10586;
import static net.runelite.api.ObjectID.ROUGH_WALL_10833;
import static net.runelite.api.ObjectID.ROUGH_WALL_11385;
import static net.runelite.api.ObjectID.ROUGH_WALL_11391;
import static net.runelite.api.ObjectID.SHELF_18086;
import static net.runelite.api.ObjectID.SHELF_18087;
import static net.runelite.api.ObjectID.SHELF_18095;
import static net.runelite.api.ObjectID.SHELF_18096;
import static net.runelite.api.ObjectID.SHELF_18105;
import static net.runelite.api.ObjectID.SHELF_18106;
import static net.runelite.api.ObjectID.SHELF_18107;
import static net.runelite.api.ObjectID.SHELF_18108;
import static net.runelite.api.ObjectID.SKULL_SLOPE;
import static net.runelite.api.ObjectID.SKULL_SLOPE_15483;
import static net.runelite.api.ObjectID.STAIRS_10857;
import static net.runelite.api.ObjectID.STAIRS_22608;
import static net.runelite.api.ObjectID.STAIRS_22609;
import static net.runelite.api.ObjectID.STAIRS_22650;
import static net.runelite.api.ObjectID.STAIRS_22651;
import static net.runelite.api.ObjectID.STAIRS_DOWN;
import static net.runelite.api.ObjectID.STEEP_ROOF;
import static net.runelite.api.ObjectID.STEPPING_STONE_11643;
import static net.runelite.api.ObjectID.STEPPING_STONE_15412;
import static net.runelite.api.ObjectID.STEPPING_STONE_21120;
import static net.runelite.api.ObjectID.STEPPING_STONE_21126;
import static net.runelite.api.ObjectID.STEPPING_STONE_21128;
import static net.runelite.api.ObjectID.STEPPING_STONE_21129;
import static net.runelite.api.ObjectID.STEPPING_STONE_21130;
import static net.runelite.api.ObjectID.STEPPING_STONE_21131;
import static net.runelite.api.ObjectID.STEPPING_STONE_21132;
import static net.runelite.api.ObjectID.STEPPING_STONE_21133;
import static net.runelite.api.ObjectID.STEPPING_STONE_23556;
import static net.runelite.api.ObjectID.STILE_7527;
import static net.runelite.api.ObjectID.TALL_TREE_10819;
import static net.runelite.api.ObjectID.TIGHTROPE;
import static net.runelite.api.ObjectID.TIGHTROPE_10075;
import static net.runelite.api.ObjectID.TIGHTROPE_10284;
import static net.runelite.api.ObjectID.TIGHTROPE_10583;
import static net.runelite.api.ObjectID.TIGHTROPE_10834;
import static net.runelite.api.ObjectID.TIGHTROPE_11361;
import static net.runelite.api.ObjectID.TIGHTROPE_11364;
import static net.runelite.api.ObjectID.TIGHTROPE_11378;
import static net.runelite.api.ObjectID.TIGHTROPE_11393;
import static net.runelite.api.ObjectID.TIGHTROPE_11397;
import static net.runelite.api.ObjectID.TREE_11384;
import static net.runelite.api.ObjectID.TREE_11389;
import static net.runelite.api.ObjectID.TREE_BRANCH_23559;
import static net.runelite.api.ObjectID.TREE_BRANCH_23560;
import static net.runelite.api.ObjectID.TROPICAL_TREE_10357;
import static net.runelite.api.ObjectID.TROPICAL_TREE_15414;
import static net.runelite.api.ObjectID.TROPICAL_TREE_16062;
import static net.runelite.api.ObjectID.TUNNEL_18085;
import static net.runelite.api.ObjectID.TUNNEL_22557;
import static net.runelite.api.ObjectID.WALL_10084;
import static net.runelite.api.ObjectID.WALL_10777;
import static net.runelite.api.ObjectID.WALL_11373;
import static net.runelite.api.ObjectID.WALL_17980;
import static net.runelite.api.ObjectID.WALL_18078;
import static net.runelite.api.ObjectID.WALL_18088;
import static net.runelite.api.ObjectID.WALL_RUBBLE;
import static net.runelite.api.ObjectID.WALL_RUBBLE_18038;
import static net.runelite.api.ObjectID.WASHING_LINE_18099;
import static net.runelite.api.ObjectID.WASHING_LINE_18100;
import static net.runelite.api.ObjectID.WOODEN_BEAMS;
import static net.runelite.api.ObjectID.ZIP_LINE;
import static net.runelite.api.ObjectID.ZIP_LINE_11644;
import static net.runelite.api.ObjectID.ZIP_LINE_11645;
import static net.runelite.api.ObjectID.ZIP_LINE_11646;
import net.runelite.client.game.AgilityShortcut;
class Obstacles
{
static final Set<Integer> COURSE_OBSTACLE_IDS = ImmutableSet.of(
// Gnome
OBSTACLE_NET_23134, TREE_BRANCH_23559, TREE_BRANCH_23560, OBSTACLE_NET_23135, OBSTACLE_PIPE_23138,
OBSTACLE_PIPE_23139, LOG_BALANCE_23145, BALANCING_ROPE_23557,
// Brimhaven
PLANK_3572, PLANK_3571, PLANK_3570, ROPE_SWING, PILLAR_3578, LOW_WALL, LOG_BALANCE, LOG_BALANCE_3557,
BALANCING_LEDGE_3561, BALANCING_LEDGE, MONKEY_BARS_3564, BALANCING_ROPE, HAND_HOLDS_3583,
// Draynor
ROUGH_WALL, TIGHTROPE, TIGHTROPE_10075, NARROW_WALL, WALL_10084, GAP_10085, CRATE_10086, STILE_7527,
// Al-Kharid
ROUGH_WALL_10093, TIGHTROPE_10284, CABLE, ZIP_LINE, TROPICAL_TREE_10357, ROOF_TOP_BEAMS,
TIGHTROPE_10583, GAP_10352,
// Pyramid
STAIRS_10857, LOW_WALL_10865, LEDGE_10860, PLANK_10868, GAP_10882, LEDGE_10886, STAIRS_10857, GAP_10884,
GAP_10859, GAP_10861, LOW_WALL_10865, GAP_10859, LEDGE_10888, PLANK_10868, CLIMBING_ROCKS_10851, DOORWAY_10855,
// Varrock
ROUGH_WALL_10586, CLOTHES_LINE, GAP_10642, WALL_10777, GAP_10778, GAP_10779, GAP_10780, LEDGE_10781, EDGE,
// Penguin
STEPPING_STONE_21120, STEPPING_STONE_21126, STEPPING_STONE_21128, STEPPING_STONE_21129,
STEPPING_STONE_21130, STEPPING_STONE_21131, STEPPING_STONE_21132, STEPPING_STONE_21133,
ICICLES, ICE, ICE_21149, ICE_21150, ICE_21151, ICE_21152, ICE_21153, ICE_21154, ICE_21155, ICE_21156,
// Barbarian
ROPESWING_23131, LOG_BALANCE_23144, OBSTACLE_NET_20211, BALANCING_LEDGE_23547, LADDER_16682, CRUMBLING_WALL_1948,
// Canifis
TALL_TREE_10819, GAP_10820, GAP_10821, GAP_10828, GAP_10822, POLEVAULT, GAP_10823, GAP_10832,
// Ape atoll
STEPPING_STONE_15412, TROPICAL_TREE_15414, MONKEYBARS_15417, SKULL_SLOPE_15483, ROPE_15487, TROPICAL_TREE_16062,
// Falador
ROUGH_WALL_10833, TIGHTROPE_10834, HAND_HOLDS_10836, GAP_11161, GAP_11360, TIGHTROPE_11361,
TIGHTROPE_11364, GAP_11365, LEDGE_11366, LEDGE_11367, LEDGE_11369, LEDGE_11370, EDGE_11371,
// Wilderness
OBSTACLE_PIPE_23137, ROPESWING_23132, STEPPING_STONE_23556, LOG_BALANCE_23542, ROCKS_23640,
// Seers
WALL_11373, GAP_11374, TIGHTROPE_11378, GAP_11375, GAP_11376, EDGE_11377,
// Dorgesh-Kaan
CABLE_22569, CABLE_22572, LADDER_22564, JUTTING_WALL_22552, TUNNEL_22557, PYLON_22664,
CONSOLE, BOILER_22635, STAIRS_22650, STAIRS_22651, STAIRS_22609, STAIRS_22608,
// Pollniveach
BASKET_11380, MARKET_STALL_11381, BANNER_11382, GAP_11383, TREE_11384, ROUGH_WALL_11385,
MONKEYBARS, TREE_11389, DRYING_LINE,
// Rellaka
ROUGH_WALL_11391, GAP_11392, TIGHTROPE_11393, GAP_11395, GAP_11396, TIGHTROPE_11397, PILE_OF_FISH,
// Ardougne
GAP_11406, GAP_11429, GAP_11430, STEEP_ROOF, GAP_11630, PLANK_11631, WOODEN_BEAMS,
// Meiyerditch
NULL_12945, ROCK_17958, ROCK_17959, ROCK_17960, BOAT_17961, NULL_18122, NULL_18124, WALL_RUBBLE,
WALL_RUBBLE_18038, FLOORBOARDS, FLOORBOARDS_18071, FLOORBOARDS_18072, FLOORBOARDS_18073, NULL_18129, NULL_18130,
WALL_18078, NULL_18132, NULL_18133, NULL_18083, TUNNEL_18085, SHELF_18086, SHELF_18087, WALL_18088,
FLOORBOARDS_18089, FLOORBOARDS_18090, DOOR_18091, FLOORBOARDS_18093, FLOORBOARDS_18094, SHELF_18095,
SHELF_18096, FLOORBOARDS_18097, FLOORBOARDS_18098, WASHING_LINE_18099, WASHING_LINE_18100,
NULL_18135, NULL_18136, SHELF_18105, SHELF_18106, SHELF_18107, SHELF_18108, FLOORBOARDS_18109,
FLOORBOARDS_18110, FLOORBOARDS_18112, FLOORBOARDS_18111, FLOORBOARDS_18114, FLOORBOARDS_18113,
NULL_18116, FLOORBOARDS_18117, FLOORBOARDS_18118, STAIRS_DOWN, WALL_17980,
// Werewolf
STEPPING_STONE_11643, HURDLE, HURDLE_11639, HURDLE_11640, PIPE_11657, SKULL_SLOPE, ZIP_LINE_11644,
ZIP_LINE_11645, ZIP_LINE_11646
);
static final Multimap<Integer, AgilityShortcut> SHORTCUT_OBSTACLE_IDS;
static final Set<Integer> TRAP_OBSTACLE_IDS = ImmutableSet.of(
// Agility pyramid
NULL_3550, NULL_10872, NULL_10873
);
static final List<Integer> TRAP_OBSTACLE_REGIONS = ImmutableList.of(12105, 13356);
static
{
final ImmutableMultimap.Builder<Integer, AgilityShortcut> builder = ImmutableMultimap.builder();
for (final AgilityShortcut item : AgilityShortcut.values())
{
for (int obstacle : item.getObstacleIds())
{
builder.put(obstacle, item);
}
}
SHORTCUT_OBSTACLE_IDS = builder.build();
}
}

View File

@@ -1,71 +1,71 @@
/* /*
* Copyright (c) 2019, Lucas <https://github.com/lucwousin> * Copyright (c) 2019, Lucas <https://github.com/lucwousin>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.alchemicalhydra; package net.runelite.client.plugins.alchemicalhydra;
import lombok.Getter; import lombok.Getter;
import net.runelite.api.AnimationID; import net.runelite.api.AnimationID;
import net.runelite.api.ProjectileID; import net.runelite.api.ProjectileID;
import net.runelite.api.SpriteID; import net.runelite.api.SpriteID;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
enum HydraPhase enum HydraPhase
{ // Sorry for the autism { // Sorry for the autism
ONE (3, AnimationID.HYDRA_1_1, AnimationID.HYDRA_1_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, new WorldPoint(1371, 10263, 0)), ONE(3, AnimationID.HYDRA_1_1, AnimationID.HYDRA_1_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, new WorldPoint(1371, 10263, 0)),
TWO (3, AnimationID.HYDRA_2_1, AnimationID.HYDRA_2_2, 0, AnimationID.HYDRA_LIGHTNING, SpriteID.BIG_SPEC_TRANSFER, new WorldPoint(1371, 10272, 0)), TWO(3, AnimationID.HYDRA_2_1, AnimationID.HYDRA_2_2, 0, AnimationID.HYDRA_LIGHTNING, SpriteID.BIG_SPEC_TRANSFER, new WorldPoint(1371, 10272, 0)),
THREE (3, AnimationID.HYDRA_3_1, AnimationID.HYDRA_3_2, 0, AnimationID.HYDRA_FIRE, SpriteID.BIG_SUPERHEAT, new WorldPoint(1362, 10272, 0)), THREE(3, AnimationID.HYDRA_3_1, AnimationID.HYDRA_3_2, 0, AnimationID.HYDRA_FIRE, SpriteID.BIG_SUPERHEAT, new WorldPoint(1362, 10272, 0)),
FOUR (1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null); FOUR(1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null);
@Getter @Getter
private final int attacksPerSwitch; private final int attacksPerSwitch;
@Getter @Getter
private final int deathAnim1; private final int deathAnim1;
@Getter @Getter
private final int deathAnim2; private final int deathAnim2;
@Getter @Getter
private final int specProjectileId; private final int specProjectileId;
@Getter @Getter
private final int specAnimationId; private final int specAnimationId;
@Getter @Getter
private final int specImage; private final int specImage;
@Getter @Getter
private WorldPoint fountain; private WorldPoint fountain;
HydraPhase(int attacksPerSwitch, int deathAnim1, int deathAnim2, int specProjectileId, int specAnimationId, int specImage, WorldPoint fountain) HydraPhase(int attacksPerSwitch, int deathAnim1, int deathAnim2, int specProjectileId, int specAnimationId, int specImage, WorldPoint fountain)
{ {
this.attacksPerSwitch = attacksPerSwitch; this.attacksPerSwitch = attacksPerSwitch;
this.deathAnim1 = deathAnim1; this.deathAnim1 = deathAnim1;
this.deathAnim2 = deathAnim2; this.deathAnim2 = deathAnim2;
this.specProjectileId = specProjectileId; this.specProjectileId = specProjectileId;
this.specAnimationId = specAnimationId; this.specAnimationId = specAnimationId;
this.specImage = specImage; this.specImage = specImage;
this.fountain = fountain; this.fountain = fountain;
} }
} }

View File

@@ -117,9 +117,9 @@ public class HydraPlugin extends Plugin
{ {
if (hydra != null) if (hydra != null)
{ {
removeOverlays(); removeOverlays();
hydra = null; hydra = null;
} }
return; return;
} }
@@ -305,8 +305,8 @@ public class HydraPlugin extends Plugin
} }
else else
{ {
hydra.setNextSwitch(hydra.getNextSwitch() - 1); hydra.setNextSwitch(hydra.getNextSwitch() - 1);
hydra.setLastAttack(hydra.getNextAttack()); hydra.setLastAttack(hydra.getNextAttack());
} }
hydra.setAttackCount(hydra.getAttackCount() + 1); hydra.setAttackCount(hydra.getAttackCount() + 1);

View File

@@ -1,145 +1,147 @@
/* /*
* Copyright (c) 2019, Lucas <https://github.com/lucwousin> * Copyright (c) 2019, Lucas <https://github.com/lucwousin>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.alchemicalhydra; package net.runelite.client.plugins.alchemicalhydra;
import java.awt.Color; import java.awt.BasicStroke;
import java.awt.Dimension; import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Dimension;
import java.awt.Polygon; import java.awt.Graphics2D;
import java.awt.geom.Area; import java.awt.Polygon;
import java.util.Collection; import java.awt.geom.Area;
import java.util.Map; import java.util.Collection;
import javax.inject.Inject; import java.util.Map;
import javax.inject.Singleton; import javax.inject.Inject;
import net.runelite.api.Client; import javax.inject.Singleton;
import static net.runelite.api.Perspective.getCanvasTileAreaPoly; import net.runelite.api.Client;
import net.runelite.api.Projectile; import static net.runelite.api.Perspective.getCanvasTileAreaPoly;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.Projectile;
import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldArea;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.api.coords.WorldPoint;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
@Singleton
class HydraPoisonOverlay extends Overlay @Singleton
{ class HydraPoisonOverlay extends Overlay
private final HydraPlugin plugin; {
private final Client client; private final HydraPlugin plugin;
private final Client client;
@Inject
public HydraPoisonOverlay(Client client, HydraPlugin plugin) @Inject
{ public HydraPoisonOverlay(Client client, HydraPlugin plugin)
setPosition(OverlayPosition.DYNAMIC); {
setLayer(OverlayLayer.UNDER_WIDGETS); setPosition(OverlayPosition.DYNAMIC);
this.plugin = plugin; setLayer(OverlayLayer.UNDER_WIDGETS);
this.client = client; this.plugin = plugin;
} this.client = client;
}
@Override
public Dimension render(Graphics2D graphics) @Override
{ public Dimension render(Graphics2D graphics)
Hydra hydra = plugin.getHydra(); {
final Map<LocalPoint, Projectile> poisonProjectiles = plugin.getPoisonProjectiles(); Hydra hydra = plugin.getHydra();
final Map<LocalPoint, Projectile> poisonProjectiles = plugin.getPoisonProjectiles();
if (!poisonProjectiles.isEmpty())
{ if (!poisonProjectiles.isEmpty())
drawPoisonArea(graphics, poisonProjectiles); {
} drawPoisonArea(graphics, poisonProjectiles);
}
if (hydra.getPhase().getFountain() != null)
{ if (hydra.getPhase().getFountain() != null)
drawFountain(graphics, hydra); {
} drawFountain(graphics, hydra);
}
return null;
} return null;
}
private void drawPoisonArea(Graphics2D graphics, Map<LocalPoint, Projectile> poisonProjectiles)
{ private void drawPoisonArea(Graphics2D graphics, Map<LocalPoint, Projectile> poisonProjectiles)
Area poisonTiles = new Area(); {
Area poisonTiles = new Area();
for (Map.Entry<LocalPoint, Projectile> entry : poisonProjectiles.entrySet())
{ for (Map.Entry<LocalPoint, Projectile> entry : poisonProjectiles.entrySet())
if (entry.getValue().getEndCycle() < client.getGameCycle()) {
{ if (entry.getValue().getEndCycle() < client.getGameCycle())
continue; {
} continue;
}
LocalPoint point = entry.getKey();
Polygon poly = getCanvasTileAreaPoly(client, point, 3); LocalPoint point = entry.getKey();
Polygon poly = getCanvasTileAreaPoly(client, point, 3);
if (poly != null)
{ if (poly != null)
poisonTiles.add(new Area(poly)); {
} poisonTiles.add(new Area(poly));
} }
}
graphics.setPaintMode();
graphics.setColor(new Color(255, 0, 0, 100)); graphics.setPaintMode();
graphics.draw(poisonTiles); graphics.setColor(new Color(255, 0, 0, 100));
graphics.setColor(new Color(255, 0, 0, 50)); graphics.draw(poisonTiles);
graphics.fill(poisonTiles); graphics.setColor(new Color(255, 0, 0, 50));
} graphics.fill(poisonTiles);
}
private void drawFountain(Graphics2D graphics, Hydra hydra)
{ private void drawFountain(Graphics2D graphics, Hydra hydra)
Collection<WorldPoint> fountainWorldPoint = WorldPoint.toLocalInstance(client, hydra.getPhase().getFountain()); // thanks {
if (fountainWorldPoint.size() > 1) // for Collection<WorldPoint> fountainWorldPoint = WorldPoint.toLocalInstance(client, hydra.getPhase().getFountain()); // thanks
{ if (fountainWorldPoint.size() > 1) // for
return; {
} return;
}
WorldPoint wp = null;
for (WorldPoint p : fountainWorldPoint) // this WorldPoint wp = null;
{ for (WorldPoint p : fountainWorldPoint) // this
wp = p; {
} wp = p;
}
LocalPoint fountainPoint = wp == null ? null : LocalPoint.fromWorld(client, wp); // trash
LocalPoint fountainPoint = wp == null ? null : LocalPoint.fromWorld(client, wp); // trash
if (fountainPoint == null || hydra.isWeakened()) // I
{ if (fountainPoint == null || hydra.isWeakened()) // I
return; {
} return;
}
final Polygon poly = getCanvasTileAreaPoly(client, fountainPoint, 3); // don't
final Polygon poly = getCanvasTileAreaPoly(client, fountainPoint, 3); // don't
if (poly == null)
{ if (poly == null)
return; {
} return;
}
Color color = new Color(255, 0, 0, 100); // like
Color color = new Color(255, 0, 0, 100); // like
if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
{ // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
color = new Color(0, 255, 0, 100); { // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE
} color = new Color(0, 255, 0, 100);
}
graphics.setColor(color);
graphics.draw(poly); graphics.setColor(color);
} graphics.setStroke(new BasicStroke(3));
} graphics.draw(poly);
}
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, https://runelitepl.us * Copyright (c) 2018, DennisDeV <https://github.com/DevDennis>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -24,11 +24,10 @@
*/ */
package net.runelite.client.plugins.antidrag; package net.runelite.client.plugins.antidrag;
import net.runelite.api.Constants;
import java.awt.Color; import java.awt.Color;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import net.runelite.client.config.Alpha;
import net.runelite.api.Constants; import net.runelite.api.Constants;
import net.runelite.client.config.Alpha;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;

View File

@@ -23,30 +23,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.antidrag; package net.runelite.client.plugins.antidrag;
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.
*/
import com.google.inject.Provides; import com.google.inject.Provides;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;

View File

@@ -32,7 +32,6 @@ import java.util.Map;
import net.runelite.api.ProjectileID; import net.runelite.api.ProjectileID;
public enum AoeProjectileInfo public enum AoeProjectileInfo
{ {
LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 5), LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 5),
@@ -108,10 +107,10 @@ public enum AoeProjectileInfo
ADDY_DRAG_POISON(ProjectileID.ADDY_DRAG_POISON, 1), ADDY_DRAG_POISON(ProjectileID.ADDY_DRAG_POISON, 1),
/** /**
* the Breath of the Drake * the Breath of the Drake
*/ */
DRAKE_BREATH(ProjectileID.DRAKE_BREATH, 1), DRAKE_BREATH(ProjectileID.DRAKE_BREATH, 1),
/** /**
* Cerbs fire * Cerbs fire
*/ */

View File

@@ -71,7 +71,7 @@ public class AoeWarningOverlay extends Overlay
{ {
for (WorldPoint point : plugin.getLightningTrail()) for (WorldPoint point : plugin.getLightningTrail())
{ {
drawTile(graphics, point, new Color(0,150,200), 2, 150, 50); drawTile(graphics, point, new Color(0, 150, 200), 2, 150, 50);
} }
for (WorldPoint point : plugin.getAcidTrail()) for (WorldPoint point : plugin.getAcidTrail())
{ {
@@ -84,7 +84,7 @@ public class AoeWarningOverlay extends Overlay
Instant now = Instant.now(); Instant now = Instant.now();
Map<Projectile, AoeProjectile> projectiles = plugin.getProjectiles(); Map<Projectile, AoeProjectile> projectiles = plugin.getProjectiles();
for (Iterator<AoeProjectile> it = projectiles.values().iterator(); it.hasNext();) for (Iterator<AoeProjectile> it = projectiles.values().iterator(); it.hasNext(); )
{ {
AoeProjectile aoeProjectile = it.next(); AoeProjectile aoeProjectile = it.next();
@@ -145,18 +145,22 @@ public class AoeWarningOverlay extends Overlay
return null; return null;
} }
private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha)
{
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
if (point.distanceTo(playerLocation) >= 32) { if (point.distanceTo(playerLocation) >= 32)
{
return; return;
} }
LocalPoint lp = LocalPoint.fromWorld(client, point); LocalPoint lp = LocalPoint.fromWorld(client, point);
if (lp == null) { if (lp == null)
{
return; return;
} }
Polygon poly = Perspective.getCanvasTilePoly(client, lp); Polygon poly = Perspective.getCanvasTilePoly(client, lp);
if (poly == null) { if (poly == null)
{
return; return;
} }
//OverlayUtil.renderPolygon(graphics, poly, color); //OverlayUtil.renderPolygon(graphics, poly, color);

View File

@@ -301,8 +301,8 @@ public class AoeWarningPlugin extends Plugin
return config.isXarpusEnabled(); return config.isXarpusEnabled();
case ADDY_DRAG_POISON: case ADDY_DRAG_POISON:
return config.addyDrags(); return config.addyDrags();
case DRAKE_BREATH: case DRAKE_BREATH:
return config.isDrakeEnabled(); return config.isDrakeEnabled();
case CERB_FIRE: case CERB_FIRE:
return config.isCerbFireEnabled(); return config.isCerbFireEnabled();
} }

View File

@@ -73,7 +73,7 @@ public class BombOverlay extends Overlay
//Utilized from the npc highlight code for formatting text being displayed on the client canvas. //Utilized from the npc highlight code for formatting text being displayed on the client canvas.
private static final NumberFormat TIME_LEFT_FORMATTER = private static final NumberFormat TIME_LEFT_FORMATTER =
DecimalFormat.getInstance(Locale.US); DecimalFormat.getInstance(Locale.US);
static static
{ {
@@ -157,22 +157,22 @@ public class BombOverlay extends Overlay
Instant now = Instant.now(); Instant now = Instant.now();
double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() - double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() -
bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) - bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0; (now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
//divided by 1000.00 because of milliseconds :) //divided by 1000.00 because of milliseconds :)
timeLeft = Math.max(0.0, timeLeft); timeLeft = Math.max(0.0, timeLeft);
String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft); String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft);
int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString); int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString);
int textHeight = graphics.getFontMetrics().getAscent(); int textHeight = graphics.getFontMetrics().getAscent();
Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(), Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(),
localLoc.getY(), bomb.getWorldLocation().getPlane()); localLoc.getY(), bomb.getWorldLocation().getPlane());
if (canvasPoint != null) if (canvasPoint != null)
{ {
Point canvasCenterPoint = new Point( Point canvasCenterPoint = new Point(
canvasPoint.getX() - textWidth / 2, canvasPoint.getX() - textWidth / 2,
canvasPoint.getY() + textHeight / 2); canvasPoint.getY() + textHeight / 2);
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code); OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
} }

View File

@@ -1,113 +1,113 @@
/* /*
* Copyright (c) 2018, Ron Young <https://github.com/raiyni> * Copyright (c) 2018, Ron Young <https://github.com/raiyni>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.banktags; package net.runelite.client.plugins.banktags;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
@ConfigGroup("banktags") @ConfigGroup("banktags")
public interface BankTagsConfig extends Config public interface BankTagsConfig extends Config
{ {
@ConfigItem( @ConfigItem(
keyName = "useTabs", keyName = "useTabs",
name = "Use Tag Tabs", name = "Use Tag Tabs",
description = "Enable the ability to add tabs to your bank which allow fast access to tags.", description = "Enable the ability to add tabs to your bank which allow fast access to tags.",
position = 1 position = 1
) )
default boolean tabs() default boolean tabs()
{ {
return true; return true;
} }
@ConfigItem( @ConfigItem(
keyName = "rememberTab", keyName = "rememberTab",
name = "Remember last Tag Tab", name = "Remember last Tag Tab",
description = "Enable the ability to remember last Tag Tab when closing/opening the bank.", description = "Enable the ability to remember last Tag Tab when closing/opening the bank.",
position = 2 position = 2
) )
default boolean rememberTab() default boolean rememberTab()
{ {
return true; return true;
} }
@ConfigItem( @ConfigItem(
keyName = "removeSeparators", keyName = "removeSeparators",
name = "Remove tab separators in Tag Tabs", name = "Remove tab separators in Tag Tabs",
description = "Removes tab separators and corrects item layouts in Tag Tabs to mimic a regular tab", description = "Removes tab separators and corrects item layouts in Tag Tabs to mimic a regular tab",
position = 3 position = 3
) )
default boolean removeSeparators() default boolean removeSeparators()
{ {
return true; return true;
} }
@ConfigItem( @ConfigItem(
keyName = "hidePlaceholders", keyName = "hidePlaceholders",
name = "Hide placeholders", name = "Hide placeholders",
description = "Hide placeholders in tag tabs or tag search.", description = "Hide placeholders in tag tabs or tag search.",
position = 4 position = 4
) )
default boolean hidePlaceholders() default boolean hidePlaceholders()
{ {
return false; return false;
} }
@ConfigItem( @ConfigItem(
keyName = "position", keyName = "position",
name = "", name = "",
description = "", description = "",
hidden = true hidden = true
) )
default int position() default int position()
{ {
return 0; return 0;
} }
@ConfigItem( @ConfigItem(
keyName = "position", keyName = "position",
name = "", name = "",
description = "" description = ""
) )
void position(int idx); void position(int idx);
@ConfigItem( @ConfigItem(
keyName = "tab", keyName = "tab",
name = "", name = "",
description = "", description = "",
hidden = true hidden = true
) )
default String tab() default String tab()
{ {
return ""; return "";
} }
@ConfigItem( @ConfigItem(
keyName = "tab", keyName = "tab",
name = "", name = "",
description = "" description = ""
) )
void tab(String tab); void tab(String tab);
} }

View File

@@ -24,7 +24,6 @@
*/ */
package net.runelite.client.plugins.barbarianassault; package net.runelite.client.plugins.barbarianassault;
import com.google.common.collect.ImmutableList;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;

View File

@@ -1,44 +1,44 @@
/* /*
* Copyright (c) 2018, whartd <github.com/whartd> * Copyright (c) 2018, whartd <github.com/whartd>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.barbarianassault; package net.runelite.client.plugins.barbarianassault;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
enum HealerTeam enum HealerTeam
{ {
TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115), TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115),
TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115), TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115),
TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115), TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115),
TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115); TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115);
private WidgetInfo teammate; private WidgetInfo teammate;
private Point offset; private Point offset;
private int width; private int width;
} }

View File

@@ -1,99 +1,99 @@
/* /*
* Copyright (c) 2018, Seth <http://github.com/sethtroll> * Copyright (c) 2018, Seth <http://github.com/sethtroll>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.barrows; package net.runelite.client.plugins.barrows;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.PanelComponent;
public class BarrowsBrotherSlainOverlay extends Overlay public class BarrowsBrotherSlainOverlay extends Overlay
{ {
private final Client client; private final Client client;
private final PanelComponent panelComponent = new PanelComponent(); private final PanelComponent panelComponent = new PanelComponent();
@Inject @Inject
private BarrowsBrotherSlainOverlay(BarrowsPlugin plugin, Client client) private BarrowsBrotherSlainOverlay(BarrowsPlugin plugin, Client client)
{ {
super(plugin); super(plugin);
setPosition(OverlayPosition.TOP_LEFT); setPosition(OverlayPosition.TOP_LEFT);
setPriority(OverlayPriority.LOW); setPriority(OverlayPriority.LOW);
this.client = client; this.client = client;
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Barrows overlay")); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Barrows overlay"));
} }
@Override @Override
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
// Do not display overlay if potential is null/hidden // Do not display overlay if potential is null/hidden
final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL); final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL);
if (potential == null || potential.isHidden()) if (potential == null || potential.isHidden())
{ {
return null; return null;
} }
// Hide original overlay // Hide original overlay
final Widget barrowsBrothers = client.getWidget(WidgetInfo.BARROWS_BROTHERS); final Widget barrowsBrothers = client.getWidget(WidgetInfo.BARROWS_BROTHERS);
if (barrowsBrothers != null) if (barrowsBrothers != null)
{ {
barrowsBrothers.setHidden(true); barrowsBrothers.setHidden(true);
potential.setHidden(true); potential.setHidden(true);
} }
panelComponent.getChildren().clear(); panelComponent.getChildren().clear();
for (BarrowsBrothers brother : BarrowsBrothers.values()) for (BarrowsBrothers brother : BarrowsBrothers.values())
{ {
final boolean brotherSlain = client.getVar(brother.getKilledVarbit()) > 0; final boolean brotherSlain = client.getVar(brother.getKilledVarbit()) > 0;
String slain = brotherSlain ? "\u2713" : "\u2717"; String slain = brotherSlain ? "\u2713" : "\u2717";
panelComponent.getChildren().add(LineComponent.builder() panelComponent.getChildren().add(LineComponent.builder()
.left(brother.getName()) .left(brother.getName())
.right(slain) .right(slain)
.rightColor(brotherSlain ? Color.GREEN : Color.RED) .rightColor(brotherSlain ? Color.GREEN : Color.RED)
.build()); .build());
} }
float rewardPercent = client.getVar(Varbits.BARROWS_REWARD_POTENTIAL) / 10.0f; float rewardPercent = client.getVar(Varbits.BARROWS_REWARD_POTENTIAL) / 10.0f;
panelComponent.getChildren().add(LineComponent.builder() panelComponent.getChildren().add(LineComponent.builder()
.left("Potential") .left("Potential")
.right(rewardPercent != 0 ? rewardPercent + "%" : "0%") .right(rewardPercent != 0 ? rewardPercent + "%" : "0%")
.rightColor(rewardPercent >= 73.0f && rewardPercent <= 88.0f ? Color.GREEN : rewardPercent < 65.6f ? Color.WHITE : Color.YELLOW) .rightColor(rewardPercent >= 73.0f && rewardPercent <= 88.0f ? Color.GREEN : rewardPercent < 65.6f ? Color.WHITE : Color.YELLOW)
.build()); .build());
return panelComponent.render(graphics); return panelComponent.render(graphics);
} }
} }

View File

@@ -1,243 +1,244 @@
/* /*
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com> * Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.barrows; package net.runelite.client.plugins.barrows;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameObject; import net.runelite.api.GameObject;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.NPCComposition; import net.runelite.api.NPCComposition;
import net.runelite.api.ObjectComposition; import net.runelite.api.ObjectComposition;
import net.runelite.api.Perspective; import net.runelite.api.Perspective;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.WallObject; import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
class BarrowsOverlay extends Overlay class BarrowsOverlay extends Overlay
{ {
private static final int MAX_DISTANCE = 2350; private static final int MAX_DISTANCE = 2350;
private final Client client; private final Client client;
private final BarrowsPlugin plugin; private final BarrowsPlugin plugin;
private final BarrowsConfig config; private final BarrowsConfig config;
@Inject @Inject
private BarrowsOverlay(Client client, BarrowsPlugin plugin, BarrowsConfig config) private BarrowsOverlay(Client client, BarrowsPlugin plugin, BarrowsConfig config)
{ {
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS); setLayer(OverlayLayer.ABOVE_WIDGETS);
this.client = client; this.client = client;
this.plugin = plugin; this.plugin = plugin;
this.config = config; this.config = config;
} }
@Override @Override
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
Player local = client.getLocalPlayer(); Player local = client.getLocalPlayer();
final Color npcColor = getMinimapDotColor(1); final Color npcColor = getMinimapDotColor(1);
final Color playerColor = getMinimapDotColor(2); final Color playerColor = getMinimapDotColor(2);
Widget puzzleAnswer = plugin.getPuzzleAnswer(); Widget puzzleAnswer = plugin.getPuzzleAnswer();
// tunnels are only on z=0 // tunnels are only on z=0
if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && config.showMinimap()) if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && config.showMinimap())
{ {
// NPC dots // NPC dots
graphics.setColor(npcColor); graphics.setColor(npcColor);
final List<NPC> npcs = client.getNpcs(); final List<NPC> npcs = client.getNpcs();
for (NPC npc : npcs) for (NPC npc : npcs)
{ {
final NPCComposition composition = npc.getComposition(); final NPCComposition composition = npc.getComposition();
if (composition != null && !composition.isMinimapVisible()) if (composition != null && !composition.isMinimapVisible())
{ {
continue; continue;
} }
net.runelite.api.Point minimapLocation = npc.getMinimapLocation(); net.runelite.api.Point minimapLocation = npc.getMinimapLocation();
if (minimapLocation != null) if (minimapLocation != null)
{ {
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4); graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
} }
} }
// Player dots // Player dots
graphics.setColor(playerColor); graphics.setColor(playerColor);
final List<Player> players = client.getPlayers(); final List<Player> players = client.getPlayers();
for (Player player : players) for (Player player : players)
{ {
if (player == local) if (player == local)
{ {
// Skip local player as we draw square for it later // Skip local player as we draw square for it later
continue; continue;
} }
net.runelite.api.Point minimapLocation = player.getMinimapLocation(); net.runelite.api.Point minimapLocation = player.getMinimapLocation();
if (minimapLocation != null) if (minimapLocation != null)
{ {
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4); graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
} }
} }
// Render barrows walls/doors // Render barrows walls/doors
renderObjects(graphics, local); renderObjects(graphics, local);
// Local player square // Local player square
graphics.setColor(playerColor); graphics.setColor(playerColor);
graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3); graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3);
} }
else if (config.showBrotherLoc()) else if (config.showBrotherLoc())
{ {
renderBarrowsBrothers(graphics); renderBarrowsBrothers(graphics);
} }
if (puzzleAnswer != null && config.showPuzzleAnswer() && !puzzleAnswer.isHidden()) if (puzzleAnswer != null && config.showPuzzleAnswer() && !puzzleAnswer.isHidden())
{ {
Rectangle answerRect = puzzleAnswer.getBounds(); Rectangle answerRect = puzzleAnswer.getBounds();
graphics.setColor(Color.GREEN); graphics.setColor(Color.GREEN);
graphics.draw(answerRect); graphics.draw(answerRect);
} }
return null; return null;
} }
private void renderObjects(Graphics2D graphics, Player localPlayer) private void renderObjects(Graphics2D graphics, Player localPlayer)
{ {
LocalPoint localLocation = localPlayer.getLocalLocation(); LocalPoint localLocation = localPlayer.getLocalLocation();
for (WallObject wall : plugin.getWalls()) for (WallObject wall : plugin.getWalls())
{ {
LocalPoint location = wall.getLocalLocation(); LocalPoint location = wall.getLocalLocation();
if (localLocation.distanceTo(location) <= MAX_DISTANCE) if (localLocation.distanceTo(location) <= MAX_DISTANCE)
{ {
renderWalls(graphics, wall); renderWalls(graphics, wall);
} }
} }
for (GameObject ladder : plugin.getLadders()) for (GameObject ladder : plugin.getLadders())
{ {
LocalPoint location = ladder.getLocalLocation(); LocalPoint location = ladder.getLocalLocation();
if (localLocation.distanceTo(location) <= MAX_DISTANCE) if (localLocation.distanceTo(location) <= MAX_DISTANCE)
{ {
renderLadders(graphics, ladder); renderLadders(graphics, ladder);
} }
} }
} }
private void renderWalls(Graphics2D graphics, WallObject wall) private void renderWalls(Graphics2D graphics, WallObject wall)
{ {
net.runelite.api.Point minimapLocation = wall.getMinimapLocation(); net.runelite.api.Point minimapLocation = wall.getMinimapLocation();
if (minimapLocation == null) if (minimapLocation == null)
{ {
return; return;
} }
ObjectComposition objectComp = client.getObjectDefinition(wall.getId()); ObjectComposition objectComp = client.getObjectDefinition(wall.getId());
ObjectComposition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null; ObjectComposition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null;
if (impostor != null && impostor.getActions()[0] != null) if (impostor != null && impostor.getActions()[0] != null)
{ {
graphics.setColor(Color.green); graphics.setColor(Color.green);
} }
else else
{ {
graphics.setColor(Color.gray); graphics.setColor(Color.gray);
} }
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3); graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3);
} }
/** /**
* Get minimap dot color from client * Get minimap dot color from client
* @param typeIndex index of minimap dot type (1 npcs, 2 players) *
* @return color * @param typeIndex index of minimap dot type (1 npcs, 2 players)
*/ * @return color
private Color getMinimapDotColor(int typeIndex) */
{ private Color getMinimapDotColor(int typeIndex)
final int pixel = client.getMapDots()[typeIndex].getPixels()[1]; {
return new Color(pixel); final int pixel = client.getMapDots()[typeIndex].getPixels()[1];
} return new Color(pixel);
}
private void renderLadders(Graphics2D graphics, GameObject ladder)
{ private void renderLadders(Graphics2D graphics, GameObject ladder)
net.runelite.api.Point minimapLocation = ladder.getMinimapLocation(); {
net.runelite.api.Point minimapLocation = ladder.getMinimapLocation();
if (minimapLocation == null)
{ if (minimapLocation == null)
return; {
} return;
}
ObjectComposition objectComp = client.getObjectDefinition(ladder.getId());
ObjectComposition objectComp = client.getObjectDefinition(ladder.getId());
if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null)
{ if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null)
graphics.setColor(Color.orange); {
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6); graphics.setColor(Color.orange);
} graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6);
} }
}
private void renderBarrowsBrothers(Graphics2D graphics)
{ private void renderBarrowsBrothers(Graphics2D graphics)
for (BarrowsBrothers brother : BarrowsBrothers.values()) {
{ for (BarrowsBrothers brother : BarrowsBrothers.values())
LocalPoint localLocation = LocalPoint.fromWorld(client, brother.getLocation()); {
LocalPoint localLocation = LocalPoint.fromWorld(client, brother.getLocation());
if (localLocation == null)
{ if (localLocation == null)
continue; {
} continue;
}
String brotherLetter = Character.toString(brother.getName().charAt(0));
net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics, String brotherLetter = Character.toString(brother.getName().charAt(0));
localLocation, brotherLetter); net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics,
localLocation, brotherLetter);
if (minimapText != null)
{ if (minimapText != null)
graphics.setColor(Color.black); {
graphics.drawString(brotherLetter, minimapText.getX() + 1, minimapText.getY() + 1); graphics.setColor(Color.black);
graphics.drawString(brotherLetter, minimapText.getX() + 1, minimapText.getY() + 1);
if (client.getVar(brother.getKilledVarbit()) > 0)
{ if (client.getVar(brother.getKilledVarbit()) > 0)
graphics.setColor(config.deadBrotherLocColor()); {
} graphics.setColor(config.deadBrotherLocColor());
else }
{ else
graphics.setColor(config.brotherLocColor()); {
} graphics.setColor(config.brotherLocColor());
}
graphics.drawString(brotherLetter, minimapText.getX(), minimapText.getY());
} graphics.drawString(brotherLetter, minimapText.getX(), minimapText.getY());
} }
} }
}
} }

View File

@@ -81,13 +81,13 @@ public class BarrowsPlugin extends Plugin
{ {
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private static final Set<Integer> BARROWS_WALLS = Sets.newHashSet private static final Set<Integer> BARROWS_WALLS = Sets.newHashSet
( (
ObjectID.DOOR_20678, NullObjectID.NULL_20681, NullObjectID.NULL_20682, NullObjectID.NULL_20683, NullObjectID.NULL_20684, NullObjectID.NULL_20685, NullObjectID.NULL_20686, NullObjectID.NULL_20687, ObjectID.DOOR_20678, NullObjectID.NULL_20681, NullObjectID.NULL_20682, NullObjectID.NULL_20683, NullObjectID.NULL_20684, NullObjectID.NULL_20685, NullObjectID.NULL_20686, NullObjectID.NULL_20687,
NullObjectID.NULL_20688, NullObjectID.NULL_20689, NullObjectID.NULL_20690, NullObjectID.NULL_20691, NullObjectID.NULL_20692, NullObjectID.NULL_20693, NullObjectID.NULL_20694, NullObjectID.NULL_20695, NullObjectID.NULL_20688, NullObjectID.NULL_20689, NullObjectID.NULL_20690, NullObjectID.NULL_20691, NullObjectID.NULL_20692, NullObjectID.NULL_20693, NullObjectID.NULL_20694, NullObjectID.NULL_20695,
NullObjectID.NULL_20696, ObjectID.DOOR_20697, NullObjectID.NULL_20700, NullObjectID.NULL_20701, NullObjectID.NULL_20702, NullObjectID.NULL_20703, NullObjectID.NULL_20704, NullObjectID.NULL_20705, NullObjectID.NULL_20696, ObjectID.DOOR_20697, NullObjectID.NULL_20700, NullObjectID.NULL_20701, NullObjectID.NULL_20702, NullObjectID.NULL_20703, NullObjectID.NULL_20704, NullObjectID.NULL_20705,
NullObjectID.NULL_20706, NullObjectID.NULL_20707, NullObjectID.NULL_20708, NullObjectID.NULL_20709, NullObjectID.NULL_20710, NullObjectID.NULL_20711, NullObjectID.NULL_20712, NullObjectID.NULL_20713, NullObjectID.NULL_20706, NullObjectID.NULL_20707, NullObjectID.NULL_20708, NullObjectID.NULL_20709, NullObjectID.NULL_20710, NullObjectID.NULL_20711, NullObjectID.NULL_20712, NullObjectID.NULL_20713,
NullObjectID.NULL_20714, NullObjectID.NULL_20715, NullObjectID.NULL_20728, NullObjectID.NULL_20730 NullObjectID.NULL_20714, NullObjectID.NULL_20715, NullObjectID.NULL_20728, NullObjectID.NULL_20730
); );
private static final Set<Integer> BARROWS_LADDERS = Sets.newHashSet(NullObjectID.NULL_20675, NullObjectID.NULL_20676, NullObjectID.NULL_20677); private static final Set<Integer> BARROWS_LADDERS = Sets.newHashSet(NullObjectID.NULL_20675, NullObjectID.NULL_20676, NullObjectID.NULL_20677);
private static final ImmutableList<WidgetInfo> POSSIBLE_SOLUTIONS = ImmutableList.of( private static final ImmutableList<WidgetInfo> POSSIBLE_SOLUTIONS = ImmutableList.of(

View File

@@ -81,26 +81,6 @@ public interface BAToolsConfig extends Config
return false; return false;
} }
@ConfigItem(
keyName = "antiDrag",
name = "Anti Drag",
description = "asd"
)
default boolean antiDrag()
{
return false;
}
@ConfigItem(
keyName = "antiDragDelay",
name = "Anti Drag Delay",
description = "asd"
)
default int antiDragDelay()
{
return 5;
}
@ConfigItem( @ConfigItem(
keyName = "eggBoi", keyName = "eggBoi",
name = "Collector helper", name = "Collector helper",

View File

@@ -25,14 +25,14 @@
package net.runelite.client.plugins.batools; package net.runelite.client.plugins.batools;
import java.awt.Color; import java.awt.Color;
import static java.awt.Color.GREEN;
import static java.awt.Color.RED;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import javax.inject.Inject; import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.NPCComposition;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
@@ -42,16 +42,6 @@ import net.runelite.client.ui.overlay.OverlayUtil;
public class BAToolsOverlay extends Overlay public class BAToolsOverlay extends Overlay
{ {
private static final Color RED = new Color(221, 44, 0);
private static final Color GREEN = new Color(0, 200, 83);
private static final Color ORANGE = new Color(255, 109, 0);
private static final Color YELLOW = new Color(255, 214, 0);
private static final Color CYAN = new Color(0, 184, 212);
private static final Color BLUE = new Color(41, 98, 255);
private static final Color DEEP_PURPLE = new Color(98, 0, 234);
private static final Color PURPLE = new Color(170, 0, 255);
private static final Color GRAY = new Color(158, 158, 158);
private final BAToolsConfig config; private final BAToolsConfig config;
private BAToolsPlugin plugin; private BAToolsPlugin plugin;

View File

@@ -24,6 +24,7 @@
*/ */
package net.runelite.client.plugins.batools; package net.runelite.client.plugins.batools;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -61,9 +62,23 @@ import net.runelite.api.events.NpcSpawned;
import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.WidgetLoaded; import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID; import static net.runelite.api.widgets.WidgetID.BA_REWARD_GROUP_ID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.chat.ChatMessageManager; import static net.runelite.api.widgets.WidgetInfo.BA_ATK_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_ATK_LISTEN_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_ATK_ROLE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_COLL_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_COLL_LISTEN_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_COLL_ROLE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_DEF_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_DEF_ROLE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_HEAL_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_HEAL_LISTEN_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_REWARD_TEXT;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_FOUR;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_ONE;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_THREE;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_TWO;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
@@ -93,6 +108,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
private int currentWave = 1; private int currentWave = 1;
private static final int BA_WAVE_NUM_INDEX = 2; private static final int BA_WAVE_NUM_INDEX = 2;
private final List<MenuEntry> entries = new ArrayList<>(); private final List<MenuEntry> entries = new ArrayList<>();
private ImmutableMap<WidgetInfo, Boolean> originalAttackStyles;
private HashMap<Integer, Instant> foodPressed = new HashMap<>(); private HashMap<Integer, Instant> foodPressed = new HashMap<>();
private CycleCounter counter; private CycleCounter counter;
private Actor lastInteracted; private Actor lastInteracted;
@@ -141,7 +157,6 @@ public class BAToolsPlugin extends Plugin implements KeyListener
wave_start = Instant.now(); wave_start = Instant.now();
lastInteracted = null; lastInteracted = null;
foodPressed.clear(); foodPressed.clear();
client.setInventoryDragDelay(config.antiDragDelay());
keyManager.registerKeyListener(this); keyManager.registerKeyListener(this);
} }
@@ -153,7 +168,6 @@ public class BAToolsPlugin extends Plugin implements KeyListener
inGameBit = 0; inGameBit = 0;
lastInteracted = null; lastInteracted = null;
overlayManager.remove(overlay); overlayManager.remove(overlay);
client.setInventoryDragDelay(5);
keyManager.unregisterKeyListener(this); keyManager.unregisterKeyListener(this);
shiftDown = false; shiftDown = false;
} }
@@ -161,9 +175,9 @@ public class BAToolsPlugin extends Plugin implements KeyListener
@Subscribe @Subscribe
public void onWidgetLoaded(WidgetLoaded event) public void onWidgetLoaded(WidgetLoaded event)
{ {
if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID) if (event.getGroupId() == BA_REWARD_GROUP_ID)
{ {
Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT); Widget rewardWidget = client.getWidget(BA_REWARD_TEXT);
if (rewardWidget != null && rewardWidget.getText().contains("<br>5")) if (rewardWidget != null && rewardWidget.getText().contains("<br>5"))
{ {
tickNum = 0; tickNum = 0;
@@ -174,11 +188,6 @@ public class BAToolsPlugin extends Plugin implements KeyListener
@Subscribe @Subscribe
public void onGameTick(GameTick event) public void onGameTick(GameTick event)
{ {
if (config.antiDrag())
{
client.setInventoryDragDelay(config.antiDragDelay());
}
Widget callWidget = getWidget(); Widget callWidget = getWidget();
if (callWidget != null) if (callWidget != null)
@@ -189,21 +198,20 @@ public class BAToolsPlugin extends Plugin implements KeyListener
} }
pastCall = callWidget.getTextColor(); pastCall = callWidget.getTextColor();
} }
if (inGameBit == 1) if (inGameBit == 1 && config.defTimer())
{ {
if (tickNum > 9) if (tickNum > 9)
{ {
tickNum = 0; tickNum = 0;
} }
if (counter == null) if (counter == null)
{ {
addCounter(); addCounter();
} }
counter.setCount(tickNum); counter.setCount(tickNum);
if (config.defTimer())
{ tickNum++;
tickNum++;
}
} }
Widget weapon = client.getWidget(593, 1); Widget weapon = client.getWidget(593, 1);
@@ -212,61 +220,70 @@ public class BAToolsPlugin extends Plugin implements KeyListener
&& weapon != null && weapon != null
&& inGameBit == 1 && inGameBit == 1
&& weapon.getText().contains("Crystal halberd") || weapon.getText().contains("Dragon claws") && weapon.getText().contains("Crystal halberd") || weapon.getText().contains("Dragon claws")
&& client.getWidget(WidgetInfo.BA_ATK_LISTEN_TEXT) != null) && client.getWidget(BA_ATK_LISTEN_TEXT) != null)
{ {
String style = client.getWidget(WidgetInfo.BA_ATK_LISTEN_TEXT).getText(); if (originalAttackStyles == null)
{
ImmutableMap.Builder<WidgetInfo, Boolean> builder = new ImmutableMap.Builder<>();
builder.put(COMBAT_STYLE_ONE, client.getWidget(COMBAT_STYLE_ONE).isHidden());
builder.put(COMBAT_STYLE_TWO, client.getWidget(COMBAT_STYLE_TWO).isHidden());
builder.put(COMBAT_STYLE_THREE, client.getWidget(COMBAT_STYLE_THREE).isHidden());
builder.put(COMBAT_STYLE_FOUR, client.getWidget(COMBAT_STYLE_FOUR).isHidden());
originalAttackStyles = builder.build();
}
String style = client.getWidget(BA_ATK_LISTEN_TEXT).getText();
if (style.contains("Defensive")) if (style.contains("Defensive"))
{ {
client.getWidget(WidgetInfo.COMBAT_STYLE_ONE).setHidden(true); client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_TWO).setHidden(true); client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_THREE).setHidden(true); client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_FOUR).setHidden(false); client.getWidget(COMBAT_STYLE_FOUR).setHidden(false);
} }
else if (style.contains("Aggressive")) else if (style.contains("Aggressive"))
{ {
client.getWidget(WidgetInfo.COMBAT_STYLE_ONE).setHidden(true); client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_TWO).setHidden(false); client.getWidget(COMBAT_STYLE_TWO).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_THREE).setHidden(true); client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_FOUR).setHidden(true); client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
} }
else if (style.contains("Controlled")) else if (style.contains("Controlled"))
{ {
if (weapon.getText().contains("Crystal halberd")) if (weapon.getText().contains("Crystal halberd"))
{ {
client.getWidget(WidgetInfo.COMBAT_STYLE_ONE).setHidden(false); client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_THREE).setHidden(true); client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
} }
else else
{ {
client.getWidget(WidgetInfo.COMBAT_STYLE_ONE).setHidden(true); client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_THREE).setHidden(false); client.getWidget(COMBAT_STYLE_THREE).setHidden(false);
} }
client.getWidget(WidgetInfo.COMBAT_STYLE_TWO).setHidden(true); client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_FOUR).setHidden(true); client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
} }
else if (style.contains("Accurate") && weapon.getText().contains("Dragon claws")) else if (style.contains("Accurate") && weapon.getText().contains("Dragon claws"))
{ {
client.getWidget(WidgetInfo.COMBAT_STYLE_ONE).setHidden(false); client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_TWO).setHidden(true); client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_THREE).setHidden(true); client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
client.getWidget(WidgetInfo.COMBAT_STYLE_FOUR).setHidden(true); client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
} }
else else
{ {
client.getWidget(WidgetInfo.COMBAT_STYLE_ONE).setHidden(false); client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_TWO).setHidden(false); client.getWidget(COMBAT_STYLE_TWO).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_THREE).setHidden(false); client.getWidget(COMBAT_STYLE_THREE).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_FOUR).setHidden(false); client.getWidget(COMBAT_STYLE_FOUR).setHidden(false);
} }
} }
else else if (originalAttackStyles != null)
{ {
client.getWidget(WidgetInfo.COMBAT_STYLE_ONE).setHidden(false); originalAttackStyles.forEach((w, b) -> client.getWidget(w).setHidden(b));
client.getWidget(WidgetInfo.COMBAT_STYLE_TWO).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_THREE).setHidden(false);
client.getWidget(WidgetInfo.COMBAT_STYLE_FOUR).setHidden(false);
} }
if (config.prayerMetronome() && isAnyPrayerActive()) if (config.prayerMetronome() && isAnyPrayerActive())
@@ -280,21 +297,21 @@ public class BAToolsPlugin extends Plugin implements KeyListener
private Widget getWidget() private Widget getWidget()
{ {
if (client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT) != null) if (client.getWidget(BA_DEF_CALL_TEXT) != null)
{ {
return client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT); return client.getWidget(BA_DEF_CALL_TEXT);
} }
else if (client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT) != null) else if (client.getWidget(BA_ATK_CALL_TEXT) != null)
{ {
return client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT); return client.getWidget(BA_ATK_CALL_TEXT);
} }
else if (client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT) != null) else if (client.getWidget(BA_COLL_CALL_TEXT) != null)
{ {
return client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT); return client.getWidget(BA_COLL_CALL_TEXT);
} }
else if (client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) != null) else if (client.getWidget(BA_HEAL_CALL_TEXT) != null)
{ {
return client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT); return client.getWidget(BA_HEAL_CALL_TEXT);
} }
return null; return null;
} }
@@ -306,7 +323,9 @@ public class BAToolsPlugin extends Plugin implements KeyListener
if (inGameBit != inGame) if (inGameBit != inGame)
{ {
if (inGameBit == 1) inGameBit = inGame;
if (inGameBit == 0)
{ {
pastCall = 0; pastCall = 0;
removeCounter(); removeCounter();
@@ -317,8 +336,6 @@ public class BAToolsPlugin extends Plugin implements KeyListener
addCounter(); addCounter();
} }
} }
inGameBit = inGame;
} }
@Subscribe @Subscribe
@@ -371,10 +388,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
@Subscribe @Subscribe
public void onNpcDespawned(NpcDespawned event) public void onNpcDespawned(NpcDespawned event)
{ {
if (healers.remove(event.getNpc()) != null && healers.isEmpty()) healers.remove(event.getNpc());
{
healers.clear();
}
} }
@Subscribe @Subscribe
@@ -440,33 +454,34 @@ public class BAToolsPlugin extends Plugin implements KeyListener
if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder")) if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder"))
{ {
swap(client, "quick-start", option, target, true); swap(client, "quick-start", option, target);
} }
else if (config.removeBA() && client.getVar(Varbits.IN_GAME_BA) == 1 && !option.contains("tell-"))//if in barbarian assault and menu isnt from a horn else if (config.removeBA() && client.getVar(Varbits.IN_GAME_BA) == 1 && !option.contains("tell-"))//if in barbarian assault and menu isnt from a horn
{ {
if (itemId == ItemID.LOGS && !target.contains("healing vial")) if (itemId == ItemID.LOGS && !target.contains("healing vial"))
{ {
if (client.getWidget(WidgetInfo.BA_DEF_ROLE_TEXT) == null) if (client.getWidget(BA_DEF_ROLE_TEXT) == null)
{ {
remove(new String[]{"take", "light"}, target, true); remove(new String[]{"take", "light"}, target);
} }
else//remove "Light" option (and "Take" option if not defender). else //remove "Light" option (and "Take" option if not defender).
{ {
remove("light", target, true); remove("light", target);
} }
} }
else if (option.equals("use")) else if (option.equals("use"))
{ {
if (config.removeHealWrongFood()) if (config.removeHealWrongFood())
{ {
Widget healer = client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT); Widget healer = client.getWidget(BA_HEAL_LISTEN_TEXT);
if (healer != null) if (healer != null)
{ {
String item = target.split("-")[0].trim(); String item = target.split("-")[0].trim();
List<String> poison = Arrays.asList("poisoned tofu", "poisoned meat", "poisoned worms"); List<String> poison = Arrays.asList("poisoned tofu", "poisoned meat", "poisoned worms");
List<String> vials = Arrays.asList("healing vial", "healing vial(1)", "healing vial(2)", "healing vial(3)", "healing vial(4)");//"healing vial(4)" List<String> vials = Arrays.asList("healing vial", "healing vial(1)", "healing vial(2)", "healing vial(3)", "healing vial(4)");//"healing vial(4)"
if (poison.contains(item)) if (poison.contains(item))
{//if item is a poison item {
//if item is a poison item
int calledPoison = 0; int calledPoison = 0;
switch (healer.getText())//choose which poison to hide the use/destroy option for switch (healer.getText())//choose which poison to hide the use/destroy option for
{ {
@@ -485,12 +500,12 @@ public class BAToolsPlugin extends Plugin implements KeyListener
{ {
if (calledPoison != 0 && itemId != calledPoison)//if no call or chosen item is not the called one if (calledPoison != 0 && itemId != calledPoison)//if no call or chosen item is not the called one
{ {
remove(new String[]{"use", "destroy", "examine"}, target, true);//remove options remove(new String[]{"use", "destroy", "examine"}, target);//remove options
} }
} }
else if (!target.contains("penance healer")) else if (!target.contains("penance healer"))
{ {
remove(option, target, true); remove(option, target);
} }
} }
else if (vials.contains(item))//if item is the healer's healing vial else if (vials.contains(item))//if item is the healer's healing vial
@@ -501,28 +516,30 @@ public class BAToolsPlugin extends Plugin implements KeyListener
if (!target.contains("level") || target.contains("penance") || target.contains("queen spawn"))//if someone has "penance" or "queen spawn" in their name, gg... if (!target.contains("level") || target.contains("penance") || target.contains("queen spawn"))//if someone has "penance" or "queen spawn" in their name, gg...
{ {
remove(option, target, true); remove(option, target);
} }
} }
} }
} }
} }
} }
else if (option.equals("attack") && client.getWidget(WidgetInfo.BA_ATK_ROLE_TEXT) == null && !target.equals("queen spawn"))//if not attacker else if (option.equals("attack") && client.getWidget(BA_ATK_ROLE_TEXT) == null && !target.equals("queen spawn"))//if not attacker
{//remove attack option from everything but queen spawns
remove(option, target, true);
}
else if ((option.equals("fix") || (option.equals("block") && target.equals("penance cave"))) && client.getWidget(WidgetInfo.BA_DEF_ROLE_TEXT) == null)//if not defender
{//the check for option requires checking target as well because defensive attack style option is also called "block".
remove(option, target, true);
}
else if ((option.equals("load")) && client.getWidget(WidgetInfo.BA_COLL_ROLE_TEXT) == null)//if not collector, remove hopper options
{ {
remove(new String[]{option, "look-in"}, target, true); //remove attack option from everything but queen spawns
remove(option, target);
}
else if ((option.equals("fix") || (option.equals("block") && target.equals("penance cave"))) && client.getWidget(BA_DEF_ROLE_TEXT) == null)//if not defender
{
//the check for option requires checking target as well because defensive attack style option is also called "block".
remove(option, target);
}
else if ((option.equals("load")) && client.getWidget(BA_COLL_ROLE_TEXT) == null)//if not collector, remove hopper options
{
remove(new String[]{option, "look-in"}, target);
} }
else if (config.removeWrongEggs() && option.equals("take")) else if (config.removeWrongEggs() && option.equals("take"))
{ {
Widget eggToColl = client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT); Widget eggToColl = client.getWidget(BA_COLL_LISTEN_TEXT);
if (eggToColl != null)//if we're a collector if (eggToColl != null)//if we're a collector
{ {
List<Integer> eggsToHide = new ArrayList<>(); List<Integer> eggsToHide = new ArrayList<>();
@@ -544,15 +561,15 @@ public class BAToolsPlugin extends Plugin implements KeyListener
} }
if (eggsToHide.contains(itemId)) if (eggsToHide.contains(itemId))
{ {
remove(option, target, true);//hide wrong eggs remove(option, target);//hide wrong eggs
} }
} }
else else
{ {
List<Integer> defenderItems = Arrays.asList(ItemID.HAMMER, ItemID.TOFU, ItemID.CRACKERS, ItemID.WORMS);//logs are handled separately due to hiding "light" option too. List<Integer> defenderItems = Arrays.asList(ItemID.HAMMER, ItemID.TOFU, ItemID.CRACKERS, ItemID.WORMS);//logs are handled separately due to hiding "light" option too.
if (client.getWidget(WidgetInfo.BA_DEF_ROLE_TEXT) == null || !defenderItems.contains(itemId))//if not defender, or item is not a defenderItem if (client.getWidget(BA_DEF_ROLE_TEXT) == null || !defenderItems.contains(itemId))//if not defender, or item is not a defenderItem
{ {
remove(option, target, true);//hide everything except hammer/logs and bait if Defender remove(option, target);//hide everything except hammer/logs and bait if Defender
} }
} }
} }
@@ -583,9 +600,9 @@ public class BAToolsPlugin extends Plugin implements KeyListener
client.setMenuEntries(menuEntries); client.setMenuEntries(menuEntries);
} }
if (client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT) != null && inGameBit == 1 && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown) if (client.getWidget(BA_COLL_LISTEN_TEXT) != null && inGameBit == 1 && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown)
{ {
String[] currentCall = client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT).getText().split(" "); String[] currentCall = client.getWidget(BA_COLL_LISTEN_TEXT).getText().split(" ");
MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry correctEgg = null; MenuEntry correctEgg = null;
@@ -609,9 +626,9 @@ public class BAToolsPlugin extends Plugin implements KeyListener
client.setMenuEntries(entries.toArray(new MenuEntry[0])); client.setMenuEntries(entries.toArray(new MenuEntry[0]));
} }
if (client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT) != null && inGameBit == 1 && config.osHelp() && event.getTarget().equals("<col=ffff>Healer item machine") && shiftDown) if (client.getWidget(BA_HEAL_LISTEN_TEXT) != null && inGameBit == 1 && config.osHelp() && event.getTarget().equals("<col=ffff>Healer item machine") && shiftDown)
{ {
String[] currentCall = client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT).getText().split(" "); String[] currentCall = client.getWidget(BA_HEAL_LISTEN_TEXT).getText().split(" ");
if (!currentCall[0].contains("Pois.")) if (!currentCall[0].contains("Pois."))
{ {
@@ -632,7 +649,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
if (correctEgg != null) if (correctEgg != null)
{ {
entries.add(correctEgg); entries.add(correctEgg);
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()])); client.setMenuEntries(entries.toArray(new MenuEntry[0]));
} }
} }
@@ -641,12 +658,12 @@ public class BAToolsPlugin extends Plugin implements KeyListener
@Subscribe @Subscribe
public void onMenuOptionClicked(MenuOptionClicked event) public void onMenuOptionClicked(MenuOptionClicked event)
{ {
if (!config.healerMenuOption() || !event.getMenuTarget().contains("Penance Healer") || client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) == null) if (!config.healerMenuOption() || !event.getMenuTarget().contains("Penance Healer") || client.getWidget(BA_HEAL_CALL_TEXT) == null)
{ {
return; return;
} }
String currentCall = client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT).getText(); String currentCall = client.getWidget(BA_HEAL_CALL_TEXT).getText();
String target = event.getMenuTarget(); String target = event.getMenuTarget();
if ((currentCall.equals("Pois. Worms") && (target.contains("Poisoned worms") && target.contains("->") && target.contains("Penance Healer"))) if ((currentCall.equals("Pois. Worms") && (target.contains("Poisoned worms") && target.contains("->") && target.contains("Penance Healer")))
@@ -662,12 +679,11 @@ public class BAToolsPlugin extends Plugin implements KeyListener
} }
} }
@Subscribe
public void onConfigChanged(ConfigChanged event) public void onConfigChanged(ConfigChanged event)
{ {
if (config.antiDrag()) if (counter != null && !config.defTimer())
{ {
client.setInventoryDragDelay(config.antiDragDelay()); removeCounter();
} }
} }
@@ -697,10 +713,10 @@ public class BAToolsPlugin extends Plugin implements KeyListener
counter = null; counter = null;
} }
private void remove(String option, String target, boolean strict) private void remove(String option, String target)
{ {
MenuEntry[] entries = client.getMenuEntries(); MenuEntry[] entries = client.getMenuEntries();
int idx = searchIndex(entries, option, target, strict); int idx = searchIndex(entries, option, target);
if (idx >= 0 && entries[idx] != null) if (idx >= 0 && entries[idx] != null)
{ {
entries = ArrayUtils.removeElement(entries, entries[idx]); entries = ArrayUtils.removeElement(entries, entries[idx]);
@@ -708,12 +724,12 @@ public class BAToolsPlugin extends Plugin implements KeyListener
} }
} }
private void remove(String[] options, String target, boolean strict) private void remove(String[] options, String target)
{ {
MenuEntry[] entries = client.getMenuEntries(); MenuEntry[] entries = client.getMenuEntries();
for (String option : options) for (String option : options)
{ {
int idx = searchIndex(entries, option, target, strict); int idx = searchIndex(entries, option, target);
if (idx >= 0 && entries[idx] != null) if (idx >= 0 && entries[idx] != null)
{ {
entries = ArrayUtils.removeElement(entries, entries[idx]); entries = ArrayUtils.removeElement(entries, entries[idx]);
@@ -723,7 +739,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
client.setMenuEntries(entries); client.setMenuEntries(entries);
} }
private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) private int searchIndex(MenuEntry[] entries, String option, String target)
{ {
for (int i = entries.length - 1; i >= 0; i--) for (int i = entries.length - 1; i >= 0; i--)
{ {
@@ -731,19 +747,9 @@ public class BAToolsPlugin extends Plugin implements KeyListener
String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); String entryOption = Text.removeTags(entry.getOption()).toLowerCase();
String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase();
if (strict) if (entryOption.equals(option) && entryTarget.equals(target))
{ {
if (entryOption.equals(option) && entryTarget.equals(target)) return i;
{
return i;
}
}
else
{
if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target))
{
return i;
}
} }
} }

View File

@@ -24,10 +24,10 @@
*/ */
package net.runelite.client.plugins.batools; package net.runelite.client.plugins.batools;
import lombok.Getter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import lombok.Getter;
@Getter @Getter
public enum Calls public enum Calls
{ {

View File

@@ -24,11 +24,10 @@
*/ */
package net.runelite.client.plugins.batools; package net.runelite.client.plugins.batools;
import java.awt.image.BufferedImage;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.ui.overlay.infobox.Counter; import net.runelite.client.ui.overlay.infobox.Counter;
import java.awt.image.BufferedImage;
class CycleCounter extends Counter class CycleCounter extends Counter
{ {
CycleCounter(BufferedImage img, Plugin plugin, int tick) CycleCounter(BufferedImage img, Plugin plugin, int tick)

View File

@@ -27,9 +27,7 @@ package net.runelite.client.plugins.batools;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.Actor;
class Healer class Healer
@@ -75,7 +73,7 @@ class Healer
private HealerCode getCode(int wave) private HealerCode getCode(int wave)
{ {
switch(wave) switch (wave)
{ {
case 1: case 1:
return HealerCode.WAVEONE; return HealerCode.WAVEONE;
@@ -97,7 +95,8 @@ class Healer
return HealerCode.WAVENINE; return HealerCode.WAVENINE;
case 10: case 10:
return HealerCode.WAVETEN; return HealerCode.WAVETEN;
default: return null; default:
return null;
} }
} }
} }

View File

@@ -30,16 +30,16 @@ import lombok.Getter;
enum HealerCode enum HealerCode
{ {
WAVEONE(new int[] {1,1}, new int[] {0,0}, new int[] {0,0}), WAVEONE(new int[]{1, 1}, new int[]{0, 0}, new int[]{0, 0}),
WAVETWO(new int[] {1,1,2}, new int[] {0,0,0}, new int[] {0,0,21}), WAVETWO(new int[]{1, 1, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 21}),
WAVETHREE(new int[] {1,6,2}, new int[] {0,0,0}, new int[] {0,0,0}), WAVETHREE(new int[]{1, 6, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 0}),
WAVEFOUR(new int[] {2,5,2,0}, new int[] {0,0,7,10}, new int[] {0,0,0,0}), WAVEFOUR(new int[]{2, 5, 2, 0}, new int[]{0, 0, 7, 10}, new int[]{0, 0, 0, 0}),
WAVEFIVE(new int[] {2,5,2,3,0}, new int[] {0,0,0,0,7}, new int[] {0,0,21,30,0}), WAVEFIVE(new int[]{2, 5, 2, 3, 0}, new int[]{0, 0, 0, 0, 7}, new int[]{0, 0, 21, 30, 0}),
WAVESIX(new int[] {3,5,2,2,0,0}, new int[] {0,0,0,2,9,10}, new int[] {12,18,21,0,0,0}), WAVESIX(new int[]{3, 5, 2, 2, 0, 0}, new int[]{0, 0, 0, 2, 9, 10}, new int[]{12, 18, 21, 0, 0, 0}),
WAVESEVEN(new int[] {3,7,1,1,0,0,0}, new int[] {2,0,1,1,2,4,10}, new int[] {0,21,0,0,30,45,0}), WAVESEVEN(new int[]{3, 7, 1, 1, 0, 0, 0}, new int[]{2, 0, 1, 1, 2, 4, 10}, new int[]{0, 21, 0, 0, 30, 45, 0}),
WAVEEIGHT(new int[] {1,9,1,1,0,0,0}, new int[] {1,0,1,1,2,2,10}, new int[] {0,0,0,0,33,42,0}), WAVEEIGHT(new int[]{1, 9, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 2, 10}, new int[]{0, 0, 0, 0, 33, 42, 0}),
WAVENINE(new int[] {2,8,1,1,0,0,0,0}, new int[] {1,0,1,1,2,1,1,10}, new int[] {0,21,0,0,0,0,0,0,0}), WAVENINE(new int[]{2, 8, 1, 1, 0, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 1, 1, 10}, new int[]{0, 21, 0, 0, 0, 0, 0, 0, 0}),
WAVETEN(new int[] {2,5,1,1,0,0,0}, new int[] {1,0,1,1,4,4,8}, new int[] {21,33,0,33,30,45,0}); WAVETEN(new int[]{2, 5, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 4, 4, 8}, new int[]{21, 33, 0, 33, 30, 45, 0});
@Getter @Getter

View File

@@ -27,107 +27,139 @@ package net.runelite.client.plugins.blackjack;
import com.google.inject.Binder; import com.google.inject.Binder;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.MenuEntry; import static net.runelite.api.Varbits.QUEST_THE_FEUD;
import net.runelite.api.Quest;
import net.runelite.api.QuestState;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.VarbitChanged;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginType;
import static net.runelite.client.util.MenuUtil.swap;
/** /**
* Authors gazivodag longstreet * Authors gazivodag longstreet
*/ */
@PluginDescriptor( @PluginDescriptor(
name = "Blackjack", name = "Blackjack",
description = "Uses chat messages and tick timers instead of animations to read", description = "Uses chat messages and tick timers instead of animations to read",
tags = {"blackjack", "thieving"}, tags = {"blackjack", "thieving"},
type = PluginType.UTILITY type = PluginType.UTILITY
) )
@Singleton @Singleton
@Slf4j @Slf4j
public class BlackjackPlugin extends Plugin { public class BlackjackPlugin extends Plugin
{
private static final String PICKPOCKET = "Pickpocket";
private static final String KNOCK_OUT = "Knock-out";
private static final String LURE = "Lure";
private static final String BANDIT = "Bandit";
private static final String MENAPHITE = "Menaphite Thug";
@Inject @Inject
Client client; private Client client;
private static long timeSinceKnockout; @Inject
private static long timeSinceAggro; private MenuManager menuManager;
@Getter private int lastKnockout;
private static long currentGameTick; private boolean pickpocketing;
private boolean ableToBlackJack;
@Override @Override
public void configure(Binder binder) { public void configure(Binder binder)
} {
}
@Override @Override
protected void startUp() throws Exception { protected void startUp() throws Exception
currentGameTick = 0; {
} menuManager.addPriorityEntry(LURE, BANDIT);
menuManager.addPriorityEntry(LURE, MENAPHITE);
@Override menuManager.addPriorityEntry(KNOCK_OUT, BANDIT);
protected void shutDown() throws Exception { menuManager.addPriorityEntry(KNOCK_OUT, MENAPHITE);
currentGameTick = 0; }
}
@Subscribe @Override
public void onGameTick(GameTick gameTick) { protected void shutDown() throws Exception
currentGameTick++; {
} menuManager.removePriorityEntry(LURE, BANDIT);
menuManager.removePriorityEntry(LURE, MENAPHITE);
menuManager.removePriorityEntry(PICKPOCKET, BANDIT);
menuManager.removePriorityEntry(PICKPOCKET, MENAPHITE);
@Subscribe menuManager.removePriorityEntry(KNOCK_OUT, BANDIT);
public void onChatMessage(ChatMessage chatMessage) { menuManager.removePriorityEntry(KNOCK_OUT, MENAPHITE);
if (chatMessage.getType() == ChatMessageType.SPAM) { }
if (chatMessage.getMessage().equals("You smack the bandit over the head and render them unconscious.")) {
timeSinceKnockout = getCurrentGameTick();
}
if (chatMessage.getMessage().equals("Your blow only glances off the bandit's head.")) {
timeSinceAggro = getCurrentGameTick();
}
}
}
@Subscribe @Subscribe
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) { public void onGameTick(GameTick gameTick)
String target = menuEntryAdded.getTarget().toLowerCase(); {
if ((target.contains("bandit") | target.contains("menaphite thug"))) { if (ableToBlackJack && pickpocketing && client.getTickCount() >= lastKnockout + 4)
Quest quest = Quest.THE_FEUD; {
if (quest.getState(client) == QuestState.FINISHED) { pickpocketing = false;
if (currentGameTick < (timeSinceKnockout + 4)) {
stripSpecificEntries("pickpocket");
}
if (currentGameTick < (timeSinceAggro + 4)) {
stripSpecificEntries("pickpocket");
}
stripSpecificEntries("knock-out");
}
}
}
private void stripSpecificEntries(String exceptFor) { menuManager.removePriorityEntry(PICKPOCKET, BANDIT);
MenuEntry[] currentEntires = client.getMenuEntries(); menuManager.removePriorityEntry(PICKPOCKET, MENAPHITE);
MenuEntry[] newEntries = new MenuEntry[2];
for (MenuEntry currentEntry : currentEntires) { menuManager.addPriorityEntry(KNOCK_OUT, BANDIT);
if (currentEntry.getOption().toLowerCase().equals(exceptFor.toLowerCase())) { menuManager.addPriorityEntry(KNOCK_OUT, MENAPHITE);
newEntries[1] = currentEntry; }
} }
if (currentEntry.getOption().toLowerCase().equals("lure")) {
newEntries[0] = currentEntry;
}
}
if (newEntries[0] != null && newEntries[1] != null) { @Subscribe
client.setMenuEntries(newEntries); public void onMenuEntryAdded(MenuEntryAdded event)
} {
} // Lure has higher priority than knock-out
if (event.getTarget().contains(MENAPHITE) || event.getTarget().contains(BANDIT)
&& event.getOption().equals(LURE))
{
swap(client, KNOCK_OUT, LURE, event.getTarget(), false);
}
}
@Subscribe
public void onChatMessage(ChatMessage chatMessage)
{
if (chatMessage.getType() == ChatMessageType.SPAM)
{
if (chatMessage.getMessage().equals("You smack the bandit over the head and render them unconscious.")
|| chatMessage.getMessage().equals("Your blow only glances off the bandit's head."))
{
menuManager.removePriorityEntry(KNOCK_OUT, BANDIT);
menuManager.removePriorityEntry(KNOCK_OUT, MENAPHITE);
menuManager.addPriorityEntry(PICKPOCKET, BANDIT);
menuManager.addPriorityEntry(PICKPOCKET, MENAPHITE);
lastKnockout = client.getTickCount();
pickpocketing = true;
}
}
}
@Subscribe
public void onVarbitChanged(VarbitChanged event)
{
ableToBlackJack = client.getVar(QUEST_THE_FEUD) >= 13;
if (!ableToBlackJack)
{
menuManager.removePriorityEntry(LURE, BANDIT);
menuManager.removePriorityEntry(LURE, MENAPHITE);
menuManager.removePriorityEntry(KNOCK_OUT, BANDIT);
menuManager.removePriorityEntry(KNOCK_OUT, MENAPHITE);
menuManager.removePriorityEntry(PICKPOCKET, BANDIT);
menuManager.removePriorityEntry(PICKPOCKET, MENAPHITE);
}
}
} }

View File

@@ -36,7 +36,6 @@ import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;

View File

@@ -1,101 +1,100 @@
/* /*
* Copyright (c) 2018, Unmoon <https://github.com/Unmoon> * Copyright (c) 2018, Unmoon <https://github.com/Unmoon>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.blastmine; package net.runelite.client.plugins.blastmine;
import net.runelite.client.config.Config; import java.awt.Color;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import java.awt.Color;
@ConfigGroup("blastmine")
@ConfigGroup("blastmine") public interface BlastMinePluginConfig extends Config
public interface BlastMinePluginConfig extends Config {
{ @ConfigItem(
@ConfigItem( position = 0,
position = 0, keyName = "showOreOverlay",
keyName = "showOreOverlay", name = "Show ore overlay",
name = "Show ore overlay", description = "Configures whether or not the ore count overlay is displayed"
description = "Configures whether or not the ore count overlay is displayed" )
) default boolean showOreOverlay()
default boolean showOreOverlay() {
{ return true;
return true; }
}
@ConfigItem(
@ConfigItem( position = 1,
position = 1, keyName = "showRockIconOverlay",
keyName = "showRockIconOverlay", name = "Show icons overlay",
name = "Show icons overlay", description = "Configures whether or not the icon overlay is displayed"
description = "Configures whether or not the icon overlay is displayed" )
) default boolean showRockIconOverlay()
default boolean showRockIconOverlay() {
{ return true;
return true; }
}
@ConfigItem(
@ConfigItem( position = 2,
position = 2, keyName = "showTimerOverlay",
keyName = "showTimerOverlay", name = "Show timer overlay",
name = "Show timer overlay", description = "Configures whether or not the timer overlay is displayed"
description = "Configures whether or not the timer overlay is displayed" )
) default boolean showTimerOverlay()
default boolean showTimerOverlay() {
{ return true;
return true; }
}
@ConfigItem(
@ConfigItem( position = 3,
position = 3, keyName = "showWarningOverlay",
keyName = "showWarningOverlay", name = "Show explosion warning",
name = "Show explosion warning", description = "Configures whether or not the explosion warning overlay is displayed"
description = "Configures whether or not the explosion warning overlay is displayed" )
) default boolean showWarningOverlay()
default boolean showWarningOverlay() {
{ return true;
return true; }
}
@ConfigItem(
@ConfigItem( position = 4,
position = 4, keyName = "hexTimerColor",
keyName = "hexTimerColor", name = "Timer color",
name = "Timer color", description = "Color of timer overlay"
description = "Color of timer overlay" )
) default Color getTimerColor()
default Color getTimerColor() {
{ return new Color(217, 54, 0);
return new Color(217, 54, 0); }
}
@ConfigItem(
@ConfigItem( position = 5,
position = 5, keyName = "hexWarningColor",
keyName = "hexWarningColor", name = "Warning color",
name = "Warning color", description = "Color of warning overlay"
description = "Color of warning overlay" )
) default Color getWarningColor()
default Color getWarningColor() {
{ return new Color(217, 54, 0);
return new Color(217, 54, 0); }
} }
}

View File

@@ -356,7 +356,7 @@ public class BoostsPlugin extends Plugin
* section it will "activate" adding an additional 15 second section * section it will "activate" adding an additional 15 second section
* to the boost timing. If again the preserve prayer is active for that * to the boost timing. If again the preserve prayer is active for that
* entire section a second 15 second section will be added. * entire section a second 15 second section will be added.
* * <p>
* Preserve is only required to be on for the 4th and 5th sections of the boost timer * Preserve is only required to be on for the 4th and 5th sections of the boost timer
* to gain full effect (seconds 45-75). * to gain full effect (seconds 45-75).
* *
@@ -365,8 +365,8 @@ public class BoostsPlugin extends Plugin
int getChangeDownTicks() int getChangeDownTicks()
{ {
if (lastChangeDown == -1 || if (lastChangeDown == -1 ||
config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.NEVER || config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
(config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedUp)) (config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedUp))
{ {
return -1; return -1;
} }
@@ -393,8 +393,8 @@ public class BoostsPlugin extends Plugin
int getChangeUpTicks() int getChangeUpTicks()
{ {
if (lastChangeUp == -1 || if (lastChangeUp == -1 ||
config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.NEVER || config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
(config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedDown)) (config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedDown))
{ {
return -1; return -1;
} }
@@ -406,12 +406,13 @@ public class BoostsPlugin extends Plugin
/** /**
* Converts tick-based time to accurate second time * Converts tick-based time to accurate second time
*
* @param time tick-based time * @param time tick-based time
* @return second-based time * @return second-based time
*/ */
int getChangeTime(final int time) int getChangeTime(final int time)
{ {
final long diff = System.currentTimeMillis() - lastTickMillis; final long diff = System.currentTimeMillis() - lastTickMillis;
return time != -1 ? (int)((time * Constants.GAME_TICK_LENGTH - diff) / 1000d) : time; return time != -1 ? (int) ((time * Constants.GAME_TICK_LENGTH - diff) / 1000d) : time;
} }
} }

View File

@@ -77,7 +77,7 @@ enum Boss
bosses = builder.build(); bosses = builder.build();
} }
private Boss(int id, long period, ChronoUnit unit, int itemSpriteId) Boss(int id, long period, ChronoUnit unit, int itemSpriteId)
{ {
this.id = id; this.id = id;
this.spawnTime = Duration.of(period, unit); this.spawnTime = Duration.of(period, unit);

View File

@@ -29,6 +29,7 @@ import net.runelite.client.config.Alpha;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Range;
@ConfigGroup("cannon") @ConfigGroup("cannon")
public interface CannonConfig extends Config public interface CannonConfig extends Config
@@ -84,6 +85,9 @@ public interface CannonConfig extends Config
return true; return true;
} }
@Range(
max = 29
)
@ConfigItem( @ConfigItem(
keyName = "ammoAmount", keyName = "ammoAmount",
name = "Ammo left", name = "Ammo left",

View File

@@ -1,141 +1,142 @@
/* /*
* Copyright (c) 2016-2018, Seth <Sethtroll3@gmail.com> * Copyright (c) 2016-2018, Seth <Sethtroll3@gmail.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.cannon; package net.runelite.client.plugins.cannon;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Polygon; import java.awt.Polygon;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Perspective; import net.runelite.api.Perspective;
import static net.runelite.api.Perspective.LOCAL_TILE_SIZE; import static net.runelite.api.Perspective.LOCAL_TILE_SIZE;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.TextComponent; import net.runelite.client.ui.overlay.components.TextComponent;
class CannonOverlay extends Overlay class CannonOverlay extends Overlay
{ {
private static final int MAX_DISTANCE = 2500; private static final int MAX_DISTANCE = 2500;
private final Client client; private final Client client;
private final CannonConfig config; private final CannonConfig config;
private final CannonPlugin plugin; private final CannonPlugin plugin;
private final TextComponent textComponent = new TextComponent(); private final TextComponent textComponent = new TextComponent();
@Inject @Inject
CannonOverlay(Client client, CannonConfig config, CannonPlugin plugin) CannonOverlay(Client client, CannonConfig config, CannonPlugin plugin)
{ {
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.MED); setPriority(OverlayPriority.MED);
this.client = client; this.client = client;
this.config = config; this.config = config;
this.plugin = plugin; this.plugin = plugin;
} }
@Override @Override
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null) if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null)
{ {
return null; return null;
} }
LocalPoint cannonPoint = LocalPoint.fromWorld(client, plugin.getCannonPosition()); LocalPoint cannonPoint = LocalPoint.fromWorld(client, plugin.getCannonPosition());
if (cannonPoint == null) if (cannonPoint == null)
{ {
return null; return null;
} }
LocalPoint localLocation = client.getLocalPlayer().getLocalLocation(); LocalPoint localLocation = client.getLocalPlayer().getLocalLocation();
if (localLocation.distanceTo(cannonPoint) <= MAX_DISTANCE) if (localLocation.distanceTo(cannonPoint) <= MAX_DISTANCE)
{ {
Point cannonLoc = Perspective.getCanvasTextLocation(client, Point cannonLoc = Perspective.getCanvasTextLocation(client,
graphics, graphics,
cannonPoint, cannonPoint,
String.valueOf(plugin.getCballsLeft()), 150); String.valueOf(plugin.getCballsLeft()), 150);
if (cannonLoc != null) if (cannonLoc != null)
{ {
textComponent.setText(String.valueOf(plugin.getCballsLeft())); textComponent.setText(String.valueOf(plugin.getCballsLeft()));
textComponent.setPosition(new java.awt.Point(cannonLoc.getX(), cannonLoc.getY())); textComponent.setPosition(new java.awt.Point(cannonLoc.getX(), cannonLoc.getY()));
textComponent.setColor(plugin.getStateColor()); textComponent.setColor(plugin.getStateColor());
textComponent.render(graphics); textComponent.render(graphics);
} }
if (config.showDoubleHitSpot()) if (config.showDoubleHitSpot())
{ {
Color color = config.highlightDoubleHitColor(); Color color = config.highlightDoubleHitColor();
drawDoubleHitSpots(graphics, cannonPoint, color); drawDoubleHitSpots(graphics, cannonPoint, color);
} }
} }
return null; return null;
} }
/** /**
* Draw the double hit spots on a 6 by 6 grid around the cannon * Draw the double hit spots on a 6 by 6 grid around the cannon
* @param startTile The position of the cannon *
*/ * @param startTile The position of the cannon
private void drawDoubleHitSpots(Graphics2D graphics, LocalPoint startTile, Color color) */
{ private void drawDoubleHitSpots(Graphics2D graphics, LocalPoint startTile, Color color)
for (int x = -3; x <= 3; x++) {
{ for (int x = -3; x <= 3; x++)
for (int y = -3; y <= 3; y++) {
{ for (int y = -3; y <= 3; y++)
if (y != 1 && x != 1 && y != -1 && x != -1) {
{ if (y != 1 && x != 1 && y != -1 && x != -1)
continue; {
} continue;
}
//Ignore center square
if (y >= -1 && y <= 1 && x >= -1 && x <= 1) //Ignore center square
{ if (y >= -1 && y <= 1 && x >= -1 && x <= 1)
continue; {
} continue;
}
int xPos = startTile.getX() - (x * LOCAL_TILE_SIZE);
int yPos = startTile.getY() - (y * LOCAL_TILE_SIZE); int xPos = startTile.getX() - (x * LOCAL_TILE_SIZE);
int yPos = startTile.getY() - (y * LOCAL_TILE_SIZE);
LocalPoint marker = new LocalPoint(xPos, yPos);
Polygon poly = Perspective.getCanvasTilePoly(client, marker); LocalPoint marker = new LocalPoint(xPos, yPos);
Polygon poly = Perspective.getCanvasTilePoly(client, marker);
if (poly == null)
{ if (poly == null)
continue; {
} continue;
}
OverlayUtil.renderPolygon(graphics, poly, color);
} OverlayUtil.renderPolygon(graphics, poly, color);
} }
} }
}
} }

View File

@@ -24,6 +24,7 @@
*/ */
package net.runelite.client.plugins.cannon; package net.runelite.client.plugins.cannon;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
@@ -38,7 +39,6 @@ import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameObject; import net.runelite.api.GameObject;
import net.runelite.api.InventoryID; import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import static net.runelite.api.ObjectID.CANNON_BASE; import static net.runelite.api.ObjectID.CANNON_BASE;
import net.runelite.api.Player; import net.runelite.api.Player;
@@ -62,6 +62,7 @@ import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.task.Schedule; import net.runelite.client.task.Schedule;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.util.ItemUtil;
@PluginDescriptor( @PluginDescriptor(
name = "Cannon", name = "Cannon",
@@ -72,6 +73,9 @@ public class CannonPlugin extends Plugin
{ {
private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)"); private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)");
private static final int MAX_CBALLS = 30; private static final int MAX_CBALLS = 30;
private static final ImmutableSet<Integer> CANNON_PARTS = ImmutableSet.of(
ItemID.CANNON_BASE, ItemID.CANNON_STAND, ItemID.CANNON_BARRELS, ItemID.CANNON_FURNACE
);
private CannonCounter counter; private CannonCounter counter;
private boolean skipProjectileCheckThisTick; private boolean skipProjectileCheckThisTick;
@@ -157,46 +161,7 @@ public class CannonPlugin extends Plugin
return; return;
} }
boolean hasBase = false; cannonSpotOverlay.setHidden(!ItemUtil.containsAllItemIds(event.getItemContainer().getItems(), CANNON_PARTS));
boolean hasStand = false;
boolean hasBarrels = false;
boolean hasFurnace = false;
boolean hasAll = false;
if (!cannonPlaced)
{
for (Item item : event.getItemContainer().getItems())
{
if (item == null)
{
continue;
}
switch (item.getId())
{
case ItemID.CANNON_BASE:
hasBase = true;
break;
case ItemID.CANNON_STAND:
hasStand = true;
break;
case ItemID.CANNON_BARRELS:
hasBarrels = true;
break;
case ItemID.CANNON_FURNACE:
hasFurnace = true;
break;
}
if (hasBase && hasStand && hasBarrels && hasFurnace)
{
hasAll = true;
break;
}
}
}
cannonSpotOverlay.setHidden(!hasAll);
} }
@Subscribe @Subscribe

View File

@@ -60,6 +60,7 @@ public enum CerberusGhost
/** /**
* Try to identify if NPC is ghost * Try to identify if NPC is ghost
*
* @param npc npc * @param npc npc
* @return optional ghost * @return optional ghost
*/ */

Some files were not shown because too many files have changed in this diff Show More