Merge pull request #274 from Lucwousin/trav

Enable checkstyle in travis
This commit is contained in:
Tyler Bochard
2019-05-17 00:56:53 -04:00
committed by GitHub
453 changed files with 57947 additions and 54112 deletions

View File

@@ -33,11 +33,11 @@ public class MethodGarbageValue
public MethodGarbageValue(int value)
{
if(value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE)
if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE)
{
type = "B";
}
else if(value <= Short.MAX_VALUE && value >= Short.MIN_VALUE)
else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE)
{
type = "S";
}
@@ -60,6 +60,6 @@ public class MethodGarbageValue
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.CtClass;
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 us.runelitepl.mixinprocessor.generators.AnnotationProcessor;
import us.runelitepl.mixinprocessor.generators.PatchGenerator;
@@ -50,14 +46,11 @@ import us.runelitepl.mixinprocessor.util.JavassistUtils;
import us.runelitepl.mixinprocessor.util.RefUtils;
import org.apache.maven.plugin.AbstractMojo;
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.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -111,9 +104,9 @@ public class MixinProcessorMojo
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()
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));
}
@@ -267,7 +260,7 @@ public class MixinProcessorMojo
INST.stderr(s, format);
}
static void deleteDir(File file) throws IOException
private static void deleteDir(File file) throws IOException
{
if (!file.exists())
{

View File

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

View File

@@ -26,8 +26,6 @@
package us.runelitepl.mixinprocessor.generators;
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.AsmStaticUsageTransformer;
import us.runelitepl.mixinprocessor.transformers.DoNothingTransformer;

View File

@@ -25,18 +25,12 @@
package us.runelitepl.mixinprocessor.generators;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.NotFoundException;
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
import us.runelitepl.mixinprocessor.util.JavassistUtils;
import us.runelitepl.mixinprocessor.util.RefUtils;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -45,11 +39,11 @@ import java.util.Set;
public class StaticGenerator
{
public static HashMap<String, ArrayList<MethodNode>> staticMethods = new HashMap<>();
public static HashMap<String, ArrayList<FieldNode>> staticFields = new HashMap<>();
public static Set<String> modifiedClasses = new HashSet<>();
static HashMap<String, ArrayList<MethodNode>> staticMethods = new HashMap<>();
static HashMap<String, ArrayList<FieldNode>> staticFields = new HashMap<>();
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);
@@ -68,7 +62,7 @@ public class StaticGenerator
continue;
}
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);
throw new RuntimeException();
@@ -93,7 +87,7 @@ public class StaticGenerator
continue;
}
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);
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.MethodNode;
import org.objectweb.asm.tree.TypeAnnotationNode;
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
import us.runelitepl.mixinprocessor.parsers.MethodReflector;
import java.util.HashMap;

View File

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

View File

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

View File

@@ -51,7 +51,7 @@ public class MethodAnnotationParser
public void run() throws ClassNotFoundException
{
for(CtMethod method : patch.getDeclaredMethods())
for (CtMethod method : patch.getDeclaredMethods())
{
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,
RefUtils.reobMethodDescriptor(method.getSignature()));

View File

@@ -96,7 +96,7 @@ public class AnnotationRemoverTransformer extends AsmBaseTransformer
return cw.toByteArray();
}
public static String makeAnnotationDescriptor(String s)
static String makeAnnotationDescriptor(String 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> validFields = new ArrayList<>();
// CHECKSTYLE:OFF
protected void buildMethodList(){}
protected void buildFieldList(){}
// CHECKSTYLE:ON
public abstract byte[] transform();
}

View File

@@ -32,8 +32,6 @@ import org.objectweb.asm.MethodVisitor;
import us.runelitepl.mixinprocessor.MethodGarbageValue;
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
import us.runelitepl.mixinprocessor.util.RefUtils;
import java.sql.Ref;
import java.util.HashMap;
public class AsmMethodGarbageTransformer extends AsmBaseTransformer
@@ -74,13 +72,13 @@ public class AsmMethodGarbageTransformer extends AsmBaseTransformer
// mv.visitLdcInsn(BIPUSH, constant);
// 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 nn = RefUtils.reobMethodName(owner, name, desc).split(" ")[1];
String nd = RefUtils.reobMethodDescriptor(desc);
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)
{
switch (value.getType())

View File

@@ -72,7 +72,7 @@ public class AsmMethodSignatureTransformer extends AsmBaseTransformer
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());
}

View File

@@ -32,11 +32,6 @@ import org.objectweb.asm.MethodVisitor;
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
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
{
@@ -89,7 +84,7 @@ public class AsmStaticUsageTransformer extends AsmBaseTransformer
@Override
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 temp = RefUtils.reobMethodName(RefUtils.STATICS_STRING, name, descriptor);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -43,10 +43,10 @@ public class Scene
return true;
}
if(renderable instanceof RSPlayer)
if (renderable instanceof RSPlayer)
{
RSPlayer p = (RSPlayer) renderable;
if(Client.hideClanMates && p.isClanMember())
if (Client.hideClanMates && p.isClanMember())
{
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,
String menuTarget, int mouseX, int mouseY)
{
if(Client.printMenuActions)
if (Client.printMenuActions)
{
int printOpcode = opcode;
if(opcode >= 2000)
if (opcode >= 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 BLACKJACK_KO = 838;
public static final int VETION_EARTHQUAKE = 5507;
public static final int ZULRAH_DEATH = 5804;
public static final int ZULRAH_DEATH = 5804;
// Farming
public static final int FARMING_HARVEST_FRUIT_TREE = 2280;
@@ -214,8 +214,8 @@ public final class AnimationID
// POH Animations
public static final int INCENSE_BURNER = 3687;
public static final int LOW_LEVEL_MAGIC_ATTACK = 1162;
public static final int HIGH_LEVEL_MAGIC_ATTACK = 1167;
public static final int BLOWPIPE_ATTACK = 5061;
public static final int HIGH_LEVEL_MAGIC_ATTACK = 1167;
public static final int BLOWPIPE_ATTACK = 5061;
// Hydra
public static final int HYDRA_POISON_1 = 8234;

View File

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

View File

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

View File

@@ -59,7 +59,6 @@ import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginInstantiationException;
import net.runelite.client.plugins.PluginManager;
import net.runelite.client.plugins.config.ConfigPanel;
import net.runelite.client.rs.ClientUpdateCheckMode;
import net.runelite.client.task.Scheduler;
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 PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
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;
@Inject
@@ -242,7 +241,7 @@ public class RuneLite
// The submessage is shown in case the connection is slow
splashScreen.setMessage("Starting RuneLite Injector");
splashScreen.setSubMessage( " ");
splashScreen.setSubMessage(" ");
final long start = System.currentTimeMillis();

View File

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

View File

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

View File

@@ -1,232 +1,232 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.account;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Instant;
import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.events.SessionClose;
import net.runelite.client.events.SessionOpen;
import net.runelite.client.RuneLite;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.util.LinkBrowser;
import net.runelite.client.ws.WSClient;
import net.runelite.http.api.account.AccountClient;
import net.runelite.http.api.account.OAuthResponse;
import net.runelite.http.api.ws.messages.LoginResponse;
@Singleton
@Slf4j
public class SessionManager
{
private static final File SESSION_FILE = new File(RuneLite.RUNELITE_DIR, "session");
@Getter
private AccountSession accountSession;
private final EventBus eventBus;
private final ConfigManager configManager;
private final WSClient wsClient;
@Inject
private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient)
{
this.configManager = configManager;
this.eventBus = eventBus;
this.wsClient = wsClient;
eventBus.register(this);
}
public void loadSession()
{
if (!SESSION_FILE.exists())
{
log.info("No session file exists");
return;
}
AccountSession session;
try (FileInputStream in = new FileInputStream(SESSION_FILE))
{
session = new Gson().fromJson(new InputStreamReader(in), AccountSession.class);
log.debug("Loaded session for {}", session.getUsername());
}
catch (Exception ex)
{
log.warn("Unable to load session file", ex);
return;
}
// Check if session is still valid
AccountClient accountClient = new AccountClient(session.getUuid());
if (!accountClient.sesssionCheck())
{
log.debug("Loaded session {} is invalid", session.getUuid());
return;
}
openSession(session, false);
}
private void saveSession()
{
if (accountSession == null)
{
return;
}
try (FileWriter fw = new FileWriter(SESSION_FILE))
{
new Gson().toJson(accountSession, fw);
log.debug("Saved session to {}", SESSION_FILE);
}
catch (IOException ex)
{
log.warn("Unable to save session file", ex);
}
}
private void deleteSession()
{
SESSION_FILE.delete();
}
/**
* Set the given session as the active session and open a socket to the
* server with the given session
*
* @param session session
*/
private void openSession(AccountSession session, boolean openSocket)
{
// Change session on the websocket
if (openSocket)
{
wsClient.changeSession(session.getUuid());
}
accountSession = session;
if (session.getUsername() != null)
{
// Initialize config for new session
// If the session isn't logged in yet, don't switch to the new config
configManager.switchSession(session);
}
eventBus.post(new SessionOpen());
}
private void closeSession()
{
wsClient.changeSession(null);
if (accountSession == null)
{
return;
}
log.debug("Logging out of account {}", accountSession.getUsername());
AccountClient client = new AccountClient(accountSession.getUuid());
try
{
client.logout();
}
catch (IOException ex)
{
log.warn("Unable to logout of session", ex);
}
accountSession = null; // No more account
// Restore config
configManager.switchSession(null);
eventBus.post(new SessionClose());
}
public void login()
{
// If a session is already open, use that id. Otherwise generate a new id.
UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID();
AccountClient loginClient = new AccountClient(uuid);
final OAuthResponse login;
try
{
login = loginClient.login();
}
catch (IOException ex)
{
log.warn("Unable to get oauth url", ex);
return;
}
// Create new session
openSession(new AccountSession(login.getUid(), Instant.now()), true);
// Navigate to login link
LinkBrowser.browse(login.getOauthUrl());
}
@Subscribe
public void onLoginResponse(LoginResponse loginResponse)
{
log.debug("Now logged in as {}", loginResponse.getUsername());
AccountSession session = getAccountSession();
session.setUsername(loginResponse.getUsername());
// Open session, again, now that we have a username
// This triggers onSessionOpen
// The socket is already opened here anyway so we pass true for openSocket
openSession(session, true);
// Save session to disk
saveSession();
}
public void logout()
{
closeSession();
deleteSession();
}
}
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.account;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Instant;
import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLite;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.SessionClose;
import net.runelite.client.events.SessionOpen;
import net.runelite.client.util.LinkBrowser;
import net.runelite.client.ws.WSClient;
import net.runelite.http.api.account.AccountClient;
import net.runelite.http.api.account.OAuthResponse;
import net.runelite.http.api.ws.messages.LoginResponse;
@Singleton
@Slf4j
public class SessionManager
{
private static final File SESSION_FILE = new File(RuneLite.RUNELITE_DIR, "session");
@Getter
private AccountSession accountSession;
private final EventBus eventBus;
private final ConfigManager configManager;
private final WSClient wsClient;
@Inject
private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient)
{
this.configManager = configManager;
this.eventBus = eventBus;
this.wsClient = wsClient;
eventBus.register(this);
}
public void loadSession()
{
if (!SESSION_FILE.exists())
{
log.info("No session file exists");
return;
}
AccountSession session;
try (FileInputStream in = new FileInputStream(SESSION_FILE))
{
session = new Gson().fromJson(new InputStreamReader(in), AccountSession.class);
log.debug("Loaded session for {}", session.getUsername());
}
catch (Exception ex)
{
log.warn("Unable to load session file", ex);
return;
}
// Check if session is still valid
AccountClient accountClient = new AccountClient(session.getUuid());
if (!accountClient.sesssionCheck())
{
log.debug("Loaded session {} is invalid", session.getUuid());
return;
}
openSession(session, false);
}
private void saveSession()
{
if (accountSession == null)
{
return;
}
try (FileWriter fw = new FileWriter(SESSION_FILE))
{
new Gson().toJson(accountSession, fw);
log.debug("Saved session to {}", SESSION_FILE);
}
catch (IOException ex)
{
log.warn("Unable to save session file", ex);
}
}
private void deleteSession()
{
SESSION_FILE.delete();
}
/**
* Set the given session as the active session and open a socket to the
* server with the given session
*
* @param session session
*/
private void openSession(AccountSession session, boolean openSocket)
{
// Change session on the websocket
if (openSocket)
{
wsClient.changeSession(session.getUuid());
}
accountSession = session;
if (session.getUsername() != null)
{
// Initialize config for new session
// If the session isn't logged in yet, don't switch to the new config
configManager.switchSession(session);
}
eventBus.post(new SessionOpen());
}
private void closeSession()
{
wsClient.changeSession(null);
if (accountSession == null)
{
return;
}
log.debug("Logging out of account {}", accountSession.getUsername());
AccountClient client = new AccountClient(accountSession.getUuid());
try
{
client.logout();
}
catch (IOException ex)
{
log.warn("Unable to logout of session", ex);
}
accountSession = null; // No more account
// Restore config
configManager.switchSession(null);
eventBus.post(new SessionClose());
}
public void login()
{
// If a session is already open, use that id. Otherwise generate a new id.
UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID();
AccountClient loginClient = new AccountClient(uuid);
final OAuthResponse login;
try
{
login = loginClient.login();
}
catch (IOException ex)
{
log.warn("Unable to get oauth url", ex);
return;
}
// Create new session
openSession(new AccountSession(login.getUid(), Instant.now()), true);
// Navigate to login link
LinkBrowser.browse(login.getOauthUrl());
}
@Subscribe
public void onLoginResponse(LoginResponse loginResponse)
{
log.debug("Now logged in as {}", loginResponse.getUsername());
AccountSession session = getAccountSession();
session.setUsername(loginResponse.getUsername());
// Open session, again, now that we have a username
// This triggers onSessionOpen
// The socket is already opened here anyway so we pass true for openSocket
openSession(session, true);
// Save session to disk
saveSession();
}
public void logout()
{
closeSession();
deleteSession();
}
}

View File

@@ -374,6 +374,7 @@ public class Hooks implements Callbacks
/**
* Copy an image
*
* @param src
* @return
*/

View File

@@ -1,153 +1,153 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
@Slf4j
class ConfigInvocationHandler implements InvocationHandler
{
private final ConfigManager manager;
public ConfigInvocationHandler(ConfigManager manager)
{
this.manager = manager;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Class<?> iface = proxy.getClass().getInterfaces()[0];
ConfigGroup group = iface.getAnnotation(ConfigGroup.class);
ConfigItem item = method.getAnnotation(ConfigItem.class);
if (group == null)
{
log.warn("Configuration proxy class {} has no @ConfigGroup!", proxy.getClass());
return null;
}
if (item == null)
{
log.warn("Configuration method {} has no @ConfigItem!", method);
return null;
}
if (args == null)
{
// Getting configuration item
String value = manager.getConfiguration(group.value(), item.keyName());
if (value == null)
{
if (method.isDefault())
{
return callDefaultMethod(proxy, method, null);
}
return null;
}
// Convert value to return type
Class<?> returnType = method.getReturnType();
try
{
return ConfigManager.stringToObject(value, returnType);
}
catch (Exception e)
{
log.warn("Unable to unmarshal {}.{} ", group.value(), item.keyName(), e);
if (method.isDefault())
{
return callDefaultMethod(proxy, method, null);
}
return null;
}
}
else
{
// Setting a configuration value
if (args.length != 1)
{
throw new RuntimeException("Invalid number of arguents to configuration method");
}
Object newValue = args[0];
Class<?> type = method.getParameterTypes()[0];
Object oldValue = manager.getConfiguration(group.value(), item.keyName(), type);
if (Objects.equals(oldValue, newValue))
{
// nothing to do
return null;
}
if (method.isDefault())
{
Object defaultValue = callDefaultMethod(proxy, method, args);
if (Objects.equals(newValue, defaultValue))
{
// Just unset if it goes back to the default
manager.unsetConfiguration(group.value(), item.keyName());
return null;
}
}
if (newValue == null)
{
manager.unsetConfiguration(group.value(), item.keyName());
}
else
{
String newValueStr = ConfigManager.objectToString(newValue);
manager.setConfiguration(group.value(), item.keyName(), newValueStr);
}
return null;
}
}
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/
Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
Class<?> declaringClass = method.getDeclaringClass();
return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE)
.unreflectSpecial(method, declaringClass)
.bindTo(proxy)
.invokeWithArguments(args);
}
}
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
@Slf4j
class ConfigInvocationHandler implements InvocationHandler
{
private final ConfigManager manager;
public ConfigInvocationHandler(ConfigManager manager)
{
this.manager = manager;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Class<?> iface = proxy.getClass().getInterfaces()[0];
ConfigGroup group = iface.getAnnotation(ConfigGroup.class);
ConfigItem item = method.getAnnotation(ConfigItem.class);
if (group == null)
{
log.warn("Configuration proxy class {} has no @ConfigGroup!", proxy.getClass());
return null;
}
if (item == null)
{
log.warn("Configuration method {} has no @ConfigItem!", method);
return null;
}
if (args == null)
{
// Getting configuration item
String value = manager.getConfiguration(group.value(), item.keyName());
if (value == null)
{
if (method.isDefault())
{
return callDefaultMethod(proxy, method, null);
}
return null;
}
// Convert value to return type
Class<?> returnType = method.getReturnType();
try
{
return ConfigManager.stringToObject(value, returnType);
}
catch (Exception e)
{
log.warn("Unable to unmarshal {}.{} ", group.value(), item.keyName(), e);
if (method.isDefault())
{
return callDefaultMethod(proxy, method, null);
}
return null;
}
}
else
{
// Setting a configuration value
if (args.length != 1)
{
throw new RuntimeException("Invalid number of arguents to configuration method");
}
Object newValue = args[0];
Class<?> type = method.getParameterTypes()[0];
Object oldValue = manager.getConfiguration(group.value(), item.keyName(), type);
if (Objects.equals(oldValue, newValue))
{
// nothing to do
return null;
}
if (method.isDefault())
{
Object defaultValue = callDefaultMethod(proxy, method, args);
if (Objects.equals(newValue, defaultValue))
{
// Just unset if it goes back to the default
manager.unsetConfiguration(group.value(), item.keyName());
return null;
}
}
if (newValue == null)
{
manager.unsetConfiguration(group.value(), item.keyName());
}
else
{
String newValueStr = ConfigManager.objectToString(newValue);
manager.setConfiguration(group.value(), item.keyName(), newValueStr);
}
return null;
}
}
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/
Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
Class<?> declaringClass = method.getDeclaringClass();
return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE)
.unreflectSpecial(method, declaringClass)
.bindTo(proxy)
.invokeWithArguments(args);
}
}

View File

