diff --git a/build.gradle b/build.gradle index d26e3b315f..ab267f2985 100644 --- a/build.gradle +++ b/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 { diff --git a/deobfuscator/build.gradle b/deobfuscator/build.gradle index 3142757b1c..5a7f4af7a4 100644 --- a/deobfuscator/build.gradle +++ b/deobfuscator/build.gradle @@ -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('\\', "/") ]) } } \ No newline at end of file diff --git a/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java b/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java index 6d9110a3b3..a5f3a6ecb6 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java +++ b/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java @@ -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) diff --git a/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java b/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java index 416281c305..33ab161acc 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java +++ b/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java @@ -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); + } } diff --git a/deobfuscator/src/main/java/net/runelite/asm/Field.java b/deobfuscator/src/main/java/net/runelite/asm/Field.java index 8d70053adb..39590b021c 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/Field.java +++ b/deobfuscator/src/main/java/net/runelite/asm/Field.java @@ -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; diff --git a/deobfuscator/src/main/java/net/runelite/asm/Method.java b/deobfuscator/src/main/java/net/runelite/asm/Method.java index e8cbdef92b..ad7394c7be 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/Method.java +++ b/deobfuscator/src/main/java/net/runelite/asm/Method.java @@ -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; diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/Code.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/Code.java index 2a3f08126c..b20c183fea 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/Code.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/Code.java @@ -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 getLineNumbers() + { + final List 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; + } } diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/Label.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/Label.java index 7f2cd70ffd..095f9ddb15 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/Label.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/Label.java @@ -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(); diff --git a/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java b/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java index a63a3d762e..ca24bb33af 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java +++ b/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java @@ -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 diff --git a/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java b/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java index 510868d191..4585655f2e 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java +++ b/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java @@ -43,7 +43,7 @@ public class Method @Override public String toString() { - return clazz + "." + name + type; + return clazz.getName() + "." + name + type; } @Override diff --git a/deobfuscator/src/main/java/net/runelite/deob/Deob.java b/deobfuscator/src/main/java/net/runelite/deob/Deob.java index 2dfeae9e6b..6efdfe3500 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/Deob.java +++ b/deobfuscator/src/main/java/net/runelite/deob/Deob.java @@ -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(); diff --git a/deobfuscator/src/main/java/net/runelite/deob/DeobProperties.java b/deobfuscator/src/main/java/net/runelite/deob/DeobProperties.java index f25cd2bd01..979c7bb41f 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/DeobProperties.java +++ b/deobfuscator/src/main/java/net/runelite/deob/DeobProperties.java @@ -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")); } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/MappingDumper.java b/deobfuscator/src/main/java/net/runelite/deob/updater/MappingDumper.java new file mode 100644 index 0000000000..275b3dca74 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/MappingDumper.java @@ -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 classMap = new HashMap<>(); + private static final Map fieldMap = new HashMap<>(); + private static final Map 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); + } + +} diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedClass.java b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedClass.java new file mode 100644 index 0000000000..9a0a6e7511 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedClass.java @@ -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 interfaces; + public List fields; + public List methods; + public List 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; + } +} diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedField.java b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedField.java new file mode 100644 index 0000000000..dc2b7a7242 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedField.java @@ -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 puts = new HashMap<>(); + public Map 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; + } +} diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedMethod.java b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedMethod.java new file mode 100644 index 0000000000..8131ecd1f6 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedMethod.java @@ -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 parameters; + public String descriptor; + public String garbageValue; + public List lineNumbers; + public Map fieldGets = new HashMap<>(); + public Map fieldPuts = new HashMap<>(); + public Map 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 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); + } + } + } +} diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappingDump.java b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappingDump.java new file mode 100644 index 0000000000..adcf228893 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappingDump.java @@ -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 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 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 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; + } +} diff --git a/deobfuscator/src/main/resources/deob.properties b/deobfuscator/src/main/resources/deob.properties new file mode 100644 index 0000000000..0ce0372f8e --- /dev/null +++ b/deobfuscator/src/main/resources/deob.properties @@ -0,0 +1,3 @@ +rs.version=@rs.version@ +vanilla.jar=@vanilla.jar@ +rs.client=@rs.client@ \ No newline at end of file diff --git a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java index 262e7bce2e..d43ffbfe6d 100644 --- a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java +++ b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java @@ -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 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("")) - { - 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("")) - { - 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 diff --git a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedClass.java b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedClass.java deleted file mode 100644 index 329d16415f..0000000000 --- a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedClass.java +++ /dev/null @@ -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 interfaces; - public List fields; - public List methods; - public List constructors; - // Static fields/methods belonging to this class (ClassName_name) - public List staticFields; - public List staticMethods; -} diff --git a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedField.java b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedField.java deleted file mode 100644 index b690c0d805..0000000000 --- a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedField.java +++ /dev/null @@ -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; -} diff --git a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedMethod.java b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedMethod.java deleted file mode 100644 index b2f0c15345..0000000000 --- a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappedMethod.java +++ /dev/null @@ -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 parameters; - public String descriptor; - public Long garbageValue; -} diff --git a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappingDump.java b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappingDump.java deleted file mode 100644 index bd3f089bd3..0000000000 --- a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/mappingdumper/MappingDump.java +++ /dev/null @@ -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 classes; - - // Static things belonging to a certain class will be in both these lists and in the classes - public List staticFields; - public List staticMethods; -} diff --git a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java index 2687df25cf..dce02d8895 100644 --- a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java +++ b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java @@ -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() diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java index 12dc9b068c..84233ef310 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -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; } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index d0f106a1c8..3de67d4fb8 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -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 names); + + /** + * Sets which NPCs are hidden on death + * + * @param names the names of the npcs + */ + void setNPCsHiddenOnDeath(List 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. *

