Merge remote-tracking branch 'upstream/master' into priority-swaps
Conflicts: runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
This commit is contained in:
17
build.gradle
17
build.gradle
@@ -28,11 +28,12 @@ allprojects {
|
||||
apply plugin: 'checkstyle'
|
||||
|
||||
group = 'net.runelite'
|
||||
version = '1.5.30-SNAPSHOT'
|
||||
version = '1.5.31-SNAPSHOT'
|
||||
|
||||
ext {
|
||||
rsversion = 181
|
||||
cacheversion = 165
|
||||
plusVersion = '2.1.2.0'
|
||||
|
||||
gitCommit = localGitCommit
|
||||
gitCommitShort = localGitCommitShort
|
||||
@@ -51,6 +52,7 @@ allprojects {
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'maven'
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
tasks.withType(JavaCompile) {
|
||||
@@ -65,6 +67,9 @@ subprojects {
|
||||
maven { url "http://repo.runelite.net" }
|
||||
maven { url "http://repo.maven.apache.org/maven2" }
|
||||
maven { url "https://raw.githubusercontent.com/runelite-extended/maven-repo/master" }
|
||||
if (System.getenv("NEXUS-URL") != null) {
|
||||
maven { url System.getenv("NEXUS-URL") }
|
||||
}
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
@@ -76,6 +81,16 @@ subprojects {
|
||||
ignoreFailures = false
|
||||
maxWarnings = 0
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
repositories {
|
||||
mavenDeployer {
|
||||
repository(url: System.getenv("NEXUS-URL")) {
|
||||
authentication(userName: System.getenv("NEXUS-USER"), password: System.getenv("NEXUS-PASSWORD"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wrapper {
|
||||
|
||||
@@ -6,9 +6,9 @@ plugins {
|
||||
|
||||
description = 'Deobfuscator'
|
||||
|
||||
def rootPath = project.rootDir.toString().replace('\\', '/')
|
||||
def deobfuscatedJar = "${rootPath}/runescape-client/build/libs/rs-client-${project.version}.jar"
|
||||
def vanillaJar = "${rootPath}/injector-plugin/vanilla-${rsversion}.jar"
|
||||
configurations {
|
||||
deobjars
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':runelite-api')
|
||||
@@ -19,18 +19,28 @@ dependencies {
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
implementation group: 'org.ow2.asm', name: 'asm-debug-all', version: '5.2'
|
||||
runtime group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.26'
|
||||
testImplementation project(':rs-client')
|
||||
testImplementation group: 'net.runelite.rs', name: 'vanilla', version: '181'
|
||||
deobjars project(':rs-client')
|
||||
deobjars group: 'net.runelite.rs', name: 'vanilla', version: '181'
|
||||
testImplementation configurations.deobjars.dependencies
|
||||
testImplementation group: 'junit', name: 'junit', version: '4.12'
|
||||
testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
|
||||
}
|
||||
|
||||
processResources {
|
||||
from file("src/main/resources/deob.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"rs.version": rsversion.toString(),
|
||||
"vanilla.jar": configurations.deobjars.find {it.name.startsWith("vanilla")}.toString().replace('\\', "/"),
|
||||
"rs.client": configurations.deobjars.find {it.name.startsWith("rs-client")}.toString().replace('\\', "/")
|
||||
])
|
||||
}
|
||||
}
|
||||
processTestResources {
|
||||
from file("src/test/resources/deob-test.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"rs.client": deobfuscatedJar.toString(),
|
||||
"rs.client": configurations.deobjars.find {it.name.startsWith("rs-client")}.toString().replace('\\', "/"),
|
||||
"rs.version": rsversion.toString(),
|
||||
"vanilla.jar": vanillaJar.toString()
|
||||
"vanilla.jar": configurations.deobjars.find {it.name.startsWith("vanilla")}.toString().replace('\\', "/")
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import static net.runelite.deob.DeobAnnotations.*;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
@@ -308,6 +309,20 @@ public class ClassFile
|
||||
return null;
|
||||
}
|
||||
|
||||
public Method findObfStaticMethod(String name, Signature type)
|
||||
{
|
||||
for (Method m : methods)
|
||||
{
|
||||
if (m.isStatic() &&
|
||||
name.equals(getObfuscatedName(m.getAnnotations())) &&
|
||||
type.equals(getObfuscatedSignature(m)))
|
||||
{
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return findMethodDeepStatic(name, type);
|
||||
}
|
||||
|
||||
public Method findMethod(String name)
|
||||
{
|
||||
for (Method m : methods)
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import static net.runelite.deob.DeobAnnotations.*;
|
||||
|
||||
public class ClassGroup
|
||||
{
|
||||
@@ -142,4 +143,17 @@ public class ClassGroup
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
public ClassFile findObfuscatedName(String name)
|
||||
{
|
||||
for (ClassFile cf : classes)
|
||||
{
|
||||
if (name.equals(getObfuscatedName(cf.getAnnotations())))
|
||||
{
|
||||
return cf;
|
||||
}
|
||||
}
|
||||
|
||||
return findClass(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package net.runelite.asm;
|
||||
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -131,6 +132,17 @@ public class Field
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Type getObfuscatedType()
|
||||
{
|
||||
Type type = DeobAnnotations.getObfuscatedType(this);
|
||||
if (type == null)
|
||||
{
|
||||
type = getType();
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
public Object getValue()
|
||||
{
|
||||
return value;
|
||||
|
||||
@@ -35,6 +35,7 @@ import net.runelite.asm.attributes.code.LocalVariable;
|
||||
import net.runelite.asm.attributes.code.Parameter;
|
||||
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
@@ -193,6 +194,17 @@ public class Method
|
||||
this.arguments = signature;
|
||||
}
|
||||
|
||||
public Signature getObfuscatedSignature()
|
||||
{
|
||||
Signature sig = DeobAnnotations.getObfuscatedSignature(this);
|
||||
if (sig == null)
|
||||
{
|
||||
sig = arguments;
|
||||
}
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
public boolean isNative()
|
||||
{
|
||||
return (accessFlags & ACC_NATIVE) != 0;
|
||||
|
||||
@@ -25,10 +25,13 @@
|
||||
|
||||
package net.runelite.asm.attributes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.code.Exceptions;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.Label;
|
||||
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
|
||||
@@ -110,4 +113,28 @@ public class Code
|
||||
{
|
||||
return instructions;
|
||||
}
|
||||
|
||||
public List<Integer> getLineNumbers()
|
||||
{
|
||||
final List<Integer> lineNumbers = new ArrayList<>();
|
||||
|
||||
for (Instruction i : instructions.getInstructions())
|
||||
{
|
||||
if (!(i instanceof Label))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer lineNumber = ((Label) i).getLineNumber();
|
||||
if (lineNumber == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lineNumbers.add(lineNumber);
|
||||
}
|
||||
|
||||
lineNumbers.sort(Integer::compareTo);
|
||||
return lineNumbers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,11 @@ public class Label extends NOP
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
public Integer getLineNumber()
|
||||
{
|
||||
return this.lineNumber;
|
||||
}
|
||||
|
||||
public Instruction next()
|
||||
{
|
||||
Instructions ins = this.getInstructions();
|
||||
|
||||
@@ -45,7 +45,7 @@ public class Field
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Field{" + "clazz=" + clazz + ", name=" + name + ", type=" + type + '}';
|
||||
return clazz.getName() + '.' + name + " " + type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,7 +43,7 @@ public class Method
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return clazz + "." + name + type;
|
||||
return clazz.getName() + "." + name + type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -75,7 +75,7 @@ public class Deob
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
//logger.info("Deobfuscator revision {}", DeobProperties.getRevision());
|
||||
logger.info("Deobfuscator revision {}", DeobProperties.getRevision());
|
||||
|
||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||
|
||||
|
||||
@@ -24,18 +24,39 @@
|
||||
*/
|
||||
package net.runelite.deob;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
public class DeobProperties
|
||||
{
|
||||
public static String getRevision() throws IOException
|
||||
private static final Properties properties;
|
||||
static
|
||||
{
|
||||
Properties properties = new Properties();
|
||||
InputStream resourceAsStream = DeobProperties.class.getResourceAsStream("/deob.properties");
|
||||
properties.load(resourceAsStream);
|
||||
properties = new Properties();
|
||||
try (InputStream resourceAsStream = DeobProperties.class.getResourceAsStream("/deob.properties"))
|
||||
{
|
||||
properties.load(resourceAsStream);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
//yes
|
||||
}
|
||||
}
|
||||
|
||||
return "420";
|
||||
public static String getRevision()
|
||||
{
|
||||
return properties.getProperty("rs.version");
|
||||
}
|
||||
|
||||
public static File getVanilla()
|
||||
{
|
||||
return new File(properties.getProperty("vanilla.jar"));
|
||||
}
|
||||
|
||||
public static File getRsClient()
|
||||
{
|
||||
return new File(properties.getProperty("rs.client"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package net.runelite.deob.updater;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.pool.Field;
|
||||
import net.runelite.asm.pool.Method;
|
||||
import net.runelite.deob.DeobProperties;
|
||||
import net.runelite.deob.updater.mappingdumper.MappedClass;
|
||||
import net.runelite.deob.updater.mappingdumper.MappedField;
|
||||
import net.runelite.deob.updater.mappingdumper.MappedMethod;
|
||||
import net.runelite.deob.updater.mappingdumper.MappingDump;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MappingDumper
|
||||
{
|
||||
private static ClassGroup group;
|
||||
private final Logger log = LoggerFactory.getLogger(MappingDumper.class);
|
||||
private static final Map<ClassFile, MappedClass> classMap = new HashMap<>();
|
||||
private static final Map<Field, MappedField> fieldMap = new HashMap<>();
|
||||
private static final Map<Method, MappedMethod> methodMap = new HashMap<>();
|
||||
|
||||
public MappingDumper(ClassGroup group)
|
||||
{
|
||||
MappingDumper.group = group;
|
||||
}
|
||||
|
||||
public void dump(final File outputFile)
|
||||
{
|
||||
Stopwatch st = Stopwatch.createStarted();
|
||||
group.buildClassGraph();
|
||||
|
||||
// MappingDump.of(ClassGroup) dumps everything completely
|
||||
final MappingDump dump = new MappingDump().visitGroup(group);
|
||||
dump.revision = Integer.parseInt(DeobProperties.getRevision());
|
||||
|
||||
log.info("RS version {}. Dump took {}", dump.revision, st.toString());
|
||||
log.info("Total classes: {}. Total mapped classes: {}. ({}%)", dump.totalClasses, dump.totalNamedClasses, dump.totalNamedClasses * 100 / dump.totalClasses);
|
||||
log.info("Total non static methods: {}. Total mapped non static methods: {}. ({}%)", dump.totalNonStaticMethods, dump.totalNamedNonStaticMethods, dump.totalNamedNonStaticMethods * 100 / dump.totalNamedMethods);
|
||||
log.info("Total methods: {}. Total mapped methods: {}. ({}%)", dump.totalMethods, dump.totalNamedMethods, dump.totalNamedMethods * 100 / dump.totalMethods);
|
||||
log.info("Total fields: {}. Total mapped fields: {}. ({}%)", dump.totalFields, dump.totalNamedFields, dump.totalNamedFields * 100 / dump.totalFields);
|
||||
log.info("Total non static fields: {}. Total mapped non static fields: {}. ({}%)", dump.totalNonStaticFields, dump.totalNamedNonStaticFields, dump.totalNamedNonStaticFields * 100 / dump.totalNamedFields);
|
||||
writeJson(dump, outputFile);
|
||||
}
|
||||
|
||||
// Without this stack'll overflow :P
|
||||
private void writeJson(MappingDump dump, File outputFile)
|
||||
{
|
||||
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(new FileOutputStream(outputFile), StandardCharsets.UTF_8)))
|
||||
{
|
||||
writer.setIndent(" ");
|
||||
writer.beginObject();
|
||||
writer.name("revision").value(dump.revision);
|
||||
writer.name("totalClasses").value(dump.totalClasses);
|
||||
writer.name("totalNamedClasses").value(dump.totalNamedClasses);
|
||||
writer.name("totalFields").value(dump.totalFields);
|
||||
writer.name("totalNamedFields").value(dump.totalNamedFields);
|
||||
writer.name("totalNonStaticFields").value(dump.totalNonStaticFields);
|
||||
writer.name("totalNamedNonStaticFields").value(dump.totalNamedNonStaticFields);
|
||||
writer.name("totalStaticFields").value(dump.totalStaticFields);
|
||||
writer.name("totalNamedStaticFields").value(dump.totalNamedStaticFields);
|
||||
writer.name("totalMethods").value(dump.totalMethods);
|
||||
writer.name("totalNamedMethods").value(dump.totalNamedMethods);
|
||||
writer.name("totalNonStaticMethods").value(dump.totalNonStaticMethods);
|
||||
writer.name("totalNamedNonStaticMethods").value(dump.totalNamedNonStaticMethods);
|
||||
writer.name("totalStaticMethods").value(dump.totalStaticMethods);
|
||||
writer.name("totalNamedStaticMethods").value(dump.totalNamedStaticMethods);
|
||||
writer.name("mappedClasses");
|
||||
writer.beginArray();
|
||||
for (MappedClass mc : dump.classes)
|
||||
{
|
||||
gson.toJson(mc, MappedClass.class, writer);
|
||||
}
|
||||
writer.endArray();
|
||||
writer.endObject();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Error saving json: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ClassGroup getGroup()
|
||||
{
|
||||
return group;
|
||||
}
|
||||
|
||||
public static void putMap(ClassFile clazz, MappedClass mc)
|
||||
{
|
||||
classMap.put(clazz, mc);
|
||||
}
|
||||
|
||||
public static MappedClass getMap(ClassFile clazz)
|
||||
{
|
||||
return classMap.get(clazz);
|
||||
}
|
||||
|
||||
public static void putMap(Field field, MappedField mf)
|
||||
{
|
||||
fieldMap.put(field, mf);
|
||||
}
|
||||
|
||||
public static MappedField getMap(Field field)
|
||||
{
|
||||
return fieldMap.get(field);
|
||||
}
|
||||
|
||||
public static void putMap(Method method, MappedMethod mm)
|
||||
{
|
||||
methodMap.put(method, mm);
|
||||
}
|
||||
|
||||
public static MappedMethod getMap(Method method)
|
||||
{
|
||||
return methodMap.get(method);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package net.runelite.deob.updater.mappingdumper;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.updater.MappingDumper;
|
||||
|
||||
public class MappedClass
|
||||
{
|
||||
@SerializedName("class")
|
||||
public String implementingName;
|
||||
@SerializedName("name")
|
||||
public String obfuscatedName;
|
||||
@SerializedName("super")
|
||||
public String superClass;
|
||||
public int access;
|
||||
public List<String> interfaces;
|
||||
public List<MappedField> fields;
|
||||
public List<MappedMethod> methods;
|
||||
public List<MappedMethod> constructors;
|
||||
|
||||
public MappedClass visitClass(final ClassFile c, final MappingDump dump)
|
||||
{
|
||||
MappingDumper.putMap(c, this);
|
||||
|
||||
implementingName = DeobAnnotations.getImplements(c);
|
||||
|
||||
obfuscatedName = DeobAnnotations.getObfuscatedName(c.getAnnotations());
|
||||
if (obfuscatedName == null)
|
||||
{
|
||||
obfuscatedName = c.getName();
|
||||
}
|
||||
|
||||
ClassFile parent = c.getParent();
|
||||
if (parent != null)
|
||||
{
|
||||
superClass = DeobAnnotations.getObfuscatedName(parent.getAnnotations());
|
||||
}
|
||||
|
||||
access = c.getAccess();
|
||||
|
||||
interfaces = c.getInterfaces()
|
||||
.getMyInterfaces()
|
||||
.stream()
|
||||
.map(ClassFile::getAnnotations)
|
||||
.map(DeobAnnotations::getObfuscatedName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
fields = c.getFields()
|
||||
.stream()
|
||||
.map(f -> new MappedField().visitField(f, dump))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
methods = c.getMethods()
|
||||
.stream()
|
||||
.map(m -> new MappedMethod().visitMethod(m, dump))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
constructors = methods
|
||||
.stream()
|
||||
.filter(m -> m.obfuscatedName.endsWith("init>"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.runelite.deob.updater.mappingdumper;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.pool.Method;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.updater.MappingDumper;
|
||||
|
||||
public class MappedField
|
||||
{
|
||||
@SerializedName("field")
|
||||
public String exportedName;
|
||||
public String owner;
|
||||
@SerializedName("name")
|
||||
public String obfuscatedName;
|
||||
public int access;
|
||||
public String descriptor;
|
||||
public Number decoder;
|
||||
// method name, amt of times
|
||||
public Map<Method, Integer> puts = new HashMap<>();
|
||||
public Map<Method, Integer> gets = new HashMap<>();
|
||||
|
||||
public MappedField visitField(final Field f, final MappingDump dump)
|
||||
{
|
||||
MappingDumper.putMap(f.getPoolField(), this);
|
||||
|
||||
exportedName = DeobAnnotations.getExportedName(f.getAnnotations());
|
||||
|
||||
owner = MappingDumper.getMap(f.getClassFile()).obfuscatedName;
|
||||
|
||||
obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
||||
if (obfuscatedName == null)
|
||||
{
|
||||
obfuscatedName = f.getName();
|
||||
}
|
||||
|
||||
access = f.getAccessFlags();
|
||||
|
||||
descriptor = f.getObfuscatedType().toString();
|
||||
|
||||
decoder = DeobAnnotations.getObfuscatedGetter(f);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package net.runelite.deob.updater.mappingdumper;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.Parameter;
|
||||
import net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction;
|
||||
import net.runelite.asm.attributes.code.instruction.types.InvokeInstruction;
|
||||
import net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.pool.Field;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.updater.MappingDumper;
|
||||
|
||||
public class MappedMethod
|
||||
{
|
||||
@SerializedName("method")
|
||||
public String exportedName;
|
||||
public String owner;
|
||||
@SerializedName("name")
|
||||
public String obfuscatedName;
|
||||
public int access;
|
||||
public List<String> parameters;
|
||||
public String descriptor;
|
||||
public String garbageValue;
|
||||
public List<Integer> lineNumbers;
|
||||
public Map<Field, Integer> fieldGets = new HashMap<>();
|
||||
public Map<Field, Integer> fieldPuts = new HashMap<>();
|
||||
public Map<net.runelite.asm.pool.Method, Integer> dependencies = new HashMap<>();
|
||||
|
||||
public MappedMethod visitMethod(final Method m, final MappingDump dump)
|
||||
{
|
||||
MappingDumper.putMap(m.getPoolMethod(), this);
|
||||
exportedName = DeobAnnotations.getExportedName(m.getAnnotations());
|
||||
|
||||
owner = MappingDumper.getMap(m.getClassFile()).obfuscatedName;
|
||||
|
||||
obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||
if (obfuscatedName == null)
|
||||
{
|
||||
obfuscatedName = m.getName();
|
||||
}
|
||||
|
||||
access = m.getAccessFlags();
|
||||
|
||||
parameters = m.getParameters()
|
||||
.stream()
|
||||
.map(Parameter::getName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
descriptor = m.getObfuscatedSignature().toString();
|
||||
|
||||
garbageValue = DeobAnnotations.getDecoder(m);
|
||||
|
||||
Code c = m.getCode();
|
||||
if (c != null)
|
||||
{
|
||||
visitCode(c);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void visitCode(Code c)
|
||||
{
|
||||
lineNumbers = c.getLineNumbers();
|
||||
|
||||
Instructions ins = c.getInstructions();
|
||||
for (Instruction i : ins.getInstructions())
|
||||
{
|
||||
if (i instanceof GetFieldInstruction)
|
||||
{
|
||||
Field k = ((GetFieldInstruction) i).getField();
|
||||
int v = fieldGets.getOrDefault(k, 0) + 1;
|
||||
fieldGets.put(k, v);
|
||||
}
|
||||
else if (i instanceof SetFieldInstruction)
|
||||
{
|
||||
Field k = ((SetFieldInstruction) i).getField();
|
||||
int v = fieldPuts.getOrDefault(k, 0) + 1;
|
||||
fieldPuts.put(k, v);
|
||||
}
|
||||
else if (i instanceof InvokeInstruction)
|
||||
{
|
||||
List<Method> met = ((InvokeInstruction) i).getMethods();
|
||||
net.runelite.asm.pool.Method k;
|
||||
if (met.size() > 0)
|
||||
{
|
||||
Method mme = met.get(0);
|
||||
k = new net.runelite.asm.pool.Method(
|
||||
new Class(DeobAnnotations.getObfuscatedName(mme.getClassFile().getAnnotations())),
|
||||
DeobAnnotations.getObfuscatedName(mme.getAnnotations()),
|
||||
mme.getObfuscatedSignature() != null ? mme.getObfuscatedSignature() : mme.getDescriptor()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
k = ((InvokeInstruction) i).getMethod();
|
||||
}
|
||||
|
||||
int v = dependencies.getOrDefault(k, 0) + 1;
|
||||
dependencies.put(k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package net.runelite.deob.updater.mappingdumper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.pool.Field;
|
||||
import net.runelite.asm.pool.Method;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.updater.MappingDumper;
|
||||
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
|
||||
public class MappingDump
|
||||
{
|
||||
public int revision;
|
||||
|
||||
public int totalClasses = 0;
|
||||
public int totalNamedClasses = 0;
|
||||
|
||||
public int totalFields = 0;
|
||||
public int totalNamedFields = 0;
|
||||
|
||||
public int totalNonStaticFields = 0;
|
||||
public int totalNamedNonStaticFields = 0;
|
||||
|
||||
public int totalStaticFields = 0;
|
||||
public int totalNamedStaticFields = 0;
|
||||
|
||||
public int totalMethods = 0;
|
||||
public int totalNamedMethods = 0;
|
||||
|
||||
public int totalNonStaticMethods = 0;
|
||||
public int totalNamedNonStaticMethods = 0;
|
||||
|
||||
public int totalStaticMethods = 0;
|
||||
public int totalNamedStaticMethods = 0;
|
||||
|
||||
public List<MappedClass> classes;
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
public MappingDump visitGroup(ClassGroup group)
|
||||
{
|
||||
this.group = group;
|
||||
classes = new ArrayList<>();
|
||||
|
||||
for (ClassFile c : group.getClasses())
|
||||
{
|
||||
if (c.getName().contains("runelite"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final MappedClass mc = new MappedClass();
|
||||
classes.add(mc.visitClass(c, this));
|
||||
}
|
||||
|
||||
totalClasses = classes.size();
|
||||
|
||||
for (MappedClass c : classes)
|
||||
{
|
||||
if (c.implementingName != null)
|
||||
{
|
||||
totalNamedClasses++;
|
||||
}
|
||||
|
||||
for (MappedMethod mm : c.methods)
|
||||
{
|
||||
for (Map.Entry<Field, Integer> entry : mm.fieldGets.entrySet())
|
||||
{
|
||||
MappedField mf = MappingDumper.getMap(entry.getKey());
|
||||
if (mf == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
mf.gets.put(
|
||||
new Method(
|
||||
new Class(mm.owner),
|
||||
mm.obfuscatedName,
|
||||
new Signature(mm.descriptor)),
|
||||
entry.getValue());
|
||||
}
|
||||
for (Map.Entry<Field, Integer> entry : mm.fieldPuts.entrySet())
|
||||
{
|
||||
MappedField mf = MappingDumper.getMap(entry.getKey());
|
||||
if (mf == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
mf.puts.put(
|
||||
new Method(
|
||||
new Class(mm.owner),
|
||||
mm.obfuscatedName,
|
||||
new Signature(mm.descriptor)),
|
||||
entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
grabAmountInfo(c);
|
||||
}
|
||||
totalNonStaticFields = totalFields - totalStaticFields;
|
||||
totalNamedNonStaticFields = totalNamedFields - totalNamedStaticFields;
|
||||
totalNonStaticMethods = totalMethods - totalStaticMethods;
|
||||
totalNamedNonStaticMethods = totalNamedMethods - totalNamedStaticMethods;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void grabAmountInfo(MappedClass c)
|
||||
{
|
||||
totalFields += c.fields.size();
|
||||
totalNamedFields += c.fields
|
||||
.stream()
|
||||
.filter(f -> f.exportedName != null)
|
||||
.count();
|
||||
totalStaticFields += c.fields
|
||||
.stream()
|
||||
.filter(f -> (f.access & ACC_STATIC) != 0)
|
||||
.count();
|
||||
totalNamedStaticFields += c.fields
|
||||
.stream()
|
||||
.filter(f -> f.exportedName != null
|
||||
&& (f.access & ACC_STATIC) != 0)
|
||||
.count();
|
||||
|
||||
totalMethods += c.methods.size();
|
||||
totalNamedMethods += c.methods
|
||||
.stream()
|
||||
.filter(f -> f.exportedName != null)
|
||||
.count();
|
||||
totalStaticMethods += c.methods
|
||||
.stream()
|
||||
.filter(f -> (f.access & ACC_STATIC) != 0)
|
||||
.count();
|
||||
totalNamedStaticMethods += c.methods
|
||||
.stream()
|
||||
.filter(f -> f.exportedName != null
|
||||
&& (f.access & ACC_STATIC) != 0)
|
||||
.count();
|
||||
}
|
||||
|
||||
ClassGroup getGroup()
|
||||
{
|
||||
return group;
|
||||
}
|
||||
}
|
||||
3
deobfuscator/src/main/resources/deob.properties
Normal file
3
deobfuscator/src/main/resources/deob.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
rs.version=@rs.version@
|
||||
vanilla.jar=@vanilla.jar@
|
||||
rs.client=@rs.client@
|
||||
@@ -24,266 +24,47 @@
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.mapping;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.time.Instant;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.code.Parameter;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.Deob;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappedClass;
|
||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappedField;
|
||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappedMethod;
|
||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappingDump;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MappingDumper
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(MappingDumper.class);
|
||||
|
||||
private MappingDump dump;
|
||||
private Map<String, MappedClass> classMap;
|
||||
private ClassGroup group;
|
||||
private static final String OUTDIR = "";
|
||||
private final File OUTFILE = new File(OUTDIR, "rlplushooks.json");
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
public void before() throws IOException
|
||||
{
|
||||
dump = new MappingDump();
|
||||
dump.revision = properties.getRsVersion();
|
||||
dump.classes = new ArrayList<>();
|
||||
dump.staticFields = new ArrayList<>();
|
||||
dump.staticMethods = new ArrayList<>();
|
||||
classMap = new HashMap<>();
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void newDump() throws IOException
|
||||
public void newDump()
|
||||
{
|
||||
final ClassGroup group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
|
||||
|
||||
// First create all the mappedclasses, so we can add static methods to their lists
|
||||
for (ClassFile c : group.getClasses())
|
||||
{
|
||||
if (c.getName().contains("runelite"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final MappedClass mc = new MappedClass();
|
||||
|
||||
mc.obfuscatedName = DeobAnnotations.getObfuscatedName(c.getAnnotations());
|
||||
mc.implementingName = DeobAnnotations.getImplements(c);
|
||||
mc.superClass = c.getSuperName();
|
||||
mc.interfaces = c.getInterfaces().getIntfNames();
|
||||
mc.constructors = new ArrayList<>();
|
||||
mc.fields = new ArrayList<>();
|
||||
mc.methods = new ArrayList<>();
|
||||
mc.access = c.getAccess();
|
||||
mc.staticMethods = new ArrayList<>();
|
||||
mc.staticFields = new ArrayList<>();
|
||||
|
||||
dump.classes.add(mc);
|
||||
classMap.put(c.getName(), mc);
|
||||
|
||||
dump.totalClasses++;
|
||||
if (mc.implementingName != null)
|
||||
{
|
||||
dump.totalNamedClasses++;
|
||||
}
|
||||
}
|
||||
|
||||
for (ClassFile c : group.getClasses())
|
||||
{
|
||||
if (c.getName().contains("runelite"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final MappedClass mc = classMap.get(c.getName());
|
||||
|
||||
getFields(c, mc);
|
||||
|
||||
getMethods(c, mc);
|
||||
}
|
||||
|
||||
dump.totalNonStaticFields = dump.totalFields - dump.totalStaticFields;
|
||||
dump.totalNamedNonStaticFields = dump.totalNamedFields - dump.totalNamedStaticFields;
|
||||
dump.totalNonStaticMethods = dump.totalMethods - dump.totalStaticMethods;
|
||||
dump.totalNamedNonStaticMethods = dump.totalNamedMethods - dump.totalNamedStaticMethods;
|
||||
|
||||
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
Files.asCharSink(OUTFILE, Charset.defaultCharset()).write(gson.toJson(dump));
|
||||
|
||||
log.info("Dumped current mappings. revision {}", dump.revision);
|
||||
log.info("Total classes: {}. Total mapped classes: {}. ({}%)", dump.totalClasses, dump.totalNamedClasses, dump.totalNamedClasses * 100 / dump.totalClasses);
|
||||
log.info("Total non static methods: {}. Total mapped non static methods: {}. ({}%)", dump.totalNonStaticMethods, dump.totalNamedNonStaticMethods, dump.totalNamedNonStaticMethods * 100 / dump.totalNamedMethods);
|
||||
log.info("Total methods: {}. Total mapped methods: {}. ({}%)", dump.totalMethods, dump.totalNamedMethods, dump.totalNamedMethods * 100 / dump.totalMethods);
|
||||
log.info("Total fields: {}. Total mapped fields: {}. ({}%)", dump.totalFields, dump.totalNamedFields, dump.totalNamedFields * 100 / dump.totalFields);
|
||||
log.info("Total non static fields: {}. Total mapped non static fields: {}. ({}%)", dump.totalNonStaticFields, dump.totalNamedNonStaticFields, dump.totalNamedNonStaticFields * 100 / dump.totalNamedFields);
|
||||
|
||||
}
|
||||
|
||||
private void getFields(final ClassFile c, final MappedClass mc)
|
||||
{
|
||||
for (Field f : c.getFields())
|
||||
{
|
||||
dump.totalFields++;
|
||||
|
||||
if (f.isStatic())
|
||||
{
|
||||
dump.totalStaticFields++;
|
||||
}
|
||||
|
||||
if (Deob.isObfuscated(f.getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dump.totalNamedFields++;
|
||||
|
||||
final MappedField mf = new MappedField();
|
||||
|
||||
mf.exportedName = f.getName();
|
||||
mf.owner = mc.obfuscatedName;
|
||||
mf.obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
||||
mf.access = f.getAccessFlags();
|
||||
mf.descriptor = DeobAnnotations.getAnnotationValue(f.getAnnotations(), DeobAnnotations.OBFUSCATED_SIGNATURE);
|
||||
|
||||
Number decoder = DeobAnnotations.getObfuscatedGetter(f);
|
||||
if (decoder != null)
|
||||
{
|
||||
mf.decoder = decoder.longValue();
|
||||
}
|
||||
|
||||
if (mf.descriptor == null)
|
||||
{
|
||||
mf.descriptor = f.getType().toString();
|
||||
}
|
||||
|
||||
if (f.isStatic())
|
||||
{
|
||||
dump.staticFields.add(mf);
|
||||
dump.totalNamedStaticFields++;
|
||||
|
||||
int _index = mf.exportedName.indexOf('_');
|
||||
|
||||
if (_index != -1)
|
||||
{
|
||||
String className = mf.exportedName.substring(0, _index);
|
||||
MappedClass staticOwner = classMap.get(className);
|
||||
|
||||
if (staticOwner != null)
|
||||
{
|
||||
staticOwner.staticFields.add(mf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mc.fields.add(mf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getMethods(final ClassFile c, final MappedClass mc)
|
||||
{
|
||||
for (Method m : c.getMethods())
|
||||
{
|
||||
dump.totalMethods++;
|
||||
|
||||
if (m.isStatic())
|
||||
{
|
||||
dump.totalStaticMethods++;
|
||||
}
|
||||
|
||||
if (Deob.isObfuscated(m.getName()) || m.getName().equals("<clinit>"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dump.totalNamedMethods++;
|
||||
|
||||
final MappedMethod mm = new MappedMethod();
|
||||
|
||||
mm.exportedName = m.getName();
|
||||
mm.owner = mc.obfuscatedName;
|
||||
mm.obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||
mm.access = m.getAccessFlags();
|
||||
mm.parameters = new ArrayList<>();
|
||||
mm.descriptor = DeobAnnotations.getObfuscatedSignature(m) != null ? DeobAnnotations.getObfuscatedSignature(m).toString() : m.getDescriptor().toString();
|
||||
|
||||
try
|
||||
{
|
||||
mm.garbageValue = Long.parseLong(DeobAnnotations.getDecoder(m));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
mm.garbageValue = null;
|
||||
}
|
||||
|
||||
for (Parameter p : m.getParameters())
|
||||
{
|
||||
mm.parameters.add(p.getName());
|
||||
}
|
||||
|
||||
if (m.getName().equals("<init>"))
|
||||
{
|
||||
mm.exportedName = null;
|
||||
mc.constructors.add(mm);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m.isStatic())
|
||||
{
|
||||
dump.staticMethods.add(mm);
|
||||
dump.totalNamedStaticMethods++;
|
||||
|
||||
int _index = mm.exportedName.indexOf('_');
|
||||
|
||||
if (_index != -1)
|
||||
{
|
||||
String className = mm.exportedName.substring(0, _index - 1);
|
||||
MappedClass staticOwner = classMap.get(className);
|
||||
|
||||
if (staticOwner != null)
|
||||
{
|
||||
staticOwner.staticMethods.add(mm);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mc.methods.add(mm);
|
||||
}
|
||||
}
|
||||
new net.runelite.deob.updater.MappingDumper(group).dump(OUTFILE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
|
||||
public class MappedClass
|
||||
{
|
||||
@SerializedName("class")
|
||||
public String implementingName;
|
||||
@SerializedName("name")
|
||||
public String obfuscatedName;
|
||||
@SerializedName("super")
|
||||
public String superClass;
|
||||
public int access;
|
||||
public List<String> interfaces;
|
||||
public List<MappedField> fields;
|
||||
public List<MappedMethod> methods;
|
||||
public List<MappedMethod> constructors;
|
||||
// Static fields/methods belonging to this class (ClassName_name)
|
||||
public List<MappedField> staticFields;
|
||||
public List<MappedMethod> staticMethods;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class MappedField
|
||||
{
|
||||
@SerializedName("field")
|
||||
public String exportedName;
|
||||
public String owner;
|
||||
@SerializedName("name")
|
||||
public String obfuscatedName;
|
||||
public int access;
|
||||
public String descriptor;
|
||||
public Long decoder;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
|
||||
public class MappedMethod
|
||||
{
|
||||
@SerializedName("method")
|
||||
public String exportedName;
|
||||
public String owner;
|
||||
@SerializedName("name")
|
||||
public String obfuscatedName;
|
||||
public int access;
|
||||
public List<String> parameters;
|
||||
public String descriptor;
|
||||
public Long garbageValue;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MappingDump
|
||||
{
|
||||
public int revision;
|
||||
|
||||
public int totalClasses;
|
||||
public int totalNamedClasses;
|
||||
|
||||
public int totalFields;
|
||||
public int totalNamedFields;
|
||||
|
||||
public int totalNonStaticFields;
|
||||
public int totalNamedNonStaticFields;
|
||||
|
||||
public int totalStaticFields;
|
||||
public int totalNamedStaticFields;
|
||||
|
||||
public int totalMethods;
|
||||
public int totalNamedMethods;
|
||||
|
||||
public int totalNonStaticMethods;
|
||||
public int totalNamedNonStaticMethods;
|
||||
|
||||
public int totalStaticMethods;
|
||||
public int totalNamedStaticMethods;
|
||||
|
||||
public List<MappedClass> classes;
|
||||
|
||||
// Static things belonging to a certain class will be in both these lists and in the classes
|
||||
public List<MappedField> staticFields;
|
||||
public List<MappedMethod> staticMethods;
|
||||
}
|
||||
@@ -168,7 +168,7 @@ public class RuneLiteAPI
|
||||
|
||||
public static HttpUrl getPlusApiBase()
|
||||
{
|
||||
return HttpUrl.parse(RLPLUS_BASE + "/runelite-" + getRlpVersion());
|
||||
return HttpUrl.parse(RLPLUS_BASE + "/http-service-" + getRlpVersion());
|
||||
}
|
||||
|
||||
public static HttpUrl getStaticBase()
|
||||
@@ -197,7 +197,7 @@ public class RuneLiteAPI
|
||||
|
||||
public static String getVersion()
|
||||
{
|
||||
return version;
|
||||
return upstreamVersion;
|
||||
}
|
||||
|
||||
public static int getRsVersion()
|
||||
|
||||
@@ -44,6 +44,7 @@ public final class AnimationID
|
||||
public static final int WOODCUTTING_DRAGON = 2846;
|
||||
public static final int WOODCUTTING_INFERNAL = 2117;
|
||||
public static final int WOODCUTTING_3A_AXE = 7264;
|
||||
public static final int WOODCUTTING_CRYSTAL = 8324;
|
||||
public static final int CONSUMING = 829; // consuming consumables
|
||||
public static final int FIREMAKING = 733;
|
||||
public static final int DEATH = 836;
|
||||
@@ -70,6 +71,8 @@ public final class AnimationID
|
||||
public static final int FLETCHING_STRING_YEW_LONGBOW = 6688;
|
||||
public static final int FLETCHING_STRING_MAGIC_SHORTBOW = 6683;
|
||||
public static final int FLETCHING_STRING_MAGIC_LONGBOW = 6689;
|
||||
public static final int FLETCHING_ATTACH_FEATHERS_TO_ARROWSHAFT = 8481;
|
||||
public static final int FLETCHING_ATTACH_HEADS = 8480;
|
||||
public static final int GEM_CUTTING_OPAL = 890;
|
||||
public static final int GEM_CUTTING_JADE = 891;
|
||||
public static final int GEM_CUTTING_REDTOPAZ = 892;
|
||||
@@ -94,6 +97,7 @@ public final class AnimationID
|
||||
public static final int FISHING_BARBTAIL_HARPOON = 5108;
|
||||
public static final int FISHING_DRAGON_HARPOON = 7401;
|
||||
public static final int FISHING_INFERNAL_HARPOON = 7402;
|
||||
public static final int FISHING_CRYSTAL_HARPOON = 8336;
|
||||
public static final int FISHING_OILY_ROD = 622;
|
||||
public static final int FISHING_KARAMBWAN = 1193;
|
||||
public static final int FISHING_CRUSHING_INFERNAL_EELS = 7553;
|
||||
@@ -107,9 +111,11 @@ public final class AnimationID
|
||||
public static final int MINING_ADAMANT_PICKAXE = 628;
|
||||
public static final int MINING_RUNE_PICKAXE = 624;
|
||||
public static final int MINING_DRAGON_PICKAXE = 7139;
|
||||
public static final int MINING_DRAGON_PICKAXE_ORN = 642;
|
||||
public static final int MINING_DRAGON_PICKAXE_UPGRADED = 642;
|
||||
public static final int MINING_DRAGON_PICKAXE_OR = 8346;
|
||||
public static final int MINING_INFERNAL_PICKAXE = 4482;
|
||||
public static final int MINING_3A_PICKAXE = 7283;
|
||||
public static final int MINING_CRYSTAL_PICKAXE = 8347;
|
||||
public static final int MINING_MOTHERLODE_BRONZE = 6753;
|
||||
public static final int MINING_MOTHERLODE_IRON = 6754;
|
||||
public static final int MINING_MOTHERLODE_STEEL = 6755;
|
||||
@@ -118,9 +124,11 @@ public final class AnimationID
|
||||
public static final int MINING_MOTHERLODE_ADAMANT = 6756;
|
||||
public static final int MINING_MOTHERLODE_RUNE = 6752;
|
||||
public static final int MINING_MOTHERLODE_DRAGON = 6758;
|
||||
public static final int MINING_MOTHERLODE_DRAGON_ORN = 335;
|
||||
public static final int MINING_MOTHERLODE_DRAGON_UPGRADED = 335;
|
||||
public static final int MINING_MOTHERLODE_DRAGON_OR = 8344;
|
||||
public static final int MINING_MOTHERLODE_INFERNAL = 4481;
|
||||
public static final int MINING_MOTHERLODE_3A = 7282;
|
||||
public static final int MINING_MOTHERLODE_CRYSTAL = 8345;
|
||||
public static final int DENSE_ESSENCE_CHIPPING = 7201;
|
||||
public static final int DENSE_ESSENCE_CHISELING = 7202;
|
||||
public static final int HERBLORE_POTIONMAKING = 363; //used for both herb and secondary
|
||||
@@ -326,4 +334,9 @@ public final class AnimationID
|
||||
public static final int HUNLEFF_TRAMPLE = 8420;
|
||||
public static final int HUNLEFF_ATTACK = 8419;
|
||||
public static final int HUNLEFF_TORNADO = 8418;
|
||||
|
||||
//Zalcano
|
||||
public static final int ZALCANO_KNOCKED_DOWN = 8437;
|
||||
public static final int ZALCANO_WAKEUP = 8439;
|
||||
public static final int ZALCANO_ROCK_GLOWING = 8448;
|
||||
}
|
||||
@@ -1452,9 +1452,16 @@ public interface Client extends GameShell
|
||||
/**
|
||||
* Sets which NPCs are hidden
|
||||
*
|
||||
* @param names the names of the npcs seperated by ','
|
||||
* @param names the names of the npcs
|
||||
*/
|
||||
void setNPCsNames(String names);
|
||||
void setNPCsNames(List<String> names);
|
||||
|
||||
/**
|
||||
* Sets which NPCs are hidden on death
|
||||
*
|
||||
* @param names the names of the npcs
|
||||
*/
|
||||
void setNPCsHiddenOnDeath(List<String> names);
|
||||
|
||||
/**
|
||||
* Sets whether 2D sprites (ie. overhead prayers) related to
|
||||
@@ -1478,6 +1485,13 @@ public interface Client extends GameShell
|
||||
*/
|
||||
void setProjectilesHidden(boolean state);
|
||||
|
||||
/**
|
||||
* Sets whether dead NPCs are hidden.
|
||||
*
|
||||
* @param state new NPC hidden state
|
||||
*/
|
||||
void setDeadNPCsHidden(boolean state);
|
||||
|
||||
/**
|
||||
* Gets an array of tile collision data.
|
||||
* <p>
|
||||
@@ -1678,9 +1692,9 @@ public interface Client extends GameShell
|
||||
MouseRecorder getMouseRecorder();
|
||||
|
||||
void setPrintMenuActions(boolean b);
|
||||
|
||||
|
||||
String getSelectedSpellName();
|
||||
|
||||
|
||||
boolean isSpellSelected();
|
||||
|
||||
/**
|
||||
@@ -1707,7 +1721,7 @@ public interface Client extends GameShell
|
||||
* Set spells excluded from above hiding
|
||||
*/
|
||||
void setUnhiddenCasts(Set<String> casts);
|
||||
|
||||
|
||||
/**
|
||||
* Sorts the current menu entries in the same way the client does this.
|
||||
* The last entry will be the left click one after this.
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.awt.Image;
|
||||
/**
|
||||
* Represents the clients primary image buffer.
|
||||
*/
|
||||
public interface MainBufferProvider
|
||||
public interface MainBufferProvider extends BufferProvider
|
||||
{
|
||||
/**
|
||||
* Gets the image currently loaded in the buffer.
|
||||
|
||||
@@ -102,9 +102,12 @@ public class ProjectileID
|
||||
public static final int HYDRA_LIGHTNING_2 = 1665;
|
||||
public static final int DRAKE_BREATH = 1637;
|
||||
|
||||
public static final int HUNLEFF_MAGE_ATTACK = 1707;
|
||||
public static final int HUNLEFF_CORRUPTED_MAGE_ATTACK = 1708;
|
||||
public static final int HUNLEFF_RANGE_ATTACK = 1711;
|
||||
public static final int HUNLEFF_CORRUPTED_RANGE_ATTACK = 1712;
|
||||
|
||||
public static final int HUNLLEF_MAGE_ATTACK = 1707;
|
||||
public static final int HUNLLEF_CORRUPTED_MAGE_ATTACK = 1708;
|
||||
public static final int HUNLLEF_RANGE_ATTACK = 1711;
|
||||
public static final int HUNLLEF_CORRUPTED_RANGE_ATTACK = 1712;
|
||||
public static final int HUNLLEF_PRAYER_ATTACK = 1713;
|
||||
public static final int HUNLLEF_CORRUPTED_PRAYER_ATTACK = 1714;
|
||||
|
||||
public static final int ZALCANO_PROJECTILE = 1728;
|
||||
}
|
||||
|
||||
@@ -692,7 +692,12 @@ public enum Varbits
|
||||
/**
|
||||
* 1 is true, 0 is false.
|
||||
*/
|
||||
GAUNTLET_FINAL_ROOM_ENTERED(9177);
|
||||
GAUNTLET_FINAL_ROOM_ENTERED(9177),
|
||||
|
||||
/**
|
||||
* 1 is true, 0 is false.
|
||||
*/
|
||||
GAUNTLET_ENTERED(9178);
|
||||
|
||||
/**
|
||||
* The raw varbit ID.
|
||||
|
||||
@@ -975,7 +975,7 @@ public class WidgetID
|
||||
static final int PVP_WIDGET_CONTAINER = 54; // OUTDATED?
|
||||
static final int SKULL = 56; // OUTDATED?
|
||||
static final int ATTACK_RANGE = 59; // OUTDATED?
|
||||
static final int BOUNTY_HUNTER_INFO = 19;
|
||||
static final int BOUNTY_HUNTER_INFO = 18;
|
||||
static final int KILLDEATH_RATIO = 15;
|
||||
static final int SKULL_CONTAINER = 61;
|
||||
static final int SAFE_ZONE = 63;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '5.1.0'
|
||||
id 'java'
|
||||
@@ -60,6 +63,23 @@ dependencies {
|
||||
compileOnly group: 'net.runelite', name: 'orange-extensions', version: '1.0'
|
||||
}
|
||||
|
||||
static def getDate() {
|
||||
return new SimpleDateFormat("MM-dd-yyyy", Locale.forLanguageTag("en-US")).format(new Date())
|
||||
}
|
||||
|
||||
def buildDate = getDate()
|
||||
|
||||
processResources {
|
||||
from file("src/main/resources/runelite.plus.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"project.version": project.version,
|
||||
"rs.version": rsversion.toString(),
|
||||
"runelite.plus.version": plusVersion.toString(),
|
||||
"runelite.plus.builddate": buildDate.toString()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(AbstractArchiveTask) {
|
||||
preserveFileTimestamps = false
|
||||
reproducibleFileOrder = true
|
||||
|
||||
@@ -24,18 +24,29 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.config.RuneLitePlusConfig;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class RuneLiteProperties
|
||||
{
|
||||
private static final String DISCORD_APP_ID_PLUS = "560644885250572289";
|
||||
private static final String RUNELITE_TITLE = "runelite.plus.title";
|
||||
private static final String RUNELITE_VERSION = "runelite.version";
|
||||
private static final String RUNELITE_PLUS_VERSION = "runelite.plus.version";
|
||||
private static final String RUNELITE_PLUS_DATE = "runelite.plus.builddate";
|
||||
private static final String RUNESCAPE_VERSION = "runescape.version";
|
||||
private static final String DISCORD_APP_ID = "runelite.plus.discord.appid";
|
||||
private static final String DISCORD_INVITE = "runelite.discord.invite";
|
||||
private static final String GITHUB_LINK = "runelite.github.link";
|
||||
private static final String WIKI_LINK = "runelite.wiki.link";
|
||||
private static final String PATREON_LINK = "runelite.patreon.link";
|
||||
private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version";
|
||||
|
||||
private final Properties properties = new Properties();
|
||||
|
||||
@@ -45,6 +56,15 @@ public class RuneLiteProperties
|
||||
public RuneLiteProperties(final RuneLitePlusConfig runeLiteConfig)
|
||||
{
|
||||
this.runeLitePlusConfig = runeLiteConfig;
|
||||
|
||||
try (InputStream in = getClass().getResourceAsStream("/runelite.plus.properties"))
|
||||
{
|
||||
properties.load(in);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("unable to load propertries", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public RuneLiteProperties()
|
||||
@@ -54,7 +74,7 @@ public class RuneLiteProperties
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
final StringBuilder sb = new StringBuilder("RuneLitePlus");
|
||||
final StringBuilder sb = new StringBuilder(properties.getProperty(RUNELITE_TITLE));
|
||||
String proxy;
|
||||
if ((proxy = System.getProperty("socksProxyHost")) != null)
|
||||
{
|
||||
@@ -65,41 +85,46 @@ public class RuneLiteProperties
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return RuneLiteAPI.getVersion();
|
||||
return properties.getProperty(RUNELITE_VERSION);
|
||||
}
|
||||
|
||||
public String getPlusVersion()
|
||||
{
|
||||
return RuneLite.PLUS_VERSION;
|
||||
return properties.getProperty(RUNELITE_PLUS_VERSION);
|
||||
}
|
||||
|
||||
public String getPlusDate()
|
||||
{
|
||||
return properties.getProperty(RUNELITE_PLUS_DATE);
|
||||
}
|
||||
|
||||
public String getRunescapeVersion()
|
||||
{
|
||||
return "" + RuneLiteAPI.getRsVersion();
|
||||
return properties.getProperty(RUNESCAPE_VERSION);
|
||||
}
|
||||
|
||||
public String getDiscordAppId()
|
||||
{
|
||||
return DISCORD_APP_ID_PLUS;
|
||||
return properties.getProperty(DISCORD_APP_ID);
|
||||
}
|
||||
|
||||
public String getDiscordInvite()
|
||||
{
|
||||
return "https://discord.gg/HN5gf3m";
|
||||
return properties.getProperty(DISCORD_INVITE);
|
||||
}
|
||||
|
||||
public String getGithubLink()
|
||||
{
|
||||
return "https://github.com/runelite-extended/runelite";
|
||||
return properties.getProperty(GITHUB_LINK);
|
||||
}
|
||||
|
||||
public String getWikiLink()
|
||||
{
|
||||
return "https://github.com/runelite-extended/runelite/wiki";
|
||||
return properties.getProperty(WIKI_LINK);
|
||||
}
|
||||
|
||||
public String getPatreonLink()
|
||||
{
|
||||
return "https://www.patreon.com/RuneLitePlus";
|
||||
return properties.getProperty(PATREON_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,31 @@ public class Hooks implements Callbacks
|
||||
private long lastCheck;
|
||||
private boolean shouldProcessGameTick;
|
||||
|
||||
private static MainBufferProvider lastMainBufferProvider;
|
||||
private static Graphics2D lastGraphics;
|
||||
|
||||
/**
|
||||
* Get the Graphics2D for the MainBufferProvider image
|
||||
* This caches the Graphics2D instance so it can be reused
|
||||
* @param mainBufferProvider
|
||||
* @return
|
||||
*/
|
||||
private static Graphics2D getGraphics(MainBufferProvider mainBufferProvider)
|
||||
{
|
||||
if (lastGraphics == null || lastMainBufferProvider != mainBufferProvider)
|
||||
{
|
||||
if (lastGraphics != null)
|
||||
{
|
||||
log.debug("Graphics reset!");
|
||||
lastGraphics.dispose();
|
||||
}
|
||||
|
||||
lastMainBufferProvider = mainBufferProvider;
|
||||
lastGraphics = (Graphics2D) mainBufferProvider.getImage().getGraphics();
|
||||
}
|
||||
return lastGraphics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void post(Class<T> eventClass, Event event)
|
||||
{
|
||||
@@ -293,9 +318,7 @@ public class Hooks implements Callbacks
|
||||
return;
|
||||
}
|
||||
|
||||
Image image = mainBufferProvider.getImage();
|
||||
final Image finalImage;
|
||||
final Graphics2D graphics2d = (Graphics2D) image.getGraphics();
|
||||
final Graphics2D graphics2d = getGraphics(mainBufferProvider);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -311,8 +334,6 @@ public class Hooks implements Callbacks
|
||||
// Draw clientUI overlays
|
||||
clientUi.paintOverlays(graphics2d);
|
||||
|
||||
graphics2d.dispose();
|
||||
|
||||
if (client.isGpu())
|
||||
{
|
||||
// processDrawComplete gets called on GPU by the gpu plugin at the end of its
|
||||
@@ -321,6 +342,8 @@ public class Hooks implements Callbacks
|
||||
}
|
||||
|
||||
// Stretch the game image if the user has that enabled
|
||||
Image image = mainBufferProvider.getImage();
|
||||
final Image finalImage;
|
||||
if (client.isStretchedEnabled())
|
||||
{
|
||||
GraphicsConfiguration gc = clientUi.getGraphicsConfiguration();
|
||||
@@ -388,8 +411,7 @@ public class Hooks implements Callbacks
|
||||
public void drawScene()
|
||||
{
|
||||
MainBufferProvider bufferProvider = (MainBufferProvider) client.getBufferProvider();
|
||||
BufferedImage image = (BufferedImage) bufferProvider.getImage();
|
||||
Graphics2D graphics2d = image.createGraphics();
|
||||
Graphics2D graphics2d = getGraphics(bufferProvider);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -399,18 +421,13 @@ public class Hooks implements Callbacks
|
||||
{
|
||||
log.warn("Error during overlay rendering", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
graphics2d.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawAboveOverheads()
|
||||
{
|
||||
MainBufferProvider bufferProvider = (MainBufferProvider) client.getBufferProvider();
|
||||
BufferedImage image = (BufferedImage) bufferProvider.getImage();
|
||||
Graphics2D graphics2d = image.createGraphics();
|
||||
Graphics2D graphics2d = getGraphics(bufferProvider);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -420,17 +437,12 @@ public class Hooks implements Callbacks
|
||||
{
|
||||
log.warn("Error during overlay rendering", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
graphics2d.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawAfterWidgets()
|
||||
{
|
||||
MainBufferProvider bufferProvider = (MainBufferProvider) client.getBufferProvider();
|
||||
BufferedImage image = (BufferedImage) bufferProvider.getImage();
|
||||
Graphics2D graphics2d = image.createGraphics();
|
||||
Graphics2D graphics2d = getGraphics(bufferProvider);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -441,10 +453,6 @@ public class Hooks implements Callbacks
|
||||
{
|
||||
log.warn("Error during overlay rendering", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
graphics2d.dispose();
|
||||
}
|
||||
|
||||
// WidgetItemOverlays render at ABOVE_WIDGETS, reset widget item
|
||||
// list for next frame.
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.io.File;
|
||||
@@ -66,7 +65,6 @@ import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.client.RuneLite;
|
||||
import static net.runelite.client.RuneLite.PROFILES_DIR;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@Singleton
|
||||
@@ -508,10 +506,6 @@ public class ConfigManager
|
||||
{
|
||||
return Enum.valueOf((Class<? extends Enum>) type, str);
|
||||
}
|
||||
if (type == Font.class)
|
||||
{
|
||||
return FontManager.getFontOrDefault(FontManager.lookupFont(str));
|
||||
}
|
||||
if (type == Instant.class)
|
||||
{
|
||||
return Instant.parse(str);
|
||||
@@ -568,10 +562,6 @@ public class ConfigManager
|
||||
{
|
||||
return ((Enum) object).name();
|
||||
}
|
||||
if (object instanceof Font)
|
||||
{
|
||||
return FontManager.getFontName((Font)object);
|
||||
}
|
||||
if (object instanceof Dimension)
|
||||
{
|
||||
Dimension d = (Dimension) object;
|
||||
|
||||
@@ -24,18 +24,21 @@
|
||||
*/
|
||||
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"),
|
||||
BOLD("Bold"),
|
||||
SMALL("Small");
|
||||
REGULAR("Regular", FontManager.getRunescapeFont()),
|
||||
BOLD("Bold", FontManager.getRunescapeBoldFont()),
|
||||
SMALL("Small", FontManager.getRunescapeSmallFont());
|
||||
|
||||
private final String name;
|
||||
private final Font font;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
|
||||
@@ -66,7 +66,8 @@ public enum ItemMapping
|
||||
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_PICKAXE(DRAGON_PICKAXE, DRAGON_PICKAXE_12797, DRAGON_PICKAXEOR),
|
||||
ITEM_DRAGON_PICKAXE_OR(ZALCANO_SHARD, DRAGON_PICKAXEOR),
|
||||
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),
|
||||
@@ -214,7 +215,17 @@ public enum ItemMapping
|
||||
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);
|
||||
ITEM_BOTTOMLESS_COMPOST_BUCKET(BOTTOMLESS_COMPOST_BUCKET, BOTTOMLESS_COMPOST_BUCKET_22997),
|
||||
|
||||
// Crystal items
|
||||
ITEM_CRYSTAL_TOOL_SEED(CRYSTAL_TOOL_SEED, CRYSTAL_AXE, CRYSTAL_AXE_INACTIVE, CRYSTAL_HARPOON, CRYSTAL_HARPOON_INACTIVE, CRYSTAL_PICKAXE, CRYSTAL_PICKAXE_INACTIVE),
|
||||
ITEM_CRYSTAL_AXE(DRAGON_AXE, CRYSTAL_AXE, CRYSTAL_AXE_INACTIVE),
|
||||
ITEM_CRYSTAL_HARPOON(DRAGON_HARPOON, CRYSTAL_HARPOON, CRYSTAL_HARPOON_INACTIVE),
|
||||
ITEM_CRYSTAL_PICKAXE(DRAGON_PICKAXE, CRYSTAL_PICKAXE, CRYSTAL_PICKAXE_INACTIVE),
|
||||
ITEM_BLADE_OF_SAELDOR(BLADE_OF_SAELDOR_INACTIVE, BLADE_OF_SAELDOR),
|
||||
ITEM_CRYSTAL_BOW(CRYSTAL_WEAPON_SEED, CRYSTAL_BOW, CRYSTAL_BOW_INACTIVE),
|
||||
ITEM_CRYSTAL_HALBERD(CRYSTAL_WEAPON_SEED, CRYSTAL_HALBERD, CRYSTAL_HALBERD_INACTIVE),
|
||||
ITEM_CRYSTAL_SHIELD(CRYSTAL_WEAPON_SEED, CRYSTAL_SHIELD, CRYSTAL_SHIELD_INACTIVE);
|
||||
|
||||
private static final Multimap<Integer, Integer> MAPPINGS = HashMultimap.create();
|
||||
private final int tradeableItem;
|
||||
|
||||
@@ -46,7 +46,14 @@ public enum UntradeableItemMapping
|
||||
PROSPECTOR_HELMET(ItemID.PROSPECTOR_HELMET, 32, ItemID.GOLDEN_NUGGET),
|
||||
PROSPECTOR_JACKET(ItemID.PROSPECTOR_JACKET, 48, ItemID.GOLDEN_NUGGET),
|
||||
PROSPECTOR_LEGS(ItemID.PROSPECTOR_LEGS, 40, ItemID.GOLDEN_NUGGET),
|
||||
PROSPECTOR_BOOTS(ItemID.PROSPECTOR_BOOTS, 24, ItemID.GOLDEN_NUGGET);
|
||||
PROSPECTOR_BOOTS(ItemID.PROSPECTOR_BOOTS, 24, ItemID.GOLDEN_NUGGET),
|
||||
|
||||
CRYSTAL_HELMET(ItemID.CRYSTAL_HELM, 1, ItemID.CRYSTAL_ARMOUR_SEED),
|
||||
CRYSTAL_HELMET_INACTIVE(ItemID.CRYSTAL_HELM_INACTIVE, 1, ItemID.CRYSTAL_ARMOUR_SEED),
|
||||
CRYSTAL_LEGS(ItemID.CRYSTAL_LEGS, 2, ItemID.CRYSTAL_ARMOUR_SEED),
|
||||
CRYSTAL_LEGS_INACTIVE(ItemID.CRYSTAL_LEGS_INACTIVE, 2, ItemID.CRYSTAL_ARMOUR_SEED),
|
||||
CRYSTAL_BODY(ItemID.CRYSTAL_BODY, 3, ItemID.CRYSTAL_ARMOUR_SEED),
|
||||
CRYSTAL_BODY_INACTIVE(ItemID.CRYSTAL_BODY_INACTIVE, 3, ItemID.CRYSTAL_ARMOUR_SEED);
|
||||
|
||||
private static final ImmutableMap<Integer, UntradeableItemMapping> UNTRADEABLE_RECLAIM_MAP;
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ public enum WorldLocation
|
||||
s = entry.getValue();
|
||||
return s;
|
||||
}
|
||||
int distTo = worldArea.distanceTo(worldArea);
|
||||
int distTo = worldArea.distanceTo(worldPoint);
|
||||
if (distTo < dist)
|
||||
{
|
||||
dist = distTo;
|
||||
|
||||
@@ -37,13 +37,13 @@ import net.runelite.api.Client;
|
||||
import net.runelite.api.DecorativeObject;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GroundObject;
|
||||
import net.runelite.api.TileItemPile;
|
||||
import net.runelite.api.MainBufferProvider;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.TileItemPile;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
@@ -968,7 +968,7 @@ public class ModelOutlineRenderer
|
||||
}
|
||||
}
|
||||
|
||||
private void drawOutline(GameObject gameObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
public void drawOutline(GameObject gameObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
{
|
||||
LocalPoint lp = gameObject.getLocalLocation();
|
||||
if (lp != null)
|
||||
@@ -979,7 +979,7 @@ public class ModelOutlineRenderer
|
||||
}
|
||||
}
|
||||
|
||||
private void drawOutline(GroundObject groundObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
public void drawOutline(GroundObject groundObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
{
|
||||
LocalPoint lp = groundObject.getLocalLocation();
|
||||
if (lp != null)
|
||||
|
||||
@@ -39,7 +39,7 @@ enum Boss
|
||||
KREEARRA(NpcID.KREEARRA, 90, ChronoUnit.SECONDS, ItemID.PET_KREEARRA),
|
||||
COMMANDER_ZILYANA(NpcID.COMMANDER_ZILYANA, 90, ChronoUnit.SECONDS, ItemID.PET_ZILYANA),
|
||||
CALLISTO(NpcID.CALLISTO_6609, 30, ChronoUnit.SECONDS, ItemID.CALLISTO_CUB),
|
||||
CHAOS_ELEMENTAL(NpcID.CHAOS_ELEMENTAL, 150, ChronoUnit.SECONDS, ItemID.PET_CHAOS_ELEMENTAL),
|
||||
CHAOS_ELEMENTAL(NpcID.CHAOS_ELEMENTAL, 60, ChronoUnit.SECONDS, ItemID.PET_CHAOS_ELEMENTAL),
|
||||
CHAOS_FANATIC(NpcID.CHAOS_FANATIC, 30, ChronoUnit.SECONDS, ItemID.ANCIENT_STAFF),
|
||||
CRAZY_ARCHAEOLOGIST(NpcID.CRAZY_ARCHAEOLOGIST, 30, ChronoUnit.SECONDS, ItemID.FEDORA),
|
||||
KING_BLACK_DRAGON(NpcID.KING_BLACK_DRAGON, 9, ChronoUnit.SECONDS, ItemID.PRINCE_BLACK_DRAGON),
|
||||
|
||||
@@ -27,7 +27,6 @@ package net.runelite.client.plugins.cannon;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -52,7 +51,7 @@ import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.api.events.ProjectileSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
@@ -60,7 +59,6 @@ import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ItemUtil;
|
||||
@@ -77,57 +75,39 @@ public class CannonPlugin extends Plugin
|
||||
private static final ImmutableSet<Integer> CANNON_PARTS = ImmutableSet.of(
|
||||
ItemID.CANNON_BASE, ItemID.CANNON_STAND, ItemID.CANNON_BARRELS, ItemID.CANNON_FURNACE
|
||||
);
|
||||
|
||||
private CannonCounter counter;
|
||||
private boolean skipProjectileCheckThisTick;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int cballsLeft;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean cannonPlaced;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private WorldPoint cannonPosition;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private GameObject cannon;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> spotPoints = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private CannonOverlay cannonOverlay;
|
||||
|
||||
@Inject
|
||||
private CannonSpotOverlay cannonSpotOverlay;
|
||||
|
||||
@Inject
|
||||
private CannonConfig config;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private EventBus eventbus;
|
||||
|
||||
private boolean lock;
|
||||
|
||||
private boolean showEmptyCannonNotification;
|
||||
private boolean showInfobox;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@@ -178,7 +158,7 @@ public class CannonPlugin extends Plugin
|
||||
eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventbus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged);
|
||||
eventbus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned);
|
||||
eventbus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved);
|
||||
eventbus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
eventbus.subscribe(ChatMessage.class, this, this::onChatMessage);
|
||||
eventbus.subscribe(GameTick.class, this, this::onGameTick);
|
||||
}
|
||||
@@ -211,37 +191,13 @@ public class CannonPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Schedule(
|
||||
period = 1,
|
||||
unit = ChronoUnit.SECONDS
|
||||
)
|
||||
public void checkSpots()
|
||||
{
|
||||
if (!this.showCannonSpots)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
spotPoints.clear();
|
||||
for (WorldPoint spot : CannonSpots.getCannonSpots())
|
||||
{
|
||||
if (spot.getPlane() != client.getPlane() || !spot.isInScene(client))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spotPoints.add(spot);
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
|
||||
Player localPlayer = client.getLocalPlayer();
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
if (gameObject.getId() == CANNON_BASE && !cannonPlaced &&
|
||||
localPlayer.getWorldLocation().distanceTo(gameObject.getWorldLocation()) <= 2 &&
|
||||
localPlayer.getAnimation() == AnimationID.BURYING_BONES)
|
||||
@@ -251,22 +207,15 @@ public class CannonPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void onProjectileMoved(ProjectileMoved event)
|
||||
private void onProjectileSpawned(ProjectileSpawned event)
|
||||
{
|
||||
Projectile projectile = event.getProjectile();
|
||||
final Projectile projectile = event.getProjectile();
|
||||
|
||||
if ((projectile.getId() == CANNONBALL || projectile.getId() == GRANITE_CANNONBALL) && cannonPosition != null)
|
||||
{
|
||||
WorldPoint projectileLoc = WorldPoint.fromLocal(client, projectile.getX1(), projectile.getY1(), client.getPlane());
|
||||
final WorldPoint projectileLoc = WorldPoint.fromLocal(client, projectile.getX1(), projectile.getY1(), client.getPlane());
|
||||
|
||||
//Check to see if projectile x,y is 0 else it will continuously decrease while ball is flying.
|
||||
if (projectileLoc.equals(cannonPosition) && projectile.getX() == 0 && projectile.getY() == 0 &&
|
||||
// When there's a chat message about cannon reloaded/unloaded/out of ammo,
|
||||
// the message event runs before the projectile event. However they run
|
||||
// in the opposite order on the server. So if both fires in the same tick,
|
||||
// we don't want to update the cannonball counter if it was set to a specific
|
||||
// amount.
|
||||
!skipProjectileCheckThisTick)
|
||||
if (projectileLoc.equals(cannonPosition) && !skipProjectileCheckThisTick)
|
||||
{
|
||||
cballsLeft--;
|
||||
}
|
||||
|
||||
@@ -87,12 +87,12 @@ import org.apache.commons.text.WordUtils;
|
||||
@Slf4j
|
||||
public class ChatCommandsPlugin extends Plugin
|
||||
{
|
||||
private static final Pattern KILLCOUNT_PATTERN = Pattern.compile("Your (.+) (?:kill|harvest|lap) count is: <col=ff0000>(\\d+)</col>");
|
||||
private static final Pattern KILLCOUNT_PATTERN = Pattern.compile("Your (.+) (?:kill|harvest|lap|completion) count is: <col=ff0000>(\\d+)</col>");
|
||||
private static final Pattern RAIDS_PATTERN = Pattern.compile("Your completed (.+) count is: <col=ff0000>(\\d+)</col>");
|
||||
private static final Pattern WINTERTODT_PATTERN = Pattern.compile("Your subdued Wintertodt count is: <col=ff0000>(\\d+)</col>");
|
||||
private static final Pattern BARROWS_PATTERN = Pattern.compile("Your Barrows chest count is: <col=ff0000>(\\d+)</col>");
|
||||
private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?:Fight|Lap) duration: <col=ff0000>[0-9:]+</col>. Personal best: ([0-9:]+)");
|
||||
private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?:Fight|Lap) duration: <col=ff0000>([0-9:]+)</col> \\(new personal best\\)");
|
||||
private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: <col=ff0000>[0-9:]+</col>\\. Personal best: ([0-9:]+)");
|
||||
private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: <col=ff0000>([0-9:]+)</col> \\(new personal best\\)");
|
||||
private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?");
|
||||
private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?");
|
||||
private static final String TOTAL_LEVEL_COMMAND_STRING = "!total";
|
||||
@@ -113,6 +113,7 @@ public class ChatCommandsPlugin extends Plugin
|
||||
private boolean logKills;
|
||||
private HiscoreEndpoint hiscoreEndpoint; // hiscore endpoint for current player
|
||||
private String lastBossKill;
|
||||
private int lastPb = -1;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
@@ -244,7 +245,17 @@ public class ChatCommandsPlugin extends Plugin
|
||||
int kc = Integer.parseInt(matcher.group(2));
|
||||
|
||||
setKc(boss, kc);
|
||||
lastBossKill = boss;
|
||||
// We either already have the pb, or need to remember the boss for the upcoming pb
|
||||
if (lastPb > -1)
|
||||
{
|
||||
log.debug("Got out-of-order personal best for {}: {}", boss, lastPb);
|
||||
setPb(boss, lastPb);
|
||||
lastPb = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastBossKill = boss;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -312,19 +323,16 @@ public class ChatCommandsPlugin extends Plugin
|
||||
setKc("Barrows Chests", kc);
|
||||
}
|
||||
|
||||
if (lastBossKill != null)
|
||||
matcher = KILL_DURATION_PATTERN.matcher(message);
|
||||
if (matcher.find())
|
||||
{
|
||||
matcher = KILL_DURATION_PATTERN.matcher(message);
|
||||
if (matcher.find())
|
||||
{
|
||||
matchPb(matcher);
|
||||
}
|
||||
matchPb(matcher);
|
||||
}
|
||||
|
||||
matcher = NEW_PB_PATTERN.matcher(message);
|
||||
if (matcher.find())
|
||||
{
|
||||
matchPb(matcher);
|
||||
}
|
||||
matcher = NEW_PB_PATTERN.matcher(message);
|
||||
if (matcher.find())
|
||||
{
|
||||
matchPb(matcher);
|
||||
}
|
||||
|
||||
lastBossKill = null;
|
||||
@@ -337,8 +345,19 @@ public class ChatCommandsPlugin extends Plugin
|
||||
if (s.length == 2)
|
||||
{
|
||||
int seconds = Integer.parseInt(s[0]) * 60 + Integer.parseInt(s[1]);
|
||||
log.debug("Got personal best for {}: {}", lastBossKill, seconds);
|
||||
setPb(lastBossKill, seconds);
|
||||
if (lastBossKill != null)
|
||||
{
|
||||
// Most bosses sent boss kill message, and then pb message, so we
|
||||
// use the remembered lastBossKill
|
||||
log.debug("Got personal best for {}: {}", lastBossKill, seconds);
|
||||
setPb(lastBossKill, seconds);
|
||||
lastPb = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some bosses send the pb message, and then the kill message!
|
||||
lastPb = seconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1382,6 +1401,16 @@ public class ChatCommandsPlugin extends Plugin
|
||||
case "prifddinas":
|
||||
return "Prifddinas Agility Course";
|
||||
|
||||
// The Gauntlet
|
||||
case "gaunt":
|
||||
case "gauntlet":
|
||||
return "Gauntlet";
|
||||
|
||||
// Corrupted Gauntlet
|
||||
case "cgaunt":
|
||||
case "cgauntlet":
|
||||
return "Corrupted Gauntlet";
|
||||
|
||||
default:
|
||||
return WordUtils.capitalize(boss);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
|
||||
new EmoteClue("Cry in the Catherby Ranging shop. Bow before you talk to me. Equip blue gnome boots, a hard leather body and an unblessed silver sickle.", "Catherby", HICKTONS_ARCHERY_EMPORIUM, new WorldPoint(2823, 3443, 0), CRY, BOW, item(BLUE_BOOTS), item(HARDLEATHER_BODY), item(SILVER_SICKLE)),
|
||||
new EmoteClue("Cry on the shore of Catherby beach. Laugh before you talk to me, equip an adamant sq shield, a bone dagger and mithril platebody.", "Catherby", OUTSIDE_HARRYS_FISHING_SHOP_IN_CATHERBY, new WorldPoint(2852, 3429, 0), CRY, LAUGH, item(ADAMANT_SQ_SHIELD), item(BONE_DAGGER), item(MITHRIL_PLATEBODY)),
|
||||
new EmoteClue("Cry on top of the western tree in the Gnome Agility Arena. Indicate 'no' before you talk to me. Equip a steel kiteshield, ring of forging and green dragonhide chaps.", "Gnome Stronghold", GNOME_STRONGHOLD_BALANCING_ROPE, new WorldPoint(2473, 3420, 2), CRY, NO, item(STEEL_KITESHIELD), item(RING_OF_FORGING), item(GREEN_DHIDE_CHAPS)),
|
||||
new EmoteClue("Cry in the TzHaar gem store. Beware of double agents! Equip a fire cape and TokTz-Xil-Ul.", "Tzhaar gem store", TZHAAR_GEM_STORE, new WorldPoint(2463, 5149, 0), CRY, any("Fire cape", item(FIRE_CAPE), item(FIRE_MAX_CAPE)), item(TOKTZXILUL)),
|
||||
new EmoteClue("Cry in the TzHaar gem store. Beware of double agents! Equip a fire cape and TokTz-Xil-Ul.", "Tzhaar gem store", TZHAAR_GEM_STORE, new WorldPoint(2463, 5149, 0), CRY, any("Fire cape", item(FIRE_CAPE), item(FIRE_MAX_CAPE), item(INFERNAL_CAPE), item(INFERNAL_MAX_CAPE)), item(TOKTZXILUL)),
|
||||
new EmoteClue("Cry in the Draynor Village jail. Jump for joy before you talk to me. Equip an adamant sword, a sapphire amulet and an adamant plateskirt.", "Draynor Village jail", OUTSIDE_DRAYNOR_VILLAGE_JAIL, new WorldPoint(3128, 3245, 0), CRY, JUMP_FOR_JOY, item(ADAMANT_SWORD), item(SAPPHIRE_AMULET), item(ADAMANT_PLATESKIRT)),
|
||||
new EmoteClue("Dance at the crossroads north of Draynor. Equip an iron chain body, a sapphire ring and a longbow.", "Draynor Village", CROSSROADS_NORTH_OF_DRAYNOR_VILLAGE, new WorldPoint(3109, 3294, 0), DANCE, item(IRON_CHAINBODY), item(SAPPHIRE_RING), item(LONGBOW)),
|
||||
new EmoteClue("Dance in the Party Room. Equip a steel full helmet, steel platebody and an iron plateskirt.", "Falador Party Room", OUTSIDE_THE_FALADOR_PARTY_ROOM, new WorldPoint(3045, 3376, 0), DANCE, item(STEEL_FULL_HELM), item(STEEL_PLATEBODY), item(IRON_PLATESKIRT)),
|
||||
@@ -155,7 +155,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
|
||||
new EmoteClue("Slap your head in the centre of the Kourend catacombs. Beware of double agents! Equip the arclight and the amulet of the damned.", "Kourend catacombs", CENTRE_OF_THE_CATACOMBS_OF_KOUREND, new WorldPoint(1663, 10045, 0), SLAP_HEAD, item(ARCLIGHT), any("Amulet of the damned", item(AMULET_OF_THE_DAMNED), item(AMULET_OF_THE_DAMNED_FULL))),
|
||||
new EmoteClue("Spin at the crossroads north of Rimmington. Equip a green gnome hat, cream gnome top and leather chaps.", "Rimmington", ROAD_JUNCTION_NORTH_OF_RIMMINGTON, new WorldPoint(2981, 3276, 0), SPIN, item(GREEN_HAT), item(CREAM_ROBE_TOP), item(LEATHER_CHAPS)),
|
||||
new EmoteClue("Spin in Draynor Manor by the fountain. Equip an iron platebody, studded leather chaps and a bronze full helmet.", "Draynor Manor", DRAYNOR_MANOR_BY_THE_FOUNTAIN, new WorldPoint(3088, 3336, 0), SPIN, item(IRON_PLATEBODY), item(STUDDED_CHAPS), item(BRONZE_FULL_HELM)),
|
||||
new EmoteClue("Spin in front of the Soul altar. Beware of double agents! Equip a dragon pickaxe, helm of neitiznot and a pair of rune boots.", "Soul altar", SOUL_ALTAR, new WorldPoint(1815, 3856, 0), SPIN, any("Dragon pickaxe", item(DRAGON_PICKAXE), item(DRAGON_PICKAXE_12797), item(INFERNAL_PICKAXE), item(INFERNAL_PICKAXE_UNCHARGED)), item(HELM_OF_NEITIZNOT), item(RUNE_BOOTS)),
|
||||
new EmoteClue("Spin in front of the Soul altar. Beware of double agents! Equip a dragon pickaxe, helm of neitiznot and a pair of rune boots.", "Soul altar", SOUL_ALTAR, new WorldPoint(1815, 3856, 0), SPIN, any("Dragon pickaxe", item(DRAGON_PICKAXE), item(DRAGON_PICKAXE_12797), item(INFERNAL_PICKAXE), item(INFERNAL_PICKAXE_UNCHARGED), item(DRAGON_PICKAXEOR)), item(HELM_OF_NEITIZNOT), item(RUNE_BOOTS)),
|
||||
new EmoteClue("Spin in the Varrock Castle courtyard. Equip a black axe, a coif and a ruby ring.", "Varrock Castle", OUTSIDE_VARROCK_PALACE_COURTYARD, new WorldPoint(3213, 3463, 0), SPIN, item(BLACK_AXE), item(COIF), item(RUBY_RING)),
|
||||
new EmoteClue("Spin in West Ardougne Church. Equip a dragon spear and red dragonhide chaps.", "Ardougne", CHAPEL_IN_WEST_ARDOUGNE, new WorldPoint(2530, 3290, 0), SPIN, item(DRAGON_SPEAR), item(RED_DHIDE_CHAPS)),
|
||||
new EmoteClue("Spin on the bridge by the Barbarian Village. Salute before you talk to me. Equip purple gloves, a steel kiteshield and a mithril full helmet.", "Barbarian Village", EAST_OF_THE_BARBARIAN_VILLAGE_BRIDGE, new WorldPoint(3105, 3420, 0), SPIN, SALUTE, item(PURPLE_GLOVES), item(STEEL_KITESHIELD), item(MITHRIL_FULL_HELM)),
|
||||
|
||||
@@ -153,12 +153,12 @@ public enum HotColdLocation
|
||||
WILDERNESS_32(new WorldPoint(3311, 3773, 0), WILDERNESS, "North of Venenatis' nest, level 32 Wilderness."),
|
||||
WILDERNESS_35(new WorldPoint(3153, 3795, 0), WILDERNESS, "East of the Wilderness canoe exit, level 35 Wilderness."),
|
||||
WILDERNESS_37(new WorldPoint(2975, 3811, 0), WILDERNESS, "South-east of the Chaos Temple, level 37 Wilderness."),
|
||||
WILDERNESS_38(new WorldPoint(3294, 3817, 0), WILDERNESS, "South of Callisto, level 38 Wilderness."),
|
||||
WILDERNESS_38(new WorldPoint(3293, 3813, 0), WILDERNESS, "South of Callisto, level 38 Wilderness."),
|
||||
WILDERNESS_49(new WorldPoint(3140, 3910, 0), WILDERNESS, "South-west of the Deserted Keep, level 49 Wilderness."),
|
||||
WILDERNESS_54(new WorldPoint(2983, 3946, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness."),
|
||||
ZEAH_BLASTMINE_BANK(new WorldPoint(1507, 3856, 0), ZEAH, "Next to the bank in the Lovakengj blast mine."),
|
||||
ZEAH_BLASTMINE_NORTH(new WorldPoint(1490, 3883, 0), ZEAH, "Northern part of the Lovakengj blast mine."),
|
||||
ZEAH_LOVAKITE_FURNACE(new WorldPoint(1505, 3814, 0), ZEAH, "Next to the lovakite furnace in Lovakengj."),
|
||||
ZEAH_LOVAKITE_FURNACE(new WorldPoint(1507, 3819, 0), ZEAH, "Next to the lovakite furnace in Lovakengj."),
|
||||
ZEAH_LOVAKENGJ_MINE(new WorldPoint(1477, 3779, 0), ZEAH, "Next to mithril rock in the Lovakengj mine."),
|
||||
ZEAH_SULPHR_MINE(new WorldPoint(1428, 3866, 0), ZEAH, "Western entrance in the Lovakengj sulphur mine."),
|
||||
ZEAH_SHAYZIEN_BANK(new WorldPoint(1517, 3603, 0), ZEAH, "South-east of the bank in Shayzien."),
|
||||
|
||||
@@ -30,7 +30,6 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
@@ -101,7 +100,6 @@ import net.runelite.client.plugins.PluginManager;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.DynamicGridLayout;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.components.ComboBoxListRenderer;
|
||||
import net.runelite.client.ui.components.IconButton;
|
||||
@@ -1017,37 +1015,6 @@ public class ConfigPanel extends PluginPanel
|
||||
|
||||
item.add(button, BorderLayout.EAST);
|
||||
}
|
||||
|
||||
if (cid.getType() == Font.class)
|
||||
{
|
||||
JComboBox box = new JComboBox(FontManager.getAvailableFontNames());
|
||||
box.setPreferredSize(new Dimension(150, 25));
|
||||
box.setRenderer(new ComboBoxListRenderer());
|
||||
box.setForeground(Color.WHITE);
|
||||
box.setFocusable(false);
|
||||
String currentlyConfigured = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName());
|
||||
if (FontManager.lookupFont(currentlyConfigured) != null)
|
||||
{
|
||||
box.setSelectedItem(currentlyConfigured);
|
||||
box.setToolTipText(currentlyConfigured);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Selected font wasn't found on this system, resetting font back to runescape regular");
|
||||
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), FontManager.getRunescapeFont());
|
||||
}
|
||||
box.addItemListener(e ->
|
||||
{
|
||||
if (e.getStateChange() == ItemEvent.SELECTED && box.getSelectedItem() != null)
|
||||
{
|
||||
final Font selected = FontManager.lookupFont(box.getSelectedItem().toString());
|
||||
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), selected);
|
||||
box.setToolTipText(box.getSelectedItem().toString());
|
||||
}
|
||||
});
|
||||
item.add(box, BorderLayout.EAST);
|
||||
}
|
||||
|
||||
mainPanel.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public class CoxInfoBox extends Overlay
|
||||
if (System.currentTimeMillis() < (plugin.getLastPrayTime() + 120000) && plugin.getPrayAgainstOlm() != null)
|
||||
{
|
||||
InfoBoxComponent prayComponent = new InfoBoxComponent();
|
||||
BufferedImage prayImg = scaleImg(getPrayerImage(plugin.prayAgainstOlm));
|
||||
BufferedImage prayImg = scaleImg(getPrayerImage(plugin.getPrayAgainstOlm()));
|
||||
prayComponent.setImage(prayImg);
|
||||
prayComponent.setColor(Color.WHITE);
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(prayAgainst.getPrayer())
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package net.runelite.client.plugins.coxhelper;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
@@ -32,6 +33,7 @@ import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Actor;
|
||||
@@ -53,6 +55,9 @@ import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
@Singleton
|
||||
public class CoxOverlay extends Overlay
|
||||
{
|
||||
private static final Set<Integer> GAP = ImmutableSet.of(
|
||||
34, 33, 26, 25, 18, 17, 10, 9, 2, 1
|
||||
);
|
||||
private final Client client;
|
||||
private final CoxPlugin plugin;
|
||||
|
||||
@@ -105,7 +110,6 @@ public class CoxOverlay extends Overlay
|
||||
if (plugin.isTektonTickCounter())
|
||||
{
|
||||
ticksLeft = npcs.getTicksUntilAttack();
|
||||
int attackTicksleft = plugin.getTektonAttackTicks();
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
@@ -214,67 +218,67 @@ public class CoxOverlay extends Overlay
|
||||
|
||||
if (plugin.isTimers())
|
||||
{
|
||||
if (plugin.getBurnTarget().size() > 0)
|
||||
if (plugin.getVictims().size() > 0)
|
||||
{
|
||||
for (Actor actor : plugin.getBurnTarget())
|
||||
plugin.getVictims().forEach(victim ->
|
||||
{
|
||||
final int ticksLeft = plugin.getBurnTicks();
|
||||
final int ticksLeft = victim.getTicks();
|
||||
String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Color tickcolor;
|
||||
if (ticksLeft >= 0)
|
||||
switch (victim.getType())
|
||||
{
|
||||
if (ticksLeft == 34 ||
|
||||
ticksLeft == 33 ||
|
||||
ticksLeft == 26 ||
|
||||
ticksLeft == 25 ||
|
||||
ticksLeft == 18 ||
|
||||
ticksLeft == 17 ||
|
||||
ticksLeft == 10 ||
|
||||
ticksLeft == 9 ||
|
||||
ticksLeft == 2 ||
|
||||
ticksLeft == 1)
|
||||
{
|
||||
tickcolor = new Color(255, 0, 0, 255);
|
||||
ticksLeftStr = "GAP";
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
Point canvasPoint = actor.getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, plugin.getTextSize(), plugin.getFontStyle().getFont(), tickcolor, canvasPoint);
|
||||
case ACID:
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft > 1)
|
||||
{
|
||||
tickcolor = new Color(69, 241, 44, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
Point canvasPoint = victim.getPlayer().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, plugin.getTextSize(), plugin.getFontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
break;
|
||||
case BURN:
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (GAP.contains(ticksLeft))
|
||||
{
|
||||
tickcolor = new Color(255, 0, 0, 255);
|
||||
ticksLeftStr = "GAP";
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
Point canvasPoint = victim.getPlayer().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, plugin.getTextSize(), plugin.getFontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
break;
|
||||
case TELEPORT:
|
||||
if (plugin.isTpOverlay())
|
||||
{
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft > 1)
|
||||
{
|
||||
tickcolor = new Color(193, 255, 245, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
Point canvasPoint = victim.getPlayer().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, plugin.getTextSize(), plugin.getFontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
renderActorOverlay(graphics, victim.getPlayer(), new Color(193, 255, 245, 255), 2, 100, 10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.getAcidTarget() != null)
|
||||
{
|
||||
Actor actor = plugin.getAcidTarget();
|
||||
renderActorOverlay(graphics, actor, plugin.getAcidColor(), 2, 100, 10);
|
||||
final int ticksLeft = plugin.getAcidTicks();
|
||||
Color tickcolor;
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft > 1)
|
||||
{
|
||||
tickcolor = new Color(69, 241, 44, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = actor.getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, plugin.getTextSize(), plugin.getFontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.isTpOverlay())
|
||||
{
|
||||
if (plugin.getTeleportTarget() != null)
|
||||
{
|
||||
renderActorOverlay(graphics, plugin.getTeleportTarget(), new Color(193, 255, 245, 255), 2, 100, 10);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,10 @@ import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
@@ -59,7 +61,7 @@ import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.api.events.ProjectileSpawned;
|
||||
import net.runelite.api.events.SpotAnimationChanged;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
@@ -80,123 +82,77 @@ import net.runelite.client.util.Text;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
public class CoxPlugin extends Plugin
|
||||
{
|
||||
private static final int ANIMATION_ID_G1 = 430;
|
||||
private static final String OLM_HAND_CRIPPLE = "The Great Olm\'s left claw clenches to protect itself temporarily.";
|
||||
private static final Pattern TP_REGEX = Pattern.compile("You have been paired with <col=ff0000>(.*)</col>! The magical power will enact soon...");
|
||||
@Setter
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
protected PrayAgainst prayAgainstOlm;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
protected long lastPrayTime;
|
||||
private int sleepcount = 0;
|
||||
private boolean needOlm = false;
|
||||
private GraphicsObject teleportObject;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private Client client;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private ChatMessageManager chatMessageManager;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private CoxOverlay coxOverlay;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private CoxInfoBox coxInfoBox;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private CoxConfig config;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private OverlayManager overlayManager;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private EventBus eventBus;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean HandCripple;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean handCripple;
|
||||
private boolean runOlm;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int vanguards;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean tektonActive;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private NPC hand;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private NPC Olm_NPC;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private NPC OlmMelee_NPC;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> Olm_Crystals = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> Olm_Heal = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> Olm_TP = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> Olm_PSN = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<Actor> burnTarget = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Actor teleportTarget;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Set<Victim> victims = new HashSet<>();
|
||||
private Actor acidTarget;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int crippleTimer = 45;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int burnTicks = 41;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int acidTicks = 25;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int teleportTicks = 10;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int tektonAttackTicks;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int OlmPhase = 0;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int Olm_TicksUntilAction = -1;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int Olm_ActionCycle = -1; //4:0 = auto 3:0 = null 2:0 = auto 1:0 = spec + actioncycle =4
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int Olm_NextSpec = -1; // 1= crystals 2=lightnig 3=portals 4= heal hand if p4
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private float percent;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<NPC, NPCContainer> npcContainer = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private PrayAgainst prayAgainstOlm;
|
||||
private long lastPrayTime;
|
||||
private int sleepcount = 0;
|
||||
private boolean needOlm = false;
|
||||
private boolean muttadile;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean tekton;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean tektonTickCounter;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean guardians;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean guardinTickCounter;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean vangHighlight;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean vangHealth;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean configPrayAgainstOlm;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean timers;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean tpOverlay;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean olmTick;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color muttaColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color guardColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color tektonColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color burnColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color acidColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color tpColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private CoxConfig.FontStyle fontStyle;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int textSize;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean shadows;
|
||||
|
||||
@Provides
|
||||
@@ -213,16 +169,12 @@ public class CoxPlugin extends Plugin
|
||||
|
||||
overlayManager.add(coxOverlay);
|
||||
overlayManager.add(coxInfoBox);
|
||||
HandCripple = false;
|
||||
handCripple = false;
|
||||
hand = null;
|
||||
acidTarget = null;
|
||||
teleportTarget = null;
|
||||
Olm_TP.clear();
|
||||
prayAgainstOlm = null;
|
||||
burnTarget.clear();
|
||||
victims.clear();
|
||||
crippleTimer = 45;
|
||||
burnTicks = 40;
|
||||
acidTicks = 25;
|
||||
teleportTicks = 10;
|
||||
vanguards = 0;
|
||||
}
|
||||
@@ -231,7 +183,6 @@ public class CoxPlugin extends Plugin
|
||||
protected void shutDown()
|
||||
{
|
||||
eventBus.unregister(this);
|
||||
|
||||
overlayManager.remove(coxOverlay);
|
||||
overlayManager.remove(coxInfoBox);
|
||||
}
|
||||
@@ -240,203 +191,231 @@ public class CoxPlugin extends Plugin
|
||||
{
|
||||
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventBus.subscribe(ChatMessage.class, this, this::onChatMessage);
|
||||
eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved);
|
||||
eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged);
|
||||
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
|
||||
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
|
||||
eventBus.subscribe(GameTick.class, this, this::onGameTick);
|
||||
}
|
||||
|
||||
private void onChatMessage(ChatMessage chatMessage)
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (inRaid())
|
||||
if (event.getGroup().equals("Cox"))
|
||||
{
|
||||
if (chatMessage.getType() == ChatMessageType.GAMEMESSAGE)
|
||||
updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (!inRaid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getType() == ChatMessageType.GAMEMESSAGE)
|
||||
{
|
||||
final Matcher tpMatcher = TP_REGEX.matcher(event.getMessage());
|
||||
|
||||
if (tpMatcher.matches())
|
||||
{
|
||||
Matcher tpMatcher = TP_REGEX.matcher(chatMessage.getMessage());
|
||||
if (tpMatcher.matches())
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
log.info("TP Matcher has found a match");
|
||||
for (Actor actor : client.getPlayers())
|
||||
if (player.getName().equals(tpMatcher.group(1)))
|
||||
{
|
||||
if (actor.getName().equals(tpMatcher.group(1)))
|
||||
{
|
||||
log.info("Teleport Target Assigned");
|
||||
teleportTarget = actor;
|
||||
}
|
||||
victims.add(new Victim(player, Victim.Type.TELEPORT));
|
||||
}
|
||||
}
|
||||
switch (Text.standardize(chatMessage.getMessageNode().getValue()))
|
||||
{
|
||||
case "the great olm rises with the power of acid.":
|
||||
case "the great olm rises with the power of crystal.":
|
||||
case "the great olm rises with the power of flame.":
|
||||
case "the great olm is giving its all. this is its final stand.":
|
||||
if (!runOlm)
|
||||
{
|
||||
Olm_ActionCycle = -1;
|
||||
Olm_TicksUntilAction = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
Olm_ActionCycle = -1;
|
||||
Olm_TicksUntilAction = 3;
|
||||
}
|
||||
OlmPhase = 0;
|
||||
runOlm = true;
|
||||
needOlm = true;
|
||||
crippleTimer = 45;
|
||||
Olm_NextSpec = -1;
|
||||
break;
|
||||
case "the great olm fires a sphere of aggression your way. your prayers have been sapped.":
|
||||
prayAgainstOlm = PrayAgainst.MELEE;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of aggression your way.":
|
||||
prayAgainstOlm = PrayAgainst.MELEE;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of magical power your way. your prayers have been sapped.":
|
||||
prayAgainstOlm = PrayAgainst.MAGIC;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of magical power your way.":
|
||||
prayAgainstOlm = PrayAgainst.MAGIC;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of accuracy and dexterity your way. your prayers have been sapped.":
|
||||
prayAgainstOlm = PrayAgainst.RANGED;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of accuracy and dexterity your way.":
|
||||
prayAgainstOlm = PrayAgainst.RANGED;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm's left claw clenches to protect itself temporarily.":
|
||||
HandCripple = true;
|
||||
}
|
||||
|
||||
switch (Text.standardize(event.getMessageNode().getValue()))
|
||||
{
|
||||
case "the great olm rises with the power of acid.":
|
||||
case "the great olm rises with the power of crystal.":
|
||||
case "the great olm rises with the power of flame.":
|
||||
case "the great olm is giving its all. this is its final stand.":
|
||||
if (!runOlm)
|
||||
{
|
||||
Olm_ActionCycle = -1;
|
||||
Olm_TicksUntilAction = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
Olm_ActionCycle = -1;
|
||||
Olm_TicksUntilAction = 3;
|
||||
}
|
||||
OlmPhase = 0;
|
||||
runOlm = true;
|
||||
needOlm = true;
|
||||
crippleTimer = 45;
|
||||
Olm_NextSpec = -1;
|
||||
break;
|
||||
case "the great olm fires a sphere of aggression your way. your prayers have been sapped.":
|
||||
case "the great olm fires a sphere of aggression your way.":
|
||||
prayAgainstOlm = PrayAgainst.MELEE;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of magical power your way. your prayers have been sapped.":
|
||||
case "the great olm fires a sphere of magical power your way.":
|
||||
prayAgainstOlm = PrayAgainst.MAGIC;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of accuracy and dexterity your way. your prayers have been sapped.":
|
||||
case "the great olm fires a sphere of accuracy and dexterity your way.":
|
||||
prayAgainstOlm = PrayAgainst.RANGED;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm's left claw clenches to protect itself temporarily.":
|
||||
handCripple = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onProjectileMoved(ProjectileMoved event)
|
||||
private void onProjectileSpawned(ProjectileSpawned event)
|
||||
{
|
||||
if (inRaid())
|
||||
if (!inRaid())
|
||||
{
|
||||
Projectile projectile = event.getProjectile();
|
||||
if (projectile.getId() == ProjectileID.OLM_MAGE_ATTACK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Projectile projectile = event.getProjectile();
|
||||
|
||||
switch (projectile.getId())
|
||||
{
|
||||
case ProjectileID.OLM_MAGE_ATTACK:
|
||||
prayAgainstOlm = PrayAgainst.MAGIC;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
}
|
||||
if (projectile.getId() == ProjectileID.OLM_RANGE_ATTACK)
|
||||
{
|
||||
break;
|
||||
case ProjectileID.OLM_RANGE_ATTACK:
|
||||
prayAgainstOlm = PrayAgainst.RANGED;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
}
|
||||
if (projectile.getId() == ProjectileID.OLM_ACID_TRAIL)
|
||||
{
|
||||
break;
|
||||
case ProjectileID.OLM_ACID_TRAIL:
|
||||
acidTarget = projectile.getInteracting();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void onSpotAnimationChanged(SpotAnimationChanged graphicChanged)
|
||||
private void onSpotAnimationChanged(SpotAnimationChanged event)
|
||||
{
|
||||
if (inRaid())
|
||||
if (!inRaid())
|
||||
{
|
||||
Actor actor = graphicChanged.getActor();
|
||||
if (actor.getSpotAnimation() == GraphicID.OLM_BURN)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.getActor() instanceof Player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = (Player) event.getActor();
|
||||
|
||||
if (player.getSpotAnimation() == GraphicID.OLM_BURN)
|
||||
{
|
||||
int add = 0;
|
||||
|
||||
for (Victim victim : victims)
|
||||
{
|
||||
if (!burnTarget.contains(actor))
|
||||
if (victim.getPlayer().getName().equals(player.getName()))
|
||||
{
|
||||
burnTarget.add(actor);
|
||||
add++;
|
||||
}
|
||||
}
|
||||
|
||||
if (add == 0)
|
||||
{
|
||||
victims.add(new Victim(player, Victim.Type.BURN));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onNpcSpawned(NpcSpawned npcSpawned)
|
||||
private void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
if (inRaid())
|
||||
{
|
||||
NPC npc = npcSpawned.getNpc();
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.TEKTON:
|
||||
case NpcID.TEKTON_7541:
|
||||
case NpcID.TEKTON_7542:
|
||||
case NpcID.TEKTON_7545:
|
||||
case NpcID.TEKTON_ENRAGED:
|
||||
case NpcID.TEKTON_ENRAGED_7544:
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
tektonAttackTicks = 27;
|
||||
break;
|
||||
case NpcID.MUTTADILE:
|
||||
case NpcID.MUTTADILE_7562:
|
||||
case NpcID.MUTTADILE_7563:
|
||||
case NpcID.GUARDIAN:
|
||||
case NpcID.GUARDIAN_7570:
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.VANGUARD:
|
||||
case NpcID.VANGUARD_7526:
|
||||
case NpcID.VANGUARD_7527:
|
||||
case NpcID.VANGUARD_7528:
|
||||
case NpcID.VANGUARD_7529:
|
||||
vanguards++;
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.GREAT_OLM_LEFT_CLAW:
|
||||
case NpcID.GREAT_OLM_LEFT_CLAW_7555:
|
||||
hand = npc;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final NPC npc = event.getNpc();
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.TEKTON:
|
||||
case NpcID.TEKTON_7541:
|
||||
case NpcID.TEKTON_7542:
|
||||
case NpcID.TEKTON_7545:
|
||||
case NpcID.TEKTON_ENRAGED:
|
||||
case NpcID.TEKTON_ENRAGED_7544:
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
tektonAttackTicks = 27;
|
||||
break;
|
||||
case NpcID.MUTTADILE:
|
||||
case NpcID.MUTTADILE_7562:
|
||||
case NpcID.MUTTADILE_7563:
|
||||
case NpcID.GUARDIAN:
|
||||
case NpcID.GUARDIAN_7570:
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.VANGUARD:
|
||||
case NpcID.VANGUARD_7526:
|
||||
case NpcID.VANGUARD_7527:
|
||||
case NpcID.VANGUARD_7528:
|
||||
case NpcID.VANGUARD_7529:
|
||||
vanguards++;
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.GREAT_OLM_LEFT_CLAW:
|
||||
case NpcID.GREAT_OLM_LEFT_CLAW_7555:
|
||||
hand = npc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (inRaid())
|
||||
if (!inRaid())
|
||||
{
|
||||
NPC npc = event.getNpc();
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.TEKTON:
|
||||
case NpcID.TEKTON_7541:
|
||||
case NpcID.TEKTON_7542:
|
||||
case NpcID.TEKTON_7545:
|
||||
case NpcID.TEKTON_ENRAGED:
|
||||
case NpcID.TEKTON_ENRAGED_7544:
|
||||
case NpcID.MUTTADILE:
|
||||
case NpcID.MUTTADILE_7562:
|
||||
case NpcID.MUTTADILE_7563:
|
||||
case NpcID.GUARDIAN:
|
||||
case NpcID.GUARDIAN_7570:
|
||||
case NpcID.GUARDIAN_7571:
|
||||
case NpcID.GUARDIAN_7572:
|
||||
if (npcContainer.remove(event.getNpc()) != null && !npcContainer.isEmpty())
|
||||
{
|
||||
npcContainer.remove(event.getNpc());
|
||||
}
|
||||
break;
|
||||
case NpcID.VANGUARD:
|
||||
case NpcID.VANGUARD_7526:
|
||||
case NpcID.VANGUARD_7527:
|
||||
case NpcID.VANGUARD_7528:
|
||||
case NpcID.VANGUARD_7529:
|
||||
if (npcContainer.remove(event.getNpc()) != null && !npcContainer.isEmpty())
|
||||
{
|
||||
npcContainer.remove(event.getNpc());
|
||||
}
|
||||
vanguards--;
|
||||
break;
|
||||
case NpcID.GREAT_OLM_RIGHT_CLAW_7553:
|
||||
case NpcID.GREAT_OLM_RIGHT_CLAW:
|
||||
HandCripple = false;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final NPC npc = event.getNpc();
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.TEKTON:
|
||||
case NpcID.TEKTON_7541:
|
||||
case NpcID.TEKTON_7542:
|
||||
case NpcID.TEKTON_7545:
|
||||
case NpcID.TEKTON_ENRAGED:
|
||||
case NpcID.TEKTON_ENRAGED_7544:
|
||||
case NpcID.MUTTADILE:
|
||||
case NpcID.MUTTADILE_7562:
|
||||
case NpcID.MUTTADILE_7563:
|
||||
case NpcID.GUARDIAN:
|
||||
case NpcID.GUARDIAN_7570:
|
||||
case NpcID.GUARDIAN_7571:
|
||||
case NpcID.GUARDIAN_7572:
|
||||
if (npcContainer.remove(event.getNpc()) != null && !npcContainer.isEmpty())
|
||||
{
|
||||
npcContainer.remove(event.getNpc());
|
||||
}
|
||||
break;
|
||||
case NpcID.VANGUARD:
|
||||
case NpcID.VANGUARD_7526:
|
||||
case NpcID.VANGUARD_7527:
|
||||
case NpcID.VANGUARD_7528:
|
||||
case NpcID.VANGUARD_7529:
|
||||
if (npcContainer.remove(event.getNpc()) != null && !npcContainer.isEmpty())
|
||||
{
|
||||
npcContainer.remove(event.getNpc());
|
||||
}
|
||||
vanguards--;
|
||||
break;
|
||||
case NpcID.GREAT_OLM_RIGHT_CLAW_7553:
|
||||
case NpcID.GREAT_OLM_RIGHT_CLAW:
|
||||
handCripple = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,7 +428,7 @@ public class CoxPlugin extends Plugin
|
||||
sleepcount = 0;
|
||||
Olm_Heal.clear();
|
||||
npcContainer.clear();
|
||||
burnTarget.clear();
|
||||
victims.clear();
|
||||
Olm_NPC = null;
|
||||
hand = null;
|
||||
prayAgainstOlm = null;
|
||||
@@ -457,7 +436,8 @@ public class CoxPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
npcHandler();
|
||||
handleNpcs();
|
||||
handleVictims();
|
||||
|
||||
if (needOlm = true)
|
||||
{
|
||||
@@ -472,57 +452,32 @@ public class CoxPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
if (teleportTarget != null)
|
||||
{
|
||||
log.info(teleportTarget.getName());
|
||||
Player target = (Player) teleportTarget;
|
||||
client.setHintArrow(target);
|
||||
teleportTicks--;
|
||||
if (teleportTicks <= 0)
|
||||
{
|
||||
client.clearHintArrow();
|
||||
teleportTarget = null;
|
||||
teleportTicks = 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (acidTarget != null)
|
||||
{
|
||||
acidTicks--;
|
||||
if (acidTicks <= 0)
|
||||
{
|
||||
acidTarget = null;
|
||||
acidTicks = 25;
|
||||
}
|
||||
}
|
||||
|
||||
if (burnTarget.size() > 0)
|
||||
{
|
||||
burnTicks--;
|
||||
if (burnTicks <= 0)
|
||||
{
|
||||
burnTarget.clear();
|
||||
burnTicks = 41;
|
||||
}
|
||||
}
|
||||
|
||||
if (HandCripple)
|
||||
if (handCripple)
|
||||
{
|
||||
crippleTimer--;
|
||||
if (crippleTimer <= 0)
|
||||
{
|
||||
HandCripple = false;
|
||||
handCripple = false;
|
||||
crippleTimer = 45;
|
||||
}
|
||||
}
|
||||
|
||||
if (runOlm)
|
||||
{
|
||||
olmHandler();
|
||||
handleOlm();
|
||||
}
|
||||
}
|
||||
|
||||
private void npcHandler()
|
||||
private void handleVictims()
|
||||
{
|
||||
if (victims.size() > 0)
|
||||
{
|
||||
victims.forEach(Victim::updateTicks);
|
||||
victims.removeIf(victim -> victim.getTicks() <= 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNpcs()
|
||||
{
|
||||
for (NPCContainer npcs : getNpcContainer().values())
|
||||
{
|
||||
@@ -605,7 +560,7 @@ public class CoxPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void olmHandler()
|
||||
private void handleOlm()
|
||||
{
|
||||
Olm_Crystals.clear();
|
||||
Olm_Heal.clear();
|
||||
@@ -706,14 +661,6 @@ public class CoxPlugin extends Plugin
|
||||
return client.getVar(Varbits.IN_RAID) == 1;
|
||||
}
|
||||
|
||||
private void onConfigChanged(ConfigChanged configChanged)
|
||||
{
|
||||
if (configChanged.getGroup().equals("Cox"))
|
||||
{
|
||||
updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.muttadile = config.muttadile();
|
||||
|
||||
@@ -34,43 +34,25 @@ import net.runelite.api.Actor;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class NPCContainer
|
||||
{
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private NPC npc;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int npcIndex;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private String npcName;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int npcSize;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int ticksUntilAttack;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int intermissionPeriod;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int npcSpeed;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Actor npcInteracting;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Specials specials;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Attackstyle attackStyle;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package net.runelite.client.plugins.coxhelper;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Player;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class Victim
|
||||
{
|
||||
private Player player;
|
||||
private Type type;
|
||||
private int ticks;
|
||||
|
||||
Victim(Player player, Type type)
|
||||
{
|
||||
this.player = player;
|
||||
this.type = type;
|
||||
this.ticks = type.getTicks();
|
||||
}
|
||||
|
||||
void updateTicks()
|
||||
{
|
||||
if (ticks > 0)
|
||||
{
|
||||
ticks--;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
enum Type
|
||||
{
|
||||
BURN(41),
|
||||
ACID(23),
|
||||
TELEPORT(10);
|
||||
|
||||
private int ticks;
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,14 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.demonicgorilla;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -54,7 +56,7 @@ import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.api.events.PlayerDespawned;
|
||||
import net.runelite.api.events.PlayerSpawned;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.api.events.ProjectileSpawned;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
@@ -69,6 +71,8 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
@Singleton
|
||||
public class DemonicGorillaPlugin extends Plugin
|
||||
{
|
||||
private static final Set<Integer> DEMONIC_PROJECTILES = ImmutableSet.of(ProjectileID.DEMONIC_GORILLA_RANGED, ProjectileID.DEMONIC_GORILLA_MAGIC, ProjectileID.DEMONIC_GORILLA_BOULDER);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@@ -118,7 +122,7 @@ public class DemonicGorillaPlugin extends Plugin
|
||||
|
||||
private void addSubscriptions()
|
||||
{
|
||||
eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved);
|
||||
eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied);
|
||||
eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned);
|
||||
@@ -175,8 +179,7 @@ public class DemonicGorillaPlugin extends Plugin
|
||||
npcId == NpcID.DEMONIC_GORILLA_7149;
|
||||
}
|
||||
|
||||
private void checkGorillaAttackStyleSwitch(DemonicGorilla gorilla,
|
||||
final DemonicGorilla.AttackStyle... protectedStyles)
|
||||
private void checkGorillaAttackStyleSwitch(DemonicGorilla gorilla, final DemonicGorilla.AttackStyle... protectedStyles)
|
||||
{
|
||||
if (gorilla.getAttacksUntilSwitch() <= 0 ||
|
||||
gorilla.getNextPosibleAttackStyles().isEmpty())
|
||||
@@ -545,35 +548,27 @@ public class DemonicGorillaPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void onProjectileMoved(ProjectileMoved event)
|
||||
private void onProjectileSpawned(ProjectileSpawned event)
|
||||
{
|
||||
Projectile projectile = event.getProjectile();
|
||||
int projectileId = projectile.getId();
|
||||
if (projectileId != ProjectileID.DEMONIC_GORILLA_RANGED &&
|
||||
projectileId != ProjectileID.DEMONIC_GORILLA_MAGIC &&
|
||||
projectileId != ProjectileID.DEMONIC_GORILLA_BOULDER)
|
||||
final Projectile projectile = event.getProjectile();
|
||||
final int projectileId = projectile.getId();
|
||||
|
||||
if (!DEMONIC_PROJECTILES.contains(projectileId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// The event fires once before the projectile starts moving,
|
||||
// and we only want to check each projectile once
|
||||
if (client.getGameCycle() >= projectile.getStartMovementCycle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
final WorldPoint loc = WorldPoint.fromLocal(client, projectile.getX1(), projectile.getY1(), client.getPlane());
|
||||
|
||||
if (projectileId == ProjectileID.DEMONIC_GORILLA_BOULDER)
|
||||
{
|
||||
recentBoulders.add(WorldPoint.fromLocal(client, event.getPosition()));
|
||||
recentBoulders.add(loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPoint projectileSourcePosition = WorldPoint.fromLocal(
|
||||
client, projectile.getX1(), projectile.getY1(), client.getPlane());
|
||||
for (DemonicGorilla gorilla : gorillas.values())
|
||||
{
|
||||
if (gorilla.getNpc().getWorldLocation().distanceTo(projectileSourcePosition) == 0)
|
||||
if (gorilla.getNpc().getWorldLocation().distanceTo(loc) == 0)
|
||||
{
|
||||
gorilla.setRecentProjectileId(projectile.getId());
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package net.runelite.client.plugins.devtools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
@@ -62,6 +63,7 @@ import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -75,6 +77,7 @@ class DevToolsOverlay extends Overlay
|
||||
private static final int ITEM_EMPTY = 6512;
|
||||
private static final int ITEM_FILLED = 20594;
|
||||
|
||||
private static final Font FONT = FontManager.getRunescapeFont().deriveFont(Font.BOLD, 16);
|
||||
private static final Color RED = new Color(221, 44, 0);
|
||||
private static final Color GREEN = new Color(0, 200, 83);
|
||||
private static final Color TURQOISE = new Color(0, 200, 157);
|
||||
@@ -112,6 +115,7 @@ class DevToolsOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
graphics.setFont(FONT);
|
||||
|
||||
if (plugin.getPlayers().isActive())
|
||||
{
|
||||
@@ -394,7 +398,7 @@ class DevToolsOverlay extends Overlay
|
||||
Rectangle2D textBounds = fm.getStringBounds(idText, graphics);
|
||||
|
||||
int textX = (int) (slotBounds.getX() + (slotBounds.getWidth() / 2) - (textBounds.getWidth() / 2));
|
||||
int textY = (int) (slotBounds.getY() + (slotBounds.getHeight() / 2) + (fm.getHeight() / 2) - fm.getMaxDescent());
|
||||
int textY = (int) (slotBounds.getY() + (slotBounds.getHeight() / 2) + (textBounds.getHeight() / 2));
|
||||
|
||||
graphics.setColor(new Color(255, 255, 255, 65));
|
||||
graphics.fill(slotBounds);
|
||||
@@ -536,7 +540,7 @@ class DevToolsOverlay extends Overlay
|
||||
Rectangle2D textBounds = fm.getStringBounds(text, graphics);
|
||||
|
||||
int textX = (int) (bounds.getX() + (bounds.getWidth() / 2) - (textBounds.getWidth() / 2));
|
||||
int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (fm.getHeight() / 2) - fm.getMaxDescent());
|
||||
int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (textBounds.getHeight() / 2));
|
||||
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawString(text, textX + 1, textY + 1);
|
||||
|
||||
@@ -192,7 +192,7 @@ class VarInspector extends JFrame
|
||||
{
|
||||
lastTick = tick;
|
||||
JLabel header = new JLabel("Tick " + tick);
|
||||
header.setFont(FontManager.getSmallFont(getFont()));
|
||||
header.setFont(FontManager.getRunescapeSmallFont());
|
||||
header.setBorder(new CompoundBorder(
|
||||
BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.LIGHT_GRAY_COLOR),
|
||||
BorderFactory.createEmptyBorder(3, 6, 0, 0)
|
||||
|
||||
@@ -84,71 +84,74 @@ enum DiscordGameEventType
|
||||
BOSS_SMOKE_DEVIL("Thermonuclear smoke devil", DiscordAreaType.BOSSES, 9363, 9619),
|
||||
BOSS_VORKATH("Vorkath", DiscordAreaType.BOSSES, 9023),
|
||||
BOSS_WINTERTODT("Wintertodt", DiscordAreaType.BOSSES, 6462),
|
||||
BOSS_ZALCANO("Zalcano", DiscordAreaType.BOSSES, 13250),
|
||||
BOSS_ZULRAH("Zulrah", DiscordAreaType.BOSSES, 9007),
|
||||
|
||||
// Cities
|
||||
CITY_AL_KHARID("Al Kharid", DiscordAreaType.CITIES, 13105, 13106),
|
||||
CITY_APE_ATOLL("Ape Atoll", DiscordAreaType.CITIES, 10795, 11051, 10974, 11050),
|
||||
CITY_ARCEUUS_HOUSE("Arceuus", DiscordAreaType.CITIES, 6459, 6715, 6458, 6714),
|
||||
CITY_ARDOUGNE("Ardougne", DiscordAreaType.CITIES, 10548, 10547, 10292, 10291, 10036, 10035, 9780, 9779),
|
||||
CITY_BARBARIAN_VILLAGE("Barbarian Village", DiscordAreaType.CITIES, 12341),
|
||||
CITY_BANDIT_CAMP("Bandit Camp", DiscordAreaType.CITIES, 12591),
|
||||
CITY_BEDABIN_CAMP("Bedabin Camp", DiscordAreaType.CITIES, 12590),
|
||||
CITY_BRIMHAVEN("Brimhaven", DiscordAreaType.CITIES, 11057, 11058),
|
||||
CITY_BURGH_DE_ROTT("Burgh de Rott", DiscordAreaType.CITIES, 13874, 13873, 14130, 14129),
|
||||
CITY_BURTHORPE("Burthorpe", DiscordAreaType.CITIES, 11319, 11575),
|
||||
CITY_CANIFIS("Canifis", DiscordAreaType.CITIES, 13878),
|
||||
CITY_CATHERBY("Catherby", DiscordAreaType.CITIES, 11317, 11318, 11061),
|
||||
CITY_CORSAIR_CAVE("Corsair Cove", DiscordAreaType.CITIES, 10028, 10284),
|
||||
CITY_DORGESH_KAAN("Dorgesh-Kaan", DiscordAreaType.CITIES, 10835, 10834),
|
||||
CITY_DRAYNOR("Draynor", DiscordAreaType.CITIES, 12338),
|
||||
CITY_EDGEVILLE("Edgeville", DiscordAreaType.CITIES, 12342),
|
||||
CITY_ENTRANA("Entrana", DiscordAreaType.CITIES, 11060, 11316),
|
||||
CITY_FALADOR("Falador", DiscordAreaType.CITIES, 11828, 11572, 11571, 11827, 12084),
|
||||
CITY_GOBLIN_VILLAGE("Goblin Village", DiscordAreaType.CITIES, 11830),
|
||||
CITY_GUTANOTH("Gu'Tanoth", DiscordAreaType.CITIES, 10031),
|
||||
CITY_HOSIDIUS_HOUSE("Hosidius", DiscordAreaType.CITIES, 6713, 6712, 6455, 6711, 6710, 6965, 6966, 7222, 7223, 6967),
|
||||
CITY_JATISZO("Jatizso", DiscordAreaType.CITIES, 9531),
|
||||
CITY_JIGGIG("Jiggig", DiscordAreaType.CITIES, 9775),
|
||||
CITY_KARAMJA("Karamja", DiscordAreaType.CITIES, 11569, 11568, 11567, 11566, 11313, 11312, 11311),
|
||||
CITY_KELDAGRIM("Keldagrim", DiscordAreaType.CITIES, 11423, 11422, 11679, 11678),
|
||||
CITY_LLETYA("Lletya", DiscordAreaType.CITIES, 9265),
|
||||
CITY_LOVAKENGJ_HOUSE("Lovakengj", DiscordAreaType.CITIES, 5692, 5948, 5691, 5947, 6203, 6202, 5690, 5946),
|
||||
CITY_LUMBRIDGE("Lumbridge", DiscordAreaType.CITIES, 12850),
|
||||
CITY_LUNAR_ISLE("Lunar Isle", DiscordAreaType.CITIES, 8253, 8252, 8509, 8508),
|
||||
CITY_MEIYERDITCH("Meiyerditch", DiscordAreaType.CITIES, 14132, 14388, 14387, 14386, 14385),
|
||||
CITY_MISCELLANIA("Miscellania", DiscordAreaType.CITIES, 10044, 10300),
|
||||
CITY_MOS_LE_HARMLESS("Mos Le'Harmless", DiscordAreaType.CITIES, 14638),
|
||||
CITY_MORTTON("Mort'ton", DiscordAreaType.CITIES, 13875),
|
||||
CITY_MOR_UI_REK("Mor UI Rek", DiscordAreaType.CITIES, 9808, 9807, 10064, 10063),
|
||||
CITY_AL_KHARID("Al Kharid" , DiscordAreaType.CITIES, 13105, 13106),
|
||||
CITY_APE_ATOLL("Ape Atoll" , DiscordAreaType.CITIES, 10795, 11051, 10974, 11050),
|
||||
CITY_ARCEUUS_HOUSE("Arceuus" , DiscordAreaType.CITIES, 6459, 6715, 6458, 6714),
|
||||
CITY_ARDOUGNE("Ardougne" , DiscordAreaType.CITIES, 10548, 10547, 10292, 10291, 10036, 10035, 9780, 9779),
|
||||
CITY_BARBARIAN_VILLAGE("Barbarian Village" , DiscordAreaType.CITIES, 12341),
|
||||
CITY_BANDIT_CAMP("Bandit Camp" , DiscordAreaType.CITIES, 12591),
|
||||
CITY_BEDABIN_CAMP("Bedabin Camp" , DiscordAreaType.CITIES, 12590),
|
||||
CITY_BRIMHAVEN("Brimhaven" , DiscordAreaType.CITIES, 11057, 11058),
|
||||
CITY_BURGH_DE_ROTT("Burgh de Rott" , DiscordAreaType.CITIES, 13874, 13873, 14130, 14129),
|
||||
CITY_BURTHORPE("Burthorpe" , DiscordAreaType.CITIES, 11319, 11575),
|
||||
CITY_CANIFIS("Canifis" , DiscordAreaType.CITIES, 13878),
|
||||
CITY_CATHERBY("Catherby" , DiscordAreaType.CITIES, 11317, 11318, 11061),
|
||||
CITY_CORSAIR_CAVE("Corsair Cove" , DiscordAreaType.CITIES, 10028, 10284),
|
||||
CITY_DORGESH_KAAN("Dorgesh-Kaan" , DiscordAreaType.CITIES, 10835, 10834),
|
||||
CITY_DRAYNOR("Draynor" , DiscordAreaType.CITIES, 12338),
|
||||
CITY_EDGEVILLE("Edgeville" , DiscordAreaType.CITIES, 12342),
|
||||
CITY_ENTRANA("Entrana" , DiscordAreaType.CITIES, 11060, 11316),
|
||||
CITY_FALADOR("Falador" , DiscordAreaType.CITIES, 11828, 11572, 11571, 11827, 12084),
|
||||
CITY_GOBLIN_VILLAGE("Goblin Village" , DiscordAreaType.CITIES, 11830),
|
||||
CITY_GUTANOTH("Gu'Tanoth" , DiscordAreaType.CITIES, 10031),
|
||||
CITY_GWENITH("Gwenith", DiscordAreaType.CITIES, 8501, 8757, 9013),
|
||||
CITY_HOSIDIUS_HOUSE("Hosidius" , DiscordAreaType.CITIES, 6713, 6712, 6455, 6711, 6710, 6965, 6966, 7222, 7223, 6967),
|
||||
CITY_JATISZO("Jatizso" , DiscordAreaType.CITIES, 9531),
|
||||
CITY_JIGGIG("Jiggig" , DiscordAreaType.CITIES, 9775),
|
||||
CITY_KARAMJA("Karamja" , DiscordAreaType.CITIES, 11569, 11568, 11567, 11566, 11313, 11312, 11311),
|
||||
CITY_KELDAGRIM("Keldagrim" , DiscordAreaType.CITIES, 11423, 11422, 11679, 11678),
|
||||
CITY_LLETYA("Lletya" , DiscordAreaType.CITIES, 9265),
|
||||
CITY_LOVAKENGJ_HOUSE("Lovakengj" , DiscordAreaType.CITIES, 5692, 5948, 5691, 5947, 6203, 6202, 5690, 5946),
|
||||
CITY_LUMBRIDGE("Lumbridge" , DiscordAreaType.CITIES, 12850),
|
||||
CITY_LUNAR_ISLE("Lunar Isle" , DiscordAreaType.CITIES, 8253, 8252, 8509, 8508),
|
||||
CITY_MEIYERDITCH("Meiyerditch" , DiscordAreaType.CITIES, 14132, 14388, 14387, 14386, 14385),
|
||||
CITY_MISCELLANIA("Miscellania" , DiscordAreaType.CITIES, 10044, 10300),
|
||||
CITY_MOS_LE_HARMLESS("Mos Le'Harmless" , DiscordAreaType.CITIES, 14638),
|
||||
CITY_MORTTON("Mort'ton" , DiscordAreaType.CITIES, 13875),
|
||||
CITY_MOR_UI_REK("Mor UI Rek" , DiscordAreaType.CITIES, 9808, 9807, 10064, 10063),
|
||||
CITY_MOUNT_KARUULM("Mount Karuulm", DiscordAreaType.CITIES, 5179, 4923, 5180),
|
||||
CITY_NARDAH("Nardah", DiscordAreaType.CITIES, 13613),
|
||||
CITY_NEITIZNOT("Neitiznot", DiscordAreaType.CITIES, 9275),
|
||||
CITY_PISCATORIS("Piscatoris", DiscordAreaType.CITIES, 9273),
|
||||
CITY_POLLNIVNEACH("Pollnivneach", DiscordAreaType.CITIES, 13358),
|
||||
CITY_PORT_KHAZARD("Port Khazard", DiscordAreaType.CITIES, 10545),
|
||||
CITY_PORT_PHASMATYS("Port Phasmatys", DiscordAreaType.CITIES, 14646),
|
||||
CITY_PORT_SARIM("Port Sarim", DiscordAreaType.CITIES, 12082),
|
||||
CITY_PISCARILIUS_HOUSE("Port Piscarilius", DiscordAreaType.CITIES, 6971, 7227, 6970, 7226),
|
||||
CITY_RELLEKKA("Rellekka", DiscordAreaType.CITIES, 10553),
|
||||
CITY_RIMMINGTON("Rimmington", DiscordAreaType.CITIES, 11826, 11570),
|
||||
CITY_SEERS_VILLAGE("Seers' Village", DiscordAreaType.CITIES, 10806),
|
||||
CITY_SHAYZIEN_HOUSE("Shayzien", DiscordAreaType.CITIES, 5944, 5943, 6200, 6199, 5688),
|
||||
CITY_SHILO_VILLAGE("Shilo Village", DiscordAreaType.CITIES, 11310),
|
||||
CITY_SOPHANEM("Sophanem", DiscordAreaType.CITIES, 13099),
|
||||
CITY_TAI_BWO_WANNAI("Tai Bwo Wannai", DiscordAreaType.CITIES, 11056, 11055),
|
||||
CITY_TAVERLEY("Taverley", DiscordAreaType.CITIES, 11574, 11573),
|
||||
CITY_TREE_GNOME_STRONGHOLD("Tree Gnome Stronghold", DiscordAreaType.CITIES, 9782, 9781),
|
||||
CITY_TREE_GNOME_VILLAGE("Tree Gnome Village", DiscordAreaType.CITIES, 10033),
|
||||
CITY_TROLL_STRONGHOLD("Troll Stronghold", DiscordAreaType.CITIES, 11321),
|
||||
CITY_TYRAS_CAMP("Tyras Camp", DiscordAreaType.CITIES, 8753, 8752),
|
||||
CITY_UZER("Uzer", DiscordAreaType.CITIES, 13872),
|
||||
CITY_VARROCK("Varrock", DiscordAreaType.CITIES, 12596, 12597, 12598, 12852, 12853, 12854, 13108, 13109, 13110),
|
||||
CITY_WITCHHAVEN("Witchaven", DiscordAreaType.CITIES, 10803),
|
||||
CITY_NARDAH("Nardah" , DiscordAreaType.CITIES, 13613),
|
||||
CITY_NEITIZNOT("Neitiznot" , DiscordAreaType.CITIES, 9275),
|
||||
CITY_PISCATORIS("Piscatoris" , DiscordAreaType.CITIES, 9273),
|
||||
CITY_POLLNIVNEACH("Pollnivneach" , DiscordAreaType.CITIES, 13358),
|
||||
CITY_PORT_KHAZARD("Port Khazard" , DiscordAreaType.CITIES, 10545),
|
||||
CITY_PORT_PHASMATYS("Port Phasmatys" , DiscordAreaType.CITIES, 14646),
|
||||
CITY_PORT_SARIM("Port Sarim" , DiscordAreaType.CITIES, 12082),
|
||||
CITY_PISCARILIUS_HOUSE("Port Piscarilius" , DiscordAreaType.CITIES, 6971, 7227, 6970, 7226),
|
||||
CITY_PRIFDDINAS("Prifddinas", DiscordAreaType.CITIES, 12894, 12895, 13150, 13151),
|
||||
CITY_RELLEKKA("Rellekka" , DiscordAreaType.CITIES, 10553),
|
||||
CITY_RIMMINGTON("Rimmington" , DiscordAreaType.CITIES, 11826, 11570),
|
||||
CITY_SEERS_VILLAGE("Seers' Village" , DiscordAreaType.CITIES, 10806),
|
||||
CITY_SHAYZIEN_HOUSE("Shayzien" , DiscordAreaType.CITIES, 5944, 5943, 6200, 6199, 5688),
|
||||
CITY_SHILO_VILLAGE("Shilo Village" , DiscordAreaType.CITIES, 11310),
|
||||
CITY_SOPHANEM("Sophanem" , DiscordAreaType.CITIES, 13099),
|
||||
CITY_TAI_BWO_WANNAI("Tai Bwo Wannai" , DiscordAreaType.CITIES, 11056, 11055),
|
||||
CITY_TAVERLEY("Taverley" , DiscordAreaType.CITIES, 11574, 11573),
|
||||
CITY_TREE_GNOME_STRONGHOLD("Tree Gnome Stronghold" , DiscordAreaType.CITIES, 9782, 9781),
|
||||
CITY_TREE_GNOME_VILLAGE("Tree Gnome Village" , DiscordAreaType.CITIES, 10033),
|
||||
CITY_TROLL_STRONGHOLD("Troll Stronghold" , DiscordAreaType.CITIES, 11321),
|
||||
CITY_TYRAS_CAMP("Tyras Camp" , DiscordAreaType.CITIES, 8753, 8752),
|
||||
CITY_UZER("Uzer" , DiscordAreaType.CITIES, 13872),
|
||||
CITY_VARROCK("Varrock" , DiscordAreaType.CITIES, 12596, 12597, 12598, 12852, 12853, 12854, 13108, 13109, 13110),
|
||||
CITY_WITCHHAVEN("Witchaven" , DiscordAreaType.CITIES, 10803),
|
||||
CITY_WOODCUTTING_GUILD("Woodcutting Guild", DiscordAreaType.CITIES, 6454, 6198, 6298),
|
||||
CITY_YANILLE("Yanille", DiscordAreaType.CITIES, 10288, 10032),
|
||||
CITY_ZANARIS("Zanaris", DiscordAreaType.CITIES, 9285, 9541, 9540, 9797),
|
||||
CITY_ZULANDRA("Zul-Andra", DiscordAreaType.CITIES, 8751),
|
||||
CITY_YANILLE("Yanille" , DiscordAreaType.CITIES, 10288, 10032),
|
||||
CITY_ZANARIS("Zanaris" , DiscordAreaType.CITIES, 9285, 9541, 9540, 9797),
|
||||
CITY_ZULANDRA("Zul-Andra" , DiscordAreaType.CITIES, 8751),
|
||||
|
||||
// Dungeons
|
||||
DUNGEON_ABANDONED_MINE("Abandoned Mine", DiscordAreaType.DUNGEONS, 13718, 11079, 11078, 11077, 10823, 10822, 10821),
|
||||
@@ -180,6 +183,7 @@ enum DiscordGameEventType
|
||||
DUNGEON_GOBLIN_CAVE("Goblin Cave", DiscordAreaType.DUNGEONS, 10393),
|
||||
DUNGEON_GRAND_TREE_TUNNELS("Grand Tree Tunnels", DiscordAreaType.DUNGEONS, 9882),
|
||||
DUNGEON_HAM("H.A.M Dungeon", DiscordAreaType.DUNGEONS, 12694, 10321),
|
||||
DUNGEON_IORWERTH("Iorwerth Dungeon", DiscordAreaType.DUNGEONS, 12738, 12993, 12994),
|
||||
DUNGEON_JATIZSO_MINES("Jatizo Mines", DiscordAreaType.DUNGEONS, 9631),
|
||||
DUNGEON_JIGGIG_BURIAL_TOMB("Jiggig Burial Tomb", DiscordAreaType.DUNGEONS, 9875, 9874),
|
||||
DUNGEON_JOGRE("Jogre Dungeon", DiscordAreaType.DUNGEONS, 11412),
|
||||
@@ -211,6 +215,7 @@ enum DiscordGameEventType
|
||||
DUNGEON_THE_WARRENS("The Warrens", DiscordAreaType.DUNGEONS, 7070, 7326),
|
||||
DUNGEON_TOLNA("Dungeon of Tolna", DiscordAreaType.DUNGEONS, 13209),
|
||||
DUNGEON_TOWER_OF_LIFE("Tower of Life Basement", DiscordAreaType.DUNGEONS, 12100),
|
||||
DUNGEON_TRAHAEARN_MINE("Trahaearn Mine", DiscordAreaType.DUNGEONS, 13249),
|
||||
DUNGEON_TUNNEL_OF_CHAOS("Tunnel of Chaos", DiscordAreaType.DUNGEONS, 12625),
|
||||
DUNGEON_UNDERGROUND_PASS("Underground Pass", DiscordAreaType.DUNGEONS, 9369, 9370),
|
||||
DUNGEON_VARROCKSEWERS("Varrock Sewers", DiscordAreaType.DUNGEONS, 12954, 13210),
|
||||
@@ -232,6 +237,7 @@ enum DiscordGameEventType
|
||||
MG_CLAN_WARS("Clan Wars", DiscordAreaType.MINIGAMES, 13135, 13134, 13133, 13131, 13130, 13387, 13386),
|
||||
MG_DUEL_ARENA("Duel Arena", DiscordAreaType.MINIGAMES, 13362),
|
||||
MG_FISHING_TRAWLER("Fishing Trawler", DiscordAreaType.MINIGAMES, 7499),
|
||||
MG_GAUNTLET("Gauntlet", DiscordAreaType.MINIGAMES, 12995),
|
||||
MG_INFERNO("The Inferno", DiscordAreaType.MINIGAMES, 9043),
|
||||
MG_LAST_MAN_STANDING("Last Man Standing", DiscordAreaType.MINIGAMES, 13660, 13659, 13658, 13916, 13915, 13914),
|
||||
MG_MAGE_TRAINING_ARENA("Mage Training Arena", DiscordAreaType.MINIGAMES, 13462, 13463),
|
||||
|
||||
@@ -132,10 +132,10 @@ public interface EntityHiderConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "hideNPCsNames",
|
||||
name = "Hide NPCs Names",
|
||||
description = "Configures which NPCs to hide"
|
||||
position = 10,
|
||||
keyName = "hideNPCsNames",
|
||||
name = "Hide NPCs Names",
|
||||
description = "Configures which NPCs to hide"
|
||||
)
|
||||
default String hideNPCsNames()
|
||||
{
|
||||
@@ -144,6 +144,28 @@ public interface EntityHiderConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "hideDeadNPCs",
|
||||
name = "Hide Dead NPCs",
|
||||
description = "Configures whether or not NPCs that just died are hidden"
|
||||
)
|
||||
default boolean hideDeadNPCs()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "hideNPCsOnDeath",
|
||||
name = "Hide NPCs On Death",
|
||||
description = "Configures which NPCs to hide when they die"
|
||||
)
|
||||
default String hideNPCsOnDeath()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "hideProjectiles",
|
||||
name = "Hide Projectiles",
|
||||
description = "Configures whether or not projectiles are hidden"
|
||||
@@ -152,5 +174,4 @@ public interface EntityHiderConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Entity Hider",
|
||||
@@ -107,11 +108,14 @@ public class EntityHiderPlugin extends Plugin
|
||||
|
||||
client.setNPCsHidden(config.hideNPCs());
|
||||
client.setNPCsHidden2D(config.hideNPCs2D());
|
||||
client.setNPCsNames(config.hideNPCsNames());
|
||||
client.setNPCsNames(Text.fromCSV(config.hideNPCsNames()));
|
||||
client.setNPCsHiddenOnDeath(Text.fromCSV(config.hideNPCsOnDeath()));
|
||||
|
||||
client.setAttackersHidden(config.hideAttackers());
|
||||
|
||||
client.setProjectilesHidden(config.hideProjectiles());
|
||||
|
||||
client.setDeadNPCsHidden(config.hideDeadNPCs());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,6 +140,8 @@ public class EntityHiderPlugin extends Plugin
|
||||
client.setAttackersHidden(false);
|
||||
|
||||
client.setProjectilesHidden(false);
|
||||
|
||||
client.setDeadNPCsHidden(false);
|
||||
}
|
||||
|
||||
private boolean isPlayerRegionAllowed()
|
||||
|
||||
@@ -49,7 +49,7 @@ class ItemPanel extends JPanel
|
||||
JLabel name = new JLabel(item.getName());
|
||||
|
||||
JLabel location = new JLabel(StringUtils.capitalize(kitType.toString().toLowerCase()));
|
||||
location.setFont(FontManager.getSmallFont(getFont()));
|
||||
location.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel imageLabel = new JLabel();
|
||||
icon.addTo(imageLabel);
|
||||
|
||||
@@ -223,14 +223,14 @@ class FeedPanel extends PluginPanel
|
||||
Color darkerForeground = UIManager.getColor("Label.foreground").darker();
|
||||
|
||||
JLabel titleLabel = new JLabel(item.getTitle());
|
||||
titleLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
titleLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
titleLabel.setBackground(null);
|
||||
titleLabel.setForeground(darkerForeground);
|
||||
titleLabel.setPreferredSize(new Dimension(CONTENT_WIDTH - TIME_WIDTH, 0));
|
||||
|
||||
Duration duration = Duration.between(Instant.ofEpochMilli(item.getTimestamp()), Instant.now());
|
||||
JLabel timeLabel = new JLabel(durationToString(duration));
|
||||
timeLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
timeLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
timeLabel.setForeground(darkerForeground);
|
||||
|
||||
titleAndTime.add(titleLabel, BorderLayout.WEST);
|
||||
@@ -239,9 +239,9 @@ class FeedPanel extends PluginPanel
|
||||
JPanel content = new JPanel(new BorderLayout());
|
||||
content.setBackground(null);
|
||||
|
||||
JLabel contentLabel = new JLabel(lineBreakText(item.getContent(), FontManager.getSmallFont(getFont())));
|
||||
JLabel contentLabel = new JLabel(lineBreakText(item.getContent(), FontManager.getRunescapeSmallFont()));
|
||||
contentLabel.setBorder(new EmptyBorder(2, 0, 0, 0));
|
||||
contentLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
contentLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
contentLabel.setForeground(darkerForeground);
|
||||
|
||||
content.add(contentLabel, BorderLayout.CENTER);
|
||||
|
||||
@@ -99,6 +99,8 @@ import static net.runelite.api.NpcID.ROD_FISHING_SPOT_7464;
|
||||
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_7468;
|
||||
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_7676;
|
||||
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_8524;
|
||||
import static net.runelite.api.NpcID.FISHING_SPOT_4928;
|
||||
import static net.runelite.api.NpcID.FISHING_SPOT_6784;
|
||||
|
||||
@Getter
|
||||
enum FishingSpot
|
||||
@@ -132,6 +134,9 @@ enum FishingSpot
|
||||
ROD_FISHING_SPOT_1526, ROD_FISHING_SPOT_1527, ROD_FISHING_SPOT_7463,
|
||||
ROD_FISHING_SPOT_7464, ROD_FISHING_SPOT_7468, ROD_FISHING_SPOT_8524
|
||||
),
|
||||
LAVA_EEL("Lava eel", ItemID.LAVA_EEL,
|
||||
FISHING_SPOT_4928, FISHING_SPOT_6784
|
||||
),
|
||||
BARB_FISH("Sturgeon, Salmon, Trout", ItemID.LEAPING_STURGEON,
|
||||
FISHING_SPOT_1542, FISHING_SPOT_7323
|
||||
),
|
||||
|
||||
@@ -68,15 +68,4 @@ public interface FpsConfig extends Config
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "drawPing",
|
||||
name = "Draw ping indicator",
|
||||
description = "Show a number in the corner for the current ping",
|
||||
position = 3
|
||||
)
|
||||
default boolean drawPing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,14 +26,14 @@ package net.runelite.client.plugins.fps;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -51,6 +51,10 @@ import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
@Singleton
|
||||
public class FpsOverlay extends Overlay
|
||||
{
|
||||
private static final int Y_OFFSET = 1;
|
||||
private static final int X_OFFSET = 1;
|
||||
private static final String FPS_STRING = " FPS";
|
||||
|
||||
// Local dependencies
|
||||
private final Client client;
|
||||
private final FpsPlugin plugin;
|
||||
@@ -84,62 +88,30 @@ public class FpsOverlay extends Overlay
|
||||
return isEnforced() ? Color.red : Color.yellow;
|
||||
}
|
||||
|
||||
private static Color getPingColor(int ping)
|
||||
{
|
||||
if (ping >= 100 || ping < 0)
|
||||
{
|
||||
return Color.red;
|
||||
}
|
||||
else if (ping >= 50)
|
||||
{
|
||||
return Color.yellow;
|
||||
}
|
||||
return Color.green;
|
||||
}
|
||||
|
||||
private int calculateOffset()
|
||||
{
|
||||
if ((client.getVar(Varbits.SIDE_PANELS) == 1) && client.isResized())
|
||||
{
|
||||
return 27;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.isDrawFps() && !plugin.isDrawPing())
|
||||
if (!plugin.isDrawFps())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final int offset = calculateOffset();
|
||||
// On resizable bottom line mode the logout button is at the top right, so offset the overlay
|
||||
// to account for it
|
||||
Widget logoutButton = client.getWidget(WidgetInfo.RESIZABLE_MINIMAP_LOGOUT_BUTTON);
|
||||
int xOffset = X_OFFSET;
|
||||
if (logoutButton != null && !logoutButton.isHidden())
|
||||
{
|
||||
xOffset += logoutButton.getWidth();
|
||||
}
|
||||
|
||||
final String text = client.getFPS() + FPS_STRING;
|
||||
final int textWidth = graphics.getFontMetrics().stringWidth(text);
|
||||
final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent();
|
||||
|
||||
final int width = (int) client.getRealDimensions().getWidth();
|
||||
final FontMetrics fontMetrics = graphics.getFontMetrics();
|
||||
|
||||
int baseYOffset = (fontMetrics.getAscent() - fontMetrics.getDescent()) + 1;
|
||||
|
||||
if (plugin.isDrawFps())
|
||||
{
|
||||
final String fpsText = String.format("%d FPS", client.getFPS());
|
||||
final int textWidth = fontMetrics.stringWidth(fpsText);
|
||||
|
||||
final Point point = new Point(width - textWidth - offset, baseYOffset);
|
||||
OverlayUtil.renderTextLocation(graphics, point, fpsText, getFpsValueColor());
|
||||
|
||||
baseYOffset += 11;
|
||||
}
|
||||
|
||||
if (plugin.isDrawPing())
|
||||
{
|
||||
final String pingText = String.format("%dms", plugin.getPing());
|
||||
final int textWidth = fontMetrics.stringWidth(pingText);
|
||||
|
||||
final Point point = new Point(width - textWidth - offset, baseYOffset);
|
||||
OverlayUtil.renderTextLocation(graphics, point, pingText, getPingColor(plugin.getPing()));
|
||||
}
|
||||
final Point point = new Point(width - textWidth - xOffset, textHeight + Y_OFFSET);
|
||||
OverlayUtil.renderTextLocation(graphics, point, text, getFpsValueColor());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -27,27 +27,19 @@ package net.runelite.client.plugins.fps;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.DrawManager;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ExecutorServiceExceptionLogger;
|
||||
import net.runelite.client.util.ping.Ping;
|
||||
|
||||
/**
|
||||
* Performance has two primary areas, this plugin class just keeps those areas up to date and handles setup / teardown.
|
||||
* FPS Control has two primary areas, this plugin class just keeps those areas up to date and handles setup / teardown.
|
||||
*
|
||||
* <p>Overlay paints the current FPS, the color depends on whether or not FPS is being enforced.
|
||||
* The overlay is lightweight and is merely and indicator.
|
||||
@@ -55,15 +47,11 @@ import net.runelite.client.util.ping.Ping;
|
||||
* <p>Draw Listener, sleeps a calculated amount after each canvas paint operation.
|
||||
* This is the heart of the plugin, the amount of sleep taken is regularly adjusted to account varying
|
||||
* game and system load, it usually finds the sweet spot in about two seconds.
|
||||
*
|
||||
* <p>Pinging the world, when logged in and ping display is enabled, every 5 seconds the remote server
|
||||
* for the current world is pinged. A scheduled method in this class is responsible for that. When ping fails
|
||||
* or those conditions are not met, ping will have the value of -1.
|
||||
*/
|
||||
@PluginDescriptor(
|
||||
name = "Performance",
|
||||
description = "Show current Ping and FPS or set an FPS limit",
|
||||
tags = {"frames", "framerate", "limit", "overlay", "ping"},
|
||||
description = "Show current FPS or set an FPS limit",
|
||||
tags = {"frames", "framerate", "limit", "overlay"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Singleton
|
||||
@@ -71,9 +59,6 @@ public class FpsPlugin extends Plugin
|
||||
{
|
||||
static final String CONFIG_GROUP_KEY = "fpscontrol";
|
||||
|
||||
@Getter
|
||||
private int ping;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@@ -86,30 +71,18 @@ public class FpsPlugin extends Plugin
|
||||
@Inject
|
||||
private DrawManager drawManager;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private FpsConfig fpsConfig;
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
|
||||
private final ScheduledExecutorService pingExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor());
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
private boolean shutdown;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private FpsLimitMode limitMode;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean drawFps;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean drawPing;
|
||||
|
||||
@Provides
|
||||
FpsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -124,7 +97,6 @@ public class FpsPlugin extends Plugin
|
||||
|
||||
limitMode = fpsConfig.limitMode();
|
||||
drawFps = fpsConfig.drawFps();
|
||||
drawPing = fpsConfig.drawPing();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,11 +106,6 @@ public class FpsPlugin extends Plugin
|
||||
overlay.onFocusChanged(event);
|
||||
}
|
||||
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
shutdown = event.getGameState() != GameState.LOGGED_IN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
@@ -146,17 +113,9 @@ public class FpsPlugin extends Plugin
|
||||
|
||||
limitMode = fpsConfig.limitMode();
|
||||
drawFps = fpsConfig.drawFps();
|
||||
drawPing = fpsConfig.drawPing();
|
||||
overlayManager.add(overlay);
|
||||
drawManager.registerEveryFrameListener(drawListener);
|
||||
drawListener.reloadConfig();
|
||||
shutdown = client.getGameState() != GameState.LOGGED_IN;
|
||||
|
||||
if (!loaded)
|
||||
{
|
||||
pingExecutorService.scheduleAtFixedRate(this::getPingToCurrentWorld, 5, 5, TimeUnit.SECONDS);
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,25 +125,11 @@ public class FpsPlugin extends Plugin
|
||||
|
||||
overlayManager.remove(overlay);
|
||||
drawManager.unregisterEveryFrameListener(drawListener);
|
||||
shutdown = true;
|
||||
}
|
||||
|
||||
private void addSubscriptions()
|
||||
{
|
||||
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged);
|
||||
eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
}
|
||||
|
||||
private void getPingToCurrentWorld()
|
||||
{
|
||||
if (!shutdown && drawPing)
|
||||
{
|
||||
ping = Ping.ping(String.format("oldschool%d.runescape.com", client.getWorld() - 300));
|
||||
}
|
||||
else
|
||||
{
|
||||
ping = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI
|
||||
* No rights reserved. Use, redistribute, and modify at your own discretion,
|
||||
* and in accordance with Yagex and RuneLite guidelines.
|
||||
* However, aforementioned monkey would prefer if you don't sell this plugin for profit.
|
||||
* Good luck on your raids!
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Range;
|
||||
import net.runelite.client.config.Stub;
|
||||
|
||||
@ConfigGroup("Gauntlet")
|
||||
|
||||
public interface GauntletConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "resources",
|
||||
name = "Resources",
|
||||
description = ""
|
||||
)
|
||||
default Stub resources()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "highlightResources",
|
||||
name = "Highlight Resources",
|
||||
description = "Highlights all the resources in each room with a color.",
|
||||
parent = "resources"
|
||||
)
|
||||
default boolean highlightResources()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "highlightResourcesColor",
|
||||
name = "Highlight Color",
|
||||
description = "Highlights all the resources in each room with this color.",
|
||||
parent = "resources",
|
||||
hidden = true,
|
||||
unhide = "highlightResources"
|
||||
)
|
||||
default Color highlightResourcesColor()
|
||||
{
|
||||
return Color.YELLOW;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "highlightResourcesIcons",
|
||||
name = "Highlight Resources with an Icon",
|
||||
description = "Highlights all the icons in each room with an icon.",
|
||||
parent = "resources",
|
||||
hidden = true,
|
||||
unhide = "highlightResources"
|
||||
)
|
||||
default boolean highlightResourcesIcons()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 1,
|
||||
max = 50
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "resourceIconSize",
|
||||
name = "Resource Icon Size",
|
||||
description = " change the size of resource icons.",
|
||||
hidden = true,
|
||||
unhide = "highlightResources",
|
||||
parent = "resources"
|
||||
)
|
||||
default int resourceIconSize()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "boss",
|
||||
name = "Boss",
|
||||
description = ""
|
||||
)
|
||||
default Stub boss()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "countBossAttacks",
|
||||
name = "Count Boss Attacks",
|
||||
description = "Count the attacks until the boss switches their style.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean countBossAttacks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "countPlayerAttacks",
|
||||
name = "Count Player Attacks",
|
||||
description = "Count the player attacks until the boss switches their prayer.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean countPlayerAttacks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "highlightWidget",
|
||||
name = "Highlight Correct Prayer",
|
||||
description = "Highlights correct prayer in your prayer book.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean highlightWidget()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "flashOnWrongAttack",
|
||||
name = "Flash on Wrong Attack",
|
||||
description = "This will flash your screen if you attack with the wrong stlye.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean flashOnWrongAttack()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "uniquePrayerAudio",
|
||||
name = "Unique Prayer Audio",
|
||||
description = "Plays a unique sound whenever the boss is about to shut down your prayer.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean uniquePrayerAudio()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "uniquePrayerVisual",
|
||||
name = "Unique Prayer Visual",
|
||||
description = "Prayer attacks will have a unique overlay visual.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean uniquePrayerVisual()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "uniqueAttackVisual",
|
||||
name = "Unique Magic & Range Visuals",
|
||||
description = "Magic and Range attacks will have a unique overlay visual.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean uniqueAttackVisual()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "overlayBoss",
|
||||
name = "Overlay the Boss (Color)",
|
||||
description = "Overlay the boss with an color denoting it's current attack style.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean overlayBoss()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "overlayBossPrayer",
|
||||
name = "Overlay the Boss (Icon)",
|
||||
description = "Overlay the boss with an icon denoting it's current attack style.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean overlayBossPrayer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "overlayTornadoes",
|
||||
name = "Show Tornado Decay",
|
||||
description = "Display the amount of ticks left until the tornadoes decay.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean overlayTornadoes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 1,
|
||||
max = 50
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 15,
|
||||
keyName = "projectileIconSize",
|
||||
name = "Boss Projectile Icon Size",
|
||||
description = " change the size of Projectile icons.",
|
||||
parent = "boss"
|
||||
)
|
||||
default int projectileIconSize()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 16,
|
||||
keyName = "timer",
|
||||
name = "Timer",
|
||||
description = ""
|
||||
)
|
||||
default Stub timer()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 17,
|
||||
keyName = "displayTimerWidget",
|
||||
name = "Show Custom Timer (Widget)",
|
||||
description = "Display a timer widget that tracks your gauntlet progress.",
|
||||
parent = "timer"
|
||||
)
|
||||
default boolean displayTimerWidget()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 18,
|
||||
keyName = "displayTimerChat",
|
||||
name = "Show Custom Timer (Chat)",
|
||||
description = "Display a chat message that tracks your gauntlet progress.",
|
||||
parent = "timer"
|
||||
)
|
||||
default boolean displayTimerChat()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
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.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class GauntletInfoBox extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
private final Client client;
|
||||
private final GauntletPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
private final SpriteManager spriteManager;
|
||||
|
||||
@Inject
|
||||
GauntletInfoBox(final @Nullable Client client, final GauntletPlugin plugin, final SpriteManager spriteManager)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.spriteManager = spriteManager;
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (plugin.getHunllef() == null || !plugin.isInRoom())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Prayer prayer = plugin.getNextPrayer();
|
||||
|
||||
if (prayer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
InfoBoxComponent prayComponent = new InfoBoxComponent();
|
||||
BufferedImage prayImg = scaleImg(getPrayerImage(prayer));
|
||||
prayComponent.setImage(prayImg);
|
||||
prayComponent.setColor(Color.WHITE);
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(prayer)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
prayComponent.setPreferredSize(new Dimension(40, 40));
|
||||
panelComponent.getChildren().add(prayComponent);
|
||||
panelComponent.setPreferredSize(new Dimension(40, 40));
|
||||
panelComponent.setBorder(new Rectangle(0, 0, 0, 0));
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(Prayer prayer)
|
||||
{
|
||||
switch (prayer)
|
||||
{
|
||||
case PROTECT_FROM_MAGIC:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||
case PROTECT_FROM_MELEE:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MELEE, 0);
|
||||
case PROTECT_FROM_MISSILES:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static BufferedImage scaleImg(final BufferedImage img)
|
||||
{
|
||||
if (img == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final double width = img.getWidth(null);
|
||||
final double height = img.getHeight(null);
|
||||
final double size = 36; // Limit size to 2 as that is minimum size not causing breakage
|
||||
final double scalex = size / width;
|
||||
final double scaley = size / height;
|
||||
final double scale = Math.min(scalex, scaley);
|
||||
final int newWidth = (int) (width * scale);
|
||||
final int newHeight = (int) (height * scale);
|
||||
final BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
final Graphics g = scaledImage.createGraphics();
|
||||
g.drawImage(img, 0, 0, newWidth, newHeight, null);
|
||||
g.dispose();
|
||||
return scaledImage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright (c) 2019, kThisIsCvpv <https://github.com/kThisIsCvpv>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.model.Jarvis;
|
||||
import net.runelite.api.model.Vertex;
|
||||
import net.runelite.client.graphics.ModelOutlineRenderer;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import static net.runelite.client.util.ImageUtil.resizeImage;
|
||||
|
||||
public class GauntletOverlay extends Overlay
|
||||
{
|
||||
private static final Color FLASH_COLOR = new Color(255, 0, 0, 70);
|
||||
private static final int MAX_DISTANCE = 2400;
|
||||
private final Client client;
|
||||
private final GauntletPlugin plugin;
|
||||
private final ModelOutlineRenderer outlineRenderer;
|
||||
private int timeout;
|
||||
|
||||
@Inject
|
||||
private GauntletOverlay(Client client, GauntletPlugin plugin, ModelOutlineRenderer outlineRenderer)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.outlineRenderer = outlineRenderer;
|
||||
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Save resources. There's nothing to render if the user is not in a raid.
|
||||
|
||||
if (!plugin.startedGauntlet())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (plugin.fightingBoss())
|
||||
{
|
||||
// This section handles the visuals when the player is in the boss room.
|
||||
// This section handles the projectile overlays.
|
||||
Set<Missiles> projectiles = plugin.getProjectiles();
|
||||
projectiles.forEach(projectile ->
|
||||
{
|
||||
BufferedImage icon = resizeImage(projectile.getImage(), plugin.getProjectileIconSize(), plugin.getProjectileIconSize());
|
||||
Color color = projectile.getColor();
|
||||
|
||||
Polygon polygon = boundProjectile(projectile.getProjectile());
|
||||
if (polygon == null)
|
||||
{
|
||||
int x = (int) projectile.getProjectile().getX();
|
||||
int y = (int) projectile.getProjectile().getY();
|
||||
|
||||
LocalPoint point = new LocalPoint(x, y);
|
||||
Point loc = Perspective.getCanvasImageLocation(client, point, icon, -(int) projectile.getProjectile().getZ());
|
||||
|
||||
if (loc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.isUniqueAttackVisual())
|
||||
{
|
||||
graphics.drawImage(icon, loc.getX(), loc.getY(), null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(color);
|
||||
graphics.draw(polygon);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 50));
|
||||
graphics.fill(polygon);
|
||||
if (plugin.isUniqueAttackVisual())
|
||||
{
|
||||
Rectangle bounds = polygon.getBounds();
|
||||
int x = (int) bounds.getCenterX() - (icon.getWidth() / 2);
|
||||
int y = (int) bounds.getCenterY() - (icon.getHeight() / 2);
|
||||
graphics.drawImage(icon, x, y, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
projectiles.removeIf(proj -> proj.getProjectile().getRemainingCycles() <= 0);
|
||||
|
||||
plugin.getTornadoes().forEach(tornado ->
|
||||
{
|
||||
if (plugin.isOverlayTornadoes())
|
||||
{
|
||||
if (tornado.getTimeLeft() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String textOverlay = Integer.toString(tornado.getTimeLeft());
|
||||
final Point textLoc = Perspective.getCanvasTextLocation(client, graphics, tornado.getNpc().getLocalLocation(), textOverlay, 0);
|
||||
final LocalPoint lp = LocalPoint.fromWorld(client, tornado.getNpc().getWorldLocation());
|
||||
|
||||
if (lp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Polygon tilePoly = Perspective.getCanvasTilePoly(client, lp);
|
||||
OverlayUtil.renderPolygon(graphics, tilePoly, Color.YELLOW);
|
||||
|
||||
if (textLoc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Font oldFont = graphics.getFont();
|
||||
graphics.setFont(new Font("Arial", Font.BOLD, 20));
|
||||
Point pointShadow = new Point(textLoc.getX() + 1, textLoc.getY() + 1);
|
||||
OverlayUtil.renderTextLocation(graphics, pointShadow, textOverlay, Color.BLACK);
|
||||
OverlayUtil.renderTextLocation(graphics, textLoc, textOverlay, Color.YELLOW);
|
||||
graphics.setFont(oldFont);
|
||||
}
|
||||
});
|
||||
|
||||
if (plugin.getHunllef() != null)
|
||||
{
|
||||
final Hunllef hunllef = plugin.getHunllef();
|
||||
final Hunllef.BossAttackPhase phase = hunllef.getCurrentPhase();
|
||||
final NPC boss = hunllef.getNpc();
|
||||
final LocalPoint point = boss.getLocalLocation();
|
||||
|
||||
if (plugin.isFlash())
|
||||
{
|
||||
final Color flash = graphics.getColor();
|
||||
graphics.setColor(FLASH_COLOR);
|
||||
graphics.fill(new Rectangle(client.getCanvas().getSize()));
|
||||
graphics.setColor(flash);
|
||||
timeout++;
|
||||
if (timeout >= 15)
|
||||
{
|
||||
timeout = 0;
|
||||
plugin.setFlash(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.isOverlayBoss())
|
||||
{
|
||||
Polygon polygon = boss.getConvexHull();
|
||||
|
||||
if (polygon == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (phase.getPrayer() != null && !client.isPrayerActive(phase.getPrayer()))
|
||||
{
|
||||
Color color = phase.getColor();
|
||||
outlineRenderer.drawOutline(boss, 12, color, new Color(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.isOverlayBossPrayer())
|
||||
{
|
||||
BufferedImage attackIcon = null;
|
||||
|
||||
switch (phase)
|
||||
{
|
||||
case MAGIC:
|
||||
attackIcon = resizeImage(hunllef.getMage(), plugin.getProjectileIconSize(), plugin.getProjectileIconSize());
|
||||
break;
|
||||
case RANGE:
|
||||
attackIcon = resizeImage(hunllef.getRange(), plugin.getProjectileIconSize(), plugin.getProjectileIconSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (attackIcon == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Point imageLoc = Perspective.getCanvasImageLocation(client, point, attackIcon, boss.getLogicalHeight() / 2);
|
||||
|
||||
if (imageLoc == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
graphics.drawImage(attackIcon, imageLoc.getX(), imageLoc.getY(), null);
|
||||
}
|
||||
|
||||
if (plugin.isHighlightWidget())
|
||||
{
|
||||
if (phase.getPrayer() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Rectangle bounds = OverlayUtil.renderPrayerOverlay(graphics, client, phase.getPrayer(), phase.getColor());
|
||||
|
||||
if (bounds != null)
|
||||
{
|
||||
final Color color = hunllef.getTicksUntilAttack() == 1 ? Color.WHITE : phase.getColor();
|
||||
renderTextLocation(graphics, Integer.toString(hunllef.getTicksUntilAttack()), 16, Font.BOLD, color, centerPoint(bounds), false);
|
||||
}
|
||||
}
|
||||
|
||||
// This section handles any text overlays.
|
||||
String textOverlay = "";
|
||||
|
||||
// Handles the counter for the boss.
|
||||
if (plugin.isCountBossAttacks())
|
||||
{
|
||||
textOverlay = Integer.toString(hunllef.getBossAttacks());
|
||||
}
|
||||
|
||||
// Handles the counter for the player.
|
||||
if (plugin.isCountPlayerAttacks())
|
||||
{
|
||||
if (textOverlay.length() > 0)
|
||||
{
|
||||
textOverlay += " | ";
|
||||
}
|
||||
textOverlay += Integer.toString(hunllef.getPlayerAttacks());
|
||||
}
|
||||
|
||||
// Handles drawing the text onto the boss.
|
||||
if (textOverlay.length() > 0)
|
||||
{
|
||||
Point textLoc = Perspective.getCanvasTextLocation(client, graphics, point, textOverlay, boss.getLogicalHeight() / 2);
|
||||
|
||||
if (textLoc == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
textLoc = new Point(textLoc.getX(), textLoc.getY() + 35);
|
||||
|
||||
Font oldFont = graphics.getFont();
|
||||
|
||||
graphics.setFont(new Font("Arial", Font.BOLD, 20));
|
||||
Point pointShadow = new Point(textLoc.getX() + 1, textLoc.getY() + 1);
|
||||
|
||||
OverlayUtil.renderTextLocation(graphics, pointShadow, textOverlay, Color.BLACK);
|
||||
OverlayUtil.renderTextLocation(graphics, textLoc, textOverlay, phase.getColor());
|
||||
|
||||
graphics.setFont(oldFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This section overlays all resources.
|
||||
final LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
final Set<Resources> resources = plugin.getResources();
|
||||
resources.forEach(object ->
|
||||
{
|
||||
if (object.getGameObject().getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
{
|
||||
|
||||
// Don't use Convex Hull click box. As the room start to fill up, your FPS will dip.
|
||||
Polygon polygon = object.getGameObject().getConvexHull();
|
||||
|
||||
if (polygon == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// This section will highlight the resource with color.
|
||||
if (plugin.isHighlightResources())
|
||||
{
|
||||
outlineRenderer.drawOutline(object.getGameObject(), 2, plugin.getHighlightResourcesColor());
|
||||
}
|
||||
|
||||
// This section will overlay the resource with an icon.
|
||||
if (plugin.isHighlightResourcesIcons())
|
||||
{
|
||||
BufferedImage icon = resizeImage(object.getImage(), plugin.getResourceIconSize(), plugin.getResourceIconSize());
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
Rectangle bounds = polygon.getBounds();
|
||||
int startX = (int) bounds.getCenterX() - (icon.getWidth() / 2);
|
||||
int startY = (int) bounds.getCenterY() - (icon.getHeight() / 2);
|
||||
graphics.drawImage(icon, startX, startY, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Polygon boundProjectile(Projectile proj)
|
||||
{
|
||||
if (proj == null || proj.getModel() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Model model = proj.getModel();
|
||||
LocalPoint point = new LocalPoint((int) proj.getX(), (int) proj.getY());
|
||||
int tileHeight = Perspective.getTileHeight(client, point, client.getPlane());
|
||||
|
||||
double angle = Math.atan(proj.getVelocityY() / proj.getVelocityX());
|
||||
angle = Math.toDegrees(angle) + (proj.getVelocityX() < 0 ? 180 : 0);
|
||||
angle = angle < 0 ? angle + 360 : angle;
|
||||
angle = 360 - angle - 90;
|
||||
|
||||
double ori = angle * (512d / 90d);
|
||||
ori = ori < 0 ? ori + 2048 : ori;
|
||||
|
||||
int orientation = (int) Math.round(ori);
|
||||
|
||||
List<Vertex> vertices = model.getVertices();
|
||||
for (int i = 0; i < vertices.size(); ++i)
|
||||
{
|
||||
vertices.set(i, vertices.get(i).rotate(orientation));
|
||||
}
|
||||
|
||||
List<Point> list = new ArrayList<>();
|
||||
|
||||
for (Vertex vertex : vertices)
|
||||
{
|
||||
final Point localToCanvas = Perspective.localToCanvas(client, point.getX() - vertex.getX(), point.getY() - vertex.getZ(), tileHeight + vertex.getY() + (int) proj.getZ());
|
||||
if (localToCanvas != null)
|
||||
{
|
||||
list.add(localToCanvas);
|
||||
}
|
||||
}
|
||||
|
||||
final List<Point> convexHull = Jarvis.convexHull(list);
|
||||
if (convexHull == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Polygon polygon = new Polygon();
|
||||
for (final Point hullPoint : convexHull)
|
||||
{
|
||||
polygon.addPoint(hullPoint.getX(), hullPoint.getY());
|
||||
}
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", fontStyle, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX() - 3,
|
||||
canvasPoint.getY() + 6);
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() - 2,
|
||||
canvasPoint.getY() + 7);
|
||||
if (shadows)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
private Point centerPoint(Rectangle rect)
|
||||
{
|
||||
int x = (int) (rect.getX() + rect.getWidth() / 2);
|
||||
int y = (int) (rect.getY() + rect.getHeight() / 2);
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
|
||||
* Copyright (c) 2019, kThisIsCvpv <https://github.com/kThisIsCvpv>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -22,244 +22,430 @@
|
||||
* (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.gauntlet;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SoundEffectID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
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.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.api.events.ProjectileSpawned;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.LIGHTNING;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.MAGIC;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.PRAYER;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.RANGE;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Gauntlet Boss Helper",
|
||||
description = "Prayer Overlay For The Gauntlet Boss",
|
||||
tags = {"gauntlet"},
|
||||
type = PluginType.PVM,
|
||||
enabledByDefault = false
|
||||
name = "Gauntlet",
|
||||
description = "All-in-one plugin for the Gauntlet.",
|
||||
tags = {"Gauntlet"},
|
||||
enabledByDefault = false,
|
||||
type = PluginType.PVM
|
||||
)
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
public class GauntletPlugin extends Plugin
|
||||
{
|
||||
private static final Set<Integer> PLAYER_ANIMATIONS = ImmutableSet.of(426, 1167, 422, 423, 440, 428);
|
||||
private static final Set<Integer> HUNLEFF_ANIMATIONS = ImmutableSet.of(AnimationID.HUNLEFF_ATTACK, AnimationID.HUNLEFF_TORNADO);
|
||||
private static final Set<Integer> HUNLEFF_MAGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLEFF_MAGE_ATTACK, ProjectileID.HUNLEFF_CORRUPTED_MAGE_ATTACK);
|
||||
private static final Set<Integer> HUNLEFF_RANGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLEFF_RANGE_ATTACK, ProjectileID.HUNLEFF_CORRUPTED_RANGE_ATTACK);
|
||||
private static final int BOW_ATTACK = 426;
|
||||
private static final int STAFF_ATTACK = 1167;
|
||||
private static final int LIGHTNING_ANIMATION = 8418;
|
||||
private static final Set<Integer> TORNADO_NPC_IDS = ImmutableSet.of(9025, 9039);
|
||||
private static final Set<Integer> MELEE_ANIMATIONS = ImmutableSet.of(395, 401, 400, 401, 386, 390, 422, 423, 401, 428, 440);
|
||||
private static final Set<Integer> PLAYER_ANIMATIONS = ImmutableSet.of(395, 401, 400, 401, 386, 390, 422, 423, 401, 428, 440, 426, 1167);
|
||||
private static final Set<Integer> HUNLLEF_MAGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_MAGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK);
|
||||
private static final Set<Integer> HUNLLEF_RANGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_RANGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK);
|
||||
private static final Set<Integer> HUNLLEF_PRAYER_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_PRAYER_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK);
|
||||
private static final Set<Integer> HUNLLEF_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_PRAYER_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK,
|
||||
ProjectileID.HUNLLEF_RANGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK, ProjectileID.HUNLLEF_MAGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK
|
||||
);
|
||||
private static final Set<Integer> HUNLLEF_NPC_IDS = ImmutableSet.of(NpcID.CRYSTALLINE_HUNLLEF, NpcID.CRYSTALLINE_HUNLLEF_9022, NpcID.CRYSTALLINE_HUNLLEF_9023,
|
||||
NpcID.CRYSTALLINE_HUNLLEF_9024, NpcID.CORRUPTED_HUNLLEF, NpcID.CORRUPTED_HUNLLEF_9036, NpcID.CORRUPTED_HUNLLEF_9037, NpcID.CORRUPTED_HUNLLEF_9038
|
||||
);
|
||||
private static final Set<Integer> RESOURCES = ImmutableSet.of(ObjectID.CRYSTAL_DEPOSIT, ObjectID.CORRUPT_DEPOSIT, ObjectID.PHREN_ROOTS,
|
||||
ObjectID.PHREN_ROOTS_36066, ObjectID.FISHING_SPOT_36068, ObjectID.FISHING_SPOT_35971, ObjectID.GRYM_ROOT, ObjectID.GRYM_ROOT_36070,
|
||||
ObjectID.LINUM_TIRINUM, ObjectID.LINUM_TIRINUM_36072
|
||||
);
|
||||
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private Client client;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private EventBus eventBus;
|
||||
private ClientThread clientThread;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private OverlayManager overlayManager;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private GauntletInfoBox GauntletInfoBox;
|
||||
private GauntletOverlay overlay;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private GauntletCounter GauntletCounter;
|
||||
private int attacks = 0;
|
||||
private int playerAttacks = 0;
|
||||
private Prayer nextPrayer;
|
||||
private NPC hunllef;
|
||||
private boolean firstHitDetected;
|
||||
private HeadIcon currentPrayer;
|
||||
private GauntletConfig config;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private EventBus eventBus;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private GauntletTimer timer;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private SkillIconManager skillIconManager;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Hunllef hunllef;
|
||||
private final Set<Resources> resources = new HashSet<>();
|
||||
private final Set<Missiles> projectiles = new HashSet<>();
|
||||
private final Map<String, Integer> items = new HashMap<>();
|
||||
private Set<Tornado> tornadoes = new HashSet<>();
|
||||
private boolean completeStartup = false;
|
||||
private boolean countBossAttacks;
|
||||
private boolean countPlayerAttacks;
|
||||
private boolean displayTimerChat;
|
||||
private boolean highlightResources;
|
||||
private boolean highlightResourcesIcons;
|
||||
private boolean highlightWidget;
|
||||
private boolean overlayBoss;
|
||||
private boolean overlayBossPrayer;
|
||||
private boolean overlayTornadoes;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean flash;
|
||||
private boolean flashOnWrongAttack;
|
||||
private Color highlightResourcesColor;
|
||||
private boolean displayTimerWidget;
|
||||
private boolean timerVisible = true;
|
||||
private boolean uniqueAttackVisual;
|
||||
private boolean uniquePrayerAudio;
|
||||
private boolean uniquePrayerVisual;
|
||||
private int resourceIconSize;
|
||||
private int projectileIconSize;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
@Provides
|
||||
GauntletConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
addSubscriptions();
|
||||
overlayManager.add(GauntletInfoBox);
|
||||
overlayManager.add(GauntletCounter);
|
||||
reset();
|
||||
return configManager.getConfig(GauntletConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
protected void startUp()
|
||||
{
|
||||
addSubscriptions();
|
||||
updateConfig();
|
||||
timerVisible = this.displayTimerWidget;
|
||||
timer.resetStates();
|
||||
if (timerVisible)
|
||||
{
|
||||
overlayManager.add(timer);
|
||||
}
|
||||
overlayManager.add(overlay);
|
||||
if (client.getGameState() != GameState.STARTING && client.getGameState() != GameState.UNKNOWN)
|
||||
{
|
||||
completeStartup = false;
|
||||
clientThread.invoke(() -> {
|
||||
timer.initStates();
|
||||
completeStartup = true;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
completeStartup = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
eventBus.unregister(this);
|
||||
overlayManager.remove(GauntletInfoBox);
|
||||
overlayManager.remove(GauntletCounter);
|
||||
reset();
|
||||
timer.resetStates();
|
||||
if (timerVisible)
|
||||
{
|
||||
overlayManager.remove(timer);
|
||||
timerVisible = false;
|
||||
}
|
||||
overlayManager.remove(overlay);
|
||||
resources.clear();
|
||||
projectiles.clear();
|
||||
tornadoes.clear();
|
||||
setHunllef(null);
|
||||
}
|
||||
|
||||
private void addSubscriptions()
|
||||
{
|
||||
eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged);
|
||||
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
|
||||
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
|
||||
eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned);
|
||||
eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned);
|
||||
eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventBus.subscribe(GameTick.class, this, this::onGameTick);
|
||||
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
|
||||
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
|
||||
eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged);
|
||||
}
|
||||
|
||||
private void onAnimationChanged(AnimationChanged event)
|
||||
{
|
||||
if (getHunllef() == null || !isInRoom())
|
||||
final Actor actor = event.getActor();
|
||||
|
||||
// This section handles the player counter.
|
||||
if (actor instanceof Player && fightingBoss())
|
||||
{
|
||||
final Player player = (Player) actor;
|
||||
final int anim = player.getAnimation();
|
||||
|
||||
if (!player.getName().equals(client.getLocalPlayer().getName()) || anim == -1 || !PLAYER_ANIMATIONS.contains(anim))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NPCDefinition comp = hunllef.getNpc().getDefinition();
|
||||
|
||||
if (comp == null || comp.getOverheadIcon() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final HeadIcon prayer = comp.getOverheadIcon();
|
||||
|
||||
switch (prayer)
|
||||
{
|
||||
case MELEE:
|
||||
if (MELEE_ANIMATIONS.contains(anim))
|
||||
{
|
||||
setFlash(true);
|
||||
return;
|
||||
}
|
||||
hunllef.updatePlayerAttack();
|
||||
break;
|
||||
case RANGED:
|
||||
if (BOW_ATTACK == anim)
|
||||
{
|
||||
setFlash(true);
|
||||
return;
|
||||
}
|
||||
hunllef.updatePlayerAttack();
|
||||
break;
|
||||
case MAGIC:
|
||||
if (STAFF_ATTACK == anim)
|
||||
{
|
||||
setFlash(true);
|
||||
return;
|
||||
}
|
||||
hunllef.updatePlayerAttack();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This section handles the boss attack counter if they perform a lightning attack.
|
||||
if (actor instanceof NPC)
|
||||
{
|
||||
final NPC npc = (NPC) actor;
|
||||
|
||||
if (npc.getAnimation() == LIGHTNING_ANIMATION)
|
||||
{
|
||||
hunllef.updateAttack(LIGHTNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!event.getGroup().equals("Gauntlet"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int anim = event.getActor().getAnimation();
|
||||
updateConfig();
|
||||
|
||||
if (HUNLEFF_ANIMATIONS.contains(anim))
|
||||
if (event.getKey().equals("displayTimerWidget"))
|
||||
{
|
||||
setAttacks(getAttacks() + 1);
|
||||
|
||||
if (getAttacks() == 4)
|
||||
if (this.displayTimerWidget && !timerVisible)
|
||||
{
|
||||
if (getNextPrayer() == Prayer.PROTECT_FROM_MISSILES)
|
||||
{
|
||||
log.debug("Attacks are: {}, switching to prot mage", getAttacks());
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MAGIC);
|
||||
}
|
||||
else if (getNextPrayer() == Prayer.PROTECT_FROM_MAGIC)
|
||||
{
|
||||
log.debug("Attacks are: {}, switching to prot missiles", getAttacks());
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MISSILES);
|
||||
}
|
||||
setAttacks(0);
|
||||
overlayManager.add(timer);
|
||||
timerVisible = true;
|
||||
}
|
||||
else if (!this.displayTimerWidget && timerVisible)
|
||||
{
|
||||
overlayManager.remove(timer);
|
||||
timerVisible = false;
|
||||
}
|
||||
}
|
||||
else if (PLAYER_ANIMATIONS.contains(anim))
|
||||
}
|
||||
|
||||
private void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
final GameObject obj = event.getGameObject();
|
||||
if (RESOURCES.contains(obj.getId()))
|
||||
{
|
||||
setPlayerAttacks(getPlayerAttacks() - 1);
|
||||
if (getPlayerAttacks() == 0)
|
||||
{
|
||||
setPlayerAttacks(6);
|
||||
}
|
||||
resources.removeIf(object -> object.getGameObject() == obj);
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject obj = event.getGameObject();
|
||||
if (RESOURCES.contains(obj.getId()))
|
||||
{
|
||||
resources.add(new Resources(obj, event.getTile(), skillIconManager));
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOADING)
|
||||
{
|
||||
resources.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameTick(GameTick event)
|
||||
{
|
||||
if (getHunllef() == null || !isInRoom())
|
||||
// This handles the timer based on player health.
|
||||
if (this.completeStartup)
|
||||
{
|
||||
return;
|
||||
timer.checkStates(false);
|
||||
}
|
||||
|
||||
HeadIcon overhead = getOverheadIcon(getHunllef());
|
||||
|
||||
if (overhead == null)
|
||||
if (!tornadoes.isEmpty())
|
||||
{
|
||||
return;
|
||||
tornadoes.forEach(Tornado::updateTimeLeft);
|
||||
}
|
||||
|
||||
switch (overhead)
|
||||
if (hunllef != null)
|
||||
{
|
||||
case MELEE:
|
||||
case MAGIC:
|
||||
case RANGED:
|
||||
if (currentPrayer == overhead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
currentPrayer = overhead;
|
||||
setPlayerAttacks(6);
|
||||
break;
|
||||
if (hunllef.getTicksUntilAttack() > 0)
|
||||
{
|
||||
hunllef.setTicksUntilAttack(hunllef.getTicksUntilAttack() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
final NPC npc = event.getNpc();
|
||||
|
||||
if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef"))
|
||||
if (HUNLLEF_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
return;
|
||||
setHunllef(null);
|
||||
}
|
||||
else if (TORNADO_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
tornadoes.removeIf(tornado -> tornado.getNpc() == npc);
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
private void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
final NPC npc = event.getNpc();
|
||||
|
||||
if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef"))
|
||||
if (HUNLLEF_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
return;
|
||||
setHunllef(new Hunllef(npc, skillIconManager));
|
||||
}
|
||||
else if (TORNADO_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
tornadoes.add(new Tornado(npc));
|
||||
}
|
||||
|
||||
setPlayerAttacks(6);
|
||||
setAttacks(0);
|
||||
setHunllef(npc);
|
||||
}
|
||||
|
||||
private void onProjectileSpawned(ProjectileSpawned event)
|
||||
{
|
||||
if (getHunllef() == null || !isInRoom() || isFirstHitDetected())
|
||||
if (hunllef == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int projectileID = event.getProjectile().getId();
|
||||
final Projectile proj = event.getProjectile();
|
||||
|
||||
if (HUNLEFF_MAGE_PROJECTILES.contains(projectileID))
|
||||
if (HUNLLEF_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MAGIC);
|
||||
setFirstHitDetected(true);
|
||||
}
|
||||
else if (HUNLEFF_RANGE_PROJECTILES.contains(projectileID))
|
||||
{
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MISSILES);
|
||||
setFirstHitDetected(true);
|
||||
projectiles.add(new Missiles(proj, skillIconManager));
|
||||
if (HUNLLEF_MAGE_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
hunllef.updateAttack(MAGIC);
|
||||
}
|
||||
else if (HUNLLEF_PRAYER_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
hunllef.updateAttack(PRAYER);
|
||||
if (this.uniquePrayerAudio)
|
||||
{
|
||||
client.playSoundEffect(SoundEffectID.MAGIC_SPLASH_BOING);
|
||||
}
|
||||
}
|
||||
else if (HUNLLEF_RANGE_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
hunllef.updateAttack(RANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void reset()
|
||||
private void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
setHunllef(null);
|
||||
setNextPrayer(null);
|
||||
setCurrentPrayer(null);
|
||||
setFirstHitDetected(false);
|
||||
setAttacks(0);
|
||||
setPlayerAttacks(6);
|
||||
}
|
||||
|
||||
private HeadIcon getOverheadIcon(NPC npc)
|
||||
{
|
||||
NPCDefinition composition = npc.getDefinition();
|
||||
if (composition != null)
|
||||
if (this.completeStartup)
|
||||
{
|
||||
return composition.getOverheadIcon();
|
||||
timer.checkStates(true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isInRoom()
|
||||
boolean fightingBoss()
|
||||
{
|
||||
return client.getVar(Varbits.GAUNTLET_FINAL_ROOM_ENTERED) == 1;
|
||||
}
|
||||
|
||||
boolean startedGauntlet()
|
||||
{
|
||||
return client.getVar(Varbits.GAUNTLET_ENTERED) == 1;
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.highlightResources = config.highlightResources();
|
||||
this.highlightResourcesColor = config.highlightResourcesColor();
|
||||
this.highlightResourcesIcons = config.highlightResourcesIcons();
|
||||
this.flashOnWrongAttack = config.flashOnWrongAttack();
|
||||
this.highlightWidget = config.highlightWidget();
|
||||
this.resourceIconSize = config.resourceIconSize();
|
||||
this.projectileIconSize = config.projectileIconSize();
|
||||
this.countBossAttacks = config.countBossAttacks();
|
||||
this.countPlayerAttacks = config.countPlayerAttacks();
|
||||
this.uniquePrayerAudio = config.uniquePrayerAudio();
|
||||
this.uniquePrayerVisual = config.uniquePrayerVisual();
|
||||
this.uniqueAttackVisual = config.uniqueAttackVisual();
|
||||
this.overlayBoss = config.overlayBoss();
|
||||
this.overlayBossPrayer = config.overlayBossPrayer();
|
||||
this.overlayTornadoes = config.overlayTornadoes();
|
||||
this.displayTimerWidget = config.displayTimerWidget();
|
||||
this.displayTimerChat = config.displayTimerChat();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.QueuedMessage;
|
||||
import static net.runelite.client.plugins.gauntlet.GauntletTimer.RaidState.IN_BOSS;
|
||||
import static net.runelite.client.plugins.gauntlet.GauntletTimer.RaidState.IN_RAID;
|
||||
import static net.runelite.client.plugins.gauntlet.GauntletTimer.RaidState.UNKNOWN;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
|
||||
class GauntletTimer extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final GauntletPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
private long timeRaidStart = -1L;
|
||||
private long timeBossEnter = -1L;
|
||||
private RaidState currentState = UNKNOWN;
|
||||
|
||||
@Inject
|
||||
public GauntletTimer(Client client, GauntletPlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
|
||||
setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Gauntlet Timer Overlay"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the timer.
|
||||
*/
|
||||
void resetStates()
|
||||
{
|
||||
timeRaidStart = -1L;
|
||||
timeBossEnter = -1L;
|
||||
|
||||
currentState = UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the player resets the plugin mid-raid. We do not want to confuse the timer.
|
||||
* <p>
|
||||
* TODO: Originally, this function will disable the timer if the plugin is started mid raid.
|
||||
* Unfortunately, VARBITS can't be checked unless you're on the client thread.
|
||||
* I've no idea how to access RL's task handler.
|
||||
* Good luck to you. If you restart plugin mid raid, oh well. Your timer's going to be inaccurate.
|
||||
*/
|
||||
void initStates()
|
||||
{
|
||||
timeRaidStart = -1L;
|
||||
timeBossEnter = -1L;
|
||||
|
||||
if (plugin.startedGauntlet())
|
||||
{
|
||||
currentState = IN_RAID;
|
||||
if (plugin.fightingBoss())
|
||||
{
|
||||
currentState = IN_BOSS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentState = UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the different between two epoch times into minutes:seconds format.
|
||||
*
|
||||
* @param epochA long
|
||||
* @param epochB long
|
||||
* @return String
|
||||
*/
|
||||
private String calculateElapsedTime(long epochA, long epochB)
|
||||
{
|
||||
long max = Math.max(epochA, epochB);
|
||||
long min = Math.min(epochA, epochB);
|
||||
|
||||
long elapsedEpoch = max - min;
|
||||
long seconds = elapsedEpoch / 1000L;
|
||||
|
||||
long minutes = seconds / 60L;
|
||||
seconds = seconds % 60;
|
||||
|
||||
if (seconds == 0)
|
||||
{
|
||||
return minutes + ":00";
|
||||
}
|
||||
|
||||
if (seconds < 10)
|
||||
{
|
||||
return minutes + ":0" + seconds;
|
||||
}
|
||||
|
||||
return minutes + ":" + seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when varbit changes. See if the the raid state has changed.
|
||||
*/
|
||||
void checkStates(boolean checkVarps)
|
||||
{
|
||||
final Player p = client.getLocalPlayer();
|
||||
|
||||
if (p == null || !plugin.isCompleteStartup())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkVarps)
|
||||
{
|
||||
switch (currentState)
|
||||
{
|
||||
case UNKNOWN:
|
||||
if (plugin.startedGauntlet() && p.getHealthRatio() != 0)
|
||||
{
|
||||
// Player has started a new raid.
|
||||
if (!plugin.fightingBoss())
|
||||
{
|
||||
currentState = IN_RAID;
|
||||
timeRaidStart = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
currentState = IN_RAID;
|
||||
timeRaidStart = timeBossEnter = System.currentTimeMillis();
|
||||
}
|
||||
break;
|
||||
case IN_RAID:
|
||||
if (!plugin.startedGauntlet())
|
||||
{
|
||||
printPrepTime();
|
||||
resetStates();
|
||||
return;
|
||||
}
|
||||
if (plugin.fightingBoss())
|
||||
{
|
||||
// Player has begun the boss fight.
|
||||
printPrepTime();
|
||||
currentState = IN_BOSS;
|
||||
timeBossEnter = System.currentTimeMillis();
|
||||
}
|
||||
break;
|
||||
case IN_BOSS:
|
||||
if (!plugin.fightingBoss() || !plugin.startedGauntlet())
|
||||
{
|
||||
// Player has killed the boss.
|
||||
resetStates();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentState == IN_BOSS && p.getHealthRatio() == 0)
|
||||
{
|
||||
printBossTime();
|
||||
resetStates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void printPrepTime()
|
||||
{
|
||||
if (!plugin.isDisplayTimerChat() || timeRaidStart == -1L)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String elapsedTime = calculateElapsedTime(System.currentTimeMillis(), timeRaidStart);
|
||||
|
||||
final ChatMessageBuilder prepmessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append("Preparation time: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedTime);
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(prepmessage.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
private void printBossTime()
|
||||
{
|
||||
if (!plugin.isDisplayTimerChat() || timeRaidStart == -1L || timeBossEnter == -1L)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String elapsedBossTime = calculateElapsedTime(System.currentTimeMillis(), timeBossEnter);
|
||||
String elapsedPrepTime = calculateElapsedTime(timeRaidStart, timeBossEnter);
|
||||
String elapsedTotalTime = calculateElapsedTime(System.currentTimeMillis(), timeRaidStart);
|
||||
|
||||
final ChatMessageBuilder challengedurationmessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append("Challenge duration: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedTotalTime);
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(challengedurationmessage.build())
|
||||
.build());
|
||||
|
||||
final ChatMessageBuilder prepdeathmessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append("Preparation time: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedPrepTime)
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(" player/boss death time: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedBossTime);
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(prepdeathmessage.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (currentState == UNKNOWN)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text("Gauntlet Timer").color(Color.WHITE).build());
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
|
||||
if (timeRaidStart == -1L)
|
||||
{ // User restarted the plugin mid raid. Timer is inaccurate.
|
||||
tableComponent.addRow("Inactive", "0:00");
|
||||
}
|
||||
else
|
||||
{
|
||||
String elapsedPrepTime, elapsedBossTime, elapsedTotalTime;
|
||||
elapsedTotalTime = calculateElapsedTime(System.currentTimeMillis(), timeRaidStart);
|
||||
|
||||
if (currentState == IN_RAID)
|
||||
{
|
||||
elapsedPrepTime = calculateElapsedTime(timeRaidStart, System.currentTimeMillis());
|
||||
elapsedBossTime = "0:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
elapsedPrepTime = calculateElapsedTime(timeRaidStart, timeBossEnter);
|
||||
elapsedBossTime = calculateElapsedTime(System.currentTimeMillis(), timeBossEnter);
|
||||
}
|
||||
tableComponent.addRow("Preparation", elapsedPrepTime);
|
||||
tableComponent.addRow("Boss Fight", elapsedBossTime);
|
||||
tableComponent.addRow("Total Time", elapsedTotalTime);
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
}
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
public enum RaidState
|
||||
{
|
||||
UNKNOWN, IN_RAID, IN_BOSS
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
public class Hunllef
|
||||
{
|
||||
private NPC npc;
|
||||
private int bossAttacks;
|
||||
private int playerAttacks;
|
||||
private int ticksUntilAttack;
|
||||
private BufferedImage mage;
|
||||
private BufferedImage range;
|
||||
private BossAttackPhase currentPhase;
|
||||
|
||||
Hunllef(NPC npc, SkillIconManager skillIconManager)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.bossAttacks = 0;
|
||||
this.playerAttacks = 6;
|
||||
this.ticksUntilAttack = 0;
|
||||
this.mage = skillIconManager.getSkillImage(Skill.MAGIC);
|
||||
this.range = skillIconManager.getSkillImage(Skill.RANGED);
|
||||
this.currentPhase = BossAttackPhase.UNKNOWN;
|
||||
}
|
||||
|
||||
void updatePlayerAttack()
|
||||
{
|
||||
playerAttacks--;
|
||||
if (playerAttacks <= 0)
|
||||
{
|
||||
playerAttacks = 6;
|
||||
}
|
||||
}
|
||||
|
||||
void updateAttack(BossAttack style)
|
||||
{
|
||||
ticksUntilAttack = 6;
|
||||
if (style == BossAttack.PRAYER)
|
||||
{
|
||||
style = BossAttack.MAGIC;
|
||||
}
|
||||
|
||||
if (style == BossAttack.LIGHTNING)
|
||||
{
|
||||
bossAttacks--;
|
||||
}
|
||||
else if (style == BossAttack.RANGE)
|
||||
{
|
||||
if (currentPhase != BossAttackPhase.RANGE)
|
||||
{
|
||||
currentPhase = BossAttackPhase.RANGE;
|
||||
bossAttacks = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
bossAttacks--;
|
||||
}
|
||||
}
|
||||
else if (style == BossAttack.MAGIC)
|
||||
{
|
||||
if (currentPhase != BossAttackPhase.MAGIC)
|
||||
{
|
||||
currentPhase = BossAttackPhase.MAGIC;
|
||||
bossAttacks = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
bossAttacks--;
|
||||
}
|
||||
}
|
||||
|
||||
if (bossAttacks <= 0)
|
||||
{
|
||||
BossAttackPhase nextPhase;
|
||||
|
||||
switch (currentPhase)
|
||||
{
|
||||
case MAGIC:
|
||||
bossAttacks = 4;
|
||||
nextPhase = BossAttackPhase.RANGE;
|
||||
break;
|
||||
case RANGE:
|
||||
bossAttacks = 4;
|
||||
nextPhase = BossAttackPhase.MAGIC;
|
||||
break;
|
||||
default:
|
||||
bossAttacks = 0;
|
||||
nextPhase = BossAttackPhase.UNKNOWN;
|
||||
break;
|
||||
}
|
||||
currentPhase = nextPhase;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
enum BossAttackPhase
|
||||
{
|
||||
MAGIC(Color.CYAN, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE(Color.GREEN, Prayer.PROTECT_FROM_MISSILES),
|
||||
UNKNOWN(Color.WHITE, null);
|
||||
|
||||
private Color color;
|
||||
private Prayer prayer;
|
||||
}
|
||||
|
||||
enum BossAttack
|
||||
{
|
||||
MAGIC,
|
||||
RANGE,
|
||||
PRAYER,
|
||||
LIGHTNING
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class Missiles
|
||||
{
|
||||
private Projectile projectile;
|
||||
private int id;
|
||||
private BufferedImage image;
|
||||
private Color color;
|
||||
|
||||
Missiles(Projectile projectile, SkillIconManager skillIconManager)
|
||||
{
|
||||
this.projectile = projectile;
|
||||
this.id = projectile.getId();
|
||||
this.image = assignedImage(skillIconManager, id);
|
||||
this.color = assignedColor(id);
|
||||
}
|
||||
|
||||
private Color assignedColor(int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case ProjectileID.HUNLLEF_MAGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK:
|
||||
return Color.CYAN;
|
||||
case ProjectileID.HUNLLEF_RANGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK:
|
||||
return Color.GREEN;
|
||||
case ProjectileID.HUNLLEF_PRAYER_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK:
|
||||
return Color.MAGENTA;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage assignedImage(SkillIconManager SkillIconManager, int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case ProjectileID.HUNLLEF_MAGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK:
|
||||
return SkillIconManager.getSkillImage(Skill.MAGIC);
|
||||
case ProjectileID.HUNLLEF_RANGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK:
|
||||
return SkillIconManager.getSkillImage(Skill.RANGED);
|
||||
case ProjectileID.HUNLLEF_PRAYER_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK:
|
||||
return SkillIconManager.getSkillImage(Skill.PRAYER);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class Resources
|
||||
{
|
||||
private GameObject gameObject;
|
||||
private Tile tile;
|
||||
private BufferedImage image;
|
||||
|
||||
Resources(GameObject object, Tile tile, SkillIconManager skillIconManager)
|
||||
{
|
||||
this.gameObject = object;
|
||||
this.tile = tile;
|
||||
this.image = assignedImage(skillIconManager, object.getId());
|
||||
}
|
||||
|
||||
private BufferedImage assignedImage(SkillIconManager SkillIconManager, int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case ObjectID.CRYSTAL_DEPOSIT:
|
||||
case ObjectID.CORRUPT_DEPOSIT:
|
||||
return SkillIconManager.getSkillImage(Skill.MINING);
|
||||
case ObjectID.PHREN_ROOTS:
|
||||
case ObjectID.PHREN_ROOTS_36066:
|
||||
return SkillIconManager.getSkillImage(Skill.WOODCUTTING);
|
||||
case ObjectID.FISHING_SPOT_36068:
|
||||
case ObjectID.FISHING_SPOT_35971:
|
||||
return SkillIconManager.getSkillImage(Skill.FISHING);
|
||||
case ObjectID.GRYM_ROOT:
|
||||
case ObjectID.GRYM_ROOT_36070:
|
||||
return SkillIconManager.getSkillImage(Skill.HERBLORE);
|
||||
case ObjectID.LINUM_TIRINUM:
|
||||
case ObjectID.LINUM_TIRINUM_36072:
|
||||
return SkillIconManager.getSkillImage(Skill.FARMING);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -22,21 +21,30 @@
|
||||
* (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.gauntlet;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
|
||||
public interface GauntletPluginConfig extends Config
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class Tornado
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "gauntletEnable",
|
||||
name = "Enable gauntlet",
|
||||
description = "gauntlet boss prayer"
|
||||
)
|
||||
default boolean enableGauntlet()
|
||||
private NPC npc;
|
||||
private int timeLeft;
|
||||
|
||||
Tornado(NPC npc)
|
||||
{
|
||||
return true;
|
||||
this.npc = npc;
|
||||
this.timeLeft = 20;
|
||||
}
|
||||
}
|
||||
|
||||
void updateTimeLeft()
|
||||
{
|
||||
if (timeLeft > 0)
|
||||
{
|
||||
timeLeft--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,11 +136,11 @@ class GrandExchangeOfferSlot extends JPanel
|
||||
|
||||
itemName.setForeground(Color.WHITE);
|
||||
itemName.setVerticalAlignment(JLabel.BOTTOM);
|
||||
itemName.setFont(FontManager.getSmallFont(getFont()));
|
||||
itemName.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
offerInfo.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
offerInfo.setVerticalAlignment(JLabel.TOP);
|
||||
offerInfo.setFont(FontManager.getSmallFont(getFont()));
|
||||
offerInfo.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel switchFaceViewIcon = new JLabel();
|
||||
switchFaceViewIcon.setIcon(RIGHT_ARROW_ICON);
|
||||
@@ -172,11 +172,11 @@ class GrandExchangeOfferSlot extends JPanel
|
||||
|
||||
itemPrice.setForeground(Color.WHITE);
|
||||
itemPrice.setVerticalAlignment(JLabel.BOTTOM);
|
||||
itemPrice.setFont(FontManager.getSmallFont(getFont()));
|
||||
itemPrice.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
offerSpent.setForeground(Color.WHITE);
|
||||
offerSpent.setVerticalAlignment(JLabel.TOP);
|
||||
offerSpent.setFont(FontManager.getSmallFont(getFont()));
|
||||
offerSpent.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel switchDetailsViewIcon = new JLabel();
|
||||
switchDetailsViewIcon.setIcon(LEFT_ARROW_ICON);
|
||||
|
||||
@@ -109,6 +109,8 @@ public class GroundItemsOverlay extends Overlay
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final FontMetrics fm = graphics.getFontMetrics();
|
||||
final Player player = client.getLocalPlayer();
|
||||
|
||||
if (player == null || client.getViewportWidget() == null)
|
||||
@@ -116,8 +118,6 @@ public class GroundItemsOverlay extends Overlay
|
||||
return null;
|
||||
}
|
||||
|
||||
final FontMetrics fm = graphics.getFontMetrics();
|
||||
|
||||
offsetMap.clear();
|
||||
final LocalPoint localLocation = player.getLocalLocation();
|
||||
final Point mousePos = client.getMouseCanvasPosition();
|
||||
@@ -319,14 +319,14 @@ public class GroundItemsOverlay extends Overlay
|
||||
|
||||
// Item bounds
|
||||
int x = textX - 2;
|
||||
int y = textY - stringHeight - 2 + fm.getMaxDescent();
|
||||
int y = textY - stringHeight - 2;
|
||||
int width = stringWidth + 4;
|
||||
int height = stringHeight + 4;
|
||||
final Rectangle itemBounds = new Rectangle(x, y, width, height);
|
||||
|
||||
// Hidden box
|
||||
x += width + 2;
|
||||
y = textY - (fm.getMaxAscent() + RECTANGLE_SIZE) / 2;
|
||||
y = textY - (RECTANGLE_SIZE + stringHeight) / 2;
|
||||
width = height = RECTANGLE_SIZE;
|
||||
final Rectangle itemHiddenBox = new Rectangle(x, y, width, height);
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ public class HiscorePanel extends PluginPanel
|
||||
private JPanel makeSkillPanel(HiscoreSkill skill)
|
||||
{
|
||||
JLabel label = new JLabel();
|
||||
label.setFont(FontManager.getSmallFont(getFont()));
|
||||
label.setFont(FontManager.getRunescapeSmallFont());
|
||||
label.setText("--");
|
||||
|
||||
String skillName = (skill == null ? "combat" : skill.getName().toLowerCase());
|
||||
|
||||
@@ -195,11 +195,12 @@ public class IdleNotifierPlugin extends Plugin
|
||||
case WOODCUTTING_DRAGON:
|
||||
case WOODCUTTING_INFERNAL:
|
||||
case WOODCUTTING_3A_AXE:
|
||||
/* Cooking(Fire, Range) */
|
||||
case WOODCUTTING_CRYSTAL:
|
||||
/* Cooking(Fire, Range) */
|
||||
case COOKING_FIRE:
|
||||
case COOKING_RANGE:
|
||||
case COOKING_WINE:
|
||||
/* Crafting(Gem Cutting, Glassblowing, Spinning, Battlestaves, Pottery) */
|
||||
/* Crafting(Gem Cutting, Glassblowing, Spinning, Battlestaves, Pottery) */
|
||||
case GEM_CUTTING_OPAL:
|
||||
case GEM_CUTTING_JADE:
|
||||
case GEM_CUTTING_REDTOPAZ:
|
||||
@@ -214,7 +215,7 @@ public class IdleNotifierPlugin extends Plugin
|
||||
case CRAFTING_LEATHER:
|
||||
case CRAFTING_POTTERS_WHEEL:
|
||||
case CRAFTING_POTTERY_OVEN:
|
||||
/* Fletching(Cutting, Stringing) */
|
||||
/* Fletching(Cutting, Stringing, Adding feathers and heads) */
|
||||
case FLETCHING_BOW_CUTTING:
|
||||
case FLETCHING_STRING_NORMAL_SHORTBOW:
|
||||
case FLETCHING_STRING_OAK_SHORTBOW:
|
||||
@@ -228,11 +229,13 @@ public class IdleNotifierPlugin extends Plugin
|
||||
case FLETCHING_STRING_MAPLE_LONGBOW:
|
||||
case FLETCHING_STRING_YEW_LONGBOW:
|
||||
case FLETCHING_STRING_MAGIC_LONGBOW:
|
||||
/* Smithing(Anvil, Furnace, Cannonballs */
|
||||
case FLETCHING_ATTACH_FEATHERS_TO_ARROWSHAFT:
|
||||
case FLETCHING_ATTACH_HEADS:
|
||||
/* Smithing(Anvil, Furnace, Cannonballs */
|
||||
case SMITHING_ANVIL:
|
||||
case SMITHING_SMELTING:
|
||||
case SMITHING_CANNONBALL:
|
||||
/* Fishing */
|
||||
/* Fishing */
|
||||
case FISHING_CRUSHING_INFERNAL_EELS:
|
||||
case FISHING_CUTTING_SACRED_EELS:
|
||||
case FISHING_BIG_NET:
|
||||
@@ -246,7 +249,7 @@ public class IdleNotifierPlugin extends Plugin
|
||||
case FISHING_OILY_ROD:
|
||||
case FISHING_KARAMBWAN:
|
||||
case FISHING_BAREHAND:
|
||||
/* Mining(Normal) */
|
||||
/* Mining(Normal) */
|
||||
case MINING_BRONZE_PICKAXE:
|
||||
case MINING_IRON_PICKAXE:
|
||||
case MINING_STEEL_PICKAXE:
|
||||
@@ -255,16 +258,32 @@ public class IdleNotifierPlugin extends Plugin
|
||||
case MINING_ADAMANT_PICKAXE:
|
||||
case MINING_RUNE_PICKAXE:
|
||||
case MINING_DRAGON_PICKAXE:
|
||||
case MINING_DRAGON_PICKAXE_ORN:
|
||||
case MINING_DRAGON_PICKAXE_UPGRADED:
|
||||
case MINING_DRAGON_PICKAXE_OR:
|
||||
case MINING_INFERNAL_PICKAXE:
|
||||
case MINING_3A_PICKAXE:
|
||||
case MINING_CRYSTAL_PICKAXE:
|
||||
case DENSE_ESSENCE_CHIPPING:
|
||||
case DENSE_ESSENCE_CHISELING:
|
||||
/* Herblore */
|
||||
/* Mining(Motherlode) */
|
||||
case MINING_MOTHERLODE_BRONZE:
|
||||
case MINING_MOTHERLODE_IRON:
|
||||
case MINING_MOTHERLODE_STEEL:
|
||||
case MINING_MOTHERLODE_BLACK:
|
||||
case MINING_MOTHERLODE_MITHRIL:
|
||||
case MINING_MOTHERLODE_ADAMANT:
|
||||
case MINING_MOTHERLODE_RUNE:
|
||||
case MINING_MOTHERLODE_DRAGON:
|
||||
case MINING_MOTHERLODE_DRAGON_UPGRADED:
|
||||
case MINING_MOTHERLODE_DRAGON_OR:
|
||||
case MINING_MOTHERLODE_INFERNAL:
|
||||
case MINING_MOTHERLODE_3A:
|
||||
case MINING_MOTHERLODE_CRYSTAL:
|
||||
/* Herblore */
|
||||
case HERBLORE_PESTLE_AND_MORTAR:
|
||||
case HERBLORE_POTIONMAKING:
|
||||
case HERBLORE_MAKE_TAR:
|
||||
/* Magic */
|
||||
/* Magic */
|
||||
case MAGIC_CHARGING_ORBS:
|
||||
case MAGIC_LUNAR_PLANK_MAKE:
|
||||
case MAGIC_LUNAR_STRING_JEWELRY:
|
||||
@@ -273,16 +292,16 @@ public class IdleNotifierPlugin extends Plugin
|
||||
case MAGIC_ENCHANTING_AMULET_1:
|
||||
case MAGIC_ENCHANTING_AMULET_2:
|
||||
case MAGIC_ENCHANTING_AMULET_3:
|
||||
/* Prayer */
|
||||
/* Prayer */
|
||||
case USING_GILDED_ALTAR:
|
||||
/* Farming */
|
||||
/* Farming */
|
||||
case FARMING_MIX_ULTRACOMPOST:
|
||||
case FARMING_HARVEST_BUSH:
|
||||
case FARMING_HARVEST_HERB:
|
||||
case FARMING_HARVEST_FRUIT_TREE:
|
||||
case FARMING_HARVEST_FLOWER:
|
||||
case FARMING_HARVEST_ALLOTMENT:
|
||||
/* Misc */
|
||||
/* Misc */
|
||||
case PISCARILIUS_CRANE_REPAIR:
|
||||
case HOME_MAKE_TABLET:
|
||||
case SAND_COLLECTION:
|
||||
|
||||
@@ -60,7 +60,7 @@ enum Impling
|
||||
|
||||
NINJA(ImplingType.NINJA, NpcID.NINJA_IMPLING),
|
||||
NINJA_2(ImplingType.NINJA, NpcID.NINJA_IMPLING_1653),
|
||||
|
||||
|
||||
CRYSTAL(ImplingType.CRYSTAL, NpcID.CRYSTAL_IMPLING),
|
||||
CRYSTAL_2(ImplingType.CRYSTAL, NpcID.CRYSTAL_IMPLING_8742),
|
||||
CRYSTAL_3(ImplingType.CRYSTAL, NpcID.CRYSTAL_IMPLING_8743),
|
||||
@@ -78,7 +78,6 @@ enum Impling
|
||||
CRYSTAL_15(ImplingType.CRYSTAL, NpcID.CRYSTAL_IMPLING_8755),
|
||||
CRYSTAL_16(ImplingType.CRYSTAL, NpcID.CRYSTAL_IMPLING_8756),
|
||||
CRYSTAL_17(ImplingType.CRYSTAL, NpcID.CRYSTAL_IMPLING_8757),
|
||||
|
||||
|
||||
DRAGON(ImplingType.DRAGON, NpcID.DRAGON_IMPLING),
|
||||
DRAGON_2(ImplingType.DRAGON, NpcID.DRAGON_IMPLING_1654),
|
||||
@@ -86,8 +85,6 @@ enum Impling
|
||||
LUCKY(ImplingType.LUCKY, NpcID.LUCKY_IMPLING),
|
||||
LUCKY_2(ImplingType.LUCKY, NpcID.LUCKY_IMPLING_7302);
|
||||
|
||||
|
||||
|
||||
private ImplingType implingType;
|
||||
private final int npcId;
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ public interface ImplingsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 19,
|
||||
keyName = "showcrystal",
|
||||
keyName = "showCrystal",
|
||||
name = "Show Crystal implings",
|
||||
description = "Configures whether or not Crystal impling tags are displayed"
|
||||
)
|
||||
@@ -252,7 +252,7 @@ public interface ImplingsConfig extends Config
|
||||
)
|
||||
default Color getCrystalColor()
|
||||
{
|
||||
return new Color(2, 255, 251);
|
||||
return new Color(93, 188, 210);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
|
||||
@@ -309,6 +309,7 @@ public class ImplingsPlugin extends Plugin
|
||||
return this.getNinjaColor;
|
||||
case CRYSTAL:
|
||||
return this.getCrystalColor;
|
||||
|
||||
case DRAGON:
|
||||
return this.getDragonColor;
|
||||
case LUCKY:
|
||||
|
||||
@@ -117,7 +117,7 @@ public class InfoPanel extends PluginPanel
|
||||
versionPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
versionPanel.setLayout(new GridLayout(0, 1));
|
||||
|
||||
final Font smallFont = FontManager.getSmallFont(getFont());
|
||||
final Font smallFont = FontManager.getRunescapeSmallFont();
|
||||
|
||||
JLabel version = new JLabel(htmlLabel("RuneLite version: ", runeLiteProperties.getVersion()));
|
||||
version.setFont(smallFont);
|
||||
@@ -207,7 +207,7 @@ public class InfoPanel extends PluginPanel
|
||||
/**
|
||||
* Builds a link panel with a given icon, text and url to redirect to.
|
||||
*/
|
||||
private JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, String url)
|
||||
private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, String url)
|
||||
{
|
||||
return buildLinkPanel(icon, topText, bottomText, () -> LinkBrowser.browse(url));
|
||||
}
|
||||
@@ -215,7 +215,7 @@ public class InfoPanel extends PluginPanel
|
||||
/**
|
||||
* Builds a link panel with a given icon, text and callable to call.
|
||||
*/
|
||||
private JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, Runnable callback)
|
||||
private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, Runnable callback)
|
||||
{
|
||||
JPanel container = new JPanel();
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
@@ -269,11 +269,11 @@ public class InfoPanel extends PluginPanel
|
||||
|
||||
JLabel topLine = new JLabel(topText);
|
||||
topLine.setForeground(Color.WHITE);
|
||||
topLine.setFont(FontManager.getSmallFont(getFont()));
|
||||
topLine.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel bottomLine = new JLabel(bottomText);
|
||||
bottomLine.setForeground(Color.WHITE);
|
||||
bottomLine.setFont(FontManager.getSmallFont(getFont()));
|
||||
bottomLine.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
textContainer.add(topLine);
|
||||
textContainer.add(bottomLine);
|
||||
|
||||
@@ -170,7 +170,7 @@ class ItemChargeOverlay extends WidgetItemOverlay
|
||||
|
||||
final Rectangle bounds = itemWidget.getCanvasBounds();
|
||||
final TextComponent textComponent = new TextComponent();
|
||||
textComponent.setPosition(new Point(bounds.x, bounds.y + 1 + graphics.getFontMetrics().getMaxAscent() - graphics.getFontMetrics().getMaxDescent()));
|
||||
textComponent.setPosition(new Point(bounds.x - 1, bounds.y + 15));
|
||||
textComponent.setText(charges < 0 ? "?" : String.valueOf(charges));
|
||||
textComponent.setColor(plugin.getColor(charges));
|
||||
textComponent.render(graphics);
|
||||
|
||||
@@ -72,6 +72,7 @@ enum ItemIdentification
|
||||
MAGIC_SAPLING(Type.SAPLING, "Magic", "MAG", ItemID.MAGIC_SAPLING, ItemID.MAGIC_SEEDLING, ItemID.MAGIC_SEEDLING_W),
|
||||
REDWOOD_SAPLING(Type.SAPLING, "Red", "RED", ItemID.REDWOOD_SAPLING, ItemID.REDWOOD_SEEDLING, ItemID.REDWOOD_SEEDLING_W),
|
||||
SPIRIT_SAPLING(Type.SAPLING, "Spirit", "SPI", ItemID.SPIRIT_SAPLING, ItemID.SPIRIT_SEEDLING, ItemID.SPIRIT_SEEDLING_W),
|
||||
CRYSTAL_SAPLING(Type.SAPLING, "Crystal", "CRY", ItemID.CRYSTAL_SAPLING, ItemID.CRYSTAL_SEEDLING, ItemID.CRYSTAL_SEEDLING_W),
|
||||
|
||||
APPLE_SAPLING(Type.SAPLING, "Apple", "APP", ItemID.APPLE_SAPLING, ItemID.APPLE_SEEDLING, ItemID.APPLE_SEEDLING_W),
|
||||
BANANA_SAPLING(Type.SAPLING, "Banana", "BAN", ItemID.BANANA_SAPLING, ItemID.BANANA_SEEDLING, ItemID.BANANA_SEEDLING_W),
|
||||
|
||||
@@ -30,426 +30,16 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import static net.runelite.api.ItemID.ADMIRAL_PIE;
|
||||
import static net.runelite.api.ItemID.AGILITY_POTION1;
|
||||
import static net.runelite.api.ItemID.AGILITY_POTION2;
|
||||
import static net.runelite.api.ItemID.AGILITY_POTION3;
|
||||
import static net.runelite.api.ItemID.AGILITY_POTION4;
|
||||
import static net.runelite.api.ItemID.ANCHOVIES;
|
||||
import static net.runelite.api.ItemID.ANCHOVY_PIZZA;
|
||||
import static net.runelite.api.ItemID.ANGLERFISH;
|
||||
import static net.runelite.api.ItemID.APPLE_PIE;
|
||||
import static net.runelite.api.ItemID.ATTACK_POTION1;
|
||||
import static net.runelite.api.ItemID.ATTACK_POTION2;
|
||||
import static net.runelite.api.ItemID.ATTACK_POTION3;
|
||||
import static net.runelite.api.ItemID.ATTACK_POTION4;
|
||||
import static net.runelite.api.ItemID.AUTUMN_SQIRKJUICE;
|
||||
import static net.runelite.api.ItemID.BAGUETTE;
|
||||
import static net.runelite.api.ItemID.BAKED_POTATO;
|
||||
import static net.runelite.api.ItemID.BANANA;
|
||||
import static net.runelite.api.ItemID.BANDAGES;
|
||||
import static net.runelite.api.ItemID.BASS;
|
||||
import static net.runelite.api.ItemID.BASTION_POTION1;
|
||||
import static net.runelite.api.ItemID.BASTION_POTION2;
|
||||
import static net.runelite.api.ItemID.BASTION_POTION3;
|
||||
import static net.runelite.api.ItemID.BASTION_POTION4;
|
||||
import static net.runelite.api.ItemID.BATTLEMAGE_POTION1;
|
||||
import static net.runelite.api.ItemID.BATTLEMAGE_POTION2;
|
||||
import static net.runelite.api.ItemID.BATTLEMAGE_POTION3;
|
||||
import static net.runelite.api.ItemID.BATTLEMAGE_POTION4;
|
||||
import static net.runelite.api.ItemID.BAT_SHISH;
|
||||
import static net.runelite.api.ItemID.BOTANICAL_PIE;
|
||||
import static net.runelite.api.ItemID.BOTTLE_OF_WINE;
|
||||
import static net.runelite.api.ItemID.BRAWK_FISH_3;
|
||||
import static net.runelite.api.ItemID.BREAD;
|
||||
import static net.runelite.api.ItemID.CABBAGE;
|
||||
import static net.runelite.api.ItemID.CABBAGE_1967;
|
||||
import static net.runelite.api.ItemID.CAKE;
|
||||
import static net.runelite.api.ItemID.CAVE_EEL;
|
||||
import static net.runelite.api.ItemID.CAVIAR;
|
||||
import static net.runelite.api.ItemID.CHEESE;
|
||||
import static net.runelite.api.ItemID.CHEESETOM_BATTA;
|
||||
import static net.runelite.api.ItemID.CHILLI_CON_CARNE;
|
||||
import static net.runelite.api.ItemID.CHILLI_POTATO;
|
||||
import static net.runelite.api.ItemID.CHOCCHIP_CRUNCHIES;
|
||||
import static net.runelite.api.ItemID.CHOCICE;
|
||||
import static net.runelite.api.ItemID.CHOCOLATEY_MILK;
|
||||
import static net.runelite.api.ItemID.CHOCOLATE_BAR;
|
||||
import static net.runelite.api.ItemID.CHOCOLATE_BOMB;
|
||||
import static net.runelite.api.ItemID.CHOCOLATE_CAKE;
|
||||
import static net.runelite.api.ItemID.CHOCOLATE_SLICE;
|
||||
import static net.runelite.api.ItemID.CHOC_SATURDAY;
|
||||
import static net.runelite.api.ItemID.CHOPPED_ONION;
|
||||
import static net.runelite.api.ItemID.CHOPPED_TOMATO;
|
||||
import static net.runelite.api.ItemID.CHOPPED_TUNA;
|
||||
import static net.runelite.api.ItemID.COATED_FROGS_LEGS;
|
||||
import static net.runelite.api.ItemID.COD;
|
||||
import static net.runelite.api.ItemID.COMBAT_POTION1;
|
||||
import static net.runelite.api.ItemID.COMBAT_POTION2;
|
||||
import static net.runelite.api.ItemID.COMBAT_POTION3;
|
||||
import static net.runelite.api.ItemID.COMBAT_POTION4;
|
||||
import static net.runelite.api.ItemID.COOKED_CHICKEN;
|
||||
import static net.runelite.api.ItemID.COOKED_CHOMPY;
|
||||
import static net.runelite.api.ItemID.COOKED_CRAB_MEAT;
|
||||
import static net.runelite.api.ItemID.COOKED_FISHCAKE;
|
||||
import static net.runelite.api.ItemID.COOKED_JUBBLY;
|
||||
import static net.runelite.api.ItemID.COOKED_KARAMBWAN;
|
||||
import static net.runelite.api.ItemID.COOKED_MEAT;
|
||||
import static net.runelite.api.ItemID.COOKED_RABBIT;
|
||||
import static net.runelite.api.ItemID.COOKED_SLIMY_EEL;
|
||||
import static net.runelite.api.ItemID.COOKED_SWEETCORN;
|
||||
import static net.runelite.api.ItemID.CURRY;
|
||||
import static net.runelite.api.ItemID.DARK_CRAB;
|
||||
import static net.runelite.api.ItemID.DEFENCE_POTION1;
|
||||
import static net.runelite.api.ItemID.DEFENCE_POTION2;
|
||||
import static net.runelite.api.ItemID.DEFENCE_POTION3;
|
||||
import static net.runelite.api.ItemID.DEFENCE_POTION4;
|
||||
import static net.runelite.api.ItemID.DRUNK_DRAGON;
|
||||
import static net.runelite.api.ItemID.DWELLBERRIES;
|
||||
import static net.runelite.api.ItemID.EASTER_EGG;
|
||||
import static net.runelite.api.ItemID.EDIBLE_SEAWEED;
|
||||
import static net.runelite.api.ItemID.EEL_SUSHI;
|
||||
import static net.runelite.api.ItemID.EGG_AND_TOMATO;
|
||||
import static net.runelite.api.ItemID.EGG_POTATO;
|
||||
import static net.runelite.api.ItemID.ELDER_1;
|
||||
import static net.runelite.api.ItemID.ELDER_1_20921;
|
||||
import static net.runelite.api.ItemID.ELDER_2;
|
||||
import static net.runelite.api.ItemID.ELDER_2_20922;
|
||||
import static net.runelite.api.ItemID.ELDER_3;
|
||||
import static net.runelite.api.ItemID.ELDER_3_20923;
|
||||
import static net.runelite.api.ItemID.ELDER_4;
|
||||
import static net.runelite.api.ItemID.ELDER_4_20924;
|
||||
import static net.runelite.api.ItemID.ELDER_POTION_1;
|
||||
import static net.runelite.api.ItemID.ELDER_POTION_2;
|
||||
import static net.runelite.api.ItemID.ELDER_POTION_3;
|
||||
import static net.runelite.api.ItemID.ELDER_POTION_4;
|
||||
import static net.runelite.api.ItemID.ENERGY_POTION1;
|
||||
import static net.runelite.api.ItemID.ENERGY_POTION2;
|
||||
import static net.runelite.api.ItemID.ENERGY_POTION3;
|
||||
import static net.runelite.api.ItemID.ENERGY_POTION4;
|
||||
import static net.runelite.api.ItemID.FAT_SNAIL_MEAT;
|
||||
import static net.runelite.api.ItemID.FIELD_RATION;
|
||||
import static net.runelite.api.ItemID.FILLETS;
|
||||
import static net.runelite.api.ItemID.FINGERS;
|
||||
import static net.runelite.api.ItemID.FISHING_POTION1;
|
||||
import static net.runelite.api.ItemID.FISHING_POTION2;
|
||||
import static net.runelite.api.ItemID.FISHING_POTION3;
|
||||
import static net.runelite.api.ItemID.FISHING_POTION4;
|
||||
import static net.runelite.api.ItemID.FISH_PIE;
|
||||
import static net.runelite.api.ItemID.FRIED_MUSHROOMS;
|
||||
import static net.runelite.api.ItemID.FRIED_ONIONS;
|
||||
import static net.runelite.api.ItemID.FROGBURGER;
|
||||
import static net.runelite.api.ItemID.FROGSPAWN_GUMBO;
|
||||
import static net.runelite.api.ItemID.FROG_SPAWN;
|
||||
import static net.runelite.api.ItemID.FRUIT_BATTA;
|
||||
import static net.runelite.api.ItemID.FRUIT_BLAST;
|
||||
import static net.runelite.api.ItemID.GARDEN_PIE;
|
||||
import static net.runelite.api.ItemID.GIANT_CARP;
|
||||
import static net.runelite.api.ItemID.GIRAL_BAT_2;
|
||||
import static net.runelite.api.ItemID.GOUT_TUBER;
|
||||
import static net.runelite.api.ItemID.GREEN_GLOOP_SOUP;
|
||||
import static net.runelite.api.ItemID.GRUBS__LA_MODE;
|
||||
import static net.runelite.api.ItemID.GUANIC_BAT_0;
|
||||
import static net.runelite.api.ItemID.GUTHIX_REST1;
|
||||
import static net.runelite.api.ItemID.GUTHIX_REST2;
|
||||
import static net.runelite.api.ItemID.GUTHIX_REST3;
|
||||
import static net.runelite.api.ItemID.GUTHIX_REST4;
|
||||
import static net.runelite.api.ItemID.HALF_AN_ADMIRAL_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_AN_APPLE_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_BOTANICAL_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_FISH_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_GARDEN_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_MEAT_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_MUSHROOM_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_REDBERRY_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_SUMMER_PIE;
|
||||
import static net.runelite.api.ItemID.HALF_A_WILD_PIE;
|
||||
import static net.runelite.api.ItemID.HERRING;
|
||||
import static net.runelite.api.ItemID.HUNTER_POTION1;
|
||||
import static net.runelite.api.ItemID.HUNTER_POTION2;
|
||||
import static net.runelite.api.ItemID.HUNTER_POTION3;
|
||||
import static net.runelite.api.ItemID.HUNTER_POTION4;
|
||||
import static net.runelite.api.ItemID.IMBUED_HEART;
|
||||
import static net.runelite.api.ItemID.JANGERBERRIES;
|
||||
import static net.runelite.api.ItemID.JUG_OF_WINE;
|
||||
import static net.runelite.api.ItemID.KODAI_1;
|
||||
import static net.runelite.api.ItemID.KODAI_1_20945;
|
||||
import static net.runelite.api.ItemID.KODAI_2;
|
||||
import static net.runelite.api.ItemID.KODAI_2_20946;
|
||||
import static net.runelite.api.ItemID.KODAI_3;
|
||||
import static net.runelite.api.ItemID.KODAI_3_20947;
|
||||
import static net.runelite.api.ItemID.KODAI_4;
|
||||
import static net.runelite.api.ItemID.KODAI_4_20948;
|
||||
import static net.runelite.api.ItemID.KODAI_POTION_1;
|
||||
import static net.runelite.api.ItemID.KODAI_POTION_2;
|
||||
import static net.runelite.api.ItemID.KODAI_POTION_3;
|
||||
import static net.runelite.api.ItemID.KODAI_POTION_4;
|
||||
import static net.runelite.api.ItemID.KRYKET_BAT_4;
|
||||
import static net.runelite.api.ItemID.KYREN_FISH_6;
|
||||
import static net.runelite.api.ItemID.LAVA_EEL;
|
||||
import static net.runelite.api.ItemID.LECKISH_FISH_2;
|
||||
import static net.runelite.api.ItemID.LEMON;
|
||||
import static net.runelite.api.ItemID.LEMON_CHUNKS;
|
||||
import static net.runelite.api.ItemID.LEMON_SLICES;
|
||||
import static net.runelite.api.ItemID.LIME;
|
||||
import static net.runelite.api.ItemID.LIME_CHUNKS;
|
||||
import static net.runelite.api.ItemID.LIME_SLICES;
|
||||
import static net.runelite.api.ItemID.LOACH;
|
||||
import static net.runelite.api.ItemID.LOBSTER;
|
||||
import static net.runelite.api.ItemID.MACKEREL;
|
||||
import static net.runelite.api.ItemID.MAGIC_ESSENCE1;
|
||||
import static net.runelite.api.ItemID.MAGIC_ESSENCE2;
|
||||
import static net.runelite.api.ItemID.MAGIC_ESSENCE3;
|
||||
import static net.runelite.api.ItemID.MAGIC_ESSENCE4;
|
||||
import static net.runelite.api.ItemID.MAGIC_POTION1;
|
||||
import static net.runelite.api.ItemID.MAGIC_POTION2;
|
||||
import static net.runelite.api.ItemID.MAGIC_POTION3;
|
||||
import static net.runelite.api.ItemID.MAGIC_POTION4;
|
||||
import static net.runelite.api.ItemID.MANTA_RAY;
|
||||
import static net.runelite.api.ItemID.MEAT_PIE;
|
||||
import static net.runelite.api.ItemID.MEAT_PIZZA;
|
||||
import static net.runelite.api.ItemID.MINT_CAKE;
|
||||
import static net.runelite.api.ItemID.MONKFISH;
|
||||
import static net.runelite.api.ItemID.MOONLIGHT_MEAD;
|
||||
import static net.runelite.api.ItemID.MURNG_BAT_5;
|
||||
import static net.runelite.api.ItemID.MUSHROOMS;
|
||||
import static net.runelite.api.ItemID.MUSHROOM_PIE;
|
||||
import static net.runelite.api.ItemID.MUSHROOM_POTATO;
|
||||
import static net.runelite.api.ItemID.MUSHROOM__ONION;
|
||||
import static net.runelite.api.ItemID.MYCIL_FISH_4;
|
||||
import static net.runelite.api.ItemID.ONION;
|
||||
import static net.runelite.api.ItemID.ORANGE;
|
||||
import static net.runelite.api.ItemID.ORANGE_CHUNKS;
|
||||
import static net.runelite.api.ItemID.ORANGE_SLICES;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_1;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_1_20985;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_1_20989;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_1_20993;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_2;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_2_20986;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_2_20990;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_2_20994;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_3;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_3_20987;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_3_20991;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_3_20995;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_4;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_4_20988;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_4_20992;
|
||||
import static net.runelite.api.ItemID.OVERLOAD_4_20996;
|
||||
import static net.runelite.api.ItemID.PAPAYA_FRUIT;
|
||||
import static net.runelite.api.ItemID.PEACH;
|
||||
import static net.runelite.api.ItemID.PHLUXIA_BAT_3;
|
||||
import static net.runelite.api.ItemID.PIKE;
|
||||
import static net.runelite.api.ItemID.PINEAPPLE_CHUNKS;
|
||||
import static net.runelite.api.ItemID.PINEAPPLE_PIZZA;
|
||||
import static net.runelite.api.ItemID.PINEAPPLE_PUNCH;
|
||||
import static net.runelite.api.ItemID.PINEAPPLE_RING;
|
||||
import static net.runelite.api.ItemID.PLAIN_PIZZA;
|
||||
import static net.runelite.api.ItemID.POISON_KARAMBWAN;
|
||||
import static net.runelite.api.ItemID.POTATO;
|
||||
import static net.runelite.api.ItemID.POTATO_WITH_BUTTER;
|
||||
import static net.runelite.api.ItemID.POTATO_WITH_CHEESE;
|
||||
import static net.runelite.api.ItemID.POT_OF_CREAM;
|
||||
import static net.runelite.api.ItemID.PRAEL_BAT_1;
|
||||
import static net.runelite.api.ItemID.PRAYER_POTION1;
|
||||
import static net.runelite.api.ItemID.PRAYER_POTION2;
|
||||
import static net.runelite.api.ItemID.PRAYER_POTION3;
|
||||
import static net.runelite.api.ItemID.PRAYER_POTION4;
|
||||
import static net.runelite.api.ItemID.PREMADE_CHOC_BOMB;
|
||||
import static net.runelite.api.ItemID.PREMADE_CHOC_SDY;
|
||||
import static net.runelite.api.ItemID.PREMADE_CH_CRUNCH;
|
||||
import static net.runelite.api.ItemID.PREMADE_CT_BATTA;
|
||||
import static net.runelite.api.ItemID.PREMADE_DR_DRAGON;
|
||||
import static net.runelite.api.ItemID.PREMADE_FRT_BATTA;
|
||||
import static net.runelite.api.ItemID.PREMADE_FR_BLAST;
|
||||
import static net.runelite.api.ItemID.PREMADE_P_PUNCH;
|
||||
import static net.runelite.api.ItemID.PREMADE_SGG;
|
||||
import static net.runelite.api.ItemID.PREMADE_SY_CRUNCH;
|
||||
import static net.runelite.api.ItemID.PREMADE_TD_BATTA;
|
||||
import static net.runelite.api.ItemID.PREMADE_TD_CRUNCH;
|
||||
import static net.runelite.api.ItemID.PREMADE_TTL;
|
||||
import static net.runelite.api.ItemID.PREMADE_VEG_BALL;
|
||||
import static net.runelite.api.ItemID.PREMADE_VEG_BATTA;
|
||||
import static net.runelite.api.ItemID.PREMADE_WIZ_BLZD;
|
||||
import static net.runelite.api.ItemID.PREMADE_WM_BATTA;
|
||||
import static net.runelite.api.ItemID.PREMADE_WM_CRUN;
|
||||
import static net.runelite.api.ItemID.PREMADE_WORM_HOLE;
|
||||
import static net.runelite.api.ItemID.PSYKK_BAT_6;
|
||||
import static net.runelite.api.ItemID.PUMPKIN;
|
||||
import static net.runelite.api.ItemID.PURPLE_SWEETS_10476;
|
||||
import static net.runelite.api.ItemID.PYSK_FISH_0;
|
||||
import static net.runelite.api.ItemID.RAINBOW_FISH;
|
||||
import static net.runelite.api.ItemID.RANGING_POTION1;
|
||||
import static net.runelite.api.ItemID.RANGING_POTION2;
|
||||
import static net.runelite.api.ItemID.RANGING_POTION3;
|
||||
import static net.runelite.api.ItemID.RANGING_POTION4;
|
||||
import static net.runelite.api.ItemID.REDBERRY_PIE;
|
||||
import static net.runelite.api.ItemID.RESTORE_POTION1;
|
||||
import static net.runelite.api.ItemID.RESTORE_POTION2;
|
||||
import static net.runelite.api.ItemID.RESTORE_POTION3;
|
||||
import static net.runelite.api.ItemID.RESTORE_POTION4;
|
||||
import static net.runelite.api.ItemID.REVITALISATION_1_20957;
|
||||
import static net.runelite.api.ItemID.REVITALISATION_2_20958;
|
||||
import static net.runelite.api.ItemID.REVITALISATION_3_20959;
|
||||
import static net.runelite.api.ItemID.REVITALISATION_4_20960;
|
||||
import static net.runelite.api.ItemID.ROAST_BEAST_MEAT;
|
||||
import static net.runelite.api.ItemID.ROAST_BIRD_MEAT;
|
||||
import static net.runelite.api.ItemID.ROAST_FROG;
|
||||
import static net.runelite.api.ItemID.ROAST_RABBIT;
|
||||
import static net.runelite.api.ItemID.ROE;
|
||||
import static net.runelite.api.ItemID.ROLL;
|
||||
import static net.runelite.api.ItemID.ROQED_FISH_5;
|
||||
import static net.runelite.api.ItemID.SALMON;
|
||||
import static net.runelite.api.ItemID.SANFEW_SERUM1;
|
||||
import static net.runelite.api.ItemID.SANFEW_SERUM2;
|
||||
import static net.runelite.api.ItemID.SANFEW_SERUM3;
|
||||
import static net.runelite.api.ItemID.SANFEW_SERUM4;
|
||||
import static net.runelite.api.ItemID.SARADOMIN_BREW1;
|
||||
import static net.runelite.api.ItemID.SARADOMIN_BREW2;
|
||||
import static net.runelite.api.ItemID.SARADOMIN_BREW3;
|
||||
import static net.runelite.api.ItemID.SARADOMIN_BREW4;
|
||||
import static net.runelite.api.ItemID.SARDINE;
|
||||
import static net.runelite.api.ItemID.SEA_TURTLE;
|
||||
import static net.runelite.api.ItemID.SHARK;
|
||||
import static net.runelite.api.ItemID.SHORT_GREEN_GUY;
|
||||
import static net.runelite.api.ItemID.SHRIMPS;
|
||||
import static net.runelite.api.ItemID.SLICED_BANANA;
|
||||
import static net.runelite.api.ItemID.SLICE_OF_CAKE;
|
||||
import static net.runelite.api.ItemID.SPICY_CRUNCHIES;
|
||||
import static net.runelite.api.ItemID.SPICY_SAUCE;
|
||||
import static net.runelite.api.ItemID.SPICY_STEW;
|
||||
import static net.runelite.api.ItemID.SPIDER_ON_SHAFT_6299;
|
||||
import static net.runelite.api.ItemID.SPIDER_ON_STICK_6297;
|
||||
import static net.runelite.api.ItemID.SPINACH_ROLL;
|
||||
import static net.runelite.api.ItemID.SPRING_SQIRKJUICE;
|
||||
import static net.runelite.api.ItemID.SQUARE_SANDWICH;
|
||||
import static net.runelite.api.ItemID.STAMINA_POTION1;
|
||||
import static net.runelite.api.ItemID.STAMINA_POTION2;
|
||||
import static net.runelite.api.ItemID.STAMINA_POTION3;
|
||||
import static net.runelite.api.ItemID.STAMINA_POTION4;
|
||||
import static net.runelite.api.ItemID.STEW;
|
||||
import static net.runelite.api.ItemID.STRANGE_FRUIT;
|
||||
import static net.runelite.api.ItemID.STRAWBERRY;
|
||||
import static net.runelite.api.ItemID.STRENGTH_POTION1;
|
||||
import static net.runelite.api.ItemID.STRENGTH_POTION2;
|
||||
import static net.runelite.api.ItemID.STRENGTH_POTION3;
|
||||
import static net.runelite.api.ItemID.STRENGTH_POTION4;
|
||||
import static net.runelite.api.ItemID.STUFFED_SNAKE;
|
||||
import static net.runelite.api.ItemID.SUMMER_PIE;
|
||||
import static net.runelite.api.ItemID.SUMMER_SQIRKJUICE;
|
||||
import static net.runelite.api.ItemID.SUPER_ATTACK1;
|
||||
import static net.runelite.api.ItemID.SUPER_ATTACK2;
|
||||
import static net.runelite.api.ItemID.SUPER_ATTACK3;
|
||||
import static net.runelite.api.ItemID.SUPER_ATTACK4;
|
||||
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION1;
|
||||
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION2;
|
||||
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION3;
|
||||
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION4;
|
||||
import static net.runelite.api.ItemID.SUPER_DEFENCE1;
|
||||
import static net.runelite.api.ItemID.SUPER_DEFENCE2;
|
||||
import static net.runelite.api.ItemID.SUPER_DEFENCE3;
|
||||
import static net.runelite.api.ItemID.SUPER_DEFENCE4;
|
||||
import static net.runelite.api.ItemID.SUPER_ENERGY1;
|
||||
import static net.runelite.api.ItemID.SUPER_ENERGY2;
|
||||
import static net.runelite.api.ItemID.SUPER_ENERGY3;
|
||||
import static net.runelite.api.ItemID.SUPER_ENERGY4;
|
||||
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_1;
|
||||
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_2;
|
||||
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_3;
|
||||
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_4;
|
||||
import static net.runelite.api.ItemID.SUPER_RANGING_1;
|
||||
import static net.runelite.api.ItemID.SUPER_RANGING_2;
|
||||
import static net.runelite.api.ItemID.SUPER_RANGING_3;
|
||||
import static net.runelite.api.ItemID.SUPER_RANGING_4;
|
||||
import static net.runelite.api.ItemID.SUPER_RESTORE1;
|
||||
import static net.runelite.api.ItemID.SUPER_RESTORE2;
|
||||
import static net.runelite.api.ItemID.SUPER_RESTORE3;
|
||||
import static net.runelite.api.ItemID.SUPER_RESTORE4;
|
||||
import static net.runelite.api.ItemID.SUPER_STRENGTH1;
|
||||
import static net.runelite.api.ItemID.SUPER_STRENGTH2;
|
||||
import static net.runelite.api.ItemID.SUPER_STRENGTH3;
|
||||
import static net.runelite.api.ItemID.SUPER_STRENGTH4;
|
||||
import static net.runelite.api.ItemID.SUPHI_FISH_1;
|
||||
import static net.runelite.api.ItemID.SWEETCORN_7088;
|
||||
import static net.runelite.api.ItemID.SWORDFISH;
|
||||
import static net.runelite.api.ItemID.TANGLED_TOADS_LEGS;
|
||||
import static net.runelite.api.ItemID.THIN_SNAIL_MEAT;
|
||||
import static net.runelite.api.ItemID.TOAD_BATTA;
|
||||
import static net.runelite.api.ItemID.TOAD_CRUNCHIES;
|
||||
import static net.runelite.api.ItemID.TOMATO;
|
||||
import static net.runelite.api.ItemID.TRIANGLE_SANDWICH;
|
||||
import static net.runelite.api.ItemID.TROUT;
|
||||
import static net.runelite.api.ItemID.TUNA;
|
||||
import static net.runelite.api.ItemID.TUNA_AND_CORN;
|
||||
import static net.runelite.api.ItemID.TUNA_POTATO;
|
||||
import static net.runelite.api.ItemID.TWISTED_1;
|
||||
import static net.runelite.api.ItemID.TWISTED_1_20933;
|
||||
import static net.runelite.api.ItemID.TWISTED_2;
|
||||
import static net.runelite.api.ItemID.TWISTED_2_20934;
|
||||
import static net.runelite.api.ItemID.TWISTED_3;
|
||||
import static net.runelite.api.ItemID.TWISTED_3_20935;
|
||||
import static net.runelite.api.ItemID.TWISTED_4;
|
||||
import static net.runelite.api.ItemID.TWISTED_4_20936;
|
||||
import static net.runelite.api.ItemID.TWISTED_POTION_1;
|
||||
import static net.runelite.api.ItemID.TWISTED_POTION_2;
|
||||
import static net.runelite.api.ItemID.TWISTED_POTION_3;
|
||||
import static net.runelite.api.ItemID.TWISTED_POTION_4;
|
||||
import static net.runelite.api.ItemID.UGTHANKI_KEBAB;
|
||||
import static net.runelite.api.ItemID.UGTHANKI_KEBAB_1885;
|
||||
import static net.runelite.api.ItemID.VEGETABLE_BATTA;
|
||||
import static net.runelite.api.ItemID.VEG_BALL;
|
||||
import static net.runelite.api.ItemID.WATERMELON_SLICE;
|
||||
import static net.runelite.api.ItemID.WHITE_TREE_FRUIT;
|
||||
import static net.runelite.api.ItemID.WILD_PIE;
|
||||
import static net.runelite.api.ItemID.WINTER_SQIRKJUICE;
|
||||
import static net.runelite.api.ItemID.WIZARD_BLIZZARD;
|
||||
import static net.runelite.api.ItemID.WORM_BATTA;
|
||||
import static net.runelite.api.ItemID.WORM_CRUNCHIES;
|
||||
import static net.runelite.api.ItemID.WORM_HOLE;
|
||||
import static net.runelite.api.ItemID.XERICS_AID_1_20981;
|
||||
import static net.runelite.api.ItemID.XERICS_AID_2_20982;
|
||||
import static net.runelite.api.ItemID.XERICS_AID_3_20983;
|
||||
import static net.runelite.api.ItemID.XERICS_AID_4_20984;
|
||||
import static net.runelite.api.ItemID.ZAMORAK_BREW1;
|
||||
import static net.runelite.api.ItemID.ZAMORAK_BREW2;
|
||||
import static net.runelite.api.ItemID.ZAMORAK_BREW3;
|
||||
import static net.runelite.api.ItemID.ZAMORAK_BREW4;
|
||||
import static net.runelite.api.ItemID._12_ANCHOVY_PIZZA;
|
||||
import static net.runelite.api.ItemID._12_MEAT_PIZZA;
|
||||
import static net.runelite.api.ItemID._12_PINEAPPLE_PIZZA;
|
||||
import static net.runelite.api.ItemID._12_PLAIN_PIZZA;
|
||||
import static net.runelite.api.ItemID._23_CAKE;
|
||||
import static net.runelite.api.ItemID._23_CHOCOLATE_CAKE;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.boost;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.combo;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.dec;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.food;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.heal;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.perc;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.range;
|
||||
import static net.runelite.api.ItemID.*;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.*;
|
||||
import net.runelite.client.plugins.itemstats.food.Anglerfish;
|
||||
import net.runelite.client.plugins.itemstats.potions.GauntletPotion;
|
||||
import net.runelite.client.plugins.itemstats.potions.PrayerPotion;
|
||||
import net.runelite.client.plugins.itemstats.potions.SaradominBrew;
|
||||
import net.runelite.client.plugins.itemstats.potions.SuperRestore;
|
||||
import net.runelite.client.plugins.itemstats.special.CastleWarsBandage;
|
||||
import net.runelite.client.plugins.itemstats.special.SpicyStew;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.AGILITY;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.ATTACK;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.CRAFTING;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.DEFENCE;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.FARMING;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.FISHING;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.HERBLORE;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.HITPOINTS;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.HUNTER;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.MAGIC;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.PRAYER;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.RANGED;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.RUN_ENERGY;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.SLAYER;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.STRENGTH;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.THIEVING;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.*;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
@@ -609,6 +199,10 @@ public class ItemStatChanges
|
||||
add(boost(MAGIC, perc(.10, 1)), IMBUED_HEART);
|
||||
add(combo(boost(ATTACK, 2), boost(STRENGTH, 1), heal(DEFENCE, -1)), JANGERBERRIES);
|
||||
|
||||
// Gauntlet items
|
||||
add(heal(HITPOINTS, 20), PADDLEFISH);
|
||||
add(new GauntletPotion(), EGNIOL_POTION_1, EGNIOL_POTION_2, EGNIOL_POTION_3, EGNIOL_POTION_4);
|
||||
|
||||
log.debug("{} items; {} behaviours loaded", effects.size(), new HashSet<>(effects.values()).size());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* 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.itemstats.potions;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Skill;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.heal;
|
||||
import net.runelite.client.plugins.itemstats.Effect;
|
||||
import net.runelite.client.plugins.itemstats.StatChange;
|
||||
import net.runelite.client.plugins.itemstats.StatsChanges;
|
||||
import net.runelite.client.plugins.itemstats.stats.Stats;
|
||||
|
||||
/**
|
||||
* Acts like a prayer potion and stamina dose combined but restores 40 energy instead of 20
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class GauntletPotion implements Effect
|
||||
{
|
||||
private static final int PRAYER_RESTORE_DELTA = 7;
|
||||
private static final double PRAYER_RESTORE_PERCENT = .25;
|
||||
|
||||
@Override
|
||||
public StatsChanges calculate(Client client)
|
||||
{
|
||||
// Restores prayer similar to PrayerPotion but there aren't any possible boost so simplify the calculation
|
||||
final int restorePerc = (int) (client.getRealSkillLevel(Skill.PRAYER) * PRAYER_RESTORE_PERCENT);
|
||||
final StatChange prayer = heal(Stats.PRAYER, restorePerc + PRAYER_RESTORE_DELTA).effect(client);
|
||||
|
||||
final StatChange runEnergy = heal(Stats.RUN_ENERGY, 40).effect(client);
|
||||
|
||||
final StatsChanges changes = new StatsChanges(2);
|
||||
changes.setStatChanges(new StatChange[]{runEnergy, prayer});
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ class BookPanel extends JPanel
|
||||
JLabel image = new JLabel();
|
||||
b.getIcon().addTo(image);
|
||||
JLabel name = new JLabel(b.getShortName());
|
||||
location.setFont(FontManager.getSmallFont(getFont()));
|
||||
location.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
layout.setVerticalGroup(layout.createParallelGroup()
|
||||
.addComponent(image)
|
||||
|
||||
@@ -97,12 +97,12 @@ class LootTrackerBox extends JPanel
|
||||
logTitle.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker());
|
||||
|
||||
final JLabel titleLabel = new JLabel(Text.removeTags(id));
|
||||
titleLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
titleLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
titleLabel.setForeground(Color.WHITE);
|
||||
|
||||
logTitle.add(titleLabel, BorderLayout.WEST);
|
||||
|
||||
subTitleLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
subTitleLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
subTitleLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
logTitle.add(subTitleLabel, BorderLayout.CENTER);
|
||||
|
||||
@@ -121,7 +121,7 @@ class LootTrackerBox extends JPanel
|
||||
subTitleLabel.setText(subtitle);
|
||||
}
|
||||
|
||||
priceLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
priceLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
priceLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
logTitle.add(priceLabel, BorderLayout.EAST);
|
||||
|
||||
|
||||
@@ -349,8 +349,8 @@ class LootTrackerPanel extends PluginPanel
|
||||
overallInfo.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
overallInfo.setLayout(new GridLayout(2, 1));
|
||||
overallInfo.setBorder(new EmptyBorder(2, 10, 2, 0));
|
||||
overallKillsLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
overallGpLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
overallKillsLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
overallGpLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
overallInfo.add(overallKillsLabel);
|
||||
overallInfo.add(overallGpLabel);
|
||||
overallPanel.add(overallIcon, BorderLayout.WEST);
|
||||
|
||||
@@ -32,6 +32,7 @@ import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.BurningAmuletMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.CombatBraceletMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.ConstructionCapeMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.DigsitePendantMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.DuelingRingMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.FairyRingMode;
|
||||
@@ -47,7 +48,6 @@ import net.runelite.client.plugins.menuentryswapper.util.RingOfWealthMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.SkillsNecklaceMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.SlayerRingMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.XericsTalismanMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.teleEquippedMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.CharterOption;
|
||||
|
||||
|
||||
@@ -218,37 +218,11 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "teleEquippedCape",
|
||||
name = "Teleport Equipped Cape",
|
||||
description = "Makes Teleport/Tele to POH the left click option on equip screen",
|
||||
position = 1,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean teleEquippedCape()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "telecapeMode",
|
||||
name = "ModeTeleCape",
|
||||
description = "",
|
||||
position = 2,
|
||||
group = "Equipment swapper",
|
||||
hidden = true,
|
||||
unhide = "teleEquippedCape"
|
||||
)
|
||||
default teleEquippedMode telecapeMode()
|
||||
{
|
||||
return teleEquippedMode.TELEPORT;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "maxMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 3,
|
||||
position = 1,
|
||||
group = "Equipment swapper",
|
||||
hidden = true,
|
||||
unhide = "swapMax"
|
||||
@@ -262,7 +236,7 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
keyName = "swapArdougneCape",
|
||||
name = "Swap Ardougne Cape",
|
||||
description = "Enables swapping of 'Teleport' and 'Wear'.",
|
||||
position = 4,
|
||||
position = 2,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean getSwapArdougneCape()
|
||||
@@ -274,7 +248,7 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
keyName = "swapConstructionCape",
|
||||
name = "Swap Construction Cape",
|
||||
description = "Enables swapping of 'Teleport' and 'Wear'.",
|
||||
position = 5,
|
||||
position = 3,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean getSwapConstructionCape()
|
||||
@@ -282,11 +256,25 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "constructionCapeMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 4,
|
||||
group = "Equipment swapper",
|
||||
hidden = true,
|
||||
unhide = "swapConstructionCape"
|
||||
)
|
||||
default ConstructionCapeMode constructionCapeMode()
|
||||
{
|
||||
return ConstructionCapeMode.TELE_TO_POH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapCraftingCape",
|
||||
name = "Swap Crafting Cape",
|
||||
description = "Enables swapping of 'Teleport' and 'Wear'.",
|
||||
position = 6,
|
||||
position = 5,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean getSwapCraftingCape()
|
||||
@@ -298,7 +286,7 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
keyName = "swapMagicCape",
|
||||
name = "Swap Magic Cape",
|
||||
description = "Enables swapping of 'Spellbook' and 'Wear'.",
|
||||
position = 7,
|
||||
position = 6,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean getSwapMagicCape()
|
||||
@@ -310,7 +298,7 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
keyName = "swapExplorersRing",
|
||||
name = "Swap Explorer's Ring",
|
||||
description = "Enables swapping of 'Spellbook' and 'Wear'.",
|
||||
position = 8,
|
||||
position = 7,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean getSwapExplorersRing()
|
||||
@@ -322,19 +310,19 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
keyName = "swapAdmire",
|
||||
name = "Admire",
|
||||
description = "Swap 'Admire' with 'Teleport', 'Spellbook' and 'Perks' (max cape) for mounted skill capes.",
|
||||
position = 9,
|
||||
position = 8,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean swapAdmire()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapQuestCape",
|
||||
name = "Swap Quest Cape",
|
||||
description = "Enables swapping Quest cape options in worn interface.",
|
||||
position = 10,
|
||||
position = 9,
|
||||
group = "Equipment swapper"
|
||||
)
|
||||
default boolean swapQuestCape()
|
||||
@@ -346,7 +334,7 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
keyName = "questCapeMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 11,
|
||||
position = 10,
|
||||
group = "Equipment swapper",
|
||||
hidden = true,
|
||||
unhide = "swapQuestCape"
|
||||
@@ -652,20 +640,20 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
description = "Don't open implings if bank has a clue.",
|
||||
position = 23,
|
||||
group = "Miscellaneous"
|
||||
)
|
||||
default boolean swapImps()
|
||||
)
|
||||
default boolean swapImps()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
@ConfigItem(
|
||||
keyName = "charterOption",
|
||||
name = "Trader Crew",
|
||||
description = "Configure whether you want Charter or Trade to be the first option of Trader Crewmembers.",
|
||||
position = 24,
|
||||
group = "Miscellaneous"
|
||||
)
|
||||
default CharterOption charterOption()
|
||||
)
|
||||
default CharterOption charterOption()
|
||||
{
|
||||
return CharterOption.TRADE;
|
||||
}
|
||||
@@ -913,23 +901,11 @@ default CharterOption charterOption()
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSmithing",
|
||||
name = "Swap Smithing",
|
||||
description = "Enables swapping of 'Smith-1' and 'Smith-all' options.",
|
||||
position = 2,
|
||||
group = "Skilling"
|
||||
)
|
||||
default boolean getSwapSmithing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapTanning",
|
||||
name = "Swap Tanning",
|
||||
description = "Enables swapping of 'Tan-1' and 'Tan-all' options.",
|
||||
position = 3,
|
||||
position = 2,
|
||||
group = "Skilling"
|
||||
)
|
||||
default boolean getSwapTanning()
|
||||
@@ -941,7 +917,7 @@ default CharterOption charterOption()
|
||||
keyName = "swapSawmill",
|
||||
name = "Swap Sawmill Operator",
|
||||
description = "Makes 'Buy-plank' the default option on the Sawmill Operator.",
|
||||
position = 4,
|
||||
position = 3,
|
||||
group = "Skilling"
|
||||
)
|
||||
default boolean getSwapSawmill()
|
||||
@@ -953,7 +929,7 @@ default CharterOption charterOption()
|
||||
keyName = "swapSawmillPlanks",
|
||||
name = "Swap Buy Planks",
|
||||
description = "Makes 'Buy All' the default option when buying planks.",
|
||||
position = 5,
|
||||
position = 4,
|
||||
group = "Skilling"
|
||||
)
|
||||
default boolean getSwapSawmillPlanks()
|
||||
@@ -965,7 +941,7 @@ default CharterOption charterOption()
|
||||
keyName = "swapPuroPuro",
|
||||
name = "Swap Puro-Puro Wheat",
|
||||
description = "",
|
||||
position = 6,
|
||||
position = 5,
|
||||
group = "Skilling"
|
||||
)
|
||||
default boolean getSwapPuro()
|
||||
@@ -1677,9 +1653,9 @@ default CharterOption charterOption()
|
||||
)
|
||||
|
||||
default boolean hideCastToB()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hideCastIgnoredToB",
|
||||
|
||||
@@ -87,6 +87,7 @@ import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.BurningAmuletMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.CharterOption;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.CombatBraceletMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.ConstructionCapeMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.DigsitePendantMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.DuelingRingMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.FairyRingMode;
|
||||
@@ -102,7 +103,6 @@ import net.runelite.client.plugins.menuentryswapper.util.RingOfWealthMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.SkillsNecklaceMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.SlayerRingMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.XericsTalismanMode;
|
||||
import net.runelite.client.plugins.menuentryswapper.util.teleEquippedMode;
|
||||
import net.runelite.client.plugins.pvptools.PvpToolsConfig;
|
||||
import net.runelite.client.plugins.pvptools.PvpToolsPlugin;
|
||||
import static net.runelite.client.util.MenuUtil.swap;
|
||||
@@ -187,6 +187,7 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
private boolean configuringShiftClick = false;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean shiftModifier = false;
|
||||
|
||||
private boolean getWithdrawOne;
|
||||
private String getWithdrawOneItems;
|
||||
private boolean getWithdrawFive;
|
||||
@@ -199,11 +200,10 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
private boolean getWithdrawAll;
|
||||
private String getWithdrawAllItems;
|
||||
private boolean swapMax;
|
||||
private boolean teleEquippedCape;
|
||||
private teleEquippedMode telecapeMode;
|
||||
private MaxCapeMode maxMode;
|
||||
private boolean getSwapArdougneCape;
|
||||
private boolean getSwapConstructionCape;
|
||||
private ConstructionCapeMode constructionCapeMode;
|
||||
private boolean getSwapCraftingCape;
|
||||
private boolean getSwapMagicCape;
|
||||
private boolean getSwapExplorersRing;
|
||||
@@ -251,7 +251,6 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
private String getSellFiftyItems;
|
||||
private boolean getEasyConstruction;
|
||||
private String getEasyConstructionItems;
|
||||
private boolean getSwapSmithing;
|
||||
private boolean getSwapTanning;
|
||||
private boolean getSwapSawmill;
|
||||
private boolean getSwapSawmillPlanks;
|
||||
@@ -1093,12 +1092,6 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
Text.fromCSV(this.getSellFiftyItems).forEach(item -> menuManager.addPriorityEntry("Sell-50", item));
|
||||
}
|
||||
|
||||
if (this.getSwapSmithing)
|
||||
{
|
||||
menuManager.addPriorityEntry("Smith All");
|
||||
menuManager.addPriorityEntry("Smith All Sets");
|
||||
}
|
||||
|
||||
if (this.getSwapTanning)
|
||||
{
|
||||
menuManager.addPriorityEntry("Tan All");
|
||||
@@ -1128,8 +1121,8 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
|
||||
if (this.getSwapConstructionCape)
|
||||
{
|
||||
menuManager.addPriorityEntry("Tele to poh", "Construct. cape");
|
||||
menuManager.addPriorityEntry("Tele to poh", "Construct. cape(t)");
|
||||
menuManager.addPriorityEntry(constructionCapeMode.toString(), "Construct. cape");
|
||||
menuManager.addPriorityEntry(constructionCapeMode.toString(), "Construct. cape(t)");
|
||||
}
|
||||
|
||||
if (this.getSwapMagicCape)
|
||||
@@ -1396,12 +1389,6 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
menuManager.addPriorityEntry("Quick-pay(100)", "Hardwood grove doors");
|
||||
}
|
||||
|
||||
if (this.teleEquippedCape)
|
||||
{
|
||||
menuManager.addPriorityEntry(this.telecapeMode.toString(), "tele to poh");
|
||||
menuManager.addPriorityEntry(this.telecapeMode.toString(), "teleport");
|
||||
}
|
||||
|
||||
if (this.getCombatBracelet)
|
||||
{
|
||||
menuManager.addPriorityEntry(this.getCombatBraceletMode.toString(), "combat bracelet");
|
||||
@@ -1808,11 +1795,10 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
this.getWithdrawAll = config.getWithdrawAll();
|
||||
this.getWithdrawAllItems = config.getWithdrawAllItems();
|
||||
this.swapMax = config.swapMax();
|
||||
this.teleEquippedCape = config.teleEquippedCape();
|
||||
this.telecapeMode = config.telecapeMode();
|
||||
this.maxMode = config.maxMode();
|
||||
this.getSwapArdougneCape = config.getSwapArdougneCape();
|
||||
this.getSwapConstructionCape = config.getSwapConstructionCape();
|
||||
this.constructionCapeMode = config.constructionCapeMode();
|
||||
this.getSwapCraftingCape = config.getSwapCraftingCape();
|
||||
this.getSwapMagicCape = config.getSwapMagicCape();
|
||||
this.getSwapExplorersRing = config.getSwapExplorersRing();
|
||||
@@ -1860,7 +1846,6 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
this.getSellFiftyItems = config.getSellFiftyItems();
|
||||
this.getEasyConstruction = config.getEasyConstruction();
|
||||
this.getEasyConstructionItems = config.getEasyConstructionItems();
|
||||
this.getSwapSmithing = config.getSwapSmithing();
|
||||
this.getSwapTanning = config.getSwapTanning();
|
||||
this.getSwapSawmill = config.getSwapSawmill();
|
||||
this.getSwapSawmillPlanks = config.getSwapSawmillPlanks();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package net.runelite.client.plugins.menuentryswapper.util;
|
||||
|
||||
public enum teleEquippedMode
|
||||
public enum ConstructionCapeMode
|
||||
{
|
||||
TELE_TO_POH("Tele to POH"),
|
||||
TELEPORT("teleport");
|
||||
TELEPORT("Teleport");
|
||||
|
||||
private final String name;
|
||||
|
||||
teleEquippedMode(String name)
|
||||
ConstructionCapeMode(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ enum Rock
|
||||
{
|
||||
TIN(Duration.ofMillis(2400), 0, ROCKS_11360, ROCKS_11361),
|
||||
COPPER(Duration.ofMillis(2400), 0, ROCKS_10943, ROCKS_11161),
|
||||
IRON(Duration.ofMillis(5400), 0, ROCKS_11364, ROCKS_11365)
|
||||
IRON(Duration.ofMillis(5400), 0, ROCKS_11364, ROCKS_11365, ROCKS_36203)
|
||||
{
|
||||
@Override
|
||||
Duration getRespawnTime(boolean inMiningGuild)
|
||||
@@ -43,7 +43,7 @@ enum Rock
|
||||
return inMiningGuild ? Duration.ofMillis(2400) : super.respawnTime;
|
||||
}
|
||||
},
|
||||
COAL(Duration.ofMillis(29400), 0, ROCKS_11366, ROCKS_11367)
|
||||
COAL(Duration.ofMillis(29400), 0, ROCKS_11366, ROCKS_11367, ROCKS_36204)
|
||||
{
|
||||
@Override
|
||||
Duration getRespawnTime(boolean inMiningGuild)
|
||||
@@ -51,11 +51,11 @@ enum Rock
|
||||
return inMiningGuild ? Duration.ofMillis(14400) : super.respawnTime;
|
||||
}
|
||||
},
|
||||
SILVER(Duration.ofMinutes(1), 0, ROCKS_11368, ROCKS_11369),
|
||||
SILVER(Duration.ofMinutes(1), 0, ROCKS_11368, ROCKS_11369, ROCKS_36205),
|
||||
SANDSTONE(Duration.ofMillis(5400), 0, ROCKS_11386),
|
||||
GOLD(Duration.ofMinutes(1), 0, ROCKS_11370, ROCKS_11371),
|
||||
GOLD(Duration.ofMinutes(1), 0, ROCKS_11370, ROCKS_11371, ROCKS_36206),
|
||||
GRANITE(Duration.ofMillis(5400), 0, ROCKS_11387),
|
||||
MITHRIL(Duration.ofMinutes(2), 0, ROCKS_11372, ROCKS_11373)
|
||||
MITHRIL(Duration.ofMinutes(2), 0, ROCKS_11372, ROCKS_11373, ROCKS_36207)
|
||||
{
|
||||
@Override
|
||||
Duration getRespawnTime(boolean inMiningGuild)
|
||||
@@ -63,7 +63,7 @@ enum Rock
|
||||
return inMiningGuild ? Duration.ofMinutes(1) : super.respawnTime;
|
||||
}
|
||||
},
|
||||
ADAMANTITE(Duration.ofMinutes(4), 0, ROCKS_11374, ROCKS_11375)
|
||||
ADAMANTITE(Duration.ofMinutes(4), 0, ROCKS_11374, ROCKS_11375, ROCKS_36208)
|
||||
{
|
||||
@Override
|
||||
Duration getRespawnTime(boolean inMiningGuild)
|
||||
@@ -71,7 +71,7 @@ enum Rock
|
||||
return inMiningGuild ? Duration.ofMinutes(2) : super.respawnTime;
|
||||
}
|
||||
},
|
||||
RUNITE(Duration.ofMinutes(12), 0, ROCKS_11376, ROCKS_11377)
|
||||
RUNITE(Duration.ofMinutes(12), 0, ROCKS_11376, ROCKS_11377, ROCKS_36209)
|
||||
{
|
||||
@Override
|
||||
Duration getRespawnTime(boolean inMiningGuild)
|
||||
|
||||
@@ -43,18 +43,7 @@ import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.AnimationID;
|
||||
import static net.runelite.api.AnimationID.IDLE;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_3A;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_ADAMANT;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BLACK;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_BRONZE;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_DRAGON_ORN;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_INFERNAL;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_IRON;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_MITHRIL;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_RUNE;
|
||||
import static net.runelite.api.AnimationID.MINING_MOTHERLODE_STEEL;
|
||||
import static net.runelite.api.AnimationID.*;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
@@ -451,7 +440,9 @@ public class MotherlodePlugin extends Plugin
|
||||
case MINING_MOTHERLODE_ADAMANT:
|
||||
case MINING_MOTHERLODE_RUNE:
|
||||
case MINING_MOTHERLODE_DRAGON:
|
||||
case MINING_MOTHERLODE_DRAGON_ORN:
|
||||
case MINING_MOTHERLODE_DRAGON_UPGRADED:
|
||||
case MINING_MOTHERLODE_DRAGON_OR:
|
||||
case MINING_MOTHERLODE_CRYSTAL:
|
||||
case MINING_MOTHERLODE_INFERNAL:
|
||||
case MINING_MOTHERLODE_3A:
|
||||
lastAnimation = animation;
|
||||
|
||||
@@ -53,7 +53,7 @@ public class MTAInventoryOverlay extends Overlay
|
||||
{
|
||||
if (room.inside())
|
||||
{
|
||||
graphics.setFont(FontManager.getSmallFont(graphics.getFont()));
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
room.over(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class MTASceneOverlay extends Overlay
|
||||
{
|
||||
if (room.inside())
|
||||
{
|
||||
graphics.setFont(FontManager.getSmallFont(graphics.getFont()));
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
room.under(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,14 +102,19 @@ class NightmareZoneOverlay extends Overlay
|
||||
|
||||
renderAbsorptionCounter();
|
||||
|
||||
final int currentPoints = client.getVar(Varbits.NMZ_POINTS);
|
||||
final int totalPoints = currentPoints + client.getVar(VarPlayer.NMZ_REWARD_POINTS);
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
tableComponent.addRow("Points:", StackFormatter.formatNumber(client.getVar(Varbits.NMZ_POINTS)));
|
||||
tableComponent.addRow("Points:", StackFormatter.formatNumber(currentPoints));
|
||||
tableComponent.addRow("Points/Hour:", StackFormatter.formatNumber(plugin.getPointsPerHour()));
|
||||
|
||||
if (plugin.isShowtotalpoints())
|
||||
{
|
||||
tableComponent.addRow("Total:", StackFormatter.formatNumber(client.getVar(VarPlayer.NMZ_REWARD_POINTS) + client.getVar(Varbits.NMZ_POINTS)));
|
||||
tableComponent.addRow("Total:", StackFormatter.formatNumber(totalPoints));
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
|
||||
@@ -25,11 +25,14 @@
|
||||
package net.runelite.client.plugins.nightmarezone;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Arrays;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
@@ -56,6 +59,7 @@ import net.runelite.client.util.Text;
|
||||
public class NightmareZonePlugin extends Plugin
|
||||
{
|
||||
private static final int[] NMZ_MAP_REGION = {9033};
|
||||
private static final Duration HOUR = Duration.ofHours(1);
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
@@ -75,6 +79,11 @@ public class NightmareZonePlugin extends Plugin
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
|
||||
@Getter
|
||||
private int pointsPerHour;
|
||||
|
||||
private Instant nmzSessionStartTime;
|
||||
|
||||
// This starts as true since you need to get
|
||||
// above the threshold before sending notifications
|
||||
private boolean absorptionNotificationSend = true;
|
||||
@@ -120,6 +129,8 @@ public class NightmareZonePlugin extends Plugin
|
||||
{
|
||||
nmzWidget.setHidden(false);
|
||||
}
|
||||
|
||||
resetPointsPerHour();
|
||||
}
|
||||
|
||||
private void addSubscriptions()
|
||||
@@ -155,6 +166,11 @@ public class NightmareZonePlugin extends Plugin
|
||||
absorptionNotificationSend = true;
|
||||
}
|
||||
|
||||
if (nmzSessionStartTime != null)
|
||||
{
|
||||
resetPointsPerHour();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,6 +178,11 @@ public class NightmareZonePlugin extends Plugin
|
||||
{
|
||||
checkAbsorption();
|
||||
}
|
||||
|
||||
if (config.moveOverlay())
|
||||
{
|
||||
pointsPerHour = calculatePointsPerHour();
|
||||
}
|
||||
}
|
||||
|
||||
private void onChatMessage(ChatMessage event)
|
||||
@@ -239,6 +260,32 @@ public class NightmareZonePlugin extends Plugin
|
||||
return !Arrays.equals(client.getMapRegions(), NMZ_MAP_REGION);
|
||||
}
|
||||
|
||||
private int calculatePointsPerHour()
|
||||
{
|
||||
Instant now = Instant.now();
|
||||
final int currentPoints = client.getVar(Varbits.NMZ_POINTS);
|
||||
|
||||
if (nmzSessionStartTime == null)
|
||||
{
|
||||
nmzSessionStartTime = now;
|
||||
}
|
||||
|
||||
Duration timeSinceStart = Duration.between(nmzSessionStartTime, now);
|
||||
|
||||
if (!timeSinceStart.isZero())
|
||||
{
|
||||
return (int) ((double) currentPoints * (double) HOUR.toMillis() / (double) timeSinceStart.toMillis());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void resetPointsPerHour()
|
||||
{
|
||||
nmzSessionStartTime = null;
|
||||
pointsPerHour = 0;
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.moveOverlay = config.moveOverlay();
|
||||
|
||||
@@ -116,7 +116,7 @@ class ProfilesPanel extends PluginPanel
|
||||
JPanel helpPanel = new JPanel(new BorderLayout());
|
||||
helpPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
JLabel helpLabel = new JLabel("<html> <p>" + HELP + "</p></html>");
|
||||
helpLabel.setFont(FontManager.getSmallFont(getFont()));
|
||||
helpLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
helpPanel.setPreferredSize(HELP_PREFERRED_SIZE);
|
||||
// helpPanel.setSize(MINIMUM_SIZE);
|
||||
helpPanel.add(helpLabel, BorderLayout.NORTH);
|
||||
|
||||
@@ -118,7 +118,6 @@ public class RaidsPlugin extends Plugin
|
||||
private static final String RAID_START_MESSAGE = "The raid has begun!";
|
||||
private static final String LEVEL_COMPLETE_MESSAGE = "level complete!";
|
||||
private static final String RAID_COMPLETE_MESSAGE = "Congratulations - your raid is complete!";
|
||||
private static final String SPLIT_REGEX = "\\s*,\\s*";
|
||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##");
|
||||
private static final Pattern ROTATION_REGEX = Pattern.compile("\\[(.*?)]");
|
||||
private static final Pattern RAID_COMPLETE_REGEX = Pattern.compile("Congratulations - your raid is complete! Duration: ([0-9:]+)");
|
||||
@@ -717,16 +716,27 @@ public class RaidsPlugin extends Plugin
|
||||
final String layout = getRaid().getLayout().toCodeString();
|
||||
final String rooms = getRaid().toRoomString();
|
||||
final String raidData = "[" + layout + "]: " + rooms;
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(new ChatMessageBuilder()
|
||||
layoutMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Layout: ")
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(raidData)
|
||||
.build())
|
||||
.build());
|
||||
.build();
|
||||
|
||||
final PartyMember localMember = party.getLocalMember();
|
||||
if (party.getMembers().isEmpty() || localMember == null)
|
||||
{
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(layoutMessage)
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
final PartyChatMessage message = new PartyChatMessage(layoutMessage);
|
||||
message.setMemberId(localMember.getMemberId());
|
||||
ws.send(message);
|
||||
}
|
||||
|
||||
if (recordRaid() != null)
|
||||
{
|
||||
@@ -746,22 +756,6 @@ public class RaidsPlugin extends Plugin
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
final PartyMember localMember = party.getLocalMember();
|
||||
|
||||
if (party.getMembers().isEmpty() || localMember == null)
|
||||
{
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(layoutMessage)
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
final PartyChatMessage message = new PartyChatMessage(layoutMessage);
|
||||
message.setMemberId(localMember.getMemberId());
|
||||
ws.send(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInfoBoxState()
|
||||
@@ -816,7 +810,7 @@ public class RaidsPlugin extends Plugin
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String[] itemNames = everything.substring(split).split(SPLIT_REGEX);
|
||||
List<String> itemNames = Text.fromCSV(everything.substring(split));
|
||||
|
||||
map.computeIfAbsent(key, k -> new ArrayList<>());
|
||||
|
||||
|
||||
@@ -24,41 +24,171 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.roguesden;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Set;
|
||||
import static net.runelite.api.NullObjectID.NULL_7235;
|
||||
import static net.runelite.api.ObjectID.BLADE_7252;
|
||||
import static net.runelite.api.ObjectID.CONTORTION_BARS;
|
||||
import static net.runelite.api.ObjectID.FLOOR;
|
||||
import static net.runelite.api.ObjectID.FLOOR_7230;
|
||||
import static net.runelite.api.ObjectID.FLOOR_7245;
|
||||
import static net.runelite.api.ObjectID.LEDGE_7240;
|
||||
import static net.runelite.api.ObjectID.PENDULUM;
|
||||
import static net.runelite.api.ObjectID.SPINNING_BLADES_7224;
|
||||
import static net.runelite.api.ObjectID.WALL_7228;
|
||||
import static net.runelite.api.ObjectID.WALL_7229;
|
||||
import static net.runelite.api.ObjectID.WALL_7248;
|
||||
import static net.runelite.api.ObjectID.WALL_7249;
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import static net.runelite.api.ObjectID.*;
|
||||
|
||||
class Obstacles
|
||||
{
|
||||
static final Set<Integer> OBSTACLE_IDS_HULL = Sets.newHashSet(
|
||||
SPINNING_BLADES_7224,
|
||||
CONTORTION_BARS,
|
||||
PENDULUM,
|
||||
WALL_7249, /*Wall crushers*/
|
||||
WALL_7248, /*Wall blade*/
|
||||
LEDGE_7240, /*Ledge climb*/
|
||||
NULL_7235 /*Wall safe*/
|
||||
);
|
||||
static final Map<WorldPoint, Obstacle> TILE_MAP = new HashMap<>();
|
||||
static final Obstacle[] OBSTACLES =
|
||||
{
|
||||
new Obstacle(3050, 4997, "Enter"),
|
||||
new Obstacle(3049, 4997, CONTORTION_BARS),
|
||||
new Obstacle(3039, 4999, "Stand"),
|
||||
new Obstacle(3029, 5003, "Run"),
|
||||
new Obstacle(3024, 5001, "Open", GRILL_7255),
|
||||
new Obstacle(3011, 5005, "Run"),
|
||||
new Obstacle(3004, 5003, "Run"),
|
||||
|
||||
static final Set<Integer> OBSTACLE_IDS_TILE = Sets.newHashSet(
|
||||
FLOOR, /*Floor spikes*/
|
||||
WALL_7228, /*Wall spikes*/
|
||||
WALL_7229, /*Wall spears*/
|
||||
FLOOR_7245, /*Pressure pad a*/
|
||||
FLOOR_7230, /*Pressure pad b*/
|
||||
BLADE_7252, /*Floor blade*/
|
||||
7239 /*Bridge [Ground object]*/
|
||||
);
|
||||
new Obstacle(2994, 5004, "Climb"),
|
||||
new Obstacle(2993, 5004, LEDGE_7240),
|
||||
new Obstacle(2994, 5005, "Climb"),
|
||||
new Obstacle(2993, 5005, LEDGE_7240),
|
||||
|
||||
new Obstacle(2969, 5016, "Stand"),
|
||||
new Obstacle(2969, 5017, "Stand"),
|
||||
new Obstacle(2969, 5018, "Stand"),
|
||||
new Obstacle(2969, 5019, "Stand"),
|
||||
|
||||
new Obstacle(2958, 5031, "Cross"),
|
||||
new Obstacle(2962, 5050, "Stand"),
|
||||
new Obstacle(2963, 5056, "Run"),
|
||||
|
||||
new Obstacle(2957, 5068, "Enter"),
|
||||
new Obstacle(2957, 5069, PASSAGEWAY),
|
||||
|
||||
new Obstacle(2955, 5094, "Enter"),
|
||||
new Obstacle(2955, 5095, PASSAGEWAY),
|
||||
|
||||
new Obstacle(2963, 5105, "Stand"),
|
||||
|
||||
new Obstacle(2972, 5098, "Enter"),
|
||||
new Obstacle(2972, 5097, PASSAGEWAY),
|
||||
|
||||
new Obstacle(2972, 5094, "Open"),
|
||||
new Obstacle(2972, 5094, GRILL_7255),
|
||||
|
||||
new Obstacle(2982, 5087, "Climb"),
|
||||
new Obstacle(2983, 5087, LEDGE_7240),
|
||||
|
||||
new Obstacle(2982, 5090, "Climb"),
|
||||
new Obstacle(2983, 5090, LEDGE_7240),
|
||||
|
||||
new Obstacle(2993, 5088, "Search"),
|
||||
new Obstacle(2993, 5087, WALL_7249),
|
||||
new Obstacle(2997, 5088, "Run"),
|
||||
|
||||
new Obstacle(2993, 5089, "Search"),
|
||||
new Obstacle(2993, 5089, WALL_7249),
|
||||
new Obstacle(2997, 5089, "Run"),
|
||||
|
||||
new Obstacle(3006, 5088, "Run"),
|
||||
new Obstacle(3018, 5080, "Take"),
|
||||
new Obstacle(3023, 5082, "Open", DOOR_7234),
|
||||
|
||||
// Maze
|
||||
new Obstacle(3030, 5079, GRILL_7255),
|
||||
new Obstacle(3032, 5078, GRILL_7255),
|
||||
new Obstacle(3036, 5076, GRILL_7255),
|
||||
new Obstacle(3039, 5079, GRILL_7255),
|
||||
new Obstacle(3042, 5076, GRILL_7255),
|
||||
new Obstacle(3044, 5069, GRILL_7255),
|
||||
new Obstacle(3041, 5068, GRILL_7255),
|
||||
new Obstacle(3040, 5070, GRILL_7255),
|
||||
new Obstacle(3038, 5069, GRILL_7255),
|
||||
|
||||
new Obstacle(3028, 5033, "Stand"),
|
||||
new Obstacle(3024, 5033, "Run"),
|
||||
new Obstacle(3028, 5034, "Stand"),
|
||||
new Obstacle(3024, 5034, "Run"),
|
||||
|
||||
new Obstacle(3015, 5033, "Open", GRILL_7255),
|
||||
new Obstacle(3010, 5033, "Run/Open", GRILL_7255),
|
||||
|
||||
new Obstacle(3000, 5034, "Run"),
|
||||
|
||||
new Obstacle(2992, 5045, "Stand"),
|
||||
new Obstacle(2992, 5053, "Run"),
|
||||
|
||||
new Obstacle(2992, 5067, "Stand"),
|
||||
new Obstacle(2992, 5075, "Run"),
|
||||
new Obstacle(3009, 5063, "Take"),
|
||||
new Obstacle(3028, 5056, "Run"),
|
||||
new Obstacle(3028, 5047, "Walk"),
|
||||
|
||||
new Obstacle(3018, 5047, "Crack", WALL_SAFE_7237),
|
||||
|
||||
// Start of 80+ thieving shortcut
|
||||
new Obstacle(2967, 5061, "80 Thieving", DOOR_7246),
|
||||
new Obstacle(2967, 5066, "80 Thieving", DOOR_7246),
|
||||
new Obstacle(2974, 5061, "Enter"),
|
||||
new Obstacle(2974, 5060, CONTORTION_BARS),
|
||||
new Obstacle(2989, 5057, "Open", GRILL_7255),
|
||||
new Obstacle(2989, 5058, "Open", GRILL_7255),
|
||||
|
||||
// The 3x3 square around the spinning blade in the middle of the maze
|
||||
new AvoidObstacle(2977, 5090), new AvoidObstacle(2978, 5090), new AvoidObstacle(2979, 5090),
|
||||
new AvoidObstacle(2977, 5089), new AvoidObstacle(2978, 5089), new AvoidObstacle(2979, 5089),
|
||||
new AvoidObstacle(2977, 5088), new AvoidObstacle(2978, 5088), new AvoidObstacle(2979, 5088),
|
||||
|
||||
new TipObstacle(3014, 5063, "Stun NPC"),
|
||||
new TipObstacle(2992, 5057, "Continue North"), // Hint for 80 thieving shortcut
|
||||
};
|
||||
|
||||
@Getter
|
||||
static class Obstacle
|
||||
{
|
||||
private WorldPoint tile;
|
||||
private String hint;
|
||||
private int objectId = -1;
|
||||
private final Color tileColor = Color.GREEN;
|
||||
|
||||
// Highlights tile and shows a hint
|
||||
private Obstacle(int x, int y, String hint)
|
||||
{
|
||||
tile = new WorldPoint(x, y, 1);
|
||||
this.hint = hint;
|
||||
}
|
||||
|
||||
// Doesn't highlight tile, but instead highlights object of objectId found on tile
|
||||
private Obstacle(int x, int y, int objectId)
|
||||
{
|
||||
this(x, y, "");
|
||||
this.objectId = objectId;
|
||||
TILE_MAP.put(new WorldPoint(x, y, 1), this);
|
||||
}
|
||||
|
||||
// Doesn't highlight tile, but instead highlights object of objectId found on tile and shows a hint
|
||||
private Obstacle(int x, int y, String hint, int objectId)
|
||||
{
|
||||
this(x, y, objectId);
|
||||
this.hint = hint;
|
||||
}
|
||||
}
|
||||
|
||||
private static class AvoidObstacle extends Obstacle
|
||||
{
|
||||
@Getter
|
||||
private final Color tileColor = Color.RED;
|
||||
|
||||
private AvoidObstacle(int x, int y)
|
||||
{
|
||||
super(x, y, "AVOID");
|
||||
}
|
||||
}
|
||||
|
||||
private static class TipObstacle extends Obstacle
|
||||
{
|
||||
@Getter
|
||||
private final Color tileColor = Color.ORANGE;
|
||||
|
||||
private TipObstacle(int x, int y, String hint)
|
||||
{
|
||||
super(x, y, hint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@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.roguesden;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.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 RoguesDenMinimapOverlay extends Overlay
|
||||
{
|
||||
private Client client;
|
||||
private RoguesDenPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public RoguesDenMinimapOverlay(Client client, RoguesDenPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.isHasGem())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Obstacles.Obstacle obstacle : Obstacles.OBSTACLES)
|
||||
{
|
||||
final LocalPoint localPoint = LocalPoint.fromWorld(client, obstacle.getTile());
|
||||
|
||||
if (localPoint == null || obstacle.getTile().getPlane() != client.getPlane())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Point minimapPoint = Perspective.localToMinimap(client, localPoint);
|
||||
|
||||
if (minimapPoint != null)
|
||||
{
|
||||
OverlayUtil.renderMinimapLocation(graphics, minimapPoint, obstacle.getObjectId() == -1 ? Color.GREEN : Color.RED);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -28,10 +28,15 @@ import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.geom.Area;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.graphics.ModelOutlineRenderer;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -39,18 +44,22 @@ import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@Singleton
|
||||
public class RoguesDenOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
private static final Color OBJECT_BORDER_COLOR = Color.RED;
|
||||
private static final Color OBJECT_COLOR = new Color(OBJECT_BORDER_COLOR.getRed(), OBJECT_BORDER_COLOR.getGreen(), OBJECT_BORDER_COLOR.getBlue(), 50);
|
||||
private static final Color OBJECT_BORDER_HOVER_COLOR = OBJECT_BORDER_COLOR.darker();
|
||||
|
||||
private final Client client;
|
||||
private final RoguesDenPlugin plugin;
|
||||
private final ModelOutlineRenderer modelOutliner;
|
||||
|
||||
@Inject
|
||||
public RoguesDenOverlay(final Client client, final RoguesDenPlugin plugin)
|
||||
public RoguesDenOverlay(final Client client, final RoguesDenPlugin plugin, ModelOutlineRenderer modelOutliner)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.modelOutliner = modelOutliner;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,33 +70,74 @@ public class RoguesDenOverlay extends Overlay
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
plugin.getObstaclesHull().forEach((obstacle, tile) ->
|
||||
{
|
||||
if (tile.getPlane() == client.getPlane() && obstacle.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
if (tile.getPlane() == client.getPlane())
|
||||
{
|
||||
Polygon p = tile.getGameObjects()[0].getConvexHull();
|
||||
if (p != null)
|
||||
final Area clickBox = obstacle.getClickbox();
|
||||
if (clickBox != null)
|
||||
{
|
||||
graphics.setColor(Color.CYAN);
|
||||
graphics.drawPolygon(p);
|
||||
final Point mouse = client.getMouseCanvasPosition();
|
||||
if (clickBox.contains(mouse.getX(), mouse.getY()))
|
||||
{
|
||||
graphics.setColor(OBJECT_BORDER_HOVER_COLOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(OBJECT_BORDER_COLOR);
|
||||
}
|
||||
|
||||
graphics.draw(clickBox);
|
||||
graphics.setColor(OBJECT_COLOR);
|
||||
graphics.fill(clickBox);
|
||||
}
|
||||
else
|
||||
{
|
||||
Polygon p;
|
||||
if (obstacle instanceof GameObject)
|
||||
{
|
||||
p = ((GameObject) obstacle).getConvexHull();
|
||||
}
|
||||
else
|
||||
{
|
||||
p = obstacle.getCanvasTilePoly();
|
||||
}
|
||||
|
||||
if (p != null)
|
||||
{
|
||||
graphics.setColor(OBJECT_COLOR);
|
||||
graphics.drawPolygon(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
plugin.getObstaclesTile().forEach((obstacle, tile) ->
|
||||
for (Obstacles.Obstacle obstacle : Obstacles.OBSTACLES)
|
||||
{
|
||||
if (tile.getPlane() == client.getPlane() && obstacle.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
final LocalPoint localPoint = LocalPoint.fromWorld(client, obstacle.getTile());
|
||||
|
||||
if (localPoint == null || obstacle.getTile().getPlane() != client.getPlane())
|
||||
{
|
||||
Polygon p = obstacle.getCanvasTilePoly();
|
||||
if (p != null)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!obstacle.getHint().isEmpty())
|
||||
{
|
||||
final Polygon polygon = Perspective.getCanvasTilePoly(client, localPoint);
|
||||
if (polygon != null)
|
||||
{
|
||||
graphics.setColor(Color.CYAN);
|
||||
graphics.drawPolygon(p);
|
||||
graphics.setColor(obstacle.getTileColor());
|
||||
graphics.drawPolygon(polygon);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Point textLocation = Perspective.getCanvasTextLocation(client, graphics, localPoint, obstacle.getHint(), 0);
|
||||
if (textLocation != null)
|
||||
{
|
||||
graphics.setColor(Color.LIGHT_GRAY);
|
||||
graphics.drawString(obstacle.getHint(), textLocation.getX(), textLocation.getY());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user