@@ -1,52 +1,52 @@
/*
* 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 lombok.AccessLevel;
import lombok.Getter;
import java.util.ArrayList;
import java.util.Collection;
public class ConfigItemsGroup
{
@Getter(AccessLevel.PUBLIC)
private final String group;
@Getter(AccessLevel.PUBLIC)
private Collection<ConfigItemDescriptor> items;
public ConfigItemsGroup(String group)
{
this.group = group;
this.items = new ArrayList<>();
}
public void addItem(ConfigItemDescriptor item)
{
items.add(item);
}
}
/*
* 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.Collection;
import lombok.AccessLevel;
import lombok.Getter;
public class ConfigItemsGroup
{
@Getter(AccessLevel.PUBLIC)
private final String group;
@Getter(AccessLevel.PUBLIC)
private Collection<ConfigItemDescriptor> items;
public ConfigItemsGroup(String group)
{
this.group = group;
this.items = new ArrayList<>();
}
public void addItem(ConfigItemDescriptor item)
{
items.add(item);
}
}

View File

@@ -364,9 +364,9 @@ public class ConfigManager
}
itemGroups = itemGroups.stream().sorted((a, b) -> ComparisonChain.start()
.compare(a.getGroup(), b.getGroup())
.result())
.collect(Collectors.toList());
.compare(a.getGroup(), b.getGroup())
.result())
.collect(Collectors.toList());
return new ConfigDescriptor(group, itemGroups);
}
@@ -511,22 +511,22 @@ public class ConfigManager
{
return Duration.ofMillis(Long.parseLong(str));
}
if (type == Map.class)
{
Map<String, String> output = new HashMap<>();
str = str.substring(1, str.length() - 1);
String[] splitStr = str.split(", ");
for (String s : splitStr)
{
String[] keyVal = s.split("=");
if (keyVal.length > 1)
{
output.put(keyVal[0], keyVal[1]);
}
}
if (type == Map.class)
{
Map<String, String> output = new HashMap<>();
str = str.substring(1, str.length() - 1);
String[] splitStr = str.split(", ");
for (String s : splitStr)
{
String[] keyVal = s.split("=");
if (keyVal.length > 1)
{
output.put(keyVal[0], keyVal[1]);
}
}
return output;
}
return output;
}
return str;
}

View File

@@ -1,49 +1,48 @@
/*
* Copyright (c) 2018, Tanner <https://github.com/Reasel>
* 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 lombok.RequiredArgsConstructor;
import lombok.Getter;
import net.runelite.client.ui.FontManager;
import java.awt.Font;
@Getter
@RequiredArgsConstructor
public enum FontType
{
REGULAR("Regular", FontManager.getRunescapeFont()),
BOLD("Bold", FontManager.getRunescapeBoldFont()),
SMALL("Small", FontManager.getRunescapeSmallFont());
private final String name;
private final Font font;
@Override
public String toString()
{
return name;
}
}
/*
* Copyright (c) 2018, Tanner <https://github.com/Reasel>
* 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.awt.Font;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.runelite.client.ui.FontManager;
@Getter
@RequiredArgsConstructor
public enum FontType
{
REGULAR("Regular", FontManager.getRunescapeFont()),
BOLD("Bold", FontManager.getRunescapeBoldFont()),
SMALL("Small", FontManager.getRunescapeSmallFont());
private final String name;
private final Font font;
@Override
public String toString()
{
return name;
}
}

View File

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

View File

@@ -106,7 +106,7 @@ public class DiscordService implements AutoCloseable
discordEventHandlers.joinGame = this::joinGame;
discordEventHandlers.spectateGame = this::spectateGame;
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);
}

View File

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

View File

@@ -28,163 +28,198 @@
package net.runelite.client.flexo;
import net.runelite.client.ui.ClientUI;
import java.awt.*;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Random;
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.
*/
public static Point getClickPoint(Rectangle rect)
{
if (rect!=null) {
Random r = new Random();
int x = -1;
int y = -1;
x = rect.x+r.nextInt(rect.width);
y = rect.y+r.nextInt(rect.height);
/*
Should pass unstretched coords, handles all conversions here.
*/
public static Point getClickPoint(Rectangle rect)
{
if (rect != null)
{
Random r = new Random();
int x = -1;
int y = -1;
x = rect.x + r.nextInt(rect.width);
y = rect.y + r.nextInt(rect.height);
if (Flexo.isStretched) {
double wScale;
double hScale;
if (Flexo.isStretched)
{
double wScale;
double hScale;
if (Flexo.client.isResized()) {
wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width);
hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height);
int newX = (int)(x*wScale);
int newY = (int)(y*hScale);
if (newX>0 && newX< ClientUI.frame.getWidth()) {
if (newY>0 && newY< ClientUI.frame.getHeight()) {
return new Point(newX, newY);
}
}
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
return null;
} else {
if (x>0 && x< ClientUI.frame.getWidth()) {
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;
}
if (Flexo.client.isResized())
{
wScale = (Flexo.client.getStretchedDimensions().width / (double) Flexo.client.getRealDimensions().width);
hScale = (Flexo.client.getStretchedDimensions().height / (double) Flexo.client.getRealDimensions().height);
int newX = (int) (x * wScale);
int newY = (int) (y * hScale);
if (newX > 0 && newX < ClientUI.frame.getWidth())
{
if (newY > 0 && newY < ClientUI.frame.getHeight())
{
return new Point(newX, newY);
}
}
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
return null;
}
else
{
if (x > 0 && x < ClientUI.frame.getWidth())
{
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;
int widthDif = ClientUI.frame.getWidth();
}
else if (!Flexo.client.isResized())
{
final int fixedWidth = Constants.GAME_FIXED_WIDTH;
int widthDif = ClientUI.frame.getWidth();
if (ClientUI.pluginToolbar.isVisible()) {
widthDif -= ClientUI.pluginToolbar.getWidth();
}
if (ClientUI.pluginPanel!=null)
widthDif -= ClientUI.pluginPanel.getWidth();
if (ClientUI.pluginToolbar.isVisible())
{
widthDif -= ClientUI.pluginToolbar.getWidth();
}
if (ClientUI.pluginPanel != null)
{
widthDif -= ClientUI.pluginPanel.getWidth();
}
widthDif -= fixedWidth;
if (x+(widthDif/2)>0 && x+(widthDif/2)< ClientUI.frame.getWidth()) {
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 (x>0 && x< ClientUI.frame.getWidth()) {
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;
}
}
return null;
}
widthDif -= fixedWidth;
if (x + (widthDif / 2) > 0 && x + (widthDif / 2) < ClientUI.frame.getWidth())
{
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 (x > 0 && x < ClientUI.frame.getWidth())
{
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;
}
}
return null;
}
public static Rectangle getClickArea(Rectangle rect)
{
if (Flexo.isStretched)
{
double wScale;
double hScale;
public static Rectangle getClickArea(Rectangle rect)
{
if (Flexo.isStretched)
{
double wScale;
double hScale;
if (Flexo.client.isResized()) {
wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width);
hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height);
} else {
wScale = ((double) Flexo.client.getStretchedDimensions().width) / Flexo.fixedWidth;
hScale = ((double) Flexo.client.getStretchedDimensions().height) / Flexo.fixedHeight;
}
if (Flexo.client.isResized())
{
wScale = (Flexo.client.getStretchedDimensions().width / (double) Flexo.client.getRealDimensions().width);
hScale = (Flexo.client.getStretchedDimensions().height / (double) Flexo.client.getRealDimensions().height);
}
else
{
wScale = (Flexo.client.getStretchedDimensions().width) / (double) Flexo.fixedWidth;
hScale = (Flexo.client.getStretchedDimensions().height) / (double) Flexo.fixedHeight;
}
int xPadding = (int)rect.getWidth()/5;
int yPadding = (int)rect.getHeight()/5;
Random r = new Random();
Rectangle clickRect = new Rectangle();
clickRect.width = rect.width-xPadding*2;
clickRect.height = rect.height-yPadding*2;
clickRect.x = rect.x+xPadding;
clickRect.y = rect.y+yPadding;
if (clickRect.width>0&&clickRect.height>0) {
int x = clickRect.x+r.nextInt(clickRect.width);
int y = clickRect.y+r.nextInt(clickRect.height);
double tScale = 1 + (Flexo.scale / 100);
int xPadding = (int) rect.getWidth() / 5;
int yPadding = (int) rect.getHeight() / 5;
Random r = new Random();
Rectangle clickRect = new Rectangle();
clickRect.width = rect.width - xPadding * 2;
clickRect.height = rect.height - yPadding * 2;
clickRect.x = rect.x + xPadding;
clickRect.y = rect.y + yPadding;
if (clickRect.width > 0 && clickRect.height > 0)
{
int x = clickRect.x + r.nextInt(clickRect.width);
int y = clickRect.y + r.nextInt(clickRect.height);
double tScale = 1 + (Flexo.scale / 100);
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), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight()));
}
}
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(clickRect.x, clickRect.y, clickRect.width, (int) (clickRect.getHeight()));
}
}
}
//Fixed, not stretched
else if (!Flexo.client.isResized()) {
int fixedWidth = 765;
int widthDif = ClientUI.frame.getWidth();
}
//Fixed, not stretched
else if (!Flexo.client.isResized())
{
int fixedWidth = 765;
int widthDif = ClientUI.frame.getWidth();
if (ClientUI.pluginToolbar.isVisible()) {
widthDif -= ClientUI.pluginToolbar.getWidth();
}
if (ClientUI.pluginPanel!=null)
widthDif -= ClientUI.pluginPanel.getWidth();
if (ClientUI.pluginToolbar.isVisible())
{
widthDif -= ClientUI.pluginToolbar.getWidth();
}
if (ClientUI.pluginPanel != null)
{
widthDif -= ClientUI.pluginPanel.getWidth();
}
widthDif -= fixedWidth;
int xPadding = (int)rect.getWidth()/5;
int yPadding = (int)rect.getHeight()/5;
Random r = new Random();
Rectangle clickRect = new Rectangle();
clickRect.width = rect.width-xPadding;
clickRect.height = rect.height-yPadding;
clickRect.x = rect.x+xPadding;
clickRect.y = rect.y+yPadding;
if (clickRect.height>0&&clickRect.width>0) {
int x = clickRect.x + r.nextInt(clickRect.width);
int y = clickRect.y + r.nextInt(clickRect.height);
return new Rectangle((int) (clickRect.x), (int) (clickRect.y), (int) (clickRect.width), (int) (clickRect.getHeight()));
}
}
//Resizable, not stretched
else {
int xPadding = (int)rect.getWidth()/5;
int yPadding = (int)rect.getHeight()/5;
Random r = new Random();
Rectangle clickRect = new Rectangle();
clickRect.width = rect.width-xPadding*2;
clickRect.height = rect.height-yPadding*2;
clickRect.x = rect.x+xPadding;
clickRect.y = rect.y+yPadding;
if (clickRect.height>0&&clickRect.width>0) {
int x = clickRect.x+r.nextInt(clickRect.width);
int y = clickRect.y+r.nextInt(clickRect.height);
return new Rectangle((int)(clickRect.x), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight()));
}
}
widthDif -= fixedWidth;
int xPadding = (int) rect.getWidth() / 5;
int yPadding = (int) rect.getHeight() / 5;
Random r = new Random();
Rectangle clickRect = new Rectangle();
clickRect.width = rect.width - xPadding;
clickRect.height = rect.height - yPadding;
clickRect.x = rect.x + xPadding;
clickRect.y = rect.y + yPadding;
if (clickRect.height > 0 && clickRect.width > 0)
{
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()));
}
}
//Resizable, not stretched
else
{
int xPadding = (int) rect.getWidth() / 5;
int yPadding = (int) rect.getHeight() / 5;
Random r = new Random();
Rectangle clickRect = new Rectangle();
clickRect.width = rect.width - xPadding * 2;
clickRect.height = rect.height - yPadding * 2;
clickRect.x = rect.x + xPadding;
clickRect.y = rect.y + yPadding;
if (clickRect.height > 0 && clickRect.width > 0)
{
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;
import lombok.Getter;
import static net.runelite.api.NullObjectID.*;
import static net.runelite.api.ObjectID.*;
import static net.runelite.api.NullObjectID.NULL_25337;
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;
@Getter
public enum AgilityShortcut
{
GENERIC_SHORTCUT(1, "Shortcut", null,
// Trollheim
ROCKS_3790, ROCKS_3791,
// Fremennik Slayer Cave
STEPS_29993,
// Fossil Island
LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM,
// Brimhaven dungeon
CREVICE_30198,
// Lumbridge
STILE_12982,
// Gu'Tanoth Bridge
GAP, GAP_2831,
// Lumbridge Swamp Caves
STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673,
// Morytania Pirate Ship
ROCK_16115,
// Lumber Yard
BROKEN_FENCE_2618,
// McGrubor's Wood
LOOSE_RAILING,
// Underwater Area Fossil Island
TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962,
// Tree Gnome Village
LOOSE_RAILING_2186,
// Burgh de Rott
LOW_FENCE,
// Taverley
STILE,
// Asgarnian Ice Dungeon
STEPS,
// Fossil Island Wyvern Cave
STAIRS_31485),
// Trollheim
ROCKS_3790, ROCKS_3791,
// Fremennik Slayer Cave
STEPS_29993,
// Fossil Island
LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM,
// Brimhaven dungeon
CREVICE_30198,
// Lumbridge
STILE_12982,
// Gu'Tanoth Bridge
GAP, GAP_2831,
// Lumbridge Swamp Caves
STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673,
// Morytania Pirate Ship
ROCK_16115,
// Lumber Yard
BROKEN_FENCE_2618,
// McGrubor's Wood
LOOSE_RAILING,
// Underwater Area Fossil Island
TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962,
// Tree Gnome Village
LOOSE_RAILING_2186,
// Burgh de Rott
LOW_FENCE,
// Taverley
STILE,
// Asgarnian Ice Dungeon
STEPS,
// Fossil Island Wyvern Cave
STAIRS_31485),
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_STEPPING_STONES_RETURN(1, "Pipe Squeeze", null, STEPPING_STONE_21739),
BRIMHAVEN_DUNGEON_LOG_BALANCE_RETURN(1, "Log Balance", null, LOG_BALANCE_20884),
AGILITY_PYRAMID_ROCKS_WEST(1, "Rocks", null, CLIMBING_ROCKS_11948),
CAIRN_ISLE_CLIMBING_ROCKS(1, "Rocks", null, CLIMBING_ROCKS),
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 ),
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),
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),
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),
CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809),
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_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056),
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),
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),
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),
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),
@@ -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),
RELEKKA_EAST_FENCE(57, "Fence", new WorldPoint(2688, 3697, 0), BROKEN_FENCE),
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),
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),
@@ -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_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),
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_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),
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_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),
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),
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),
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_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),
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),
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),

View File