@@ -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 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. diff --git a/runelite-api/src/main/java/net/runelite/api/MainBufferProvider.java b/runelite-api/src/main/java/net/runelite/api/MainBufferProvider.java index c644859bd2..5c14f8cf1c 100644 --- a/runelite-api/src/main/java/net/runelite/api/MainBufferProvider.java +++ b/runelite-api/src/main/java/net/runelite/api/MainBufferProvider.java @@ -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. diff --git a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java index 706151e1c8..63e462843b 100644 --- a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java +++ b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java @@ -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; } diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index 0ceac97105..b66f73e078 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -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. diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 64a22743c6..cde3bbeafb 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -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; diff --git a/runelite-client/build.gradle b/runelite-client/build.gradle index 9d2d067d91..cbb3710f75 100644 --- a/runelite-client/build.gradle +++ b/runelite-client/build.gradle @@ -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 diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java index 8a1f4d1839..99e3bd50d5 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java @@ -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); } } diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 9cbc2c60c6..d95daefee5 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -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 void post(Class 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. diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index eaeebc8b82..b123d406b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -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) 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; diff --git a/runelite-client/src/main/java/net/runelite/client/config/FontType.java b/runelite-client/src/main/java/net/runelite/client/config/FontType.java index df1044de5c..8cf3dcbad8 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/FontType.java +++ b/runelite-client/src/main/java/net/runelite/client/config/FontType.java @@ -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() diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java index 1c5d861649..55075cac92 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java @@ -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 MAPPINGS = HashMultimap.create(); private final int tradeableItem; diff --git a/runelite-client/src/main/java/net/runelite/client/game/UntradeableItemMapping.java b/runelite-client/src/main/java/net/runelite/client/game/UntradeableItemMapping.java index 1884a9ac7b..2fd63f1fc0 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/UntradeableItemMapping.java +++ b/runelite-client/src/main/java/net/runelite/client/game/UntradeableItemMapping.java @@ -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 UNTRADEABLE_RECLAIM_MAP; diff --git a/runelite-client/src/main/java/net/runelite/client/game/WorldLocation.java b/runelite-client/src/main/java/net/runelite/client/game/WorldLocation.java index 701a2e1534..8ff7dbeeb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/WorldLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/game/WorldLocation.java @@ -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; diff --git a/runelite-client/src/main/java/net/runelite/client/graphics/ModelOutlineRenderer.java b/runelite-client/src/main/java/net/runelite/client/graphics/ModelOutlineRenderer.java index 9e9d14aca9..2d115b0855 100644 --- a/runelite-client/src/main/java/net/runelite/client/graphics/ModelOutlineRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/graphics/ModelOutlineRenderer.java @@ -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) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java index 5cbe672527..4e85727f21 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java @@ -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), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java index 1a017ba004..6c5c9735c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java @@ -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 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 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--; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 8304dbd5b2..6649cdc977 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -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: (\\d+)"); + private static final Pattern KILLCOUNT_PATTERN = Pattern.compile("Your (.+) (?:kill|harvest|lap|completion) count is: (\\d+)"); private static final Pattern RAIDS_PATTERN = Pattern.compile("Your completed (.+) count is: (\\d+)"); private static final Pattern WINTERTODT_PATTERN = Pattern.compile("Your subdued Wintertodt count is: (\\d+)"); private static final Pattern BARROWS_PATTERN = Pattern.compile("Your Barrows chest count is: (\\d+)"); - private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?:Fight|Lap) duration: [0-9:]+. Personal best: ([0-9:]+)"); - private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?:Fight|Lap) duration: ([0-9:]+) \\(new personal best\\)"); + private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: [0-9:]+\\. Personal best: ([0-9:]+)"); + private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: ([0-9:]+) \\(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); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java index c3a019d5bf..d9daec3b44 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java @@ -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)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index b3bd0c91db..1ca4216358 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -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."), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 4388c08b9b..f0388bed8b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -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); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java index 7c2e3e83e6..8200a00e1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java @@ -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()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxOverlay.java index 00d60e94ee..25df342865 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxOverlay.java @@ -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 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); + }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java index bde7448e3a..bb7b69bcf1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java @@ -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 (.*)! 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 Olm_Crystals = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) private List Olm_Heal = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) private List Olm_TP = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) private List Olm_PSN = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private List burnTarget = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private Actor teleportTarget; - @Getter(AccessLevel.PACKAGE) + private Set 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 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(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/NPCContainer.java b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/NPCContainer.java index 6265025058..ba0a17adb2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/NPCContainer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/NPCContainer.java @@ -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; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/Victim.java b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/Victim.java new file mode 100644 index 0000000000..b5b3684b3e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/Victim.java @@ -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; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java index aa7262b424..94a4237d59 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java @@ -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 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()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java index 10f6b7f905..a64a93e28b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java index 3115963a9f..a02659b4c5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java @@ -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) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java index ea63fe7136..7e78d776f1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java @@ -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), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderConfig.java index 154258d2d6..e817546a98 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderConfig.java @@ -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; } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java index 73263e4877..9fb8c196c1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java @@ -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() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java index 684cb8ab31..20f1c2f9be 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java index 622ef7d273..437f32700c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java index dca9efe014..7277065380 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java @@ -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 ), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java index 539c810de2..16922d9874 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsConfig.java @@ -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; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java index 17afae61b6..0103337792 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsOverlay.java @@ -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; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java index b33699436a..4af5c588a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java @@ -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. * *

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; *

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. - * - *

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; - } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletConfig.java new file mode 100644 index 0000000000..328fda2afc --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletConfig.java @@ -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; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletInfoBox.java deleted file mode 100644 index c07d509a3d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletInfoBox.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2019, 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; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletOverlay.java new file mode 100644 index 0000000000..915d636b78 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletOverlay.java @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2019, kThisIsCvpv + * Copyright (c) 2019, 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 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 = 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 vertices = model.getVertices(); + for (int i = 0; i < vertices.size(); ++i) + { + vertices.set(i, vertices.get(i).rotate(orientation)); + } + + List 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 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); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java index 7bffc75c7d..2bae9afb99 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, xperiaclash + * Copyright (c) 2019, kThisIsCvpv * Copyright (c) 2019, 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 PLAYER_ANIMATIONS = ImmutableSet.of(426, 1167, 422, 423, 440, 428); - private static final Set HUNLEFF_ANIMATIONS = ImmutableSet.of(AnimationID.HUNLEFF_ATTACK, AnimationID.HUNLEFF_TORNADO); - private static final Set HUNLEFF_MAGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLEFF_MAGE_ATTACK, ProjectileID.HUNLEFF_CORRUPTED_MAGE_ATTACK); - private static final Set 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 TORNADO_NPC_IDS = ImmutableSet.of(9025, 9039); + private static final Set MELEE_ANIMATIONS = ImmutableSet.of(395, 401, 400, 401, 386, 390, 422, 423, 401, 428, 440); + private static final Set PLAYER_ANIMATIONS = ImmutableSet.of(395, 401, 400, 401, 386, 390, 422, 423, 401, 428, 440, 426, 1167); + private static final Set HUNLLEF_MAGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_MAGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK); + private static final Set HUNLLEF_RANGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_RANGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK); + private static final Set HUNLLEF_PRAYER_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_PRAYER_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK); + private static final Set 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 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 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 = new HashSet<>(); + private final Set projectiles = new HashSet<>(); + private final Map items = new HashMap<>(); + private Set 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(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletTimer.java new file mode 100644 index 0000000000..1737bbec6e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletTimer.java @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2018, Seth + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.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. + *

+ * 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 + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Hunllef.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Hunllef.java new file mode 100644 index 0000000000..215c061923 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Hunllef.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2019, 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 + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Missiles.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Missiles.java new file mode 100644 index 0000000000..445d50a77a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Missiles.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019, 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; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Resources.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Resources.java new file mode 100644 index 0000000000..517a393ca8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Resources.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019, 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; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPluginConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Tornado.java similarity index 78% rename from runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPluginConfig.java rename to runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Tornado.java index d714001209..a9d2dee2b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletPluginConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/Tornado.java @@ -1,5 +1,4 @@ /* - * Copyright (c) 2019, xperiaclash * Copyright (c) 2019, 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--; + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java index 79c5545ef1..39f628e151 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 40b8a7f97c..1b4f9646e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index f0c7df167c..eb95a47ad8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -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()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java index 09bc5ab850..88db86c14c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java @@ -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: diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java b/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java index 968a50c869..01008bb1a2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java @@ -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; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsConfig.java index d538509825..faeef07940 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsConfig.java @@ -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( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java index 7c1f3077de..81afca3341 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java @@ -309,6 +309,7 @@ public class ImplingsPlugin extends Plugin return this.getNinjaColor; case CRYSTAL: return this.getCrystalColor; + case DRAGON: return this.getDragonColor; case LUCKY: diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index 95d31b4856..7e5cf64195 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index 13768f428a..e307aac089 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java index d71bcc0074..8d411a4aaa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java @@ -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), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java index dc20acc1d8..22ee17d8bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java @@ -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()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/GauntletPotion.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/GauntletPotion.java new file mode 100644 index 0000000000..9ecee451ce --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/GauntletPotion.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019, 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; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java index 857c50cef3..ab4f6a6ac1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java @@ -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) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java index a50e25af13..1c53f27aff 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java index addffcee41..454a9c0812 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 06850797da..e57210a6a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -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", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 54cca7656e..4d6bee3d61 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -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(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/teleEquippedMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/ConstructionCapeMode.java similarity index 69% rename from runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/teleEquippedMode.java rename to runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/ConstructionCapeMode.java index 9f22bcbc3e..41966d61d6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/teleEquippedMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/util/ConstructionCapeMode.java @@ -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; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java index b87b46d3ff..8ecfeba2bd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java @@ -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) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java index 880a74c8fe..c38ed61de1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java @@ -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; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java index 928522a48a..700e48108a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java @@ -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); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java index c9c405aa75..5c794ee741 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java @@ -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); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index 247b2f97ab..c13389485d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java index 9c32dabc51..7993ae37ca 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java @@ -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(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java index 28b554e6f2..d6ebee4681 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java @@ -116,7 +116,7 @@ class ProfilesPanel extends PluginPanel JPanel helpPanel = new JPanel(new BorderLayout()); helpPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); JLabel helpLabel = new JLabel("

" + HELP + "

"); - helpLabel.setFont(FontManager.getSmallFont(getFont())); + helpLabel.setFont(FontManager.getRunescapeSmallFont()); helpPanel.setPreferredSize(HELP_PREFERRED_SIZE); // helpPanel.setSize(MINIMUM_SIZE); helpPanel.add(helpLabel, BorderLayout.NORTH); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index e73188e953..02613488e8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -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 itemNames = Text.fromCSV(everything.substring(split)); map.computeIfAbsent(key, k -> new ArrayList<>()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/Obstacles.java b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/Obstacles.java index 59c2c9428e..62fd01bcc0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/Obstacles.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/Obstacles.java @@ -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 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 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 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); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenMinimapOverlay.java new file mode 100644 index 0000000000..4dc0c11b9e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenMinimapOverlay.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018, Jordan Atwood + * 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; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenOverlay.java index e76f6c4f70..2a4775fdce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenOverlay.java @@ -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; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java index 469a1ff4cd..e77b5e2019 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java @@ -25,18 +25,19 @@ package net.runelite.client.plugins.roguesden; import java.util.HashMap; -import java.util.Map; import javax.inject.Inject; -import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.InventoryID; -import net.runelite.api.Item; -import net.runelite.api.ItemID; +import static net.runelite.api.ItemID.MYSTIC_JEWEL; import net.runelite.api.Tile; import net.runelite.api.TileObject; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.DecorativeObjectChanged; +import net.runelite.api.events.DecorativeObjectDespawned; +import net.runelite.api.events.DecorativeObjectSpawned; import net.runelite.api.events.GameObjectChanged; import net.runelite.api.events.GameObjectDespawned; import net.runelite.api.events.GameObjectSpawned; @@ -45,24 +46,27 @@ import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.events.WallObjectChanged; +import net.runelite.api.events.WallObjectDespawned; +import net.runelite.api.events.WallObjectSpawned; import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.ItemUtil; @PluginDescriptor( - name = "Rogues' Den", - description = "Mark tiles and clickboxes to help traverse the maze", - tags = {"agility", "maze", "minigame", "overlay", "thieving"} + name = "Rogues' Den", + description = "Mark tiles and clickboxes to help traverse the maze", + tags = {"agility", "maze", "minigame", "overlay", "thieving"} ) -@Singleton public class RoguesDenPlugin extends Plugin { @Getter(AccessLevel.PACKAGE) - private final Map obstaclesHull = new HashMap<>(); + private final HashMap obstaclesHull = new HashMap<>(); @Getter(AccessLevel.PACKAGE) - private final Map obstaclesTile = new HashMap<>(); + private final HashMap obstaclesTile = new HashMap<>(); @Getter(AccessLevel.PACKAGE) private boolean hasGem; @@ -76,6 +80,9 @@ public class RoguesDenPlugin extends Plugin @Inject private RoguesDenOverlay overlay; + @Inject + private RoguesDenMinimapOverlay minimapOverlay; + @Inject private EventBus eventBus; @@ -85,6 +92,7 @@ public class RoguesDenPlugin extends Plugin addSubscriptions(); overlayManager.add(overlay); + overlayManager.add(minimapOverlay); } @Override @@ -93,6 +101,7 @@ public class RoguesDenPlugin extends Plugin eventBus.unregister(this); overlayManager.remove(overlay); + overlayManager.remove(minimapOverlay); obstaclesHull.clear(); obstaclesTile.clear(); hasGem = false; @@ -108,6 +117,12 @@ public class RoguesDenPlugin extends Plugin eventBus.subscribe(GroundObjectChanged.class, this, this::onGroundObjectChanged); eventBus.subscribe(GroundObjectDespawned.class, this, this::onGroundObjectDespawned); eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); + eventBus.subscribe(WallObjectChanged.class, this, this::onWallObjectChanged); + eventBus.subscribe(WallObjectDespawned.class, this, this::onWallObjectDespawned); + eventBus.subscribe(DecorativeObjectSpawned.class, this, this::onDecorativeObjectSpawned); + eventBus.subscribe(DecorativeObjectChanged.class, this, this::onDecorativeObjectChanged); + eventBus.subscribe(DecorativeObjectDespawned.class, this, this::onDecorativeObjectDespawned); } private void onItemContainerChanged(ItemContainerChanged event) @@ -117,16 +132,16 @@ public class RoguesDenPlugin extends Plugin return; } - for (Item item : event.getItemContainer().getItems()) - { - if (item.getId() == ItemID.MYSTIC_JEWEL) - { - hasGem = true; - return; - } - } + hasGem = ItemUtil.containsItemId(event.getItemContainer().getItems(), MYSTIC_JEWEL); + } - hasGem = false; + private void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOADING) + { + obstaclesHull.clear(); + obstaclesTile.clear(); + } } private void onGameObjectSpawned(GameObjectSpawned event) @@ -159,27 +174,48 @@ public class RoguesDenPlugin extends Plugin onTileObject(event.getTile(), event.getGroundObject(), null); } - private void onGameStateChanged(GameStateChanged event) + private void onWallObjectSpawned(WallObjectSpawned event) { - if (event.getGameState() == GameState.LOADING) - { - obstaclesHull.clear(); - obstaclesTile.clear(); - } + onTileObject(event.getTile(), null, event.getWallObject()); } - private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject) + private void onWallObjectChanged(WallObjectChanged event) + { + onTileObject(event.getTile(), event.getPrevious(), event.getWallObject()); + } + + private void onWallObjectDespawned(WallObjectDespawned event) + { + onTileObject(event.getTile(), event.getWallObject(), null); + } + + private void onDecorativeObjectSpawned(DecorativeObjectSpawned event) + { + onTileObject(event.getTile(), null, event.getDecorativeObject()); + } + + private void onDecorativeObjectChanged(DecorativeObjectChanged event) + { + onTileObject(event.getTile(), event.getPrevious(), event.getDecorativeObject()); + } + + private void onDecorativeObjectDespawned(DecorativeObjectDespawned event) + { + onTileObject(event.getTile(), event.getDecorativeObject(), null); + } + + private void onTileObject(final Tile tile, final TileObject oldObject, final TileObject newObject) { obstaclesHull.remove(oldObject); - if (newObject != null && Obstacles.OBSTACLE_IDS_HULL.contains(newObject.getId())) + if (newObject != null) { - obstaclesHull.put(newObject, tile); - } + WorldPoint point = tile.getWorldLocation(); - obstaclesTile.remove(oldObject); - if (newObject != null && Obstacles.OBSTACLE_IDS_TILE.contains(newObject.getId())) - { - obstaclesTile.put(newObject, tile); + Obstacles.Obstacle obstacle = Obstacles.TILE_MAP.get(point); + if (obstacle != null && obstacle.getObjectId() == newObject.getId()) + { + obstaclesHull.put(newObject, tile); + } } } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java index f587c38818..968e983d74 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java @@ -90,10 +90,6 @@ public class RunepouchOverlay extends WidgetItemOverlay Point location = itemWidget.getCanvasLocation(); StringBuilder tooltipBuilder = new StringBuilder(); - // location.getY() + graphics.getFontMetrics().getMaxAscent() - graphics.getFontMetrics().getMaxDescent() - // this will draw the character exactly on the border - int yLocation = location.getY() + 1 + - graphics.getFontMetrics().getMaxAscent() - graphics.getFontMetrics().getMaxDescent(); for (int i = 0; i < AMOUNT_VARBITS.length; i++) { Varbits amountVarbit = AMOUNT_VARBITS[i]; @@ -129,12 +125,9 @@ public class RunepouchOverlay extends WidgetItemOverlay int yOffset = (1 + (graphics.getFontMetrics().getMaxAscent()) * i); graphics.setColor(Color.black); - graphics.drawString("" + formatNumber(amount), location.getX() + (plugin.isShowIcons() ? 13 : 6), - yLocation + yOffset); - graphics.setColor(plugin.getFontColor()); graphics.drawString("" + formatNumber(amount), location.getX() + (plugin.isShowIcons() ? 12 : 5), - yLocation + yOffset); + location.getY() + 13 + (graphics.getFontMetrics().getHeight() - 1) * i); graphics.setColor(plugin.getFontColor()); graphics.drawString("" + formatNumber(amount), location.getX() + (plugin.isShowIcons() ? 11 : 4), @@ -149,13 +142,7 @@ public class RunepouchOverlay extends WidgetItemOverlay if (image != null) { OverlayUtil.renderImageLocation(graphics, - //TODO :: SEE WHAT ONE IS RIGHT? - //new Point(location.getX() - 1, location.getY() + graphics.getFontMetrics().getMaxAscent() * i - 1), - //image); - //or - //new Point(location.getX(), location.getY() + (1 + graphics.getFontMetrics().getMaxAscent()) * i), - //image); - new Point(location.getX(), location.getY() + (1 + graphics.getFontMetrics().getMaxAscent()) * i), + new Point(location.getX() - 1, location.getY() + graphics.getFontMetrics().getHeight() * i - 1), image); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java index 82197c6160..d3c61ff5a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java @@ -71,7 +71,7 @@ public class ScreenMarkerCreationPanel extends JPanel setBorder(new EmptyBorder(8, 8, 8, 8)); setLayout(new BorderLayout()); - instructionsLabel.setFont(FontManager.getSmallFont(getFont())); + instructionsLabel.setFont(FontManager.getRunescapeSmallFont()); instructionsLabel.setForeground(Color.WHITE); JPanel actionsContainer = new JPanel(new GridLayout(1, 2, 8, 0)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index 3aced96c5a..108282172a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -162,7 +162,7 @@ class ScreenMarkerPanel extends JPanel nameActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); save.setVisible(false); - save.setFont(FontManager.getSmallFont(getFont())); + save.setFont(FontManager.getRunescapeSmallFont()); save.setForeground(ColorScheme.PROGRESS_COMPLETE_COLOR); save.addMouseListener(new MouseAdapter() { @@ -191,7 +191,7 @@ class ScreenMarkerPanel extends JPanel }); cancel.setVisible(false); - cancel.setFont(FontManager.getSmallFont(getFont())); + cancel.setFont(FontManager.getRunescapeSmallFont()); cancel.setForeground(ColorScheme.PROGRESS_ERROR_COLOR); cancel.addMouseListener(new MouseAdapter() { @@ -217,7 +217,7 @@ class ScreenMarkerPanel extends JPanel } }); - rename.setFont(FontManager.getSmallFont(getFont())); + rename.setFont(FontManager.getRunescapeSmallFont()); rename.setForeground(ColorScheme.LIGHT_GRAY_COLOR.darker()); rename.addMouseListener(new MouseAdapter() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 234e79ab73..d0d2c8de09 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -115,9 +115,9 @@ import okhttp3.Response; import org.jetbrains.annotations.Nullable; @PluginDescriptor( - name = "Screenshot", - description = "Enable the manual and automatic taking of screenshots", - tags = {"external", "images", "imgur", "integration", "notifications"} + name = "Screenshot", + description = "Enable the manual and automatic taking of screenshots", + tags = {"external", "images", "imgur", "integration", "notifications"} ) @Slf4j @Singleton @@ -136,8 +136,8 @@ public class ScreenshotPlugin extends Plugin private static final Pattern UNTRADEABLE_DROP_PATTERN = Pattern.compile(".*Untradeable drop: ([^<>]+)(?:)?"); private static final Pattern DUEL_END_PATTERN = Pattern.compile("You have now (won|lost) ([0-9]+) duels?\\."); private static final ImmutableList PET_MESSAGES = ImmutableList.of("You have a funny feeling like you're being followed", - "You feel something weird sneaking into your backpack", - "You have a funny feeling like you would have been followed"); + "You feel something weird sneaking into your backpack", + "You have a funny feeling like you would have been followed"); private static String format(Date date) { @@ -253,25 +253,25 @@ public class ScreenshotPlugin extends Plugin final BufferedImage iconImage = ImageUtil.getResourceStreamFromClass(getClass(), "screenshot.png"); titleBarButton = NavigationButton.builder() - .tab(false) - .tooltip("Take screenshot") - .icon(iconImage) - .onClick(() -> takeScreenshot(format(new Date()))) - .popup(ImmutableMap - .builder() - .put("Open screenshot folder...", () -> - { - try - { - Desktop.getDesktop().open(SCREENSHOT_DIR); - } - catch (IOException ex) - { - log.warn("Error opening screenshot dir", ex); - } - }) - .build()) - .build(); + .tab(false) + .tooltip("Take screenshot") + .icon(iconImage) + .onClick(() -> takeScreenshot(format(new Date()))) + .popup(ImmutableMap + .builder() + .put("Open screenshot folder...", () -> + { + try + { + Desktop.getDesktop().open(SCREENSHOT_DIR); + } + catch (IOException ex) + { + log.warn("Error opening screenshot dir", ex); + } + }) + .build()) + .build(); clientToolbar.addNavigation(titleBarButton); @@ -302,7 +302,7 @@ public class ScreenshotPlugin extends Plugin private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN - && reportButton == null) + && reportButton == null) { reportButton = spriteManager.getSprite(SpriteID.CHATBOX_REPORT_BUTTON, 0); } @@ -358,9 +358,17 @@ public class ScreenshotPlugin extends Plugin private void onAnimationChanged(AnimationChanged e) { - //this got refactored somewhere, but some things were missing - if (!this.screenshotFriendDeath || !this.screenshotPlayerDeath) + + if (e.getActor().getAnimation() != 836) + { return; + } + + if (this.screenshotPlayerDeath && client.getLocalPlayer().equals(e.getActor())) + { + takeScreenshot("Death - " + format(new Date())); + } + if (!(e.getActor() instanceof Player)) return; @@ -705,7 +713,7 @@ public class ScreenshotPlugin extends Plugin Consumer imageCallback = (img) -> { // This callback is on the game thread, move to executor thread - executor.submit(() -> takeScreenshot(fileName, img, subdirectory)); + executor.submit(() -> takeScreenshot(fileName, img, subdirectory)); }; @@ -721,8 +729,8 @@ public class ScreenshotPlugin extends Plugin private void takeScreenshot(String fileName, Image image, @Nullable String subdirectory) { BufferedImage screenshot = this.includeFrame - ? new BufferedImage(clientUi.getWidth(), clientUi.getHeight(), BufferedImage.TYPE_INT_ARGB) - : new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); + ? new BufferedImage(clientUi.getWidth(), clientUi.getHeight(), BufferedImage.TYPE_INT_ARGB) + : new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics graphics = screenshot.getGraphics(); @@ -826,10 +834,10 @@ public class ScreenshotPlugin extends Plugin { RequestBody body = RequestBody.Companion.create(json, JSON); request = new Request.Builder() - .url(IMGUR_IMAGE_UPLOAD_URL) - .addHeader("Authorization", "Client-ID " + IMGUR_CLIENT_ID) - .post(body) - .build(); + .url(IMGUR_IMAGE_UPLOAD_URL) + .addHeader("Authorization", "Client-ID " + IMGUR_CLIENT_ID) + .post(body) + .build(); } if (request != null) @@ -848,13 +856,13 @@ public class ScreenshotPlugin extends Plugin try (InputStream in = response.body().byteStream()) { ImageUploadResponse imageUploadResponse = RuneLiteAPI.GSON - .fromJson(new InputStreamReader(in), ImageUploadResponse.class); + .fromJson(new InputStreamReader(in), ImageUploadResponse.class); if (imageUploadResponse.isSuccess()) { String link = imageUploadResponse.getData().getLink(); - Clipboard.store(link); + Clipboard.store(link); if (notifyWhenTaken) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java index 16aee82217..ff53e7ce03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java @@ -232,16 +232,22 @@ public enum Activity CriticalItem.SHAIKAHAN_BONES, null, null), BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, "Babydragon bones", Skill.PRAYER, 1, 30.0, CriticalItem.BABYDRAGON_BONES, null, null), + WYRM_BONES(ItemID.WYRM_BONES, "Wyrm bones", Skill.PRAYER, 1, 50, + CriticalItem.WYRM_BONES, null, null), WYVERN_BONES(ItemID.WYVERN_BONES, "Wyvern bones", Skill.PRAYER, 1, 72.0, CriticalItem.WYVERN_BONES, null, null), DRAGON_BONES(ItemID.DRAGON_BONES, "Dragon bones", Skill.PRAYER, 1, 72.0, CriticalItem.DRAGON_BONES, null, null), + DRAKE_BONES(ItemID.DRAKE_BONES, "Drake bones", Skill.PRAYER, 1, 80, + CriticalItem.DRAKE_BONES, null, null), FAYRG_BONES(ItemID.FAYRG_BONES, "Fayrg bones", Skill.PRAYER, 1, 84.0, CriticalItem.FAYRG_BONES, null, null), LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, "Lava dragon bones", Skill.PRAYER, 1, 85.0, CriticalItem.LAVA_DRAGON_BONES, null, null), RAURG_BONES(ItemID.RAURG_BONES, "Raurg bones", Skill.PRAYER, 1, 96.0, CriticalItem.RAURG_BONES, null, null), + HYDRA_BONES(ItemID.HYDRA_BONES, "Hydra bones", Skill.PRAYER, 1, 110, + CriticalItem.HYDRA_BONES, null, null), DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, "Dagannoth bones", Skill.PRAYER, 1, 125.0, CriticalItem.DAGANNOTH_BONES, null, null), OURG_BONES(ItemID.OURG_BONES, "Ourg bones", Skill.PRAYER, 1, 140.0, @@ -719,4 +725,4 @@ public enum Activity a.outputItemInfo = new ItemInfo(c.getName(), c.isStackable()); } } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java index d6f3752742..dad745e77e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java @@ -117,11 +117,14 @@ public enum CriticalItem ZOGRE_BONES(ItemID.ZOGRE_BONES, Skill.PRAYER, "Bones"), SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, Skill.PRAYER, "Bones"), BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, Skill.PRAYER, "Bones"), + WYRM_BONES(ItemID.WYRM_BONES, Skill.PRAYER, "Bones"), WYVERN_BONES(ItemID.WYVERN_BONES, Skill.PRAYER, "Bones"), DRAGON_BONES(ItemID.DRAGON_BONES, Skill.PRAYER, "Bones"), + DRAKE_BONES(ItemID.DRAKE_BONES, Skill.PRAYER, "Bones"), FAYRG_BONES(ItemID.FAYRG_BONES, Skill.PRAYER, "Bones"), LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, Skill.PRAYER, "Bones"), RAURG_BONES(ItemID.RAURG_BONES, Skill.PRAYER, "Bones"), + HYDRA_BONES(ItemID.HYDRA_BONES, Skill.PRAYER, "Bones"), DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, Skill.PRAYER, "Bones"), OURG_BONES(ItemID.OURG_BONES, Skill.PRAYER, "Bones"), SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, Skill.PRAYER, "Bones"), @@ -352,4 +355,4 @@ public enum CriticalItem i.itemInfo = new ItemInfo(c.getName(), c.isStackable()); } } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java index 52ee0770aa..1291c12d44 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java @@ -117,7 +117,7 @@ class SlayerOverlay extends WidgetItemOverlay return; } - graphics.setFont(FontManager.getSmallFont(graphics.getFont())); + graphics.setFont(FontManager.getRunescapeBoldFont()); final Rectangle bounds = itemWidget.getCanvasBounds(); final TextComponent textComponent = new TextComponent(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerTaskPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerTaskPanel.java index d9eb0d0065..f865237fe9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerTaskPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerTaskPanel.java @@ -195,8 +195,8 @@ public class SlayerTaskPanel 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())); - overallTimeLabel.setFont(FontManager.getSmallFont(getFont())); + overallKillsLabel.setFont(FontManager.getRunescapeSmallFont()); + overallTimeLabel.setFont(FontManager.getRunescapeSmallFont()); overallInfo.add(overallKillsLabel); overallInfo.add(overallTimeLabel); overallPanel.add(overallIcon, BorderLayout.WEST); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java index 983587c50c..088d2421b5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPanel.java @@ -90,8 +90,8 @@ class SuppliesTrackerPanel extends PluginPanel overallInfo.setBackground(ColorScheme.DARKER_GRAY_COLOR); overallInfo.setLayout(new GridLayout(2, 1)); overallInfo.setBorder(new EmptyBorder(0, 10, 0, 0)); - overallSuppliesUsedLabel.setFont(FontManager.getSmallFont(getFont())); - overallCostLabel.setFont(FontManager.getSmallFont(getFont())); + overallSuppliesUsedLabel.setFont(FontManager.getRunescapeSmallFont()); + overallCostLabel.setFont(FontManager.getRunescapeSmallFont()); overallInfo.add(overallSuppliesUsedLabel); overallInfo.add(overallCostLabel); overallPanel.add(overallIcon, BorderLayout.WEST); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java index 142d40e982..2f9fe2db68 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java @@ -10,8 +10,6 @@ package net.runelite.client.plugins.theatre; import com.google.inject.Provides; import java.awt.Color; -import java.util.LinkedList; -import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; @@ -28,12 +26,9 @@ import net.runelite.api.events.NpcDefinitionChanged; 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.api.events.VarbitChanged; -import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetID; -import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.graphics.ModelOutlineRenderer; @@ -57,103 +52,55 @@ import net.runelite.client.ui.overlay.OverlayManager; ) @Singleton @Slf4j +@Getter public class TheatrePlugin extends Plugin { - @Getter(AccessLevel.PUBLIC) - @Setter(AccessLevel.PUBLIC) - private TheatreRoom room; - - @Getter(AccessLevel.PUBLIC) - private MaidenHandler maidenHandler; - - @Getter(AccessLevel.PUBLIC) - private BloatHandler bloatHandler; - - @Getter(AccessLevel.PUBLIC) - private NyloHandler nyloHandler; - - @Getter(AccessLevel.PUBLIC) - private SotetsegHandler sotetsegHandler; - - @Getter(AccessLevel.PUBLIC) - private XarpusHandler xarpusHandler; - - @Getter(AccessLevel.PUBLIC) - private VerzikHandler verzikHandler; - @Inject private Client client; - @Inject private EventBus eventBus; - - private Widget widget = null; - - @Getter(AccessLevel.PUBLIC) @Inject private OverlayManager overlayManager; - @Inject private TheatreOverlay overlay; - @Inject private TheatreConfig config; - @Inject private ModelOutlineRenderer modelOutline; - - @Getter - private boolean showMaidenBloodToss; - @Getter - private boolean showMaidenBloodSpawns; - @Getter - private boolean showNyloFreezeHighlights; - @Getter - private boolean showBloatIndicator; - @Getter - private boolean showBloatHands; - @Getter + private BloatHandler bloatHandler; + private MaidenHandler maidenHandler; + private NyloHandler nyloHandler; + private SotetsegHandler sotetsegHandler; + @Setter(AccessLevel.PUBLIC) + private TheatreRoom room; + private VerzikHandler verzikHandler; + private XarpusHandler xarpusHandler; private boolean BloatFeetIndicatorRaveEdition; - @Getter - private boolean showBloatTimer; - @Getter - private boolean showNyloPillarHealth; - @Getter - private TheatreConfig.NYLOOPTION showNylocasExplosions; - @Getter - private boolean showNylocasAmount; - @Getter - private boolean highlightNyloAgros; - @Getter - private boolean showSotetsegAttacks; - @Getter - private boolean showSotetsegMaze; - @Getter - private boolean showSotetsegSolo; - @Getter - private Color mazeTileColour; - @Getter - private boolean showXarpusHeals; - @Getter - private boolean showXarpusTick; - @Getter - private boolean showVerzikAttacks; - @Getter - private boolean showVerzikYellows; - @Getter - private boolean showCrabTargets; - @Getter - private boolean VerzikTankTile; - @Getter - private boolean verzikRangeAttacks; - @Getter private boolean extraTimers; - @Getter + private boolean highlightNyloAgros; private boolean p1attacks; - @Getter private boolean p2attacks; - @Getter private boolean p3attacks; + private boolean showBloatHands; + private boolean showBloatIndicator; + private boolean showBloatTimer; + private boolean showCrabTargets; + private boolean showMaidenBloodSpawns; + private boolean showMaidenBloodToss; + private boolean showNylocasAmount; + private boolean showNyloFreezeHighlights; + private boolean showNyloPillarHealth; + private boolean showSotetsegAttacks; + private boolean showSotetsegMaze; + private boolean showSotetsegSolo; + private boolean showVerzikAttacks; + private boolean showVerzikYellows; + private boolean showXarpusHeals; + private boolean showXarpusTick; + private boolean verzikRangeAttacks; + private boolean VerzikTankTile; + private Color mazeTileColour; + private TheatreConfig.NYLOOPTION showNylocasExplosions; @Provides TheatreConfig getConfig(ConfigManager configManager) @@ -166,16 +113,13 @@ public class TheatrePlugin extends Plugin { updateConfig(); addSubscriptions(); - room = TheatreRoom.UNKNOWN; - maidenHandler = new MaidenHandler(client, this, modelOutline); bloatHandler = new BloatHandler(client, this); nyloHandler = new NyloHandler(client, this); sotetsegHandler = new SotetsegHandler(client, this); xarpusHandler = new XarpusHandler(client, this); verzikHandler = new VerzikHandler(client, this); - overlayManager.add(overlay); } @@ -183,52 +127,111 @@ public class TheatrePlugin extends Plugin protected void shutDown() { eventBus.unregister(this); - maidenHandler.onStop(); maidenHandler = null; - bloatHandler.onStop(); bloatHandler = null; - nyloHandler.startTime = 0L; nyloHandler.onStop(); nyloHandler = null; - sotetsegHandler.onStop(); sotetsegHandler = null; - xarpusHandler.onStop(); xarpusHandler = null; - verzikHandler.onStop(); verzikHandler = null; - room = TheatreRoom.UNKNOWN; - overlayManager.remove(overlay); } private void addSubscriptions() { - eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); - eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); - eventBus.subscribe(NpcDefinitionChanged.class, this, this::onNpcDefinitionChanged); - eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); - eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); - eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); eventBus.subscribe(GameTick.class, this, this::onGameTick); eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); - eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(NpcDefinitionChanged.class, this, this::onNpcDefinitionChanged); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); } - private void onSpotAnimationChanged(SpotAnimationChanged event) + private void onAnimationChanged(AnimationChanged event) + { + if (verzikHandler != null) + { + verzikHandler.onAnimationChanged(event); + } + } + + private void onChatMessage(ChatMessage event) { if (maidenHandler != null) { - maidenHandler.onSpotAnimationChanged(event); + maidenHandler.onChatMessage(event); + } + } + + private void onConfigChanged(ConfigChanged event) + { + if (!event.getGroup().equals("Theatre")) + { + return; + } + + if (nyloHandler != null) + { + nyloHandler.onConfigChanged(); + } + } + + private void onGameTick(GameTick event) + { + if (maidenHandler != null) + { + maidenHandler.onGameTick(); + } + + if (bloatHandler != null) + { + bloatHandler.onGameTick(); + } + + if (nyloHandler != null) + { + nyloHandler.onGameTick(); + } + + if (sotetsegHandler != null) + { + sotetsegHandler.onGameTick(); + } + + if (xarpusHandler != null) + { + xarpusHandler.onGameTick(); + } + + if (verzikHandler != null) + { + verzikHandler.onGameTick(); + } + } + + private void onGroundObjectSpawned(GroundObjectSpawned event) + { + if (sotetsegHandler != null) + { + sotetsegHandler.onGroundObjectSpawned(event); + } + + if (xarpusHandler != null) + { + xarpusHandler.onGroundObjectSpawned(event); } } @@ -240,6 +243,35 @@ public class TheatrePlugin extends Plugin } } + private void onNpcDespawned(NpcDespawned event) + { + if (maidenHandler != null) + { + maidenHandler.onNpcDespawned(event); + } + + if (bloatHandler != null) + { + bloatHandler.onNpcDespawned(event); + } + + if (nyloHandler != null) + { + nyloHandler.onNpcDespawned(event); + } + + if (sotetsegHandler != null) + { + sotetsegHandler.onNpcDespawned(event); + } + + if (xarpusHandler != null) + { + xarpusHandler.onNpcDespawned(event); + } + + } + private void onNpcSpawned(NpcSpawned event) { if (maidenHandler != null) @@ -274,214 +306,28 @@ public class TheatrePlugin extends Plugin } - private void onNpcDespawned(NpcDespawned event) - { - if (maidenHandler != null) - { - maidenHandler.onNpcDespawned(event); - } - - if (bloatHandler != null) - { - bloatHandler.onNpcDespawned(event); - } - - if (nyloHandler != null) - { - nyloHandler.onNpcDespawned(event); - } - - if (sotetsegHandler != null) - { - sotetsegHandler.onNpcDespawned(event); - } - - if (xarpusHandler != null) - { - xarpusHandler.onNpcDespawned(event); - } - - } - - private void onAnimationChanged(AnimationChanged event) + private void onProjectileMoved(ProjectileMoved event) { if (verzikHandler != null) { - verzikHandler.onAnimationChanged(event); + verzikHandler.onProjectileMoved(event); } } - private void onChatMessage(ChatMessage event) - { - if (maidenHandler != null) - { - maidenHandler.onChatMessage(event); - } - } - - private void onWidgetLoaded(WidgetLoaded event) - { - if (event.getGroupId() != WidgetID.PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID && event.getGroupId() != WidgetID.PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID) - { - return; - } - - if (event.getGroupId() == WidgetID.PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID) - { - widget = client.getWidget(WidgetID.PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID, 0); - } - - if (event.getGroupId() == WidgetID.PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID) - { - widget = client.getWidget(WidgetID.PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID, 0); - } - } - - private void onGameTick(GameTick event) - { - if (maidenHandler != null) - { - maidenHandler.onGameTick(); - } - - if (bloatHandler != null) - { - bloatHandler.onGameTick(); - } - - if (nyloHandler != null) - { - nyloHandler.onGameTick(); - } - - if (sotetsegHandler != null) - { - sotetsegHandler.onGameTick(); - } - - if (xarpusHandler != null) - { - xarpusHandler.onGameTick(); - } - - if (verzikHandler != null) - { - verzikHandler.onGameTick(); - } - - if (widget == null) - { - return; - } - - // recheck if the widget is still active - int p_id = WidgetInfo.TO_GROUP(widget.getId()); - - List widgetList = new LinkedList<>(); - - if (p_id == WidgetID.PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID) - { - Widget w = client.getWidget(p_id, 16); - if (w == null) - { - return; - } - - Widget[] ws = w.getStaticChildren(); - for (Widget widget : ws) - { - Widget[] widgets = widget.getDynamicChildren(); - if (widgets.length > 3) - { - widgetList.add(widgets[3]); - } - } - - } - else if (p_id == WidgetID.PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID) - { - Widget w1 = client.getWidget(p_id, 26); - - if (w1 != null) - { - Widget[] dChildsAccepted = w1.getDynamicChildren(); - - if (dChildsAccepted.length > 2) - { - for (int i = 1; i < dChildsAccepted.length; i += 11) - { - if (!dChildsAccepted[i].getText().equals("-")) - { - widgetList.add(dChildsAccepted[i]); - } - } - } - } - - Widget w2 = client.getWidget(p_id, 41); - - if (w2 != null) - { - Widget[] dChildsApplied = w2.getDynamicChildren(); - - if (dChildsApplied.length > 2) - { - for (int i = 1; i < dChildsApplied.length; i += 11) - { - if (!dChildsApplied[i].getText().equals("-")) - { - widgetList.add(dChildsApplied[i]); - } - } - } - } - } - - for (Widget w : widgetList) - { - String wtext = w.getText(); - if (client.isFriended(wtext, false)) - { - w.setTextColor(Color.green.getRGB()); - continue; - } - for (int i = 0; i < client.getIgnoreCount(); i++) - { - String name = client.getIgnores()[i].getName(); - if (name.replace('\u00A0', ' ').equals(wtext)) - { - w.setTextColor(Color.red.getRGB()); - break; - } - } - } - - widget = null; - } - - private void onGroundObjectSpawned(GroundObjectSpawned event) + private void onProjectileSpawned(ProjectileSpawned event) { if (sotetsegHandler != null) { - sotetsegHandler.onGroundObjectSpawned(event); - } + sotetsegHandler.onProjectileSpawned(event); - if (xarpusHandler != null) - { - xarpusHandler.onGroundObjectSpawned(event); } } - private void onConfigChanged(ConfigChanged event) + private void onSpotAnimationChanged(SpotAnimationChanged event) { - if (!event.getGroup().equals("Theatre")) + if (maidenHandler != null) { - return; - } - - if (nyloHandler != null) - { - nyloHandler.onConfigChanged(); + maidenHandler.onSpotAnimationChanged(event); } } @@ -498,19 +344,6 @@ public class TheatrePlugin extends Plugin } } - private void onProjectileMoved(ProjectileMoved event) - { - if (sotetsegHandler != null) - { - sotetsegHandler.onProjectileMoved(event); - - } - if (verzikHandler != null) - { - verzikHandler.onProjectileMoved(event); - } - } - private void updateConfig() { this.showMaidenBloodToss = config.showMaidenBloodToss(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java index ae6aabfcf3..8d792afc60 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/SotetsegHandler.java @@ -6,9 +6,11 @@ import java.awt.Graphics2D; import java.awt.Polygon; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.Client; @@ -22,7 +24,7 @@ import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; -import net.runelite.api.events.ProjectileMoved; +import net.runelite.api.events.ProjectileSpawned; import net.runelite.client.plugins.theatre.RoomHandler; import net.runelite.client.plugins.theatre.TheatreConstant; import net.runelite.client.plugins.theatre.TheatrePlugin; @@ -43,7 +45,7 @@ public class SotetsegHandler extends RoomHandler private final List blackUnderworld = new ArrayList<>(); private final List redUnderworld = new ArrayList<>(); private final List gridPath = new ArrayList<>(); - private final Map soteyProjectiles = new HashMap<>(); + private final Set soteyProjectiles = new HashSet<>(); private NPC npc; public SotetsegHandler(final Client client, final TheatrePlugin plugin) @@ -120,7 +122,7 @@ public class SotetsegHandler extends RoomHandler { Map projectileMap = new HashMap<>(); - for (Projectile p : soteyProjectiles.keySet()) + for (Projectile p : soteyProjectiles) { final int ticksRemaining = p.getRemainingCycles() / 30; int id = p.getId(); @@ -140,15 +142,14 @@ public class SotetsegHandler extends RoomHandler } } - public void onProjectileMoved(ProjectileMoved event) + public void onProjectileSpawned(ProjectileSpawned event) { - Projectile projectile = event.getProjectile(); + final Projectile projectile = event.getProjectile(); //1604 ball - if (event.getPosition().getX() == playerX && event.getPosition().getY() == playerY || event.getProjectile().getId() == 1604) + if (projectile.getId() == 1604 && projectile.getInteracting() == client.getLocalPlayer()) { - WorldPoint p = WorldPoint.fromLocal(client, event.getPosition()); - soteyProjectiles.put(projectile, p); + soteyProjectiles.add(projectile); } } @@ -241,7 +242,7 @@ public class SotetsegHandler extends RoomHandler //Remove projectiles that are about to die if (!soteyProjectiles.isEmpty()) { - soteyProjectiles.keySet().removeIf(p -> p.getRemainingCycles() < 1); + soteyProjectiles.removeIf(p -> p.getRemainingCycles() <= 0); } boolean sotetsegFighting = false; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index 1f3406a040..e3088c219f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -73,7 +73,13 @@ enum GameTimer SKULL(SpriteID.PLAYER_KILLER_SKULL_523, GameTimerImageType.SPRITE, "Skull", 20, ChronoUnit.MINUTES), ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Antipoison"), ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom"), - DRAGON_FIRE_SHIELD(ItemID.DRAGONFIRE_SHIELD_11284, GameTimerImageType.ITEM, "Dragonfire Shield Special", 2, ChronoUnit.MINUTES); + DRAGON_FIRE_SHIELD(ItemID.DRAGONFIRE_SHIELD_11284, GameTimerImageType.ITEM, "Dragonfire Shield Special", 2, ChronoUnit.MINUTES), + DIVINE_SUPER_ATTACK(ItemID.DIVINE_SUPER_ATTACK_POTION4, GameTimerImageType.ITEM, "Divine Super Attack", 5, ChronoUnit.MINUTES, true), + DIVINE_SUPER_STRENGTH(ItemID.DIVINE_SUPER_STRENGTH_POTION4, GameTimerImageType.ITEM, "Divine Super Strength", 5, ChronoUnit.MINUTES, true), + DIVINE_SUPER_DEFENCE(ItemID.DIVINE_SUPER_DEFENCE_POTION4, GameTimerImageType.ITEM, "Divine Super Defence", 5, ChronoUnit.MINUTES, true), + DIVINE_SUPER_COMBAT(ItemID.DIVINE_SUPER_COMBAT_POTION4, GameTimerImageType.ITEM, "Divine Super Combat", 5, ChronoUnit.MINUTES, true), + DIVINE_RANGING(ItemID.DIVINE_RANGING_POTION4, GameTimerImageType.ITEM, "Divine Ranging", 5, ChronoUnit.MINUTES, true), + DIVINE_MAGIC(ItemID.DIVINE_MAGIC_POTION4, GameTimerImageType.ITEM, "Divine Magic", 5, ChronoUnit.MINUTES, true); private final Duration duration; private final Integer graphicId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java index 4926b9893c..74b422ac98 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java @@ -91,6 +91,16 @@ public interface TimersConfig extends Config return true; } + @ConfigItem( + keyName = "showDivine", + name = "Divine potion timer", + description = "Configures whether divine potion timer is displayed" + ) + default boolean showDivine() + { + return true; + } + @ConfigItem( keyName = "showCannon", name = "Cannon timer", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index b66d821b93..26ed8821b0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.timers; import com.google.inject.Provides; +import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; @@ -113,10 +114,12 @@ public class TimersPlugin extends Plugin private static final String SUPER_ANTIFIRE_EXPIRED_MESSAGE = "Your super antifire potion has expired."; private static final int VENOM_VALUE_CUTOFF = -40; // Antivenom < -40 =< Antipoison < 0 private static final int POISON_TICK_LENGTH = 30; - - private static final Pattern DEADMAN_HALF_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+). It will expire in 1 minute, 15 seconds."); - private static final Pattern FULL_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+). It will expire in 5 minutes, 0 seconds."); - private static final Pattern HALF_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+). It will expire in 2 minutes, 30 seconds."); + private static final String SUPER_ANTIVENOM_DRINK_MESSAGE = "You drink some of your super antivenom potion"; + private static final String KILLED_TELEBLOCK_OPPONENT_TEXT = "Your Tele Block has been removed because you killed "; + private static final Pattern DEADMAN_HALF_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+)\\. It will expire in 1 minute, 15 seconds\\."); + private static final Pattern FULL_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+)\\. It will expire in 5 minutes, 0 seconds\\."); + private static final Pattern HALF_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+)\\. It will expire in 2 minutes, 30 seconds\\."); + private static final Pattern DIVINE_POTION_PATTERN = Pattern.compile("You drink some of your divine (.+) potion\\."); private TimerTimer freezeTimer; private int freezeTime = -1; // time frozen, in game ticks @@ -172,6 +175,7 @@ public class TimersPlugin extends Plugin private boolean showSkull; private boolean showStaffOfTheDead; private boolean showAbyssalSireStun; + private boolean showDivine; @Provides TimersConfig getConfig(ConfigManager configManager) @@ -355,6 +359,16 @@ public class TimersPlugin extends Plugin removeGameTimer(PRAYER_ENHANCE); } + if (!this.showDivine) + { + removeGameTimer(DIVINE_SUPER_ATTACK); + removeGameTimer(DIVINE_SUPER_STRENGTH); + removeGameTimer(DIVINE_SUPER_DEFENCE); + removeGameTimer(DIVINE_SUPER_COMBAT); + removeGameTimer(DIVINE_RANGING); + removeGameTimer(DIVINE_MAGIC); + } + if (!this.showCannon) { removeGameTimer(CANNON); @@ -421,7 +435,11 @@ public class TimersPlugin extends Plugin if (this.showStamina && event.getOption().contains("Drink") && (event.getIdentifier() == ItemID.STAMINA_MIX1 - || event.getIdentifier() == ItemID.STAMINA_MIX2)) + || event.getIdentifier() == ItemID.STAMINA_MIX2 + || event.getIdentifier() == ItemID.EGNIOL_POTION_1 + || event.getIdentifier() == ItemID.EGNIOL_POTION_2 + || event.getIdentifier() == ItemID.EGNIOL_POTION_3 + || event.getIdentifier() == ItemID.EGNIOL_POTION_4)) { // Needs menu option hook because mixes use a common drink message, distinct from their standard potion messages createGameTimer(STAMINA); @@ -582,6 +600,10 @@ public class TimersPlugin extends Plugin { createGameTimer(DMM_HALFTB); } + else if (event.getMessage().startsWith(KILLED_TELEBLOCK_OPPONENT_TEXT)) + { + removeTbTimers(); + } } if (this.showAntiFire && event.getMessage().contains(SUPER_ANTIFIRE_DRINK_MESSAGE)) @@ -635,6 +657,40 @@ public class TimersPlugin extends Plugin freezeTimer = createGameTimer(ICEBARRAGE); freezeTime = client.getTickCount(); } + + if (config.showDivine()) + { + Matcher mDivine = DIVINE_POTION_PATTERN.matcher(event.getMessage()); + if (mDivine.find()) + { + switch (mDivine.group(1)) + { + case "super attack": + createGameTimer(DIVINE_SUPER_ATTACK); + break; + + case "super strength": + createGameTimer(DIVINE_SUPER_STRENGTH); + break; + + case "super defence": + createGameTimer(DIVINE_SUPER_DEFENCE); + break; + + case "combat": + createGameTimer(DIVINE_SUPER_COMBAT); + break; + + case "ranging": + createGameTimer(DIVINE_RANGING); + break; + + case "magic": + createGameTimer(DIVINE_MAGIC); + break; + } + } + } } private void onGameTick(GameTick event) @@ -1020,5 +1076,6 @@ public class TimersPlugin extends Plugin this.showSkull = config.showSkull(); this.showStaffOfTheDead = config.showStaffOfTheDead(); this.showAbyssalSireStun = config.showAbyssalSireStun(); + this.showDivine = config.showDivine(); } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java index c1b8d5a211..973eec5eaa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java @@ -106,11 +106,11 @@ class OverviewItemPanel extends JPanel JLabel titleLabel = new JLabel(title); titleLabel.setForeground(Color.WHITE); - titleLabel.setFont(FontManager.getSmallFont(getFont())); + titleLabel.setFont(FontManager.getRunescapeSmallFont()); statusLabel = new JLabel(); statusLabel.setForeground(Color.GRAY); - statusLabel.setFont(FontManager.getSmallFont(getFont())); + statusLabel.setFont(FontManager.getRunescapeSmallFont()); textContainer.add(titleLabel); textContainer.add(statusLabel); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java index 81693a2ea3..c01f770063 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java @@ -67,10 +67,10 @@ public class TimeablePanel extends JPanel infoPanel.setBorder(new EmptyBorder(4, 4, 4, 0)); final JLabel location = new JShadowedLabel(title); - location.setFont(FontManager.getSmallFont(getFont())); + location.setFont(FontManager.getRunescapeSmallFont()); location.setForeground(Color.WHITE); - estimate.setFont(FontManager.getSmallFont(getFont())); + estimate.setFont(FontManager.getRunescapeSmallFont()); estimate.setForeground(Color.GRAY); infoPanel.add(location); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java index 14722f4b4a..fcc460fdf8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java @@ -155,7 +155,7 @@ public class ClockTabPanel extends TabContentPanel JLabel headerLabel = new JLabel(title); headerLabel.setForeground(Color.WHITE); - headerLabel.setFont(FontManager.getSmallFont(getFont())); + headerLabel.setFont(FontManager.getRunescapeSmallFont()); panel.add(headerLabel, BorderLayout.CENTER); IconButton addButton = new IconButton(ADD_ICON, ADD_ICON_HOVER); @@ -175,7 +175,7 @@ public class ClockTabPanel extends TabContentPanel JLabel infoLabel = new JShadowedLabel(text); infoLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR.darker()); - infoLabel.setFont(FontManager.getSmallFont(getFont())); + infoLabel.setFont(FontManager.getRunescapeSmallFont()); panel.add(infoLabel); return panel; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java index bf285be9e9..99bb8def81 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java @@ -129,7 +129,7 @@ class StopwatchPanel extends ClockPanel private JLabel createSmallLabel(String text) { JLabel label = new JLabel(text, SwingConstants.CENTER); - label.setFont(FontManager.getSmallFont(getFont())); + label.setFont(FontManager.getRunescapeSmallFont()); label.setForeground(LAP_DATA_COLOR); return label; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java index b99212963b..fa6852082d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java @@ -92,7 +92,7 @@ public class FarmingTabPanel extends TabContentPanel groupLabel.setBorder(new EmptyBorder(15, 0, 0, 0)); } - groupLabel.setFont(FontManager.getSmallFont(getFont())); + groupLabel.setFont(FontManager.getRunescapeSmallFont()); add(groupLabel, c); c.gridy++; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java index b98fe9fdc6..6e0a086f05 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java @@ -453,6 +453,7 @@ public class WintertodtPlugin extends Plugin case WOODCUTTING_DRAGON: case WOODCUTTING_INFERNAL: case WOODCUTTING_3A_AXE: + case WOODCUTTING_CRYSTAL: setActivity(WintertodtActivity.WOODCUTTING); break; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java index 709ea85378..dfdf86f6f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java @@ -33,6 +33,7 @@ import static net.runelite.api.AnimationID.WOODCUTTING_3A_AXE; import static net.runelite.api.AnimationID.WOODCUTTING_ADAMANT; import static net.runelite.api.AnimationID.WOODCUTTING_BLACK; import static net.runelite.api.AnimationID.WOODCUTTING_BRONZE; +import static net.runelite.api.AnimationID.WOODCUTTING_CRYSTAL; import static net.runelite.api.AnimationID.WOODCUTTING_DRAGON; import static net.runelite.api.AnimationID.WOODCUTTING_INFERNAL; import static net.runelite.api.AnimationID.WOODCUTTING_IRON; @@ -42,6 +43,7 @@ import static net.runelite.api.AnimationID.WOODCUTTING_STEEL; import static net.runelite.api.ItemID.ADAMANT_AXE; import static net.runelite.api.ItemID.BLACK_AXE; import static net.runelite.api.ItemID.BRONZE_AXE; +import static net.runelite.api.ItemID.CRYSTAL_AXE; import static net.runelite.api.ItemID.DRAGON_AXE; import static net.runelite.api.ItemID.INFERNAL_AXE; import static net.runelite.api.ItemID.IRON_AXE; @@ -63,7 +65,8 @@ enum Axe RUNE(WOODCUTTING_RUNE, RUNE_AXE), DRAGON(WOODCUTTING_DRAGON, DRAGON_AXE), INFERNAL(WOODCUTTING_INFERNAL, INFERNAL_AXE), - THIRDAGE(WOODCUTTING_3A_AXE, _3RD_AGE_AXE); + THIRDAGE(WOODCUTTING_3A_AXE, _3RD_AGE_AXE), + CRYSTAL(WOODCUTTING_CRYSTAL, CRYSTAL_AXE); private final Integer animId; private final Integer itemId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java index 8035af73fb..d21ed61e80 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Lotto + * Copyright (c) 2019, gregg1494 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -123,4 +124,15 @@ public interface WorldHopperConfig extends Config { return SubscriptionFilterMode.BOTH; } + + @ConfigItem( + keyName = "displayPing", + name = "Display current ping", + description = "Displays ping to current game world", + position = 7 + ) + default boolean displayPing() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java similarity index 51% rename from runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletCounter.java rename to runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java index d16684fb66..1839b14ddd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gauntlet/GauntletCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPingOverlay.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ganom + * Copyright (c) 2019, gregg1494 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,6 +10,7 @@ * 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 @@ -21,62 +22,70 @@ * (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; +package net.runelite.client.plugins.worldhopper; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import javax.inject.Inject; -import javax.inject.Singleton; -import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.Point; +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; 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; -import net.runelite.client.util.ColorUtil; +import net.runelite.client.ui.overlay.OverlayUtil; -@Singleton -@Slf4j -public class GauntletCounter extends Overlay +class WorldHopperPingOverlay extends Overlay { - private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150); - private final GauntletPlugin plugin; - private final PanelComponent panelComponent = new PanelComponent(); + private static final int Y_OFFSET = 11; + private static final int X_OFFSET = 1; + + private final Client client; + private final WorldHopperPlugin worldHopperPlugin; @Inject - GauntletCounter(final GauntletPlugin plugin) + private WorldHopperPingOverlay(Client client, WorldHopperPlugin worldHopperPlugin) { - this.plugin = plugin; - setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + this.client = client; + this.worldHopperPlugin = worldHopperPlugin; + setLayer(OverlayLayer.ABOVE_WIDGETS); setPriority(OverlayPriority.HIGH); + setPosition(OverlayPosition.DYNAMIC); } @Override public Dimension render(Graphics2D graphics) { - panelComponent.getChildren().clear(); - - if (plugin.getHunllef() == null || !plugin.isInRoom()) + if (!worldHopperPlugin.isDisplayPing()) { return null; } - panelComponent.getChildren().add(TitleComponent.builder() - .text("Hunllef") - .color(Color.pink) - .build()); + final int ping = worldHopperPlugin.getCurrentPing(); + if (ping < 0) + { + return null; + } - Color color = plugin.getPlayerAttacks() == 1 ? Color.RED : Color.WHITE; - final String pHits = ColorUtil.prependColorTag(Integer.toString(plugin.getPlayerAttacks()), color); + final String text = ping + " ms"; + final int textWidth = graphics.getFontMetrics().stringWidth(text); + final int textHeight = graphics.getFontMetrics().getAscent() - graphics.getFontMetrics().getDescent(); - TableComponent tableComponent = new TableComponent(); - tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT); - tableComponent.addRow("Hunllef Hits: ", Integer.toString(plugin.getAttacks())); - tableComponent.addRow("Player Hits Left: ", pHits); - panelComponent.getChildren().add(tableComponent); - return panelComponent.render(graphics); + // Adjust ping offset for logout button + Widget logoutButton = client.getWidget(WidgetInfo.RESIZABLE_MINIMAP_LOGOUT_BUTTON); + int xOffset = X_OFFSET; + if (logoutButton != null && !logoutButton.isHidden()) + { + xOffset += logoutButton.getWidth(); + } + + final int width = (int) client.getRealDimensions().getWidth(); + final Point point = new Point(width - textWidth - xOffset, textHeight + Y_OFFSET); + OverlayUtil.renderTextLocation(graphics, point, text, Color.YELLOW); + + return null; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 8513a87814..1b232678b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2017, Adam * Copyright (c) 2018, Lotto + * Copyright (c) 2019, gregg1494 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,6 +47,7 @@ import javax.imageio.ImageIO; import javax.inject.Inject; import javax.inject.Singleton; import javax.swing.SwingUtilities; +import lombok.AccessLevel; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; @@ -78,6 +80,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; +import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ExecutorServiceExceptionLogger; import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.Text; @@ -98,8 +101,7 @@ import org.apache.commons.lang3.ArrayUtils; public class WorldHopperPlugin extends Plugin { private static final int WORLD_FETCH_TIMER = 10; - private static final int WORLD_PING_TIMER = 10; - private static final int REFRESH_THROTTLE = 60_000; // ms + private static final int REFRESH_THROTTLE = 60_000; // ms private static final int TICK_THROTTLE = (int) Duration.ofMinutes(10).toMillis(); private static final int DISPLAY_SWITCHER_MAX_ATTEMPTS = 3; @@ -133,6 +135,12 @@ public class WorldHopperPlugin extends Plugin @Inject private EventBus eventBus; + @Inject + private OverlayManager overlayManager; + + @Inject + private WorldHopperPingOverlay worldHopperOverlay; + private ScheduledExecutorService hopperExecutorService; private NavigationButton navButton; @@ -146,8 +154,9 @@ public class WorldHopperPlugin extends Plugin private int favoriteWorld1, favoriteWorld2; - private ScheduledFuture worldResultFuture, pingFuture; + private ScheduledFuture worldResultFuture, pingFuture, currPingFuture; private WorldResult worldResult; + private int currentWorld; private Instant lastFetch; private boolean firstRun; @@ -158,6 +167,11 @@ public class WorldHopperPlugin extends Plugin private boolean ping; private boolean showWorldHopMessage; private SubscriptionFilterMode subscriptionFilter; + @Getter(AccessLevel.PACKAGE) + private boolean displayPing; + + @Getter(AccessLevel.PACKAGE) + private int currentPing; private final HotkeyListener previousKeyListener = new HotkeyListener(() -> this.previousKey) { @@ -189,6 +203,7 @@ public class WorldHopperPlugin extends Plugin addSubscriptions(); firstRun = true; + currentPing = -1; keyManager.registerKeyListener(previousKeyListener); keyManager.registerKeyListener(nextKeyListener); @@ -213,11 +228,18 @@ public class WorldHopperPlugin extends Plugin clientToolbar.addNavigation(navButton); } - panel.setFilterMode(this.subscriptionFilter); + overlayManager.add(worldHopperOverlay); + + panel.setFilterMode(config.subscriptionFilter()); + + // The plugin has its own executor for pings, as it blocks for a long time + hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); + // On first run this schedules an initial ping on hopperExecutorService worldResultFuture = executorService.scheduleAtFixedRate(this::tick, 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES); - hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); - pingFuture = hopperExecutorService.scheduleAtFixedRate(this::pingWorlds, WORLD_PING_TIMER, WORLD_PING_TIMER, TimeUnit.MINUTES); + // Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway + pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS); + currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS); } @Override @@ -228,6 +250,11 @@ public class WorldHopperPlugin extends Plugin pingFuture.cancel(true); pingFuture = null; + currPingFuture.cancel(true); + currPingFuture = null; + + overlayManager.remove(worldHopperOverlay); + keyManager.unregisterKeyListener(previousKeyListener); keyManager.unregisterKeyListener(nextKeyListener); @@ -482,7 +509,8 @@ public class WorldHopperPlugin extends Plugin if (firstRun) { firstRun = false; - hopperExecutorService.execute(this::pingWorlds); + // On first run we ping all of the worlds at once to initialize the ping values + hopperExecutorService.execute(this::pingInitialWorlds); } } @@ -504,6 +532,7 @@ public class WorldHopperPlugin extends Plugin new WorldClient().lookupWorlds() .subscribeOn(Schedulers.io()) + .take(1) .subscribe( (worldResult) -> { @@ -775,7 +804,10 @@ public class WorldHopperPlugin extends Plugin return null; } - private void pingWorlds() + /** + * Ping all worlds. This takes a long time and is only run on first run. + */ + private void pingInitialWorlds() { if (worldResult == null || !this.showSidebar || !this.ping) { @@ -804,5 +836,66 @@ public class WorldHopperPlugin extends Plugin this.ping = config.ping(); this.showWorldHopMessage = config.showWorldHopMessage(); this.subscriptionFilter = config.subscriptionFilter(); + this.displayPing = config.displayPing(); + } + + /** + * Ping the next world + */ + private void pingNextWorld() + { + if (worldResult == null || !config.showSidebar() || !config.ping()) + { + return; + } + + List worlds = worldResult.getWorlds(); + if (worlds.isEmpty()) + { + return; + } + + if (currentWorld >= worlds.size()) + { + // Wrap back around + currentWorld = 0; + } + + World world = worlds.get(currentWorld++); + + // If we are displaying the ping overlay, there is a separate scheduled task for the current world + boolean displayPing = config.displayPing() && client.getGameState() == GameState.LOGGED_IN; + if (displayPing && client.getWorld() == world.getId()) + { + return; + } + + int ping = Ping.ping(world); + log.trace("Ping for world {} is: {}", world.getId(), ping); + SwingUtilities.invokeLater(() -> panel.updatePing(world.getId(), ping)); + } + + /** + * Ping the current world for the ping overlay + */ + private void pingCurrentWorld() + { + // There is no reason to ping the current world if not logged in, as the overlay doesn't draw + if (worldResult == null || !config.displayPing() || client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + final World currentWorld = worldResult.findWorld(client.getWorld()); + if (currentWorld == null) + { + log.debug("unable to find current world: {}", client.getWorld()); + return; + } + + currentPing = Ping.ping(currentWorld); + log.trace("Ping for current world is: {}", currentPing); + + SwingUtilities.invokeLater(() -> panel.updatePing(currentWorld.getId(), currentPing)); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java index a1ad1e76b7..18b7fddbac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java @@ -104,7 +104,7 @@ class WorldTableHeader extends JPanel }); textLabel.setText(title); - textLabel.setFont(FontManager.getSmallFont(getFont())); + textLabel.setFont(FontManager.getRunescapeSmallFont()); final JMenuItem refresh = new JMenuItem("Refresh worlds"); refresh.addActionListener(e -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java index 7aa7eb12b1..cad6358120 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java @@ -273,7 +273,7 @@ class WorldTableRow extends JPanel column.setBorder(new EmptyBorder(0, 5, 0, 5)); playerCountField = new JLabel(world.getPlayers() + ""); - playerCountField.setFont(FontManager.getSmallFont(getFont())); + playerCountField.setFont(FontManager.getRunescapeSmallFont()); column.add(playerCountField, BorderLayout.WEST); @@ -302,7 +302,7 @@ class WorldTableRow extends JPanel column.setBorder(new EmptyBorder(0, 5, 0, 5)); activityField = new JLabel(world.getActivity()); - activityField.setFont(FontManager.getSmallFont(getFont())); + activityField.setFont(FontManager.getRunescapeSmallFont()); column.add(activityField, BorderLayout.WEST); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java index d15ddf86b1..1f47124afa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java @@ -72,7 +72,7 @@ enum QuestStartLocation DARKNESS_OF_HALLOWVALE(Quest.DARKNESS_OF_HALLOWVALE, new WorldPoint(3494, 9628, 0)), DEATH_PLATEAU_TROLL_STRONGHOLD(new Quest[]{Quest.DEATH_PLATEAU, Quest.TROLL_STRONGHOLD}, new WorldPoint(2895, 3528, 0)), DEATH_TO_THE_DORGESHUUN(Quest.DEATH_TO_THE_DORGESHUUN, new WorldPoint(3316, 9613, 0)), - THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1846, 3556, 0)), + THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1780, 3569, 0)), DESERT_TREASURE(Quest.DESERT_TREASURE, new WorldPoint(3177, 3043, 0)), DEVIOUS_MINDS(Quest.DEVIOUS_MINDS, new WorldPoint(3405, 3492, 0)), THE_DIG_SITE(Quest.THE_DIG_SITE, new WorldPoint(3363, 3337, 0)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java index 9ef2cab0ed..94feddf47c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TransportationPointLocation.java @@ -175,7 +175,7 @@ enum TransportationPointLocation TELEPORT_RUNE_ARDOUGNE("Teleport to Rune Essence", new WorldPoint(2681, 3325, 0)), TELEPORT_RUNE_YANILLE("Teleport to Rune Essence", new WorldPoint(2592, 3089, 0)), TELEPORT_SORCERESS_GARDEN("Teleport to Sorceress's Garden", new WorldPoint(3320, 3141, 0)), - TELEPORT_PRIFDDINAS_LIBRARY("Teleport to Priffdinas Library", new WorldPoint(3254, 6082, 2)), + TELEPORT_PRIFDDINAS_LIBRARY("Teleport to Prifddinas Library", new WorldPoint(3254, 6082, 2)), //Other ALTER_KOUREND_UNDERGROUND("Altar to Skotizo", new WorldPoint(1662, 10047, 0)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java index c71facbc97..1c922f0956 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java @@ -180,10 +180,10 @@ class XpInfoBox extends JPanel statsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); statsPanel.setBorder(new EmptyBorder(6, 5, 0, 2)); - expGained.setFont(FontManager.getSmallFont(getFont())); - expHour.setFont(FontManager.getSmallFont(getFont())); - expLeft.setFont(FontManager.getSmallFont(getFont())); - actionsLeft.setFont(FontManager.getSmallFont(getFont())); + expGained.setFont(FontManager.getRunescapeSmallFont()); + expHour.setFont(FontManager.getRunescapeSmallFont()); + expLeft.setFont(FontManager.getRunescapeSmallFont()); + actionsLeft.setFont(FontManager.getRunescapeSmallFont()); statsPanel.add(expGained); statsPanel.add(expLeft); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java index 8a05ccc932..5634dc9ee0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java @@ -111,8 +111,8 @@ class XpPanel extends PluginPanel overallInfo.setLayout(new GridLayout(2, 1)); overallInfo.setBorder(new EmptyBorder(0, 10, 0, 0)); - overallExpGained.setFont(FontManager.getSmallFont(getFont())); - overallExpHour.setFont(FontManager.getSmallFont(getFont())); + overallExpGained.setFont(FontManager.getRunescapeSmallFont()); + overallExpHour.setFont(FontManager.getRunescapeSmallFont()); overallInfo.add(overallExpGained); overallInfo.add(overallExpHour); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java new file mode 100644 index 0000000000..91b1103607 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/Step.java @@ -0,0 +1,11 @@ +package net.runelite.client.plugins.zalcano; + +enum Step +{ + IDLE, + MINE, + SMELT, + RUNECRAFT, + THROW, + MINE_ZALCANO +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoConfig.java new file mode 100644 index 0000000000..6c84d5d155 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoConfig.java @@ -0,0 +1,185 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +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.Stub; + +@ConfigGroup("zalcano") +public interface ZalcanoConfig extends Config +{ + + @ConfigItem( + keyName = "zalcanoStub", + name = "Zalcano", + description = "", + position = 0 + ) + default Stub zalcanoStub() + { + return new Stub(); + } + + @ConfigItem( + keyName = "highlightZalcanoHull", + name = "Highlight Zalcano", + description = "Highlight Zalcano\'s convex hull.", + parent = "zalcanoStub", + position = 1 + ) + default boolean highlightZalcanoHull() + { + return false; + } + + @ConfigItem( + keyName = "zalcanoHullColor", + name = "Color for highlight", + description = "", + parent = "zalcanoStub", + position = 2 + ) + default Color zalcanoHullColor() + { + return new Color(255, 25, 0); + } + + @ConfigItem( + keyName = "zalcanoAoesStub", + name = "Area of Effect", + description = "", + position = 3 + ) + default Stub zalcanoAoesStub() + { + return new Stub(); + } + + @ConfigItem( + keyName = "showAoeZalcanoWakeup", + name = "Zalcano Wakeup", + description = "Shows an AOE warning for Zalcano waking back up.", + parent = "zalcanoAoesStub", + position = 4 + ) + default boolean showAoeZalcanoWakeup() + { + return true; + } + + @ConfigItem( + keyName = "showAoeForRockfall", + name = "Small Rocks", + description = "Shows an AOE warning for the rocks that fall occasionally.", + parent = "zalcanoAoesStub", + position = 5 + ) + default boolean showAoeForRockfall() + { + return true; + } + + @ConfigItem( + keyName = "showAoeForRedSymbols", + name = "Red Symbols", + description = "Shows an AOE warning for the 3x3 red symbols that appear.", + parent = "zalcanoAoesStub", + position = 6 + ) + default boolean showAoeForRedSymbols() + { + return true; + } + + @ConfigItem( + keyName = "highlightMiningSpot", + name = "Mining spot", + description = "Highlights the glowing rock and warns you if Zalcano attacks it.", + parent = "zalcanoAoesStub", + position = 7 + ) + default boolean highlightMiningSpot() + { + return true; + } + + @ConfigItem( + keyName = "helperStub", + name = "Helpers", + description = "", + position = 8 + ) + default Stub helperStub() + { + return new Stub(); + } + + /** + * TODO: improve helper + */ + @ConfigItem( + keyName = "showSteps", + name = "Show Step", + description = "", + parent = "helperStub", + position = 9, + hidden = true //hidden until fully functional + ) + default boolean showSteps() + { + return false; + } + + @ConfigItem( + keyName = "showAoeZalcanoMineable", + name = "Zalcano Mineable", + description = "Highlights Zalcano if she is mineable.", + parent = "helperStub", + position = 10 + ) + default boolean showAoeZalcanoMineable() + { + return true; + } + + @ConfigItem( + keyName = "highlightGolem", + name = "Highlight Golem", + description = "Highlights the Golem that Zalcano spawns in.", + parent = "helperStub", + position = 11 + ) + default boolean highlightGolem() + { + return true; + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoOverlay.java new file mode 100644 index 0000000000..b0c97ef371 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoOverlay.java @@ -0,0 +1,242 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.AnimationID; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.GraphicsObject; +import net.runelite.api.Perspective; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; + +import javax.inject.Inject; +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; + +/** + * some ids + * 9049 = zalcano npc id 8439 wakeup animation 8437 mineable stage + * 1727 = rocks falling graphics object id + * 1728 = red projectile flying into rock + *

+ * 36192 + anim 8448 = glowing rock + *

+ * 36199 red circle + * 36200 blue circle + *

+ * golem id = 9051 + *

+ * 23905, 23906, 23907 + */ +@Slf4j +public class ZalcanoOverlay extends Overlay +{ + + private final ZalcanoPlugin plugin; + private final ZalcanoConfig config; + private final ZalcanoUtil util; + private final Client client; + + + @Inject + ZalcanoOverlay(final ZalcanoPlugin plugin, final ZalcanoConfig config, final ZalcanoUtil util, final Client client) + { + super(plugin); + this.plugin = plugin; + this.config = config; + this.util = util; + this.client = client; + + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!util.isInZalcanoRegion()) + { + return null; + } + + if (config.showAoeForRockfall()) + { + renderBadTiles(graphics); + } + if (config.showAoeForRedSymbols()) + { + renderRedSymbols(graphics); + } + if (config.highlightMiningSpot()) + { + renderRockToMine(graphics); + } + if (config.highlightGolem()) + { + renderGolem(graphics); + } + if (config.highlightZalcanoHull()) + { + renderZalcano(graphics); + } + + //has their own configs within this method + renderZalcanoAnimations(graphics); + + return null; + } + + private void renderBadTiles(Graphics2D graphics) + { + List rockFall = util.getRockfall(); + + if (rockFall != null) + { + for (GraphicsObject graphicsObject : rockFall) + { + WorldPoint worldPoint = WorldPoint.fromLocal(client, graphicsObject.getLocation()); + OverlayUtil.drawTiles(graphics, client, worldPoint, client.getLocalPlayer().getWorldLocation(), Color.RED, 2, 150, 50); + } + } + } + + private void renderRedSymbols(Graphics2D graphics) + { + List symbolsToRender = util.getRedSymbols(); + + if (symbolsToRender != null) + { + for (GameObject gameObject : symbolsToRender) + { + final LocalPoint loc = gameObject.getLocalLocation(); + final Polygon poly = Perspective.getCanvasTileAreaPoly(client, loc, 3); + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, new Color(249, 47, 30)); + } + } + } + } + + private void renderRockToMine(Graphics2D graphics) + { + GameObject glowingRock = util.getGlowingRock(); + + if (glowingRock != null) + { + final Polygon poly = Perspective.getCanvasTileAreaPoly(client, glowingRock.getLocalLocation(), !util.projectileExists() ? 2 : 4); + + if (poly != null) + { + final Color green = new Color(140, 255, 60); + OverlayUtil.renderPolygon(graphics, poly, !util.projectileExists() ? green : Color.RED); + OverlayUtil.renderTextLocation(graphics, glowingRock.getCanvasLocation(), !util.projectileExists() ? util.mine : util.warning, !util.projectileExists() ? green : Color.RED); + } + } + } + + private void renderGolem(Graphics2D graphics) + { + if (plugin.getGolem() != null) + { + Polygon hull = plugin.getGolem().getConvexHull(); + if (hull != null) + { + OverlayUtil.renderPolygon(graphics, hull, new Color(206, 41, 231)); + } + + } + } + + private void renderZalcano(Graphics2D graphics) + { + if (plugin.getZalcano() != null) + { + Polygon hull = plugin.getZalcano().getConvexHull(); + if (hull != null) + { + OverlayUtil.renderPolygon(graphics, hull, config.zalcanoHullColor()); + } + + } + } + + private void renderZalcanoAnimations(Graphics2D graphics) + { + if (plugin.getZalcano() != null) + { + switch (plugin.getZalcano().getAnimation()) + { + case AnimationID.ZALCANO_KNOCKED_DOWN: + if (config.showAoeZalcanoMineable()) + { + renderZalcanoMineable(graphics); + } + break; + case AnimationID.ZALCANO_WAKEUP: + if (config.showAoeZalcanoWakeup()) + { + renderZalcanoWakeup(graphics); + } + break; + } + } + } + + private void renderZalcanoMineable(Graphics2D graphics) + { + renderZalcanoAOE(graphics, 4, util.mine, Color.GREEN); + } + + private void renderZalcanoWakeup(Graphics2D graphics) + { + renderZalcanoAOE(graphics, 6, ZalcanoUtil.warning, Color.RED); + } + + private void renderZalcanoAOE(Graphics2D graphics, int polySize, String text, Color color) + { + Polygon poly = Perspective.getCanvasTileAreaPoly(client, plugin.getZalcano().getLocalLocation(), polySize); + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + OverlayUtil.renderTextLocation(graphics, plugin.getZalcano().getCanvasTextLocation(graphics, text, plugin.getZalcano().getLogicalHeight() / 2), text, color); + } + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java new file mode 100644 index 0000000000..a5d0be7736 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoPlugin.java @@ -0,0 +1,234 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import com.google.inject.Binder; +import com.google.inject.Inject; +import com.google.inject.Provides; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.AnimationID; +import net.runelite.api.Client; +import net.runelite.api.ItemID; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.kit.KitType; +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.plugins.PluginType; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "Zalcano", + description = "Highlights Zalcano AOEs and useful stuff", + tags = {"zalcano", "aoe", "prifddinas", "elf", "boss"}, + type = PluginType.PVM +) +@Slf4j +public class ZalcanoPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private ZalcanoConfig config; + + @Inject + private ZalcanoUtil util; + + @Inject + private ZalcanoOverlay overlay; + + @Inject + private ZalcanoStepsOverlay stepsOverlay; + + @Inject + private OverlayManager overlayManager; + + @Inject + private EventBus eventBus; + + @Setter(AccessLevel.PACKAGE) + @Getter(AccessLevel.PACKAGE) + private NPC zalcano; + + @Getter(AccessLevel.PACKAGE) + private NPC golem; + + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private Step step; + + private int ores = 0; + + @Provides + ZalcanoConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(ZalcanoConfig.class); + } + + @Override + protected void startUp() + { + eventBus.subscribe(GameTick.class, "regionchecker", this::onGameTickCheckRegion); + } + + @Override + protected void shutDown() + { + eventBus.unregister(this); + eventBus.unregister("regionchecker"); + overlayManager.remove(overlay); + overlayManager.remove(stepsOverlay); + } + + @Override + public void configure(Binder binder) + { + } + + private void onGameTickCheckRegion(GameTick gameTick) + { + if (util.isInZalcanoRegion()) + { + log.debug("region check complete loading other events"); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::gameTickStepMachine); + eventBus.subscribe(GameTick.class, this, this::gameTickOreListener); + + util.manuallyFindZalcano(); //this is here because the new subscribed npcspawn doesn't catch a pre existing zalcano + + overlayManager.add(overlay); + overlayManager.add(stepsOverlay); + + eventBus.unregister("regionchecker"); + } + } + + private void onNpcSpawned(NpcSpawned npcSpawned) + { + switch (npcSpawned.getNpc().getId()) + { + case NpcID.ZALCANO: + log.debug("zalcano spawned"); + zalcano = npcSpawned.getNpc(); + break; + case NpcID.GOLEM_9051: + log.debug("golem spawned"); + golem = npcSpawned.getNpc(); + break; + } + } + + private void onNpcDespawned(NpcDespawned npcDespawned) + { + switch (npcDespawned.getNpc().getId()) + { + case NpcID.ZALCANO: + zalcano = null; + break; + case NpcID.GOLEM_9051: + golem = null; + break; + } + } + + //23905 //ore + //23906 //smelted + //23907 //runecrafted ore + + /** + * This event switches steps based on different conditions (inaccurate) + * TODO: improve this. until then its option is disabled in the config + * + * @param gameTick + */ + private void gameTickStepMachine(GameTick gameTick) + { + if (!config.showSteps()) + { + return; + } + + if (getZalcano() != null) + { + if (getZalcano().getAnimation() == AnimationID.ZALCANO_KNOCKED_DOWN) //zalcano got knocked down + { + setStep(Step.MINE_ZALCANO); + return; + } + } + if (util.countItemInInventory(ItemID.TEPHRA) < 3 && util.countItemInInventory(ItemID.REFINED_TEPHRA) < 3 && util.countStackInInventory(ItemID.IMBUED_TEPHRA) < 3) + { + if (client.getLocalPlayer().getPlayerAppearance().getEquipmentId(KitType.WEAPON) == ItemID.IMBUED_TEPHRA) + { + setStep(Step.THROW); + return; + } + if (getZalcano() != null && util.countItemInInventory(ItemID.REFINED_TEPHRA) == 0 && util.countItemInInventory(ItemID.IMBUED_TEPHRA) == 0) + { + setStep(Step.MINE); + return; + } + } + if (util.countItemInInventory(ItemID.TEPHRA) >= 3) + { + setStep(Step.SMELT); + return; + } + if (util.countItemInInventory(ItemID.REFINED_TEPHRA) >= 3 && ores == 0) + { + setStep(Step.RUNECRAFT); + return; + } + if (util.countStackInInventory(ItemID.IMBUED_TEPHRA) >= 3) + { + setStep(Step.THROW); + return; + } + setStep(Step.IDLE); + } + + private void gameTickOreListener(GameTick gameTick) + { + if (!config.showSteps()) + { + return; + } + ores = util.countItemInInventory(ItemID.TEPHRA); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java new file mode 100644 index 0000000000..16256c215f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoStepsOverlay.java @@ -0,0 +1,72 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +public class ZalcanoStepsOverlay extends Overlay +{ + private final Client client; + private final ZalcanoPlugin plugin; + private final ZalcanoConfig config; + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + ZalcanoStepsOverlay(final Client client, final ZalcanoPlugin plugin, final ZalcanoConfig config) + { + super(plugin); + setPosition(OverlayPosition.TOP_LEFT); + this.client = client; + this.config = config; + this.plugin = plugin; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (client.getLocalPlayer().getWorldLocation().getRegionID() == 12126 && config.showSteps()) + { + panelComponent.getChildren().clear(); + + panelComponent.getChildren().add(TitleComponent.builder() + .text("Step: " + plugin.getStep().name()) + .color(Color.CYAN) + .build()); + + return panelComponent.render(graphics); + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java new file mode 100644 index 0000000000..15023023fb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zalcano/ZalcanoUtil.java @@ -0,0 +1,236 @@ +/* + * + * * Copyright (c) 2019, gazivodag + * * 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.zalcano; + +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import net.runelite.api.AnimationID; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.api.DynamicObject; +import net.runelite.api.GameObject; +import net.runelite.api.GraphicsObject; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.NPC; +import net.runelite.api.NpcID; +import net.runelite.api.ObjectID; +import net.runelite.api.Projectile; +import net.runelite.api.ProjectileID; +import net.runelite.api.Renderable; +import net.runelite.api.Tile; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; + +public class ZalcanoUtil +{ + + private final Client client; + private final ZalcanoPlugin plugin; + + static final String mine = "MINE"; + protected static final String warning = "GET BACK"; + private static final int ZALCANO_REGION = 12126; + + @Inject + ZalcanoUtil(Client client, ZalcanoPlugin plugin) + { + this.client = client; + this.plugin = plugin; + } + + boolean isInZalcanoRegion() + { + return client.getLocalPlayer().getWorldLocation().getRegionID() == ZALCANO_REGION; + } + + + boolean projectileExists() + { + for (Projectile projectile : client.getProjectiles()) + { + if (projectile != null) + { + if (projectile.getId() == ProjectileID.ZALCANO_PROJECTILE) + { + return true; + } + } + } + return false; + } + + //this should be a project-wide standard + private List getGameObjects() + { + List gameObjectArrayList = new ArrayList<>(); + + for (int x = 0; x < Constants.SCENE_SIZE; x++) + { + for (int y = 0; y < Constants.SCENE_SIZE; y++) + { + Tile tile = client.getScene().getTiles()[client.getPlane()][x][y]; + + if (tile.getGameObjects() != null) + { + for (GameObject gameObject : tile.getGameObjects()) + { + if (gameObject != null) //im aware this can still give null objects + { + gameObjectArrayList.add(gameObject); + } + } + } + } + } + return gameObjectArrayList; + } + + GameObject getGlowingRock() + { + for (GameObject gameObject : getGameObjects()) + { + if (gameObject != null) + { + if (gameObject.getId() == ObjectID.ROCK_FORMATION_GLOWING) + { + if (client.getLocalPlayer().getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= 2400) + { + Renderable renderable = gameObject.getRenderable(); + if (renderable instanceof DynamicObject) + { + if (((DynamicObject) renderable).getAnimationID() == AnimationID.ZALCANO_ROCK_GLOWING) + { + return gameObject; + } + } + } + } + } + } + return null; + } + + List getRedSymbols() + { + List list = new ArrayList<>(); + for (GameObject gameObject : getGameObjects()) + { + if (gameObject != null) + { + if (gameObject.getId() == ObjectID.DEMONIC_SYMBOL) + { + if (client.getLocalPlayer().getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= 2400) + { + Renderable renderable = gameObject.getRenderable(); + if (renderable instanceof DynamicObject) + { + list.add(gameObject); + } + } + } + } + } + return list.size() > 0 ? list : null; + } + + List getRockfall() + { + List list = new ArrayList<>(); + for (GraphicsObject graphicsObject : client.getGraphicsObjects()) + { + if (graphicsObject != null) + { + if (graphicsObject.getId() == 1727/*<-- not sure where to add that*/) + { + list.add(graphicsObject); + } + } + } + return list.size() > 0 ? list : null; + } + + int countItemInInventory(int itemID) + { + int i = 0; + Widget widget = client.getWidget(WidgetInfo.INVENTORY); + for (WidgetItem widgetItem : widget.getWidgetItems()) + { + if (widgetItem.getId() == itemID) + { + i++; + } + } + return i; + } + + /** + * Courtesy of OP + * + * @param itemId + * @return + */ + int countStackInInventory(int itemId) + { + ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY); + if (inventory != null) + { + Item[] items = inventory.getItems(); + for (int i = 0; i < 28; ++i) + { + if (i < items.length) + { + Item item = items[i]; + if (item.getId() >= 0 && item.getId() == itemId) + { + return item.getQuantity(); + } + } + } + } + return 0; + } + + void manuallyFindZalcano() + { + for (NPC npc : client.getNpcs()) + { + if (npc != null) + { + if (npc.getId() == NpcID.ZALCANO) + { + plugin.setZalcano(npc); + } + } + } + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahInstance.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahInstance.java index fdbff52358..a7faac13e3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahInstance.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahInstance.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.zulrah; +import javax.annotation.Nullable; import net.runelite.api.NPC; import net.runelite.api.Prayer; import net.runelite.api.coords.LocalPoint; @@ -101,6 +102,7 @@ public class ZulrahInstance stage = 0; } + @Nullable public ZulrahPhase getPhase() { ZulrahPhase patternPhase = null; @@ -116,6 +118,7 @@ public class ZulrahInstance this.phase = phase; } + @Nullable public ZulrahPhase getNextPhase() { if (pattern != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java index 18ee33b51f..3328d50d89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java @@ -217,28 +217,32 @@ public class ZulrahPlugin extends Plugin } ZulrahPhase currentPhase = instance.getPhase(); + ZulrahPhase nextPhase = instance.getNextPhase(); - if (currentPhase == null) + if (currentPhase == null || nextPhase == null) { return; } - Actor actor = event.getActor(); + final Actor actor = event.getActor(); + if (config.sounds() && zulrah != null && zulrah.equals(actor) && zulrah.getAnimation() == AnimationID.ZULRAH_PHASE) { - Prayer prayer = instance.getNextPhase().getPrayer(); + Prayer prayer = nextPhase.getPrayer(); - if (prayer != null) + if (prayer == null) { - switch (prayer) - { - case PROTECT_FROM_MAGIC: - soundManager.playSound(Sound.PRAY_MAGIC); - break; - case PROTECT_FROM_MISSILES: - soundManager.playSound(Sound.PRAY_RANGED); - break; - } + return; + } + + switch (prayer) + { + case PROTECT_FROM_MAGIC: + soundManager.playSound(Sound.PRAY_MAGIC); + break; + case PROTECT_FROM_MISSILES: + soundManager.playSound(Sound.PRAY_RANGED); + break; } } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java index 1205c6b3a7..5f703bb002 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java @@ -24,19 +24,11 @@ */ package net.runelite.client.ui; -import com.google.common.collect.ImmutableBiMap; -import java.awt.Canvas; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.awt.Font; import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; import java.io.IOException; -import java.util.Map; -import lombok.Getter; -import net.runelite.client.config.FontType; +import javax.swing.text.StyleContext; public class FontManager { @@ -44,59 +36,37 @@ public class FontManager private static final Font runescapeSmallFont; private static final Font runescapeBoldFont; - @Getter - private static class CachedFont - { - private final Font reg; - private final Font small; - private final Font bold; - - private CachedFont(Font f) - { - reg = f.deriveFont(14.0f); - small = getFontOffCorrectSize(f); - bold = f.deriveFont(Font.BOLD, 14.0f); - } - } - - private static final ImmutableBiMap fontMap; - private static final Map derivedFontMap = new HashMap<>(); - static { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); try { - runescapeFont = Font.createFont(Font.TRUETYPE_FONT, + Font font = Font.createFont(Font.TRUETYPE_FONT, FontManager.class.getResourceAsStream("runescape.ttf")) .deriveFont(Font.PLAIN, 16); + ge.registerFont(font); - runescapeSmallFont = Font.createFont(Font.TRUETYPE_FONT, + runescapeFont = StyleContext.getDefaultStyleContext() + .getFont(font.getName(), Font.PLAIN, 16); + ge.registerFont(runescapeFont); + + Font smallFont = Font.createFont(Font.TRUETYPE_FONT, FontManager.class.getResourceAsStream("runescape_small.ttf")) .deriveFont(Font.PLAIN, 16); + ge.registerFont(smallFont); - runescapeBoldFont = Font.createFont(Font.TRUETYPE_FONT, + runescapeSmallFont = StyleContext.getDefaultStyleContext() + .getFont(smallFont.getName(), Font.PLAIN, 16); + ge.registerFont(runescapeSmallFont); + + Font boldFont = Font.createFont(Font.TRUETYPE_FONT, FontManager.class.getResourceAsStream("runescape_bold.ttf")) .deriveFont(Font.PLAIN, 16); + ge.registerFont(boldFont); - final LinkedHashMap _fontMap = new LinkedHashMap<>(); - _fontMap.put("Runescape", runescapeFont); - - // Get all available fonts on the system - Font[] availableFonts = ge.getAllFonts(); - // build bidirectional map - Arrays.stream(availableFonts).sorted(Comparator.comparing(Font::getFontName)).forEach(f -> - { - if (!_fontMap.containsKey(f.getFontName())) - { - _fontMap.put(f.getFontName(), f); - } - }); - fontMap = ImmutableBiMap.copyOf(_fontMap); - - ge.registerFont(runescapeFont); - ge.registerFont(runescapeSmallFont); + runescapeBoldFont = StyleContext.getDefaultStyleContext() + .getFont(boldFont.getName(), Font.PLAIN, 16); ge.registerFont(runescapeBoldFont); } catch (FontFormatException ex) @@ -109,25 +79,6 @@ public class FontManager } } - private static Font getFontOffCorrectSize(Font f) - { - // Size of the font is already set - if (f.getSize2D() > 1) - { - return f; - } - - // Dummy canvas for font metrics - Canvas c = new Canvas(); - - f = f.deriveFont(12f); - if (c.getFontMetrics(f).getMaxAscent() > 11) - { - f = f.deriveFont(11f); - } - return f; - } - public static Font getRunescapeFont() { return runescapeFont; @@ -142,93 +93,4 @@ public class FontManager { return runescapeBoldFont; } - - private static boolean isRunescapeFont(Font f) - { - return f.equals(runescapeFont) || f.equals(runescapeSmallFont) || f.equals(runescapeBoldFont); - } - - public static Font getSmallFont(Font f) - { - if (isRunescapeFont(f)) - { - return runescapeSmallFont; - } - - if (derivedFontMap.containsKey(f)) - { - return derivedFontMap.get(f).getSmall(); - } - - // cache and return - CachedFont cachedFont = new CachedFont(f); - derivedFontMap.put(f, cachedFont); - return cachedFont.getSmall(); - } - - public static Font getFontFromType(Font f, FontType type) - { - switch (type) - { - case SMALL: - return getSmallFont(f); - case BOLD: - if (isRunescapeFont(f)) - { - return runescapeBoldFont; - } - if (derivedFontMap.containsKey(f)) - { - return derivedFontMap.get(f).getBold(); - } - - // cache and return - CachedFont cachedBoldFont = new CachedFont(f); - derivedFontMap.put(f, cachedBoldFont); - return cachedBoldFont.getBold(); - default: //in this case regular - if (isRunescapeFont(f)) - { - return runescapeFont; - } - if (derivedFontMap.containsKey(f)) - { - return derivedFontMap.get(f).getReg(); - } - - // cache and return - CachedFont cachedFont = new CachedFont(f); - derivedFontMap.put(f, cachedFont); - return cachedFont.getReg(); - } - } - - public static Font lookupFont(String fontName) - { - return fontMap.get(fontName); - } - - public static String getFontName(Font font) - { - return fontMap.inverse().get(font); - } - - public static String[] getAvailableFontNames() - { - return fontMap.keySet().toArray(new String[0]); - } - - public static boolean isAvailable(Font font) - { - return fontMap.containsKey(font.getFontName()); - } - - public static Font getFontOrDefault(Font font) - { - if (font == null || !fontMap.containsKey(font.getFontName())) - { - return getRunescapeFont(); - } - return getFontOffCorrectSize(font); - } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java b/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java index 66a388e9bf..67f52ded62 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/RuneLiteSplashScreen.java @@ -30,6 +30,8 @@ import java.awt.GridBagLayout; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; import javax.imageio.ImageIO; import javax.inject.Singleton; import javax.swing.ImageIcon; @@ -40,8 +42,6 @@ import javax.swing.JProgressBar; import javax.swing.SwingUtilities; import javax.swing.plaf.basic.BasicProgressBarUI; import lombok.extern.slf4j.Slf4j; -import net.runelite.client.RuneLite; -import net.runelite.client.RuneLiteProperties; import net.runelite.client.util.SwingUtil; import org.pushingpixels.substance.internal.SubstanceSynapse; @@ -53,7 +53,9 @@ import org.pushingpixels.substance.internal.SubstanceSynapse; @Singleton public class RuneLiteSplashScreen { - private final RuneLiteProperties runeLiteProperties = new RuneLiteProperties(); + 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 JFrame frame; private final JPanel panel = new JPanel(); @@ -61,6 +63,20 @@ public class RuneLiteSplashScreen private JLabel subMessageLabel; private final JProgressBar progressBar = new JProgressBar(); + private final Properties properties = new Properties(); + + public RuneLiteSplashScreen() + { + try (InputStream in = getClass().getResourceAsStream("/runelite.plus.properties")) + { + properties.load(in); + } + catch (IOException ex) + { + log.warn("unable to load propertries", ex); + } + } + /** * This is not done in the constructor in order to avoid processing in case the user chooses to not load * the splash screen. @@ -90,7 +106,7 @@ public class RuneLiteSplashScreen panel.setBackground(ColorScheme.DARKER_GRAY_COLOR); final GridBagLayout layout = new GridBagLayout(); layout.columnWeights = new double[]{1}; - layout.rowWeights = new double[]{1, 0, 0, 1, 0, 1}; + layout.rowWeights = new double[]{1, 0, 0, 1, 0, 0, 1}; panel.setLayout(layout); // logo @@ -119,7 +135,7 @@ public class RuneLiteSplashScreen panel.add(title, titleConstraints); // version - final JLabel version = new JLabel("RuneLite Version : " + runeLiteProperties.getVersion()); + final JLabel version = new JLabel("RuneLite Version : " + properties.getProperty(RUNELITE_VERSION)); version.setForeground(Color.GREEN); version.setFont(FontManager.getRunescapeSmallFont()); version.setForeground(version.getForeground().darker()); @@ -128,34 +144,42 @@ public class RuneLiteSplashScreen panel.add(version, versionConstraints); // version - final JLabel litVersion = new JLabel("Plus Version : " + RuneLite.PLUS_VERSION); + final JLabel litVersion = new JLabel("Plus Version : " + properties.getProperty(RUNELITE_PLUS_VERSION)); litVersion.setForeground(Color.GREEN); litVersion.setFont(FontManager.getRunescapeSmallFont()); litVersion.setForeground(litVersion.getForeground().darker()); final GridBagConstraints litVersionConstraints = new GridBagConstraints(); litVersionConstraints.gridy = 3; - litVersionConstraints.weightx = 4; panel.add(litVersion, litVersionConstraints); + // build date + final JLabel litBuildDate = new JLabel("Build date : " + properties.getProperty(RUNELITE_PLUS_DATE)); + litBuildDate.setForeground(Color.GREEN); + litBuildDate.setFont(FontManager.getRunescapeSmallFont()); + litBuildDate.setForeground(litBuildDate.getForeground().darker()); + final GridBagConstraints litBuildDateConstraints = new GridBagConstraints(); + litBuildDateConstraints.gridy = 4; + panel.add(litBuildDate, litBuildDateConstraints); + // progressbar final GridBagConstraints progressConstraints = new GridBagConstraints(); progressConstraints.fill = GridBagConstraints.HORIZONTAL; progressConstraints.anchor = GridBagConstraints.SOUTH; - progressConstraints.gridy = 4; + progressConstraints.gridy = 5; panel.add(progressBar, progressConstraints); // main message messageLabel.setFont(FontManager.getRunescapeSmallFont()); final GridBagConstraints messageConstraints = new GridBagConstraints(); - messageConstraints.gridy = 5; + messageConstraints.gridy = 6; panel.add(messageLabel, messageConstraints); // alternate message final GridBagConstraints subMessageConstraints = new GridBagConstraints(); subMessageLabel.setForeground(subMessageLabel.getForeground().darker()); subMessageLabel.setFont(FontManager.getRunescapeSmallFont()); - subMessageConstraints.gridy = 6; + subMessageConstraints.gridy = 7; panel.add(subMessageLabel, subMessageConstraints); frame.setContentPane(panel); @@ -235,7 +259,7 @@ public class RuneLiteSplashScreen final GridBagConstraints progressConstraints = new GridBagConstraints(); progressConstraints.fill = GridBagConstraints.HORIZONTAL; progressConstraints.anchor = GridBagConstraints.SOUTH; - progressConstraints.gridy = 4; + progressConstraints.gridy = 5; panel.add(progressBar, progressConstraints); panel.validate(); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java b/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java index 92f48a6993..e7b2fad971 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java @@ -52,7 +52,7 @@ public class PluginErrorPanel extends JPanel noResultsTitle.setForeground(Color.WHITE); noResultsTitle.setHorizontalAlignment(SwingConstants.CENTER); - noResultsDescription.setFont(FontManager.getSmallFont(getFont())); + noResultsDescription.setFont(FontManager.getRunescapeSmallFont()); noResultsDescription.setForeground(Color.GRAY); noResultsDescription.setHorizontalAlignment(SwingConstants.CENTER); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java index ac5ba1cd79..2204e47ead 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java @@ -77,15 +77,15 @@ public class ProgressBar extends DimmableJPanel topIndent = 2; } - leftLabel.setFont(FontManager.getSmallFont(getFont())); + leftLabel.setFont(FontManager.getRunescapeSmallFont()); leftLabel.setForeground(Color.WHITE); leftLabel.setBorder(new EmptyBorder(topIndent, 5, 0, 0)); - rightLabel.setFont(FontManager.getSmallFont(getFont())); + rightLabel.setFont(FontManager.getRunescapeSmallFont()); rightLabel.setForeground(Color.WHITE); rightLabel.setBorder(new EmptyBorder(topIndent, 0, 0, 5)); - centerLabel.setFont(FontManager.getSmallFont(getFont())); + centerLabel.setFont(FontManager.getRunescapeSmallFont()); centerLabel.setForeground(Color.WHITE); centerLabel.setHorizontalAlignment(SwingConstants.CENTER); centerLabel.setBorder(new EmptyBorder(topIndent, 0, 0, 0)); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index ed26a222b9..8d138a26e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -34,6 +34,7 @@ import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; +import java.awt.geom.AffineTransform; import java.util.List; import java.util.Map; import javax.inject.Inject; @@ -56,7 +57,6 @@ import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseAdapter; import net.runelite.client.input.MouseManager; -import net.runelite.client.ui.FontManager; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.MiscUtils; @@ -122,10 +122,9 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private void updateConfig() { // Overlay Fonts - Font clientFont = runeLiteConfig.clientFont(); - this.standardFont = FontManager.getFontFromType(clientFont, runeLiteConfig.fontType()); - this.tooltipFont = FontManager.getFontFromType(clientFont, runeLiteConfig.tooltipFontType()); - this.interfaceFont = FontManager.getFontFromType(clientFont, runeLiteConfig.interfaceFontType()); + this.standardFont = runeLiteConfig.fontType().getFont(); + this.tooltipFont = runeLiteConfig.tooltipFontType().getFont(); + this.interfaceFont = runeLiteConfig.interfaceFontType().getFont(); } private void onConfigChanged(ConfigChanged event) @@ -471,38 +470,46 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private void safeRender(Client client, Overlay overlay, OverlayLayer layer, Graphics2D graphics, Point point) { - final Graphics2D subGraphics = (Graphics2D) graphics.create(); - if (!isResizeable && (layer == OverlayLayer.ABOVE_SCENE || layer == OverlayLayer.UNDER_WIDGETS)) { - subGraphics.setClip(client.getViewportXOffset(), + graphics.setClip(client.getViewportXOffset(), client.getViewportYOffset(), client.getViewportWidth(), client.getViewportHeight()); } + else + { + graphics.setClip(0, 0, client.getCanvasWidth(), client.getCanvasHeight()); + } final OverlayPosition position = overlay.getPosition(); // Set font based on configuration if (position == OverlayPosition.DYNAMIC || position == OverlayPosition.DETACHED) { - subGraphics.setFont(this.standardFont); + graphics.setFont(this.standardFont); // TODO MAKE USE CONFIG SYSTEM + } else if (position == OverlayPosition.TOOLTIP) { - subGraphics.setFont(this.tooltipFont); + graphics.setFont(this.tooltipFont); } else { - subGraphics.setFont(this.interfaceFont); + graphics.setFont(this.interfaceFont); } - subGraphics.translate(point.x, point.y); + // Reset the default color + graphics.setColor(Color.WHITE); + + // Get transform so we can reset it after drawing + AffineTransform transform = graphics.getTransform(); + graphics.translate(point.x, point.y); final Dimension overlayDimension; try { - overlayDimension = overlay.render(subGraphics); + overlayDimension = overlay.render(graphics); } catch (Exception ex) { @@ -511,7 +518,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener } finally { - subGraphics.dispose(); + graphics.setTransform(transform); } final Dimension dimension = MoreObjects.firstNonNull(overlayDimension, new Dimension()); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java index 49a18caba6..6c8debf59d 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java @@ -45,6 +45,7 @@ import net.runelite.api.Perspective; import net.runelite.api.Point; import net.runelite.api.Prayer; import net.runelite.api.TileObject; +import net.runelite.api.VarClientInt; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; @@ -348,7 +349,7 @@ public class OverlayUtil { Widget widget = client.getWidget(prayer.getWidgetInfo()); - if (widget == null || widget.isHidden()) + if (widget == null || client.getVar(VarClientInt.PLAYER_INTERFACE_CONTAINER_OPENED) != 5) { return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java index b643bc0062..be1a8b1da5 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java @@ -39,7 +39,7 @@ import net.runelite.client.ui.FontManager; @Setter public class InfoBoxComponent implements LayoutableRenderableEntity { - private static final int SEPARATOR = 2; + private static final int SEPARATOR = 3; private static final int DEFAULT_SIZE = 32; @Getter @@ -63,15 +63,7 @@ public class InfoBoxComponent implements LayoutableRenderableEntity return new Dimension(); } - if (graphics.getFont().equals(FontManager.getRunescapeFont()) && getSize() > DEFAULT_SIZE) - { - graphics.setFont(FontManager.getRunescapeFont()); - } - else - { - graphics.setFont(FontManager.getSmallFont(graphics.getFont())); - } - + graphics.setFont(getSize() < DEFAULT_SIZE ? FontManager.getRunescapeSmallFont() : FontManager.getRunescapeFont()); final int baseX = preferredLocation.x; final int baseY = preferredLocation.y; @@ -99,7 +91,7 @@ public class InfoBoxComponent implements LayoutableRenderableEntity final TextComponent textComponent = new TextComponent(); textComponent.setColor(color); textComponent.setText(text); - textComponent.setPosition(new Point(baseX + ((size - metrics.stringWidth(text)) / 2), baseY + size - metrics.getMaxDescent() - SEPARATOR)); + textComponent.setPosition(new Point(baseX + ((size - metrics.stringWidth(text)) / 2), baseY + size - SEPARATOR)); textComponent.render(graphics); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java index 03b8c0a71d..f6c2f5e77c 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java @@ -68,7 +68,7 @@ public class LineComponent implements LayoutableRenderableEntity final FontMetrics metrics = graphics.getFontMetrics(); final int baseX = preferredLocation.x; - final int baseY = preferredLocation.y; + final int baseY = preferredLocation.y + metrics.getHeight(); int x = baseX; int y = baseY; final int leftFullWidth = getLineWidth(left, metrics); @@ -92,7 +92,6 @@ public class LineComponent implements LayoutableRenderableEntity for (int i = 0; i < lineCount; i++) { - y += metrics.getMaxAscent(); String leftText = ""; String rightText = ""; @@ -117,7 +116,7 @@ public class LineComponent implements LayoutableRenderableEntity rightLineComponent.setText(rightText); rightLineComponent.setColor(rightColor); rightLineComponent.render(graphics); - y += metrics.getMaxDescent(); + y += metrics.getHeight(); } final Dimension dimension = new Dimension(preferredSize.width, y - baseY); @@ -125,7 +124,6 @@ public class LineComponent implements LayoutableRenderableEntity bounds.setSize(dimension); return dimension; } - y += metrics.getMaxAscent(); final TextComponent leftLineComponent = new TextComponent(); leftLineComponent.setPosition(new Point(x, y)); @@ -138,7 +136,7 @@ public class LineComponent implements LayoutableRenderableEntity rightLineComponent.setText(right); rightLineComponent.setColor(rightColor); rightLineComponent.render(graphics); - y += metrics.getMaxDescent(); + y += metrics.getHeight(); final Dimension dimension = new Dimension(preferredSize.width, y - baseY); bounds.setLocation(preferredLocation); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java index 226c3da270..01f52d6ad0 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java @@ -109,7 +109,7 @@ public class ProgressBarComponent implements LayoutableRenderableEntity final int width = preferredSize.width; final int height = Math.max(preferredSize.height, 16); final int progressTextX = barX + (width - metrics.stringWidth(textToWrite)) / 2; - final int progressTextY = barY + ((height - metrics.getHeight()) / 2) + metrics.getMaxAscent(); + final int progressTextY = barY + ((height - metrics.getHeight()) / 2) + metrics.getHeight(); final int progressFill = (int) (width * Math.min(1, pc)); // Draw bar diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java index 9c9793be66..fa4c9bc3bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java @@ -64,7 +64,7 @@ public class TitleComponent implements LayoutableRenderableEntity titleComponent.setColor(color); titleComponent.setPosition(new Point( baseX + ((preferredSize.width - metrics.stringWidth(text)) / 2), - baseY + metrics.getMaxAscent())); + baseY + metrics.getHeight())); final Dimension rendered = titleComponent.render(graphics); final Dimension dimension = new Dimension(preferredSize.width, rendered.height); bounds.setLocation(preferredLocation); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java index 91ee736023..2179a6a5b6 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java @@ -106,7 +106,7 @@ public class TooltipComponent implements RenderableEntity textComponent.setColor(nextColor); String text = line.substring(begin, j); textComponent.setText(text); - textComponent.setPosition(new Point(lineX, textY + (i + 1) * metrics.getMaxAscent() + i * metrics.getMaxDescent())); + textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent)); textComponent.render(graphics); lineX += metrics.stringWidth(text); @@ -144,7 +144,7 @@ public class TooltipComponent implements RenderableEntity textComponent.setColor(nextColor); String text = line.substring(begin, j + 1); textComponent.setText(text); - textComponent.setPosition(new Point(lineX, textY + (i + 1) * metrics.getMaxAscent() + i * metrics.getMaxDescent())); + textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent)); textComponent.render(graphics); lineX += metrics.stringWidth(text); @@ -159,7 +159,7 @@ public class TooltipComponent implements RenderableEntity final TextComponent textComponent = new TextComponent(); textComponent.setColor(nextColor); textComponent.setText(line.substring(begin)); - textComponent.setPosition(new Point(lineX, textY + (i + 1) * metrics.getMaxAscent() + i * metrics.getMaxDescent())); + textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent)); textComponent.render(graphics); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 919b31882c..fef98b9f84 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -278,7 +278,7 @@ public class WorldMapOverlay extends Overlay graphics.setColor(JagexColors.TOOLTIP_BORDER); graphics.drawRect((int) tooltipRect.getX(), (int) tooltipRect.getY(), (int) tooltipRect.getWidth(), (int) tooltipRect.getHeight()); graphics.setColor(JagexColors.TOOLTIP_TEXT); - graphics.drawString(tooltip, drawPoint.getX(), drawPoint.getY() + fm.getMaxAscent()); + graphics.drawString(tooltip, drawPoint.getX(), drawPoint.getY() + height); } private Point clipToRectangle(Point drawPoint, Rectangle mapDisplayRectangle) diff --git a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java index 62fb948cfb..f26b23035b 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java +++ b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrap.java @@ -14,7 +14,7 @@ import org.codehaus.plexus.util.FileUtils; public class Bootstrap { - private String projectVersion = "1.5.30-SNAPSHOT"; + private String projectVersion = "1.5.31-SNAPSHOT"; String buildCommit = "6fe334c02648d3f8b38625e3175e3f547d54aa37"; Client client = new Client(); String[] clientJvm9Arguments = new String[]{ diff --git a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrapper.java b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrapper.java index edce589251..770c377457 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrapper.java +++ b/runelite-client/src/main/java/net/runelite/client/util/bootstrap/Bootstrapper.java @@ -32,7 +32,7 @@ public class Bootstrapper } else { - remoteLocation = "/live/"; + remoteLocation = "live/"; localLocation = "./live/"; Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); File dir = new File("./live/"); diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index 140d8d911b..afe84dc109 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -9235,5 +9235,172 @@ "giant egg sac": [ 23517, 23520 +], + "crystal seedling": [ + 23655, + 23657 + ], + "crystal axe": [ + 23673, + 23675, + 23862 + ], + "crystal pickaxe": [ + 23680, + 23682, + 23863 + ], + "divine super combat potion": [ + 23685, + 23688, + 23691, + 23694 + ], + "divine super attack potion": [ + 23697, + 23700, + 23703, + 23706 + ], + "divine super strength potion": [ + 23709, + 23712, + 23715, + 23718 + ], + "divine super defence potion": [ + 23721, + 23724, + 23727, + 23730 + ], + "divine ranging potion": [ + 23733, + 23736, + 23739, + 23742 + ], + "divine magic potion": [ + 23745, + 23748, + 23751, + 23754 + ], + "crystal harpoon": [ + 23762, + 23764, + 23864 + ], + "crystal dust": [ + 23804, + 23867, + 23964 + ], + "crystal seed": [ + 23808, + 23810 + ], + "weapon frame": [ + 23834, + 23871 + ], + "grym leaf": [ + 23835, + 23875 + ], + "linum tirinum": [ + 23836, + 23876 + ], + "phren bark": [ + 23838, + 23878 + ], + "corrupted body": [ + 23843, + 23844, + 23845 + ], + "corrupted legs": [ + 23846, + 23847, + 23848 + ], + "corrupted halberd": [ + 23849, + 23850, + 23851 + ], + "corrupted staff": [ + 23852, + 23853, + 23854 + ], + "corrupted bow": [ + 23855, + 23856, + 23857 + ], + "egniol potion": [ + 23882, + 23883, + 23884, + 23885 + ], + "crystal helm": [ + 23886, + 23887, + 23888, + 23971, + 23973 + ], + "crystal body": [ + 23889, + 23890, + 23891, + 23975, + 23977 + ], + "crystal legs": [ + 23892, + 23893, + 23894, + 23979, + 23981 + ], + "crystal staff": [ + 23898, + 23899, + 23900 + ], + "crystal crown": [ + 23911, + 23913, + 23915, + 23917, + 23919, + 23921, + 23923, + 23925 + ], + "blade of saeldor": [ + 23995, + 23997 + ], + "elven top": [ + 24009, + 24015, + 24021, + 24027 + ], + "elven skirt": [ + 24012, + 24018 + ], + "memoriam crystal": [ + 24030, + 24031, + 24032, + 24033 ] -} \ No newline at end of file +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json index 19fca53730..b72b8d59e9 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_agility.json @@ -78,6 +78,12 @@ "name": "Pollnivneach Rooftop", "xp": 890 }, + { + "level": 75, + "icon": 23962, + "name": "Prifddinas Agility Course", + "xp": 1220 + }, { "level": 80, "icon": 11849, diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json index bc5cde0ef6..5953579264 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json @@ -240,6 +240,12 @@ "name": "Lantadyme", "xp": 134.5 }, + { + "level": 74, + "icon": 23962, + "name": "Crystal Tree", + "xp": 13366 + }, { "level": 75, "icon": 1513, diff --git a/runelite-client/src/main/resources/net/runelite/client/runelite.properties b/runelite-client/src/main/resources/runelite.plus.properties similarity index 60% rename from runelite-client/src/main/resources/net/runelite/client/runelite.properties rename to runelite-client/src/main/resources/runelite.plus.properties index 95807daaf6..d9a0701f7e 100644 --- a/runelite-client/src/main/resources/net/runelite/client/runelite.properties +++ b/runelite-client/src/main/resources/runelite.plus.properties @@ -1,10 +1,10 @@ -runelite.title=RuneLite -runelite.version=${project.version} -runescape.version=${rs.version} -runelite.discord.appid=409416265891971072 +runelite.version=@project.version@ +runescape.version=@rs.version@ runelite.plus.discord.appid=560644885250572289 runelite.discord.invite=https://discord.gg/HN5gf3m runelite.github.link=https://github.com/runelite-extended/runelite runelite.wiki.link=https://github.com/runelite-extended/runelite/wiki runelite.patreon.link=https://www.patreon.com/RuneLitePlus -runelit.version =2.0.1-1 \ No newline at end of file +runelite.plus.title=RuneLitePlus +runelite.plus.version=@runelite.plus.version@ +runelite.plus.builddate=@runelite.plus.builddate@ \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index 58860a03fb..31c9bfd205 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -38,11 +38,11 @@ import net.runelite.client.config.ConfigManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.eq; import org.mockito.Mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ChatCommandsPluginTest @@ -142,6 +142,28 @@ public class ChatCommandsPluginTest verify(configManager).setConfiguration("killcount.adam", "herbiboar", 4091); } + @Test + public void testGauntlet() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage gauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: 123.", null, 0); + chatCommandsPlugin.onChatMessage(gauntletMessage); + + verify(configManager).setConfiguration("killcount.adam", "gauntlet", 123); + } + + @Test + public void testCorruptedGauntlet() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage corruptedGauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Corrupted Gauntlet completion count is: 4729.", null, 0); + chatCommandsPlugin.onChatMessage(corruptedGauntletMessage); + + verify(configManager).setConfiguration("killcount.adam", "corrupted gauntlet", 4729); + } + @Test public void testPersonalBest() { @@ -244,4 +266,94 @@ public class ChatCommandsPluginTest verify(configManager).setConfiguration(eq("personalbest.adam"), eq("prifddinas agility course"), eq(61)); verify(configManager).setConfiguration(eq("killcount.adam"), eq("prifddinas agility course"), eq(2)); } + + @Test + public void testZukNewPb() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: 2.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: 104:31 (new personal best)", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("tzkal-zuk"), eq(104 * 60 + 31)); + verify(configManager).setConfiguration(eq("killcount.adam"), eq("tzkal-zuk"), eq(2)); + } + + @Test + public void testZukKill() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: 3.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: 172:18. Personal best: 134:52", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("tzkal-zuk"), eq(134 * 60 + 52)); + verify(configManager).setConfiguration(eq("killcount.adam"), eq("tzkal-zuk"), eq(3)); + } + + @Test + public void testGgNewPb() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: 1:36 (new personal best)", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: 179.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("grotesque guardians"), eq(96)); + verify(configManager).setConfiguration(eq("killcount.adam"), eq("grotesque guardians"), eq(179)); + } + + @Test + public void testGgKill() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: 2:41. Personal best: 2:14", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: 32.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("grotesque guardians"), eq(2 * 60 + 14)); + verify(configManager).setConfiguration(eq("killcount.adam"), eq("grotesque guardians"), eq(32)); + } + + @Test + public void testGuantletPersonalBest() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: 10:24. Personal best: 7:59.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: 124.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setConfiguration(eq("killcount.adam"), eq("gauntlet"), eq(124)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("gauntlet"), eq(7 * 60 + 59)); + } + + @Test + public void testGuantletNewPersonalBest() + { + when(client.getUsername()).thenReturn("Adam"); + + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: 10:24 (new personal best).", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: 124.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("gauntlet"), eq(10 * 60 + 24)); + verify(configManager).setConfiguration(eq("killcount.adam"), eq("gauntlet"), eq(124)); + } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderBridgeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderBridgeMixin.java index f9e9a175f2..81c60a8c12 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderBridgeMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderBridgeMixin.java @@ -24,6 +24,7 @@ */ package net.runelite.mixins; +import java.util.List; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; import net.runelite.rs.api.RSClient; @@ -65,8 +66,13 @@ public abstract class EntityHiderBridgeMixin implements RSClient public static boolean hideProjectiles; @Inject - public static String hideNPCsNames; + public static boolean hideDeadNPCs; + @Inject + public static List hideNPCsNames; + + @Inject + public static List hideNPCsOnDeath; @Inject @Override @@ -133,11 +139,18 @@ public abstract class EntityHiderBridgeMixin implements RSClient @Inject @Override - public void setNPCsNames(String NPCs) + public void setNPCsNames(List NPCs) { hideNPCsNames = NPCs; } + @Inject + @Override + public void setNPCsHiddenOnDeath(List NPCs) + { + hideNPCsOnDeath = NPCs; + } + @Inject @Override public void setAttackersHidden(boolean state) @@ -151,4 +164,11 @@ public abstract class EntityHiderBridgeMixin implements RSClient { hideProjectiles = state; } + + @Inject + @Override + public void setDeadNPCsHidden(boolean state) + { + hideDeadNPCs = state; + } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderMixin.java index 8f84b9d917..80122ba7bf 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/EntityHiderMixin.java @@ -24,6 +24,9 @@ */ package net.runelite.mixins; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.runelite.api.mixins.Copy; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; @@ -40,6 +43,12 @@ import net.runelite.rs.api.RSScene; @Mixin(RSScene.class) public abstract class EntityHiderMixin implements RSScene { + @Inject + private static final Pattern WILDCARD_PATTERN = Pattern.compile("(?i)[^*]+|(\\*)"); + + @Inject + private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>"); + @Shadow("client") private static RSClient client; @@ -68,7 +77,10 @@ public abstract class EntityHiderMixin implements RSScene private static boolean hideNPCs; @Shadow("hideNPCsNames") - private static String hideNPCsNames; + private static List hideNPCsNames; + + @Shadow("hideNPCsOnDeath") + private static List hideNPCsOnDeath; @Shadow("hideNPCs2D") private static boolean hideNPCs2D; @@ -79,6 +91,9 @@ public abstract class EntityHiderMixin implements RSScene @Shadow("hideProjectiles") private static boolean hideProjectiles; + @Shadow("hideDeadNPCs") + private static boolean hideDeadNPCs; + @Copy("newGameObject") abstract boolean addEntityMarker(int var1, int var2, int var3, int var4, int var5, int x, int y, int var8, RSEntity renderable, int var10, boolean var11, long var12, int var13); @@ -154,7 +169,6 @@ public abstract class EntityHiderMixin implements RSScene else if (renderable instanceof RSNPC) { RSNPC npc = (RSNPC) renderable; - String[] names = hideNPCsNames.split(","); if (!hideAttackers) { @@ -164,16 +178,29 @@ public abstract class EntityHiderMixin implements RSScene } } - for (String name : names) + if (hideDeadNPCs && npc.getHealthRatio() == 0) + { + return false; + } + + for (String name : hideNPCsNames) { if (name != null && !name.equals("")) { - if (npc.getName() != null) + if (npc.getName() != null && matches(name, npc.getName())) { - if (npc.getName().startsWith(name)) - { - return false; - } + return false; + } + } + } + + for (String name : hideNPCsOnDeath) + { + if (name != null && !name.equals("")) + { + if (npc.getName() != null && matches(name, npc.getName()) && npc.getHealthRatio() == 0) + { + return false; } } } @@ -187,4 +214,34 @@ public abstract class EntityHiderMixin implements RSScene return true; } + + @Inject + static private boolean matches(String pattern, String text) + { + String standardized = TAG_REGEXP.matcher(text) + .replaceAll("") + .replace('\u00A0', ' ') + .toLowerCase(); + + final Matcher matcher = WILDCARD_PATTERN.matcher(pattern.toLowerCase()); + final StringBuffer buffer = new StringBuffer(); + + buffer.append("(?i)"); + while (matcher.find()) + { + if (matcher.group(1) != null) + { + matcher.appendReplacement(buffer, ".*"); + } + else + { + matcher.appendReplacement(buffer, "\\\\Q" + matcher.group(0) + "\\\\E"); + } + } + + matcher.appendTail(buffer); + final String replaced = buffer.toString(); + + return standardized.matches(replaced); + } } diff --git a/scripts/pom.xml b/scripts/pom.xml deleted file mode 100644 index 7898c2e8fb..0000000000 --- a/scripts/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - 4.0.0 - - net.runelite - scripts - 1.0.0 - Scripts - - - - - org.apache.maven.wagon - wagon-webdav-jackrabbit - 2.12 - - - -