@@ -1,84 +1,85 @@
/*
* Copyright (c) 2018 Abex
* 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.game;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
public class AsyncBufferedImage extends BufferedImage
{
private final List<Runnable> listeners = new CopyOnWriteArrayList<>();
public AsyncBufferedImage(int width, int height, int imageType)
{
super(width, height, imageType);
}
/**
* Call when the buffer has been changed
*/
public void changed()
{
for (Runnable r : listeners)
{
r.run();
}
}
/**
* Register a function to be ran when the buffer has changed
*/
public void onChanged(Runnable r)
{
listeners.add(r);
}
/**
* Calls setIcon on c, ensuring it is repainted when this changes
*/
public void addTo(JButton c)
{
c.setIcon(makeIcon(c));
}
/**
* Calls setIcon on c, ensuring it is repainted when this changes
*/
public void addTo(JLabel c)
{
c.setIcon(makeIcon(c));
}
private ImageIcon makeIcon(JComponent c)
{
listeners.add(c::repaint);
return new ImageIcon(this);
}
}
/*
* Copyright (c) 2018 Abex
* 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.game;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
public class AsyncBufferedImage extends BufferedImage
{
private final List<Runnable> listeners = new CopyOnWriteArrayList<>();
public AsyncBufferedImage(int width, int height, int imageType)
{
super(width, height, imageType);
}
/**
* Call when the buffer has been changed
*/
public void changed()
{
for (Runnable r : listeners)
{
r.run();
}
}
/**
* Register a function to be ran when the buffer has changed
*/
public void onChanged(Runnable r)
{
listeners.add(r);
}
/**
* Calls setIcon on c, ensuring it is repainted when this changes
*/
public void addTo(JButton c)
{
c.setIcon(makeIcon(c));
}
/**
* Calls setIcon on c, ensuring it is repainted when this changes
*/
public void addTo(JLabel c)
{
c.setIcon(makeIcon(c));
}
private ImageIcon makeIcon(JComponent c)
{
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, Seth <Sethtroll3@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.game;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.Collections;
import static net.runelite.api.ItemID.*;
/**
* 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();
}
}
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* Copyright (c) 2018, Seth <Sethtroll3@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.game;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.Collections;
import static net.runelite.api.ItemID.ABYSSAL_TENTACLE;
import static net.runelite.api.ItemID.ABYSSAL_WHIP;
import static net.runelite.api.ItemID.AHRIMS_HOOD;
import static net.runelite.api.ItemID.AHRIMS_HOOD_100;
import static net.runelite.api.ItemID.AHRIMS_HOOD_25;
import static net.runelite.api.ItemID.AHRIMS_HOOD_50;
import static net.runelite.api.ItemID.AHRIMS_HOOD_75;
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT;
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_100;
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_25;
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_50;
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_75;
import static net.runelite.api.ItemID.AHRIMS_ROBETOP;
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_100;
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_25;
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_50;
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_75;
import static net.runelite.api.ItemID.AHRIMS_STAFF;
import static net.runelite.api.ItemID.AHRIMS_STAFF_100;
import static net.runelite.api.ItemID.AHRIMS_STAFF_25;
import static net.runelite.api.ItemID.AHRIMS_STAFF_50;
import static net.runelite.api.ItemID.AHRIMS_STAFF_75;
import static net.runelite.api.ItemID.AMULET_OF_FURY;
import static net.runelite.api.ItemID.AMULET_OF_FURY_OR;
import static net.runelite.api.ItemID.AMULET_OF_GLORY;
import static net.runelite.api.ItemID.AMULET_OF_GLORY1;
import static net.runelite.api.ItemID.AMULET_OF_GLORY2;
import static net.runelite.api.ItemID.AMULET_OF_GLORY3;
import static net.runelite.api.ItemID.AMULET_OF_GLORY5;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T1;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T2;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T3;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T5;
import static net.runelite.api.ItemID.AMULET_OF_TORTURE;
import static net.runelite.api.ItemID.AMULET_OF_TORTURE_OR;
import static net.runelite.api.ItemID.ANCIENT_WYVERN_SHIELD;
import static net.runelite.api.ItemID.ANCIENT_WYVERN_SHIELD_21634;
import static net.runelite.api.ItemID.ANGUISH_ORNAMENT_KIT;
import static net.runelite.api.ItemID.ARCHERS_RING;
import static net.runelite.api.ItemID.ARCHERS_RING_I;
import static net.runelite.api.ItemID.ARMADYL_GODSWORD;
import static net.runelite.api.ItemID.ARMADYL_GODSWORD_OR;
import static net.runelite.api.ItemID.ARMADYL_GODSWORD_ORNAMENT_KIT;
import static net.runelite.api.ItemID.BANDOS_GODSWORD;
import static net.runelite.api.ItemID.BANDOS_GODSWORD_OR;
import static net.runelite.api.ItemID.BANDOS_GODSWORD_ORNAMENT_KIT;
import static net.runelite.api.ItemID.BERSERKER_RING;
import static net.runelite.api.ItemID.BERSERKER_RING_I;
import static net.runelite.api.ItemID.BLACK_MASK;
import static net.runelite.api.ItemID.BLACK_MASK_1;
import static net.runelite.api.ItemID.BLACK_MASK_10_I;
import static net.runelite.api.ItemID.BLACK_MASK_1_I;
import static net.runelite.api.ItemID.BLACK_MASK_2;
import static net.runelite.api.ItemID.BLACK_MASK_2_I;
import static net.runelite.api.ItemID.BLACK_MASK_3;
import static net.runelite.api.ItemID.BLACK_MASK_3_I;
import static net.runelite.api.ItemID.BLACK_MASK_4;
import static net.runelite.api.ItemID.BLACK_MASK_4_I;
import static net.runelite.api.ItemID.BLACK_MASK_5;
import static net.runelite.api.ItemID.BLACK_MASK_5_I;
import static net.runelite.api.ItemID.BLACK_MASK_6;
import static net.runelite.api.ItemID.BLACK_MASK_6_I;
import static net.runelite.api.ItemID.BLACK_MASK_7;
import static net.runelite.api.ItemID.BLACK_MASK_7_I;
import static net.runelite.api.ItemID.BLACK_MASK_8;
import static net.runelite.api.ItemID.BLACK_MASK_8_I;
import static net.runelite.api.ItemID.BLACK_MASK_9;
import static net.runelite.api.ItemID.BLACK_MASK_9_I;
import static net.runelite.api.ItemID.BLACK_MASK_I;
import static net.runelite.api.ItemID.BLACK_SLAYER_HELMET;
import static net.runelite.api.ItemID.BLACK_SLAYER_HELMET_I;
import static net.runelite.api.ItemID.BONECRUSHER_NECKLACE;
import static net.runelite.api.ItemID.BOTTOMLESS_COMPOST_BUCKET;
import static net.runelite.api.ItemID.BOTTOMLESS_COMPOST_BUCKET_22997;
import static net.runelite.api.ItemID.CRAWS_BOW;
import static net.runelite.api.ItemID.CRAWS_BOW_U;
import static net.runelite.api.ItemID.DARK_BOW;
import static net.runelite.api.ItemID.DARK_BOW_12765;
import static net.runelite.api.ItemID.DARK_BOW_12766;
import static net.runelite.api.ItemID.DARK_BOW_12767;
import static net.runelite.api.ItemID.DARK_BOW_12768;
import static net.runelite.api.ItemID.DARK_BOW_20408;
import static net.runelite.api.ItemID.DARK_INFINITY_BOTTOMS;
import static net.runelite.api.ItemID.DARK_INFINITY_COLOUR_KIT;
import static net.runelite.api.ItemID.DARK_INFINITY_HAT;
import static net.runelite.api.ItemID.DARK_INFINITY_TOP;
import static net.runelite.api.ItemID.DHAROKS_GREATAXE;
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_100;
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_25;
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_50;
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_75;
import static net.runelite.api.ItemID.DHAROKS_HELM;
import static net.runelite.api.ItemID.DHAROKS_HELM_100;
import static net.runelite.api.ItemID.DHAROKS_HELM_25;
import static net.runelite.api.ItemID.DHAROKS_HELM_50;
import static net.runelite.api.ItemID.DHAROKS_HELM_75;
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY;
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_100;
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_25;
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_50;
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_75;
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS;
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_100;
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_25;
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_50;
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_75;
import static net.runelite.api.ItemID.DRAGONBONE_NECKLACE;
import static net.runelite.api.ItemID.DRAGONFIRE_SHIELD;
import static net.runelite.api.ItemID.DRAGONFIRE_SHIELD_11284;
import static net.runelite.api.ItemID.DRAGONFIRE_WARD;
import static net.runelite.api.ItemID.DRAGONFIRE_WARD_22003;
import static net.runelite.api.ItemID.DRAGON_BOOTS;
import static net.runelite.api.ItemID.DRAGON_BOOTS_G;
import static net.runelite.api.ItemID.DRAGON_BOOTS_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_CHAINBODY_3140;
import static net.runelite.api.ItemID.DRAGON_CHAINBODY_G;
import static net.runelite.api.ItemID.DRAGON_CHAINBODY_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_DEFENDER_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_DEFENDER_T;
import static net.runelite.api.ItemID.DRAGON_FULL_HELM;
import static net.runelite.api.ItemID.DRAGON_FULL_HELM_G;
import static net.runelite.api.ItemID.DRAGON_FULL_HELM_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_KITESHIELD;
import static net.runelite.api.ItemID.DRAGON_KITESHIELD_G;
import static net.runelite.api.ItemID.DRAGON_KITESHIELD_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_LEGSSKIRT_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_PICKAXE;
import static net.runelite.api.ItemID.DRAGON_PICKAXE_12797;
import static net.runelite.api.ItemID.DRAGON_PLATEBODY;
import static net.runelite.api.ItemID.DRAGON_PLATEBODY_G;
import static net.runelite.api.ItemID.DRAGON_PLATEBODY_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_PLATELEGS;
import static net.runelite.api.ItemID.DRAGON_PLATELEGS_G;
import static net.runelite.api.ItemID.DRAGON_PLATESKIRT;
import static net.runelite.api.ItemID.DRAGON_PLATESKIRT_G;
import static net.runelite.api.ItemID.DRAGON_SCIMITAR;
import static net.runelite.api.ItemID.DRAGON_SCIMITAR_OR;
import static net.runelite.api.ItemID.DRAGON_SCIMITAR_ORNAMENT_KIT;
import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD;
import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD_G;
import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD_ORNAMENT_KIT;
import static net.runelite.api.ItemID.ENSOULED_ABYSSAL_HEAD;
import static net.runelite.api.ItemID.ENSOULED_ABYSSAL_HEAD_13508;
import static net.runelite.api.ItemID.ENSOULED_AVIANSIE_HEAD;
import static net.runelite.api.ItemID.ENSOULED_AVIANSIE_HEAD_13505;
import static net.runelite.api.ItemID.ENSOULED_BEAR_HEAD;
import static net.runelite.api.ItemID.ENSOULED_BEAR_HEAD_13463;
import static net.runelite.api.ItemID.ENSOULED_BLOODVELD_HEAD;
import static net.runelite.api.ItemID.ENSOULED_BLOODVELD_HEAD_13496;
import static net.runelite.api.ItemID.ENSOULED_CHAOS_DRUID_HEAD;
import static net.runelite.api.ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472;
import static net.runelite.api.ItemID.ENSOULED_DAGANNOTH_HEAD;
import static net.runelite.api.ItemID.ENSOULED_DAGANNOTH_HEAD_13493;
import static net.runelite.api.ItemID.ENSOULED_DEMON_HEAD;
import static net.runelite.api.ItemID.ENSOULED_DEMON_HEAD_13502;
import static net.runelite.api.ItemID.ENSOULED_DOG_HEAD;
import static net.runelite.api.ItemID.ENSOULED_DOG_HEAD_13469;
import static net.runelite.api.ItemID.ENSOULED_DRAGON_HEAD;
import static net.runelite.api.ItemID.ENSOULED_DRAGON_HEAD_13511;
import static net.runelite.api.ItemID.ENSOULED_ELF_HEAD;
import static net.runelite.api.ItemID.ENSOULED_ELF_HEAD_13481;
import static net.runelite.api.ItemID.ENSOULED_GIANT_HEAD;
import static net.runelite.api.ItemID.ENSOULED_GIANT_HEAD_13475;
import static net.runelite.api.ItemID.ENSOULED_GOBLIN_HEAD;
import static net.runelite.api.ItemID.ENSOULED_GOBLIN_HEAD_13448;
import static net.runelite.api.ItemID.ENSOULED_HORROR_HEAD;
import static net.runelite.api.ItemID.ENSOULED_HORROR_HEAD_13487;
import static net.runelite.api.ItemID.ENSOULED_IMP_HEAD;
import static net.runelite.api.ItemID.ENSOULED_IMP_HEAD_13454;
import static net.runelite.api.ItemID.ENSOULED_KALPHITE_HEAD;
import static net.runelite.api.ItemID.ENSOULED_KALPHITE_HEAD_13490;
import static net.runelite.api.ItemID.ENSOULED_MINOTAUR_HEAD;
import static net.runelite.api.ItemID.ENSOULED_MINOTAUR_HEAD_13457;
import static net.runelite.api.ItemID.ENSOULED_MONKEY_HEAD;
import static net.runelite.api.ItemID.ENSOULED_MONKEY_HEAD_13451;
import static net.runelite.api.ItemID.ENSOULED_OGRE_HEAD;
import static net.runelite.api.ItemID.ENSOULED_OGRE_HEAD_13478;
import static net.runelite.api.ItemID.ENSOULED_SCORPION_HEAD;
import static net.runelite.api.ItemID.ENSOULED_SCORPION_HEAD_13460;
import static net.runelite.api.ItemID.ENSOULED_TROLL_HEAD;
import static net.runelite.api.ItemID.ENSOULED_TROLL_HEAD_13484;
import static net.runelite.api.ItemID.ENSOULED_TZHAAR_HEAD;
import static net.runelite.api.ItemID.ENSOULED_TZHAAR_HEAD_13499;
import static net.runelite.api.ItemID.ENSOULED_UNICORN_HEAD;
import static net.runelite.api.ItemID.ENSOULED_UNICORN_HEAD_13466;
import static net.runelite.api.ItemID.FEROCIOUS_GLOVES;
import static net.runelite.api.ItemID.FROZEN_ABYSSAL_WHIP;
import static net.runelite.api.ItemID.FURY_ORNAMENT_KIT;
import static net.runelite.api.ItemID.GAMES_NECKLACE1;
import static net.runelite.api.ItemID.GAMES_NECKLACE2;
import static net.runelite.api.ItemID.GAMES_NECKLACE3;
import static net.runelite.api.ItemID.GAMES_NECKLACE4;
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;
import static net.runelite.api.ItemID.GRANITE_MAUL_12848;
import static net.runelite.api.ItemID.GRANITE_RING;
import static net.runelite.api.ItemID.GRANITE_RING_I;
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;
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_25;
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_50;
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_75;
import static net.runelite.api.ItemID.GUTHANS_HELM;
import static net.runelite.api.ItemID.GUTHANS_HELM_100;
import static net.runelite.api.ItemID.GUTHANS_HELM_25;
import static net.runelite.api.ItemID.GUTHANS_HELM_50;
import static net.runelite.api.ItemID.GUTHANS_HELM_75;
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY;
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_100;
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_25;
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;
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;
import static net.runelite.api.ItemID.HYDRA_LEATHER;
import static net.runelite.api.ItemID.HYDRA_SLAYER_HELMET;
import static net.runelite.api.ItemID.HYDRA_SLAYER_HELMET_I;
import static net.runelite.api.ItemID.HYDRA_TAIL;
import static net.runelite.api.ItemID.INFINITY_BOTTOMS;
import static net.runelite.api.ItemID.INFINITY_BOTTOMS_20575;
import static net.runelite.api.ItemID.INFINITY_HAT;
import static net.runelite.api.ItemID.INFINITY_TOP;
import static net.runelite.api.ItemID.INFINITY_TOP_10605;
import static net.runelite.api.ItemID.INFINITY_TOP_20574;
import static net.runelite.api.ItemID.KARILS_COIF;
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;
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>
* 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.game;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class NPCManager
{
private final Map<String, Integer> healthMap;
@Inject
private NPCManager()
{
final Gson gson = new Gson();
final Type typeToken = new TypeToken<Map<String, Integer>>()
{
}.getType();
final InputStream healthFile = getClass().getResourceAsStream("/npc_health.json");
healthMap = gson.fromJson(new InputStreamReader(healthFile), typeToken);
}
/**
* Returns health for target NPC based on it's combat level and name
* @param name npc name
* @param combatLevel npc combat level
* @return health or null if HP is unknown
*/
@Nullable
public Integer getHealth(final String name, final int combatLevel)
{
return healthMap.get(name + "_" + combatLevel);
}
}
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* 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.game;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class NPCManager
{
private final Map<String, Integer> healthMap;
@Inject
private NPCManager()
{
final Gson gson = new Gson();
final Type typeToken = new TypeToken<Map<String, Integer>>()
{
}.getType();
final InputStream healthFile = getClass().getResourceAsStream("/npc_health.json");
healthMap = gson.fromJson(new InputStreamReader(healthFile), typeToken);
}
/**
* Returns health for target NPC based on it's combat level and name
*
* @param name npc name
* @param combatLevel npc combat level
* @return health or null if HP is unknown
*/
@Nullable
public Integer getHealth(final String name, final int combatLevel)
{
return healthMap.get(name + "_" + combatLevel);
}
}

View File

@@ -1,202 +1,202 @@
/*
* Copyright (c) 2018 Abex
* 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.game.chatbox;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.ScriptID;
import net.runelite.api.VarClientInt;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.vars.InputType;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseListener;
import net.runelite.client.input.MouseManager;
import net.runelite.client.input.MouseWheelListener;
@Singleton
@Slf4j
public class ChatboxPanelManager
{
private final Client client;
private final ClientThread clientThread;
private final EventBus eventBus;
private final KeyManager keyManager;
private final MouseManager mouseManager;
private final Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider;
private final Provider<ChatboxTextInput> chatboxTextInputProvider;
@Getter
private ChatboxInput currentInput = null;
@Inject
private ChatboxPanelManager(EventBus eventBus, Client client, ClientThread clientThread,
KeyManager keyManager, MouseManager mouseManager,
Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider, Provider<ChatboxTextInput> chatboxTextInputProvider)
{
this.client = client;
this.clientThread = clientThread;
this.eventBus = eventBus;
this.keyManager = keyManager;
this.mouseManager = mouseManager;
this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider;
this.chatboxTextInputProvider = chatboxTextInputProvider;
}
public void close()
{
clientThread.invokeLater(this::unsafeCloseInput);
}
private void unsafeCloseInput()
{
client.runScript(
ScriptID.RESET_CHATBOX_INPUT,
0,
1
);
if (currentInput != null)
{
killCurrentPanel();
}
}
private void unsafeOpenInput(ChatboxInput input)
{
client.runScript(ScriptID.CLEAR_CHATBOX_PANEL);
eventBus.register(input);
if (input instanceof KeyListener)
{
keyManager.registerKeyListener((KeyListener) input);
}
if (input instanceof MouseListener)
{
mouseManager.registerMouseListener((MouseListener) input);
}
if (input instanceof MouseWheelListener)
{
mouseManager.registerMouseWheelListener((MouseWheelListener) input);
}
if (currentInput != null)
{
killCurrentPanel();
}
currentInput = input;
client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType());
client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true);
client.getWidget(WidgetInfo.CHATBOX_FULL_INPUT).setHidden(true);
Widget c = getContainerWidget();
c.deleteAllChildren();
c.setOnDialogAbortListener((JavaScriptCallback) ev -> this.unsafeCloseInput());
input.open();
}
public void openInput(ChatboxInput input)
{
clientThread.invokeLater(() -> unsafeOpenInput(input));
}
public ChatboxTextMenuInput openTextMenuInput(String title)
{
return chatboxTextMenuInputProvider.get()
.title(title);
}
public ChatboxTextInput openTextInput(String prompt)
{
return chatboxTextInputProvider.get()
.prompt(prompt);
}
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent ev)
{
if (currentInput != null && "resetChatboxInput".equals(ev.getEventName()))
{
killCurrentPanel();
}
}
@Subscribe
private void onGameStateChanged(GameStateChanged ev)
{
if (currentInput != null && ev.getGameState() == GameState.LOGIN_SCREEN)
{
killCurrentPanel();
}
}
private void killCurrentPanel()
{
try
{
currentInput.close();
}
catch (Exception e)
{
log.warn("Exception closing {}", currentInput.getClass(), e);
}
eventBus.unregister(currentInput);
if (currentInput instanceof KeyListener)
{
keyManager.unregisterKeyListener((KeyListener) currentInput);
}
if (currentInput instanceof MouseListener)
{
mouseManager.unregisterMouseListener((MouseListener) currentInput);
}
if (currentInput instanceof MouseWheelListener)
{
mouseManager.unregisterMouseWheelListener((MouseWheelListener) currentInput);
}
currentInput = null;
}
public Widget getContainerWidget()
{
return client.getWidget(WidgetInfo.CHATBOX_CONTAINER);
}
}
/*
* Copyright (c) 2018 Abex
* 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.game.chatbox;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.ScriptID;
import net.runelite.api.VarClientInt;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.vars.InputType;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseListener;
import net.runelite.client.input.MouseManager;
import net.runelite.client.input.MouseWheelListener;
@Singleton
@Slf4j
public class ChatboxPanelManager
{
private final Client client;
private final ClientThread clientThread;
private final EventBus eventBus;
private final KeyManager keyManager;
private final MouseManager mouseManager;
private final Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider;
private final Provider<ChatboxTextInput> chatboxTextInputProvider;
@Getter
private ChatboxInput currentInput = null;
@Inject
private ChatboxPanelManager(EventBus eventBus, Client client, ClientThread clientThread,
KeyManager keyManager, MouseManager mouseManager,
Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider, Provider<ChatboxTextInput> chatboxTextInputProvider)
{
this.client = client;
this.clientThread = clientThread;
this.eventBus = eventBus;
this.keyManager = keyManager;
this.mouseManager = mouseManager;
this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider;
this.chatboxTextInputProvider = chatboxTextInputProvider;
}
public void close()
{
clientThread.invokeLater(this::unsafeCloseInput);
}
private void unsafeCloseInput()
{
client.runScript(
ScriptID.RESET_CHATBOX_INPUT,
0,
1
);
if (currentInput != null)
{
killCurrentPanel();
}
}
private void unsafeOpenInput(ChatboxInput input)
{
client.runScript(ScriptID.CLEAR_CHATBOX_PANEL);
eventBus.register(input);
if (input instanceof KeyListener)
{
keyManager.registerKeyListener((KeyListener) input);
}
if (input instanceof MouseListener)
{
mouseManager.registerMouseListener((MouseListener) input);
}
if (input instanceof MouseWheelListener)
{
mouseManager.registerMouseWheelListener((MouseWheelListener) input);
}
if (currentInput != null)
{
killCurrentPanel();
}
currentInput = input;
client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType());
client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true);
client.getWidget(WidgetInfo.CHATBOX_FULL_INPUT).setHidden(true);
Widget c = getContainerWidget();
c.deleteAllChildren();
c.setOnDialogAbortListener((JavaScriptCallback) ev -> this.unsafeCloseInput());
input.open();
}
public void openInput(ChatboxInput input)
{
clientThread.invokeLater(() -> unsafeOpenInput(input));
}
public ChatboxTextMenuInput openTextMenuInput(String title)
{
return chatboxTextMenuInputProvider.get()
.title(title);
}
public ChatboxTextInput openTextInput(String prompt)
{
return chatboxTextInputProvider.get()
.prompt(prompt);
}
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent ev)
{
if (currentInput != null && "resetChatboxInput".equals(ev.getEventName()))
{
killCurrentPanel();
}
}
@Subscribe
private void onGameStateChanged(GameStateChanged ev)
{
if (currentInput != null && ev.getGameState() == GameState.LOGIN_SCREEN)
{
killCurrentPanel();
}
}
private void killCurrentPanel()
{
try
{
currentInput.close();
}
catch (Exception e)
{
log.warn("Exception closing {}", currentInput.getClass(), e);
}
eventBus.unregister(currentInput);
if (currentInput instanceof KeyListener)
{
keyManager.unregisterKeyListener((KeyListener) currentInput);
}
if (currentInput instanceof MouseListener)
{
mouseManager.unregisterMouseListener((MouseListener) currentInput);
}
if (currentInput instanceof MouseWheelListener)
{
mouseManager.unregisterMouseWheelListener((MouseWheelListener) currentInput);
}
currentInput = null;
}
public Widget getContainerWidget()
{
return client.getWidget(WidgetInfo.CHATBOX_CONTAINER);
}
}

View File

@@ -1,213 +1,213 @@
/*
* Copyright (c) 2018 Abex
* 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.game.chatbox;
import com.google.inject.Inject;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.FontID;
import net.runelite.api.widgets.WidgetType;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetTextAlignment;
import net.runelite.client.input.KeyListener;
@Slf4j
public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener
{
@Data
@AllArgsConstructor
private static final class Entry
{
private String text;
private Runnable callback;
}
private final ChatboxPanelManager chatboxPanelManager;
@Getter
private String title;
@Getter
private List<Entry> options = new ArrayList<>();
@Getter
private Runnable onClose;
@Inject
protected ChatboxTextMenuInput(ChatboxPanelManager chatboxPanelManager)
{
this.chatboxPanelManager = chatboxPanelManager;
}
public ChatboxTextMenuInput title(String title)
{
this.title = title;
return this;
}
public ChatboxTextMenuInput option(String text, Runnable callback)
{
options.add(new Entry(text, callback));
return this;
}
public ChatboxTextMenuInput onClose(Runnable onClose)
{
this.onClose = onClose;
return this;
}
public ChatboxTextMenuInput build()
{
if (title == null)
{
throw new IllegalStateException("Title must be set");
}
if (options.size() < 1)
{
throw new IllegalStateException("You must have atleast 1 option");
}
chatboxPanelManager.openInput(this);
return this;
}
@Override
protected void open()
{
Widget container = chatboxPanelManager.getContainerWidget();
Widget prompt = container.createChild(-1, WidgetType.TEXT);
prompt.setText(title);
prompt.setTextColor(0x800000);
prompt.setFontId(FontID.QUILL_8);
prompt.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
prompt.setOriginalX(0);
prompt.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
prompt.setOriginalY(8);
prompt.setOriginalHeight(24);
prompt.setXTextAlignment(WidgetTextAlignment.CENTER);
prompt.setYTextAlignment(WidgetTextAlignment.CENTER);
prompt.setWidthMode(WidgetSizeMode.MINUS);
prompt.revalidate();
int y = prompt.getRelativeX() + prompt.getHeight() + 6;
int height = container.getHeight() - y - 8;
int step = height / options.size();
int maxStep = options.size() >= 3 ? 25 : 30;
if (step > maxStep)
{
int ds = step - maxStep;
step = maxStep;
y += (ds * options.size()) / 2;
}
for (Entry option : options)
{
Widget optWidget = container.createChild(-1, WidgetType.TEXT);
optWidget.setText(option.text);
optWidget.setFontId(FontID.QUILL_8);
optWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
optWidget.setOriginalX(0);
optWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
optWidget.setOriginalY(y);
optWidget.setOriginalHeight(24);
optWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
optWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
optWidget.setWidthMode(WidgetSizeMode.MINUS);
optWidget.setAction(0, "Continue");
optWidget.setOnOpListener((JavaScriptCallback) ev -> callback(option));
optWidget.setOnMouseOverListener((JavaScriptCallback) ev -> optWidget.setTextColor(0xFFFFFF));
optWidget.setOnMouseLeaveListener((JavaScriptCallback) ev -> optWidget.setTextColor(0));
optWidget.setHasListener(true);
optWidget.revalidate();
y += step;
}
}
private void callback(Entry entry)
{
Widget container = chatboxPanelManager.getContainerWidget();
container.setOnKeyListener((Object[]) null);
chatboxPanelManager.close();
entry.callback.run();
}
@Override
protected void close()
{
if (onClose != null)
{
onClose.run();
}
}
@Override
public void keyTyped(KeyEvent e)
{
char c = e.getKeyChar();
if (c == '\033')
{
chatboxPanelManager.close();
e.consume();
return;
}
int n = c - '1';
if (n >= 0 && n < options.size())
{
callback(options.get(n));
e.consume();
}
}
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
e.consume();
}
}
@Override
public void keyReleased(KeyEvent e)
{
}
}
/*
* Copyright (c) 2018 Abex
* 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.game.chatbox;
import com.google.inject.Inject;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.FontID;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetTextAlignment;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.input.KeyListener;
@Slf4j
public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener
{
@Data
@AllArgsConstructor
private static final class Entry
{
private String text;
private Runnable callback;
}
private final ChatboxPanelManager chatboxPanelManager;
@Getter
private String title;
@Getter
private List<Entry> options = new ArrayList<>();
@Getter
private Runnable onClose;
@Inject
protected ChatboxTextMenuInput(ChatboxPanelManager chatboxPanelManager)
{
this.chatboxPanelManager = chatboxPanelManager;
}
public ChatboxTextMenuInput title(String title)
{
this.title = title;
return this;
}
public ChatboxTextMenuInput option(String text, Runnable callback)
{
options.add(new Entry(text, callback));
return this;
}
public ChatboxTextMenuInput onClose(Runnable onClose)
{
this.onClose = onClose;
return this;
}
public ChatboxTextMenuInput build()
{
if (title == null)
{
throw new IllegalStateException("Title must be set");
}
if (options.size() < 1)
{
throw new IllegalStateException("You must have atleast 1 option");
}
chatboxPanelManager.openInput(this);
return this;
}
@Override
protected void open()
{
Widget container = chatboxPanelManager.getContainerWidget();
Widget prompt = container.createChild(-1, WidgetType.TEXT);
prompt.setText(title);
prompt.setTextColor(0x800000);
prompt.setFontId(FontID.QUILL_8);
prompt.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
prompt.setOriginalX(0);
prompt.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
prompt.setOriginalY(8);
prompt.setOriginalHeight(24);
prompt.setXTextAlignment(WidgetTextAlignment.CENTER);
prompt.setYTextAlignment(WidgetTextAlignment.CENTER);
prompt.setWidthMode(WidgetSizeMode.MINUS);
prompt.revalidate();
int y = prompt.getRelativeX() + prompt.getHeight() + 6;
int height = container.getHeight() - y - 8;
int step = height / options.size();
int maxStep = options.size() >= 3 ? 25 : 30;
if (step > maxStep)
{
int ds = step - maxStep;
step = maxStep;
y += (ds * options.size()) / 2;
}
for (Entry option : options)
{
Widget optWidget = container.createChild(-1, WidgetType.TEXT);
optWidget.setText(option.text);
optWidget.setFontId(FontID.QUILL_8);
optWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
optWidget.setOriginalX(0);
optWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
optWidget.setOriginalY(y);
optWidget.setOriginalHeight(24);
optWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
optWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
optWidget.setWidthMode(WidgetSizeMode.MINUS);
optWidget.setAction(0, "Continue");
optWidget.setOnOpListener((JavaScriptCallback) ev -> callback(option));
optWidget.setOnMouseOverListener((JavaScriptCallback) ev -> optWidget.setTextColor(0xFFFFFF));
optWidget.setOnMouseLeaveListener((JavaScriptCallback) ev -> optWidget.setTextColor(0));
optWidget.setHasListener(true);
optWidget.revalidate();
y += step;
}
}
private void callback(Entry entry)
{
Widget container = chatboxPanelManager.getContainerWidget();
container.setOnKeyListener((Object[]) null);
chatboxPanelManager.close();
entry.callback.run();
}
@Override
protected void close()
{
if (onClose != null)
{
onClose.run();
}
}
@Override
public void keyTyped(KeyEvent e)
{
char c = e.getKeyChar();
if (c == '\033')
{
chatboxPanelManager.close();
e.consume();
return;
}
int n = c - '1';
if (n >= 0 && n < options.size())
{
callback(options.get(n));
e.consume();
}
}
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
e.consume();
}
}
@Override
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
*/
private void renderOutline(BufferedImage image, int outlineWidth,
Color innerColor, Color outerColor)
Color innerColor, Color outerColor)
{
int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
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
*/
private void drawModelOutline(Model model,
int localX, int localY, int localZ, int orientation,
int outlineWidth, Color innerColor, Color outerColor)
int localX, int localY, int localZ, int orientation,
int outlineWidth, Color innerColor, Color outerColor)
{
if (outlineWidth <= 0)
{

View File

@@ -1,106 +1,105 @@
/*
* Copyright (c) 2017, Robin <robin.weymans@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.menus;
import net.runelite.api.widgets.WidgetInfo;
import java.awt.Color;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
public final class WidgetMenuOption
{
/**
* The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop"
*/
private String menuOption;
/**
* The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones"
*/
private String menuTarget;
/**
* The color that the menuTarget should be. Defaults to the brownish color that most menu options have.
*/
private Color color = JagexColors.MENU_TARGET;
/**
* The widget to add the option to
*/
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
*
* @param menuOption Option text of this right click option
* @param menuTarget Target text of this right click option
* @param widget The widget to attach this option to
*/
public WidgetMenuOption(String menuOption, String menuTarget, WidgetInfo widget)
{
this.menuOption = menuOption;
setMenuTarget(menuTarget);
this.widget = widget;
}
public void setMenuOption(String option)
{
menuOption = option;
}
/**
* Sets the target of the menu option. Color code will be added on to target
*
* @param target The target text without color code.
*/
public void setMenuTarget(String target)
{
menuTarget = ColorUtil.wrapWithColorTag(target, color);
}
public String getMenuOption()
{
return menuOption;
}
public String getMenuTarget()
{
return menuTarget;
}
public WidgetInfo getWidget()
{
return widget;
}
public Color getColor()
{
return color;
}
public void setColor(Color col)
{
color = col;
}
}
/*
* Copyright (c) 2017, Robin <robin.weymans@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.menus;
import java.awt.Color;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
public final class WidgetMenuOption
{
/**
* The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop"
*/
private String menuOption;
/**
* The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones"
*/
private String menuTarget;
/**
* The color that the menuTarget should be. Defaults to the brownish color that most menu options have.
*/
private Color color = JagexColors.MENU_TARGET;
/**
* The widget to add the option to
*/
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
*
* @param menuOption Option text of this right click option
* @param menuTarget Target text of this right click option
* @param widget The widget to attach this option to
*/
public WidgetMenuOption(String menuOption, String menuTarget, WidgetInfo widget)
{
this.menuOption = menuOption;
setMenuTarget(menuTarget);
this.widget = widget;
}
public void setMenuOption(String option)
{
menuOption = option;
}
/**
* Sets the target of the menu option. Color code will be added on to target
*
* @param target The target text without color code.
*/
public void setMenuTarget(String target)
{
menuTarget = ColorUtil.wrapWithColorTag(target, color);
}
public String getMenuOption()
{
return menuOption;
}
public String getMenuTarget()
{
return menuTarget;
}
public WidgetInfo getWidget()
{
return widget;
}
public Color getColor()
{
return color;
}
public void setColor(Color col)
{
color = col;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,131 +1,334 @@
/*
* Copyright (c) 2018, SomeoneWithAnInternetConnection
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.agility;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import java.util.List;
import java.util.Set;
import static net.runelite.api.NullObjectID.NULL_10872;
import static net.runelite.api.NullObjectID.NULL_10873;
import static net.runelite.api.NullObjectID.NULL_12945;
import static net.runelite.api.NullObjectID.NULL_18083;
import static net.runelite.api.NullObjectID.NULL_18116;
import static net.runelite.api.NullObjectID.NULL_18122;
import static net.runelite.api.NullObjectID.NULL_18124;
import static net.runelite.api.NullObjectID.NULL_18129;
import static net.runelite.api.NullObjectID.NULL_18130;
import static net.runelite.api.NullObjectID.NULL_18132;
import static net.runelite.api.NullObjectID.NULL_18133;
import static net.runelite.api.NullObjectID.NULL_18135;
import static net.runelite.api.NullObjectID.NULL_18136;
import static net.runelite.api.NullObjectID.NULL_3550;
import static net.runelite.api.ObjectID.*;
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();
}
}
/*
* Copyright (c) 2018, SomeoneWithAnInternetConnection
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.agility;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import java.util.List;
import java.util.Set;
import static net.runelite.api.NullObjectID.NULL_10872;
import static net.runelite.api.NullObjectID.NULL_10873;
import static net.runelite.api.NullObjectID.NULL_12945;
import static net.runelite.api.NullObjectID.NULL_18083;
import static net.runelite.api.NullObjectID.NULL_18116;
import static net.runelite.api.NullObjectID.NULL_18122;
import static net.runelite.api.NullObjectID.NULL_18124;
import static net.runelite.api.NullObjectID.NULL_18129;
import static net.runelite.api.NullObjectID.NULL_18130;
import static net.runelite.api.NullObjectID.NULL_18132;
import static net.runelite.api.NullObjectID.NULL_18133;
import static net.runelite.api.NullObjectID.NULL_18135;
import static net.runelite.api.NullObjectID.NULL_18136;
import static net.runelite.api.NullObjectID.NULL_3550;
import static net.runelite.api.ObjectID.BALANCING_LEDGE;
import static net.runelite.api.ObjectID.BALANCING_LEDGE_23547;
import static net.runelite.api.ObjectID.BALANCING_LEDGE_3561;
import static net.runelite.api.ObjectID.BALANCING_ROPE;
import static net.runelite.api.ObjectID.BALANCING_ROPE_23557;
import static net.runelite.api.ObjectID.BANNER_11382;
import static net.runelite.api.ObjectID.BASKET_11380;
import static net.runelite.api.ObjectID.BOAT_17961;
import static net.runelite.api.ObjectID.BOILER_22635;
import static net.runelite.api.ObjectID.CABLE;
import static net.runelite.api.ObjectID.CABLE_22569;
import static net.runelite.api.ObjectID.CABLE_22572;
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_10851;
import static net.runelite.api.ObjectID.CLOTHES_LINE;
import static net.runelite.api.ObjectID.CONSOLE;
import static net.runelite.api.ObjectID.CRATE_10086;
import static net.runelite.api.ObjectID.CRUMBLING_WALL_1948;
import static net.runelite.api.ObjectID.DOORWAY_10855;
import static net.runelite.api.ObjectID.DOOR_18091;
import static net.runelite.api.ObjectID.DRYING_LINE;
import static net.runelite.api.ObjectID.EDGE;
import static net.runelite.api.ObjectID.EDGE_11371;
import static net.runelite.api.ObjectID.EDGE_11377;
import static net.runelite.api.ObjectID.FLOORBOARDS;
import static net.runelite.api.ObjectID.FLOORBOARDS_18071;
import static net.runelite.api.ObjectID.FLOORBOARDS_18072;
import static net.runelite.api.ObjectID.FLOORBOARDS_18073;
import static net.runelite.api.ObjectID.FLOORBOARDS_18089;
import static net.runelite.api.ObjectID.FLOORBOARDS_18090;
import static net.runelite.api.ObjectID.FLOORBOARDS_18093;
import static net.runelite.api.ObjectID.FLOORBOARDS_18094;
import static net.runelite.api.ObjectID.FLOORBOARDS_18097;
import static net.runelite.api.ObjectID.FLOORBOARDS_18098;
import static net.runelite.api.ObjectID.FLOORBOARDS_18109;
import static net.runelite.api.ObjectID.FLOORBOARDS_18110;
import static net.runelite.api.ObjectID.FLOORBOARDS_18111;
import static net.runelite.api.ObjectID.FLOORBOARDS_18112;
import static net.runelite.api.ObjectID.FLOORBOARDS_18113;
import static net.runelite.api.ObjectID.FLOORBOARDS_18114;
import static net.runelite.api.ObjectID.FLOORBOARDS_18117;
import static net.runelite.api.ObjectID.FLOORBOARDS_18118;
import static net.runelite.api.ObjectID.GAP_10085;
import static net.runelite.api.ObjectID.GAP_10352;
import static net.runelite.api.ObjectID.GAP_10642;
import static net.runelite.api.ObjectID.GAP_10778;
import static net.runelite.api.ObjectID.GAP_10779;
import static net.runelite.api.ObjectID.GAP_10780;
import static net.runelite.api.ObjectID.GAP_10820;
import static net.runelite.api.ObjectID.GAP_10821;
import static net.runelite.api.ObjectID.GAP_10822;
import static net.runelite.api.ObjectID.GAP_10823;
import static net.runelite.api.ObjectID.GAP_10828;
import static net.runelite.api.ObjectID.GAP_10832;
import static net.runelite.api.ObjectID.GAP_10859;
import static net.runelite.api.ObjectID.GAP_10861;
import static net.runelite.api.ObjectID.GAP_10882;
import static net.runelite.api.ObjectID.GAP_10884;
import static net.runelite.api.ObjectID.GAP_11161;
import static net.runelite.api.ObjectID.GAP_11360;
import static net.runelite.api.ObjectID.GAP_11365;
import static net.runelite.api.ObjectID.GAP_11374;
import static net.runelite.api.ObjectID.GAP_11375;
import static net.runelite.api.ObjectID.GAP_11376;
import static net.runelite.api.ObjectID.GAP_11383;
import static net.runelite.api.ObjectID.GAP_11392;
import static net.runelite.api.ObjectID.GAP_11395;
import static net.runelite.api.ObjectID.GAP_11396;
import static net.runelite.api.ObjectID.GAP_11406;
import static net.runelite.api.ObjectID.GAP_11429;
import static net.runelite.api.ObjectID.GAP_11430;
import static net.runelite.api.ObjectID.GAP_11630;
import static net.runelite.api.ObjectID.HAND_HOLDS_10836;
import static net.runelite.api.ObjectID.HAND_HOLDS_3583;
import static net.runelite.api.ObjectID.HURDLE;
import static net.runelite.api.ObjectID.HURDLE_11639;
import static net.runelite.api.ObjectID.HURDLE_11640;
import static net.runelite.api.ObjectID.ICE;
import static net.runelite.api.ObjectID.ICE_21149;
import static net.runelite.api.ObjectID.ICE_21150;
import static net.runelite.api.ObjectID.ICE_21151;
import static net.runelite.api.ObjectID.ICE_21152;
import static net.runelite.api.ObjectID.ICE_21153;
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>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.alchemicalhydra;
import lombok.Getter;
import net.runelite.api.AnimationID;
import net.runelite.api.ProjectileID;
import net.runelite.api.SpriteID;
import net.runelite.api.coords.WorldPoint;
enum HydraPhase
{ // 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)),
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)),
FOUR (1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null);
@Getter
private final int attacksPerSwitch;
@Getter
private final int deathAnim1;
@Getter
private final int deathAnim2;
@Getter
private final int specProjectileId;
@Getter
private final int specAnimationId;
@Getter
private final int specImage;
@Getter
private WorldPoint fountain;
HydraPhase(int attacksPerSwitch, int deathAnim1, int deathAnim2, int specProjectileId, int specAnimationId, int specImage, WorldPoint fountain)
{
this.attacksPerSwitch = attacksPerSwitch;
this.deathAnim1 = deathAnim1;
this.deathAnim2 = deathAnim2;
this.specProjectileId = specProjectileId;
this.specAnimationId = specAnimationId;
this.specImage = specImage;
this.fountain = fountain;
}
/*
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.alchemicalhydra;
import lombok.Getter;
import net.runelite.api.AnimationID;
import net.runelite.api.ProjectileID;
import net.runelite.api.SpriteID;
import net.runelite.api.coords.WorldPoint;
enum HydraPhase
{ // 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)),
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)),
FOUR(1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null);
@Getter
private final int attacksPerSwitch;
@Getter
private final int deathAnim1;
@Getter
private final int deathAnim2;
@Getter
private final int specProjectileId;
@Getter
private final int specAnimationId;
@Getter
private final int specImage;
@Getter
private WorldPoint fountain;
HydraPhase(int attacksPerSwitch, int deathAnim1, int deathAnim2, int specProjectileId, int specAnimationId, int specImage, WorldPoint fountain)
{
this.attacksPerSwitch = attacksPerSwitch;
this.deathAnim1 = deathAnim1;
this.deathAnim2 = deathAnim2;
this.specProjectileId = specProjectileId;
this.specAnimationId = specAnimationId;
this.specImage = specImage;
this.fountain = fountain;
}
}

View File

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

View File

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

View File

@@ -23,30 +23,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
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 javax.inject.Inject;
import net.runelite.api.Client;

View File

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

View File

@@ -71,7 +71,7 @@ public class AoeWarningOverlay extends Overlay
{
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())
{
@@ -84,7 +84,7 @@ public class AoeWarningOverlay extends Overlay
Instant now = Instant.now();
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();
@@ -145,18 +145,22 @@ public class AoeWarningOverlay extends Overlay
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();
if (point.distanceTo(playerLocation) >= 32) {
if (point.distanceTo(playerLocation) >= 32)
{
return;
}
LocalPoint lp = LocalPoint.fromWorld(client, point);
if (lp == null) {
if (lp == null)
{
return;
}
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
if (poly == null) {
if (poly == null)
{
return;
}
//OverlayUtil.renderPolygon(graphics, poly, color);

View File

@@ -301,8 +301,8 @@ public class AoeWarningPlugin extends Plugin
return config.isXarpusEnabled();
case ADDY_DRAG_POISON:
return config.addyDrags();
case DRAKE_BREATH:
return config.isDrakeEnabled();
case DRAKE_BREATH:
return config.isDrakeEnabled();
case CERB_FIRE:
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.
private static final NumberFormat TIME_LEFT_FORMATTER =
DecimalFormat.getInstance(Locale.US);
DecimalFormat.getInstance(Locale.US);
static
{
@@ -157,22 +157,22 @@ public class BombOverlay extends Overlay
Instant now = Instant.now();
double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() -
bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
//divided by 1000.00 because of milliseconds :)
bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
//divided by 1000.00 because of milliseconds :)
timeLeft = Math.max(0.0, timeLeft);
String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft);
int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString);
int textHeight = graphics.getFontMetrics().getAscent();
Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(),
localLoc.getY(), bomb.getWorldLocation().getPlane());
localLoc.getY(), bomb.getWorldLocation().getPlane());
if (canvasPoint != null)
{
Point canvasCenterPoint = new Point(
canvasPoint.getX() - textWidth / 2,
canvasPoint.getY() + textHeight / 2);
canvasPoint.getX() - textWidth / 2,
canvasPoint.getY() + textHeight / 2);
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,243 +1,244 @@
/*
* Copyright (c) 2018, Seth <Sethtroll3@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.plugins.barrows;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.List;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.NPC;
import net.runelite.api.NPCComposition;
import net.runelite.api.ObjectComposition;
import net.runelite.api.Perspective;
import net.runelite.api.Player;
import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.widgets.Widget;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
class BarrowsOverlay extends Overlay
{
private static final int MAX_DISTANCE = 2350;
private final Client client;
private final BarrowsPlugin plugin;
private final BarrowsConfig config;
@Inject
private BarrowsOverlay(Client client, BarrowsPlugin plugin, BarrowsConfig config)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.client = client;
this.plugin = plugin;
this.config = config;
}
@Override
public Dimension render(Graphics2D graphics)
{
Player local = client.getLocalPlayer();
final Color npcColor = getMinimapDotColor(1);
final Color playerColor = getMinimapDotColor(2);
Widget puzzleAnswer = plugin.getPuzzleAnswer();
// tunnels are only on z=0
if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && config.showMinimap())
{
// NPC dots
graphics.setColor(npcColor);
final List<NPC> npcs = client.getNpcs();
for (NPC npc : npcs)
{
final NPCComposition composition = npc.getComposition();
if (composition != null && !composition.isMinimapVisible())
{
continue;
}
net.runelite.api.Point minimapLocation = npc.getMinimapLocation();
if (minimapLocation != null)
{
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
}
}
// Player dots
graphics.setColor(playerColor);
final List<Player> players = client.getPlayers();
for (Player player : players)
{
if (player == local)
{
// Skip local player as we draw square for it later
continue;
}
net.runelite.api.Point minimapLocation = player.getMinimapLocation();
if (minimapLocation != null)
{
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
}
}
// Render barrows walls/doors
renderObjects(graphics, local);
// Local player square
graphics.setColor(playerColor);
graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3);
}
else if (config.showBrotherLoc())
{
renderBarrowsBrothers(graphics);
}
if (puzzleAnswer != null && config.showPuzzleAnswer() && !puzzleAnswer.isHidden())
{
Rectangle answerRect = puzzleAnswer.getBounds();
graphics.setColor(Color.GREEN);
graphics.draw(answerRect);
}
return null;
}
private void renderObjects(Graphics2D graphics, Player localPlayer)
{
LocalPoint localLocation = localPlayer.getLocalLocation();
for (WallObject wall : plugin.getWalls())
{
LocalPoint location = wall.getLocalLocation();
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
{
renderWalls(graphics, wall);
}
}
for (GameObject ladder : plugin.getLadders())
{
LocalPoint location = ladder.getLocalLocation();
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
{
renderLadders(graphics, ladder);
}
}
}
private void renderWalls(Graphics2D graphics, WallObject wall)
{
net.runelite.api.Point minimapLocation = wall.getMinimapLocation();
if (minimapLocation == null)
{
return;
}
ObjectComposition objectComp = client.getObjectDefinition(wall.getId());
ObjectComposition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null;
if (impostor != null && impostor.getActions()[0] != null)
{
graphics.setColor(Color.green);
}
else
{
graphics.setColor(Color.gray);
}
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3);
}
/**
* Get minimap dot color from client
* @param typeIndex index of minimap dot type (1 npcs, 2 players)
* @return color
*/
private Color getMinimapDotColor(int typeIndex)
{
final int pixel = client.getMapDots()[typeIndex].getPixels()[1];
return new Color(pixel);
}
private void renderLadders(Graphics2D graphics, GameObject ladder)
{
net.runelite.api.Point minimapLocation = ladder.getMinimapLocation();
if (minimapLocation == null)
{
return;
}
ObjectComposition objectComp = client.getObjectDefinition(ladder.getId());
if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null)
{
graphics.setColor(Color.orange);
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6);
}
}
private void renderBarrowsBrothers(Graphics2D graphics)
{
for (BarrowsBrothers brother : BarrowsBrothers.values())
{
LocalPoint localLocation = LocalPoint.fromWorld(client, brother.getLocation());
if (localLocation == null)
{
continue;
}
String brotherLetter = Character.toString(brother.getName().charAt(0));
net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics,
localLocation, brotherLetter);
if (minimapText != null)
{
graphics.setColor(Color.black);
graphics.drawString(brotherLetter, minimapText.getX() + 1, minimapText.getY() + 1);
if (client.getVar(brother.getKilledVarbit()) > 0)
{
graphics.setColor(config.deadBrotherLocColor());
}
else
{
graphics.setColor(config.brotherLocColor());
}
graphics.drawString(brotherLetter, minimapText.getX(), minimapText.getY());
}
}
}
/*
* Copyright (c) 2018, Seth <Sethtroll3@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.plugins.barrows;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.List;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.NPC;
import net.runelite.api.NPCComposition;
import net.runelite.api.ObjectComposition;
import net.runelite.api.Perspective;
import net.runelite.api.Player;
import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.widgets.Widget;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
class BarrowsOverlay extends Overlay
{
private static final int MAX_DISTANCE = 2350;
private final Client client;
private final BarrowsPlugin plugin;
private final BarrowsConfig config;
@Inject
private BarrowsOverlay(Client client, BarrowsPlugin plugin, BarrowsConfig config)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.client = client;
this.plugin = plugin;
this.config = config;
}
@Override
public Dimension render(Graphics2D graphics)
{
Player local = client.getLocalPlayer();
final Color npcColor = getMinimapDotColor(1);
final Color playerColor = getMinimapDotColor(2);
Widget puzzleAnswer = plugin.getPuzzleAnswer();
// tunnels are only on z=0
if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && config.showMinimap())
{
// NPC dots
graphics.setColor(npcColor);
final List<NPC> npcs = client.getNpcs();
for (NPC npc : npcs)
{
final NPCComposition composition = npc.getComposition();
if (composition != null && !composition.isMinimapVisible())
{
continue;
}
net.runelite.api.Point minimapLocation = npc.getMinimapLocation();
if (minimapLocation != null)
{
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
}
}
// Player dots
graphics.setColor(playerColor);
final List<Player> players = client.getPlayers();
for (Player player : players)
{
if (player == local)
{
// Skip local player as we draw square for it later
continue;
}
net.runelite.api.Point minimapLocation = player.getMinimapLocation();
if (minimapLocation != null)
{
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
}
}
// Render barrows walls/doors
renderObjects(graphics, local);
// Local player square
graphics.setColor(playerColor);
graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3);
}
else if (config.showBrotherLoc())
{
renderBarrowsBrothers(graphics);
}
if (puzzleAnswer != null && config.showPuzzleAnswer() && !puzzleAnswer.isHidden())
{
Rectangle answerRect = puzzleAnswer.getBounds();
graphics.setColor(Color.GREEN);
graphics.draw(answerRect);
}
return null;
}
private void renderObjects(Graphics2D graphics, Player localPlayer)
{
LocalPoint localLocation = localPlayer.getLocalLocation();
for (WallObject wall : plugin.getWalls())
{
LocalPoint location = wall.getLocalLocation();
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
{
renderWalls(graphics, wall);
}
}
for (GameObject ladder : plugin.getLadders())
{
LocalPoint location = ladder.getLocalLocation();
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
{
renderLadders(graphics, ladder);
}
}
}
private void renderWalls(Graphics2D graphics, WallObject wall)
{
net.runelite.api.Point minimapLocation = wall.getMinimapLocation();
if (minimapLocation == null)
{
return;
}
ObjectComposition objectComp = client.getObjectDefinition(wall.getId());
ObjectComposition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null;
if (impostor != null && impostor.getActions()[0] != null)
{
graphics.setColor(Color.green);
}
else
{
graphics.setColor(Color.gray);
}
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3);
}
/**
* Get minimap dot color from client
*
* @param typeIndex index of minimap dot type (1 npcs, 2 players)
* @return color
*/
private Color getMinimapDotColor(int typeIndex)
{
final int pixel = client.getMapDots()[typeIndex].getPixels()[1];
return new Color(pixel);
}
private void renderLadders(Graphics2D graphics, GameObject ladder)
{
net.runelite.api.Point minimapLocation = ladder.getMinimapLocation();
if (minimapLocation == null)
{
return;
}
ObjectComposition objectComp = client.getObjectDefinition(ladder.getId());
if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null)
{
graphics.setColor(Color.orange);
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6);
}
}
private void renderBarrowsBrothers(Graphics2D graphics)
{
for (BarrowsBrothers brother : BarrowsBrothers.values())
{
LocalPoint localLocation = LocalPoint.fromWorld(client, brother.getLocation());
if (localLocation == null)
{
continue;
}
String brotherLetter = Character.toString(brother.getName().charAt(0));
net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics,
localLocation, brotherLetter);
if (minimapText != null)
{
graphics.setColor(Color.black);
graphics.drawString(brotherLetter, minimapText.getX() + 1, minimapText.getY() + 1);
if (client.getVar(brother.getKilledVarbit()) > 0)
{
graphics.setColor(config.deadBrotherLocColor());
}
else
{
graphics.setColor(config.brotherLocColor());
}
graphics.drawString(brotherLetter, minimapText.getX(), minimapText.getY());
}
}
}
}

View File

@@ -81,13 +81,13 @@ public class BarrowsPlugin extends Plugin
{
@Getter(AccessLevel.PACKAGE)
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,
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_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
);
(
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_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_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 ImmutableList<WidgetInfo> POSSIBLE_SOLUTIONS = ImmutableList.of(

View File

@@ -31,8 +31,6 @@ import java.time.Duration;
import java.time.Instant;
import javax.inject.Inject;
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.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;

View File

@@ -63,7 +63,6 @@ import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager;
@@ -371,10 +370,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
@Subscribe
public void onNpcDespawned(NpcDespawned event)
{
if (healers.remove(event.getNpc()) != null && healers.isEmpty())
{
healers.clear();
}
healers.remove(event.getNpc());
}
@Subscribe
@@ -450,7 +446,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
{
remove(new String[]{"take", "light"}, target, true);
}
else//remove "Light" option (and "Take" option if not defender).
else //remove "Light" option (and "Take" option if not defender).
{
remove("light", target, true);
}
@@ -466,7 +462,8 @@ public class BAToolsPlugin extends Plugin implements KeyListener
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)"
if (poison.contains(item))
{//if item is a poison item
{
//if item is a poison item
int calledPoison = 0;
switch (healer.getText())//choose which poison to hide the use/destroy option for
{
@@ -509,11 +506,13 @@ public class BAToolsPlugin extends Plugin implements KeyListener
}
}
else if (option.equals("attack") && client.getWidget(WidgetInfo.BA_ATK_ROLE_TEXT) == null && !target.equals("queen spawn"))//if not attacker
{//remove attack option from everything but queen spawns
{
//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".
{
//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
@@ -632,7 +631,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
if (correctEgg != null)
{
entries.add(correctEgg);
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
client.setMenuEntries(entries.toArray(new MenuEntry[0]));
}
}

View File

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

View File

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

View File

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

View File

@@ -30,16 +30,16 @@ import lombok.Getter;
enum HealerCode
{
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}),
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}),
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}),
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}),
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});
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}),
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}),
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}),
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}),
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});
@Getter

View File

@@ -46,88 +46,107 @@ import net.runelite.client.plugins.PluginType;
* Authors gazivodag longstreet
*/
@PluginDescriptor(
name = "Blackjack",
description = "Uses chat messages and tick timers instead of animations to read",
tags = {"blackjack", "thieving"},
type = PluginType.UTILITY
name = "Blackjack",
description = "Uses chat messages and tick timers instead of animations to read",
tags = {"blackjack", "thieving"},
type = PluginType.UTILITY
)
@Singleton
@Slf4j
public class BlackjackPlugin extends Plugin {
public class BlackjackPlugin extends Plugin
{
@Inject
Client client;
@Inject
Client client;
private static long timeSinceKnockout;
private static long timeSinceAggro;
private long timeSinceKnockout;
private long timeSinceAggro;
@Getter
private static long currentGameTick;
@Getter
private long currentGameTick;
@Override
public void configure(Binder binder) {
}
@Override
public void configure(Binder binder)
{
}
@Override
protected void startUp() throws Exception {
currentGameTick = 0;
}
@Override
protected void startUp() throws Exception
{
currentGameTick = 0;
}
@Override
protected void shutDown() throws Exception {
currentGameTick = 0;
}
@Override
protected void shutDown() throws Exception
{
currentGameTick = 0;
}
@Subscribe
public void onGameTick(GameTick gameTick) {
currentGameTick++;
}
@Subscribe
public void onGameTick(GameTick gameTick)
{
currentGameTick++;
}
@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.")) {
timeSinceKnockout = getCurrentGameTick();
}
if (chatMessage.getMessage().equals("Your blow only glances off the bandit's head.")) {
timeSinceAggro = getCurrentGameTick();
}
}
}
@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."))
{
timeSinceKnockout = getCurrentGameTick();
}
if (chatMessage.getMessage().equals("Your blow only glances off the bandit's head."))
{
timeSinceAggro = getCurrentGameTick();
}
}
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) {
String target = menuEntryAdded.getTarget().toLowerCase();
if ((target.contains("bandit") | target.contains("menaphite thug"))) {
Quest quest = Quest.THE_FEUD;
if (quest.getState(client) == QuestState.FINISHED) {
if (currentGameTick < (timeSinceKnockout + 4)) {
stripSpecificEntries("pickpocket");
}
if (currentGameTick < (timeSinceAggro + 4)) {
stripSpecificEntries("pickpocket");
}
stripSpecificEntries("knock-out");
}
}
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
{
String target = menuEntryAdded.getTarget().toLowerCase();
if ((target.contains("bandit") || target.contains("menaphite thug")))
{
Quest quest = Quest.THE_FEUD;
if (quest.getState(client) == QuestState.FINISHED)
{
if (currentGameTick < (timeSinceKnockout + 4))
{
stripSpecificEntries("pickpocket");
}
if (currentGameTick < (timeSinceAggro + 4))
{
stripSpecificEntries("pickpocket");
}
stripSpecificEntries("knock-out");
}
}
}
private void stripSpecificEntries(String exceptFor) {
MenuEntry[] currentEntires = client.getMenuEntries();
MenuEntry[] newEntries = new MenuEntry[2];
private void stripSpecificEntries(String exceptFor)
{
MenuEntry[] currentEntires = client.getMenuEntries();
MenuEntry[] newEntries = new MenuEntry[2];
for (MenuEntry currentEntry : currentEntires) {
if (currentEntry.getOption().toLowerCase().equals(exceptFor.toLowerCase())) {
newEntries[1] = currentEntry;
}
if (currentEntry.getOption().toLowerCase().equals("lure")) {
newEntries[0] = currentEntry;
}
}
for (MenuEntry currentEntry : currentEntires)
{
if (currentEntry.getOption().toLowerCase().equals(exceptFor.toLowerCase()))
{
newEntries[1] = currentEntry;
}
if (currentEntry.getOption().toLowerCase().equals("lure"))
{
newEntries[0] = currentEntry;
}
}
if (newEntries[0] != null && newEntries[1] != null) {
client.setMenuEntries(newEntries);
}
}
if (newEntries[0] != null && newEntries[1] != null)
{
client.setMenuEntries(newEntries);
}
}
}

View File

@@ -36,7 +36,6 @@ import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.game.ItemManager;
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 net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPosition;

View File

@@ -1,101 +1,100 @@
/*
* Copyright (c) 2018, Unmoon <https://github.com/Unmoon>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.blastmine;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import java.awt.Color;
@ConfigGroup("blastmine")
public interface BlastMinePluginConfig extends Config
{
@ConfigItem(
position = 0,
keyName = "showOreOverlay",
name = "Show ore overlay",
description = "Configures whether or not the ore count overlay is displayed"
)
default boolean showOreOverlay()
{
return true;
}
@ConfigItem(
position = 1,
keyName = "showRockIconOverlay",
name = "Show icons overlay",
description = "Configures whether or not the icon overlay is displayed"
)
default boolean showRockIconOverlay()
{
return true;
}
@ConfigItem(
position = 2,
keyName = "showTimerOverlay",
name = "Show timer overlay",
description = "Configures whether or not the timer overlay is displayed"
)
default boolean showTimerOverlay()
{
return true;
}
@ConfigItem(
position = 3,
keyName = "showWarningOverlay",
name = "Show explosion warning",
description = "Configures whether or not the explosion warning overlay is displayed"
)
default boolean showWarningOverlay()
{
return true;
}
@ConfigItem(
position = 4,
keyName = "hexTimerColor",
name = "Timer color",
description = "Color of timer overlay"
)
default Color getTimerColor()
{
return new Color(217, 54, 0);
}
@ConfigItem(
position = 5,
keyName = "hexWarningColor",
name = "Warning color",
description = "Color of warning overlay"
)
default Color getWarningColor()
{
return new Color(217, 54, 0);
}
}
/*
* Copyright (c) 2018, Unmoon <https://github.com/Unmoon>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.blastmine;
import java.awt.Color;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("blastmine")
public interface BlastMinePluginConfig extends Config
{
@ConfigItem(
position = 0,
keyName = "showOreOverlay",
name = "Show ore overlay",
description = "Configures whether or not the ore count overlay is displayed"
)
default boolean showOreOverlay()
{
return true;
}
@ConfigItem(
position = 1,
keyName = "showRockIconOverlay",
name = "Show icons overlay",
description = "Configures whether or not the icon overlay is displayed"
)
default boolean showRockIconOverlay()
{
return true;
}
@ConfigItem(
position = 2,
keyName = "showTimerOverlay",
name = "Show timer overlay",
description = "Configures whether or not the timer overlay is displayed"
)
default boolean showTimerOverlay()
{
return true;
}
@ConfigItem(
position = 3,
keyName = "showWarningOverlay",
name = "Show explosion warning",
description = "Configures whether or not the explosion warning overlay is displayed"
)
default boolean showWarningOverlay()
{
return true;
}
@ConfigItem(
position = 4,
keyName = "hexTimerColor",
name = "Timer color",
description = "Color of timer overlay"
)
default Color getTimerColor()
{
return new Color(217, 54, 0);
}
@ConfigItem(
position = 5,
keyName = "hexWarningColor",
name = "Warning color",
description = "Color of warning overlay"
)
default Color getWarningColor()
{
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
* to the boost timing. If again the preserve prayer is active for that
* 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
* to gain full effect (seconds 45-75).
*
@@ -365,8 +365,8 @@ public class BoostsPlugin extends Plugin
int getChangeDownTicks()
{
if (lastChangeDown == -1 ||
config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
(config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedUp))
config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
(config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedUp))
{
return -1;
}
@@ -393,8 +393,8 @@ public class BoostsPlugin extends Plugin
int getChangeUpTicks()
{
if (lastChangeUp == -1 ||
config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
(config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedDown))
config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
(config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedDown))
{
return -1;
}
@@ -406,12 +406,13 @@ public class BoostsPlugin extends Plugin
/**
* Converts tick-based time to accurate second time
*
* @param time tick-based time
* @return second-based time
*/
int getChangeTime(final int time)
{
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();
}
private Boss(int id, long period, ChronoUnit unit, int itemSpriteId)
Boss(int id, long period, ChronoUnit unit, int itemSpriteId)
{
this.id = id;
this.spawnTime = Duration.of(period, unit);

View File

@@ -1,141 +1,142 @@
/*
* Copyright (c) 2016-2018, Seth <Sethtroll3@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.plugins.cannon;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import static net.runelite.api.Perspective.LOCAL_TILE_SIZE;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.TextComponent;
class CannonOverlay extends Overlay
{
private static final int MAX_DISTANCE = 2500;
private final Client client;
private final CannonConfig config;
private final CannonPlugin plugin;
private final TextComponent textComponent = new TextComponent();
@Inject
CannonOverlay(Client client, CannonConfig config, CannonPlugin plugin)
{
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.MED);
this.client = client;
this.config = config;
this.plugin = plugin;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null)
{
return null;
}
LocalPoint cannonPoint = LocalPoint.fromWorld(client, plugin.getCannonPosition());
if (cannonPoint == null)
{
return null;
}
LocalPoint localLocation = client.getLocalPlayer().getLocalLocation();
if (localLocation.distanceTo(cannonPoint) <= MAX_DISTANCE)
{
Point cannonLoc = Perspective.getCanvasTextLocation(client,
graphics,
cannonPoint,
String.valueOf(plugin.getCballsLeft()), 150);
if (cannonLoc != null)
{
textComponent.setText(String.valueOf(plugin.getCballsLeft()));
textComponent.setPosition(new java.awt.Point(cannonLoc.getX(), cannonLoc.getY()));
textComponent.setColor(plugin.getStateColor());
textComponent.render(graphics);
}
if (config.showDoubleHitSpot())
{
Color color = config.highlightDoubleHitColor();
drawDoubleHitSpots(graphics, cannonPoint, color);
}
}
return null;
}
/**
* Draw the double hit spots on a 6 by 6 grid around the cannon
* @param startTile The position of the cannon
*/
private void drawDoubleHitSpots(Graphics2D graphics, LocalPoint startTile, Color color)
{
for (int x = -3; x <= 3; x++)
{
for (int y = -3; y <= 3; y++)
{
if (y != 1 && x != 1 && y != -1 && x != -1)
{
continue;
}
//Ignore center square
if (y >= -1 && y <= 1 && x >= -1 && x <= 1)
{
continue;
}
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);
if (poly == null)
{
continue;
}
OverlayUtil.renderPolygon(graphics, poly, color);
}
}
}
/*
* Copyright (c) 2016-2018, Seth <Sethtroll3@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.plugins.cannon;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import static net.runelite.api.Perspective.LOCAL_TILE_SIZE;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.TextComponent;
class CannonOverlay extends Overlay
{
private static final int MAX_DISTANCE = 2500;
private final Client client;
private final CannonConfig config;
private final CannonPlugin plugin;
private final TextComponent textComponent = new TextComponent();
@Inject
CannonOverlay(Client client, CannonConfig config, CannonPlugin plugin)
{
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.MED);
this.client = client;
this.config = config;
this.plugin = plugin;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null)
{
return null;
}
LocalPoint cannonPoint = LocalPoint.fromWorld(client, plugin.getCannonPosition());
if (cannonPoint == null)
{
return null;
}
LocalPoint localLocation = client.getLocalPlayer().getLocalLocation();
if (localLocation.distanceTo(cannonPoint) <= MAX_DISTANCE)
{
Point cannonLoc = Perspective.getCanvasTextLocation(client,
graphics,
cannonPoint,
String.valueOf(plugin.getCballsLeft()), 150);
if (cannonLoc != null)
{
textComponent.setText(String.valueOf(plugin.getCballsLeft()));
textComponent.setPosition(new java.awt.Point(cannonLoc.getX(), cannonLoc.getY()));
textComponent.setColor(plugin.getStateColor());
textComponent.render(graphics);
}
if (config.showDoubleHitSpot())
{
Color color = config.highlightDoubleHitColor();
drawDoubleHitSpots(graphics, cannonPoint, color);
}
}
return null;
}
/**
* Draw the double hit spots on a 6 by 6 grid around the cannon
*
* @param startTile The position of the cannon
*/
private void drawDoubleHitSpots(Graphics2D graphics, LocalPoint startTile, Color color)
{
for (int x = -3; x <= 3; x++)
{
for (int y = -3; y <= 3; y++)
{
if (y != 1 && x != 1 && y != -1 && x != -1)
{
continue;
}
//Ignore center square
if (y >= -1 && y <= 1 && x >= -1 && x <= 1)
{
continue;
}
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);
if (poly == null)
{
continue;
}
OverlayUtil.renderPolygon(graphics, poly, color);
}
}
}
}

View File

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

View File

@@ -63,13 +63,13 @@ public class CerberusOverlay extends Overlay
// Ghosts are already sorted
plugin.getGhosts().stream()
// Iterate only through the correct amount of ghosts
.limit(CerberusGhost.values().length)
.forEach(npc -> CerberusGhost
.fromNPC(npc)
.ifPresent(ghost -> panelComponent
.getChildren()
.add(new ImageComponent(iconManager.getSkillImage(ghost.getType())))));
// Iterate only through the correct amount of ghosts
.limit(CerberusGhost.values().length)
.forEach(npc -> CerberusGhost
.fromNPC(npc)
.ifPresent(ghost -> panelComponent
.getChildren()
.add(new ImageComponent(iconManager.getSkillImage(ghost.getType())))));
return panelComponent.render(graphics);

View File

@@ -1,158 +1,158 @@
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.chatboxperformance;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.widgets.WidgetType;
import net.runelite.api.events.WidgetPositioned;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
@PluginDescriptor(
name = "Chatbox performance",
hidden = true
)
public class ChatboxPerformancePlugin extends Plugin
{
@Inject
private Client client;
@Subscribe
public void onWidgetPositioned(WidgetPositioned event)
{
if (!areWidgetsFixed())
{
fixChatbox();
}
}
private boolean areWidgetsFixed()
{
Widget widget = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND);
if (widget == null)
{
return true;
}
Widget[] widgets = widget.getChildren();
if (widgets != null && widgets.length > 0)
{
Widget last = widgets[widgets.length - 1];
return last != null && last.getOpacity() < 254;
}
return false;
}
private void fixChatbox()
{
fixDarkBackground();
fixWhiteLines(true);
fixWhiteLines(false);
}
private void fixDarkBackground()
{
int currOpacity = 256;
int prevY = 0;
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND).getDynamicChildren();
Widget prev = null;
for (Widget w : children)
{
if (w.getType() != WidgetType.RECTANGLE)
{
continue;
}
if (prev != null)
{
int relY = w.getRelativeY();
prev.setHeightMode(WidgetSizeMode.ABSOLUTE);
prev.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
prev.setRelativeY(prevY);
prev.setOriginalY(prev.getRelativeY());
prev.setHeight(relY - prevY);
prev.setOriginalHeight(prev.getHeight());
prev.setOpacity(currOpacity);
}
prevY = w.getRelativeY();
currOpacity -= 3; // Rough number, can't get exactly the same as Jagex because of rounding
prev = w;
}
if (prev != null)
{
prev.setOpacity(currOpacity);
}
}
private void fixWhiteLines(boolean upperLine)
{
int currOpacity = 256;
int prevWidth = 0;
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_LINES).getDynamicChildren();
Widget prev = null;
for (Widget w : children)
{
if (w.getType() != WidgetType.RECTANGLE)
{
continue;
}
if ((w.getRelativeY() == 0 && !upperLine) ||
(w.getRelativeY() != 0 && upperLine))
{
continue;
}
if (prev != null)
{
int width = w.getWidth();
prev.setWidthMode(WidgetSizeMode.ABSOLUTE);
prev.setRelativeX(width);
prev.setOriginalX(width);
prev.setWidth(prevWidth - width);
prev.setOriginalWidth(prev.getWidth());
prev.setOpacity(currOpacity);
}
prevWidth = w.getWidth();
currOpacity -= upperLine ? 3 : 4; // Rough numbers, can't get exactly the same as Jagex because of rounding
prev = w;
}
if (prev != null)
{
prev.setOpacity(currOpacity);
}
}
}
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.chatboxperformance;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.events.WidgetPositioned;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
@PluginDescriptor(
name = "Chatbox performance",
hidden = true
)
public class ChatboxPerformancePlugin extends Plugin
{
@Inject
private Client client;
@Subscribe
public void onWidgetPositioned(WidgetPositioned event)
{
if (!areWidgetsFixed())
{
fixChatbox();
}
}
private boolean areWidgetsFixed()
{
Widget widget = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND);
if (widget == null)
{
return true;
}
Widget[] widgets = widget.getChildren();
if (widgets != null && widgets.length > 0)
{
Widget last = widgets[widgets.length - 1];
return last != null && last.getOpacity() < 254;
}
return false;
}
private void fixChatbox()
{
fixDarkBackground();
fixWhiteLines(true);
fixWhiteLines(false);
}
private void fixDarkBackground()
{
int currOpacity = 256;
int prevY = 0;
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND).getDynamicChildren();
Widget prev = null;
for (Widget w : children)
{
if (w.getType() != WidgetType.RECTANGLE)
{
continue;
}
if (prev != null)
{
int relY = w.getRelativeY();
prev.setHeightMode(WidgetSizeMode.ABSOLUTE);
prev.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
prev.setRelativeY(prevY);
prev.setOriginalY(prev.getRelativeY());
prev.setHeight(relY - prevY);
prev.setOriginalHeight(prev.getHeight());
prev.setOpacity(currOpacity);
}
prevY = w.getRelativeY();
currOpacity -= 3; // Rough number, can't get exactly the same as Jagex because of rounding
prev = w;
}
if (prev != null)
{
prev.setOpacity(currOpacity);
}
}
private void fixWhiteLines(boolean upperLine)
{
int currOpacity = 256;
int prevWidth = 0;
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_LINES).getDynamicChildren();
Widget prev = null;
for (Widget w : children)
{
if (w.getType() != WidgetType.RECTANGLE)
{
continue;
}
if ((w.getRelativeY() == 0 && !upperLine) ||
(w.getRelativeY() != 0 && upperLine))
{
continue;
}
if (prev != null)
{
int width = w.getWidth();
prev.setWidthMode(WidgetSizeMode.ABSOLUTE);
prev.setRelativeX(width);
prev.setOriginalX(width);
prev.setWidth(prevWidth - width);
prev.setOriginalWidth(prev.getWidth());
prev.setOpacity(currOpacity);
}
prevWidth = w.getWidth();
currOpacity -= upperLine ? 3 : 4; // Rough numbers, can't get exactly the same as Jagex because of rounding
prev = w;
}
if (prev != null)
{
prev.setOpacity(currOpacity);
}
}
}

View File

@@ -653,7 +653,7 @@ public class ChatCommandsPlugin extends Plugin
* response.
*
* @param chatMessage The chat message containing the command.
* @param message The chat message
* @param message The chat message
*/
private void itemPriceLookup(ChatMessage chatMessage, String message)
{
@@ -689,17 +689,17 @@ public class ChatCommandsPlugin extends Plugin
int itemPrice = item.getPrice();
final ChatMessageBuilder builder = new ChatMessageBuilder();
builder.append(ChatColorType.NORMAL);
builder.append(ChatColorType.HIGHLIGHT);
builder.append(item.getName());
builder.append(ChatColorType.NORMAL);
builder.append(": GE ");
builder.append(ChatColorType.HIGHLIGHT);
builder.append(StackFormatter.formatNumber(itemPrice));
builder.append(ChatColorType.NORMAL);
builder.append(": OSB ");
builder.append(ChatColorType.HIGHLIGHT);
builder.append(StackFormatter.formatNumber(osbresult.getOverall_average()));
builder.append(ChatColorType.NORMAL);
builder.append(ChatColorType.HIGHLIGHT);
builder.append(item.getName());
builder.append(ChatColorType.NORMAL);
builder.append(": GE ");
builder.append(ChatColorType.HIGHLIGHT);
builder.append(StackFormatter.formatNumber(itemPrice));
builder.append(ChatColorType.NORMAL);
builder.append(": OSB ");
builder.append(ChatColorType.HIGHLIGHT);
builder.append(StackFormatter.formatNumber(osbresult.getOverall_average()));
ItemComposition itemComposition = itemManager.getItemComposition(itemId);
if (itemComposition != null)
@@ -726,7 +726,7 @@ public class ChatCommandsPlugin extends Plugin
* response.
*
* @param chatMessage The chat message containing the command.
* @param message The chat message
* @param message The chat message
*/
private void playerSkillLookup(ChatMessage chatMessage, String message)
{

View File

@@ -1,262 +1,263 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@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.plugins.chathistory;
import com.google.common.collect.EvictingQueue;
import com.google.inject.Provides;
import java.awt.event.KeyEvent;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import java.util.Queue;
import javax.inject.Inject;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.ScriptID;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.vars.InputType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.Text;
@PluginDescriptor(
name = "Chat History",
description = "Retain your chat history when logging in/out or world hopping",
tags = {"chat", "history", "retain", "cycle", "pm"}
)
public class ChatHistoryPlugin extends Plugin implements KeyListener
{
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape.";
private static final String CLEAR_HISTORY = "Clear history";
private static final String CLEAR_PRIVATE = "<col=ffff00>Private:";
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
private static final int FRIENDS_MAX_SIZE = 5;
private Queue<QueuedMessage> messageQueue;
private Deque<String> friends;
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private ChatHistoryConfig config;
@Inject
private KeyManager keyManager;
@Inject
private ChatMessageManager chatMessageManager;
@Provides
ChatHistoryConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(ChatHistoryConfig.class);
}
@Override
protected void startUp()
{
messageQueue = EvictingQueue.create(100);
friends = new ArrayDeque<>(FRIENDS_MAX_SIZE + 1);
keyManager.registerKeyListener(this);
}
@Override
protected void shutDown()
{
messageQueue.clear();
messageQueue = null;
friends.clear();
friends = null;
keyManager.unregisterKeyListener(this);
}
@Subscribe
public void onChatMessage(ChatMessage chatMessage)
{
// Start sending old messages right after the welcome message, as that is most reliable source
// of information that chat history was reset
if (chatMessage.getMessage().equals(WELCOME_MESSAGE))
{
if (!config.retainChatHistory())
{
return;
}
QueuedMessage queuedMessage;
while ((queuedMessage = messageQueue.poll()) != null)
{
chatMessageManager.queue(queuedMessage);
}
return;
}
switch (chatMessage.getType())
{
case PRIVATECHATOUT:
case PRIVATECHAT:
case MODPRIVATECHAT:
final String name = Text.removeTags(chatMessage.getName());
// Remove to ensure uniqueness & its place in history
if (!friends.remove(name))
{
// If the friend didn't previously exist ensure deque capacity doesn't increase by adding them
if (friends.size() >= FRIENDS_MAX_SIZE)
{
friends.remove();
}
}
friends.add(name);
// intentional fall-through
case PUBLICCHAT:
case MODCHAT:
case FRIENDSCHAT:
case CONSOLE:
final QueuedMessage queuedMessage = QueuedMessage.builder()
.type(chatMessage.getType())
.name(chatMessage.getName())
.sender(chatMessage.getSender())
.value(nbsp(chatMessage.getMessage()))
.runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage()))
.timestamp(chatMessage.getTimestamp())
.build();
if (!messageQueue.contains(queuedMessage))
{
messageQueue.offer(queuedMessage);
}
}
}
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
String menuOption = event.getMenuOption();
if (menuOption.contains(CLEAR_HISTORY))
{
if (menuOption.startsWith(CLEAR_PRIVATE))
{
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PRIVATECHAT ||
e.getType() == ChatMessageType.PRIVATECHATOUT || e.getType() == ChatMessageType.MODPRIVATECHAT);
friends.clear();
}
else
{
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PUBLICCHAT || e.getType() == ChatMessageType.MODCHAT);
}
}
}
/**
* Small hack to prevent plugins checking for specific messages to match
* @param message message
* @return message with nbsp
*/
private static String nbsp(final String message)
{
if (message != null)
{
return message.replace(' ', '\u00A0');
}
return null;
}
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() != CYCLE_HOTKEY || !config.pmTargetCycling())
{
return;
}
if (client.getVar(VarClientInt.INPUT_TYPE) != InputType.PRIVATE_MESSAGE.getType())
{
return;
}
clientThread.invoke(() ->
{
final String target = findPreviousFriend();
if (target == null)
{
return;
}
final String currentMessage = client.getVar(VarClientStr.INPUT_TEXT);
client.runScript(ScriptID.OPEN_PRIVATE_MESSAGE_INTERFACE, target);
client.setVar(VarClientStr.INPUT_TEXT, currentMessage);
client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, "");
});
}
@Override
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyReleased(KeyEvent e)
{
}
private String findPreviousFriend()
{
final String currentTarget = client.getVar(VarClientStr.PRIVATE_MESSAGE_TARGET);
if (currentTarget == null || friends.isEmpty())
{
return null;
}
for (Iterator<String> it = friends.descendingIterator(); it.hasNext(); )
{
String friend = it.next();
if (friend.equals(currentTarget))
{
return it.hasNext() ? it.next() : friends.getLast();
}
}
return friends.getLast();
}
}
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@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.plugins.chathistory;
import com.google.common.collect.EvictingQueue;
import com.google.inject.Provides;
import java.awt.event.KeyEvent;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import java.util.Queue;
import javax.inject.Inject;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.ScriptID;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.vars.InputType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.Text;
@PluginDescriptor(
name = "Chat History",
description = "Retain your chat history when logging in/out or world hopping",
tags = {"chat", "history", "retain", "cycle", "pm"}
)
public class ChatHistoryPlugin extends Plugin implements KeyListener
{
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape.";
private static final String CLEAR_HISTORY = "Clear history";
private static final String CLEAR_PRIVATE = "<col=ffff00>Private:";
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
private static final int FRIENDS_MAX_SIZE = 5;
private Queue<QueuedMessage> messageQueue;
private Deque<String> friends;
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private ChatHistoryConfig config;
@Inject
private KeyManager keyManager;
@Inject
private ChatMessageManager chatMessageManager;
@Provides
ChatHistoryConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(ChatHistoryConfig.class);
}
@Override
protected void startUp()
{
messageQueue = EvictingQueue.create(100);
friends = new ArrayDeque<>(FRIENDS_MAX_SIZE + 1);
keyManager.registerKeyListener(this);
}
@Override
protected void shutDown()
{
messageQueue.clear();
messageQueue = null;
friends.clear();
friends = null;
keyManager.unregisterKeyListener(this);
}
@Subscribe
public void onChatMessage(ChatMessage chatMessage)
{
// Start sending old messages right after the welcome message, as that is most reliable source
// of information that chat history was reset
if (chatMessage.getMessage().equals(WELCOME_MESSAGE))
{
if (!config.retainChatHistory())
{
return;
}
QueuedMessage queuedMessage;
while ((queuedMessage = messageQueue.poll()) != null)
{
chatMessageManager.queue(queuedMessage);
}
return;
}
switch (chatMessage.getType())
{
case PRIVATECHATOUT:
case PRIVATECHAT:
case MODPRIVATECHAT:
final String name = Text.removeTags(chatMessage.getName());
// Remove to ensure uniqueness & its place in history
if (!friends.remove(name))
{
// If the friend didn't previously exist ensure deque capacity doesn't increase by adding them
if (friends.size() >= FRIENDS_MAX_SIZE)
{
friends.remove();
}
}
friends.add(name);
// intentional fall-through
case PUBLICCHAT:
case MODCHAT:
case FRIENDSCHAT:
case CONSOLE:
final QueuedMessage queuedMessage = QueuedMessage.builder()
.type(chatMessage.getType())
.name(chatMessage.getName())
.sender(chatMessage.getSender())
.value(nbsp(chatMessage.getMessage()))
.runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage()))
.timestamp(chatMessage.getTimestamp())
.build();
if (!messageQueue.contains(queuedMessage))
{
messageQueue.offer(queuedMessage);
}
}
}
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
String menuOption = event.getMenuOption();
if (menuOption.contains(CLEAR_HISTORY))
{
if (menuOption.startsWith(CLEAR_PRIVATE))
{
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PRIVATECHAT ||
e.getType() == ChatMessageType.PRIVATECHATOUT || e.getType() == ChatMessageType.MODPRIVATECHAT);
friends.clear();
}
else
{
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PUBLICCHAT || e.getType() == ChatMessageType.MODCHAT);
}
}
}
/**
* Small hack to prevent plugins checking for specific messages to match
*
* @param message message
* @return message with nbsp
*/
private static String nbsp(final String message)
{
if (message != null)
{
return message.replace(' ', '\u00A0');
}
return null;
}
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() != CYCLE_HOTKEY || !config.pmTargetCycling())
{
return;
}
if (client.getVar(VarClientInt.INPUT_TYPE) != InputType.PRIVATE_MESSAGE.getType())
{
return;
}
clientThread.invoke(() ->
{
final String target = findPreviousFriend();
if (target == null)
{
return;
}
final String currentMessage = client.getVar(VarClientStr.INPUT_TEXT);
client.runScript(ScriptID.OPEN_PRIVATE_MESSAGE_INTERFACE, target);
client.setVar(VarClientStr.INPUT_TEXT, currentMessage);
client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, "");
});
}
@Override
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyReleased(KeyEvent e)
{
}
private String findPreviousFriend()
{
final String currentTarget = client.getVar(VarClientStr.PRIVATE_MESSAGE_TARGET);
if (currentTarget == null || friends.isEmpty())
{
return null;
}
for (Iterator<String> it = friends.descendingIterator(); it.hasNext(); )
{
String friend = it.next();
if (friend.equals(currentTarget))
{
return it.hasNext() ? it.next() : friends.getLast();
}
}
return friends.getLast();
}
}

View File

@@ -1,231 +1,231 @@
/*
* Copyright (c) 2018, Hydrox6 <ikada@protonmail.ch>
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.chatnotifications;
import com.google.common.base.Strings;
import com.google.inject.Provides;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.util.regex.Pattern.quote;
import java.util.stream.Collectors;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.MessageNode;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.client.Notifier;
import net.runelite.client.RuneLiteProperties;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.Text;
@PluginDescriptor(
name = "Chat Notifications",
description = "Highlight and notify you of chat messages",
tags = {"duel", "messages", "notifications", "trade", "username"},
enabledByDefault = false
)
public class ChatNotificationsPlugin extends Plugin
{
@Inject
private Client client;
@Inject
private ChatNotificationsConfig config;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private Notifier notifier;
@Inject
private RuneLiteProperties runeLiteProperties;
//Custom Highlights
private Pattern usernameMatcher = null;
private String usernameReplacer = "";
private Pattern highlightMatcher = null;
@Provides
ChatNotificationsConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(ChatNotificationsConfig.class);
}
@Override
public void startUp()
{
updateHighlights();
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
switch (event.getGameState())
{
case LOGIN_SCREEN:
case HOPPING:
usernameMatcher = null;
break;
}
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("chatnotification"))
{
updateHighlights();
}
}
private void updateHighlights()
{
highlightMatcher = null;
if (!config.highlightWordsString().trim().equals(""))
{
List<String> items = Text.fromCSV(config.highlightWordsString());
String joined = items.stream()
.map(Pattern::quote)
.collect(Collectors.joining("|"));
highlightMatcher = Pattern.compile("\\b(" + joined + ")\\b", Pattern.CASE_INSENSITIVE);
}
}
@Subscribe
public void onChatMessage(ChatMessage chatMessage)
{
MessageNode messageNode = chatMessage.getMessageNode();
String nodeValue = Text.removeTags(messageNode.getValue());
boolean update = false;
switch (chatMessage.getType())
{
case TRADEREQ:
if (chatMessage.getMessage().contains("wishes to trade with you.") && config.notifyOnTrade())
{
notifier.notify(chatMessage.getMessage());
}
break;
case CHALREQ_TRADE:
if (chatMessage.getMessage().contains("wishes to duel with you.") && config.notifyOnDuel())
{
notifier.notify(chatMessage.getMessage());
}
break;
case CONSOLE:
// Don't notify for notification messages
if (chatMessage.getName().equals(runeLiteProperties.getTitle()))
{
return;
}
break;
}
if (usernameMatcher == null && client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null)
{
String username = client.getLocalPlayer().getName();
usernameMatcher = Pattern.compile("\\b(" + quote(username) + ")\\b", Pattern.CASE_INSENSITIVE);
usernameReplacer = "<col" + ChatColorType.HIGHLIGHT.name() + "><u>" + username + "</u><col" + ChatColorType.NORMAL.name() + ">";
}
if (config.highlightOwnName() && usernameMatcher != null)
{
Matcher matcher = usernameMatcher.matcher(messageNode.getValue());
if (matcher.find())
{
messageNode.setValue(matcher.replaceAll(usernameReplacer));
update = true;
if (config.notifyOnOwnName())
{
sendNotification(chatMessage);
}
}
}
if (highlightMatcher != null)
{
Matcher matcher = highlightMatcher.matcher(nodeValue);
boolean found = false;
StringBuffer stringBuffer = new StringBuffer();
while (matcher.find())
{
String value = matcher.group();
matcher.appendReplacement(stringBuffer, "<col" + ChatColorType.HIGHLIGHT + ">" + value + "<col" + ChatColorType.NORMAL + ">");
update = true;
found = true;
}
if (found)
{
matcher.appendTail(stringBuffer);
messageNode.setValue(stringBuffer.toString());
if (config.notifyOnHighlight())
{
sendNotification(chatMessage);
}
}
}
if (update)
{
messageNode.setRuneLiteFormatMessage(messageNode.getValue());
chatMessageManager.update(messageNode);
}
}
private void sendNotification(ChatMessage message)
{
String name = Text.removeTags(message.getName());
String sender = message.getSender();
StringBuilder stringBuilder = new StringBuilder();
if (!Strings.isNullOrEmpty(sender))
{
stringBuilder.append('[').append(sender).append("] ");
}
if (!Strings.isNullOrEmpty(name))
{
stringBuilder.append(name).append(": ");
}
stringBuilder.append(Text.removeTags(message.getMessage()));
String notification = stringBuilder.toString();
notifier.notify(notification);
}
}
/*
* Copyright (c) 2018, Hydrox6 <ikada@protonmail.ch>
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.chatnotifications;
import com.google.common.base.Strings;
import com.google.inject.Provides;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.util.regex.Pattern.quote;
import java.util.stream.Collectors;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.MessageNode;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.client.Notifier;
import net.runelite.client.RuneLiteProperties;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.Text;
@PluginDescriptor(
name = "Chat Notifications",
description = "Highlight and notify you of chat messages",
tags = {"duel", "messages", "notifications", "trade", "username"},
enabledByDefault = false
)
public class ChatNotificationsPlugin extends Plugin
{
@Inject
private Client client;
@Inject
private ChatNotificationsConfig config;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private Notifier notifier;
@Inject
private RuneLiteProperties runeLiteProperties;
//Custom Highlights
private Pattern usernameMatcher = null;
private String usernameReplacer = "";
private Pattern highlightMatcher = null;
@Provides
ChatNotificationsConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(ChatNotificationsConfig.class);
}
@Override
public void startUp()
{
updateHighlights();
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
switch (event.getGameState())
{
case LOGIN_SCREEN:
case HOPPING:
usernameMatcher = null;
break;
}
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("chatnotification"))
{
updateHighlights();
}
}
private void updateHighlights()
{
highlightMatcher = null;
if (!config.highlightWordsString().trim().equals(""))
{
List<String> items = Text.fromCSV(config.highlightWordsString());
String joined = items.stream()
.map(Pattern::quote)
.collect(Collectors.joining("|"));
highlightMatcher = Pattern.compile("\\b(" + joined + ")\\b", Pattern.CASE_INSENSITIVE);
}
}
@Subscribe
public void onChatMessage(ChatMessage chatMessage)
{
MessageNode messageNode = chatMessage.getMessageNode();
String nodeValue = Text.removeTags(messageNode.getValue());
boolean update = false;
switch (chatMessage.getType())
{
case TRADEREQ:
if (chatMessage.getMessage().contains("wishes to trade with you.") && config.notifyOnTrade())
{
notifier.notify(chatMessage.getMessage());
}
break;
case CHALREQ_TRADE:
if (chatMessage.getMessage().contains("wishes to duel with you.") && config.notifyOnDuel())
{
notifier.notify(chatMessage.getMessage());
}
break;
case CONSOLE:
// Don't notify for notification messages
if (chatMessage.getName().equals(runeLiteProperties.getTitle()))
{
return;
}
break;
}
if (usernameMatcher == null && client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null)
{
String username = client.getLocalPlayer().getName();
usernameMatcher = Pattern.compile("\\b(" + quote(username) + ")\\b", Pattern.CASE_INSENSITIVE);
usernameReplacer = "<col" + ChatColorType.HIGHLIGHT.name() + "><u>" + username + "</u><col" + ChatColorType.NORMAL.name() + ">";
}
if (config.highlightOwnName() && usernameMatcher != null)
{
Matcher matcher = usernameMatcher.matcher(messageNode.getValue());
if (matcher.find())
{
messageNode.setValue(matcher.replaceAll(usernameReplacer));
update = true;
if (config.notifyOnOwnName())
{
sendNotification(chatMessage);
}
}
}
if (highlightMatcher != null)
{
Matcher matcher = highlightMatcher.matcher(nodeValue);
boolean found = false;
StringBuffer stringBuffer = new StringBuffer();
while (matcher.find())
{
String value = matcher.group();
matcher.appendReplacement(stringBuffer, "<col" + ChatColorType.HIGHLIGHT + ">" + value + "<col" + ChatColorType.NORMAL + ">");
update = true;
found = true;
}
if (found)
{
matcher.appendTail(stringBuffer);
messageNode.setValue(stringBuffer.toString());
if (config.notifyOnHighlight())
{
sendNotification(chatMessage);
}
}
}
if (update)
{
messageNode.setRuneLiteFormatMessage(messageNode.getValue());
chatMessageManager.update(messageNode);
}
}
private void sendNotification(ChatMessage message)
{
String name = Text.removeTags(message.getName());
String sender = message.getSender();
StringBuilder stringBuilder = new StringBuilder();
if (!Strings.isNullOrEmpty(sender))
{
stringBuilder.append('[').append(sender).append("] ");
}
if (!Strings.isNullOrEmpty(name))
{
stringBuilder.append(name).append(": ");
}
stringBuilder.append(Text.removeTags(message.getMessage()));
String notification = stringBuilder.toString();
notifier.notify(notification);
}
}

View File

@@ -33,13 +33,11 @@ import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject;
import net.runelite.api.ChatLineBuffer;
@@ -49,9 +47,7 @@ import net.runelite.api.ClanMemberRank;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.MessageNode;
import net.runelite.api.Opcodes;
import net.runelite.api.Player;
import net.runelite.api.Script;
import net.runelite.api.ScriptID;
import net.runelite.api.SpriteID;
import net.runelite.api.VarClientStr;
@@ -65,10 +61,7 @@ import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.PlayerDespawned;
import net.runelite.api.events.PlayerSpawned;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.VarClientStrChanged;
import net.runelite.api.events.WidgetMenuOptionClicked;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetType;
@@ -78,8 +71,6 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ClanManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.menus.MenuManager;
import net.runelite.client.menus.WidgetMenuOption;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
@@ -120,16 +111,13 @@ public class ClanChatPlugin extends Plugin
@Inject
private ClientThread clientThread;
@Inject
private MenuManager menuManager;
private List<String> chats = new ArrayList<>();
public static CopyOnWriteArrayList<Player> getClanMembers()
{
return (CopyOnWriteArrayList<Player>) clanMembers.clone();
}
private static CopyOnWriteArrayList<Player> clanMembers = new CopyOnWriteArrayList<>();
private ClanChatIndicator clanMemberCounter;
/**
@@ -139,8 +127,6 @@ public class ClanChatPlugin extends Plugin
private Map<String, ClanMemberActivity> activityBuffer = new HashMap<>();
private int clanJoinedTick;
private ConcurrentHashMap<Widget, WidgetMenuOption> ccWidgetMap = new ConcurrentHashMap<Widget, WidgetMenuOption>();
@Provides
ClanChatConfig getConfig(ConfigManager configManager)
{
@@ -561,13 +547,14 @@ public class ClanChatPlugin extends Plugin
private void loadClanChats()
{
Widget clanChatList = client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
clanChatList.setScrollHeight( 14 * chats.size());
clanChatList.revalidateScroll();
if (clanChatList == null)
{
return;
}
clanChatList.setScrollHeight(14 * chats.size());
clanChatList.revalidateScroll();
int y = 2;
clanChatList.setChildren(null);
for (String chat : Lists.reverse(chats))

View File

@@ -7,7 +7,6 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.client.game.ClanManager;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
@@ -49,7 +48,8 @@ public class ClanManModeOverlay extends Overlay
if (textLocation != null)
{
if (config.getClanAttackableColor().equals(color) && config.ShowBold()) {
if (config.getClanAttackableColor().equals(color) && config.ShowBold())
{
graphics.setFont(FontManager.getRunescapeBoldFont());
}
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);

View File

@@ -70,14 +70,16 @@ public class ClanManModePlugin extends Plugin
Map<String, Integer> clan = new HashMap<>();
@Override
protected void startUp() throws Exception {
protected void startUp() throws Exception
{
overlayManager.add(ClanManModeOverlay);
overlayManager.add(ClanManModeTileOverlay);
overlayManager.add(ClanManModeMinimapOverlay);
}
@Override
protected void shutDown() throws Exception {
protected void shutDown() throws Exception
{
overlayManager.remove(ClanManModeOverlay);
overlayManager.remove(ClanManModeTileOverlay);
overlayManager.remove(ClanManModeMinimapOverlay);
@@ -90,17 +92,21 @@ public class ClanManModePlugin extends Plugin
}
@Subscribe
public void onGameStateChanged(GameStateChanged gameStateChanged) {
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING) {
public void onGameStateChanged(GameStateChanged gameStateChanged)
{
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING)
{
ticks = 0;
}
}
@Subscribe
public void onGameTick(GameTick event) {
public void onGameTick(GameTick event)
{
ticks++;
final Player localPlayer = client.getLocalPlayer();
if (!clan.containsKey(localPlayer.getName())) {
if (!clan.containsKey(localPlayer.getName()))
{
clan.put(localPlayer.getName(), localPlayer.getCombatLevel());
}
WorldPoint a = localPlayer.getWorldLocation();
@@ -108,30 +114,38 @@ public class ClanManModePlugin extends Plugin
int upperLevel = ((a.getY() - 3520) / 8) + 1;
wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
inwildy = client.getVar(Varbits.IN_WILDERNESS);
if (clan.size() > 0) {
if (clan.size() > 0)
{
clanmin = Collections.min(clan.values());
clanmax = Collections.max(clan.values());
}
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded event) {
if (!config.hideAtkOpt()) {
public void onMenuEntryAdded(MenuEntryAdded event)
{
if (!config.hideAtkOpt())
{
return;
}
if (client.getGameState() != GameState.LOGGED_IN) {
if (client.getGameState() != GameState.LOGGED_IN)
{
return;
}
final String option = Text.removeTags(event.getOption()).toLowerCase();
if (option.equals("attack")) {
if (option.equals("attack"))
{
final Pattern ppattern = Pattern.compile("<col=ffffff>(.+?)<col=");
final Matcher pmatch = ppattern.matcher(event.getTarget());
if (pmatch.find() && pmatch.matches()) {
if (pmatch.group(1) != null) {
if (clan.containsKey(pmatch.group(1).replace(" ", " "))) {
if (pmatch.find() && pmatch.matches())
{
if (pmatch.group(1) != null)
{
if (clan.containsKey(pmatch.group(1).replace(" ", " ")))
{
MenuEntry[] entries = client.getMenuEntries();
entries = ArrayUtils.removeElement(entries, entries[entries.length - 1]);
client.setMenuEntries(entries);

View File

@@ -39,52 +39,70 @@ public class ClanManModeService
int selfmax = localPlayer.getCombatLevel() + plugin.wildernessLevel;
for (Player player : client.getPlayers())
{
if (player == null || player.getName() == null) {
if (player == null || player.getName() == null)
{
continue;
}
if (player == localPlayer) {
if (player == localPlayer)
{
continue;
}
boolean isClanMember = player.isClanMember();
Actor interacting = player.getInteracting();
Player interactor = null;
if (interacting != null && !(interacting instanceof NPC)) {
if (interacting != null && !(interacting instanceof NPC))
{
interactor = ((Player) interacting);
}
if (config.showAttackers()) {
if (interactor != null) {
if (interactor.getName().equals(localName)) {
if (config.showAttackers())
{
if (interactor != null)
{
if (interactor.getName().equals(localName))
{
consumer.accept(player, config.getAttackerColor());
}
}
}
if (plugin.inwildy == 1) {
if (isClanMember) {
if (!plugin.clan.containsKey(player.getName())) {
if (plugin.inwildy == 1)
{
if (isClanMember)
{
if (!plugin.clan.containsKey(player.getName()))
{
plugin.clan.put(player.getName(), player.getCombatLevel());
}
if (config.highlightAttacked()) {
if (interactor != null) {
if (!interactors.containsKey(interactor.getName())) {
if (config.highlightAttacked())
{
if (interactor != null)
{
if (!interactors.containsKey(interactor.getName()))
{
WorldPoint a = interactor.getWorldLocation();
int underLevel = ((a.getY() - 9920) / 8) + 1;
int upperLevel = ((a.getY() - 3520) / 8) + 1;
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
int wildydiff = plugin.wildernessLevel - wildernessLevel;
if (wildydiff < 0) {
if (wildydiff < 0)
{
wildydiff = 0;
}
if (config.CalcSelfCB()) {
if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember()) {
if (config.CalcSelfCB())
{
if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember())
{
interactors.put(interactor.getName(), player.getName());
consumer.accept(interactor, config.getClanAttackableColor());
}
} else {
if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember()) {
}
else
{
if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember())
{
interactors.put(interactor.getName(), player.getName());
consumer.accept(interactor, config.getClanAttackableColor());
}
@@ -92,43 +110,61 @@ public class ClanManModeService
}
}
}
} else {
if (config.PersistentClan()) {
if (plugin.clan.containsKey(player.getName())) {
}
else
{
if (config.PersistentClan())
{
if (plugin.clan.containsKey(player.getName()))
{
consumer.accept(player, config.getClanMemberColor());
}
}
if (config.highlightAttacked()) {
if (interactors.containsKey(player.getName())) {
if (config.highlightAttacked())
{
if (interactors.containsKey(player.getName()))
{
String attackername = interactors.get(player.getName());
boolean found = false;
for (Player attacker : client.getPlayers()) {
if (attacker == null || attacker.getName() == null) {
for (Player attacker : client.getPlayers())
{
if (attacker == null || attacker.getName() == null)
{
continue;
}
if (attacker.getName().equals(attackername)) {
if (attacker.getName().equals(attackername))
{
found = true;
Actor ainteract = attacker.getInteracting();
if (ainteract != null) {
if (ainteract.getName().equals(player.getName())) {
if (ainteract != null)
{
if (ainteract.getName().equals(player.getName()))
{
consumer.accept(player, config.getClanAttackableColor());
} else {
}
else
{
interactors.remove(player.getName());
}
} else {
}
else
{
interactors.remove(player.getName());
}
break;
}
}
if (!found) {
if (!found)
{
interactors.remove(player.getName());
}
continue;
}
}
if (config.highlightAttackable()) {
if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName())) {
if (config.highlightAttackable())
{
if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName()))
{
continue;
}
WorldPoint a = player.getWorldLocation();
@@ -136,15 +172,21 @@ public class ClanManModeService
int upperLevel = ((a.getY() - 3520) / 8) + 1;
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
int wildydiff = plugin.wildernessLevel - wildernessLevel;
if (wildydiff < 0) {
if (wildydiff < 0)
{
wildydiff = 0;
}
if (config.CalcSelfCB()) {
if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin) {
if (config.CalcSelfCB())
{
if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin)
{
consumer.accept(player, config.getAttackableColor());
}
} else {
if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk) {
}
else
{
if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk)
{
consumer.accept(player, config.getAttackableColor());
}
}

View File

@@ -749,7 +749,7 @@ public class ClueScrollPlugin extends Plugin
textComponent.render(graphics);
}
void scrollToWidget(WidgetInfo list, WidgetInfo scrollbar, Widget ... toHighlight)
void scrollToWidget(WidgetInfo list, WidgetInfo scrollbar, Widget... toHighlight)
{
final Widget parent = client.getWidget(list);
int averageCentralY = 0;

View File

@@ -267,12 +267,12 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc
@Override
public String[] getNpcs()
{
return new String[] {npc};
return new String[]{npc};
}
@Override
public int[] getObjectIds()
{
return new int[] {objectId};
return new int[]{objectId};
}
}

View File

@@ -133,6 +133,6 @@ public class CipherClue extends ClueScroll implements TextClueScroll, NpcClueScr
public String[] getNpcs()
{
return new String[] {npc};
return new String[]{npc};
}
}

View File

@@ -32,7 +32,56 @@ import lombok.Getter;
import net.runelite.api.NPC;
import static net.runelite.api.NullObjectID.NULL_1293;
import net.runelite.api.ObjectComposition;
import static net.runelite.api.ObjectID.*;
import static net.runelite.api.ObjectID.BOOKCASE_12539;
import static net.runelite.api.ObjectID.BOOKCASE_380;
import static net.runelite.api.ObjectID.BOOKCASE_394;
import static net.runelite.api.ObjectID.BOOKCASE_9523;
import static net.runelite.api.ObjectID.BOXES;
import static net.runelite.api.ObjectID.BOXES_360;
import static net.runelite.api.ObjectID.BOXES_361;
import static net.runelite.api.ObjectID.BOXES_3686;
import static net.runelite.api.ObjectID.BOXES_5111;
import static net.runelite.api.ObjectID.BOXES_6176;
import static net.runelite.api.ObjectID.BUCKET_9568;
import static net.runelite.api.ObjectID.BUSH_2357;
import static net.runelite.api.ObjectID.CLOSED_CHEST_25592;
import static net.runelite.api.ObjectID.CLOSED_CHEST_375;
import static net.runelite.api.ObjectID.CLOSED_CHEST_5108;
import static net.runelite.api.ObjectID.COFFIN;
import static net.runelite.api.ObjectID.CRATES_11600;
import static net.runelite.api.ObjectID.CRATES_24088;
import static net.runelite.api.ObjectID.CRATE_11485;
import static net.runelite.api.ObjectID.CRATE_12963;
import static net.runelite.api.ObjectID.CRATE_18204;
import static net.runelite.api.ObjectID.CRATE_18506;
import static net.runelite.api.ObjectID.CRATE_18889;
import static net.runelite.api.ObjectID.CRATE_24344;
import static net.runelite.api.ObjectID.CRATE_25775;
import static net.runelite.api.ObjectID.CRATE_26635;
import static net.runelite.api.ObjectID.CRATE_27532;
import static net.runelite.api.ObjectID.CRATE_27533;
import static net.runelite.api.ObjectID.CRATE_354;
import static net.runelite.api.ObjectID.CRATE_355;
import static net.runelite.api.ObjectID.CRATE_356;
import static net.runelite.api.ObjectID.CRATE_357;
import static net.runelite.api.ObjectID.CRATE_358;
import static net.runelite.api.ObjectID.CRATE_366;
import static net.runelite.api.ObjectID.CRATE_5106;
import static net.runelite.api.ObjectID.CRATE_5107;
import static net.runelite.api.ObjectID.CRATE_5113;
import static net.runelite.api.ObjectID.CRATE_9534;
import static net.runelite.api.ObjectID.DRAWERS;
import static net.runelite.api.ObjectID.DRAWERS_25766;
import static net.runelite.api.ObjectID.DRAWERS_350;
import static net.runelite.api.ObjectID.DRAWERS_352;
import static net.runelite.api.ObjectID.DRAWERS_5618;
import static net.runelite.api.ObjectID.DRAWERS_7194;
import static net.runelite.api.ObjectID.HAYSTACK;
import static net.runelite.api.ObjectID.JUNA;
import static net.runelite.api.ObjectID.MINE_CART_6045;
import static net.runelite.api.ObjectID.STONES_26633;
import static net.runelite.api.ObjectID.WARDROBE_5622;
import static net.runelite.api.ObjectID.WHEELBARROW_9625;
import net.runelite.api.TileObject;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
@@ -116,7 +165,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
new CrypticClue("Probably filled with wizards socks.", "Wizard", DRAWERS_350, new WorldPoint(3116, 9562, 0), "Search the drawers in the basement of the Wizard's Tower south of Draynor Village. Kill one of the Wizards for the key. Fairy ring DIS"),
new CrypticClue("Even the seers say this clue goes right over their heads.", CRATE_26635, new WorldPoint(2707, 3488, 2), "Search the crate on the Seers Agility Course in Seers Village"),
new CrypticClue("Speak to a Wyse man.", "Wyson the gardener", new WorldPoint(3026, 3378, 0), "Talk to Wyson the gardener at Falador Park."),
new CrypticClue("You'll need to look for a town with a central fountain. Look for a locked chest in the town's chapel.", "Monk" , CLOSED_CHEST_5108, new WorldPoint(3256, 3487, 0), "Search the chest by the stairs in the Varrock church. Kill a Monk in Ardougne Monastery to obtain the key."),
new CrypticClue("You'll need to look for a town with a central fountain. Look for a locked chest in the town's chapel.", "Monk", CLOSED_CHEST_5108, new WorldPoint(3256, 3487, 0), "Search the chest by the stairs in the Varrock church. Kill a Monk in Ardougne Monastery to obtain the key."),
new CrypticClue("Talk to Ambassador Spanfipple in the White Knights Castle.", "Ambassador Spanfipple", new WorldPoint(2979, 3340, 0), "Ambassador Spanfipple can be found roaming on the first floor of the White Knights Castle."),
new CrypticClue("Mine was the strangest birth under the sun. I left the crimson sack, yet life had not begun. Entered the world, and yet was seen by none.", new WorldPoint(2832, 9586, 0), "Inside Karamja Volcano, dig directly underneath the Red spiders' eggs respawn."),
new CrypticClue("Search for a crate in Varrock Castle.", CRATE_5113, new WorldPoint(3224, 3492, 0), "Search the crate in the corner of the kitchen in Varrock Castle."),
@@ -196,13 +245,13 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
new CrypticClue("Search a bookcase in Lumbridge swamp.", BOOKCASE_9523, new WorldPoint(3146, 3177, 0), "Located in Father Urhney's house."),
new CrypticClue("Surround my bones in fire, ontop the wooden pyre. Finally lay me to rest, before my one last test.", null, "Kill a confused/lost barbarian to receive mangled bones. Construct and burn a pyre ship. Kill the ferocious barbarian spirit that spawns to receive a clue casket."),
new CrypticClue("Fiendish cooks probably won't dig the dirty dishes.", new WorldPoint(3043, 4974, 1), "Dig by the fire in the Rogues' Den."),
new CrypticClue("My life was spared but these voices remain, now guarding these iron gates is my bane.", "Key Master", new WorldPoint(1310, 1251, 0), "Speak to the Key Master in Cerberus' Lair."),
new CrypticClue("My life was spared but these voices remain, now guarding these iron gates is my bane.", "Key Master", new WorldPoint(1310, 1251, 0), "Speak to the Key Master in Cerberus' Lair."),
new CrypticClue("Search the boxes in one of the tents in Al Kharid.", BOXES_361, new WorldPoint(3308, 3206, 0), "Search the boxes in the tent east of the Silk trader."),
new CrypticClue("One of several rhyming brothers, in business attire with an obsession for paper work.", "Piles", new WorldPoint(3186, 3936, 0), "Speak to Piles in the Wilderness Resource Area. An entry fee of 7,500 coins is required, or less if Wilderness Diaries have been completed."),
new CrypticClue("One of several rhyming brothers, in business attire with an obsession for paper work.", "Piles", new WorldPoint(3186, 3936, 0), "Speak to Piles in the Wilderness Resource Area. An entry fee of 7,500 coins is required, or less if Wilderness Diaries have been completed."),
new CrypticClue("Search the drawers on the first floor of a building overlooking Ardougne's Market.", DRAWERS_352, new WorldPoint(2657, 3322, 1), "Climb the ladder in the house north of the market."),
new CrypticClue("'A bag belt only?', he asked his balding brothers.", "Abbot Langley", new WorldPoint(3058, 3487, 0), "Talk-to Abbot Langley in Monastery west of Edgeville"),
new CrypticClue("Search the drawers upstairs in Falador's shield shop.", DRAWERS, new WorldPoint(2971, 3386, 1), "Cassie's Shield Shop at the northern Falador entrance."),
new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", DRAWERS_350 , new WorldPoint(2512, 3641, 1), "Search the drawers in the first floor of the Lighthouse. Kill a Rellekka marketplace guard to obtain the key."),
new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", DRAWERS_350, new WorldPoint(2512, 3641, 1), "Search the drawers in the first floor of the Lighthouse. Kill a Rellekka marketplace guard to obtain the key."),
new CrypticClue("Dig near some giant mushrooms, behind the Grand Tree.", new WorldPoint(2458, 3504, 0), "Dig near the red mushrooms northwest of the Grand Tree."),
new CrypticClue("Pentagrams and demons, burnt bones and remains, I wonder what the blood contains.", new WorldPoint(3297, 3890, 0), "Dig under the blood rune spawn next the the Demonic Ruins."),
new CrypticClue("Search the drawers above Varrock's shops.", DRAWERS_7194, new WorldPoint(3206, 3419, 1), "Located upstairs in Thessalia's Fine Clothes shop in Varrock."),
@@ -276,7 +325,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
new CrypticClue("Ghommal wishes to be impressed by how strong your equipment is.", "Ghommal", new WorldPoint(2878, 3546, 0), "Speak to Ghommal at the Warriors' Guild with a total Melee Strength bonus of over 100."),
new CrypticClue("Shhhh!", "Logosia", new WorldPoint(1633, 3808, 0), "Speak to Logosia in the Arceuus Library's ground floor."),
new CrypticClue("Salty peter.", "Konoo", new WorldPoint(1703, 3524, 0), "Talk to Konoo who is digging saltpetre in Hosidius, south of the bank."),
new CrypticClue("Talk to Zeke in Al Kharid.", "Zeke", new WorldPoint(3287, 3190, 0), "Zeke is the owner of the scimitar shop in Al Kharid."),
new CrypticClue("Talk to Zeke in Al Kharid.", "Zeke", new WorldPoint(3287, 3190, 0), "Zeke is the owner of the scimitar shop in Al Kharid."),
new CrypticClue("Guthix left his mark in a fiery lake, dig at the tip of it.", new WorldPoint(3069, 3935, 0), "Dig at the tip of the lava lake that is shaped like a Guthixian symbol, west of the Mage Arena."),
new CrypticClue("Search the drawers in the upstairs of a house in Catherby.", DRAWERS_350, new WorldPoint(2809, 3451, 1), "Perdu's house in Catherby."),
new CrypticClue("Search a crate in the Haymaker's arms.", CRATE_27532, new WorldPoint(1720, 3652, 1), "Search the crate in the north-east corner of The Haymaker's Arms tavern east of Kourend Castle."),
@@ -294,9 +343,9 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
new CrypticClue("Dig in the centre of a great kingdom of 5 cities.", new WorldPoint(1639, 3673, 0), "Dig in front of the large statue in the centre of Great Kourend."),
new CrypticClue("Hopefully this set of armour will help you to keep surviving.", "Sir Vyvin", new WorldPoint(2982, 3336, 2), "Speak to Sir Vyvin while wearing a white platebody, and platelegs."),
new CrypticClue("The beasts retreat, for their Queen is gone; the song of this town still plays on. Dig near the birthplace of a blade, be careful not to melt your spade.", new WorldPoint(2342, 3677, 0), "Dig in front of the small furnace in the Piscatoris Fishing Colony."),
new CrypticClue("Darkness wanders around me, but fills my mind with knowledge.", "Biblia", new WorldPoint(1633, 3825, 2), "Speak to Biblia on the Arceuus Library's top floor."),
new CrypticClue("Darkness wanders around me, but fills my mind with knowledge.", "Biblia", new WorldPoint(1633, 3825, 2), "Speak to Biblia on the Arceuus Library's top floor."),
new CrypticClue("I would make a chemistry joke, but I'm afraid I wouldn't get a reaction.", "Chemist", new WorldPoint(2932, 3212, 0), "Talk to the Chemist in Rimmington"),
new CrypticClue("Show this to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Hazelmere is found upstairs on the island located just east of Yanille."),
new CrypticClue("Show this to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Hazelmere is found upstairs on the island located just east of Yanille."),
new CrypticClue("Does one really need a fire to stay warm here?", new WorldPoint(3816, 3810, 0), "Dig next to the fire near the Volcanic Mine entrance."),
new CrypticClue("Search the open crate found in a small farmhouse in Hosidius. Cabbages grow outside.", CRATE_27533, new WorldPoint(1687, 3628, 0), "The house is north-east of the general store in Hosidius."),
new CrypticClue("Dig under Ithoi's cabin.", new WorldPoint(2529, 2838, 0), "Dig under Ithoi's cabin in the Corsair Cove."),
@@ -428,7 +477,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
for (TileObject gameObject : plugin.getObjectsToMark())
{
OverlayUtil.renderHoverableArea(graphics, gameObject.getClickbox(), mousePosition,
CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR);
CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR);
OverlayUtil.renderImageLocation(plugin.getClient(), graphics, gameObject.getLocalLocation(), plugin.getClueScrollImage(), IMAGE_Z_OFFSET);
}
@@ -452,12 +501,12 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
@Override
public int[] getObjectIds()
{
return new int[] {objectId};
return new int[]{objectId};
}
@Override
public String[] getNpcs()
{
return new String[] {npc};
return new String[]{npc};
}
}

View File

@@ -184,7 +184,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl
@Override
public String[] getNpcs()
{
return new String[] {FALO_THE_BARD};
return new String[]{FALO_THE_BARD};
}
public static FaloTheBardClue forText(String text)

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