diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index d3fb0c43d5..79dc14b728 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -25,7 +25,7 @@ object ProjectVersions { const val launcherVersion = "2.2.0" - const val rlVersion = "1.6.37" + const val rlVersion = "1.6.38" const val openosrsVersion = "3.5.4" diff --git a/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java b/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java index 92a82e26b7..c8d651bcf6 100644 --- a/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java +++ b/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java @@ -220,7 +220,7 @@ public class FlatStorage implements Storage br.printf("revision=%d\n", idx.getRevision()); br.printf("compression=%d\n", idx.getCompression()); br.printf("crc=%d\n", idx.getCrc()); - br.printf("named=%b\n", idx.getCompression()); + br.printf("named=%b\n", idx.isNamed()); idx.getArchives().sort(Comparator.comparing(Archive::getArchiveId)); for (Archive archive : idx.getArchives()) 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 0b017518c8..dc483f35db 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 @@ -25,10 +25,16 @@ package net.runelite.http.api; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.awt.Color; import java.io.IOException; import java.io.InputStream; +import java.time.Instant; import java.util.Properties; import java.util.concurrent.TimeUnit; +import net.runelite.http.api.gson.ColorTypeAdapter; +import net.runelite.http.api.gson.InstantTypeAdapter; +import net.runelite.http.api.gson.IllegalReflectionExclusion; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.MediaType; @@ -46,7 +52,7 @@ public class RuneLiteAPI public static final String RUNELITE_MACHINEID = "RUNELITE-MACHINEID"; public static final OkHttpClient CLIENT; - public static final Gson GSON = new Gson(); + public static final Gson GSON; public static final MediaType JSON = MediaType.parse("application/json"); public static String userAgent; @@ -96,6 +102,23 @@ public class RuneLiteAPI } }) .build(); + + GsonBuilder gsonBuilder = new GsonBuilder(); + + gsonBuilder + .registerTypeAdapter(Instant.class, new InstantTypeAdapter()) + .registerTypeAdapter(Color.class, new ColorTypeAdapter()); + + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + if (assertionsEnabled) + { + IllegalReflectionExclusion jbe = new IllegalReflectionExclusion(); + gsonBuilder.addSerializationExclusionStrategy(jbe); + gsonBuilder.addDeserializationExclusionStrategy(jbe); + } + + GSON = gsonBuilder.create(); } public static HttpUrl getSessionBase() diff --git a/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java b/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java new file mode 100644 index 0000000000..6f4b003df0 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.api.gson; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.awt.Color; +import java.io.IOException; + +public class ColorTypeAdapter extends TypeAdapter +{ + @Override + public void write(JsonWriter out, Color value) throws IOException + { + if (value == null) + { + out.nullValue(); + return; + } + + int rgba = value.getRGB(); + out.beginObject() + .name("value") + .value(rgba) + .endObject(); + } + + @Override + public Color read(JsonReader in) throws IOException + { + switch (in.peek()) + { + case NULL: + in.nextNull(); + return null; + case BEGIN_OBJECT: + in.beginObject(); + double value = 0; + while (in.peek() != JsonToken.END_OBJECT) + { + switch (in.nextName()) + { + case "value": + value = in.nextDouble(); + break; + default: + in.skipValue(); + break; + } + } + in.endObject(); + return new Color((int) value, true); + } + return null; // throws + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/gson/IllegalReflectionExclusion.java b/http-api/src/main/java/net/runelite/http/api/gson/IllegalReflectionExclusion.java new file mode 100644 index 0000000000..d7611cf83f --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/gson/IllegalReflectionExclusion.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.api.gson; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import java.lang.reflect.Modifier; + +public class IllegalReflectionExclusion implements ExclusionStrategy +{ + @Override + public boolean shouldSkipField(FieldAttributes f) + { + if (f.getDeclaringClass().getName().startsWith("net.runelite")) + { + return false; + } + + assert !Modifier.isPrivate(f.getDeclaringClass().getModifiers()) : "gsoning private class " + f.getDeclaringClass().getName(); + try + { + f.getDeclaringClass().getField(f.getName()); + } + catch (NoSuchFieldException e) + { + throw new AssertionError("gsoning private field " + f.getDeclaringClass() + "." + f.getName()); + } + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) + { + return false; + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java b/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java new file mode 100644 index 0000000000..bf92af94b8 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.api.gson; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.time.Instant; + +// Just add water! +public class InstantTypeAdapter extends TypeAdapter +{ + @Override + public void write(JsonWriter out, Instant value) throws IOException + { + if (value == null) + { + out.nullValue(); + return; + } + + out.beginObject() + .name("seconds") + .value(value.getEpochSecond()) + .name("nanos") + .value(value.getNano()) + .endObject(); + } + + @Override + public Instant read(JsonReader in) throws IOException + { + if (in.peek() == JsonToken.NULL) + { + in.nextNull(); + return null; + } + + long seconds = 0; + int nanos = 0; + in.beginObject(); + while (in.peek() != JsonToken.END_OBJECT) + { + switch (in.nextName()) + { + case "nanos": + nanos = in.nextInt(); + break; + case "seconds": + seconds = in.nextLong(); + break; + } + } + in.endObject(); + + return Instant.ofEpochSecond(seconds, nanos); + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java b/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java index 9d4e46e6ea..328d0aa1a7 100644 --- a/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java +++ b/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java @@ -25,11 +25,11 @@ package net.runelite.http.api.ws; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.ws.messages.Handshake; import net.runelite.http.api.ws.messages.LoginResponse; import net.runelite.http.api.ws.messages.party.Join; @@ -76,7 +76,7 @@ public class WebsocketGsonFactory public static Gson build(final RuntimeTypeAdapterFactory factory) { - return new GsonBuilder() + return RuneLiteAPI.GSON.newBuilder() .registerTypeAdapterFactory(factory) .create(); } diff --git a/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java b/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java new file mode 100644 index 0000000000..0be27dfa46 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Noodleeater + * 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.api; + +/** + * Represents an archive of data, which is ordered into "groups" of "files". + */ +public interface AbstractArchive extends IndexDataBase +{ + /** + * the methods bellow are usefull for reading byte data from the cache + */ + int getGroupCount(); + + byte[] getConfigData(int archiveId, int fileId); + + int[] getFileIds(int groupId); + + int[][] getFileIds(); + + byte[] getFile(int groupId, int fileId); + + int getGroupFileCount(int groupId); + + int[] getFileCounts(); +} diff --git a/runelite-api/src/main/java/net/runelite/api/Buffer.java b/runelite-api/src/main/java/net/runelite/api/Buffer.java new file mode 100644 index 0000000000..384b3cacc8 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/Buffer.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, Noodleeater + * 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.api; + +/** + * Represents a byte buffer + */ +public interface Buffer extends Node +{ + byte[] getPayload(); + + int getOffset(); + + /** + * Use this api to write to byte buffers + */ + void writeByte(int var1); + + void writeShort(int var1); + + void writeMedium(int var1); + + void writeInt(int var1); + + void writeLong(long var1); + + void writeStringCp1252NullTerminated(String string); +} diff --git a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java index f96d7fba63..d453bfbb35 100644 --- a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java +++ b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java @@ -117,7 +117,7 @@ public enum ChatMessageType */ MODAUTOTYPER(91), /** - * A game message (ie. when a setting is changed). + * A game message. (ie. when a setting is changed) */ CONSOLE(99), /** 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 bf4fbab150..a37b03dc0a 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -47,7 +47,7 @@ import org.slf4j.Logger; /** * Represents the RuneScape client. */ -public interface Client extends GameShell +public interface Client extends GameEngine { /** * The injected client invokes these callbacks to send events to us @@ -68,6 +68,8 @@ public interface Client extends GameShell */ Logger getLogger(); + String getBuildID(); + /** * Gets a list of all valid players from the player cache. * @@ -457,7 +459,7 @@ public interface Client extends GameShell int getMouseCurrentButton(); /** - * Gets the currently selected tile (ie. last right clicked tile). + * Gets the currently selected tile. (ie. last right clicked tile) * * @return the selected tile */ @@ -1543,8 +1545,8 @@ public interface Client extends GameShell void setPlayersHidden(boolean state); /** - * Sets whether 2D sprites (ie. overhead prayers, PK skull) related to - * the other players are hidden. + * Sets whether 2D sprites related to the other players are hidden. + * (ie. overhead prayers, PK skull) * * @param state the new player 2D hidden state */ @@ -1572,8 +1574,8 @@ public interface Client extends GameShell void setLocalPlayerHidden(boolean state); /** - * Sets whether 2D sprites (ie. overhead prayers, PK skull) related to - * the local player are hidden. + * Sets whether 2D sprites related to the local player are hidden. + * (ie. overhead prayers, PK skull) * * @param state new local player 2D hidden state */ @@ -2135,4 +2137,34 @@ public interface Client extends GameShell void setOutdatedScript(String outdatedScript); List getOutdatedScripts(); + + /** + * various archives you might want to use for reading data from cache + */ + AbstractArchive getSequenceDefinition_skeletonsArchive(); + + AbstractArchive getSequenceDefinition_archive(); + + AbstractArchive getSequenceDefinition_animationsArchive(); + + AbstractArchive getNpcDefinition_archive(); + + AbstractArchive getObjectDefinition_modelsArchive(); + + AbstractArchive getObjectDefinition_archive(); + + AbstractArchive getItemDefinition_archive(); + + AbstractArchive getKitDefinition_archive(); + + AbstractArchive getKitDefinition_modelsArchive(); + + AbstractArchive getSpotAnimationDefinition_archive(); + + AbstractArchive getSpotAnimationDefinition_modelArchive(); + + /** + * use createBuffer to create a new byte buffer + */ + Buffer createBuffer(byte[] initialBytes); } diff --git a/runelite-api/src/main/java/net/runelite/api/GameShell.java b/runelite-api/src/main/java/net/runelite/api/GameEngine.java similarity index 98% rename from runelite-api/src/main/java/net/runelite/api/GameShell.java rename to runelite-api/src/main/java/net/runelite/api/GameEngine.java index aa69462bfd..01b85ba512 100644 --- a/runelite-api/src/main/java/net/runelite/api/GameShell.java +++ b/runelite-api/src/main/java/net/runelite/api/GameEngine.java @@ -30,7 +30,7 @@ import java.awt.Canvas; /** * Represents the client game engine. */ -public interface GameShell +public interface GameEngine { /** * Gets the canvas that contains everything. diff --git a/runelite-api/src/main/java/net/runelite/api/HeadIcon.java b/runelite-api/src/main/java/net/runelite/api/HeadIcon.java index 6f70220ba9..ad8f00cc08 100644 --- a/runelite-api/src/main/java/net/runelite/api/HeadIcon.java +++ b/runelite-api/src/main/java/net/runelite/api/HeadIcon.java @@ -54,7 +54,7 @@ public enum HeadIcon */ REDEMPTION, /** - * Protect from range and mage (ie. used by Kalphite Queen). + * Protect from range and mage. (ie. used by Kalphite Queen) */ RANGE_MAGE } diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java index ed667b6b68..d82361802d 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -11656,8 +11656,6 @@ public final class ItemID public static final int GIANT_BOULDER = 25314; public static final int GOBLIN_DECORATIONS = 25316; public static final int GNOME_CHILD_ICON = 25319; - public static final int GNOME_CHILD = 25320; - public static final int GNOME_CHILD_25321 = 25321; public static final int _20TH_ANNIVERSARY_HAT = 25322; public static final int _20TH_ANNIVERSARY_TOP = 25324; public static final int _20TH_ANNIVERSARY_BOTTOM = 25326; @@ -11698,5 +11696,60 @@ public final class ItemID public static final int TRAILBLAZER_RELIC_HUNTER_T1_ARMOUR_SET = 25380; public static final int TRAILBLAZER_RELIC_HUNTER_T2_ARMOUR_SET = 25383; public static final int TRAILBLAZER_RELIC_HUNTER_T3_ARMOUR_SET = 25386; + public static final int SWAMPBARK_BODY = 25389; + public static final int SWAMPBARK_GAUNTLETS = 25392; + public static final int SWAMPBARK_BOOTS = 25395; + public static final int SWAMPBARK_HELM = 25398; + public static final int SWAMPBARK_LEGS = 25401; + public static final int BLOODBARK_BODY = 25404; + public static final int BLOODBARK_GAUNTLETS = 25407; + public static final int BLOODBARK_BOOTS = 25410; + public static final int BLOODBARK_HELM = 25413; + public static final int BLOODBARK_LEGS = 25416; + public static final int URIUM_REMAINS = 25419; + public static final int BLEACHED_BONES = 25422; + public static final int GOLD_KEY_RED = 25424; + public static final int GOLD_KEY_BROWN = 25426; + public static final int GOLD_KEY_CRIMSON = 25428; + public static final int GOLD_KEY_BLACK = 25430; + public static final int GOLD_KEY_PURPLE = 25432; + public static final int ZEALOTS_ROBE_TOP = 25434; + public static final int ZEALOTS_ROBE_BOTTOM = 25436; + public static final int ZEALOTS_HELM = 25438; + public static final int ZEALOTS_BOOTS = 25440; + public static final int BRONZE_LOCKS = 25442; + public static final int STEEL_LOCKS = 25445; + public static final int BLACK_LOCKS = 25448; + public static final int SILVER_LOCKS = 25451; + public static final int GOLD_LOCKS = 25454; + public static final int BROKEN_COFFIN = 25457; + public static final int BRONZE_COFFIN = 25459; + public static final int STEEL_COFFIN = 25461; + public static final int BLACK_COFFIN = 25463; + public static final int SILVER_COFFIN = 25465; + public static final int GOLD_COFFIN = 25467; + public static final int OPEN_BRONZE_COFFIN = 25469; + public static final int OPEN_STEEL_COFFIN = 25470; + public static final int OPEN_BLACK_COFFIN = 25471; + public static final int OPEN_SILVER_COFFIN = 25472; + public static final int OPEN_GOLD_COFFIN = 25473; + public static final int TREE_WIZARDS_JOURNAL = 25474; + public static final int BLOODY_NOTES = 25476; + public static final int RUNESCROLL_OF_SWAMPBARK = 25478; + public static final int RUNESCROLL_OF_BLOODBARK = 25481; + public static final int TOXIC_BLOWPIPE_BETA__BRONZE = 25484; + public static final int TOXIC_BLOWPIPE_BETA__IRON = 25485; + public static final int TOXIC_BLOWPIPE_BETA__STEEL = 25486; + public static final int TOXIC_BLOWPIPE_BETA__BLACK = 25487; + public static final int TOXIC_BLOWPIPE_BETA__MITHRIL = 25488; + public static final int TOXIC_BLOWPIPE_BETA__ADAMANT = 25489; + public static final int TOXIC_BLOWPIPE_BETA__RUNE = 25490; + public static final int TOXIC_BLOWPIPE_BETA__DRAGON = 25491; + public static final int BLACK_DHIDE_BODY_BETA = 25492; + public static final int BLACK_DHIDE_CHAPS_BETA = 25493; + public static final int BLACK_DHIDE_VAMBRACES_BETA = 25494; + public static final int CRYSTAL_HELM_BETA = 25495; + public static final int CRYSTAL_BODY_BETA = 25496; + public static final int CRYSTAL_LEGS_BETA = 25497; /* This file is automatically generated. Do not edit. */ } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index d224e6b183..9b0dd9061c 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -35,11 +35,11 @@ import lombok.NoArgsConstructor; public class MenuEntry implements Cloneable { /** - * The option text added to the menu (ie. "Walk here", "Use"). + * The option text added to the menu. (ie. "Walk here", "Use") */ private String option; /** - * The target of the action (ie. Item or Actor name). + * The target of the action. (ie. Item or Actor name) *

* If the option does not apply to any target, this field * will be set to empty string. diff --git a/runelite-api/src/main/java/net/runelite/api/MessageNode.java b/runelite-api/src/main/java/net/runelite/api/MessageNode.java index b191555d05..bd1e79ce77 100644 --- a/runelite-api/src/main/java/net/runelite/api/MessageNode.java +++ b/runelite-api/src/main/java/net/runelite/api/MessageNode.java @@ -58,7 +58,7 @@ public interface MessageNode extends Node void setName(String name); /** - * Gets the sender of the message (ie. friends chat name). + * Gets the sender of the message. (ie. friends chat name) * * @return the message sender */ diff --git a/runelite-api/src/main/java/net/runelite/api/NpcID.java b/runelite-api/src/main/java/net/runelite/api/NpcID.java index 15460768d9..f6bef67796 100644 --- a/runelite-api/src/main/java/net/runelite/api/NpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java @@ -2657,6 +2657,7 @@ public final class NpcID public static final int DRYAD = 2828; public static final int FAIRY_2829 = 2829; public static final int MYSTERIOUS_OLD_MAN = 2830; + public static final int CHAIR = 2832; public static final int LIL_CREATOR = 2833; public static final int GIANT_BAT = 2834; public static final int CAMEL = 2835; @@ -5716,6 +5717,7 @@ public final class NpcID public static final int THE_INADEQUACY_HARD = 6119; public static final int THE_EVERLASTING_HARD = 6120; public static final int THE_UNTOUCHABLE_HARD = 6121; + public static final int URIUM_SHADOW = 6143; public static final int SCION_6177 = 6177; public static final int JUNGLE_SPIDER_6267 = 6267; public static final int JUNGLE_SPIDER_6271 = 6271; @@ -8920,37 +8922,14 @@ public final class NpcID public static final int DUCK_10546 = 10546; public static final int DUCK_10547 = 10547; public static final int CHICKEN_10556 = 10556; - public static final int GNOME_CHILD_10557 = 10557; - public static final int GNOME_CHILD_10558 = 10558; public static final int SCRUBFOOT = 10559; - public static final int GNOME_CHILD_10560 = 10560; public static final int RED_FIREFLIES = 10561; - public static final int GNOME_CHILD_10562 = 10562; - public static final int THRANDER = 10563; public static final int GREEN_FIREFLIES = 10564; - public static final int CHUCK_10565 = 10565; public static final int GOBLIN_10566 = 10566; public static final int GOBLIN_10567 = 10567; - public static final int PIOUS_PETE = 10568; - public static final int MYSTERIOUS_WATCHER = 10569; - public static final int MYSTERIOUS_WATCHER_10570 = 10570; - public static final int MYSTERIOUS_WATCHER_10571 = 10571; - public static final int BIG_MO = 10572; - public static final int CHEERLEADER_10573 = 10573; - public static final int CHEERLEADER_10574 = 10574; - public static final int CHEERLEADER_10575 = 10575; - public static final int BLACK_DRAGON_10576 = 10576; - public static final int RED_DRAGON_10577 = 10577; - public static final int BLUE_DRAGON_10578 = 10578; - public static final int KING_BLACK_DRAGON_10579 = 10579; - public static final int BABY_BLUE_DRAGON_10580 = 10580; - public static final int LESSER_DEMON_10581 = 10581; - public static final int GREATER_DEMON_10582 = 10582; - public static final int BLACK_DEMON_10583 = 10583; - public static final int SCORPION_10584 = 10584; - public static final int KING_SCORPION_10585 = 10585; - public static final int ORC = 10586; - public static final int LIZARD_MAN = 10587; - public static final int TROLL_10588 = 10588; + public static final int URIUM_SHADE = 10589; + public static final int DAMPE = 10590; + public static final int UNDEAD_ZEALOT = 10591; + public static final int UNDEAD_ZEALOT_10592 = 10592; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java index c6fa2aadf0..a0bc89a2aa 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -13453,6 +13453,8 @@ public final class NullItemID public static final int NULL_25315 = 25315; public static final int NULL_25317 = 25317; public static final int NULL_25318 = 25318; + public static final int NULL_25320 = 25320; + public static final int NULL_25321 = 25321; public static final int NULL_25323 = 25323; public static final int NULL_25325 = 25325; public static final int NULL_25327 = 25327; @@ -13480,5 +13482,59 @@ public final class NullItemID public static final int NULL_25385 = 25385; public static final int NULL_25387 = 25387; public static final int NULL_25388 = 25388; + public static final int NULL_25390 = 25390; + public static final int NULL_25391 = 25391; + public static final int NULL_25393 = 25393; + public static final int NULL_25394 = 25394; + public static final int NULL_25396 = 25396; + public static final int NULL_25397 = 25397; + public static final int NULL_25399 = 25399; + public static final int NULL_25400 = 25400; + public static final int NULL_25402 = 25402; + public static final int NULL_25403 = 25403; + public static final int NULL_25405 = 25405; + public static final int NULL_25406 = 25406; + public static final int NULL_25408 = 25408; + public static final int NULL_25409 = 25409; + public static final int NULL_25411 = 25411; + public static final int NULL_25412 = 25412; + public static final int NULL_25414 = 25414; + public static final int NULL_25415 = 25415; + public static final int NULL_25417 = 25417; + public static final int NULL_25418 = 25418; + public static final int NULL_25420 = 25420; + public static final int NULL_25421 = 25421; + public static final int NULL_25423 = 25423; + public static final int NULL_25425 = 25425; + public static final int NULL_25427 = 25427; + public static final int NULL_25429 = 25429; + public static final int NULL_25431 = 25431; + public static final int NULL_25433 = 25433; + public static final int NULL_25435 = 25435; + public static final int NULL_25437 = 25437; + public static final int NULL_25439 = 25439; + public static final int NULL_25441 = 25441; + public static final int NULL_25443 = 25443; + public static final int NULL_25444 = 25444; + public static final int NULL_25446 = 25446; + public static final int NULL_25447 = 25447; + public static final int NULL_25449 = 25449; + public static final int NULL_25450 = 25450; + public static final int NULL_25452 = 25452; + public static final int NULL_25453 = 25453; + public static final int NULL_25455 = 25455; + public static final int NULL_25456 = 25456; + public static final int NULL_25458 = 25458; + public static final int NULL_25460 = 25460; + public static final int NULL_25462 = 25462; + public static final int NULL_25464 = 25464; + public static final int NULL_25466 = 25466; + public static final int NULL_25468 = 25468; + public static final int NULL_25475 = 25475; + public static final int NULL_25477 = 25477; + public static final int NULL_25479 = 25479; + public static final int NULL_25480 = 25480; + public static final int NULL_25482 = 25482; + public static final int NULL_25483 = 25483; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java index 622f0fc904..c0acd7f40c 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java @@ -174,7 +174,6 @@ public final class NullNpcID public static final int NULL_2780 = 2780; public static final int NULL_2781 = 2781; public static final int NULL_2831 = 2831; - public static final int NULL_2832 = 2832; public static final int NULL_2934 = 2934; public static final int NULL_2935 = 2935; public static final int NULL_2936 = 2936; diff --git a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java index 950d22e579..91bb2fdc18 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -879,7 +879,6 @@ public final class NullObjectID public static final int NULL_1793 = 1793; public static final int NULL_1794 = 1794; public static final int NULL_1795 = 1795; - public static final int NULL_1796 = 1796; public static final int NULL_1798 = 1798; public static final int NULL_1799 = 1799; public static final int NULL_1800 = 1800; @@ -890,7 +889,6 @@ public final class NullObjectID public static final int NULL_1807 = 1807; public static final int NULL_1808 = 1808; public static final int NULL_1809 = 1809; - public static final int NULL_1812 = 1812; public static final int NULL_1815 = 1815; public static final int NULL_1818 = 1818; public static final int NULL_1819 = 1819; @@ -19747,6 +19745,7 @@ public final class NullObjectID public static final int NULL_40427 = 40427; public static final int NULL_40428 = 40428; public static final int NULL_40429 = 40429; + public static final int NULL_40470 = 40470; public static final int NULL_40477 = 40477; public static final int NULL_40478 = 40478; public static final int NULL_40479 = 40479; @@ -20009,84 +20008,6 @@ public final class NullObjectID public static final int NULL_40934 = 40934; public static final int NULL_40935 = 40935; public static final int NULL_40936 = 40936; - public static final int NULL_40942 = 40942; - public static final int NULL_40943 = 40943; - public static final int NULL_40944 = 40944; - public static final int NULL_40945 = 40945; - public static final int NULL_40946 = 40946; - public static final int NULL_40947 = 40947; - public static final int NULL_40948 = 40948; - public static final int NULL_40949 = 40949; - public static final int NULL_40950 = 40950; - public static final int NULL_40951 = 40951; - public static final int NULL_40952 = 40952; - public static final int NULL_40953 = 40953; - public static final int NULL_40954 = 40954; - public static final int NULL_40955 = 40955; - public static final int NULL_40956 = 40956; - public static final int NULL_40957 = 40957; - public static final int NULL_40958 = 40958; - public static final int NULL_40959 = 40959; - public static final int NULL_40960 = 40960; - public static final int NULL_40961 = 40961; - public static final int NULL_40962 = 40962; - public static final int NULL_40963 = 40963; - public static final int NULL_40964 = 40964; - public static final int NULL_40965 = 40965; - public static final int NULL_40966 = 40966; - public static final int NULL_40967 = 40967; - public static final int NULL_40968 = 40968; - public static final int NULL_40969 = 40969; - public static final int NULL_40970 = 40970; - public static final int NULL_40971 = 40971; - public static final int NULL_40972 = 40972; - public static final int NULL_40973 = 40973; - public static final int NULL_40974 = 40974; - public static final int NULL_40975 = 40975; - public static final int NULL_40976 = 40976; - public static final int NULL_40977 = 40977; - public static final int NULL_40978 = 40978; - public static final int NULL_40979 = 40979; - public static final int NULL_40980 = 40980; - public static final int NULL_40981 = 40981; - public static final int NULL_40982 = 40982; - public static final int NULL_40983 = 40983; - public static final int NULL_40984 = 40984; - public static final int NULL_40985 = 40985; - public static final int NULL_40987 = 40987; - public static final int NULL_40988 = 40988; - public static final int NULL_40989 = 40989; - public static final int NULL_40990 = 40990; - public static final int NULL_40991 = 40991; - public static final int NULL_40992 = 40992; - public static final int NULL_40993 = 40993; - public static final int NULL_40994 = 40994; - public static final int NULL_40995 = 40995; - public static final int NULL_40996 = 40996; - public static final int NULL_40997 = 40997; - public static final int NULL_40998 = 40998; - public static final int NULL_40999 = 40999; - public static final int NULL_41000 = 41000; - public static final int NULL_41001 = 41001; - public static final int NULL_41002 = 41002; - public static final int NULL_41003 = 41003; - public static final int NULL_41004 = 41004; - public static final int NULL_41005 = 41005; - public static final int NULL_41006 = 41006; - public static final int NULL_41007 = 41007; - public static final int NULL_41008 = 41008; - public static final int NULL_41009 = 41009; - public static final int NULL_41010 = 41010; - public static final int NULL_41011 = 41011; - public static final int NULL_41012 = 41012; - public static final int NULL_41013 = 41013; - public static final int NULL_41014 = 41014; - public static final int NULL_41015 = 41015; - public static final int NULL_41016 = 41016; - public static final int NULL_41018 = 41018; - public static final int NULL_41019 = 41019; - public static final int NULL_41020 = 41020; - public static final int NULL_41021 = 41021; public static final int NULL_41022 = 41022; public static final int NULL_41191 = 41191; public static final int NULL_41192 = 41192; @@ -20096,5 +20017,15 @@ public final class NullObjectID public static final int NULL_41196 = 41196; public static final int NULL_41197 = 41197; public static final int NULL_41198 = 41198; + public static final int NULL_41201 = 41201; + public static final int NULL_41202 = 41202; + public static final int NULL_41203 = 41203; + public static final int NULL_41204 = 41204; + public static final int NULL_41205 = 41205; + public static final int NULL_41206 = 41206; + public static final int NULL_41207 = 41207; + public static final int NULL_41208 = 41208; + public static final int NULL_41209 = 41209; + public static final int NULL_41211 = 41211; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/ObjectID.java b/runelite-api/src/main/java/net/runelite/api/ObjectID.java index 153313b119..8bf9ca4de0 100644 --- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java @@ -18582,7 +18582,7 @@ public final class ObjectID public static final int RUBBLE_34803 = 34803; public static final int RUBBLE_34804 = 34804; public static final int RUBBLE_34805 = 34805; - public static final int JADFEST_PORTAL = 34826; + public static final int HANDY_PORTAL = 34826; public static final int LARRANS_SMALL_CHEST_34828 = 34828; public static final int LARRANS_BIG_CHEST = 34829; public static final int LARRANS_BIG_CHEST_34830 = 34830; @@ -19619,7 +19619,7 @@ public final class ObjectID public static final int GATE_37954 = 37954; public static final int LADDER_37955 = 37955; public static final int LADDER_37956 = 37956; - public static final int HANDY_PORTAL = 37957; + public static final int HANDY_PORTAL_37957 = 37957; public static final int BANK_BOOTH_37959 = 37959; public static final int DOOR_37961 = 37961; public static final int DOOR_37963 = 37963; @@ -20709,6 +20709,8 @@ public final class ObjectID public static final int EXPLOSIVE_POTION_TABLE_40467 = 40467; public static final int POTION_OF_POWER_TABLE_40468 = 40468; public static final int POTION_OF_POWER_TABLE_40469 = 40469; + public static final int GRAVESTONE_40471 = 40471; + public static final int COFFIN_40472 = 40472; public static final int BANK_CHEST_40473 = 40473; public static final int SOUL_WARS_PORTAL = 40474; public static final int SOUL_WARS_PORTAL_40475 = 40475; @@ -20899,25 +20901,8 @@ public final class ObjectID public static final int STATUE_40915 = 40915; public static final int STATUE_40916 = 40916; public static final int STATUE_40917 = 40917; - public static final int INERT_PORTAL = 40918; - public static final int PORTAL_40919 = 40919; - public static final int ODD_FEATHERS = 40920; - public static final int PORTAL_40921 = 40921; - public static final int BARRIER_40922 = 40922; - public static final int SLEEPING_BAG_40923 = 40923; - public static final int STATUE_40924 = 40924; - public static final int ARCHWAY_40929 = 40929; - public static final int LIGHT_40930 = 40930; - public static final int LIGHT_40931 = 40931; public static final int EVERGREEN_40932 = 40932; public static final int EVERGREEN_40933 = 40933; - public static final int LIGHT_40937 = 40937; - public static final int LIGHT_40938 = 40938; - public static final int LIGHT_40939 = 40939; - public static final int LIGHT_40940 = 40940; - public static final int FIREWORKS = 40941; - public static final int POST_40986 = 40986; - public static final int PARTY_TABLE = 41017; public static final int POTION_OF_POWER_TABLE_41023 = 41023; public static final int PEDESTAL_SPACE = 41024; public static final int PEDESTAL_SPACE_41025 = 41025; @@ -21088,5 +21073,17 @@ public final class ObjectID public static final int ANCIENT_BRAZIER_41190 = 41190; public static final int BARRIER_41199 = 41199; public static final int BARRIER_41200 = 41200; + public static final int SOLID_GOLD_DOOR = 41210; + public static final int GOLD_CHEST = 41212; + public static final int GOLD_CHEST_41213 = 41213; + public static final int GOLD_CHEST_41214 = 41214; + public static final int GOLD_CHEST_41215 = 41215; + public static final int GOLD_CHEST_41216 = 41216; + public static final int GOLD_CHEST_41217 = 41217; + public static final int GOLD_CHEST_41218 = 41218; + public static final int GOLD_CHEST_41219 = 41219; + public static final int GOLD_CHEST_41220 = 41220; + public static final int GOLD_CHEST_41221 = 41221; + public static final int ALTAR_41222 = 41222; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/Projectile.java b/runelite-api/src/main/java/net/runelite/api/Projectile.java index d298135af9..a539f55bfd 100644 --- a/runelite-api/src/main/java/net/runelite/api/Projectile.java +++ b/runelite-api/src/main/java/net/runelite/api/Projectile.java @@ -25,7 +25,7 @@ package net.runelite.api; /** - * Represents a projectile entity (ie. cannonball, arrow). + * Represents a projectile entity. (ie. cannonball, arrow) */ public interface Projectile extends Renderable { diff --git a/runelite-api/src/main/java/net/runelite/api/Tile.java b/runelite-api/src/main/java/net/runelite/api/Tile.java index 13b4a14bd7..46ada0f10e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Tile.java +++ b/runelite-api/src/main/java/net/runelite/api/Tile.java @@ -59,6 +59,13 @@ public interface Tile extends TileObject */ GroundObject getGroundObject(); + /** + * Sets the object on the ground layer of the tile. + * + * @param groundObject the ground object + */ + void setGroundObject(GroundObject groundObject); + /** * Gets the wall of the tile. * 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 a419be397e..f0901f473d 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -294,7 +294,7 @@ public enum Varbits TITHE_FARM_SACK_AMOUNT(4900), TITHE_FARM_SACK_ICON(5370), TITHE_FARM_POINTS(4893), - + /** * Blast Mine */ @@ -420,7 +420,7 @@ public enum Varbits /** * This varbit tracks how much bonemeal has been redeemed from Robin * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 - */ + */ DAILY_BONEMEAL_STATE(4543), DAILY_DYNAMITE_COLLECTED(7939), @@ -571,7 +571,7 @@ public enum Varbits EXPLORER_RING_ALCHS(4554), EXPLORER_RING_RUNENERGY(4553), - WINTERTODT_TIMER(7980), + /** * League relics @@ -607,10 +607,291 @@ public enum Varbits * * @see The OSRS Wiki's Minimap page */ - PVP_SPEC_ORB(8121); + PVP_SPEC_ORB(8121), + + //OPENOSRS + + /** + * Grand Exchange + */ + GRAND_EXCHANGE_PRICE_PER_ITEM(4398), + + /* + * Kharedst's Memoirs Teleport Item + */ + KHAREDSTS_MEMOIRS_CHARGES(6035), + + LMS_POISON_PROGRESS(5317), + + /** + * The y coordinate of the final safespace (world coord) + */ + LMS_SAFE_Y(5320), + + /** + * 1 is true, 0 is false. + */ + GAUNTLET_FINAL_ROOM_ENTERED(9177), + + /** + * 1 is true, 0 is false. + */ + GAUNTLET_ENTERED(9178), + + WITHDRAW_X_AMOUNT(3960), + + IN_PVP_AREA(8121), + + /** + * Value of hotkey varbits can be 0-13 + * 0 corresponds to no hotkey set + * 1-12 correspond to F1-F12 respectively + * 13 corresponds to escape + */ + COMBAT_TAB_HOTKEY(4675), + STATS_TAB_HOTKEY(4676), + QUESTS_TAB_HOTKEY(4677), + INVENTORY_TAB_HOTKEY(4678), + EQUIPMENT_TAB_HOTKEY(4679), + PRAYER_TAB_HOTKEY(4680), + SPELLBOOK_TAB_HOTKEY(4682), + FRIENDS_TAB_HOTKEY(4684), + ACCOUNT_MANAGEMENT_TAB_HOTKEY(6517), + LOGOUT_TAB_HOTKEY(4689), + OPTIONS_TAB_HOTKEY(4686), + EMOTES_TAB_HOTKEY(4687), + CLAN_TAB_HOTKEY(4683), + MUSIC_TAB_HOTKEY(4688), + + /** + * Chat Notifications settings + *
+ * LOOT_DROP_NOTIFICATIONS: 1 is true, 0 is false + * LOOT_DROP_NOTIFICATIONS_VALUE: gp value + * UNTRADEABLE_LOOT_NOTIFICATIONS: 1 is true, 0 is false + * BOSS_KILL_COUNT_UPDATES: 1 is filtered, 0 is unfiltered + * DROP_ITEM_WARNINGS: 1 is true, 0 is false + * DROP_ITEM_WARNINGS_VALUE: gp value + */ + LOOT_DROP_NOTIFICATIONS(5399), + LOOT_DROP_NOTIFICATIONS_VALUE(5400), + UNTRADEABLE_LOOT_NOTIFICATIONS(5402), + BOSS_KILL_COUNT_UPDATES(4930), + DROP_ITEM_WARNINGS(5411), + DROP_ITEM_WARNINGS_VALUE(5412), + /** + * Temple Trekking + */ + TREK_POINTS(1955), + TREK_STARTED(1956), + TREK_EVENT(1958), + TREK_STATUS(6719), + BLOAT_ENTERED_ROOM(6447), + + /** + * f2p Quest varbits, these don't hold the completion value. + */ + QUEST_DEMON_SLAYER(2561), + QUEST_GOBLIN_DIPLOMACY(2378), + QUEST_MISTHALIN_MYSTERY(3468), + QUEST_THE_CORSAIR_CURSE(6071), + QUEST_X_MARKS_THE_SPOT(8063), + QUEST_ERNEST_LEVER_A(1788), + QUEST_ERNEST_LEVER_B(1789), + QUEST_ERNEST_LEVER_C(1790), + QUEST_ERNEST_LEVER_D(1791), + QUEST_ERNEST_LEVER_E(1792), + QUEST_ERNEST_LEVER_F(1793), + + /** + * member Quest varbits, these don't hold the completion value. + */ + QUEST_ANIMAL_MAGNETISM(3185), + QUEST_BETWEEN_A_ROCK(299), + QUEST_CONTACT(3274), + QUEST_ZOGRE_FLESH_EATERS(487), + QUEST_DARKNESS_OF_HALLOWVALE(2573), + QUEST_DEATH_TO_THE_DORGESHUUN(2258), + QUEST_DESERT_TREASURE(358), + QUEST_DEVIOUS_MINDS(1465), + QUEST_EAGLES_PEAK(2780), + QUEST_ELEMENTAL_WORKSHOP_II(2639), + QUEST_ENAKHRAS_LAMENT(1560), + QUEST_ENLIGHTENED_JOURNEY(2866), + QUEST_THE_EYES_OF_GLOUPHRIE(2497), + QUEST_FAIRYTALE_I_GROWING_PAINS(1803), + QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326), + QUEST_THE_FEUD(334), // 14 = able to pickpocket + QUEST_FORGETTABLE_TALE(822), + QUEST_GARDEN_OF_TRANQUILLITY(961), + QUEST_GHOSTS_AHOY(217), + QUEST_THE_GIANT_DWARF(571), + QUEST_THE_GOLEM(346), + QUEST_HORROR_FROM_THE_DEEP(34), + QUEST_ICTHLARINS_LITTLE_HELPER(418), + QUEST_IN_AID_OF_THE_MYREQUE(1990), + QUEST_THE_LOST_TRIBE(532), + QUEST_LUNAR_DIPLOMACY(2448), + QUEST_MAKING_HISTORY(1383), + QUEST_MOUNTAIN_DAUGHTER(260), + QUEST_MOURNINGS_END_PART_II(1103), + QUEST_MY_ARMS_BIG_ADVENTURE(2790), + QUEST_RATCATCHERS(1404), + QUEST_RECIPE_FOR_DISASTER(1850), + QUEST_RECRUITMENT_DRIVE(657), + QUEST_ROYAL_TROUBLE(2140), + QUEST_THE_SLUG_MENACE(2610), + QUEST_SHADOW_OF_THE_STORM(1372), + QUEST_A_SOULS_BANE(2011), + QUEST_SPIRITS_OF_THE_ELID(1444), + QUEST_SWAN_SONG(2098), + QUEST_A_TAIL_OF_TWO_CATS(1028), + QUEST_TEARS_OF_GUTHIX(451), + QUEST_WANTED(1051), + QUEST_COLD_WAR(3293), + QUEST_THE_FREMENNIK_ISLES(3311), + QUEST_TOWER_OF_LIFE(3337), + QUEST_WHAT_LIES_BELOW(3523), + QUEST_OLAFS_QUEST(3534), + QUEST_ANOTHER_SLICE_OF_HAM(3550), + QUEST_DREAM_MENTOR(3618), + QUEST_GRIM_TALES(2783), + QUEST_KINGS_RANSOM(3888), + QUEST_MONKEY_MADNESS_II(5027), + QUEST_CLIENT_OF_KOUREND(5619), + QUEST_BONE_VOYAGE(5795), + QUEST_THE_QUEEN_OF_THIEVES(6037), + QUEST_THE_DEPTHS_OF_DESPAIR(6027), + QUEST_DRAGON_SLAYER_II(6104), + QUEST_TALE_OF_THE_RIGHTEOUS(6358), + QUEST_A_TASTE_OF_HOPE(6396), + QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528), + QUEST_THE_ASCENT_OF_ARCEUUS(7856), + QUEST_THE_FORSAKEN_TOWER(7796), + //TODO + QUEST_SONG_OF_THE_ELVES(7796), + + /** + * mini-quest varbits, these don't hold the completion value. + */ + QUEST_ARCHITECTURAL_ALLIANCE(4982), + QUEST_BEAR_YOUR_SOUL(5078), + QUEST_CURSE_OF_THE_EMPTY_LORD(821), + QUEST_ENCHANTED_KEY(1391), + QUEST_THE_GENERALS_SHADOW(3330), + QUEST_SKIPPY_AND_THE_MOGRES(1344), + QUEST_LAIR_OF_TARN_RAZORLOR(3290), + QUEST_FAMILY_PEST(5347), + QUEST_THE_MAGE_ARENA_II(6067), + //TODO + QUEST_IN_SEARCH_OF_KNOWLEDGE(6067), + + /** + * Spellbook filtering (1 = unfiltered, 0 = filtered) + */ + FILTER_SPELLBOOK(6718), + + /** + * POH Building mode (1 = yes, 0 = no) + */ + BUILDING_MODE(2176), + + WINTERTODT_TIMER(7980), + + /** + * 1 if in game, 0 if not + */ + LMS_IN_GAME(5314), + + /** + * Amount of pvp kills in current game + */ + LMS_KILLS(5315), + + /** + * The x coordinate of the final safespace (world coord) + */ + LMS_SAFE_X(5316), + + /** + * Locked Prayers + * 0-7 = Locked + * 8 = Unlocked + */ + CHIVPIETY_UNLOCKED(3909), + + /** + * Locked Prayers + * 0 = Locked + * 1 = Unlocked + */ + + RIGOUR_UNLOCKED(5451), + AUGURY_UNLOCKED(5452), + PRESERVE_UNLOCKED(5453), + + /** + * Spells being auto-casted + */ + AUTO_CAST_SPELL(276), + + /** + * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating + */ + BLOAT_DOOR(6447), + + /** + * Theatre of Blood orb varbits each number stands for the player's health on a scale of 1-27 (I think), 0 hides the orb + */ + THEATRE_OF_BLOOD_ORB_1(6442), + THEATRE_OF_BLOOD_ORB_2(6443), + THEATRE_OF_BLOOD_ORB_3(6444), + THEATRE_OF_BLOOD_ORB_4(6445), + THEATRE_OF_BLOOD_ORB_5(6446), + + //NMZ + NMZ_OVERLOAD(3955), + + //Pyramid Plunder + PYRAMID_PLUNDER_SARCO_OPEN(2362), + PYRAMID_PLUNDER_CHEST_OPEN(2363), + + /** + * Varbit used for Slayer reward points + */ + SLAYER_REWARD_POINTS(4068), + + /** + * 0 = standard + * 1 = ancients + * 2 = lunars + * 3 = arrceus + **/ + SPELLBOOK(4070), + + /** + * Bank settings/flags + **/ + BANK_NOTE_FLAG(3958), + + KINGDOM_WORKERS_WOOD(81), + KINGDOM_WORKERS_HERBS(82), + KINGDOM_WORKERS_FISHING(83), + KINGDOM_WORKERS_MINING(84), + KINGDOM_WORKERS_FISH_COOKED_BUTTON(135), // 0 - Raw, 1 - Cooked + KINGDOM_WORKERS_HARDWOOD(2131), + KINGDOM_WORKERS_FARM(2132), + KINGDOM_WORKERS_HARDWOOD_BUTTON(2133), // 0 - Mahogany, 1 - Teak, 2 - Both + KINGDOM_WORKERS_HERBS_BUTTON(2134), // 0 - Herbs, 1 - Flax + + /** + * In the Wilderness + */ + IN_THE_WILDERNESS(5963), + ; /** * The raw varbit ID. */ private final int id; -} +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java index 2b4db1ce3a..80a11edc30 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java @@ -56,6 +56,10 @@ public class MenuOptionClicked extends MenuEntry this.mouseButton = mouseButton; } + /** + * The selected item index at the time of the option click. + */ + private int selectedItemIndex; /** * Whether or not the event has been consumed by a subscriber. */ diff --git a/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java b/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java index 8976298faf..3b641e27e6 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java +++ b/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java @@ -27,7 +27,7 @@ package net.runelite.api.events; import net.runelite.api.Client; /** - * Posted when the game world the client wants to connect to has changed + * Posted when the game world the client wants to connect to has changed. * This is posted after the world ID and type have updated, but before a new * connection is established * 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 2df9dcc2b6..fed35c6c11 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 @@ -164,6 +164,20 @@ public class WidgetID public static final int DUEL_INVENTORY_GROUP_ID = 421; public static final int DUEL_INVENTORY_OTHER_GROUP_ID = 481; public static final int TRAILBLAZER_AREAS_GROUP_ID = 512; + public static final int DIALOG_MINIGAME_GROUP_ID = 229; + public static final int PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID = 243; + public static final int GAUNTLET_MAP_GROUP_ID = 638; + public static final int PLAYER_TRADE_CONFIRM_GROUP_ID = 334; + public static final int OPTIONS_GROUP_ID = 261; + public static final int JEWELLERY_BOX_GROUP_ID = 590; + public static final int EQUIPMENT_PAGE_GROUP_ID = 84; + public static final int QUESTTAB_GROUP_ID = 629; + public static final int MUSICTAB_GROUP_ID = 239; + public static final int FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID = 608; + public static final int THEATRE_OF_BLOOD_PARTY_GROUP_ID = 28; + public static final int DIALOG_NOTIFICATION_GROUP_ID = 229; + public static final int DIALOG_SPRITE2_ID = 11; + public static final int MULTISKILL_MENU_GROUP_ID = 270; static class WorldMap { @@ -197,12 +211,18 @@ public class WidgetID static class PestControlBoat { static final int INFO = 3; + + static final int NEXT_DEPARTURE = 4; + static final int PLAYERS_READY = 5; + static final int POINTS = 6; } static class PestControl { static final int INFO = 3; + static final int TIME = 6; + static final int ACTIVITY_BAR = 12; static final int ACTIVITY_PROGRESS = 14; @@ -269,6 +289,8 @@ public class WidgetID static final int TAB_CONTAINER = 10; static final int ITEM_CONTAINER = 12; static final int SCROLLBAR = 13; + static final int UNNOTED_BUTTON = 21; + static final int NOTED_BUTTON = 23; static final int SEARCH_BUTTON_BACKGROUND = 39; static final int DEPOSIT_INVENTORY = 41; static final int DEPOSIT_EQUIPMENT = 43; @@ -285,6 +307,14 @@ public class WidgetID static final int WINDOW_BORDERS = 2; static final int HISTORY_BUTTON = 3; static final int BACK_BUTTON = 4; + static final int OFFER1 = 7; + static final int OFFER2 = 8; + static final int OFFER3 = 9; + static final int OFFER4 = 10; + static final int OFFER5 = 11; + static final int OFFER6 = 12; + static final int OFFER7 = 13; + static final int OFFER8 = 14; static final int OFFER_CONTAINER = 24; static final int OFFER_DESCRIPTION = 25; static final int OFFER_PRICE = 26; @@ -303,12 +333,47 @@ public class WidgetID static class Shop { + static final int ITEMS_CONTAINER = 2; static final int INVENTORY_ITEM_CONTAINER = 0; } static class Smithing { static final int INVENTORY_ITEM_CONTAINER = 0; + + static final int QTY_1 = 3; + static final int QTY_5 = 4; + static final int QTY_10 = 5; + static final int QTY_X = 6; + static final int QTY_ALL = 7; + + static final int DAGGER = 9; + static final int SWORD = 10; + static final int SCIMITAR = 11; + static final int LONG_SWORD = 12; + static final int TWO_H_SWORD = 13; + static final int AXE = 14; + static final int MACE = 15; + static final int WARHAMMER = 16; + static final int BATTLE_AXE = 17; + static final int CLAWS = 18; + static final int CHAIN_BODY = 19; + static final int PLATE_LEGS = 20; + static final int PLATE_SKIRT = 21; + static final int PLATE_BODY = 22; + static final int NAILS = 23; + static final int MED_HELM = 24; + static final int FULL_HELM = 25; + static final int SQ_SHIELD = 26; + static final int KITE_SHIELD = 27; + static final int EXCLUSIVE1 = 28; + static final int DART_TIPS = 29; + static final int ARROW_HEADS = 30; + static final int KNIVES = 31; + static final int EXCLUSIVE2 = 32; + static final int JAVELIN_HEADS = 33; + static final int BOLTS = 34; + static final int LIMBS = 35; } static class GuidePrices @@ -319,6 +384,17 @@ public class WidgetID static class Equipment { + static final int HELMET = 14; + static final int CAPE = 15; + static final int AMULET = 16; + static final int WEAPON = 17; + static final int BODY = 18; + static final int SHIELD = 19; + static final int LEGS = 20; + static final int GLOVES = 21; + static final int BOOTS = 22; + static final int RING = 23; + static final int AMMO = 24; static final int INVENTORY_ITEM_CONTAINER = 0; } @@ -346,6 +422,7 @@ public class WidgetID static final int TOGGLE_RUN_ORB = 22; // Has the "Toggle run" name static final int RUN_ORB_TEXT = 23; static final int SPEC_ORB = 28; + static final int SPEC_CLICKBOX = 30; static final int WORLDMAP_ORB = 41; static final int WIKI_BANNER = 43; } @@ -582,6 +659,9 @@ public class WidgetID static final int SPELL_ICON = 28; static final int SPELL_TEXT = 29; static final int AUTO_RETALIATE = 30; + static final int SPECIAL_ATTACK_BAR = 34; + static final int SPECIAL_ATTACK_CLICKBOX = 36; + static final int TOOLTIP = 41; } static class VolcanicMine @@ -608,7 +688,6 @@ public class WidgetID static final int ROLE_SPRITE = 12; static final int ROLE = 13; } - static class HLR { static final int TEAMMATE1 = 19; @@ -616,7 +695,32 @@ public class WidgetID static final int TEAMMATE3 = 27; static final int TEAMMATE4 = 31; } - + static class HORN_GLORY + { + static final int ATTACKER = 5; + static final int DEFENDER = 6; + static final int COLLECTOR = 7; + static final int HEALER = 8; + } + static class REWARD_VALUES + { + static final int RUNNERS_PASSED = 14; + static final int HITPOINTS_REPLENISHED = 19; + static final int WRONG_POISON_PACKS_USED = 20; + static final int EGGS_COLLECTED = 21; + static final int FAILED_ATTACKER_ATTACKS = 22; + static final int RUNNERS_PASSED_POINTS = 24; + static final int RANGERS_KILLED = 25; + static final int FIGHTERS_KILLED = 26; + static final int HEALERS_KILLED = 27; + static final int RUNNERS_KILLED = 28; + static final int HITPOINTS_REPLENISHED_POINTS = 29; + static final int WRONG_POISON_PACKS_USED_POINTS = 30; + static final int EGGS_COLLECTED_POINTS = 31; + static final int FAILED_ATTACKER_ATTACKS_POINTS = 32; + static final int BASE_POINTS = 33; + static final int HONOUR_POINTS_REWARD = 49; + } static final int ROLE_SPRITE = 11; static final int ROLE = 12; @@ -632,6 +736,7 @@ public class WidgetID { static final int SKILL = 1; static final int LEVEL = 2; + static final int CONTINUE = 3; } static class QuestCompleted @@ -671,6 +776,7 @@ public class WidgetID static final int LIGHT_BOX = 1; static final int LIGHT_BOX_WINDOW = 2; static final int LIGHT_BULB_CONTAINER = 3; + static final int LIGHT_BOX_BUTTON_CONTAINER = 6; static final int BUTTON_A = 8; static final int BUTTON_B = 9; static final int BUTTON_C = 10; @@ -756,7 +862,9 @@ public class WidgetID static class WorldSwitcher { + static final int CONTAINER = 1; static final int WORLD_LIST = 16; + static final int LOGOUT_BUTTON = 23; } static class FossilOxygen @@ -792,6 +900,10 @@ public class WidgetID static class Pvp { + static final int FOG_OVERLAY = 1; + 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 = 6; static final int KILLDEATH_RATIO = 28; static final int SKULL_CONTAINER = 48; @@ -929,9 +1041,28 @@ public class WidgetID static final int CONTAINER = 2; } + // Also used for many other interfaces! static class BankPin { static final int CONTAINER = 0; + static final int TOP_LEFT_TEXT = 2; + static final int FIRST_ENTERED = 3; + static final int SECOND_ENTERED = 4; + static final int THIRD_ENTERED = 5; + static final int FOURTH_ENTERED = 6; + static final int INSTRUCTION_TEXT = 10; + static final int EXIT_BUTTON = 13; + static final int FORGOT_BUTTON = 15; + static final int BUTTON_1 = 16; + static final int BUTTON_2 = 18; + static final int BUTTON_3 = 20; + static final int BUTTON_4 = 22; + static final int BUTTON_5 = 24; + static final int BUTTON_6 = 26; + static final int BUTTON_7 = 28; + static final int BUTTON_8 = 30; + static final int BUTTON_9 = 32; + static final int BUTTON_10 = 34; } static class EncounterHealthBar @@ -943,4 +1074,334 @@ public class WidgetID { static final int TELEPORT = 59; } + + + static class DialogPlayer + { + static final int HEAD_MODEL = 1; + static final int NAME = 2; + static final int CONTINUE = 3; + static final int TEXT = 4; + } + + static class DialogNotification + { + static final int TEXT = 0; + static final int CONTINUE = 1; + } + + static class DialogOption + { + static final int TEXT = 0; + static final int OPTION1 = 1; + static final int OPTION2 = 2; + static final int OPTION3 = 3; + static final int OPTION4 = 4; + static final int OPTION5 = 5; + } + + static class PestControlExchangeWindow + { + static final int ITEM_LIST = 2; + static final int BOTTOM = 5; + static final int POINTS = 8; + static final int CONFIRM_BUTTON = 6; + } + + static class MinigameDialog + { + static final int TEXT = 1; + static final int CONTINUE = 2; + } + + static class TheatreOfBlood + { + static final int RAIDING_PARTY = 9; + static final int ORB_BOX = 10; + static final int BOSS_HEALTH_BAR = 35; + } + + static class TheatreOfBloodParty + { + static final int CONTAINER = 10; + } + + static class EquipmentWidgetIdentifiers + { + static final int EQUIP_YOUR_CHARACTER = 3; + static final int STAB_ATTACK_BONUS = 24; + static final int SLASH_ATTACK_BONUS = 25; + static final int CRUSH_ATTACK_BONUS = 26; + static final int MAGIC_ATTACK_BONUS = 27; + static final int RANGED_ATTACK_BONUS = 28; + static final int STAB_DEFENCE_BONUS = 30; + static final int SLASH_DEFENCE_BONUS = 31; + static final int CRUSH_DEFENCE_BONUS = 32; + static final int MAGIC_DEFENCE_BONUS = 33; + static final int RANGED_DEFENCE_BONUS = 34; + static final int MELEE_STRENGTH = 36; + static final int RANGED_STRENGTH = 37; + static final int MAGIC_DAMAGE = 38; + static final int PRAYER_BONUS = 39; + static final int UNDEAD_DAMAGE_BONUS = 41; + static final int SLAYER_DAMAGE_BONUS = 42; + static final int WEIGHT = 49; + } + + static class FossilMushroomTeleport + { + static final int ROOT = 2; + static final int HOUSE_ON_HILL = 4; + static final int VERDANT_VALLEY = 8; + static final int SWAMP = 12; + static final int MUSHROOM_MEADOW = 16; + } + + static class SpellBook + { + static final int FILTERED_SPELLS_BOUNDS = 3; + static final int TOOLTIP = 189; + + // NORMAL SPELLS + static final int LUMBRIDGE_HOME_TELEPORT = 5; + static final int WIND_STRIKE = 6; + static final int CONFUSE = 7; + static final int ENCHANT_CROSSBOW_BOLT = 8; + static final int WATER_STRIKE = 9; + static final int LVL_1_ENCHANT = 10; + static final int EARTH_STRIKE = 11; + static final int WEAKEN = 12; + static final int FIRE_STRIKE = 13; + static final int BONES_TO_BANANAS = 14; + static final int WIND_BOLT = 15; + static final int CURSE = 16; + static final int BIND = 17; + static final int LOW_LEVEL_ALCHEMY = 18; + static final int WATER_BOLT = 19; + static final int VARROCK_TELEPORT = 20; + static final int LVL_2_ENCHANT = 21; + static final int EARTH_BOLT = 22; + static final int LUMBRIDGE_TELEPORT = 23; + static final int TELEKINETIC_GRAB = 24; + static final int FIRE_BOLT = 25; + static final int FALADOR_TELEPORT = 26; + static final int CRUMBLE_UNDEAD = 27; + static final int TELEPORT_TO_HOUSE = 28; + static final int WIND_BLAST = 29; + static final int SUPERHEAT_ITEM = 30; + static final int CAMELOT_TELEPORT = 31; + static final int WATER_BLAST = 32; + static final int LVL_3_ENCHANT = 33; + static final int IBAN_BLAST = 34; + static final int SNARE = 35; + static final int MAGIC_DART = 36; + static final int ARDOUGNE_TELEPORT = 37; + static final int EARTH_BLAST = 38; + static final int HIGH_LEVEL_ALCHEMY = 39; + static final int CHARGE_WATER_ORB = 40; + static final int LVL_4_ENCHANT = 41; + static final int WATCHTOWER_TELEPORT = 42; + static final int FIRE_BLAST = 43; + static final int CHARGE_EARTH_ORB = 44; + static final int BONES_TO_PEACHES = 45; + static final int SARADOMIN_STRIKE = 46; + static final int CLAWS_OF_GUTHIX = 47; + static final int FLAMES_OF_ZAMORAK = 48; + static final int TROLLHEIM_TELEPORT = 49; + static final int WIND_WAVE = 50; + static final int CHARGE_FIRE_ORB = 51; + static final int TELEPORT_TO_APE_ATOLL = 52; + static final int WATER_WAVE = 53; + static final int CHARGE_AIR_ORB = 54; + static final int VULNERABILITY = 55; + static final int LVL_5_ENCHANT = 56; + static final int TELEPORT_TO_KOUREND = 57; + static final int EARTH_WAVE = 58; + static final int ENFEEBLE = 59; + static final int TELEOTHER_LUMBRIDGE = 60; + static final int FIRE_WAVE = 61; + static final int ENTANGLE = 62; + static final int STUN = 63; + static final int CHARGE = 64; + static final int WIND_SURGE = 65; + static final int TELEOTHER_FALADOR = 66; + static final int WATER_SURGE = 67; + static final int TELE_BLOCK = 68; + static final int BOUNTY_TARGET_TELEPORT = 69; + static final int LVL_6_ENCHANT = 70; + static final int TELEOTHER_CAMELOT = 71; + static final int EARTH_SURGE = 72; + static final int LVL_7_ENCHANT = 73; + static final int FIRE_SURGE = 74; + + // ANCIENT SPELLS + static final int ICE_RUSH = 75; + static final int ICE_BLITZ = 76; + static final int ICE_BURST = 77; + static final int ICE_BARRAGE = 78; + static final int BLOOD_RUSH = 79; + static final int BLOOD_BLITZ = 80; + static final int BLOOD_BURST = 81; + static final int BLOOD_BARRAGE = 82; + static final int SMOKE_RUSH = 83; + static final int SMOKE_BLITZ = 84; + static final int SMOKE_BURST = 85; + static final int SMOKE_BARRAGE = 86; + static final int SHADOW_RUSH = 87; + static final int SHADOW_BLITZ = 88; + static final int SHADOW_BURST = 89; + static final int SHADOW_BARRAGE = 90; + static final int PADDEWWA_TELEPORT = 91; + static final int SENNTISTEN_TELEPORT = 92; + static final int KHARYRLL_TELEPORT = 93; + static final int LASSAR_TELEPORT = 94; + static final int DAREEYAK_TELEPORT = 95; + static final int CARRALLANGER_TELEPORT = 96; + static final int ANNAKARL_TELEPORT = 97; + static final int GHORROCK_TELEPORT = 98; + static final int EDGEVILLE_HOME_TELEPORT = 99; + + // LUNAR SPELLS + static final int LUNAR_HOME_TELEPORT = 100; + static final int BAKE_PIE = 101; + static final int CURE_PLANT = 102; + static final int MONSTER_EXAMINE = 103; + static final int NPC_CONTACT = 104; + static final int CURE_OTHER = 105; + static final int HUMIDIFY = 106; + static final int MOONCLAN_TELEPORT = 107; + static final int TELE_GROUP_MOONCLAN = 108; + static final int CURE_ME = 109; + static final int HUNTER_KIT = 110; + static final int WATERBIRTH_TELEPORT = 111; + static final int TELE_GROUP_WATERBIRTH = 112; + static final int CURE_GROUP = 113; + static final int STAT_SPY = 114; + static final int BARBARIAN_TELEPORT = 115; + static final int TELE_GROUP_BARBARIAN = 116; + static final int SUPERGLASS_MAKE = 117; + static final int TAN_LEATHER = 118; + static final int KHAZARD_TELEPORT = 119; + static final int TELE_GROUP_KHAZARD = 120; + static final int DREAM = 121; + static final int STRING_JEWELLERY = 122; + static final int STAT_RESTORE_POT_SHARE = 123; + static final int MAGIC_IMBUE = 124; + static final int FERTILE_SOIL = 125; + static final int BOOST_POTION_SHARE = 126; + static final int FISHING_GUILD_TELEPORT = 127; + static final int TELE_GROUP_FISHING_GUILD = 128; + static final int PLANK_MAKE = 129; + static final int CATHERBY_TELEPORT = 130; + static final int TELE_GROUP_CATHERBY = 131; + static final int RECHARGE_DRAGONSTONE = 132; + static final int ICE_PLATEAU_TELEPORT = 133; + static final int TELE_GROUP_ICE_PLATEAU = 134; + static final int ENERGY_TRANSFER = 135; + static final int HEAL_OTHER = 136; + static final int VENGEANCE_OTHER = 137; + static final int VENGEANCE = 138; + static final int HEAL_GROUP = 139; + static final int SPELLBOOK_SWAP = 140; + static final int GEOMANCY = 141; + static final int SPIN_FLAX = 142; + static final int OURANIA_TELEPORT = 143; + + // ARCEUUS SPELLS + static final int ARCEUUS_HOME_TELEPORT = 144; + static final int BATTLEFRONT_TELEPORT = 179; + // HEADS + static final int REANIMATE_GOBLIN = 145; + static final int REANIMATE_MONKEY = 147; + static final int REANIMATE_IMP = 148; + static final int REANIMATE_MINOTAUR = 149; + static final int REANIMATE_SCORPION = 151; + static final int REANIMATE_BEAR = 152; + static final int REANIMATE_UNICORN = 153; + static final int REANIMATE_DOG = 154; + static final int REANIMATE_CHAOS_DRUID = 156; + static final int REANIMATE_GIANT = 158; + static final int REANIMATE_OGRE = 160; + static final int REANIMATE_ELF = 161; + static final int REANIMATE_TROLL = 162; + static final int REANIMATE_HORROR = 164; + static final int REANIMATE_KALPHITE = 165; + static final int REANIMATE_DAGANNOTH = 167; + static final int REANIMATE_BLOODVELD = 168; + static final int REANIMATE_TZHAAR = 170; + static final int REANIMATE_DEMON = 172; + static final int REANIMATE_AVIANSIE = 173; + static final int REANIMATE_ABYSSAL = 176; + static final int REANIMATE_DRAGON = 178; + + } + + static class DialogSprite2 + { + static final int SPRITE1 = 1; + static final int TEXT = 2; + static final int SPRITE2 = 3; + static final int CONTINUE = 4; + } + + static class QuestTab + { + static final int QUEST_TAB = 3; + } + + public static class TradeScreen + { + public static final int FIRST_TRADING_WITH = 31; + public static final int SECOND_ACCEPT_FUNC = 13; + public static final int SECOND_DECLINE_FUNC = 14; + public static final int SECOND_MY_OFFER = 23; + public static final int SECOND_THEIR_OFFER = 24; + public static final int SECOND_ACCEPT_TEXT = 25; + public static final int SECOND_DECLINE_TEXT = 26; + public static final int SECOND_MY_ITEMS = 28; + public static final int SECOND_THEIR_ITEMS = 29; + public static final int SECOND_TRADING_WITH = 30; + } + + public static class DuelConfig + { + public static final int CONFIG_GROUP_IP = 482; + public static final int TITLE = 35; + public static final int OPPONENT_ATT = 9; + public static final int OPPONENT_STR = 13; + public static final int OPPONENT_DEF = 17; + public static final int OPPONENT_HP = 21; + } + + public static class DuelResult + { + public static final int RESULT_GROUP_ID = 372; + public static final int TITLE = 16; + public static final int TOTAL_STAKED = 32; + public static final int TOTAL_TAX = 39; + public static final int WINNINGS = 40; + } + + static class JewelBox + { + static final int DUEL_RING = 2; + static final int GAME_NECK = 3; + static final int COMB_BRAC = 4; + static final int SKIL_NECK = 5; + static final int RING_OFGP = 6; + static final int AMUL_GLOR = 7; // yes + } + + static class Options + { + static final int CAMERA_ZOOM_SLIDER_HANDLE = 15; + static final int MUSIC_SLIDER = 37; + static final int SOUND_EFFECT_SLIDER = 43; + static final int AREA_SOUND_SLIDER = 49; + } + + static class GauntletMap + { + static final int CONTAINER = 4; + } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 123a118843..34ef03e1bb 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -538,6 +538,403 @@ public enum WidgetInfo MULTICOMBAT_FIXED(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.MULTICOMBAT_INDICATOR), MULTICOMBAT_RESIZEABLE_MODERN(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), MULTICOMBAT_RESIZEABLE_CLASSIC(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), + + //OpenOSRS + WORLD_MAP_BUTTON_BORDER(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), + + EQUIPMENT_HELMET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.HELMET), + EQUIPMENT_CAPE(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.CAPE), + EQUIPMENT_AMULET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMULET), + EQUIPMENT_WEAPON(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.WEAPON), + EQUIPMENT_BODY(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BODY), + EQUIPMENT_SHIELD(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.SHIELD), + EQUIPMENT_LEGS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.LEGS), + EQUIPMENT_GLOVES(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.GLOVES), + EQUIPMENT_BOOTS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BOOTS), + EQUIPMENT_RING(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.RING), + EQUIPMENT_AMMO(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMMO), + + MINIGAME_DIALOG(WidgetID.DIALOG_MINIGAME_GROUP_ID, 0), + MINIGAME_DIALOG_TEXT(WidgetID.DIALOG_MINIGAME_GROUP_ID, WidgetID.MinigameDialog.TEXT), + MINIGAME_DIALOG_CONTINUE(WidgetID.DIALOG_MINIGAME_GROUP_ID, WidgetID.MinigameDialog.CONTINUE), + PEST_CONTROL_EXCHANGE_WINDOW(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, 0), + PEST_CONTROL_EXCHANGE_WINDOW_POINTS(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, WidgetID.PestControlExchangeWindow.POINTS), + + PEST_CONTROL_BOAT_INFO_POINTS(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.POINTS), + PEST_CONTROL_INFO_TIME(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.TIME), + + BANK_UNNOTED_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.UNNOTED_BUTTON), + BANK_NOTED_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.NOTED_BUTTON), + + GRAND_EXCHANGE_HISTORY_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.HISTORY_BUTTON), + GRAND_EXCHANGE_BACK_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.BACK_BUTTON), + GRAND_EXCHANGE_OFFER1(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER1), + GRAND_EXCHANGE_OFFER2(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER2), + GRAND_EXCHANGE_OFFER3(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER3), + GRAND_EXCHANGE_OFFER4(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER4), + GRAND_EXCHANGE_OFFER5(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER5), + GRAND_EXCHANGE_OFFER6(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER6), + GRAND_EXCHANGE_OFFER7(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER7), + GRAND_EXCHANGE_OFFER8(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER8), + + GRAND_EXCHANGE_OFFER_CONFIRM_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_CONFIRM_BUTTON), + + SMITHING_ANVIL_DAGGER(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.DAGGER), + SMITHING_ANVIL_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SWORD), + SMITHING_ANVIL_SCIMITAR(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SCIMITAR), + SMITHING_ANVIL_LONG_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.LONG_SWORD), + SMITHING_ANVIL_TWO_H_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.TWO_H_SWORD), + SMITHING_ANVIL_AXE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.AXE), + SMITHING_ANVIL_MACE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.MACE), + SMITHING_ANVIL_WARHAMMER(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.WARHAMMER), + SMITHING_ANVIL_BATTLE_AXE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.BATTLE_AXE), + SMITHING_ANVIL_CLAWS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.CLAWS), + SMITHING_ANVIL_CHAIN_BODY(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.CHAIN_BODY), + SMITHING_ANVIL_PLATE_LEGS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_LEGS), + SMITHING_ANVIL_PLATE_SKIRT(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_SKIRT), + SMITHING_ANVIL_PLATE_BODY(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_BODY), + SMITHING_ANVIL_NAILS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.NAILS), + SMITHING_ANVIL_MED_HELM(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.MED_HELM), + SMITHING_ANVIL_FULL_HELM(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.FULL_HELM), + SMITHING_ANVIL_SQ_SHIELD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SQ_SHIELD), + SMITHING_ANVIL_KITE_SHIELD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.KITE_SHIELD), + SMITHING_ANVIL_DART_TIPS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.DART_TIPS), + SMITHING_ANVIL_ARROW_HEADS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.ARROW_HEADS), + SMITHING_ANVIL_KNIVES(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.KNIVES), + SMITHING_ANVIL_JAVELIN_HEADS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.JAVELIN_HEADS), + SMITHING_ANVIL_BOLTS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.BOLTS), + SMITHING_ANVIL_LIMBS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.LIMBS), + SMITHING_ANVIL_EXCLUSIVE1(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.EXCLUSIVE1), + SMITHING_ANVIL_EXCLUSIVE2(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.EXCLUSIVE2), + + MINIMAP_SPEC_CLICKBOX(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.SPEC_CLICKBOX), + + MINIMAP_WORLD_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), + + RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.SPELL_TAB), + + COMBAT_WEAPON(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.WEAPON_NAME), + + COMBAT_SPECIAL_ATTACK(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPECIAL_ATTACK_BAR), + COMBAT_SPECIAL_ATTACK_CLICKBOX(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPECIAL_ATTACK_CLICKBOX), + COMBAT_TOOLTIP(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.TOOLTIP), + + MULTI_SKILL_MENU(WidgetID.MULTISKILL_MENU_GROUP_ID, 0), + + DIALOG2_SPRITE(WidgetID.DIALOG_SPRITE2_ID, 0), + DIALOG2_SPRITE_SPRITE1(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.SPRITE1), + DIALOG2_SPRITE_SPRITE2(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.SPRITE2), + DIALOG2_SPRITE_TEXT(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.TEXT), + DIALOG2_SPRITE_CONTINUE(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.CONTINUE), + + DIALOG_PLAYER_NAME(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.NAME), + DIALOG_PLAYER_TEXT(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.TEXT), + DIALOG_PLAYER_HEAD_MODEL(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.HEAD_MODEL), + DIALOG_PLAYER_CONTINUE(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.CONTINUE), + + DIALOG_NOTIFICATION_TEXT(WidgetID.DIALOG_NOTIFICATION_GROUP_ID, WidgetID.DialogNotification.TEXT), + DIALOG_NOTIFICATION_CONTINUE(WidgetID.DIALOG_NOTIFICATION_GROUP_ID, WidgetID.DialogNotification.CONTINUE), + + DIALOG_OPTION_TEXT(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.TEXT), + DIALOG_OPTION_OPTION1(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION1), + DIALOG_OPTION_OPTION2(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION2), + DIALOG_OPTION_OPTION3(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION3), + DIALOG_OPTION_OPTION4(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION4), + DIALOG_OPTION_OPTION5(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION5), + + BA_RUNNERS_PASSED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_PASSED), + BA_HITPOINTS_REPLENISHED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HITPOINTS_REPLENISHED), + BA_WRONG_POISON_PACKS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.WRONG_POISON_PACKS_USED), + BA_EGGS_COLLECTED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.EGGS_COLLECTED), + BA_FAILED_ATTACKER_ATTACKS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FAILED_ATTACKER_ATTACKS), + BA_RUNNERS_PASSED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_PASSED_POINTS), + BA_RANGERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RANGERS_KILLED), + BA_FIGHTERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FIGHTERS_KILLED), + BA_HEALERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HEALERS_KILLED), + BA_RUNNERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_KILLED), + BA_HITPOINTS_REPLENISHED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HITPOINTS_REPLENISHED_POINTS), + BA_WRONG_POISON_PACKS_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.WRONG_POISON_PACKS_USED_POINTS), + BA_EGGS_COLLECTED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.EGGS_COLLECTED_POINTS), + BA_FAILED_ATTACKER_ATTACKS_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FAILED_ATTACKER_ATTACKS_POINTS), + BA_HONOUR_POINTS_REWARD(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HONOUR_POINTS_REWARD), + BA_BASE_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.BASE_POINTS), + + LEVEL_UP_CONTINUE(WidgetID.LEVEL_UP_GROUP_ID, WidgetID.LevelUp.CONTINUE), + + THEATRE_OF_BLOOD_PARTY(WidgetID.THEATRE_OF_BLOOD_PARTY_GROUP_ID, WidgetID.TheatreOfBloodParty.CONTAINER), + + LIGHT_BOX_BUTTON_CONTAINER(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BOX_BUTTON_CONTAINER), + + THEATRE_OF_BLOOD_HEALTH_ORBS(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.ORB_BOX), + THEATRE_OF_BLOOD_BOSS_HEALTH(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.BOSS_HEALTH_BAR), + THEATRE_OF_BLOOD_RAIDING_PARTY(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.RAIDING_PARTY), + + WORLD_SWITCHER_CONTAINER(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.CONTAINER), + + WORLD_SWITCHER_LOGOUT_BUTTON(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.LOGOUT_BUTTON), + + FOSSIL_MUSHROOM_TELEPORT(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.ROOT), + FOSSIL_MUSHROOM_HOUSE(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.HOUSE_ON_HILL), + FOSSIL_MUSHROOM_VALLEY(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.VERDANT_VALLEY), + FOSSIL_MUSHROOM_SWAMP(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.SWAMP), + FOSSIL_MUSHROOM_MEADOW(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.MUSHROOM_MEADOW), + + PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL), + PVP_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), + + SPELLBOOK(WidgetID.SPELLBOOK_GROUP_ID, 0), + SPELLBOOK_FILTERED_BOUNDS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FILTERED_SPELLS_BOUNDS), + + /* STANDARD SPELL BOOK WIDGETS*/ + SPELL_WIND_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_STRIKE), + SPELL_CONFUSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CONFUSE), + SPELL_ENCHANT_CROSSBOW_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENCHANT_CROSSBOW_BOLT), + SPELL_WATER_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_STRIKE), + SPELL_LVL_1_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_1_ENCHANT), + SPELL_EARTH_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_STRIKE), + SPELL_WEAKEN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WEAKEN), + SPELL_FIRE_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_STRIKE), + SPELL_BONES_TO_BANANAS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BONES_TO_BANANAS), + SPELL_WIND_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_BOLT), + SPELL_CURSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURSE), + SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BIND), + SPELL_LOW_LEVEL_ALCHEMY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LOW_LEVEL_ALCHEMY), + SPELL_WATER_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_BOLT), + SPELL_VARROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VARROCK_TELEPORT), + SPELL_LVL_2_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_2_ENCHANT), + SPELL_EARTH_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_BOLT), + SPELL_LUMBRIDGE_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUMBRIDGE_TELEPORT), + SPELL_TELEKINETIC_GRAB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEKINETIC_GRAB), + SPELL_FIRE_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_BOLT), + SPELL_FALADOR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FALADOR_TELEPORT), + SPELL_CRUMBLE_UNDEAD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CRUMBLE_UNDEAD), + SPELL_TELEPORT_TO_HOUSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_HOUSE), + SPELL_WIND_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_BLAST), + SPELL_SUPERHEAT_ITEM(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SUPERHEAT_ITEM), + SPELL_CAMELOT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CAMELOT_TELEPORT), + SPELL_WATER_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_BLAST), + SPELL_LVL_3_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_3_ENCHANT), + SPELL_IBAN_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.IBAN_BLAST), + SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SNARE), + SPELL_MAGIC_DART(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MAGIC_DART), + SPELL_ARDOUGNE_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARDOUGNE_TELEPORT), + SPELL_EARTH_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_BLAST), + SPELL_HIGH_LEVEL_ALCHEMY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HIGH_LEVEL_ALCHEMY), + SPELL_CHARGE_WATER_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_WATER_ORB), + SPELL_LVL_4_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_4_ENCHANT), + SPELL_WATCHTOWER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATCHTOWER_TELEPORT), + SPELL_FIRE_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_BLAST), + SPELL_CHARGE_EARTH_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_EARTH_ORB), + SPELL_BONES_TO_PEACHES(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BONES_TO_PEACHES), + SPELL_SARADOMIN_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SARADOMIN_STRIKE), + SPELL_CLAWS_OF_GUTHIX(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CLAWS_OF_GUTHIX), + SPELL_FLAMES_OF_ZAMORAK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FLAMES_OF_ZAMORAK), + SPELL_TROLLHEIM_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TROLLHEIM_TELEPORT), + SPELL_WIND_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_WAVE), + SPELL_CHARGE_FIRE_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_FIRE_ORB), + SPELL_TELEPORT_TO_APE_ATOLL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_APE_ATOLL), + SPELL_WATER_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_WAVE), + SPELL_CHARGE_AIR_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_AIR_ORB), + SPELL_VULNERABILITY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VULNERABILITY), + SPELL_LVL_5_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_5_ENCHANT), + SPELL_TELEPORT_TO_KOUREND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_KOUREND), + SPELL_EARTH_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_WAVE), + SPELL_ENFEEBLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENFEEBLE), + SPELL_FIRE_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_WAVE), + SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENTANGLE), + SPELL_TELEOTHER_LUMBRIDGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_LUMBRIDGE), + SPELL_STUN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STUN), + SPELL_CHARGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE), + SPELL_WIND_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_SURGE), + SPELL_TELEOTHER_FALADOR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_FALADOR), + SPELL_WATER_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_SURGE), + SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_BLOCK), + SPELL_LVL_6_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_6_ENCHANT), + SPELL_TELEOTHER_CAMELOT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_CAMELOT), + SPELL_EARTH_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_SURGE), + SPELL_LVL_7_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_7_ENCHANT), + SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_SURGE), + SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), + /* END OF STANDARD SPELL BOOK WIDGETS*/ + + /* ANCIENT SPELL BOOK WIDGETS*/ + SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_RUSH), + SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BLITZ), + SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BURST), + SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BARRAGE), + SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_RUSH), + SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BLITZ), + SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BURST), + SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BARRAGE), + SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_RUSH), + SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BLITZ), + SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BURST), + SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BARRAGE), + SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_RUSH), + SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BLITZ), + SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BURST), + SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BARRAGE), + SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.PADDEWWA_TELEPORT), + SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SENNTISTEN_TELEPORT), + SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.KHARYRLL_TELEPORT), + SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LASSAR_TELEPORT), + SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.DAREEYAK_TELEPORT), + SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CARRALLANGER_TELEPORT), + SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ANNAKARL_TELEPORT), + SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.GHORROCK_TELEPORT), + SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), + /* END OF ANCIENT SPELL BOOK WIDGETS*/ + + /* LUNAR SPELL BOOK WIDGETS*/ + SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE_OTHER), + SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE), + SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), + SPELL_BAKE_PIE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BAKE_PIE), + SPELL_CURE_PLANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_PLANT), + SPELL_MONSTER_EXAMINE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MONSTER_EXAMINE), + SPELL_NPC_CONTACT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.NPC_CONTACT), + SPELL_CURE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_OTHER), + SPELL_HUMIDIFY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HUMIDIFY), + SPELL_MOONCLAN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MOONCLAN_TELEPORT), + SPELL_TELE_GROUP_MOONCLAN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_MOONCLAN), + SPELL_CURE_ME(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_ME), + SPELL_HUNTER_KIT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HUNTER_KIT), + SPELL_WATERBIRTH_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATERBIRTH_TELEPORT), + SPELL_TELE_GROUP_WATERBIRTH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_WATERBIRTH), + SPELL_CURE_GROUP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_GROUP), + SPELL_STAT_SPY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STAT_SPY), + SPELL_BARBARIAN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BARBARIAN_TELEPORT), + SPELL_TELE_GROUP_BARBARIAN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_BARBARIAN), + SPELL_SUPERGLASS_MAKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SUPERGLASS_MAKE), + SPELL_TAN_LEATHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TAN_LEATHER), + SPELL_KHAZARD_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.KHAZARD_TELEPORT), + SPELL_TELE_GROUP_KHAZARD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_KHAZARD), + SPELL_DREAM(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.DREAM), + SPELL_STRING_JEWELLERY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STRING_JEWELLERY), + SPELL_STAT_RESTORE_POT_SHARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STAT_RESTORE_POT_SHARE), + SPELL_MAGIC_IMBUE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MAGIC_IMBUE), + SPELL_FERTILE_SOIL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FERTILE_SOIL), + SPELL_BOOST_POTION_SHARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOOST_POTION_SHARE), + SPELL_FISHING_GUILD_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FISHING_GUILD_TELEPORT), + SPELL_TELE_GROUP_FISHING_GUILD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_FISHING_GUILD), + SPELL_PLANK_MAKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.PLANK_MAKE), + SPELL_CATHERBY_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CATHERBY_TELEPORT), + SPELL_TELE_GROUP_CATHERBY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_CATHERBY), + SPELL_RECHARGE_DRAGONSTONE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.RECHARGE_DRAGONSTONE), + SPELL_ICE_PLATEAU_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_PLATEAU_TELEPORT), + SPELL_TELE_GROUP_ICE_PLATEAU(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_ICE_PLATEAU), + SPELL_ENERGY_TRANSFER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENERGY_TRANSFER), + SPELL_HEAL_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HEAL_OTHER), + SPELL_HEAL_GROUP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HEAL_GROUP), + SPELL_SPELLBOOK_SWAP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SPELLBOOK_SWAP), + SPELL_GEOMANCY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.GEOMANCY), + SPELL_SPIN_FLAX(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SPIN_FLAX), + SPELL_OURANIA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.OURANIA_TELEPORT), + /* END OF LUNAR SPELL BOOK WIDGETS*/ + SPELL_TOOLTIP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TOOLTIP), + /* ARCEUUS SPELL BOOK WIDGETS*/ + SPELL_BATTLEFRONT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BATTLEFRONT_TELEPORT), + SPELL_REANIMATE_GOBLIN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_GOBLIN), + SPELL_REANIMATE_MONKEY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_MONKEY), + SPELL_REANIMATE_IMP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_IMP), + SPELL_REANIMATE_MINOTAUR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_MINOTAUR), + SPELL_REANIMATE_SCORPION(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_SCORPION), + SPELL_REANIMATE_BEAR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_BEAR), + SPELL_REANIMATE_UNICORN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_UNICORN), + SPELL_REANIMATE_DOG(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DOG), + SPELL_REANIMATE_CHAOS_DRUID(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_CHAOS_DRUID), + SPELL_REANIMATE_GIANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_GIANT), + SPELL_REANIMATE_OGRE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_OGRE), + SPELL_REANIMATE_ELF(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_ELF), + SPELL_REANIMATE_TROLL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_TROLL), + SPELL_REANIMATE_HORROR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_HORROR), + SPELL_REANIMATE_KALPHITE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_KALPHITE), + SPELL_REANIMATE_DAGANNOTH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DAGANNOTH), + SPELL_REANIMATE_BLOODVELD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_BLOODVELD), + SPELL_REANIMATE_TZHAAR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_TZHAAR), + SPELL_REANIMATE_DEMON(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DEMON), + SPELL_REANIMATE_AVIANSIE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_AVIANSIE), + SPELL_REANIMATE_ABYSSAL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_ABYSSAL), + SPELL_REANIMATE_DRAGON(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DRAGON), + /* END OF ARCEUUS SPELL BOOK WIDGETS*/ + + MULTICOMBAT_RESIZEABLE(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), + + FULLSCREEN_MAP_ROOT(WidgetID.FULLSCREEN_CONTAINER_TLI, WidgetID.FullScreenMap.ROOT), + + MUSICTAB_INTERFACE(WidgetID.MUSICTAB_GROUP_ID, 1), + MUSICTAB_SONG_BOX(WidgetID.MUSICTAB_GROUP_ID, 2), + MUSICTAB_ALL_SONGS(WidgetID.MUSICTAB_GROUP_ID, 3), + MUSICTAB_SCROLLBAR(WidgetID.MUSICTAB_GROUP_ID, 4), + MUSICTAB_PLAYING(WidgetID.MUSICTAB_GROUP_ID, 5), + MUSICTAB_CURRENT_SONG_NAME(WidgetID.MUSICTAB_GROUP_ID, 6), + MUSICTAB_AUTO_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 7), + MUSICTAB_AUTO_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 8), + MUSICTAB_MANUAL_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 9), + MUSICTAB_MANUAL_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 10), + MUSICTAB_LOOP_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 11), + MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12), + MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13), + + QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB), + + EQUIPMENT_MELEE_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MELEE_STRENGTH), + EQUIPMENT_RANGED_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.RANGED_STRENGTH), + EQUIPMENT_MAGIC_DAMAGE(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MAGIC_DAMAGE), + EQUIP_YOUR_CHARACTER(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.EQUIP_YOUR_CHARACTER), + + BANK_PIN_TOP_LEFT_TEXT(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.TOP_LEFT_TEXT), + BANK_PIN_EXIT_BUTTON(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.EXIT_BUTTON), + BANK_PIN_FORGOT_BUTTON(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FORGOT_BUTTON), + BANK_PIN_FIRST_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FIRST_ENTERED), + BANK_PIN_SECOND_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.SECOND_ENTERED), + BANK_PIN_THIRD_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.THIRD_ENTERED), + BANK_PIN_FOURTH_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FOURTH_ENTERED), + BANK_PIN_INSTRUCTION_TEXT(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.INSTRUCTION_TEXT), + BANK_PIN_1(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_1), + BANK_PIN_2(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_2), + BANK_PIN_3(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_3), + BANK_PIN_4(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_4), + BANK_PIN_5(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_5), + BANK_PIN_6(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_6), + BANK_PIN_7(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_7), + BANK_PIN_8(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_8), + BANK_PIN_9(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_9), + BANK_PIN_10(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_10), + + XP_DROP_1(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_1), + XP_DROP_2(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_2), + XP_DROP_3(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_3), + XP_DROP_4(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_4), + XP_DROP_5(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_5), + XP_DROP_6(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_6), + XP_DROP_7(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_7), + + JEWELLERY_BOX_DUEL_RING(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.DUEL_RING), + JEWELLERY_BOX_GAME_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.GAME_NECK), + JEWELLERY_BOX_COMB_BRAC(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.COMB_BRAC), + JEWELLERY_BOX_SKIL_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.SKIL_NECK), + JEWELLERY_BOX_RING_OFGP(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.RING_OFGP), + JEWELLERY_BOX_AMUL_GLOR(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.AMUL_GLOR), + OPTIONS_CAMERA_ZOOM_SLIDER_HANDLE(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.CAMERA_ZOOM_SLIDER_HANDLE), + OPTIONS_MUSIC_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.MUSIC_SLIDER), + OPTIONS_SOUND_EFFECT_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.SOUND_EFFECT_SLIDER), + OPTIONS_AREA_SOUND_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.AREA_SOUND_SLIDER), + + TRADING_WITH(WidgetID.PLAYER_TRADE_SCREEN_GROUP_ID, WidgetID.TradeScreen.FIRST_TRADING_WITH), + SECOND_TRADING_WITH(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_TRADING_WITH), + SECOND_TRADING_WITH_ACCEPT_BUTTON(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_ACCEPT_FUNC), + SECOND_TRADING_WITH_ACCEPT_TEXT(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_ACCEPT_TEXT), + SECOND_TRADING_WITH_DECLINE_BUTTON(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_DECLINE_FUNC), + SECOND_TRADING_WITH_DECLINE_TEXT(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_DECLINE_TEXT), + SECOND_TRADING_WITH_MY_OFFER(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_MY_OFFER), + SECOND_TRADING_WITH_THEIR_OFFER(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_THEIR_OFFER), + SECOND_TRADING_WITH_MY_ITEMS(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_MY_ITEMS), + SECOND_TRADING_WITH_THEIR_ITEMS(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_THEIR_ITEMS), + + GAUNTLET_MAP(WidgetID.GAUNTLET_MAP_GROUP_ID, WidgetID.GauntletMap.CONTAINER), + + SHOP_ITEMS_CONTAINER(WidgetID.SHOP_GROUP_ID, WidgetID.Shop.ITEMS_CONTAINER), ; private final int groupId; diff --git a/runelite-client/src/main/java/com/openosrs/client/game/Sound.java b/runelite-client/src/main/java/com/openosrs/client/game/Sound.java new file mode 100644 index 0000000000..24b7588040 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/game/Sound.java @@ -0,0 +1,42 @@ +package com.openosrs.client.game; + +public enum Sound +{ + FIFTEEN_SECONDS(1, "net/runelite/client/game/sounds/15seconds.wav"), + FIVE_SECONDS(2, "net/runelite/client/game/sounds/5seconds.wav"), + ATTACK_WITH_MAGIC(3, "net/runelite/client/game/sounds/attackmagic.wav"), + ATTACK_WITH_MELEE(4, "net/runelite/client/game/sounds/attackmelee.wav"), + ATTACK_WITH_RANGED(5, "net/runelite/client/game/sounds/attackranged.wav"), + INCOMING(6, "net/runelite/client/game/sounds/incoming.wav"), + MOVE(7, "net/runelite/client/game/sounds/move.wav"), + PRAY_MAGIC(8, "net/runelite/client/game/sounds/praymagic.wav"), + PRAY_MELEE(9, "net/runelite/client/game/sounds/praymelee.wav"), + PRAY_RANGED(10, "net/runelite/client/game/sounds/prayranged.wav"), + REENABLE_PRAYER(11, "net/runelite/client/game/sounds/reenableprayer.wav"), + RUNAWAY(12, "net/runelite/client/game/sounds/runaway.wav"), + LOW_HEATLH(13, "net/runelite/client/game/sounds/lowhealth.wav"), + LOW_PRAYER(14, "net/runelite/client/game/sounds/lowprayer.wav"), + OUT_OF_COMBAT(15, "net/runelite/client/game/sounds/outofcombat.wav"), + RESTORED_SPECIAL_ATTACK(16, "net/runelite/client/game/sounds/restorespec.wav"), + IDLE(17, "net/runelite/client/game/sounds/idle.wav"), + BREAK(18, "net/runelite/client/game/sounds/break.wav"); + + private final String filePath; + private final int id; + + Sound(int id, String filePath) + { + this.id = id; + this.filePath = filePath; + } + + public String getFilePath() + { + return this.filePath; + } + + public int getId() + { + return this.id; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/game/SoundManager.java b/runelite-client/src/main/java/com/openosrs/client/game/SoundManager.java new file mode 100644 index 0000000000..0f46afb1f8 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/game/SoundManager.java @@ -0,0 +1,95 @@ +package com.openosrs.client.game; + +import com.google.inject.Inject; +import java.io.IOException; +import javax.inject.Singleton; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.BooleanControl; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.UnsupportedAudioFileException; +import net.runelite.client.config.RuneLiteConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Singleton +public class SoundManager +{ + private static final Logger log = LoggerFactory.getLogger(SoundManager.class); + private final RuneLiteConfig runeliteConfig; + + @Inject + private SoundManager(RuneLiteConfig runeLiteConfig) + { + this.runeliteConfig = runeLiteConfig; + } + + public void playSound(final Sound sound) + { + new Thread(new Runnable() + { + + @Override + public void run() + { + try + { + AudioInputStream in = AudioSystem.getAudioInputStream(this.getClass().getClassLoader().getResource(sound.getFilePath())); + AudioFormat outFormat = SoundManager.this.getOutFormat(in.getFormat()); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, outFormat); + SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); + if (line != null) + { + line.open(outFormat, 2200); + if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) + { + int volume = 50; + FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN); + BooleanControl muteControl = (BooleanControl) line.getControl(BooleanControl.Type.MUTE); + if (volume == 0) + { + muteControl.setValue(true); + } + else + { + muteControl.setValue(false); + gainControl.setValue((float) (Math.log((double) volume / 100.0) / Math.log(10.0) * 20.0)); + } + } + line.start(); + SoundManager.this.stream(AudioSystem.getAudioInputStream(outFormat, in), line); + line.drain(); + line.stop(); + } + } + catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) + { + throw new IllegalStateException(e); + } + } + }).start(); + } + + private AudioFormat getOutFormat(AudioFormat inFormat) + { + int ch = inFormat.getChannels(); + float rate = inFormat.getSampleRate(); + return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, rate, 16, ch, ch * 2, rate, false); + } + + private void stream(AudioInputStream in, SourceDataLine line) throws IOException + { + byte[] buffer = new byte[2200]; + int n = 0; + while (n != -1) + { + line.write(buffer, 0, n); + n = in.read(buffer, 0, buffer.length); + } + } + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/game/WorldLocation.java b/runelite-client/src/main/java/com/openosrs/client/game/WorldLocation.java new file mode 100644 index 0000000000..5a65f8ec98 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/game/WorldLocation.java @@ -0,0 +1,906 @@ +/******************************************************************************* + * Copyright (c) 2019 openosrs + * Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file. + * If there are any questions comments, or feedback about this software, please direct all inquiries directly to the file authors: + * ST0NEWALL#9112 + * Macweese#1169 UID 159941566994186240, macweese@pm.me + * openosrs Discord: https://discord.gg/Q7wFtCe + * openosrs website: https://openosrs.com + ******************************************************************************/ + +package com.openosrs.client.game; + +import com.google.common.collect.ImmutableMap; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.Getter; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import com.openosrs.client.util.PvPUtil; + + /* + * Enums sorted alphabetically by main regions (Kingdoms) and then their sub-regions or notable features + * Example: + * Wilderness + * Mage Bank + */ +public enum WorldLocation +{ + + /*- + * Ape Atoll + * Crash Island + * Marim + */ + APE_ATOLL_TEMPLE("Ape Atoll Temple", new Location(2784, 2802, 2810, 2770), 0), + APE_ATOLL_GATE("Ape Atoll Gate", new Location(2712, 2761, 2730, 2749), 0), + APE_ATOLL_GLIDER("Ape Atoll Glider", new Location(2707, 2808, 2719, 2797), 0), + APE_ATOLL_TEAKS("Ape Atoll Teak Trees", new Location(2756, 2708, 2791, 2689), 0), + CRASH_ISLAND("Crash Island", new Location(2881, 2749, 2943, 2691), 0), + KRUK_DUNGEON_1("Monkey Madness 2 Dungeon", new Location(2689, 9150, 2815, 9088), 0), + KRUK_DUNGEON_2("Monkey Madness 2 Dungeon", new Location(2689, 9150, 2815, 9088), 1), + KRUK_DUNGEON_3("Monkey Madness 2 Dungeon", new Location(2309, 9277, 2454, 9131), 1), + MARIM_NORTH("North Marim", new Location(2731, 2804, 2783, 2786), 0), + MARIM_SOUTH("South Marim", new Location(2731, 2785, 2783, 2762), 0), + MONKEY_MADNESS_DUNGEON("Monkey Madness 1 Dungeon", new Location(2689, 9150, 2815, 9088), 0), + + /*- + * Asgarnia + * Faldor + * Burthorpe + * Edgeville + * Entrana + * Port Sarim + * Rimmington + * Taverly + */ + ASGARNIAN_ICE_DUNGEON_WYVERNS("Asgarnian Ice Dungeon - Skeletal Wyverns", new Location(3022, 9559, 3070, 9537), 0), + ASGARNIAN_ICE_DUNGEON_ICE_MONSTERS("Asgarnian Ice Dungeon - Ice Warriors & Ice Giants", new Location(3043, 9587, 3065, 9570), 0), + ASGARNIAN_ICE_DUNGEON_PIRATES("Asgarnian Ice Dungeon - Pirates", new Location(2986, 9568, 2999, 9585), 0), + BURTHOPRE_GAMES_TELEPORT("Burthorpe Games Tele", new Location(2890, 3557, 2907, 3549), 0), + CRAFTING_GUILD("Crafting Guild", new Location(2921, 3292, 2944, 3275), 0), + EDGEVILLE_MONASTERY("Edgeville Monastery", new Location(3044, 3507, 3060, 3471), 0), + FALADOR_BANK("Fally Bank", new Location(2943, 3372, 2949, 3358), 0), + FALADOR_CENTER("Fally Center", new Location(2959, 3385, 2972, 3374), 0), + FALADOR_EAST_BANK("Fally East Bank", new Location(3008, 3358, 3021, 3353), 0), + FALADOR_FARM("Falador Farm", new Location(3014, 3314, 3067, 3283), 0), + FALADOR_PARK("Fally Park", new Location(2982, 3390, 3025, 3368), 0), + FALADOR_PARTYROOM("Falador Partyroom", new Location(3035, 3386, 3056, 3370), 0), + FALADOR_RESPAWN("Fally Respawn", new Location(2957, 3355, 2998, 3325), 0), + GOBLIN_VILLAGE("Goblin Village", new Location(2948, 3516, 2963, 3493), 0), + HEROES_GUILD("Heroes' Guild", new Location(2881, 3517, 2902, 3504), 0), + HEROES_GUILD_DUNGEON("Heroes' Guild Dungeon", new Location(2885, 9918, 2945, 9882), 0), + ICE_MOUNTAIN("Ice Mountain", new Location(3001, 3508, 3024, 3463), 0), + MIND_ATLAR("Mind Altar", new Location(2970, 3520, 2990, 3509), 0), + MUDSKIPPER_POINT("Mudskipper point", new Location(2980, 3145, 3011, 3104), 0), + PORT_SARIM("Port Sarim", new Location(3024, 3250, 3055, 3192), 0), + PORT_SARIM_JAIL("Port Sarim Jail", new Location(3009, 3193, 3021, 3178), 0), + RIMMINGTON("Rimmington", new Location(2946, 3213, 2970, 3188), 0), + RIMMINGTON_DOCKS("Rimmington Docks", new Location(2905, 3228, 2922, 3222), 0), + RIMMINGTON_MINE("Rimmington Mine", new Location(2968, 3252, 2991, 3230), 0), + RIMMINGTON_PORTAL("Rimmington Portal", new Location(2946, 3228, 2960, 3218), 0), + ROGUES_DEN("Rogue's Den", new Location(3036, 4957, 3067, 4986), 1), + TAVERLY("Taverly", new Location(2880, 3442, 2917, 3409), 0), + TAVERLY_DUNGEON_BLACK_KNGIHTS("Taverly Dungeon - Black Knights", new Location(2883, 9717, 2939, 9667), 0), + TAVERLY_DUNGEON_HILL_GIANTS("Taverly Dungeon - Hill Giants", new Location(2895, 9743, 2920, 9718), 0), + TAVERLY_DUNGEON_BLACK_DRAGONS("Taverly Dungeon - Black Dragons", new Location(2812, 9836, 2846, 9822), 0), + TAVERLY_DUNGEON_HELLHOUNDS("Taverly Dungeon - Hell Hounds", new Location(2847, 9854, 2873, 9822), 0), + TAVERLY_DUNGEON_BLUE_DRAGONS("Taverly Dungeon - Blue Dragons", new Location(2890, 9778, 2923, 9813), 0), + TAVERLY_DUNGEON_BLACK_DEMONS("Taverly Dungeon - Black Demons", new Location(2844, 9800, 2873, 9773), 0), + TAVERLY_DUNGEON_POISON_SPIDERS("Taverly Dungeon - Poison Spiders", new Location(3010, 4756, 3068, 4803), 0), + TAVERLY_DUNGEON_CHAOS_DRUIDS("Taverly Dungeon - Chaos Druids", new Location(2915, 9856, 2944, 9833), 0), + TAVERLY_DUNGEON_LESSER_DEMONS("Taverly Dungeon - Lesser Demons", new Location(2924, 9813, 2946, 9777), 0), + TAVERLY_DUNGEON_MAGIC_AXES("Taverly Dungeon - Magic Axes", new Location(2947, 9798, 2971, 9769), 0), + TAVERLY_DUNGEON_CHAOS_DWARVES("Taverly Dungeon - Chaos Dwarves", new Location(2920, 9776, 2938, 9745), 0), + TAVERLY_DUNGEON_MAIN_CORRIDOR("Taverly Dungeon - Main Corridor", new Location(2880, 9793, 2889, 9850), 0), + TAVERLY_GATE("Taverly Gate", new Location(2931, 3456, 2944, 3444), 0), + TAVERLY_POH_PORTAL("Taverly POH Portal", new Location(2885, 3471, 2899, 3458), 0), + WARRIORS_GUILD("Warriors' Guild", new Location(2838, 3536, 2876, 3555), 0), + WARRIORS_GUILD_BASEMENT("Warriors' Guild Basement (Dragon Defender)", new Location(2904, 9974, 2941, 9956), 0), + + /*- + * Entrana + */ + ENTRANA_BALLOON("Entrana Balloon", new Location(2803, 3359, 2815, 3347), 0), + ENTRANA_CHURCH("Entrana Church", new Location(2840, 3356, 2858, 3341), 0), + ENTRANA_DOCKS("Entrana Docks", new Location(2825, 3338, 2847, 3328), 0), + ENTRANA_NORTH("Entrana (North Portion)", new Location(2541, 2875, 2595, 2837), 0), + + /*- + * Feldip Hills + * Corsair Cove + * Gu'Tanoth + */ + CORSAIR_COVE("Corsair Cove", new Location(2541, 2875, 2595, 2837), 0), + CORSAIR_RESOURCE_AREA("Corsair Resource Area", new Location(2453, 2905, 2488, 2883), 0), + FELDIP_HILLS_GLIDER("Feldip Hills Glider", new Location(2536, 2975, 2546, 2965), 0), + FELDIP_HILLS_RED_CHINS("Feldip Hills Red Chins", new Location(2525, 2935, 2561, 2902), 0), + GU_TANOTH("Gu'Tanoth", new Location(2497, 3060, 2558, 3008), 0), + MYTHS_GUILD("Myth's Guild", new Location(2470, 2872, 2442, 2834), 0), + + /* + * Fossil Island + */ + MUSEUM_CAMP("Fossil Island Museum Camp", new Location(3708, 3797, 3751, 3833), 0), + FOSSIL_ISLAND_HOUSE_ON_THE_HILL("House on the Hill (Fossil Island)", new Location(3747, 3891, 3795, 3855), 0), + FOSSIL_ISLAND_MUSHROOM_FOREST("Fossil Island Mushroom Forest (Herbiboar)", new Location(3670, 3894, 3707, 3814), 0), + FOSSIL_ISLAND_SWAMP_NORTH("Fossil Island Swamp (North half)", new Location(3707, 3758, 3643, 3696), 0), + FOSSIL_ISLAND_SWAMP_SOUTH("Fossil Island Swamp (South half)", new Location(3707, 3813, 3643, 3759), 0), + FOSSIL_ISLAND_VERDANT_VALLEY("Fossil Island Verdant Valley (South East Island)", new Location(3670, 3894, 3707, 3814), 0), + FOSSIL_ISLAND_VOLCANO_BANK("Fossil Island Volcano Bank", new Location(3807, 3818, 3825, 3800), 0), + + /*- + * Fremennik Province + * Fremennik Isles (Neitiznot & Jatizo) + * Fremennik Slayer Dungeon + * Lunar Isle + * Miscellania and Etceteria + * Rellekka + * Waterbirth Island + */ + ETCETERIA("Etceteria", new Location(2626, 3904, 2571, 3861), 0), + ETCETERIA_DOCKS("Etceteria Docks", new Location(2571, 3904, 2626, 3861), 0), + FREMENNIK_BASILISK_KNIGHT_DUNGEON("Fremennik Basilisk Knight Dungeon", new Location(2398, 10468, 2496, 10370), 0), + FREMENNIK_SLAYER_DUNGEON("Fremennik Slayer Dungeon", new Location(2771, 10023, 2811, 9989), 0), + FREMENNIK_SLAYER_DUNGEON_BASILISKS("Fremennik Slayer Dungeon - Baslisks", new Location(2734, 10015, 2751, 9988), 0), + FREMENNIK_SLAYER_DUNGEON_ENTRANCE("Fremennik Slayer Dungeon Entrance", new Location(2776, 3604, 2801, 3626), 0), + FREMENNIK_SLAYER_DUNGEON_JELLIES("Fremennik Slayer Dungeon - Jellies", new Location(2694, 10035, 2733, 10016), 0), + FREMENNIK_SLAYER_DUNGEON_KURASKS("Fremennik Slayer Dungeon - Kurasks", new Location(2708, 10007, 2690, 9988), 0), + FREMENNIK_SLAYER_DUNGEON_PYREFIENDS("Fremennik Slayer Dungeon - Pyrefiends", new Location(2752, 10015, 2770, 9988), 0), + FREMENNIK_SLAYER_DUNGEON_TUROTHS("Fremennik Slayer Dungeon - Turoths", new Location(2709, 10015, 2733, 9988), 0), + JATIZSO("Jatizso", new Location(2369, 3826, 2428, 3776), 0), + KELDAGRIM_EAST("Eastern Keldagrim", new Location(2884, 10236, 2943, 10181), 0), + KELDAGRIM_ENTRANCE("Keldagrim Entrance", new Location(2722, 3720, 2738, 3703), 0), + KELDAGRIM_WEST("Western Keldagrim", new Location(2819, 10236, 2875, 10182), 0), + LUNAR_ISLE_CENTRAL("Lunar Isle Central", new Location(2055, 3933, 2112, 3888), 0), + LUNAR_ISLE_EAST("Lunar Isle East", new Location(2113, 3921, 2185, 3888), 0), + LUNAR_ISLE_NORTH("Lunar Isle North", new Location(2063, 3958, 2112, 3934), 0), + LUNAR_ISLE_NORTH_EAST("Lunar Isle North East", new Location(2113, 3958, 2185, 3922), 0), + LUNAR_ISLE_SOUTH("Lunar Isle South", new Location(2057, 3887, 2112, 3843), 0), + LUNAR_ISLE_SOUTHEAST("Lunar Isle SouthEast", new Location(2113, 3887, 2185, 3843), 0), + MISCELLANIA("Miscellania", new Location(2492, 3904, 2570, 3836), 0), + MISCELLANIA_DOCKS("Miscellania Docks", new Location(2623, 3851, 2603, 3840), 0), + MOUNTAIN_CAMP("Mountain Camp", new Location(2789, 3682, 2813, 3658), 0), + NEITIZNOT("Neitiznot", new Location(2300, 3826, 2368, 3776), 0), + PIRATES_COVE("Pirate's Cove", new Location(2186, 3842, 2228, 3785), 0), + RELLEKKA_MAIN_HALL("Rellekka Main Hall", new Location(2652, 3685, 2670, 3658), 0), + RELLEKKA_MARKET("Rellekka Market", new Location(2629, 3682, 2651, 3654), 0), + RELLEKKA_NORTH_DOCKS("Rellekka North Docks", new Location(2640, 3712, 2651, 3706), 0), + RELLEKKA_NORTH_EAST("Rellekka North East", new Location(2652, 3712, 2690, 3686), 0), + RELLEKKA_POH_PORTAL("Rellekka POH Portal", new Location(2662, 3635, 2676, 3624), 0), + RELLEKKA_SOUTH_DOCKS("Rellekka South Docks", new Location(2619, 3699, 2641, 3681), 0), + RELLEKKA_ZONE("Rellekka", new Location(2600, 3708, 2690, 3645), 0), + ROCK_CRABS_EAST("Rock Crabs East (Near Keldagrim)", new Location(2691, 3738, 2730, 3713), 0), + ROCK_CRABS_WEST("Rock Crabs West (North of Rellekka)", new Location(2650, 3738, 2690, 3713), 0), + VORKATH("Vorkath", new Location(2237, 4096, 2301, 4031), 0), + WATERBIRTH_DUNGEON_ROCK_LOBSTERS("Waterbirth Dungeon - Rock Lobsters", new Location(1875, 4380, 1919, 4412), 0), + WATERBIRTH_DUNGEON_DKS_1("DKS", new Location(2886, 4473, 2941, 4424), 0), // One of these is private, not sure which + WATERBIRTH_DUNGEON_DKS_2("DKS", new Location(2886, 4409, 2941, 4361), 0), // One of these is private, not sure which + WATERBIRTH_DUNGEON_ZONE_1("Waterbirth Dungeon", new Location(2435, 10176, 2558, 10112), 0), + WATERBIRTH_DUNGEON_ZONE_2("Waterbirth Dungeon", new Location(1788, 4413, 1966, 4352), 1), + WATERBIRTH_ISLAND("Waterbirth Island", new Location(2494, 3774, 2562, 3710), 0), + + /*- + * Great Kourend + * Arceuus + * Battlefront + * Catacombs of Kourend + * Crabclaw Caves + * Forthos Dungeon + * Hosidius + * Kebos Lowlands + * Kingstown + * Kourend Woodland + * Lake Molch + * Lizardman Settlement + * Lovakengj + * Mount Karuulm + * Mount Quidamortem + * Northern Tundras + * Port Piscarilius + * Shayzien + * Wintertodt + */ + ARCEUUS("Arceuus", new Location(1620, 3780, 1739, 3708), 0), + ARCEUUS_BANK("Arceuus Bank", new Location(1620, 3754, 1639, 3735), 0), + ARCEUUS_DENSE_ESSENCE_MINE("Arceuus Dense Essence Mine", new Location(1741, 3880, 1786, 3831), 0), + ARCEUUS_LIBRARY("Arceuus Library", new Location(1605, 3833, 1662, 3781), 0), + BATTLEFRONT("Battlefront Teleport", new Location(1344, 3745, 1362, 3726), 0), + BLAST_MINE("Lovakengj Blast Mine", new Location(1467, 3888, 1513, 3840), 0), + BLOOD_ALTAR("Blood Altar", new Location(1710, 3835, 1737, 3822), 0), + CHASM_OF_FIRE("Chasm of Fire", new Location(1411, 10108, 1468, 10050), 1), + COX("CoX", new Location(1226, 3574, 1270, 3559), 0), + CRAB_CLAW_ISLE("Crab Claw Isle", new Location(1745, 3449, 1795, 3399), 0), + DARK_ALTAR("Arceuus Dark Altar", new Location(1699, 3895, 1734, 3869), 0), + FARMING_GUILD("Farming Guild", new Location(1223, 3718, 1273, 3765), 0), + FISHING_HAMLET("Fishing Hamlet (East of Wintertodt Camp)", new Location(1683, 3969, 1720, 3917), 0), + FOODHALL("Piscarilius Foodhall", new Location(1830, 3762, 1854, 3734), 0), + FORTHOS_RUINS("Forthos Ruins", new Location(1666, 3590, 1684, 3561), 0), + FORTHOS_DUNGEON_ALTAR("Forthos Dungeon - Altar", new Location(1794, 9954, 1804, 9946), 0), + FORTHOS_DUNGEON_GRUBBY_CHEST("Forthos Dungeon - Grubby Chest", new Location(1793, 9928, 1799, 9922), 0), + FORTHOS_DUNGEON_LADDER_EAST("Forthos Dungeon - East Ladder", new Location(1825, 9978, 1835, 9969), 0), + FORTHOS_DUNGEON_LADDER_WEST("Forthos Dungeon - West Ladder", new Location(1795, 9972, 1805, 9958), 0), + FORTHOS_DUNGEON_RED_DRAGONS("Forthos Dungeon - Red Dragons", new Location(1807, 9944, 1828, 9933), 0), + FORTHOS_DUNGEON_SARACHNIS("Forthos Dungeon - Sarachnis", new Location(1829, 9890, 1854, 9913), 0), + FORTHOS_DUNGEON_SPIDERS("Forthos Dungeon - Red Spiders", new Location(1830, 9968, 1848, 9947), 0), + FORTHOS_DUNGEON_UNDEAD_DRUIDS_1("Forthos Dungeon - Undead Druids", new Location(1795, 9944, 1806, 9933), 0), + FORTHOS_DUNGEON_UNDEAD_DRUIDS_2("Forthos Dungeon - Undead Druids", new Location(1806, 9973, 1814, 9958), 0), + FORTHOS_DUNGEON_ZONE("Forthos Dungeon", new Location(1789, 9985, 1858, 9914), 0), + HOSIDIUS_BANK("Hosidius Bank", new Location(1743, 3603, 1753, 3594), 0), + HOSIDIUS_FRUIT_STALLS("Hosidius Fruit Stalls", new Location(1790, 3614, 1806, 3603), 0), + HOSIDIUS_KITCHEN("Hosidius Kitchen (Bank)", new Location(1671, 3625, 1687, 3610), 0), + HOSIDIUS_PLOW_FIELD("Hosidius Plow Fields", new Location(1761, 3558, 1781, 3519), 0), + HOSIDIUS_POH_PORTAL("Hosidius POH Portal", new Location(1735, 3522, 1747, 3511), 0), + HOSIDIUS_SQUARE("Hosidius Square", new Location(1754, 3607, 1772, 3589), 0), + HOSIDIUS_VINERY("Hosidius Vinery", new Location(1799, 3573, 1816, 3537), 0), + HOSIDIUS_ZONE("Hosidius", new Location(1737, 3627, 1789, 3582), 0), + KOUREND_CASTLE("Kourend Castle", new Location(1592, 3700, 1692, 3646), 0), + KOUREND_CATACOMBS_ABYSSAL_DEMONS("Kourend Catacombs - Abyssal Demons", new Location(1667, 10101, 1683, 10082), 0), + KOUREND_CATACOMBS_BLACK_DEMONS("Kourend Catacombs - Black Demons", new Location(1713, 10073, 1724, 10086), 0), + KOUREND_CATACOMBS_BRUTAL_BLACK_DRAGONS("Kourend Catacombs - Brutal Black Dragons", new Location(1604, 10105, 1635, 10068), 0), + KOUREND_CATACOMBS_CENTER("Kourend Catacombs Center", new Location(1655, 10055, 1670, 10038), 0), + KOUREND_CATACOMBS_DUST_DEVILS("Kourend Catacombs - Dust Devils", new Location(1704, 10037, 1734, 9985), 0), + KOUREND_CATACOMBS_GREATER_DEMONS("Kourend Catacombs - Greater Demons", new Location(1684, 10105, 1724, 10087), 0), + KOUREND_CATACOMBS_NECHRYAELS("Kourend Catacombs - Nechryaels", new Location(1684, 10086, 1712, 10073), 0), + KOUREND_CATACOMBS_SOUTH("Kourend Catacombs - South", new Location(1639, 10014, 1702, 9985), 0), + KOUREND_CATACOMBS_SOUTH_WEST("Kourend Catacombs South-West Corner", new Location(1596, 10028, 1634, 9984), 0), + KOUREND_CATACOMBS_STEEL_DRAGONS("Kourend Catacombs - Steel Dragons", new Location(1599, 10066, 1630, 10029), 0), + KOUREND_CATACOMBS_ZONE("Kourend Catacombs", new Location(1595, 10106, 1735, 9984), 0), + LANDS_END("Land's End", new Location(1481, 3448, 1527, 3396), 0), + LAKE_MOLCH("Lake Molch", new Location(1357, 3643, 1377, 3624), 0), + LIZARDMAN_SHAMANS("Lizardman Shamans", new Location(1414, 3726, 1461, 3688), 0), + LOVAKENGJ("Lovakengj", new Location(1425, 3810, 1520, 3730), 0), + MOUNT_KARUULM("Mount Karuulm", new Location(1287, 3829, 1331, 3787), 0), + PISCARILIUS_ANGLERFISH("Piscarilius Angler Fishing Spot", new Location(1807, 3779, 1842, 3766), 0), + PISCARILIUS_BANK("Piscarilius Bank", new Location(1793, 3794, 1812, 3782), 0), + PISCARILIUS_PORT("Port Piscarilius", new Location(1788, 3712, 1849, 3673), 0), + PISCARILIUS_ZONE("Piscarilius", new Location(1740, 3814, 1854, 3713), 0), + SANDCRABS_BANK("Sandcrabs Bank", new Location(1706, 3475, 1730, 3455), 0), + SANDCRABS_NORTH("Sandcrabs (East of Vinery)", new Location(1848, 3572, 1884, 3532), 0), + SANDCRABS_SOUTH_1("Sandcrabs (South of Tithe Farm)", new Location(1796, 3468, 1849, 3436), 0), + SANDCRABS_SOUTH_2("Sandcrabs (South Coast)", new Location(1745, 3474, 1795, 3450), 0), + SANDCRABS_SOUTH_EAST("Sandcrabs (East of Tithe Farm)", new Location(1850, 3529, 1884, 3465), 0), + SHAYZIEN_BANK("Shayzien Bank", new Location(1494, 3622, 1515, 3611), 0), + SHAYZIEN_CRYPTS_ENTRANCE("Shayzien Crypts Entrance", new Location(1474, 3570, 1502, 3535), 0), + SHAYZIEN_INFIRMARY("Shayzien Infirmary", new Location(1565, 3574, 1590, 3604), 0), + SHAYZIEN_ZONE("Shayzien", new Location(1472, 3644, 1591, 3521), 0), + SOUL_ALTAR("Soul Altar", new Location(1804, 3869, 1834, 3841), 0), + SULPHUR_MINE("Lovakengj Sulphur Mine", new Location(1415, 3888, 1466, 3840), 0), + SULPHUR_MINE_BANK("Lovakengj Sulphur Mine Bank", new Location(1430, 3838, 1443, 3817), 0), + TITHE_FARM("Tithe Farm", new Location(1794, 3480, 1841, 3517), 0), + WINTERTODT_CAMP("Wintertodt Camp", new Location(1616, 3963, 1645, 3932), 0), + WINTERTODT_ENTRANCE("Wintertodt Entrance", new Location(1617, 3986, 1641, 3964), 0), + WINTERTODT_NORTHEAST("Wintertodt NorthEast", new Location(1630, 4027, 1651, 4008), 0), + WINTERTODT_NORTHWEST("Wintertodt NorthWest", new Location(1608, 4028, 1629, 4008), 0), + WINDERTODT_SOUTH_EAST("Windertodt South East", new Location(1630, 4007, 1651, 3987), 0), + WINTERTODT_SOUTHWEST("Wintertodt SouthWest", new Location(1608, 4007, 1629, 3987), 0), + WOODCUTTING_GUILD_BANK("Woodcutting Guild Bank", new Location(1588, 3481, 1594, 3473), 0), + WOODCUTTING_GUILD_EAST("Woodcutting Guild (East Portion)", new Location(1623, 3519, 1657, 3488), 0), + WOODCUTTING_GUILD_WEST("Woodcutting Guild (Redwoods)", new Location(1562, 3503, 1586, 3476), 0), + WOODCUTTING_GUILD_ZONE("Woodcutting Guild", new Location(1560, 3520, 1659, 3471), 0), + + /*- + * Kandarin + * Ardougne + * Battlefield + * Camelot + * Catherby + * Fishing Guild & McGrubor's Woods + * Observatory + * Ourania + * Piscatoris Fishing Colony + * Port Khazard + * Seers' Village + * Tree Gnome Stronghold + * Tree Gnome Village + * Witchaven + * Yanille + */ + ARDOUGNE_CASTLE("Ardy Castle", new Location(2567, 3311, 2591, 3283), 0), + ARDOUGNE_DOCKS("Ardy Docks", new Location(2660, 3284, 2689, 3264), 0), + ARDOUGNE_MONASTERY("Ardougne Monastery", new Location(2587, 3227, 2623, 3202), 0), + ARDOUGNE_NORTH_BANK("Ardy North Bank", new Location(2611, 3336, 2622, 3329), 0), + ARDOUGNE_SOUTH_BANK("Ardy South Bank", new Location(2645, 3288, 2659, 3279), 0), + ARDOUGNE_STALLS("Ardy Stalls", new Location(2651, 3318, 2673, 3293), 0), + ARDOUGNE_ZOO("Ardy Zoo", new Location(2598, 3288, 2636, 3265), 0), + BARBARIAN_OUTPOST("Barbarian Outpost", new Location(2517, 3580, 2557, 3540), 0), + BAXTORIAN_WATERFALL_DUNGEON("Waterfall Dungeon (Baxtorian Falls)", new Location(2556, 9861, 2594, 9918), 0), + CAMELOT_CASTLE("Camelot Castle", new Location(2743, 3481, 2775, 3468), 0), + CASTLE_WARS_BANK("Castle Wars Bank", new Location(2435, 3100, 2448, 3078), 0), + CASTLE_WARS_ZONE("Castle Wars", new Location(2435, 3127, 2474, 3074), 0), + CATHERBY("Catherby", new Location(2791, 3457, 2833, 3436), 0), + CATHERBY_DOCKS("Catherby Docks", new Location(2790, 3432, 2808, 3409), 0), + CATHERBY_FISHING_SPOTS("Catherby Fishing Spots", new Location(2834, 3441, 2862, 3425), 0), + CATHERBY_FARMING_PATCH("Catherby Farming Patch", new Location(2791, 3472, 2833, 3458), 0), + EAGLES_PEAK("Eagles' Peak", new Location(2308, 3495, 2350, 3479), 0), + FALCONRY_HUNTING_AREA("Falconry Hunting Area", new Location(2365, 3621, 2390, 3572), 0), + FISHING_GUILD("Fishing Guild", new Location(2627, 3426, 2579, 3391), 0), + FISHING_PLATFORM("Fishing Platform", new Location(2763, 3290, 2792, 3273), 0), + GNOME_AGILITY("Gnome Agility", new Location(2469, 3441, 2489, 3412), 0), + GNOME_BALL("Gnome Ball", new Location(2384, 3495, 2408, 3479), 0), + GRAND_TREE("Grand Tree", new Location(2442, 3515, 2490, 3478), 0), + KRAKEN_COVE_DUNGEON("Kraken Dungeon", new Location(2303, 10047, 2240, 9983), 0), + KRAKEN_COVE_ENTRANCE("Kraken Cove Entrance", new Location(2262, 3623, 2295, 3596), 0), + LEGENDS_GUILD("Legends' Guild", new Location(2716, 3388, 2741, 3346), 0), + LEGENDS_GUILD_DUNGEON("Legends' Guild Dungeon", new Location(2690, 9784, 2740, 9730), 0), + LIGHTHOUSE("Lighthouse", new Location(2494, 3649, 2524, 3616), 0), + MCGRUBORS_WOODS("McGrubor's Woods", new Location(2624, 3501, 2647, 3481), 0), + NIEVE("Nieve", new Location(2430, 3425, 2435, 3419), 0), + NIGHTMARE_ZONE("Nightmare Zone", new Location(2599, 3119, 2614, 3111), 0), + OBSERVATORY("Observatory", new Location(2429, 3198, 2452, 3149), 0), + OBSERVATORY_DUNGEON("Obsvervatory Dungeon", new Location(2305, 9406, 2366, 9344), 0), + OTTOS_GROTTO("Barbarian Fishing", new Location(2491, 3519, 2527, 3488), 0), + OURANIA_CAVE("ZMI", new Location(3006, 5567, 3072, 5634), 0), + THE_OUTPOST("The Outpost", new Location(2428, 3356, 2443, 3338), 0), + PISCATORIS_FISHING_COLONY("Piscatoris Fishing Colony", new Location(2302, 3708, 2364, 3653), 0), + PORT_KHAZARD("Port Khazard", new Location(2624, 3182, 2680, 3143), 0), + RANGING_GUILD("Ranging Guild", new Location(2650, 3445, 2685, 3411), 0), + RED_SALAMANDERS("Red Salamanders", new Location(2441, 3229, 2464, 3204), 0), + SEERS_VILLAGE("Seers Village", new Location(2688, 3498, 2742, 3468), 0), + SINCLAIR_MANSION("Sinclair Mansion", new Location(2723, 3584, 2756, 3552), 0), + SMOKE_DEVIL_DUNGEON("CW Smoke Devil Dungeon", new Location(2379, 9467, 2427, 9415), 0), + SMOKE_DEVIL_DUNGEON_BOSS("CW Smoke Dungeon (Boss Room)", new Location(2347, 9462, 2377, 9438), 0), + SMOKE_DEVIL_DUNGEON_ENTRANCE("Smoke Devil Dungeon Entrance", new Location(2430, 3425, 2435, 3419), 0), + TRAINING_GROUND("Training Ground (Caged Ogres)", new Location(2501, 3387, 2534, 3358), 0), + TREE_GNOME_VILLAGE("Tree Gnome Village", new Location(2514, 3175, 2547, 3158), 0), + WEST_ARDOUGNE("West Ardy", new Location(2452, 3336, 2557, 3265), 0), + WITCHAVEN("Witchaven", new Location(2704, 3267, 2741, 3295), 0), + WITCHAVEN_DUNGEON("Witchaven Dungeon", new Location(2750, 9665, 2690, 9719), 0), + WIZARDS_GUILD("Wizards Guild", new Location(2585, 3092, 2596, 3082), 0), + WHITE_WOLF_MOUNTAIN_GNOME_GLIDER("White Wolf Mountain Gnome Glider", new Location(2838, 3509, 2852, 3496), 0), + YANILLE_AGILITY_DUNGEON("Yanille Agilty Dungeon", new Location(2559, 9536, 2624, 9475), 0), + YANILE_BANK("Yanile Bank", new Location(2608, 3097, 2616, 3087), 0), + YANILLE_EAST("Yanille East", new Location(2576, 3110, 2621, 3071), 0), + YANILLE_POH_PORTAL("Yanille POH Portal", new Location(2537, 3108, 2551, 3091), 0), + YANILLE_WEST("Yanille West", new Location(2532, 3110, 2575, 3071), 0), + + /*- + * Karamja + * Brimhaven + * Cairn Isle + * Crandor & Karamja Dungeon + * Kharazi Jungle + * Mor Ul Rel (TzHaar City) + * Musa Point + * Shilo Village + * Ship Yard + * Tai Bwo Wannai + */ + BRIMHAVEN_AGILITY_ARENA("Brimhaven Agility Arena", new Location(2757, 9594, 2809, 9541), 3), + BRIMHAVEN_DOCKS("Brimhaven Docks", new Location(2758, 3241, 2777, 3220), 0), + BRIMHAVEN_DUNGEON("Brimhaven Dungeon - Main Corridor", new Location(2690, 9572, 2714, 9556), 0), + BRIMHAVEN_DUNGEON_BLACK_DEMONS("Brimhaven Dungeon - Black Demons", new Location(2694, 9495, 2726, 9475), 0), + BRIMHAVEN_DUNGEON_BRONZE_DRAGONS("Brimhaven Dungeon - Bronze Dragons", new Location(2727, 9504, 2750, 9475), 0), + BRIMHAVEN_DUNGEON_DOGS("Brimhaven Dungeon - Dogs", new Location(2653, 9530, 2675, 9509), 0), + BRIMHAVEN_DUNGEON_FIRE_GIANTS("Brimhaven Dungeon - Fire Giants", new Location(2638, 9506, 2673, 9476), 0), + BRIMHAVEN_DUNGEON_METAL_DRAGONS_SLAYER("Brimhaven Dungeon - Metal Dragons (Slayer Only)", new Location(2626, 9469, 2685, 9409), 0), + BRIMHAVEN_DUNGEON_METAL_DRAGONS("Brimhaven Dungeon - Metal Dragons", new Location(2693, 9469, 2748, 9412), 0), + BRIMHAVEN_DUNGEON_MOSS_GIANTS("Brimhaven Dungeon - Moss Giants", new Location(2630, 9575, 2670, 9531), 0), + BRIMHAVEN_DUNGEON_RED_DRAGONS("Brimhaven Dungeon - Red Dragons", new Location(2686, 9553, 2726, 9496), 0), + BRIMHAVEN_POH_PORTAL("Brimhaven POH Portal", new Location(2749, 3184, 2765, 3170), 0), + CAIRN_ISLE("Cairn Isle", new Location(2752, 2993, 2775, 2963), 0), + CRANDOR("Crandor", new Location(2813, 3310, 2864, 3231), 0), + HARDWOOD_GROVE("Hardwood Grove", new Location(2815, 3092, 2830, 3073), 0), + KARAMBWAN_FISHING_SPOT("Karambwan Fishing Spot", new Location(2896, 3116, 2920, 3104), 0), + KARAMJA_DOCKS("Karamja Docks", new Location(2813, 3310, 2864, 3231), 0), + KARAMJA_GLORY_TELEPORT("Karamja Glory Tele", new Location(2910, 3177, 2934, 3156), 0), + KARAMJA_GNOME_GLIDER("Karamja Gnome Glider", new Location(2961, 2960, 2984, 2983), 0), + KARAMJA_SHIP_YARD("Karamja Ship Yard", new Location(2949, 3066, 3004, 3016), 0), + KARAMJA_VOLCANO("Karamja Volcano", new Location(2828, 3194, 2866, 3157), 0), + KARAMJA_VOLCANO_DUNGEON("Karamja Dungeon", new Location(2827, 9589, 2866, 9549), 0), + KARAMJA_VOLCANO_DUNGEON_ELVARG("Karamja Dungeon (Elvarg)", new Location(2826, 9661, 2868, 9603), 0), + KHARAZI_JUNGLE_EAST("Kharazi Jungle (Eastern Section)", new Location(2905, 2930, 2976, 2883), 0), + KHARAZI_JUNGLE_CENTER("Kharazi Jungle (Middle Section)", new Location(2816, 2930, 2905, 2883), 0), + KHARAZI_JUNGLE_WEST("Kharazi Jungle (Western Section)", new Location(2756, 2930, 2816, 2883), 0), + MOR_UL_REK_BANK("TzHaar Bank (Inferno)", new Location(2534, 5146, 2547, 5133), 0), + NATURE_ALTAR("Nature Altar", new Location(2841, 3025, 2846, 3020), 0), + SHILO_VILLAGE_NORTH("Shilo Village North", new Location(2817, 3006, 2878, 2973), 0), + SHILO_VILLAGE_SOUTH("Shilo Village South", new Location(2816, 2972, 2879, 2944), 0), + TAI_BWO_WANNAI("Tai Bwo Wannai", new Location(2770, 3105, 2830, 3050), 0), + TZHAAR_BANK("TzHaar Bank (Jad)", new Location(2437, 5184, 2452, 5172), 0), + TZHAAR_EXIT("Tzhaar City Exit", new Location(2471, 5179, 2490, 5162), 0), + TZHAAR_FIGHT_PITS("TzHaar Fight Pit", new Location(2396, 5183, 2403, 5174), 0), + TZHAAR_INNER_SOUTH_EAST("Tzhaar Inner City South-East", new Location(2499, 5112, 2559, 5057), 0), + TZHAAR_INNER_SOUTH_WEST("Tzhaar Inner City South-West", new Location(2444, 5112, 2499, 5058), 0), + + /*- + * Kharidian Desert + * Agility Pyramid + * Al Kharid + * Bandit Camp (Desert) + * Bedabin Camp + * Citharede Abbey + * Duel Arena + * Nardah + * Pollnivneach + * Smoke Dungeon + * Sophanem + * Uzer + */ + AGILITY_PYRAMID("Agility Pyramid", new Location(3334, 2864, 3386, 2819), 0), + AL_KHARID_BANK("Al Kharid Bank", new Location(3265, 3173, 3272, 3161), 0), + AL_KHARID_GATE("Al Kharid Gate", new Location(3263, 3232, 3271, 3223), 0), + AL_KHARID_GLIDER("Al Kharid_Glider", new Location(3276, 3214, 3283, 3209), 0), + AL_KHARID_MINE("Al Kharid Mine", new Location(3295, 3316, 3303, 3278), 0), + AL_KHARID_PALACE("Al Kharid Palace", new Location(3281, 3178, 3304, 3158), 0), + BEDABIN_CAMP("Bedabin Camp", new Location(3157, 3052, 3188, 3019), 0), + CITHAREDE_ABBEY("Citharede Abbey", new Location(3355, 3190, 3425, 3150), 0), + DESERT_BANDIT_CAMP("Desert Bandit Camp", new Location(3154, 2993, 3189, 2963), 0), + DESERT_QUARRY("Desert Granite Quarry", new Location(3156, 2928, 3184, 2897), 0), + DUEL_ARENA("Duel Arena", new Location(3338, 3252, 3391, 3204), 0), // This polygon is deliberately offset + DUEL_ARENA_BANK("Duel Arena Bank", new Location(3379, 3274, 3386, 3265), 0), + DUEL_ARENA_PALM_TREES("Duel Arena Palm Trees", new Location(3340, 3280, 3354, 3264), 0), + DUEL_ARENA_TELEPORT("Duel Arena Tele", new Location(3308, 3246, 3326, 3225), 0), + FIRE_ALTAR("Fire Altar", new Location(3301, 3256, 3307, 3250), 0), + KALPHITE_LAIR("Kalphite Lair Entrance", new Location(3205, 3124, 3253, 3082), 0), + NARDAH_BANK("Nardah Bank", new Location(3417, 2902, 3437, 2883), 0), + NARDAH_ZONE("Nardah", new Location(3397, 2942, 3453, 2882), 0), + POLLNIVNEACH("Pollnivneach", new Location(3331, 2990, 3379, 2945), 0), + POLLNIVNEACH_POH_PORTAL("Pollnivneach POH Portal", new Location(3333, 3008, 3346, 2995), 0), + POLLNIVNEACH_SMOKE_DUNGEON("Pollnivneach Smoke Dungeon", new Location(3199, 9404, 3327, 9345), 0), + POLLNIVNEACH_SMOKE_DUNGEON_ENTRANCE("Pollnivneach Smoke Dungeon Entrance", new Location(3303, 2967, 3314, 2955), 0), + RUINS_OF_UZER("Uzer", new Location(3463, 3114, 3506, 3075), 0), + SHANTAY_PASS("Shantay Pass", new Location(3293, 3137, 3312, 3116), 0), + SOPHANEM("Sophanem", new Location(3272, 2811, 3324, 2751), 0), + + /*- + * Misthalin + * Barbarian Village + * Digsite + * Draynor Village + * Edgeville + * Grand Exchange + * Lumbridge + * Lumbridge Swamp + * Paterdomus + * Silvarea + * Varrock + * Wizards' Tower + */ + BARB_VILLAGE("Barb Village", new Location(3071, 3448, 3092, 3405), 0), + COOKS_GUILD("Cooks Guild", new Location(3135, 3455, 3155, 3427), 0), + CHAMPIONS_GUILD("Champoins' Guild", new Location(3184, 3364, 3199, 3348), 0), + DARK_WIZARDS("Varrock Dark Wizards", new Location(3220, 3377, 3235, 3361), 0), + DIGSITE("Digsite", new Location(3340, 3435, 3380, 3390), 0), + DIGSITE_EXAM_CENTER("Digsite Exam Center", new Location(3357, 3339, 3367, 3331), 0), + DRAYNOR_MANOR("Draynor Manor", new Location(3089, 3375, 3127, 3350), 0), + DRAYNOR_SEWERS("Draynor Sewers", new Location(3077, 9699, 3135, 9642), 0), + DRYANOR_VILLAGE("Dryanor Village", new Location(3074, 3283, 3112, 3241), 0), + EDGEVILLE_BANK("Edge Bank", new Location(3090, 3499, 3099, 3487), 0), + EDGEVILLE_DUNGEON("Edgeville Dungeon - Main Corridor (Paddewwa Tele)", new Location(3091, 9890, 3105, 9866), 0), + EDGEVILLE_DUNGEON_HILLGIANTS("Varrock Underground - Hill Giants", new Location(3095, 9854, 3125, 9821), 0), + EDGEVILLE_DUNGEON_HOB_GOBLINS("Edgeville Dungeon - Hob Goblins", new Location(3115, 9880, 3143, 9857), 0), + EDGEVILLE_DUNGEON_SLAYER_MASTER("Edgeville Dungeon - Slayer Master", new Location(3128, 9917, 3151, 9881), 0), + GRAND_EXCHANGE("Grand Exchange", new Location(3155, 3499, 3174, 3480), 0), + GRAND_EXCHANGE_AGILITY_SHORTCUT("GE Agility Shortcut", new Location(3136, 3518, 3143, 3511), 0), + GRAND_EXCHANGE_ENTRANCE("GE Entrance", new Location(3159, 3472, 3170, 3460), 0), + HAM_DUNGEON("H.A.M. Dungeon", new Location(3138, 9660, 3191, 9604), 0), + HAM_ENTRANCE("H.A.M. Hideout", new Location(3159, 3254, 3172, 3243), 0), + LUMBERYARD("Lumberyard", new Location(3289, 3520, 3327, 3488), 0), + LUMBRIDGE_BASEMENT("Lumbridge Basement", new Location(3206, 9626, 3221, 9613), 0), + LUMBRIDGE_CASTLE("Lumbridge Castle", new Location(3201, 3235, 3225, 3201), 0), + LUMBRIDGE_SWAMP("Lumby Swamp", new Location(3135, 3203, 3245, 3140), 0), + LUMBRIDGE_SWAMP_CAVES("Lumbridge Swamp Caves", new Location(3142, 9598, 3260, 9537), 0), + PATERDOMUS("Priest in Peril Temple", new Location(3404, 3495, 3419, 3481), 0), + SENNTISTEN_TELEPORT("Senntisten Tele", new Location(3305, 3342, 3319, 3328), 0), + SILVAREA("Rag and Bone Man", new Location(3350, 3505, 3378, 3492), 0), + STRONGHOLD_OF_SECURITY_FLOOR_1("Stronghold of Security - Floor 1 (Minatours)", new Location(1855, 5246, 1917, 5183), 0), + STRONGHOLD_OF_SECURITY_FLOOR_2("Stronghold of Security - Floor 2 (Flesh Crawlers)", new Location(1983, 5246, 2049, 5183), 0), + STRONGHOLD_OF_SECURITY_FLOOR_3("Stronghold of Security - Floor 3 (Catablepons)", new Location(2113, 5310, 2178, 5248), 0), + STRONGHOLD_OF_SECURITY_FLOOR_4("Stronghold of Security - Floor 4 (Ankous)", new Location(2302, 5249, 2367, 5185), 0), + VARROCK_CHURCH("Varrock Church", new Location(3249, 3488, 3259, 3471), 0), + VARROCK_BANK_EAST("Varrock East Bank", new Location(3246, 3428, 3261, 3412), 0), + VARROCK_BANK_WEST("Varrock West Bank", new Location(3172, 3450, 3197, 3425), 0), + VARROCK_MAGIC_SHOP("Varrock Magic Shop", new Location(3249, 3405, 3256, 3398), 0), + VARROCK_MINE("Varrock Mine", new Location(3278, 3372, 3294, 3355), 0), + VARROCK_MOSS_GIANTS("Varrock Sewers - Moss Giants", new Location(3190, 9910, 3153, 9876), 0), + VARROCK_MUSEUM("Varrock Museum", new Location(3249, 3455, 3267, 3442), 0), + VARROCK_PALACE("Varrock Palace", new Location(3198, 3502, 3228, 3455), 0), + VARROCK_SEWERS("Varrock Sewers", new Location(3200, 9918, 3285, 9857), 0), + VARROCK_SQUARE("Varrock Square", new Location(3201, 3444, 3229, 3412), 0), + WIZARDS_TOWER("Wizards Tower", new Location(3093, 3171, 3121, 3146), 0), + + /*- + * Morytania + * Abandoned Mine + * Barrows + * Burgh de Rott + * Canifis + * Darkmeyer + * Fenkenstrain's Castle + * Hallowvale + * Haunted Woods + * Meiyerditch + * Mort'ton + * Mort Myre Swamp + * Port Phasmatys + * Slepe + * The Sisterhood Sanctuary (Nightmare Dungeon) + */ + ABANDONED_MINE("Haunted Mine", new Location(3426, 3260, 3459, 3205), 0), + BARROWS("Barrows", new Location(3546, 3314, 3583, 3268), 0), + BARROWS_CRYPT("Barrows Crypt", new Location(3523, 9723, 3580, 9666), 0), + BURGH_DE_ROTT("Burgh de Rott", new Location(3474, 3247, 3535, 3189), 0), + CANIFIS_BANK("Canifis Bank", new Location(3508, 3483, 3516, 3474), 0), + CANIFIS_ZONE("Canifis", new Location(3472, 3506, 3519, 3467), 0), + CROMBWICK_MANOR("Crombwick Manor in Slepe", new Location(3710, 3377, 3742, 3341), 0), + DARKMEYER_BANK("Darkmeyer Bank", new Location(3600, 3370, 3610, 3364), 0), + DARKMEYER_ZONE("Darkmeyer", new Location(3592, 3392, 3662, 3331), 0), + FENKENSTRAINS_CASTLE("Fenkenstrain's Castle", new Location(3533, 3568, 3564, 3534), 0), + ECTOFUNTUS("Ectofuntus", new Location(3651, 3528, 3668, 3510), 0), + HALLOWED_SEPULCHER_ENTRANCE("Hallowed Sepulcher Entrance", new Location(3649, 3389, 3659, 3379), 0), + HALLOWED_SEPULCHER_LOBBY("Hallowed Sepulcher Lobby", new Location(2383, 5996, 2417, 5963), 0), + MORT_TON("Mort'ton", new Location(3473, 3301, 3504, 3271), 0), + MORYTANIA_FARM_PATCH("Morytania Farming Patch", new Location(3596, 3531, 3607, 3520), 0), + MORYTANIA_SWAMP_NORTH("Northern half of Morytania Swamp", new Location(3412, 3450, 3481, 3410), 0), + MORYTANIA_SWAMP_SOUTH("Southern half of Morytania Swamp", new Location(3412, 3410, 3481, 3370), 0), + NATURE_GROTTO("Nature Grotto", new Location(3410, 3356, 3461, 3322), 0), + NIGHTMARE_BOSS("The Nightmare", new Location(3798, 9769, 3818, 9749), 1), + PORT_PHASMATYS_BANK("Port Phasmatys Bank", new Location(3686, 3471, 3699, 3461), 0), + PORT_PHASMATYS_DOCKS("Port Phasmatys Docks", new Location(3689, 3512, 3711, 3481), 0), + PORT_PHASMATYS_PUB("Port Phasmatys Pub", new Location(3671, 3499, 3681, 3489), 0), + PORT_PHASMATYS_SOUTH_GATE("Port Phasmatys South Gate", new Location(3663, 3455, 3674, 3445), 0), + SALVE_GRAVEYARD("Salve Graveyard", new Location(3425, 3468, 3438, 3457), 0), + SISTERHOOD_SANCTUARY("Sisterhood Sanctuary (Slepe Dungeon)", new Location(3720, 9832, 3898, 9690), 1), + SLAYER_TOWER("Slayer Tower", new Location(3403, 3579, 3454, 3530), 0), + SLEPE("Slepe", new Location(3692, 3381, 3750, 3293), 0), + SWAMP_LIZARDS("Swamp Lizards", new Location(3521, 3451, 3568, 3426), 0), + VER_SINHAZA("ToB", new Location(3640, 3236, 3685, 3202), 0), + + /*- + * Tirannwn + * Arandar + * Gwenith + * Iowerth Dungeon + * Isafdar + * Lletya + * Mynydd + * Poison Waste + * Port Tyras + * Prifddinas + * Tyras Camp + * Zul-Andra + */ + LLETYA("Lletya", new Location(2312, 3196, 2362, 3145), 0), + ELF_CAMP("Elf Camp", new Location(2212, 3265, 2182, 3237), 0), + GWENTIH("Gwenith", new Location(2187, 3425, 2220, 3393), 0), + PRIFDDINAS("Prifddinas", new Location(3221, 6056, 3241, 6039), 0), // Fallback if there are gaps + PRIFDDINAS_BANK_NORTH("Prifddinas North Bank", new Location(3254, 6113, 3260, 6101), 0), + PRIFDDINAS_BANK_SOUTH("Prifddinas South Bank", new Location(3288, 6067, 3304, 6052), 0), + PRIFDDINAS_CITY_CENTER("Prifddinas Center", new Location(3246, 6100, 3281, 6065), 0), + PRIFDDINAS_CITY_E("Eastern Part of Prifddinas", new Location(3282, 6100, 3305, 6065), 0), + PRIFDDINAS_CITY_N("Northern Part of Prifddinas", new Location(3246, 6124, 3281, 6101), 0), + PRIFDDINAS_CITY_NE("North-Eastern Prifddinas", new Location(3282, 6136, 3319, 6101), 0), + PRIFDDINAS_CITY_NW("North-Western Prifddinas", new Location(3208, 6135, 3245, 6101), 0), + PRIFDDINAS_CITY_S("Southern Part of Prifddinas", new Location(3246, 6064, 3281, 6040), 0), + PRIFDDINAS_CITY_SE("South-Eastern Prifddinas", new Location(3282, 6039, 3321, 6023), 0), + PRIFDDINAS_CITY_SW("South-Western Prifddinas", new Location(3207, 6064, 3245, 6023), 0), + PRIFDDINAS_CITY_W("Western Part of Prifddinas", new Location(3222, 6100, 3245, 6065), 0), + PRIFDDINAS_GATE_EAST("Prifddinas East Gate (Arandar / Elven Pass)", new Location(2297, 3334, 2323, 3305), 0), + PRIFDDINAS_GATE_EAST_INSIDE("Prifddinas East Gate", new Location(3306, 6100, 3319, 6064), 0), + PRIFDDINAS_GATE_NORTH("Prifddinas North Gate", new Location(2230, 3387, 2249, 3384), 0), + PRIFDDINAS_GATE_NORTH_INSIDE("Prifddinas North Gate", new Location(3246, 6136, 3281, 6125), 0), + PRIFDDINAS_GATE_SOUTH("Prifddinas South Gate", new Location(2229, 3270, 2252, 3251), 0), + PRIFDDINAS_GATE_SOUTH_INSIDE("Prifddinas South Gate", new Location(3246, 6039, 3281, 6024), 0), + PRIFDDINAS_GATE_WEST("Prifddinas West Gate (Docks)", new Location(2154, 3338, 2182, 3317), 0), + PRIFDDINAS_GATE_WEST_INSIDE("Prifddinas West Gate", new Location(3207, 6100, 3221, 6065), 0), + PRIFDDINAS_GAUNTLET_PORTAL("Prifddinas Gauntlet Portal", new Location(3224, 6112, 3243, 6087), 0), + PRIFDDINAS_POH_PORTAL("Prifddinas POH Portal", new Location(3230, 6081, 3247, 6067), 0), + PRIFDDINAS_RED_CHINS("Prifddinas Red Chins", new Location(2255, 3418, 2283, 3397), 0), + PRIFDDINAS_SLAYER_CAVE_ENTRANCE("Prifddinas Slayer Cave Entrance", new Location(3221, 6056, 3241, 6039), 0), + PRIFDDINAS_ZALCANO_ENTRANCE("Prifddinas Zalcano Entrance", new Location(3277, 6065, 3287, 6053), 0), + TYRAS_CAMP("Tyras Camp", new Location(2168, 3163, 2201, 3134), 0), + TYRAS_DOCKS("Port Tyras", new Location(2135, 3133, 2167, 3110), 0), + ZALCANO("Zalcano", new Location(3019, 6074, 3048, 6035), 0), + GAUNTLET_LOBBY("Gauntlet Lobby", new Location(3025, 6130, 3040, 6115), 1), + ZUL_ANDRA("Zul-Andra", new Location(2182, 3070, 2214, 3042), 0), + + /*- + * Troll Country + * Death Plateau + * God Wars Dungeon + * Ice Path + * Troll Stronghold + * Trollheim + * Trollweiss Mountain + * Weiss + */ + DEATH_PLATEAU("Death Plateau", new Location(2838, 3610, 2880, 3580), 0), + GOD_WARS_DUNGEON("GWD", new Location(2820, 5375, 2944, 5253), 2), + GOD_WARS_DUNGEON_ENTRANCE("GWD Entrance", new Location(2904, 3756, 2921, 3742), 0), + TROLL_STRONGHOLD("Troll Stronghold", new Location(2836, 3698, 2862, 3659), 0), + TROLLHEIM_TELEPORT("Trollheim Tele", new Location(2882, 3685, 2899, 3669), 0), + WEISS("Weiss", new Location(2837, 3967, 2890, 3914), 0), + + /* + * Dungeons, Caves, Islands and other miscellaneous areas + */ + ABYSS("Abyss", new Location(3010, 4862, 3068, 4804), 0), + ABYSSAL_AREA("Abyssal Area", new Location(3008, 4926, 3071, 4864), 0), + ABYSSAL_NEXUS("Abyssal Nexus", new Location(3010, 4803, 3068, 4756), 0), + BLAST_FURNACE("Blast Furnace", new Location(1934, 4974, 1958, 4955), 0), + CAVE_HORROR_ENTRANCE("Mos Le'Harmless Cave Entrance (Cave Horrors)", new Location(3737, 2986, 3759, 2961), 0), + COSMIC_ALTAR("Zanaris Cosmic Altar", new Location(2400, 4387, 2425, 4367), 0), + DWARVEN_MINE_CAMP("Dwarven Mine - North Exit", new Location(3013, 9854, 3033, 9820), 0), + DWARVEN_MINE_CART("Dwarven Mine - Cart Transport", new Location(2988, 9849, 3006, 9821), 0), + DWARVEN_MINE_FALADOR("Dwarven Mine - Falador Exit", new Location(3030, 9788, 3062, 9758), 0), + GORAK_PLANE("Gorak Plane", new Location(3006, 5377, 3070, 5313), 0), + FISHER_REALM("Fisher Realm (Fairy Ring BJR)", new Location(2622, 4738, 2688, 4667), 0), + HARMONY("Harmony Island", new Location(3778, 2879, 3835, 2816), 0), + MINING_GUILD("Mining Guild", new Location(3008, 9756, 3061, 9698), 0), + MOLE_LAIR("Mole Lair", new Location(1730, 5246, 1787, 5131), 0), + MOS_LE_HARMLESS("Mos Le'Harmless", new Location(3649, 3005, 3709, 2958), 0), + MOS_LE_HARMLESS_DOCKS("Mos Le'Harmless Docks", new Location(3664, 2957, 3692, 2929), 0), + MOTHERLODE_MINE("Motherlode Mine", new Location(3713, 5695, 3777, 5632), 0), + PEST_CONTROL("Pest Control", new Location(2630, 2679, 2682, 2627), 0), + PURO_PURO("Puro-Puro", new Location(2561, 4349, 2622, 4289), 0), + SORCERESS_GARDEN("Sorceress's Garden", new Location(2884, 5499, 2938, 5444), 0), + TROUBLE_BREWING("Trouble Brewing", new Location(3774, 3024, 3843, 2942), 0), + ZANARIS_BANK("Zanaris Bank", new Location(2374, 4468, 2390, 4451), 0), + ZANARIS("Zanaris", new Location(2398, 4478, 2460, 4419), 0), + + /* + * Wilderness Locations + */ + ANNAKARL_TELEPORT("GDZ", new Location(3279, 3895, 3296, 3875), 0), + AXE_HUT("Axe Hut", new Location(3187, 3962, 3194, 3957), 0), + BANDIT_CAMP("Bandit Camp", new Location(3017, 3712, 3059, 3681), 0), + BLACK_SALAMANDERS("Black Salamanders", new Location(3291, 3677, 3301, 3664), 0), + CALLISTO("Callisto", new Location(3266, 3863, 3315, 3827), 0), + CEMETERY("Cemetery", new Location(2956, 3767, 2996, 3736), 0), + CHAOS_ALTAR_PRAYER("Chaos Altar", new Location(2945, 3826, 2970, 3813), 0), + CHAOS_ALTAR_RUNECRAFT("Chaos Runecrafting Altar", new Location(3055, 3596, 3067, 3585), 0), + CHAOS_FANATIC("Chaos Fanatic", new Location(2971, 3854, 2992, 3834), 0), + CHAOS_TEMPLE("Chaos Temple", new Location(3220, 3632, 3255, 3593), 0), + BLACK_CHINCHOMPAS("Chins", new Location(3128, 3792, 3160, 3754), 0), + CORP_CAVE("Corp Cave", new Location(3201, 3684, 3219, 3672), 0), + CRAZY_ARCHAEOLOGIST("Crazy Archaeologist", new Location(2952, 3709, 2985, 3678), 0), + DARK_CRAB_TELEPORT("Dark Crab Tele", new Location(3343, 3800, 3355, 3780), 0), + DARK_WARRIORS("Dark Warriors", new Location(3014, 3648, 3046, 3616), 0), + DEEP_WILDERNESS_DUNGEON("Deep Wilderness Dungeon", new Location(3038, 10330, 3053, 10305), 0), + DEEP_WILDERNESS_DUNGEON_ENTRANCE("Deep Wild Dungeon", new Location(3042, 3929, 3051, 3920), 0), + DEEP_WILDERNESS_DUNGEON_FIRE_GIANTS("Deep Wilderness Dungeon Fire Giants", new Location(3035, 10349, 3060, 10331), 0), + DEEP_WILDERNESS_DUNGEON_WINES("Deep Wilderness Dungeon Wines", new Location(3013, 10365, 3060, 10350), 0), + DWARVES("Dwarves", new Location(3230, 3805, 3264, 3779), 0), + EDGEVILLE_DUNGEON_EARTH_WARRIORS("Edgeville Dungeon - Earth Warriors", new Location(3114, 9999, 3129, 9960), 0), + EDGEVILLE_DUNGEON_CHAOS_DRUIDS("Edgeville Dungeon - Chaos Druids", new Location(3104, 9944, 3135, 9923), 0), + EDGEVILLE_DUNGEON_SPIDERS("Edgeville Dungeon - Spiders", new Location(3104, 9959, 3135, 9945), 0), + EDGEVILLE_DUNGEON_BLACK_DEMONS("Edgeville Dungeon - Black Demons", new Location(3077, 9966, 3103, 9941), 0), + // is this label description intuitive? + ENTS("Ents", new Location(3300, 3627, 3320, 3584), 0), + FEROX_ENCLAVE("Ferox Enclave", new Location(3119, 3646, 3160, 3616), 0), + GLORY_HILL("Glory Hill", new Location(3331, 3890, 3348, 3866), 0), + GLORY_HOLE("Glory Hole", new Location(3352, 3897, 3386, 3869), 0), + CARRALLANGAR_GRAVES("Graves", new Location(3128, 3686, 3181, 3658), 0), + GREEN_DRAGONS_EAST("East Drags", new Location(3326, 3704, 3365, 3671), 0), + GREEN_DRAGONS_GRAVEYARD("Graveyard Drags", new Location(3129, 3717, 3172, 3691), 0), + GREEN_DRAGONS_WEST("West Drags", new Location(2960, 3627, 2992, 3598), 0), + HOBGOBLINS("Hobgoblins", new Location(3073, 3775, 3104, 3745), 0), + ICE_GATE("Ice Gate", new Location(2945, 3913, 2978, 3878), 0), + ICE_ROCK("Ice Rock", new Location(2957, 3942, 2984, 3929), 0), + KBD_CAGE("KBD CAGE", new Location(3007, 3855, 3021, 3839), 0), + LAVA_DRAGON_GAP("Gap", new Location(3238, 3855, 3258, 3841), 0), + LAVA_DRAGON_ISLE("Lava Drags", new Location(3175, 3857, 3221, 3805), 0), + LAVA_MAZE_DUNGEON("Lava Maze Dungeon", new Location(3075, 10239, 3008, 10291), 0), + LAVA_MAZE_TELE("Lava Maze Tele", new Location(3019, 3842, 3044, 3812), 0), + MAGE_ARENA("Mage Arena", new Location(3088, 3949, 3123, 3919), 0), + MAGE_BANK("Mage Bank", new Location(3082, 3960, 3103, 3952), 0), + MAGE_BANK_SAFE_ZONE("Mage Bank Safe Zone", new Location(2526, 4727, 2550, 4707), 0), + NEW_GATE("New Gate", new Location(3348, 3890, 3325, 3911), 0), + OBELISK_13("13s Port", new Location(3152, 3624, 3160, 3616), 0), + OBELISK_19("19s", new Location(3220, 3672, 3234, 3660), 0), +// OBELISK_27("27 GWDs Portal", new Location(3031, 3736, 3039, 3728), 0), + OBELISK_35("36 Port", new Location(3097, 3804, 3115, 3785), 0), + OBELISK_44("44s", new Location(2973, 3870, 2987, 3859), 0), + OBELISK_50("50 ports", new Location(3301, 3923, 3315, 3909), 0), + OLD_GATE("Old Gate", new Location(3211, 3906, 3238, 3882), 0), + PIRATE_HUT("Pirate Hut", new Location(3037, 3959, 3045, 3948), 0), + POISON_SPIDERS("Poison Spiders", new Location(3282, 3803, 3302, 3785), 0), + REV_CAVE_AGILITY_65("Rev Cave Green Dragon Agility Jump", new Location(3216, 10090, 3226, 10080), 0), + REV_CAVE_AGILITY_75_1("Rev Cave 75 Agility Jump", new Location(3195, 10200, 3212, 10190), 0), + REV_CAVE_AGILITY_75_2("Rev Cave 75 Agility Jump (North of Ankous)", new Location(3173, 10214, 3186, 10205), 0), + REV_CAVE_AGILITY_89("Rev Cave 89 Agility Jump", new Location(3233, 10148, 3244, 10140), 0), + REV_CAVE_ANKOUS("Rev Cave Ankous", new Location(3160, 10204, 3191, 10177), 0), + REV_CAVE_BLACK_DEMONS("Rev Cave Black Demons", new Location(3158, 10171, 3187, 10145), 0), + REV_CAVE_BLACK_DRAGS("Rev Cave Black Drags", new Location(3223, 10216, 3254, 10190), 0), + REV_CAVE_CORRIDOR_NORTH("Revenant Cave Corridor", new Location(3255, 10213, 3263, 10191), 0), + REV_CAVE_CORRIDOR_SOUTH("Rev Cave Green Dragon Corridor", new Location(3238, 10106, 3252, 10077), 0), + REV_CAVE_ENTRANCE_NORTH("Rev Entrance", new Location(3118, 3837, 3142, 3818), 0), + REV_CAVE_ENTRANCE_SOUTH("South Rev Entrance", new Location(3071, 3660, 3092, 3645), 0), + REV_CAVE_EXIT_NORTH("Rev Cave North Exit", new Location(3238, 10236, 3243, 10231), 0), + REV_CAVE_EXIT_SOUTH("Rev Cave South Exit", new Location(3190, 10062, 3215, 10052), 0), + REV_CAVE_GREATER_DEMONS("Rev Cave Greater Demons", new Location(3210, 10140, 3240, 10115), 0), + REV_CAVE_GREEN_DRAGONS_1("Rev Cave Green Dragons", new Location(3215, 10078, 3234, 10052), 0), + REV_CAVE_GREEN_DRAGONS_2("Rev Cave Green Dragons", new Location(3200, 10106, 3231, 10091), 0), + REV_CAVE_HELL_HOUNDS("Rev Cave Hell Hounds", new Location(3190, 10078, 3210, 10063), 0), + REV_CAVE_ICE_GIANTS("Rev Cave Ice Giants", new Location(3200, 10173, 3221, 10155), 0), + REV_CAVE_LESSER_DEMONS("Rev Cave Lesser Demons", new Location(3143, 10125, 3176, 10104), 0), + REVENANT_DARK_BEAST("Revenant Dark Beast", new Location(3244, 10154, 3260, 10136), 0), + REVENANT_MAIN_CHAMBER("Main Rev Chamber", new Location(3227, 10187, 3261, 10157), 0), + ROGUE_CASTLE("Rogue Castle", new Location(3275, 3947, 3299, 3920), 0), + RUNE_ROCKS("Rune Rocks", new Location(3055, 3890, 3072, 3876), 0), + SCORPIA("Scorpia", new Location(3216, 3949, 3248, 3935), 0), + SPERM_HILL("Sperm Hill", new Location(3282, 3687, 3300, 3677), 0), + SPIDER_HILL("Spider Hill", new Location(3156, 3896, 3182, 3871), 0), + VENENATIS("Venenatis", new Location(3298, 3759, 3353, 3722), 0), + VETTION("Vet'tion", new Location(3183, 3796, 3227, 3765), 0), + VOLCANO("Volcano", new Location(3345, 3957, 3390, 3916), 0), + WEB("Web", new Location(3153, 3961, 3163, 3948), 0), + WILDY_AGILITY_COURSE("Wildy Agility Course", new Location(2988, 3967, 3008, 3906), 0), + WILDERNESS_GOD_WARS_DUNGEON("God Wars Dungeon", new Location(3010, 3745, 3027, 3727), 0), + WILDERNESS_GOD_WARS("Wildy GWD Chamber", new Location(3012, 10168, 3068, 10113), 0), + WILDERNESS_LEVER("Lever", new Location(3149, 3933, 3162, 3917), 0), + WILDERNESS_RESOURCE_AREA("Resource Area", new Location(3174, 3946, 3195, 3923), 0), + ZAMORAK_MAGE("Zammy Mage", new Location(3099, 3561, 3107, 3553), 0); + + @Getter + private final String name; + @Getter + private final WorldArea worldArea; + @Getter + private final Location location; + @Getter + private static final Map LOCATION_MAP; + + static + { + ImmutableMap.Builder builder = ImmutableMap.builder(); + + for (WorldLocation value : values()) + { + builder.put(value.getWorldArea(), value.getName()); + } + + LOCATION_MAP = builder.build(); + } + + /** + * Creates a location used to get the name of a location by a WorldPoint + * + * @param name - The name that is used to represent the area in overlays etc + * @param location - A Location made out of 4 points on the world map + * @param plane - The plane of the World Area + */ + WorldLocation(String name, Location location, int plane) + { + this.name = name; + this.location = location; + this.worldArea = new WorldArea(location.x, location.y, location.width, location.height, plane); + } + + /** + * Returns all locations that aren't in the wild + * + * @return - A Collection of non-wilderness WorldLocations + */ + public static Collection getNonWildernessLocations() + { + return Arrays.stream(WorldLocation.values()).filter(loc -> + PvPUtil.getWildernessLevelFrom(loc.worldArea.toWorldPoint()) < 0).collect(Collectors.toList()); + } + + /** + * Returns only the WorldLocations that are in the wilderness + * + * @return - A Collection of WorldLocations in the wilderness + */ + public static Collection getWildernessLocations() + { + return Arrays.stream(WorldLocation.values()).filter(loc -> + PvPUtil.getWildernessLevelFrom(loc.worldArea.toWorldPoint()) > 0).collect(Collectors.toList()); + } + + /** + * Returns the WorldLocation that a WorldPoint is in, or the closest WorldLocation to the point + * + * @param worldPoint - the WorldPoint to find the WorldLocation of + * @return - Containing location or closest location if it isn't in any + */ + public static String location(WorldPoint worldPoint) + { + int dist = 128; // x2 Region lengths + String s = ""; + WorldArea closestArea = null; + + for (Map.Entry entry : LOCATION_MAP.entrySet()) + { + final WorldArea worldArea = entry.getKey(); + + if (worldArea.toWorldPointList().contains(worldPoint)) + { + s = entry.getValue(); + return s; + } + + final int distTo = worldArea.distanceTo(worldPoint); + + if (distTo < dist) + { + dist = distTo; + closestArea = worldArea; + } + } + + if (closestArea == null) + { + return s; + } + + if (worldPoint.getY() > closestArea.toWorldPoint().getY() + closestArea.getHeight()) + { + s = s + "N"; + } + + if (worldPoint.getY() < closestArea.toWorldPoint().getY()) + { + s = s + "S"; + } + + if (worldPoint.getX() < closestArea.toWorldPoint().getX()) + { + s = s + "W"; + } + + if (worldPoint.getX() > (closestArea.toWorldPoint().getX() + closestArea.getWidth())) + { + s = s + "E"; + } + + s = s + " of "; + s = s + LOCATION_MAP.get(closestArea); + + if (s.startsWith(" of ")) + { + s = s.substring(3); + } + + return s; + } + + + public static class Location + { + @Getter + private final int x; + @Getter + private final int y; + @Getter + private final int x1; + @Getter + private final int y1; + final int width; + final int height; + + Location(int x, int y, int x1, int y1) + { + this.x = Math.min(x, x1); + this.y = Math.min(y, y1); + this.x1 = Math.max(x, x1); + this.y1 = Math.max(y, y1); + this.width = Math.abs(x1 - x); + this.height = Math.abs(y1 - y); + } + + @Override + public String toString() + { + return "Location{" + + "x=" + x + + ", y=" + y + + ", width=" + width + + ", height=" + height + + '}'; + } + } + + @Override + public String toString() + { + return "WorldLocation{" + + "name='" + name + '\'' + + ", worldArea=" + worldArea + + '}'; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/graphics/ModelOutlineRenderer.java b/runelite-client/src/main/java/com/openosrs/client/graphics/ModelOutlineRenderer.java new file mode 100644 index 0000000000..5e2f10445f --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/graphics/ModelOutlineRenderer.java @@ -0,0 +1,1113 @@ +/* + * Copyright (c) 2018, Woox + * 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 com.openosrs.client.graphics; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import lombok.RequiredArgsConstructor; +import lombok.Value; +import net.runelite.api.Client; +import net.runelite.api.DecorativeObject; +import net.runelite.api.GameObject; +import net.runelite.api.GroundObject; +import net.runelite.api.MainBufferProvider; +import net.runelite.api.Model; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.Perspective; +import net.runelite.api.Player; +import net.runelite.api.ItemLayer; +import net.runelite.api.TileObject; +import net.runelite.api.WallObject; +import net.runelite.api.coords.LocalPoint; +import net.runelite.client.task.Schedule; + +@Singleton +public class ModelOutlineRenderer +{ + /* + * This class doesn't really "need" static variables, but they are + * static for performance reasons. Arrays are kept outside methods + * to avoid frequent big allocations. Arrays should mostly be seen + * as ArrayLists. The size of them is increased whenever they need + * to become bigger. + */ + + private final Client client; + + private boolean isReset; + private boolean usedSinceLastCheck; + + // Dimensions of the underlying image + private int imageWidth; + private int imageHeight; + + // Boundaries for the current rasterization + private int clipX1; + private int clipY1; + private int clipX2; + private int clipY2; + + // Pixel points that would be rendered to + private int[] visited; + private int currentVisitedNumber = 0; + + // Transformed vertex positions + private int[] projectedVerticesX; + private int[] projectedVerticesY; + private boolean[] projectedVerticesRenderable; + + // An array of pixel points to raster onto the image. These are checked against + // clip boundaries and the visited array to prevent drawing on top of the model + // and outside the scene area. They are grouped per distance to the closest pixel + // drawn on the model. + private int[][] outlinePixels; + private int[] outlinePixelsLengths; // outlinePixelsLength[i] is the used length of outlinePixels[i] + private int outlineArrayWidth; + + // A list of pixel distances ordered from shortest to longest distance for + // each outline width. These are calculated once upon first usage and then + // stored here to prevent reevaluation. + private List> precomputedDistancePriorities; + + @Inject + private ModelOutlineRenderer(Client client) + { + this.client = client; + + reset(); + } + + @Schedule(period = 5, unit = ChronoUnit.SECONDS) + public void checkUsage() + { + if (!isReset && !usedSinceLastCheck) + { + // Reset memory allocated when the rasterizer becomes inactive + reset(); + } + usedSinceLastCheck = false; + } + + /** + * Reset memory used by the rasterizer + */ + private void reset() + { + visited = new int[0]; + projectedVerticesX = new int[0]; + projectedVerticesY = new int[0]; + projectedVerticesRenderable = new boolean[0]; + outlinePixels = new int[0][]; + outlinePixelsLengths = new int[0]; + precomputedDistancePriorities = new ArrayList<>(0); + isReset = true; + } + + /** + * Calculate the next power of two of a value + * + * @param value The value to find the next power of two of + * @return Returns the next power of two + */ + private static int nextPowerOfTwo(int value) + { + value--; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value++; + return value; + } + + /** + * Determine if a triangle goes counter clockwise + * + * @return Returns true if the triangle goes counter clockwise and should be culled, otherwise false + */ + private static boolean cullFace(int x1, int y1, int x2, int y2, int x3, int y3) + { + return + (y2 - y1) * (x3 - x2) - + (x2 - x1) * (y3 - y2) < 0; + } + + /** + * Gets the list of pixel distances ordered by distance from closest pixel for a specific outline width. + * + * @param outlineWidth The outline width + * @return Returns the list of pixel distances + */ + private List getPriorityList(int outlineWidth) + { + while (precomputedDistancePriorities.size() <= outlineWidth) + { + precomputedDistancePriorities.add(null); + } + + // Grab the cached outline width if we have one + if (precomputedDistancePriorities.get(outlineWidth) != null) + { + return precomputedDistancePriorities.get(outlineWidth); + } + + List ps = new ArrayList<>(); + for (int x = 0; x <= outlineWidth; x++) + { + for (int y = 0; y <= outlineWidth; y++) + { + if (x == 0 && y == 0) + { + continue; + } + + double dist = Math.sqrt(x * x + y * y); + if (dist > outlineWidth) + { + continue; + } + + int outerAlpha = outlineWidth == 1 ? 255 // For preventing division by 0 + : (int) (255 * (dist - 1) / (outlineWidth - 1)); + ps.add(new PixelDistanceAlpha(outerAlpha, x + y * outlineArrayWidth)); + } + } + ps.sort(Comparator.comparingDouble(PixelDistanceAlpha::getOuterAlpha)); + precomputedDistancePriorities.set(outlineWidth, ps); + + return ps; + } + + /** + * Checks that the size of outlinePixels is big enough to hold a specific + * amount of elements. This is used to reduce the amount of if checks needed + * when adding elements to outlinePixels. + * + * @param distArrayPos The position in the array + * @param additionalMinimumSize The additional minimum size required + */ + private void ensureMinimumOutlineQueueSize(int distArrayPos, int additionalMinimumSize) + { + int minimumSize = outlinePixelsLengths[distArrayPos] + additionalMinimumSize; + while (outlinePixels[distArrayPos].length < minimumSize) + { + int[] newArr = new int[nextPowerOfTwo(minimumSize)]; + System.arraycopy(outlinePixels[distArrayPos], 0, newArr, 0, + outlinePixels[distArrayPos].length); + outlinePixels[distArrayPos] = newArr; + } + } + + /** + * Resets the visited flag for a specific amount of pixels + * + * @param pixelAmount The amount of pixels to reset + */ + private void resetVisited(int pixelAmount) + { + // The visited array is essentially a boolean array, but by + // making it an int array and checking if visited[i] == currentVisitedNumber + // and changing currentVisitedNumber for every new outline, we can essentially + // reset the whole array without having to iterate over every element + + if (visited.length < pixelAmount) + { + visited = new int[nextPowerOfTwo(pixelAmount)]; + currentVisitedNumber = 0; + } + + currentVisitedNumber++; + } + + /** + * Resets the pixels that are queued for outlining + * + * @param outlineWidth The width of the outline to reset pixels for + */ + private void resetOutline(int outlineWidth) + { + outlineArrayWidth = outlineWidth + 2; + + int arraySizes = outlineArrayWidth * outlineArrayWidth; + if (outlinePixels.length < arraySizes) + { + outlinePixels = new int[arraySizes][]; + outlinePixelsLengths = new int[arraySizes]; + for (int i = 0; i < arraySizes; i++) + { + outlinePixels[i] = new int[4]; + } + } + else + { + for (int i = 0; i < arraySizes; i++) + { + outlinePixelsLengths[i] = 0; + } + } + } + + /** + * Simulates a horizontal line rasterization and adds the pixels to the left + * and to the right to the outline queue if they are within the clip area. + * + * @param pixelPos The pixel position in the line where x == 0 + * @param x1 The starting x position + * @param x2 The ending x position + */ + private void simulateHorizontalLineRasterizationForOutline(int pixelPos, int x1, int x2) + { + if (x2 > clipX2) + { + x2 = clipX2; + } + if (x1 < clipX1) + { + x1 = clipX1; + } + if (x1 >= x2) + { + return; + } + + // Queue the pixel positions to the left and to the right of the line + ensureMinimumOutlineQueueSize(1, 2); + if (x2 < clipX2) + { + outlinePixels[1][outlinePixelsLengths[1]++] = pixelPos + x2; + } + if (x1 > clipX1) + { + outlinePixels[1][outlinePixelsLengths[1]++] = pixelPos + x1 - 1; + } + + // Divide by 4 to account for loop unrolling + int xDist = x2 - x1 >> 2; + pixelPos += x1; + + // This loop could run over 100m times per second without loop unrolling in some cases, + // so unrolling it can give a noticeable performance boost. + while (xDist-- > 0) + { + visited[pixelPos++] = currentVisitedNumber; + visited[pixelPos++] = currentVisitedNumber; + visited[pixelPos++] = currentVisitedNumber; + visited[pixelPos++] = currentVisitedNumber; + } + + // Draw up to 3 more pixels if there were any left + xDist = (x2 - x1) & 3; + while (xDist-- > 0) + { + visited[pixelPos++] = currentVisitedNumber; + } + } + + /** + * Queues the pixel positions above and below two horizontal lines, excluding those + * where the x positions of the lines intersect. + * + * @param pixelPos The pixel position at x == 0 of the second line + * @param x1 The starting x position of the first line + * @param x2 The ending x position of the first line + * @param x3 The starting x position of the second line + * @param x4 The ending x position of the second line + */ + private void outlineAroundHorizontalLine(int pixelPos, int x1, int x2, int x3, int x4) + { + if (x1 < clipX1) + { + x1 = clipX1; + } + if (x2 < clipX1) + { + x2 = clipX1; + } + if (x3 < clipX1) + { + x3 = clipX1; + } + if (x4 < clipX1) + { + x4 = clipX1; + } + + if (x1 > clipX2) + { + x1 = clipX2; + } + if (x2 > clipX2) + { + x2 = clipX2; + } + if (x3 > clipX2) + { + x3 = clipX2; + } + if (x4 > clipX2) + { + x4 = clipX2; + } + + if (x1 < x3) + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x3 - x1); + for (int x = x1; x < x3; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos - imageWidth + x; + } + } + else + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x1 - x3); + for (int x = x3; x < x1; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos + x; + } + } + + if (x2 < x4) + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x4 - x2); + for (int x = x2; x < x4; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos + x; + } + } + else + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x2 - x4); + for (int x = x4; x < x2; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos - imageWidth + x; + } + } + } + + /** + * Simulates rasterization of a triangle and adds every pixel outside the triangle + * to the outline queue. + * + * @param x1 The x position of the first vertex in the triangle + * @param y1 The y position of the first vertex in the triangle + * @param x2 The x position of the second vertex in the triangle + * @param y2 The y position of the second vertex in the triangle + * @param x3 The x position of the third vertex in the triangle + * @param y3 The y position of the third vertex in the triangle + */ + private void simulateTriangleRasterizationForOutline(int x1, int y1, int x2, int y2, int x3, int y3) + { + // Swap vertices so y1 <= y2 <= y3 using bubble sort + if (y1 > y2) + { + int yp = y1; + int xp = x1; + y1 = y2; + y2 = yp; + x1 = x2; + x2 = xp; + } + if (y2 > y3) + { + int yp = y2; + int xp = x2; + y2 = y3; + y3 = yp; + x2 = x3; + x3 = xp; + } + if (y1 > y2) + { + int yp = y1; + int xp = x1; + y1 = y2; + y2 = yp; + x1 = x2; + x2 = xp; + } + + if (y1 > clipY2) + { + // All points are outside clip boundaries + return; + } + + int slope1 = 0; + if (y1 != y2) + { + slope1 = (x2 - x1 << 14) / (y2 - y1); + } + + int slope2 = 0; + if (y3 != y2) + { + slope2 = (x3 - x2 << 14) / (y3 - y2); + } + + int slope3 = 0; + if (y1 != y3) + { + slope3 = (x1 - x3 << 14) / (y1 - y3); + } + + if (y2 > clipY2) + { + y2 = clipY2; + } + if (y3 > clipY2) + { + y3 = clipY2; + } + if (y1 == y3 || y3 < 0) + { + return; + } + + x1 <<= 14; + x2 <<= 14; + x3 = x1; + + if (y1 < 0) + { + x3 -= y1 * slope3; + x1 -= y1 * slope1; + y1 = 0; + } + if (y2 < 0) + { + x2 -= slope2 * y2; + y2 = 0; + } + + int pixelPos = y1 * imageWidth; + int currX1; + int currX2; + if (y1 != y2 && slope3 < slope1 || y1 == y2 && slope3 > slope2) + { + int height1 = y2 - y1; + int height2 = y3 - y2; + + int prevX1; + int prevX2; + if (height1 <= 0) + { + prevX1 = x3 >> 14; + prevX2 = x2 >> 14; + } + else + { + prevX1 = x3 >> 14; + prevX2 = x1 >> 14; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX2, prevX2, prevX2); + + while (height1-- > 0) + { + currX1 = x3 >> 14; + currX2 = x1 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x3 += slope3; + x1 += slope1; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + while (height2-- > 0) + { + currX1 = x3 >> 14; + currX2 = x2 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x3 += slope3; + x2 += slope2; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX1, prevX1, prevX2); + } + else + { + int height1 = y2 - y1; + int height2 = y3 - y2; + + int prevX1; + int prevX2; + if (height1 <= 0) + { + prevX1 = x2 >> 14; + prevX2 = x3 >> 14; + } + else + { + prevX1 = x1 >> 14; + prevX2 = x3 >> 14; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX2, prevX2, prevX2); + + while (height1-- > 0) + { + currX1 = x1 >> 14; + currX2 = x3 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x1 += slope1; + x3 += slope3; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + while (height2-- > 0) + { + currX1 = x2 >> 14; + currX2 = x3 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x3 += slope3; + x2 += slope2; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX1, prevX1, prevX2); + } + } + + /** + * Translates the vertices 3D points to the screen canvas 2D points + * + * @param localX The local x position of the vertices + * @param localY The local y position of the vertices + * @param localZ The local z position of the vertices + * @param vertexOrientation The orientation of the vertices + * @return Returns true if any of them are inside the clip area, otherwise false + */ + private boolean projectVertices(Model model, final int localX, final int localY, final int localZ, final int vertexOrientation) + { + final int cameraX = client.getCameraX(); + final int cameraY = client.getCameraY(); + final int cameraZ = client.getCameraZ(); + final int cameraYaw = client.getCameraYaw(); + final int cameraPitch = client.getCameraPitch(); + final int scale = client.getScale(); + final int orientationSin = Perspective.SINE[vertexOrientation]; + final int orientationCos = Perspective.COSINE[vertexOrientation]; + final int pitchSin = Perspective.SINE[cameraPitch]; + final int pitchCos = Perspective.COSINE[cameraPitch]; + final int yawSin = Perspective.SINE[cameraYaw]; + final int yawCos = Perspective.COSINE[cameraYaw]; + final int vertexCount = model.getVerticesCount(); + final int[] verticesX = model.getVerticesX(); + final int[] verticesY = model.getVerticesY(); + final int[] verticesZ = model.getVerticesZ(); + + boolean anyVisible = false; + + // Make sure the arrays are big enough + while (projectedVerticesX.length < vertexCount) + { + int newSize = nextPowerOfTwo(vertexCount); + projectedVerticesX = new int[newSize]; + projectedVerticesY = new int[newSize]; + projectedVerticesRenderable = new boolean[newSize]; + } + + for (int i = 0; i < vertexCount; i++) + { + int vx = verticesX[i]; + int vy = verticesZ[i]; + int vz = verticesY[i]; + int vh; // Value holder + + // Rotate based on orientation + vh = vx * orientationCos + vy * orientationSin >> 16; + vy = vy * orientationCos - vx * orientationSin >> 16; + vx = vh; + + // Translate to local coords + vx += localX; + vy += localY; + vz += localZ; + + // Translate to camera + vx -= cameraX; + vy -= cameraY; + vz -= cameraZ; + + // Transform to canvas + vh = vx * yawCos + vy * yawSin >> 16; + vy = vy * yawCos - vx * yawSin >> 16; + vx = vh; + vh = vz * pitchCos - vy * pitchSin >> 16; + vz = vz * pitchSin + vy * pitchCos >> 16; + vy = vh; + + if (vz >= 50) + { + projectedVerticesX[i] = (clipX1 + clipX2) / 2 + vx * scale / vz; + projectedVerticesY[i] = (clipY1 + clipY2) / 2 + vy * scale / vz; + + projectedVerticesRenderable[i] = true; + anyVisible |= + projectedVerticesX[i] >= clipX1 && projectedVerticesX[i] < clipX2 && + projectedVerticesY[i] >= clipY1 && projectedVerticesY[i] < clipY2; + } + else + { + projectedVerticesRenderable[i] = false; + } + } + + return anyVisible; + } + + /** + * Simulate rendering of the model and puts every pixel of the wireframe of + * the non-culled and non-transparent faces into the outline pixel queue. + */ + private void simulateModelRasterizationForOutline(Model model) + { + final int triangleCount = model.getTrianglesCount(); + final int[] indices1 = model.getTrianglesX(); + final int[] indices2 = model.getTrianglesY(); + final int[] indices3 = model.getTrianglesZ(); + final byte[] triangleTransparencies = model.getTriangleTransparencies(); + + for (int i = 0; i < triangleCount; i++) + { + if (projectedVerticesRenderable[indices1[i]] && + projectedVerticesRenderable[indices2[i]] && + projectedVerticesRenderable[indices3[i]] && + // 254 and 255 counts as fully transparent + (triangleTransparencies == null || (triangleTransparencies[i] & 255) < 254)) + { + final int index1 = indices1[i]; + final int index2 = indices2[i]; + final int index3 = indices3[i]; + final int v1x = projectedVerticesX[index1]; + final int v1y = projectedVerticesY[index1]; + final int v2x = projectedVerticesX[index2]; + final int v2y = projectedVerticesY[index2]; + final int v3x = projectedVerticesX[index3]; + final int v3y = projectedVerticesY[index3]; + + if (!cullFace(v1x, v1y, v2x, v2y, v3x, v3y)) + { + simulateTriangleRasterizationForOutline( + v1x, v1y, v2x, v2y, v3x, v3y); + } + } + } + } + + /** + * Draws an outline of the pixels in the outline queue to an image + * + * @param image The image to draw the outline to + * @param outlineWidth The width of the outline + * @param innerColor The color of the pixels of the outline closest to the model + * @param outerColor The color of the pixels of the outline furthest away from the model + */ + private void renderOutline(BufferedImage image, int outlineWidth, Color innerColor, Color outerColor) + { + int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + List ps = getPriorityList(outlineWidth); + + for (PixelDistanceAlpha p : ps) + { + int color; + int alpha; + if (outlineWidth == 1) + { + color = + ((innerColor.getRed() + outerColor.getRed()) << 15) | + ((innerColor.getGreen() + outerColor.getGreen() << 7)) | + ((innerColor.getBlue() + outerColor.getBlue() >> 1)); + alpha = (innerColor.getAlpha() + outerColor.getAlpha()) >> 1; + } + else + { + int outerAlpha = p.getOuterAlpha(); + int innerAlpha = 255 - outerAlpha; + int innerAlphaFraction = (innerAlpha * innerColor.getAlpha()) / 255; + int outerAlphaFraction = (outerAlpha * outerColor.getAlpha()) / 255; + alpha = innerAlphaFraction + outerAlphaFraction; + if (alpha != 0) + { + color = + ((innerColor.getRed() * innerAlphaFraction + + outerColor.getRed() * outerAlphaFraction) / alpha << 16) | + ((innerColor.getGreen() * innerAlphaFraction + + outerColor.getGreen() * outerAlphaFraction) / alpha << 8) | + ((innerColor.getBlue() * innerAlphaFraction + + outerColor.getBlue() * outerAlphaFraction) / alpha); + } + else + { + color = 0; + } + } + + final int distArrayPos = p.getDistArrayPos(); + final int nextDistArrayPosY = distArrayPos + outlineArrayWidth; + final int nextDistArrayPosX = distArrayPos + 1; + ensureMinimumOutlineQueueSize(nextDistArrayPosX, outlinePixelsLengths[distArrayPos] * 2); + ensureMinimumOutlineQueueSize(nextDistArrayPosY, outlinePixelsLengths[distArrayPos] * 2); + + // The following 3 branches do the same thing, but when the requirements are simple, + // there are less checks needed which can give a performance boost. + if (alpha == 255) + { + if (outlineWidth == 1) + { + for (int i2 = 0; i2 < outlinePixelsLengths[distArrayPos]; i2++) + { + int pixelPos = outlinePixels[distArrayPos][i2]; + int x = pixelPos % imageWidth; + int y = pixelPos / imageWidth; + if (x < clipX1 || x >= clipX2 || + y < clipY1 || y >= clipY2 || + visited[pixelPos] == currentVisitedNumber) + { + continue; + } + + imageData[pixelPos] = color; + } + } + else + { + for (int i2 = 0; i2 < outlinePixelsLengths[distArrayPos]; i2++) + { + int pixelPos = outlinePixels[distArrayPos][i2]; + int x = pixelPos % imageWidth; + int y = pixelPos / imageWidth; + if (x < clipX1 || x >= clipX2 || + y < clipY1 || y >= clipY2 || + visited[pixelPos] == currentVisitedNumber) + { + continue; + } + visited[pixelPos] = currentVisitedNumber; + + imageData[pixelPos] = color; + + if (pixelPos % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos - 1; + } + if ((pixelPos + 1) % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos + 1; + } + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos - imageWidth; + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos + imageWidth; + } + } + } + else + { + for (int i2 = 0; i2 < outlinePixelsLengths[distArrayPos]; i2++) + { + int pixelPos = outlinePixels[distArrayPos][i2]; + int x = pixelPos % imageWidth; + int y = pixelPos / imageWidth; + if (x < clipX1 || x >= clipX2 || + y < clipY1 || y >= clipY2 || + visited[pixelPos] == currentVisitedNumber) + { + continue; + } + visited[pixelPos] = currentVisitedNumber; + + imageData[pixelPos] = + ((((color & 0xFF0000) * alpha + (imageData[pixelPos] & 0xFF0000) * (255 - alpha)) / 255) & 0xFF0000) + + ((((color & 0xFF00) * alpha + (imageData[pixelPos] & 0xFF00) * (255 - alpha)) / 255) & 0xFF00) + + ((((color & 0xFF) * alpha + (imageData[pixelPos] & 0xFF) * (255 - alpha)) / 255) & 0xFF); + + if (pixelPos % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos - 1; + } + if ((pixelPos + 1) % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos + 1; + } + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos - imageWidth; + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos + imageWidth; + } + } + } + } + + /** + * Draws an outline around a model to an image + * + * @param localX The local x position of the model + * @param localY The local y position of the model + * @param localZ The local z position of the model + * @param orientation The orientation of the model + * @param outlineWidth The width of the outline + * @param innerColor The color of the pixels of the outline closest to the model + * @param outerColor The color of the pixels of the outline furthest away from the model + */ + private void drawModelOutline(Model model, int localX, int localY, int localZ, int orientation, int outlineWidth, Color innerColor, Color outerColor) + { + if (outlineWidth <= 0) + { + return; + } + + isReset = false; + usedSinceLastCheck = true; + + MainBufferProvider bufferProvider = (MainBufferProvider) client.getBufferProvider(); + BufferedImage image = (BufferedImage) bufferProvider.getImage(); + + clipX1 = client.getViewportXOffset(); + clipY1 = client.getViewportYOffset(); + clipX2 = client.getViewportWidth() + clipX1; + clipY2 = client.getViewportHeight() + clipY1; + imageWidth = image.getWidth(); + imageHeight = image.getHeight(); + final int pixelAmount = imageWidth * imageHeight; + + resetVisited(pixelAmount); + resetOutline(outlineWidth); + + if (!projectVertices(model, + localX, localY, localZ, orientation)) + { + // No vertex of the model is visible on the screen, so we can + // assume there are no parts of the model to outline. + return; + } + + simulateModelRasterizationForOutline(model); + + renderOutline(image, outlineWidth, innerColor, outerColor); + } + + public void drawOutline(NPC npc, int outlineWidth, Color color) + { + drawOutline(npc, outlineWidth, color, color); + } + + public void drawOutline(NPC npc, int outlineWidth, Color innerColor, Color outerColor) + { + int size = 1; + NPCComposition composition = npc.getTransformedComposition(); + if (composition != null) + { + size = composition.getSize(); + } + + LocalPoint lp = npc.getLocalLocation(); + if (lp != null) + { + // NPCs z position are calculated based on the tile height of the northeastern tile + final int northEastX = lp.getX() + Perspective.LOCAL_TILE_SIZE * (size - 1) / 2; + final int northEastY = lp.getY() + Perspective.LOCAL_TILE_SIZE * (size - 1) / 2; + final LocalPoint northEastLp = new LocalPoint(northEastX, northEastY); + + drawModelOutline(npc.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, northEastLp, client.getPlane()), + npc.getCurrentOrientation(), outlineWidth, innerColor, outerColor); + } + } + + public void drawOutline(Player player, int outlineWidth, Color color) + { + drawOutline(player, outlineWidth, color, color); + } + + public void drawOutline(Player player, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = player.getLocalLocation(); + if (lp != null) + { + drawModelOutline(player.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, client.getPlane()), + player.getCurrentOrientation(), outlineWidth, innerColor, outerColor); + } + } + + public void drawOutline(GameObject gameObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = gameObject.getLocalLocation(); + if (lp != null) + { + drawModelOutline(gameObject.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, gameObject.getPlane()), + gameObject.getRsOrientation(), outlineWidth, innerColor, outerColor); + } + } + + public void drawOutline(GroundObject groundObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = groundObject.getLocalLocation(); + if (lp != null) + { + drawModelOutline(groundObject.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, client.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + } + + private void drawOutline(ItemLayer tileItemPile, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = tileItemPile.getLocalLocation(); + if (lp != null) + { + Model model = tileItemPile.getModelBottom(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, tileItemPile.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + + model = tileItemPile.getModelMiddle(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, tileItemPile.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + + model = tileItemPile.getModelTop(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, tileItemPile.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + } + } + + private void drawOutline(DecorativeObject decorativeObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = decorativeObject.getLocalLocation(); + if (lp != null) + { + Model model = decorativeObject.getModel1(); + if (model != null) + { + drawModelOutline(model, + lp.getX() + decorativeObject.getXOffset(), + lp.getY() + decorativeObject.getYOffset(), + Perspective.getTileHeight(client, lp, decorativeObject.getPlane()), + decorativeObject.getOrientation(), outlineWidth, innerColor, outerColor); + } + + model = decorativeObject.getModel2(); + if (model != null) + { + // Offset is not used for the second model + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, decorativeObject.getPlane()), + decorativeObject.getOrientation(), outlineWidth, innerColor, outerColor); + } + } + } + + private void drawOutline(WallObject wallObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = wallObject.getLocalLocation(); + if (lp != null) + { + Model model = wallObject.getModelA(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, wallObject.getPlane()), + wallObject.getOrientationA(), outlineWidth, innerColor, outerColor); + } + + model = wallObject.getModelB(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, wallObject.getPlane()), + wallObject.getOrientationB(), outlineWidth, innerColor, outerColor); + } + } + } + + public void drawOutline(TileObject tileObject, int outlineWidth, Color color) + { + drawOutline(tileObject, outlineWidth, color, color); + } + + public void drawOutline(TileObject tileObject, + int outlineWidth, Color innerColor, Color outerColor) + { + if (tileObject instanceof GameObject) + { + drawOutline((GameObject) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof GroundObject) + { + drawOutline((GroundObject) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof ItemLayer) + { + drawOutline((ItemLayer) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof DecorativeObject) + { + drawOutline((DecorativeObject) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof WallObject) + { + drawOutline((WallObject) tileObject, outlineWidth, innerColor, outerColor); + } + } + + @Value + @RequiredArgsConstructor + class PixelDistanceAlpha + { + private final int outerAlpha; + private final int distArrayPos; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java index 06fd875d6d..0c4f611be5 100644 --- a/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java @@ -1,13 +1,24 @@ package com.openosrs.client.ui.overlay; + import java.awt.BasicStroke; import java.awt.Color; +import java.awt.Font; import java.awt.Graphics2D; import java.awt.Polygon; -import net.runelite.api.Client; -import net.runelite.api.Perspective; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.image.BufferedImage; +import java.util.List; +import net.runelite.api.*; +import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.vars.InterfaceTab; +import net.runelite.api.widgets.Widget; + public class OverlayUtil extends net.runelite.client.ui.overlay.OverlayUtil { @@ -39,4 +50,92 @@ public class OverlayUtil extends net.runelite.client.ui.overlay.OverlayUtil graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); graphics.fill(poly); } + + public static Rectangle renderPrayerOverlay(Graphics2D graphics, Client client, Prayer prayer, Color color) + { + Widget widget = client.getWidget(prayer.getWidgetInfo()); + + if (widget == null || client.getVar(VarClientInt.INVENTORY_TAB) != InterfaceTab.PRAYER.getId()) + { + return null; + } + + Rectangle bounds = widget.getBounds(); + renderPolygon(graphics, rectangleToPolygon(bounds), color); + return bounds; + } + + private static Polygon rectangleToPolygon(Rectangle rect) + { + int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; + int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height}; + + return new Polygon(xpoints, ypoints, 4); + } + + public static void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows, int yOffset) + { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) + { + final Point canvasCenterPoint = new Point( + canvasPoint.getX(), + canvasPoint.getY() + yOffset); + final Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() + 1, + canvasPoint.getY() + 1 + yOffset); + if (shadows) + { + renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + } + renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } + + public static void setProgressIcon(Graphics2D graphics, Point point, BufferedImage currentPhaseIcon, int totalWidth, int bgPadding, int currentPosX, Color colorIconBackground, int overlayIconDistance, Color colorIconBorder, Color colorIconBorderFill) + { + graphics.setStroke(new BasicStroke(2)); + graphics.setColor(colorIconBackground); + graphics.fillOval( + point.getX() - totalWidth / 2 + currentPosX - bgPadding, + point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance - bgPadding, + currentPhaseIcon.getWidth() + bgPadding * 2, + currentPhaseIcon.getHeight() + bgPadding * 2); + + graphics.setColor(colorIconBorder); + graphics.drawOval( + point.getX() - totalWidth / 2 + currentPosX - bgPadding, + point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance - bgPadding, + currentPhaseIcon.getWidth() + bgPadding * 2, + currentPhaseIcon.getHeight() + bgPadding * 2); + + graphics.drawImage( + currentPhaseIcon, + point.getX() - totalWidth / 2 + currentPosX, + point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance, + null); + + graphics.setColor(colorIconBorderFill); + } + + public static List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) + { + List little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList(); + List big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); + if (!includeUnder) + { + big.removeIf(little::contains); + } + return big; + } + + public static void renderFilledPolygon(Graphics2D graphics, Shape poly, Color color) + { + graphics.setColor(color); + final Stroke originalStroke = graphics.getStroke(); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(poly); + graphics.fill(poly); + graphics.setStroke(originalStroke); + } } diff --git a/runelite-client/src/main/java/com/openosrs/client/util/PvPUtil.java b/runelite-client/src/main/java/com/openosrs/client/util/PvPUtil.java new file mode 100644 index 0000000000..1f0120c75a --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/util/PvPUtil.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ +package com.openosrs.client.util; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemComposition; +import net.runelite.api.Player; +import net.runelite.api.Varbits; +import net.runelite.api.WorldType; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.geometry.Cuboid; +import net.runelite.client.game.ItemManager; +import net.runelite.client.util.QuantityFormatter; +import org.apache.commons.lang3.ArrayUtils; +import java.awt.Polygon; +import java.util.Comparator; +import java.util.Objects; +import java.util.TreeMap; + +public class PvPUtil +{ + private static final Polygon NOT_WILDERNESS_BLACK_KNIGHTS = new Polygon( // this is black knights castle + new int[]{2994, 2995, 2996, 2996, 2994, 2994, 2997, 2998, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3005, + 3005, 3019, 3020, 3022, 3023, 3024, 3025, 3026, 3026, 3027, 3027, 3028, 3028, 3029, 3029, 3030, 3030, 3031, + 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3037}, + new int[]{3525, 3526, 3527, 3529, 3529, 3534, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, + 3545, 3545, 3546, 3546, 3545, 3544, 3543, 3543, 3542, 3541, 3540, 3539, 3537, 3536, 3535, 3534, 3533, 3532, + 3531, 3530, 3529, 3528, 3527, 3526, 3526, 3525}, + 43 + ); + private static final Cuboid MAIN_WILDERNESS_CUBOID = new Cuboid(2944, 3525, 0, 3391, 4351, 3); + private static final Cuboid GOD_WARS_WILDERNESS_CUBOID = new Cuboid(3008, 10112, 0, 3071, 10175, 3); + private static final Cuboid WILDERNESS_UNDERGROUND_CUBOID = new Cuboid(2944, 9920, 0, 3391, 10879, 3); + + /** + * Gets the wilderness level based on a world point + * Java reimplementation of clientscript 384 [proc,wilderness_level] + * + * @param point the point in the world to get the wilderness level for + * @return the int representing the wilderness level + */ + public static int getWildernessLevelFrom(WorldPoint point) + { + if (MAIN_WILDERNESS_CUBOID.contains(point)) + { + if (NOT_WILDERNESS_BLACK_KNIGHTS.contains(point.getX(), point.getY())) + { + return 0; + } + + return ((point.getY() - 3520) / 8) + 1; // calc(((coordz(coord) - (55 * 64)) / 8) + 1) + } + else if (GOD_WARS_WILDERNESS_CUBOID.contains(point)) + { + return ((point.getY() - 9920) / 8) - 1; // calc(((coordz(coord) - (155 * 64)) / 8) - 1) + } + else if (WILDERNESS_UNDERGROUND_CUBOID.contains(point)) + { + return ((point.getY() - 9920) / 8) + 1; // calc(((coordz(coord) - (155 * 64)) / 8) + 1) + } + return 0; + } + + /** + * Determines if another player is attackable based off of wilderness level and combat levels + * + * @param client The client of the local player + * @param player the player to determine attackability + * @return returns true if the player is attackable, false otherwise + */ + public static boolean isAttackable(Client client, Player player) + { + int wildernessLevel = 0; + + if (WorldType.isDeadmanWorld(client.getWorldType())) + { + return true; + } + if (WorldType.isPvpWorld(client.getWorldType())) + { + wildernessLevel += 15; + } + if (client.getVar(Varbits.IN_WILDERNESS) == 1) + { + wildernessLevel += getWildernessLevelFrom(client.getLocalPlayer().getWorldLocation()); + } + return wildernessLevel != 0 && Math.abs(client.getLocalPlayer().getCombatLevel() - player.getCombatLevel()) <= wildernessLevel; + } + + public static int calculateRisk(Client client, ItemManager itemManager) + { + if (client.getItemContainer(InventoryID.EQUIPMENT) == null) + { + return 0; + } + if (client.getItemContainer(InventoryID.INVENTORY).getItems() == null) + { + return 0; + } + Item[] items = ArrayUtils.addAll(Objects.requireNonNull(client.getItemContainer(InventoryID.EQUIPMENT)).getItems(), + Objects.requireNonNull(client.getItemContainer(InventoryID.INVENTORY)).getItems()); + TreeMap priceMap = new TreeMap<>(Comparator.comparingInt(Integer::intValue)); + int wealth = 0; + for (Item i : items) + { + int value = (itemManager.getItemPrice(i.getId()) * i.getQuantity()); + + final ItemComposition itemComposition = itemManager.getItemComposition(i.getId()); + if (!itemComposition.isTradeable() && value == 0) + { + value = itemComposition.getPrice() * i.getQuantity(); + priceMap.put(value, i); + } + else + { + value = itemManager.getItemPrice(i.getId()) * i.getQuantity(); + if (i.getId() > 0 && value > 0) + { + priceMap.put(value, i); + } + } + wealth += value; + } + return Integer.parseInt(QuantityFormatter.quantityToRSDecimalStack(priceMap.keySet().stream().mapToInt(Integer::intValue).sum())); + + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/util/WeaponMap.java b/runelite-client/src/main/java/com/openosrs/client/util/WeaponMap.java new file mode 100644 index 0000000000..8dda59ad46 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/util/WeaponMap.java @@ -0,0 +1,832 @@ +package com.openosrs.client.util; + +import java.util.HashMap; +import net.runelite.api.ItemID; + +public class WeaponMap +{ + public static HashMap StyleMap = new HashMap<>(); + + static + { + //Melee + StyleMap.put(ItemID._3RD_AGE_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID._3RD_AGE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID._3RD_AGE_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_BLUDGEON, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER_P, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER_P_13269, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER_P_13271, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_TENTACLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_WHIP, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_WHIP_20405, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGERP_5676, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGERP_5694, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEARP_5712, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEARP_5726, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ALE_OF_THE_GODS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANCIENT_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.AMYS_SAW, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARCEUUS_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARCLIGHT, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD_20593, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD_22665, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ASSORTED_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD_20782, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD_21060, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BARBTAIL_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.BARRELCHEST_ANCHOR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BEACH_BOXING_GLOVES, WeaponStyle.MELEE); + StyleMap.put(ItemID.BEACH_BOXING_GLOVES_11706, WeaponStyle.MELEE); + StyleMap.put(ItemID.BIRTHDAY_BALLOONS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BIRTHDAY_CAKE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGERP_5682, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGERP_5700, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SALAMANDER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEARP_5734, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEARP_5736, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLADE_OF_SAELDOR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLADE_OF_SAELDOR_C, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLADE_OF_SAELDOR_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLESSED_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLISTERWOOD_SICKLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLUE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLUE_FLOWERS_8936, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLURITE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_CLUB, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER_P, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER_P_8876, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER_P_8878, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BOXING_GLOVES, WeaponStyle.MELEE); + StyleMap.put(ItemID.BOXING_GLOVES_7673, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRINE_SABRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGERP_5670, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGERP_5688, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEARP_5704, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEARP_5718, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRUMA_TORCH, WeaponStyle.MELEE); + StyleMap.put(ItemID.BUTTERFLY_NET, WeaponStyle.MELEE); + StyleMap.put(ItemID.CANDY_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CATTLEPROD, WeaponStyle.MELEE); + StyleMap.put(ItemID.CHAOTIC_HANDEGG, WeaponStyle.MELEE); + StyleMap.put(ItemID.CLEAVER, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HALBERD_ATTUNED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HALBERD_BASIC, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HALBERD_PERFECTED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_SCEPTRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRIER_BELL, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_AXE_23862, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_AXE_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_110, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_110_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_210, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_210_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_24125, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_310, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_310_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_410, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_410_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_510, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_510_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_610, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_610_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_710, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_710_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_810, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_810_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_910, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_910_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_ATTUNED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_BASIC, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_FULL, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_FULL_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_PERFECTED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HARPOON_23864, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HARPOON_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_PICKAXE_23863, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_PICKAXE_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_SCEPTRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CURSED_GOBLIN_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DARKLIGHT, WeaponStyle.MELEE); + StyleMap.put(ItemID.DARK_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DECORATIVE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DECORATIVE_SWORD_4503, WeaponStyle.MELEE); + StyleMap.put(ItemID.DECORATIVE_SWORD_4508, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.DINHS_BULWARK, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_2H_SWORD_20559, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_CLAWS_20784, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGER_20407, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGERP_5680, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGERP_5698, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAKP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAP_22737, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAP_22740, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HUNTER_LANCE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_PICKAXE_12797, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_PICKAXE_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SCIMITAR_20406, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SCIMITAR_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEARP_5716, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEARP_5730, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_WARHAMMER_20785, WeaponStyle.MELEE); + StyleMap.put(ItemID.EASTER_BASKET, WeaponStyle.MELEE); + StyleMap.put(ItemID.EGG_WHISK, WeaponStyle.MELEE); + StyleMap.put(ItemID.ELDER_MAUL, WeaponStyle.MELEE); + StyleMap.put(ItemID.ELDER_MAUL_21205, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE1, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE2, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE3, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE4, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE5, WeaponStyle.MELEE); + StyleMap.put(ItemID.EVENT_RPG, WeaponStyle.MELEE); + StyleMap.put(ItemID.EXCALIBUR, WeaponStyle.MELEE); + StyleMap.put(ItemID.EXCALIBUR_8280, WeaponStyle.MELEE); + StyleMap.put(ItemID.FLAMTAER_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.FREMENNIK_BLADE, WeaponStyle.MELEE); + StyleMap.put(ItemID.FROZEN_ABYSSAL_WHIP, WeaponStyle.MELEE); + StyleMap.put(ItemID.GADDERHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GHRAZI_RAPIER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GHRAZI_RAPIER_23628, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.GLOWING_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GOLDEN_TENCH, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_12848, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_20557, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_24225, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_24227, WeaponStyle.MELEE); + StyleMap.put(ItemID.GREEN_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.HARRYS_CUTLASS, WeaponStyle.MELEE); + StyleMap.put(ItemID.HAM_JOINT, WeaponStyle.MELEE); + StyleMap.put(ItemID.HAND_FAN, WeaponStyle.MELEE); + StyleMap.put(ItemID.HILL_GIANT_CLUB, WeaponStyle.MELEE); + StyleMap.put(ItemID.HOLY_HANDEGG, WeaponStyle.MELEE); + StyleMap.put(ItemID.HOSIDIUS_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_AXE_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_HARPOON_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_PICKAXE_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.INQUISITORS_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGERP_5668, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGERP_5686, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEARP_5706, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEARP_5720, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.JADE_MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.KATANA, WeaponStyle.MELEE); + StyleMap.put(ItemID.KITCHEN_KNIFE, WeaponStyle.MELEE); + StyleMap.put(ItemID.KERIS, WeaponStyle.MELEE); + StyleMap.put(ItemID.LARGE_SPADE, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_SPEAR_4159, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.LOVAKENGJ_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.LUCKY_CUTLASS, WeaponStyle.MELEE); + StyleMap.put(ItemID.LYRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAGIC_BUTTERFLY_NET, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAGIC_SECATEURS, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAGIC_SECATEURS_NZ, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAPLE_BLACKJACK, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAPLE_BLACKJACKD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAPLE_BLACKJACKO, WeaponStyle.MELEE); + StyleMap.put(ItemID.MEAT_TENDERISER, WeaponStyle.MELEE); + StyleMap.put(ItemID.MERFOLK_TRIDENT, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGERP_5674, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGERP_5692, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEARP_5710, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEARP_5724, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.MIXED_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.MOUSE_TOY, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL_16893, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL_I_16892, WeaponStyle.MELEE); + StyleMap.put(ItemID.NOOSE_WAND, WeaponStyle.MELEE); + StyleMap.put(ItemID.NUNCHAKU, WeaponStyle.MELEE); + StyleMap.put(ItemID.OAK_BLACKJACK, WeaponStyle.MELEE); + StyleMap.put(ItemID.OAK_BLACKJACKD, WeaponStyle.MELEE); + StyleMap.put(ItemID.OAK_BLACKJACKO, WeaponStyle.MELEE); + StyleMap.put(ItemID.OILY_FISHING_ROD, WeaponStyle.MELEE); + StyleMap.put(ItemID.OILY_PEARL_FISHING_ROD, WeaponStyle.MELEE); + StyleMap.put(ItemID.OPAL_MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ORANGE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ORANGE_SALAMANDER, WeaponStyle.MELEE); + StyleMap.put(ItemID.PEACEFUL_HANDEGG, WeaponStyle.MELEE); + StyleMap.put(ItemID.PET_ROCK, WeaponStyle.MELEE); + StyleMap.put(ItemID.PISCARILIUS_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.PROP_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.PURPLE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAPIER, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6774, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6775, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6776, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6777, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6778, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6779, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_FLOWERS_8938, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_SALAMANDER, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_TOPAZ_MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ROCK_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ROYAL_SCEPTRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUBBER_CHICKEN, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUBBER_CHICKEN_22666, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_BATTLEAXE_20552, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGERP_5678, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGERP_5696, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_20402, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_23330, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_23332, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_23334, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEARP_5714, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEARP_5728, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMINS_BLESSED_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_MJOLNIR, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARAS_BLESSED_SWORD_FULL, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE_OF_VITUR, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE_OF_VITUR_22664, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE_OF_VITUR_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.SEVERED_LEG_24792, WeaponStyle.MELEE); + StyleMap.put(ItemID.SHADOW_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SHAYZIEN_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVERLIGHT, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVERLIGHT_6745, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVERLIGHT_8279, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVER_SICKLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVER_SICKLE_B, WeaponStyle.MELEE); + StyleMap.put(ItemID.SNOWBALL, WeaponStyle.MELEE); + StyleMap.put(ItemID.SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.STALE_BAGUETTE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STATIUSS_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.STATIUSS_WARHAMMER_23620, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGERP_5672, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGERP_5690, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEARP_5708, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEARP_5722, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.STONE_BOWL, WeaponStyle.MELEE); + StyleMap.put(ItemID.SWAMP_LIZARD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SWIFT_BLADE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TOKTZXILAK, WeaponStyle.MELEE); + StyleMap.put(ItemID.TOKTZXILAK_20554, WeaponStyle.MELEE); + StyleMap.put(ItemID.TOKTZXILEK, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAINING_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TROLLWEISS, WeaponStyle.MELEE); + StyleMap.put(ItemID.TWISTED_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.TZHAARKETEM, WeaponStyle.MELEE); + StyleMap.put(ItemID.TZHAARKETOM, WeaponStyle.MELEE); + StyleMap.put(ItemID.TZHAARKETOM_T, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_BLIGHTED_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_LONGSWORD_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_LONGSWORD_23615, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.VIGGORAS_CHAINMACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.VIGGORAS_CHAINMACE_U, WeaponStyle.MELEE); + StyleMap.put(ItemID.VOLCANIC_ABYSSAL_WHIP, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_1, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_2, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_3, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_4, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGERP_6595, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGERP_6597, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_1, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_2, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_3, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_4, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILLOW_BLACKJACK, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILLOW_BLACKJACKD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILLOW_BLACKJACKO, WeaponStyle.MELEE); + StyleMap.put(ItemID.WOLFBANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.WOODEN_SPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.WOODEN_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.YELLOW_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAKIAN_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAKIAN_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAK_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAK_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZOMBIE_HEAD, WeaponStyle.MELEE); + + //Ranged + StyleMap.put(ItemID._3RD_AGE_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DARTP_5633, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DARTP_5640, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFEP_5659, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFEP_5666, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.ARMADYL_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.ARMADYL_CROSSBOW_23611, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_CHINCHOMPA, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DARTP_5631, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DARTP_5638, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFEP_5658, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFEP_5665, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLURITE_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DARTP_5628, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DARTP_5635, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFEP_5654, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFEP_5661, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.CHINCHOMPA, WeaponStyle.RANGE); + StyleMap.put(ItemID.CHINCHOMPA_10033, WeaponStyle.RANGE); + StyleMap.put(ItemID.COMP_OGRE_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CORRUPTED_BOW_ATTUNED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CORRUPTED_BOW_BASIC, WeaponStyle.RANGE); + StyleMap.put(ItemID.CORRUPTED_BOW_PERFECTED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRAWS_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRAWS_BOW_U, WeaponStyle.RANGE); + StyleMap.put(ItemID.CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_110, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_110_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_210, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_210_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_310, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_310_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_410, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_410_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_510, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_510_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_610, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_610_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_710, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_710_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_810, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_810_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_910, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_910_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_24123, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_ATTUNED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_BASIC, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_FULL, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_FULL_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_INACTIVE, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_PERFECTED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CURSED_GOBLIN_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12765, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12766, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12767, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12768, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_20408, WeaponStyle.RANGE); + StyleMap.put(ItemID.DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.DORGESHUUN_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DARTP_11233, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DARTP_11234, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_HUNTER_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFEP_22808, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFEP_22810, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.HEAVY_BALLISTA, WeaponStyle.RANGE); + StyleMap.put(ItemID.HEAVY_BALLISTA_23630, WeaponStyle.RANGE); + StyleMap.put(ItemID.HOLY_WATER, WeaponStyle.RANGE); + StyleMap.put(ItemID.HUNTERS_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DARTP_5629, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DARTP_5636, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFEP_5655, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFEP_5662, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_0, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_100, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_25, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_50, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_75, WeaponStyle.RANGE); + StyleMap.put(ItemID.LIGHT_BALLISTA, WeaponStyle.RANGE); + StyleMap.put(ItemID.LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_COMP_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_SHORTBOW_20558, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_SHORTBOW_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAPLE_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAPLE_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DARTP_5632, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DARTP_5639, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFEP_5657, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFEP_5664, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MONKEY_TALISMAN, WeaponStyle.RANGE); + StyleMap.put(ItemID.MORRIGANS_JAVELIN, WeaponStyle.RANGE); + StyleMap.put(ItemID.MORRIGANS_JAVELIN_23619, WeaponStyle.RANGE); + StyleMap.put(ItemID.MORRIGANS_THROWING_AXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.MUD_PIE, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_4213, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_16888, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_I_16889, WeaponStyle.RANGE); + StyleMap.put(ItemID.OAK_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.OAK_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.OGRE_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.PHOENIX_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.RED_CHINCHOMPA, WeaponStyle.RANGE); + StyleMap.put(ItemID.RED_CHINCHOMPA_10034, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_CROSSBOW_23601, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DARTP_5634, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DARTP_5641, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFEP_5660, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFEP_5667, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.SEERCULL, WeaponStyle.RANGE); + StyleMap.put(ItemID.SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.SIGNED_OAK_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.STARTER_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DARTP_5630, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DARTP_5637, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFEP_5656, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFEP_5663, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.TOKTZXILUL, WeaponStyle.RANGE); + StyleMap.put(ItemID.TOXIC_BLOWPIPE, WeaponStyle.RANGE); + StyleMap.put(ItemID.TOXIC_BLOWPIPE_EMPTY, WeaponStyle.RANGE); + StyleMap.put(ItemID.TRAINING_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.TWISTED_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.WILLOW_COMP_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.WILLOW_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.WILLOW_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.YEW_COMP_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.YEW_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.YEW_SHORTBOW, WeaponStyle.RANGE); + + //Magic + StyleMap.put(ItemID._3RD_AGE_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_0, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_100, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_25, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_50, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_75, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_23653, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AIR_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ANCIENT_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ANCIENT_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.APPRENTICE_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ARMADYL_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BANDOS_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BEGINNER_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BLISTERWOOD_FLAIL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BROKEN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BRYOPHYTAS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BRYOPHYTAS_STAFF_UNCHARGED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CORRUPTED_STAFF_ATTUNED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CORRUPTED_STAFF_BASIC, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CORRUPTED_STAFF_PERFECTED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CRYSTAL_STAFF_ATTUNED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CRYSTAL_STAFF_BASIC, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CRYSTAL_STAFF_PERFECTED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CURSED_GOBLIN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.DAWNBRINGER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.DRAMEN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.DUST_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.EARTH_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ELDRITCH_NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.FIRE_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.GUTHIX_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.GUTHIX_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.HARMONISED_NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IBANS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IBANS_STAFF_1410, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IBANS_STAFF_U, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IVANDIS_FLAIL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.KODAI_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.KODAI_WAND_23626, WeaponStyle.MAGIC); + StyleMap.put(ItemID.LAVA_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.LAVA_BATTLESTAFF_21198, WeaponStyle.MAGIC); + StyleMap.put(ItemID.LUNAR_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MAGIC_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MASTER_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MASTER_WAND_20560, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MIST_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MUD_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_AIR_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_DUST_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_EARTH_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_FIRE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_LAVA_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_LAVA_STAFF_21200, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_MIST_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_MUD_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_SMOKE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_STEAM_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_STEAM_STAFF_12796, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_WATER_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_1, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_2, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_3, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_4, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_5, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_6, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_7, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_8, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_1, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_10, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_2, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_3, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_4, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_5, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_6, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_7, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_8, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_9, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SANGUINESTI_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SANGUINESTI_STAFF_UNCHARGED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SARADOMIN_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SARADOMIN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SKULL_SCEPTRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SKULL_SCEPTRE_I, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SLAYERS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SLAYERS_STAFF_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SMOKE_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_AIR, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_BALANCE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_BOB_THE_CAT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_EARTH, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_FIRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_LIGHT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_THE_DEAD, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_THE_DEAD_23613, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_WATER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STARTER_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STEAM_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STEAM_BATTLESTAFF_12795, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TEACHER_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.THAMMARONS_SCEPTRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.THAMMARONS_SCEPTRE_U, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TOKTZMEJTAL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TOXIC_STAFF_OF_THE_DEAD, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TOXIC_STAFF_UNCHARGED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SEAS, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SEAS_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SEAS_FULL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SWAMP, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SWAMP_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TOXIC_TRIDENT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TOXIC_TRIDENT_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TRIDENT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TRIDENT_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.VOID_KNIGHT_MACE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.VOID_KNIGHT_MACE_BROKEN, WeaponStyle.MAGIC); + StyleMap.put(ItemID.VOLATILE_NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.WATER_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.WHITE_MAGIC_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZAMORAK_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZAMORAK_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZURIELS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZURIELS_STAFF_23617, WeaponStyle.MAGIC); + //what the fuck... + StyleMap.put(ItemID.GNOMEBALL, WeaponStyle.MAGIC); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/util/WeaponStyle.java b/runelite-client/src/main/java/com/openosrs/client/util/WeaponStyle.java new file mode 100644 index 0000000000..949fdda21f --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/util/WeaponStyle.java @@ -0,0 +1,6 @@ +package com.openosrs.client.util; + +public enum WeaponStyle +{ + MAGIC, RANGE, MELEE +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index d0222a198f..9dd8b019c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -94,7 +94,7 @@ import org.slf4j.LoggerFactory; @Slf4j public class RuneLite { - public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite"); + public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".openosrs"); public static final File CACHE_DIR = new File(RUNELITE_DIR, "cache"); public static final File PLUGINS_DIR = new File(RUNELITE_DIR, "plugins"); public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles"); @@ -334,7 +334,7 @@ public class RuneLite oprsExternalPluginManager.startExternalPluginManager(); // Update external plugins - //oprsExternalPluginManager.update(); //TODO: Re-enable after fixing actions for new repo + oprsExternalPluginManager.update(); //TODO: Re-enable after fixing actions for new repo // Load the plugins, but does not start them yet. // This will initialize configuration diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java index c20df7d8e5..f673cee903 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java @@ -25,6 +25,7 @@ package net.runelite.client; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.gson.Gson; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.name.Names; @@ -58,6 +59,7 @@ import net.runelite.client.plugins.PluginManager; import net.runelite.client.task.Scheduler; import net.runelite.client.util.DeferredEventBus; import net.runelite.client.util.ExecutorServiceExceptionLogger; +import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.chat.ChatClient; import okhttp3.OkHttpClient; import org.slf4j.Logger; @@ -95,6 +97,8 @@ public class RuneLiteModule extends AbstractModule bind(PluginManager.class); bind(SessionManager.class); + bind(Gson.class).toInstance(RuneLiteAPI.GSON); + bind(Callbacks.class).to(Hooks.class); bind(EventBus.class) diff --git a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java index cadf0b4562..4b6bf1674e 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java +++ b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java @@ -64,6 +64,7 @@ public class SessionManager private final WSClient wsClient; private final File sessionFile; private final AccountClient accountClient; + private final Gson gson; @Inject private SessionManager( @@ -71,13 +72,15 @@ public class SessionManager ConfigManager configManager, EventBus eventBus, WSClient wsClient, - OkHttpClient okHttpClient) + OkHttpClient okHttpClient, + Gson gson) { this.configManager = configManager; this.eventBus = eventBus; this.wsClient = wsClient; this.sessionFile = sessionfile; this.accountClient = new AccountClient(okHttpClient); + this.gson = gson; eventBus.register(this); } @@ -94,7 +97,7 @@ public class SessionManager try (FileInputStream in = new FileInputStream(sessionFile)) { - session = new Gson().fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), AccountSession.class); + session = gson.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), AccountSession.class); log.debug("Loaded session for {}", session.getUsername()); } @@ -124,7 +127,7 @@ public class SessionManager try (Writer fw = new OutputStreamWriter(new FileOutputStream(sessionFile), StandardCharsets.UTF_8)) { - new Gson().toJson(accountSession, fw); + gson.toJson(accountSession, fw); log.debug("Saved session to {}", sessionFile); } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java index a9a511cc08..f76f32154a 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java @@ -24,6 +24,8 @@ */ package net.runelite.client.config; +import com.openosrs.client.OpenOSRS; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -48,4 +50,11 @@ public @interface ConfigItem boolean secret() default false; String section() default ""; + + /* + OpenOSRS Lazy Helpers tm + */ + Class enumClass() default OpenOSRS.class; + String unhide() default ""; + String hide() default ""; } 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 01d8ebfe1d..a2a4eef25c 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 @@ -394,7 +394,7 @@ public class ConfigManager parent.mkdirs(); - File tempFile = new File(parent, RuneLite.DEFAULT_CONFIG_FILE.getName() + ".tmp"); + File tempFile = File.createTempFile("runelite", null, parent); try (FileOutputStream out = new FileOutputStream(tempFile)) { diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java index 4a0f722d3f..282855920a 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java @@ -40,4 +40,12 @@ public @interface ConfigSection int position(); boolean closedByDefault() default false; + + /* + OpenOSRS Lazy Helpers tm + */ + String keyName() default ""; + String section() default ""; + boolean hidden() default false; + String unhide() default ""; } diff --git a/runelite-client/src/main/java/net/runelite/client/config/Keybind.java b/runelite-client/src/main/java/net/runelite/client/config/Keybind.java index e7e338a6b3..eba500b859 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/Keybind.java +++ b/runelite-client/src/main/java/net/runelite/client/config/Keybind.java @@ -159,7 +159,7 @@ public class Keybind String mod = ""; if (modifiers != 0) { - mod = getModifiersExText(modifiers); + mod = InputEvent.getModifiersExText(modifiers); } if (mod.isEmpty() && key.isEmpty()) @@ -177,33 +177,6 @@ public class Keybind return mod; } - public static String getModifiersExText(int modifiers) - { - StringBuilder buf = new StringBuilder(); - if ((modifiers & InputEvent.META_DOWN_MASK) != 0) - { - buf.append("Meta+"); - } - if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) - { - buf.append("Ctrl+"); - } - if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) - { - buf.append("Alt+"); - } - if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) - { - buf.append("Shift+"); - } - - if (buf.length() > 0) - { - buf.setLength(buf.length() - 1); // remove trailing '+' - } - return buf.toString(); - } - @Nullable public static Integer getModifierForKeyCode(int keyCode) { diff --git a/runelite-client/src/main/java/net/runelite/client/config/Units.java b/runelite-client/src/main/java/net/runelite/client/config/Units.java index 45d54df164..ca872bfa80 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/Units.java +++ b/runelite-client/src/main/java/net/runelite/client/config/Units.java @@ -42,8 +42,12 @@ public @interface Units String MINUTES = " mins"; String PERCENT = "%"; String PIXELS = "px"; + String POINTS = "pt"; String SECONDS = "s"; String TICKS = " ticks"; + String LEVELS = " lvls"; + String FPS = " fps"; + String GP = " GP"; String value(); } diff --git a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java index 054a7779b5..5690c3d61e 100644 --- a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java @@ -24,18 +24,32 @@ */ package net.runelite.client.externalplugins; +import java.lang.invoke.MethodHandles; import java.net.URL; import java.net.URLClassLoader; import lombok.Getter; +import lombok.Setter; +import net.runelite.client.util.ReflectUtil; -class ExternalPluginClassLoader extends URLClassLoader +class ExternalPluginClassLoader extends URLClassLoader implements ReflectUtil.PrivateLookupableClassLoader { @Getter private final ExternalPluginManifest manifest; + @Getter + @Setter + private MethodHandles.Lookup lookup; + ExternalPluginClassLoader(ExternalPluginManifest manifest, URL[] urls) { super(urls, ExternalPluginClassLoader.class.getClassLoader()); this.manifest = manifest; + ReflectUtil.installLookupHelper(this); + } + + @Override + public Class defineClass0(String name, byte[] b, int off, int len) throws ClassFormatError + { + return super.defineClass(name, b, off, len); } } diff --git a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java index e6bda75032..ccf4b9fad3 100644 --- a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java +++ b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java @@ -25,6 +25,7 @@ package net.runelite.client.externalplugins; import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; @@ -59,11 +60,13 @@ import okio.BufferedSource; public class ExternalPluginClient { private final OkHttpClient okHttpClient; + private final Gson gson; @Inject - private ExternalPluginClient(OkHttpClient okHttpClient) + private ExternalPluginClient(OkHttpClient okHttpClient, Gson gson) { this.okHttpClient = okHttpClient; + this.gson = gson; } public List downloadManifest() throws IOException, VerificationException @@ -94,7 +97,7 @@ public class ExternalPluginClient throw new VerificationException("Unable to verify external plugin manifest"); } - return RuneLiteAPI.GSON.fromJson(new String(data, StandardCharsets.UTF_8), + return gson.fromJson(new String(data, StandardCharsets.UTF_8), new TypeToken>() { }.getType()); @@ -156,7 +159,7 @@ public class ExternalPluginClient Request request = new Request.Builder() .url(url) - .post(RequestBody.create(RuneLiteAPI.JSON, RuneLiteAPI.GSON.toJson(plugins))) + .post(RequestBody.create(RuneLiteAPI.JSON, gson.toJson(plugins))) .build(); okHttpClient.newCall(request).enqueue(new Callback() @@ -190,7 +193,7 @@ public class ExternalPluginClient } // CHECKSTYLE:OFF - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(res.body().byteStream()), new TypeToken>(){}.getType()); + return gson.fromJson(new InputStreamReader(res.body().byteStream()), new TypeToken>(){}.getType()); // CHECKSTYLE:ON } catch (JsonSyntaxException ex) diff --git a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java index 20b99655fb..5833b05a37 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java +++ b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java @@ -237,7 +237,7 @@ public enum AgilityShortcut @Getter private final int level; /** - * Brief description of the shortcut (e.g. 'Rocks', 'Stepping Stones', 'Jump') + * Brief description of the shortcut. (e.g. 'Rocks', 'Stepping Stones', 'Jump') */ @Getter private final String description; diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 67129b0ba5..c2231233db 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -26,33 +26,25 @@ package net.runelite.client.menus; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; +import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.api.IconID; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; -import net.runelite.api.NPCComposition; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.NpcActionChanged; -import net.runelite.api.events.PlayerMenuOptionClicked; import net.runelite.api.events.PlayerMenuOptionsChanged; import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.util.Text; @Singleton @Slf4j @@ -64,16 +56,13 @@ public class MenuManager private static final int IDX_LOWER = 4; private static final int IDX_UPPER = 8; - private static final Pattern BOUNTY_EMBLEM_TAG_AND_TIER_REGEXP = Pattern.compile(String.format("%s[1-9]0?", IconID.BOUNTY_HUNTER_EMBLEM.toString())); - private final Client client; private final EventBus eventBus; //Maps the indexes that are being used to the menu option. private final Map playerMenuIndexMap = new HashMap<>(); //Used to manage custom non-player menu options - private final Multimap managedMenuOptions = HashMultimap.create(); - private final Set npcMenuOptions = new HashSet<>(); + private final Multimap managedMenuOptions = LinkedHashMultimap.create(); @Inject @VisibleForTesting @@ -123,7 +112,7 @@ public class MenuManager @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - if (client.getSpellSelected()) + if (client.getSpellSelected() || event.getType() != MenuAction.CC_OP.getId()) { return; } @@ -200,45 +189,12 @@ public class MenuManager addPlayerMenuItem(newIdx, menuText); } - @Subscribe - public void onNpcActionChanged(NpcActionChanged event) - { - NPCComposition composition = event.getNpcComposition(); - for (String npcOption : npcMenuOptions) - { - addNpcOption(composition, npcOption); - } - } - - private void addNpcOption(NPCComposition composition, String npcOption) - { - String[] actions = composition.getActions(); - int unused = -1; - for (int i = 0; i < actions.length; ++i) - { - if (actions[i] == null && unused == -1) - { - unused = i; - } - else if (actions[i] != null && actions[i].equals(npcOption)) - { - return; - } - } - if (unused == -1) - { - return; - } - actions[unused] = npcOption; - } - @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getMenuAction() != MenuAction.RUNELITE - && event.getMenuAction() != MenuAction.RUNELITE_PLAYER) + if (event.getMenuAction() != MenuAction.RUNELITE) { - return; // not a managed widget option or custom player option + return; } int widgetId = event.getWidgetId(); @@ -254,23 +210,9 @@ public class MenuManager customMenu.setMenuTarget(event.getMenuTarget()); customMenu.setWidget(curMenuOption.getWidget()); eventBus.post(customMenu); - return; // don't continue because it's not a player option + return; } } - - // removes bounty hunter emblem tag and tier from player name, e.g: - // "username5 (level-42)" -> "username (level-42)" - String target = BOUNTY_EMBLEM_TAG_AND_TIER_REGEXP.matcher(event.getMenuTarget()).replaceAll(""); - - // removes tags and level from player names for example: - // username (level-42) or username - String username = Text.removeTags(target).split("[(]")[0].trim(); - - PlayerMenuOptionClicked playerMenuOptionClicked = new PlayerMenuOptionClicked(); - playerMenuOptionClicked.setMenuOption(event.getMenuOption()); - playerMenuOptionClicked.setMenuTarget(username); - - eventBus.post(playerMenuOptionClicked); } private void addPlayerMenuItem(int playerOptionIndex, String menuText) diff --git a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java index 307551542c..d24ae1d18d 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java @@ -33,11 +33,11 @@ import net.runelite.client.util.ColorUtil; public final class WidgetMenuOption { /** - * The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop" + * The left hand text to be displayed on the menu option. (ex. the menuOption of "Drop Bones" is "Drop") */ private String menuOption; /** - * The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones" + * The right hand text to be displayed on the menu option. (ex. the menuTarget of "Drop Bones" is "Bones") */ private String menuTarget; /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java index c7cdef0058..4e4eba0175 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java @@ -34,6 +34,7 @@ import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import net.runelite.api.Varbits; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.FontManager; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPanel; @@ -82,6 +83,7 @@ public class BarrowsBrotherSlainOverlay extends OverlayPanel panelComponent.getChildren().add(LineComponent.builder() .left(brother.getName()) .right(slain) + .rightFont(FontManager.getDefaultFont()) .rightColor(brotherSlain ? Color.GREEN : Color.RED) .build()); } 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 b59be0da14..ab3ac38982 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 @@ -45,6 +45,7 @@ import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import static net.runelite.client.plugins.cluescrolls.clues.Enemy.*; import net.runelite.client.plugins.cluescrolls.clues.emote.Emote; import static net.runelite.client.plugins.cluescrolls.clues.emote.Emote.*; import static net.runelite.client.plugins.cluescrolls.clues.emote.Emote.BULL_ROARER; @@ -53,7 +54,7 @@ import static net.runelite.client.plugins.cluescrolls.clues.emote.STASHUnit.*; import static net.runelite.client.plugins.cluescrolls.clues.emote.STASHUnit.SHANTAY_PASS; import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement; import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*; -import static net.runelite.client.plugins.cluescrolls.clues.Enemy.*; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -258,6 +259,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu panelComponent.getChildren().add(LineComponent.builder() .left("STASH Unit:") .right(stashUnitBuilt ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X) + .rightFont(FontManager.getDefaultFont()) .rightColor(stashUnitBuilt ? Color.GREEN : Color.RED) .build()); } @@ -292,6 +294,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu .left(requirement.getCollectiveName(client)) .leftColor(TITLED_CONTENT_COLOR) .right(combinedFulfilled ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X) + .rightFont(FontManager.getDefaultFont()) .rightColor(equipmentFulfilled ? Color.GREEN : (combinedFulfilled ? Color.ORANGE : Color.RED)) .build()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java index 16974ffd16..c208d5238f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java @@ -41,6 +41,7 @@ import net.runelite.client.plugins.cluescrolls.clues.item.AnyRequirementCollecti import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement; import net.runelite.client.plugins.cluescrolls.clues.item.RangeItemRequirement; import net.runelite.client.plugins.cluescrolls.clues.item.SingleItemRequirement; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -134,6 +135,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl .left(requirement.getCollectiveName(plugin.getClient())) .leftColor(TITLED_CONTENT_COLOR) .right(inventoryFulfilled ? "\u2713" : "\u2717") + .rightFont(FontManager.getDefaultFont()) .rightColor(inventoryFulfilled ? Color.GREEN : Color.RED) .build()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java index 67de8ad26a..41f6f283cb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java @@ -25,6 +25,11 @@ package net.runelite.client.plugins.cluescrolls.clues; import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -34,25 +39,21 @@ import net.runelite.api.ItemID; import net.runelite.api.NPC; import net.runelite.api.Point; import net.runelite.api.TileObject; +import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_BORDER_COLOR; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_FILL_COLOR; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_HOVER_BORDER_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; import net.runelite.client.plugins.cluescrolls.clues.item.AnyRequirementCollection; -import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*; import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement; +import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*; import net.runelite.client.plugins.cluescrolls.clues.item.SingleItemRequirement; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; -import java.awt.Color; -import java.awt.Graphics2D; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; -import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; @Getter public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, NamedObjectClueScroll @@ -379,6 +380,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam .left(requirement.getCollectiveName(plugin.getClient())) .leftColor(TITLED_CONTENT_COLOR) .right(combinedFulfilled ? "\u2713" : "\u2717") + .rightFont(FontManager.getDefaultFont()) .rightColor(equipmentFulfilled || (combinedFulfilled && !requireEquipped) ? Color.GREEN : (combinedFulfilled ? Color.ORANGE : Color.RED)) .build()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java index 55b9160c5b..131aef04bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java @@ -32,6 +32,7 @@ import javax.swing.JButton; import lombok.Getter; import net.runelite.client.config.Keybind; import net.runelite.client.config.ModifierlessKeybind; +import net.runelite.client.ui.FontManager; class HotkeyButton extends JButton { @@ -40,6 +41,7 @@ class HotkeyButton extends JButton public HotkeyButton(Keybind value, boolean modifierless) { + setFont(FontManager.getDefaultFont().deriveFont(12.f)); setValue(value); addMouseListener(new MouseAdapter() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java index 661071a786..09d737c10f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java @@ -32,7 +32,6 @@ import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.RuneLiteAPI; import okhttp3.Call; import okhttp3.Callback; import okhttp3.MediaType; @@ -47,11 +46,13 @@ public class CrowdsourcingManager { private static final String CROWDSOURCING_BASE = "https://crowdsource.runescape.wiki/runelite"; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final Gson GSON = RuneLiteAPI.GSON; @Inject private OkHttpClient okHttpClient; + @Inject + private Gson gson; + private List data = new ArrayList<>(); public void storeEvent(Object event) @@ -77,7 +78,7 @@ public class CrowdsourcingManager Request r = new Request.Builder() .url(CROWDSOURCING_BASE) - .post(RequestBody.create(JSON, GSON.toJson(temp))) + .post(RequestBody.create(JSON, gson.toJson(temp))) .build(); okHttpClient.newCall(r).enqueue(new Callback() 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 17b72b5d6e..7e07a12ee4 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 @@ -470,7 +470,7 @@ enum DiscordGameEventType private int priority; /** - * Marks this event as root event, e.g event that should be used for total time tracking + * Marks this event as root event. (eg. event that should be used for total time tracking) */ private boolean root; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index d28f4b0323..f3d9b513b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -128,7 +128,6 @@ public class GrandExchangePlugin extends Plugin private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; private static final String BUY_LIMIT_KEY = "buylimit"; - private static final Gson GSON = new Gson(); private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4); static final String SEARCH_GRAND_EXCHANGE = "Search Grand Exchange"; @@ -183,6 +182,9 @@ public class GrandExchangePlugin extends Plugin @Inject private ConfigManager configManager; + @Inject + private Gson gson; + private Widget grandExchangeText; private Widget grandExchangeItem; private String grandExchangeExamine; @@ -253,12 +255,12 @@ public class GrandExchangePlugin extends Plugin { return null; } - return GSON.fromJson(offer, SavedOffer.class); + return gson.fromJson(offer, SavedOffer.class); } private void setOffer(int slot, SavedOffer offer) { - configManager.setRSProfileConfiguration("geoffer", Integer.toString(slot), GSON.toJson(offer)); + configManager.setRSProfileConfiguration("geoffer", Integer.toString(slot), gson.toJson(offer)); } private void deleteOffer(int slot) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index 73e93f86ad..cfb6171941 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -51,6 +51,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.plugins.Plugin; @@ -72,8 +73,6 @@ public class GroundMarkerPlugin extends Plugin private static final String WALK_HERE = "Walk here"; private static final String REGION_PREFIX = "region_"; - private static final Gson GSON = new Gson(); - @Getter(AccessLevel.PACKAGE) private final List points = new ArrayList<>(); @@ -98,7 +97,16 @@ public class GroundMarkerPlugin extends Plugin @Inject private ChatboxPanelManager chatboxPanelManager; - private void savePoints(int regionId, Collection points) + @Inject + private EventBus eventBus; + + @Inject + private GroundMarkerSharingManager sharingManager; + + @Inject + private Gson gson; + + void savePoints(int regionId, Collection points) { if (points == null || points.isEmpty()) { @@ -106,11 +114,11 @@ public class GroundMarkerPlugin extends Plugin return; } - String json = GSON.toJson(points); + String json = gson.toJson(points); configManager.setConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId, json); } - private Collection getPoints(int regionId) + Collection getPoints(int regionId) { String json = configManager.getConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId); if (Strings.isNullOrEmpty(json)) @@ -119,7 +127,7 @@ public class GroundMarkerPlugin extends Plugin } // CHECKSTYLE:OFF - return GSON.fromJson(json, new TypeToken>(){}.getType()); + return gson.fromJson(json, new TypeToken>(){}.getType()); // CHECKSTYLE:ON } @@ -129,7 +137,7 @@ public class GroundMarkerPlugin extends Plugin return configManager.getConfig(GroundMarkerConfig.class); } - private void loadPoints() + void loadPoints() { points.clear(); @@ -181,14 +189,18 @@ public class GroundMarkerPlugin extends Plugin { overlayManager.add(overlay); overlayManager.add(minimapOverlay); + sharingManager.addMenuOptions(); loadPoints(); + eventBus.register(sharingManager); } @Override public void shutDown() { + eventBus.unregister(sharingManager); overlayManager.remove(overlay); overlayManager.remove(minimapOverlay); + sharingManager.removeMenuOptions(); points.clear(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java new file mode 100644 index 0000000000..91c0e800ac --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2021, Adam + * 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.groundmarkers; + +import com.google.common.base.Strings; +import com.google.common.util.concurrent.Runnables; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.events.WidgetMenuOptionClicked; +import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_OPTION; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.chatbox.ChatboxPanelManager; +import net.runelite.client.menus.MenuManager; +import net.runelite.client.menus.WidgetMenuOption; + +@Slf4j +class GroundMarkerSharingManager +{ + private static final WidgetMenuOption EXPORT_MARKERS_OPTION = new WidgetMenuOption("Export", "Ground Markers", WORLD_MAP_OPTION); + private static final WidgetMenuOption IMPORT_MARKERS_OPTION = new WidgetMenuOption("Import", "Ground Markers", WORLD_MAP_OPTION); + + private final GroundMarkerPlugin plugin; + private final Client client; + private final MenuManager menuManager; + private final ChatMessageManager chatMessageManager; + private final ChatboxPanelManager chatboxPanelManager; + private final Gson gson; + + @Inject + private GroundMarkerSharingManager(GroundMarkerPlugin plugin, Client client, MenuManager menuManager, + ChatMessageManager chatMessageManager, ChatboxPanelManager chatboxPanelManager, Gson gson) + { + this.plugin = plugin; + this.client = client; + this.menuManager = menuManager; + this.chatMessageManager = chatMessageManager; + this.chatboxPanelManager = chatboxPanelManager; + this.gson = gson; + } + + void addMenuOptions() + { + menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION); + menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION); + } + + void removeMenuOptions() + { + menuManager.removeManagedCustomMenu(EXPORT_MARKERS_OPTION); + menuManager.removeManagedCustomMenu(IMPORT_MARKERS_OPTION); + } + + private boolean widgetMenuClickedEquals(final WidgetMenuOptionClicked event, final WidgetMenuOption target) + { + return event.getMenuTarget().equals(target.getMenuTarget()) && + event.getMenuOption().equals(target.getMenuOption()); + } + + @Subscribe + public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + { + // ensure that the option clicked is the export markers option + if (event.getWidget() != WORLD_MAP_OPTION) + { + return; + } + + if (widgetMenuClickedEquals(event, EXPORT_MARKERS_OPTION)) + { + exportGroundMarkers(); + } + else if (widgetMenuClickedEquals(event, IMPORT_MARKERS_OPTION)) + { + promptForImport(); + } + } + + private void exportGroundMarkers() + { + int[] regions = client.getMapRegions(); + if (regions == null) + { + return; + } + + List activePoints = Arrays.stream(regions) + .mapToObj(regionId -> plugin.getPoints(regionId).stream()) + .flatMap(Function.identity()) + .collect(Collectors.toList()); + + if (activePoints.isEmpty()) + { + sendChatMessage("You have no ground markers to export."); + return; + } + + final String exportDump = gson.toJson(activePoints); + + log.debug("Exported ground markers: {}", exportDump); + + Toolkit.getDefaultToolkit() + .getSystemClipboard() + .setContents(new StringSelection(exportDump), null); + sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard."); + } + + private void promptForImport() + { + final String clipboardText; + try + { + clipboardText = Toolkit.getDefaultToolkit() + .getSystemClipboard() + .getData(DataFlavor.stringFlavor) + .toString(); + } + catch (IOException | UnsupportedFlavorException ex) + { + sendChatMessage("Unable to read system clipboard."); + log.warn("error reading clipboard", ex); + return; + } + + log.debug("Clipboard contents: {}", clipboardText); + if (Strings.isNullOrEmpty(clipboardText)) + { + sendChatMessage("You do not have any ground markers copied in your clipboard."); + return; + } + + List importPoints; + try + { + // CHECKSTYLE:OFF + importPoints = gson.fromJson(clipboardText, new TypeToken>(){}.getType()); + // CHECKSTYLE:ON + } + catch (JsonSyntaxException e) + { + log.debug("Malformed JSON for clipboard import", e); + sendChatMessage("You do not have any ground markers copied in your clipboard."); + return; + } + + if (importPoints.isEmpty()) + { + sendChatMessage("You do not have any ground markers copied in your clipboard."); + return; + } + + chatboxPanelManager.openTextMenuInput("Are you sure you want to import " + importPoints.size() + " ground markers?") + .option("Yes", () -> importGroundMarkers(importPoints)) + .option("No", Runnables::doNothing) + .build(); + } + + private void importGroundMarkers(Collection importPoints) + { + // regions being imported may not be loaded on client, + // so need to import each bunch directly into the config + // first, collate the list of unique region ids in the import + Map> regionGroupedPoints = importPoints.stream() + .collect(Collectors.groupingBy(GroundMarkerPoint::getRegionId)); + + // now import each region into the config + regionGroupedPoints.forEach((regionId, groupedPoints) -> + { + // combine imported points with existing region points + log.debug("Importing {} points to region {}", groupedPoints.size(), regionId); + Collection regionPoints = plugin.getPoints(regionId); + + List mergedList = new ArrayList<>(regionPoints.size() + groupedPoints.size()); + // add existing points + mergedList.addAll(regionPoints); + + // add new points + for (GroundMarkerPoint point : groupedPoints) + { + // filter out duplicates + if (!mergedList.contains(point)) + { + mergedList.add(point); + } + } + + plugin.savePoints(regionId, mergedList); + }); + + // reload points from config + log.debug("Reloading points after import"); + plugin.loadPoints(); + sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard."); + } + + private void sendChatMessage(final String message) + { + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(message) + .build()); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index edb450d61b..caf3020149 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -38,9 +38,10 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; +import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.PlayerMenuOptionClicked; +import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -174,11 +175,30 @@ public class HiscorePlugin extends Plugin } @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getMenuOption().equals(LOOKUP)) + if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + && event.getMenuOption().equals(LOOKUP)) { - lookupPlayer(Text.removeTags(event.getMenuTarget())); + final String target; + if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + { + // The player id is included in the event, so we can use that to get the player name, + // which avoids having to parse out the combat level and any icons preceding the name. + Player player = client.getCachedPlayers()[event.getId()]; + if (player == null) + { + return; + } + + target = player.getName(); + } + else + { + target = Text.removeTags(event.getMenuTarget()); + } + + lookupPlayer(target); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java index b7ab769756..99f0a5b55f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.idlenotifier; 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.Units; @ConfigGroup("idlenotifier") @@ -110,10 +111,36 @@ public interface IdleNotifierConfig extends Config return 0; } + @ConfigItem( + keyName = "lowEnergy", + name = "Low Energy Threshold", + description = "The amount of energy points remaining to send a notification at. A value of 100 will disable notification.", + position = 8 + ) + @Units(Units.PERCENT) + @Range(max = 100) + default int getLowEnergyThreshold() + { + return 100; + } + + @ConfigItem( + keyName = "highEnergy", + name = "High Energy Threshold", + description = "The amount of energy points reached to send a notification. A value of 0 will disable notification.", + position = 9 + ) + @Units(Units.PERCENT) + @Range(max = 100) + default int getHighEnergyThreshold() + { + return 0; + } + @ConfigItem( keyName = "oxygen", name = "Oxygen Threshold", - position = 8, + position = 10, description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification." ) @Units(Units.PERCENT) @@ -125,7 +152,7 @@ public interface IdleNotifierConfig extends Config @ConfigItem( keyName = "spec", name = "Spec Threshold", - position = 9, + position = 11, description = "The amount of special attack energy reached to send a notification at. A value of 0 will disable notification." ) @Units(Units.PERCENT) 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 ee084f3c44..e9d2d01896 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 @@ -93,6 +93,8 @@ public class IdleNotifierPlugin extends Plugin private boolean notifyPosition = false; private boolean notifyHitpoints = true; private boolean notifyPrayer = true; + private boolean shouldNotifyLowEnergy = false; + private boolean shouldNotifyHighEnergy = false; private boolean notifyOxygen = true; private boolean notifyIdleLogout = true; private boolean notify6HourLogout = true; @@ -471,6 +473,16 @@ public class IdleNotifierPlugin extends Plugin notifier.notify("[" + local.getName() + "] has low prayer!"); } + if (checkLowEnergy()) + { + notifier.notify("[" + local.getName() + "] has low run energy!"); + } + + if (checkHighEnergy()) + { + notifier.notify("[" + local.getName() + "] has restored run energy!"); + } + if (checkLowOxygen()) { notifier.notify("[" + local.getName() + "] has low oxygen!"); @@ -572,6 +584,52 @@ public class IdleNotifierPlugin extends Plugin return false; } + private boolean checkLowEnergy() + { + if (config.getLowEnergyThreshold() >= 100) + { + return false; + } + + if (client.getEnergy() <= config.getLowEnergyThreshold()) + { + if (shouldNotifyLowEnergy) + { + shouldNotifyLowEnergy = false; + return true; + } + } + else + { + shouldNotifyLowEnergy = true; + } + + return false; + } + + private boolean checkHighEnergy() + { + if (config.getHighEnergyThreshold() == 0) + { + return false; + } + + if (client.getEnergy() >= config.getHighEnergyThreshold()) + { + if (shouldNotifyHighEnergy) + { + shouldNotifyHighEnergy = false; + return true; + } + } + else + { + shouldNotifyHighEnergy = true; + } + + return false; + } + private boolean checkInteractionIdle(Duration waitDuration, Player local) { if (lastInteract == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java index 745d64594b..b9981d49f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java @@ -28,20 +28,74 @@ 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.ConfigSection; +import net.runelite.client.config.Range; -@ConfigGroup("inventorytags") +@ConfigGroup(InventoryTagsConfig.GROUP) public interface InventoryTagsConfig extends Config { - enum DisplayMode - { - OUTLINE, - UNDERLINE - } - String GROUP = "inventorytags"; + @ConfigSection( + name = "Tag display mode", + description = "How tags are displayed in the inventory", + position = 0 + ) + String tagStyleSection = "tagStyleSection"; + @ConfigItem( position = 0, + keyName = "showTagOutline", + name = "Outline", + description = "Configures whether or not item tags show be outlined", + section = tagStyleSection + ) + default boolean showTagOutline() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "tagUnderline", + name = "Underline", + description = "Configures whether or not item tags should be underlined", + section = tagStyleSection + ) + default boolean showTagUnderline() + { + return false; + } + + @ConfigItem( + position = 2, + keyName = "tagFill", + name = "Fill", + description = "Configures whether or not item tags should be filled", + section = tagStyleSection + ) + default boolean showTagFill() + { + return false; + } + + @Range( + max = 255 + ) + @ConfigItem( + position = 3, + keyName = "fillOpacity", + name = "Fill opacity", + description = "Configures the opacity of the tag \"Fill\"", + section = tagStyleSection + ) + default int fillOpacity() + { + return 50; + } + + @ConfigItem( + position = 1, keyName = "groupColor1", name = "Group 1 Color", description = "Color of the Tag" @@ -52,7 +106,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 1, + position = 2, keyName = "groupColor2", name = "Group 2 Color", description = "Color of the Tag" @@ -63,7 +117,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 2, + position = 3, keyName = "groupColor3", name = "Group 3 Color", description = "Color of the Tag" @@ -74,7 +128,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 3, + position = 4, keyName = "groupColor4", name = "Group 4 Color", description = "Color of the Tag" @@ -85,7 +139,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 4, + position = 5, keyName = "groupColor5", name = "Group 5 Color", description = "Color of the Tag" @@ -96,7 +150,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 5, + position = 6, keyName = "groupColor6", name = "Group 6 Color", description = "Color of the Tag" @@ -105,15 +159,4 @@ public interface InventoryTagsConfig extends Config { return new Color(0, 255, 255); } - - @ConfigItem( - position = 6, - keyName = "displayMode", - name = "Display mode", - description = "How tags are displayed in the inventory" - ) - default DisplayMode getDisplayMode() - { - return DisplayMode.OUTLINE; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java index 03857e185c..4b9e471fab 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java @@ -24,21 +24,26 @@ */ package net.runelite.client.plugins.inventorytags; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.awt.Color; import java.awt.Graphics2D; +import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import javax.inject.Inject; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorytags.InventoryTagsConfig.DisplayMode; import net.runelite.client.ui.overlay.WidgetItemOverlay; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.ImageUtil; public class InventoryTagsOverlay extends WidgetItemOverlay { private final ItemManager itemManager; private final InventoryTagsPlugin plugin; private final InventoryTagsConfig config; + private final Cache fillCache; @Inject private InventoryTagsOverlay(ItemManager itemManager, InventoryTagsPlugin plugin, InventoryTagsConfig config) @@ -48,6 +53,10 @@ public class InventoryTagsOverlay extends WidgetItemOverlay this.config = config; showOnEquipment(); showOnInventory(); + fillCache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .maximumSize(32) + .build(); } @Override @@ -57,16 +66,22 @@ public class InventoryTagsOverlay extends WidgetItemOverlay if (group != null) { final Color color = plugin.getGroupNameColor(group); - final DisplayMode displayMode = config.getDisplayMode(); if (color != null) { Rectangle bounds = widgetItem.getCanvasBounds(); - if (displayMode == DisplayMode.OUTLINE) + if (config.showTagOutline()) { final BufferedImage outline = itemManager.getItemOutline(itemId, widgetItem.getQuantity(), color); graphics.drawImage(outline, (int) bounds.getX(), (int) bounds.getY(), null); } - else + + if (config.showTagFill()) + { + final Image image = getFillImage(color, widgetItem.getId(), widgetItem.getQuantity()); + graphics.drawImage(image, (int) bounds.getX(), (int) bounds.getY(), null); + } + + if (config.showTagUnderline()) { int heightOffSet = (int) bounds.getY() + (int) bounds.getHeight() + 2; graphics.setColor(color); @@ -75,4 +90,22 @@ public class InventoryTagsOverlay extends WidgetItemOverlay } } } + + private Image getFillImage(Color color, int itemId, int qty) + { + long key = (((long) itemId) << 32) | qty; + Image image = fillCache.getIfPresent(key); + if (image == null) + { + final Color fillColor = ColorUtil.colorWithAlpha(color, config.fillOpacity()); + image = ImageUtil.fillImage(itemManager.getImage(itemId, qty, false), fillColor); + fillCache.put(key, image); + } + return image; + } + + void invalidateCache() + { + fillCache.invalidateAll(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java index 77a0548287..cdbf26a845 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java @@ -39,6 +39,7 @@ import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.ConfigChanged; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.plugins.Plugin; @@ -147,6 +148,15 @@ public class InventoryTagsPlugin extends Plugin editorMode = false; } + @Subscribe + public void onConfigChanged(ConfigChanged configChanged) + { + if (configChanged.getGroup().equals(InventoryTagsConfig.GROUP)) + { + overlay.invalidateCache(); + } + } + @Subscribe public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) { 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 1a6d4677e7..ac7be8d848 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 @@ -215,7 +215,7 @@ public class ItemStatChanges add(new GauntletPotion(), EGNIOL_POTION_1, EGNIOL_POTION_2, EGNIOL_POTION_3, EGNIOL_POTION_4); // Soul Wars - add(combo(2, heal(HITPOINTS, perc(.20, 2)), heal(RUN_ENERGY, 100)), BANDAGES_25202); + add(combo(2, heal(HITPOINTS, perc(.15, 1)), heal(RUN_ENERGY, 100)), BANDAGES_25202); add(combo(6, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(PRAYER, perc(.25, 8))), POTION_OF_POWER1, POTION_OF_POWER2, POTION_OF_POWER3, POTION_OF_POWER4); 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/stats/Stat.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/stats/Stat.java index be7b2ff4d8..2d65a7993c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/stats/Stat.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/stats/Stat.java @@ -52,7 +52,7 @@ public abstract class Stat public abstract int getValue(Client client); /** - * Get the base stat maximum, ie. the bottom half of the stat fraction. + * Get the base stat maximum. (ie. the bottom half of the stat fraction) */ public abstract int getMaximum(Client client); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index 7bf83abca3..f3802e230a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -145,7 +145,8 @@ public class LootTrackerPlugin extends Plugin // Chest loot handling private static final String CHEST_LOOTED_MESSAGE = "You find some treasure in the chest!"; private static final Pattern LARRAN_LOOTED_PATTERN = Pattern.compile("You have opened Larran's (big|small) chest .*"); - private static final String STONE_CHEST_LOOTED_MESSAGE = "You steal some loot from the chest."; + // Used by Stone Chest, Isle of Souls chest, Dark Chest + private static final String OTHER_CHEST_LOOTED_MESSAGE = "You steal some loot from the chest."; private static final String DORGESH_KAAN_CHEST_LOOTED_MESSAGE = "You find treasure inside!"; private static final String GRUBBY_CHEST_LOOTED_MESSAGE = "You have opened the Grubby Chest"; private static final Pattern HAM_CHEST_LOOTED_PATTERN = Pattern.compile("Your (?[a-z]+) key breaks in the lock.*"); @@ -161,6 +162,8 @@ public class LootTrackerPlugin extends Plugin put(10835, "Dorgesh-Kaan Chest"). put(10834, "Dorgesh-Kaan Chest"). put(7323, "Grubby Chest"). + put(8593, "Isle of Souls Chest"). + put(7827, "Dark Chest"). build(); // Shade chest loot handling @@ -186,6 +189,11 @@ public class LootTrackerPlugin extends Plugin put(ObjectID.SILVER_CHEST_4128, "Silver key crimson"). put(ObjectID.SILVER_CHEST_4129, "Silver key black"). put(ObjectID.SILVER_CHEST_4130, "Silver key purple"). + put(ObjectID.GOLD_CHEST, "Gold key red"). + put(ObjectID.GOLD_CHEST_41213, "Gold key brown"). + put(ObjectID.GOLD_CHEST_41214, "Gold key crimson"). + put(ObjectID.GOLD_CHEST_41215, "Gold key black"). + put(ObjectID.GOLD_CHEST_41216, "Gold key purple"). build(); // Hallow Sepulchre Coffin handling @@ -625,7 +633,7 @@ public class LootTrackerPlugin extends Plugin final String message = event.getMessage(); - if (message.equals(CHEST_LOOTED_MESSAGE) || message.equals(STONE_CHEST_LOOTED_MESSAGE) + if (message.equals(CHEST_LOOTED_MESSAGE) || message.equals(OTHER_CHEST_LOOTED_MESSAGE) || message.equals(DORGESH_KAAN_CHEST_LOOTED_MESSAGE) || message.startsWith(GRUBBY_CHEST_LOOTED_MESSAGE) || LARRAN_LOOTED_PATTERN.matcher(message).matches()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java index 6f3421b08a..b557cc18b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java @@ -466,6 +466,7 @@ public class MusicPlugin extends Plugin public void update() { + handle.setNoClickThrough(false); handle.setOnDragListener((JavaScriptCallback) this::drag); handle.setOnDragCompleteListener((JavaScriptCallback) this::drag); handle.setHasListener(true); @@ -511,6 +512,9 @@ public class MusicPlugin extends Plugin int level = (x * channel.max) / getWidth(); level = Ints.constrainToRange(level, 0, channel.max); channel.setLevel(level); + + int percent = (int) Math.round((level * 100.0 / channel.getMax())); + sliderTooltip = new Tooltip(channel.getName() + ": " + percent + "%"); } protected int getWidth() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java index 9582288ea1..e1fd961216 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java @@ -36,6 +36,7 @@ import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.Text; public class NpcMinimapOverlay extends Overlay { @@ -56,7 +57,7 @@ public class NpcMinimapOverlay extends Overlay { for (NPC npc : plugin.getHighlightedNpcs()) { - renderNpcOverlay(graphics, npc, npc.getName(), config.getHighlightColor()); + renderNpcOverlay(graphics, npc, Text.removeTags(npc.getName()), config.getHighlightColor()); } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java index 46a4a0924d..cfa99092a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java @@ -88,7 +88,6 @@ public class ObjectIndicatorsPlugin extends Plugin private static final String MARK = "Mark object"; private static final String UNMARK = "Unmark object"; - private final Gson GSON = new Gson(); @Getter(AccessLevel.PACKAGE) private final List objects = new ArrayList<>(); private final Map> points = new HashMap<>(); @@ -108,6 +107,9 @@ public class ObjectIndicatorsPlugin extends Plugin @Inject private ObjectIndicatorsConfig config; + @Inject + private Gson gson; + @Provides ObjectIndicatorsConfig provideConfig(ConfigManager configManager) { @@ -428,7 +430,7 @@ public class ObjectIndicatorsPlugin extends Plugin } else { - final String json = GSON.toJson(points); + final String json = gson.toJson(points); configManager.setConfiguration(CONFIG_GROUP, "region_" + id, json); } } @@ -442,7 +444,7 @@ public class ObjectIndicatorsPlugin extends Plugin return null; } - Set points = GSON.fromJson(json, new TypeToken>() + Set points = gson.fromJson(json, new TypeToken>() { }.getType()); // Prior to multiloc support the plugin would mark objects named "null", which breaks diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java index 88dca9d214..5ec747e3f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java @@ -88,6 +88,9 @@ public class ScreenMarkerPlugin extends Plugin @Inject private ScreenMarkerCreationOverlay overlay; + @Inject + private Gson gson; + @Getter @Inject private ColorPickerManager colorPickerManager; @@ -266,7 +269,6 @@ public class ScreenMarkerPlugin extends Plugin return; } - final Gson gson = new Gson(); final String json = gson .toJson(screenMarkers.stream().map(ScreenMarkerOverlay::getMarker).collect(Collectors.toList())); configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, json); @@ -279,7 +281,6 @@ public class ScreenMarkerPlugin extends Plugin return Stream.empty(); } - final Gson gson = new Gson(); final List screenMarkerData = gson.fromJson(json, new TypeToken>() { }.getType()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java index 72ad3524ee..db9b247fe3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java @@ -99,7 +99,7 @@ public class SlayerPlugin extends Plugin //Chat messages private static final Pattern CHAT_GEM_PROGRESS_MESSAGE = Pattern.compile("^(?:You're assigned to kill|You have received a new Slayer assignment from .*:) (?:[Tt]he )?(?.+?)(?: (?:in|on|south of) (?:the )?(?[^;]+))?(?:; only | \\()(?\\d+)(?: more to go\\.|\\))$"); private static final String CHAT_GEM_COMPLETE_MESSAGE = "You need something new to hunt."; - private static final Pattern CHAT_COMPLETE_MESSAGE = Pattern.compile("(?:\\d+,)*\\d+"); + private static final Pattern CHAT_COMPLETE_MESSAGE = Pattern.compile("You've completed (?:at least )?(?[\\d,]+) (?:Wilderness )?tasks?(?: and received \\d+ points, giving you a total of (?[\\d,]+)| and reached the maximum amount of Slayer points \\((?[\\d,]+)\\))?"); private static final String CHAT_CANCEL_MESSAGE = "Your task has been cancelled."; private static final String CHAT_CANCEL_MESSAGE_JAD = "You no longer have a slayer task as you left the fight cave."; private static final String CHAT_CANCEL_MESSAGE_ZUK = "You no longer have a slayer task as you left the Inferno."; @@ -450,6 +450,7 @@ public class SlayerPlugin extends Plugin expeditiousChargeCount = Integer.parseInt(mExpeditious.group(1)); config.expeditious(expeditiousChargeCount); } + if (chatMsg.startsWith(CHAT_BRACELET_SLAUGHTER_CHARGE)) { Matcher mSlaughter = CHAT_BRACELET_SLAUGHTER_CHARGE_REGEX.matcher(chatMsg); @@ -466,35 +467,25 @@ public class SlayerPlugin extends Plugin { Matcher mComplete = CHAT_COMPLETE_MESSAGE.matcher(chatMsg); - List matches = new ArrayList<>(); - while (mComplete.find()) + if (mComplete.find()) { - matches.add(mComplete.group(0).replaceAll(",", "")); - } + String mTasks = mComplete.group("tasks"); + String mPoints = mComplete.group("points"); + if (mPoints == null) + { + mPoints = mComplete.group("points2"); + } - int streak = -1, points = -1; - switch (matches.size()) - { - case 0: - streak = 1; - break; - case 1: - streak = Integer.parseInt(matches.get(0)); - break; - case 3: - streak = Integer.parseInt(matches.get(0)); - points = Integer.parseInt(matches.get(2)); - break; - default: - log.warn("Unreachable default case for message ending in '; return to Slayer master'"); - } - if (streak != -1) - { - config.streak(streak); - } - if (points != -1) - { - config.points(points); + if (mTasks != null) + { + int streak = Integer.parseInt(mTasks.replace(",", "")); + config.streak(streak); + } + if (mPoints != null) + { + int points = Integer.parseInt(mPoints.replace(",", "")); + config.points(points); + } } setTask("", 0, 0); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index 799dd098ef..65f41baf67 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -60,7 +60,7 @@ import net.runelite.client.ws.WSClient; @PluginDescriptor( name = "Special Attack Counter", - description = "Track DWH, Arclight, Darklight, and BGS special attacks used on NPCs", + description = "Track special attacks used on NPCs", tags = {"combat", "npcs", "overlay"}, enabledByDefault = false ) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java index e3cd82cfc6..a566f7680b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java @@ -37,7 +37,13 @@ enum SpecialWeapon ARCLIGHT("Arclight", ItemID.ARCLIGHT, false, SpecialCounterConfig::arclightThreshold), DARKLIGHT("Darklight", ItemID.DARKLIGHT, false, SpecialCounterConfig::darklightThreshold), BANDOS_GODSWORD("Bandos Godsword", ItemID.BANDOS_GODSWORD, true, SpecialCounterConfig::bandosGodswordThreshold), - BANDOS_GODSWORD_OR("Bandos Godsword", ItemID.BANDOS_GODSWORD_OR, true, SpecialCounterConfig::bandosGodswordThreshold); + BANDOS_GODSWORD_OR("Bandos Godsword", ItemID.BANDOS_GODSWORD_OR, true, SpecialCounterConfig::bandosGodswordThreshold), + BARRELCHEST_ANCHOR("Barrelchest Anchor", ItemID.BARRELCHEST_ANCHOR, true, (c) -> 0), + BONE_DAGGER("Bone Dagger", ItemID.BONE_DAGGER, true, (c) -> 0), + BONE_DAGGER_P("Bone Dagger (p)", ItemID.BONE_DAGGER_P, true, (c) -> 0), + BONE_DAGGER_P8876("Bone Dagger (p+)", ItemID.BONE_DAGGER_P_8876, true, (c) -> 0), + BONE_DAGGER_P8878("Bone Dagger (p++)", ItemID.BONE_DAGGER_P_8878, true, (c) -> 0), + DORGESHUUN_CROSSBOW("Dorgeshuun Crossbow", ItemID.DORGESHUUN_CROSSBOW, true, (c) -> 0); private final String name; private final int itemID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java index 8ec93c1b18..1d54c85935 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java @@ -39,7 +39,7 @@ import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; -public class TeamCapesOverlay extends OverlayPanel +class TeamCapesOverlay extends OverlayPanel { private final TeamCapesPlugin plugin; private final TeamCapesConfig config; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java index 103129d64f..c36b7ddd76 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java @@ -25,21 +25,24 @@ package net.runelite.client.plugins.teamcapes; import com.google.inject.Provides; -import java.time.temporal.ChronoUnit; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.api.GameState; import net.runelite.api.Player; +import net.runelite.api.events.PlayerChanged; +import net.runelite.api.events.PlayerDespawned; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.task.Schedule; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( @@ -48,19 +51,26 @@ import net.runelite.client.ui.overlay.OverlayManager; tags = {"overlay", "players"}, enabledByDefault = false ) +@Slf4j public class TeamCapesPlugin extends Plugin { @Inject private Client client; + @Inject + private ClientThread clientThread; + @Inject private OverlayManager overlayManager; @Inject private TeamCapesOverlay overlay; - // Hashmap of team capes: Key is the teamCape #, Value is the count of teamcapes in the area. - private Map teams = new HashMap<>(); + // Team number -> Number of players + @Getter(AccessLevel.PACKAGE) + private Map teams = new LinkedHashMap<>(); + // Player -> Team number + private final Map playerTeam = new HashMap<>(); @Provides TeamCapesConfig provideConfig(ConfigManager configManager) @@ -72,6 +82,8 @@ public class TeamCapesPlugin extends Plugin protected void startUp() throws Exception { overlayManager.add(overlay); + + clientThread.invokeLater(() -> client.getPlayers().forEach(this::update)); } @Override @@ -79,48 +91,61 @@ public class TeamCapesPlugin extends Plugin { overlayManager.remove(overlay); teams.clear(); + playerTeam.clear(); } - @Schedule( - period = 1800, - unit = ChronoUnit.MILLIS - ) - public void update() + @Subscribe + public void onPlayerChanged(PlayerChanged playerChanged) { - if (client.getGameState() != GameState.LOGGED_IN) + Player player = playerChanged.getPlayer(); + update(player); + } + + private void update(Player player) + { + int oldTeam = playerTeam.getOrDefault(player, 0); + if (oldTeam == player.getTeam()) { return; } - List players = client.getPlayers(); - teams.clear(); - for (Player player : players) + + log.debug("{} has changed teams: {} -> {}", player.getName(), oldTeam, player.getTeam()); + + if (oldTeam > 0) { - int team = player.getTeam(); - if (team > 0) - { - if (teams.containsKey(team)) - { - teams.put(team, teams.get(team) + 1); - } - else - { - teams.put(team, 1); - } - } + teams.computeIfPresent(oldTeam, (key, value) -> value > 1 ? value - 1 : null); + playerTeam.remove(player); } + if (player.getTeam() > 0) + { + teams.merge(player.getTeam(), 1, Integer::sum); + playerTeam.put(player, player.getTeam()); + } + + sort(); + } + + @Subscribe + public void onPlayerDespawned(PlayerDespawned playerDespawned) + { + Player player = playerDespawned.getPlayer(); + Integer team = playerTeam.remove(player); + if (team != null) + { + teams.computeIfPresent(team, (key, value) -> value > 1 ? value - 1 : null); + sort(); + } + } + + private void sort() + { // Sort teams by value in descending order and then by key in ascending order, limited to 5 entries teams = teams.entrySet().stream() - .sorted( - Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()) - .thenComparingInt(Map.Entry::getKey) - ) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); + .sorted( + Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()) + .thenComparingInt(Map.Entry::getKey) + ) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); } - - public Map getTeams() - { - return teams; - } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixConfig.java new file mode 100644 index 0000000000..936a14db20 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixConfig.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020, cgati + * 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.tearsofguthix; + +import java.awt.Color; +import net.runelite.client.config.Alpha; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.util.ColorUtil; + +@ConfigGroup("tearsofguthix") +public interface TearsOfGuthixConfig extends Config +{ + @ConfigItem( + keyName = "showGreenTearsTimer", + name = "Enable Green Tears Timer", + description = "Configures whether to display a timer for green tears or not", + position = 1 + ) + default boolean showGreenTearsTimer() + { + return true; + } + + @Alpha + @ConfigItem( + keyName = "blueTearsColor", + name = "Blue Tears Color", + description = "Color of Blue Tears timer", + position = 2 + ) + default Color getBlueTearsColor() + { + return ColorUtil.colorWithAlpha(Color.CYAN, 100); + } + + @Alpha + @ConfigItem( + keyName = "greenTearsColor", + name = "Green Tears Color", + description = "Color of Green Tears timer", + position = 3 + ) + default Color getGreenTearsColor() + { + return ColorUtil.colorWithAlpha(Color.GREEN, 100); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java index 87148caef7..63964d5541 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java @@ -36,17 +36,18 @@ 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.components.ProgressPieComponent; +import net.runelite.client.util.ColorUtil; class TearsOfGuthixOverlay extends Overlay { - private static final Color CYAN_ALPHA = new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 100); - private static final Color GREEN_ALPHA = new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 100); private static final Duration MAX_TIME = Duration.ofSeconds(9); + private final TearsOfGuthixConfig config; private final TearsOfGuthixPlugin plugin; @Inject - private TearsOfGuthixOverlay(TearsOfGuthixPlugin plugin) + private TearsOfGuthixOverlay(TearsOfGuthixConfig config, TearsOfGuthixPlugin plugin) { + this.config = config; this.plugin = plugin; setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_SCENE); @@ -55,8 +56,24 @@ class TearsOfGuthixOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { + if (plugin.getStreams().isEmpty()) + { + return null; + } + + Color blueTearsFill = config.getBlueTearsColor(); + Color greenTearsFill = config.getGreenTearsColor(); + Color blueTearsBorder = ColorUtil.colorWithAlpha(blueTearsFill, 255); + Color greenTearsBorder = ColorUtil.colorWithAlpha(greenTearsFill, 255); + plugin.getStreams().forEach((object, timer) -> { + if ((object.getId() == ObjectID.GREEN_TEARS || object.getId() == ObjectID.GREEN_TEARS_6666) + && !config.showGreenTearsTimer()) + { + return; + } + final Point position = object.getCanvasLocation(100); if (position == null) @@ -70,14 +87,14 @@ class TearsOfGuthixOverlay extends Overlay if (object.getId() == ObjectID.BLUE_TEARS || object.getId() == ObjectID.BLUE_TEARS_6665) { - progressPie.setFill(CYAN_ALPHA); - progressPie.setBorderColor(Color.CYAN); + progressPie.setFill(blueTearsFill); + progressPie.setBorderColor(blueTearsBorder); } else if (object.getId() == ObjectID.GREEN_TEARS || object.getId() == ObjectID.GREEN_TEARS_6666) { - progressPie.setFill(GREEN_ALPHA); - progressPie.setBorderColor(Color.GREEN); + progressPie.setFill(greenTearsFill); + progressPie.setBorderColor(greenTearsBorder); } progressPie.setPosition(position); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java index 899182b500..5b315bb142 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java @@ -28,6 +28,7 @@ import java.time.Instant; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; +import com.google.inject.Provides; import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.DecorativeObject; @@ -35,6 +36,7 @@ import net.runelite.api.ObjectID; import net.runelite.api.events.DecorativeObjectDespawned; import net.runelite.api.events.DecorativeObjectSpawned; import net.runelite.api.events.GameStateChanged; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -61,6 +63,12 @@ public class TearsOfGuthixPlugin extends Plugin @Getter private final Map streams = new HashMap<>(); + @Provides + TearsOfGuthixConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(TearsOfGuthixConfig.class); + } + @Override protected void startUp() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java index 73590d7d2d..28704ff3ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java @@ -40,6 +40,7 @@ public interface TimeTrackingConfig extends Config String BOTANIST = "botanist"; String TIMERS = "timers"; String STOPWATCHES = "stopwatches"; + String PREFER_SOONEST = "preferSoonest"; @ConfigItem( keyName = "timeFormatMode", @@ -120,6 +121,17 @@ public interface TimeTrackingConfig extends Config return 10; } + @ConfigItem( + keyName = PREFER_SOONEST, + name = "Prefer soonest completion", + description = "When displaying completion times on the overview, prefer showing the soonest any patch will complete.", + position = 7 + ) + default boolean preferSoonest() + { + return false; + } + @ConfigItem( keyName = "activeTab", name = "Active Tab", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java index 0f6f3c30f1..310c2e4e4a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java @@ -51,6 +51,7 @@ import net.runelite.client.events.RuneScapeProfileChanged; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.CONFIG_GROUP; +import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.PREFER_SOONEST; import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.STOPWATCHES; import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.TIMERS; import net.runelite.client.plugins.timetracking.clocks.ClockManager; @@ -173,6 +174,10 @@ public class TimeTrackingPlugin extends Plugin { clockManager.loadStopwatches(); } + else if (e.getKey().equals(PREFER_SOONEST)) + { + farmingTracker.loadCompletionTimes(); + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java index 720c5633e9..30d16ff573 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java @@ -53,6 +53,9 @@ public class ClockManager @Inject private Notifier notifier; + @Inject + private Gson gson; + @Getter private final List timers = new CopyOnWriteArrayList<>(); @@ -183,7 +186,6 @@ public class ClockManager if (!Strings.isNullOrEmpty(timersJson)) { - final Gson gson = new Gson(); final List timers = gson.fromJson(timersJson, new TypeToken>() { }.getType()); @@ -200,7 +202,6 @@ public class ClockManager if (!Strings.isNullOrEmpty(stopwatchesJson)) { - final Gson gson = new Gson(); final List stopwatches = gson.fromJson(stopwatchesJson, new TypeToken>() { }.getType()); @@ -227,14 +228,12 @@ public class ClockManager void saveTimers() { - final Gson gson = new Gson(); final String json = gson.toJson(timers); configManager.setConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.TIMERS, json); } void saveStopwatches() { - final Gson gson = new Gson(); final String json = gson.toJson(stopwatches); configManager.setConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.STOPWATCHES, json); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java index 409ee85e1d..a5c953f324 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java @@ -407,7 +407,7 @@ public class FarmingTracker { for (Map.Entry> tab : farmingWorld.getTabs().entrySet()) { - long maxCompletionTime = 0; + long extremumCompletionTime = config.preferSoonest() ? Long.MAX_VALUE : 0; boolean allUnknown = true; boolean allEmpty = true; @@ -426,7 +426,15 @@ public class FarmingTracker allEmpty = false; // update max duration if this patch takes longer to grow - maxCompletionTime = Math.max(maxCompletionTime, prediction.getDoneEstimate()); + if (config.preferSoonest()) + { + extremumCompletionTime = Math.min(extremumCompletionTime, prediction.getDoneEstimate()); + } + else + { + extremumCompletionTime = Math.max(extremumCompletionTime, prediction.getDoneEstimate()); + } + } } @@ -443,7 +451,7 @@ public class FarmingTracker state = SummaryState.EMPTY; completionTime = -1L; } - else if (maxCompletionTime <= Instant.now().getEpochSecond()) + else if (extremumCompletionTime <= Instant.now().getEpochSecond()) { state = SummaryState.COMPLETED; completionTime = 0; @@ -451,7 +459,7 @@ public class FarmingTracker else { state = SummaryState.IN_PROGRESS; - completionTime = maxCompletionTime; + completionTime = extremumCompletionTime; } summaries.put(tab.getKey(), state); completionTimes.put(tab.getKey(), completionTime); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java index 8552d90eef..622e4db98b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java @@ -67,7 +67,6 @@ public class WikiSearchChatboxTextInput extends ChatboxTextInput private static final int PREDICTION_DEBOUNCE_DELAY_MS = 200; private final ChatboxPanelManager chatboxPanelManager; - private final Gson gson = new Gson(); private Future runningRequest = null; private List predictions = ImmutableList.of(); @@ -78,7 +77,7 @@ public class WikiSearchChatboxTextInput extends ChatboxTextInput @Inject public WikiSearchChatboxTextInput(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread, ScheduledExecutorService scheduledExecutorService, @Named("developerMode") final boolean developerMode, - OkHttpClient okHttpClient) + OkHttpClient okHttpClient, Gson gson) { super(chatboxPanelManager, clientThread); this.chatboxPanelManager = chatboxPanelManager; 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 b10e2a0667..f0d4f88185 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 @@ -47,10 +47,10 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.ChatPlayer; -import net.runelite.api.FriendsChatMember; -import net.runelite.api.FriendsChatManager; import net.runelite.api.Client; import net.runelite.api.Friend; +import net.runelite.api.FriendsChatManager; +import net.runelite.api.FriendsChatMember; import net.runelite.api.GameState; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; @@ -60,10 +60,11 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.PlayerMenuOptionClicked; +import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WorldListLoad; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; @@ -111,6 +112,9 @@ public class WorldHopperPlugin extends Plugin @Inject private Client client; + @Inject + private ClientThread clientThread; + @Inject private ConfigManager configManager; @@ -162,7 +166,7 @@ public class WorldHopperPlugin extends Plugin @Override public void hotkeyPressed() { - hop(true); + clientThread.invoke(() -> hop(true)); } }; private final HotkeyListener nextKeyListener = new HotkeyListener(() -> config.nextKey()) @@ -170,7 +174,7 @@ public class WorldHopperPlugin extends Plugin @Override public void hotkeyPressed() { - hop(false); + clientThread.invoke(() -> hop(false)); } }; @@ -304,7 +308,7 @@ public class WorldHopperPlugin extends Plugin void hopTo(World world) { - hop(world.getId()); + clientThread.invoke(() -> hop(world.getId())); } void addToFavorites(World world) @@ -408,9 +412,9 @@ public class WorldHopperPlugin extends Plugin } @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + public void onMenuOptionClicked(MenuOptionClicked event) { - if (!event.getMenuOption().equals(HOP_TO)) + if (event.getMenuAction() != MenuAction.RUNELITE || !event.getMenuOption().equals(HOP_TO)) { return; } @@ -613,6 +617,8 @@ public class WorldHopperPlugin extends Plugin private void hop(int worldId) { + assert client.isClientThread(); + WorldResult worldResult = worldService.getWorlds(); // Don't try to hop if the world doesn't exist World world = worldResult.findWorld(worldId); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java index 9948a856f5..12d0a724c3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java @@ -370,10 +370,7 @@ class WorldSwitcherPanel extends PluginPanel private WorldTableRow buildRow(World world, boolean stripe, boolean current, boolean favorite) { WorldTableRow row = new WorldTableRow(world, current, favorite, plugin.getStoredPing(world), - world1 -> - { - plugin.hopTo(world1); - }, + plugin::hopTo, (world12, add) -> { if (add) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java index a5f0b55ca0..cc387c4872 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java @@ -55,6 +55,7 @@ enum MinigameLocation PYRAMID_PLUNDER("Pyramid Plunder", new WorldPoint(3288, 2787, 0)), RANGING_GUILD("Ranging Guild", new WorldPoint(2671, 3419, 0)), ROGUES_DEN("Rogues' Den", new WorldPoint(2905, 3537, 0)), + SHADES_OF_MORTTON("Shades of Mort'ton", new WorldPoint(3505, 3315, 0)), SORCERESSS_GARDEN("Sorceress's Garden", new WorldPoint(3285, 3180, 0)), TROUBLE_BREWING("Trouble Brewing", new WorldPoint(3811, 3021, 0)), VOLCANIC_MINE("Volcanic Mine", new WorldPoint(3812, 3810, 0)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java index 1114d56720..dcac0c700f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java @@ -186,7 +186,7 @@ public class WorldMapPlugin extends Plugin { case AGILITY: { - int newAgilityLevel = statChanged.getLevel(); + int newAgilityLevel = statChanged.getBoostedLevel(); if (newAgilityLevel != agilityLevel) { agilityLevel = newAgilityLevel; @@ -196,7 +196,7 @@ public class WorldMapPlugin extends Plugin } case WOODCUTTING: { - int newWoodcutLevel = statChanged.getLevel(); + int newWoodcutLevel = statChanged.getBoostedLevel(); if (newWoodcutLevel != woodcuttingLevel) { woodcuttingLevel = newWoodcutLevel; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java index c32a8c598a..2a956da851 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java @@ -89,11 +89,22 @@ public interface XpGlobesConfig extends Config return false; } + @ConfigItem( + keyName = "showVirtualLevel", + name = "Show virtual level", + description = "Shows virtual level if over 99 in a skill and Hide maxed skill is not checked", + position = 5 + ) + default boolean showVirtualLevel() + { + return false; + } + @ConfigItem( keyName = "enableCustomArcColor", name = "Enable custom arc color", description = "Enables the custom coloring of the globe's arc instead of using the skill's default color.", - position = 5 + position = 6 ) default boolean enableCustomArcColor() { @@ -105,7 +116,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress arc color", name = "Progress arc color", description = "Change the color of the progress arc in the xp orb", - position = 6 + position = 7 ) default Color progressArcColor() { @@ -117,7 +128,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress orb outline color", name = "Progress orb outline color", description = "Change the color of the progress orb outline", - position = 7 + position = 8 ) default Color progressOrbOutLineColor() { @@ -129,7 +140,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress orb background color", name = "Progress orb background color", description = "Change the color of the progress orb background", - position = 8 + position = 9 ) default Color progressOrbBackgroundColor() { @@ -140,7 +151,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress arc width", name = "Progress arc width", description = "Change the stroke width of the progress arc", - position = 9 + position = 10 ) @Units(Units.PIXELS) default int progressArcStrokeWidth() @@ -152,7 +163,7 @@ public interface XpGlobesConfig extends Config keyName = "Orb size", name = "Size of orbs", description = "Change the size of the xp orbs", - position = 10 + position = 11 ) @Units(Units.PIXELS) default int xpOrbSize() @@ -164,7 +175,7 @@ public interface XpGlobesConfig extends Config keyName = "Orb duration", name = "Duration of orbs", description = "Change the duration the xp orbs are visible", - position = 11 + position = 12 ) @Units(Units.SECONDS) default int xpOrbDuration() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java index 46b514151e..39b947616a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java @@ -106,9 +106,17 @@ public class XpGlobesPlugin extends Plugin return; } - if (config.hideMaxed() && currentLevel >= Experience.MAX_REAL_LEVEL) + if (currentLevel >= Experience.MAX_REAL_LEVEL) { - return; + if (config.hideMaxed()) + { + return; + } + + if (config.showVirtualLevel()) + { + currentLevel = Experience.getLevelForXp(currentXp); + } } if (cachedGlobe != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java index fac3c16410..1fbbdb2c49 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java @@ -159,8 +159,8 @@ class XpState } /** - * Update number of actions performed for skill (e.g amount of kills in this case) if last interacted - * NPC died + * Update number of actions performed for skill if last interacted NPC died. + * (eg. amount of kills in this case) * @param skill skill to update actions for * @param npc npc that just died * @param npcHealth max health of npc that just died 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 564ebcba62..5305506a41 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,17 +24,25 @@ */ package net.runelite.client.ui; -import javax.swing.text.StyleContext; import java.awt.Font; import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; import java.io.IOException; +import javax.swing.text.StyleContext; +import lombok.Getter; public class FontManager { + @Getter private static final Font runescapeFont; + @Getter private static final Font runescapeSmallFont; + @Getter private static final Font runescapeBoldFont; + @Getter + private static final Font defaultFont; + @Getter + private static final Font defaultBoldFont; static { @@ -48,7 +56,7 @@ public class FontManager ge.registerFont(font); runescapeFont = StyleContext.getDefaultStyleContext() - .getFont(font.getName(), Font.PLAIN, 16); + .getFont(font.getName(), Font.PLAIN, 16); ge.registerFont(runescapeFont); Font smallFont = Font.createFont(Font.TRUETYPE_FONT, @@ -57,16 +65,16 @@ public class FontManager ge.registerFont(smallFont); runescapeSmallFont = StyleContext.getDefaultStyleContext() - .getFont(smallFont.getName(), Font.PLAIN, 16); + .getFont(smallFont.getName(), Font.PLAIN, 16); ge.registerFont(runescapeSmallFont); Font boldFont = Font.createFont(Font.TRUETYPE_FONT, - FontManager.class.getResourceAsStream("runescape_bold.ttf")) - .deriveFont(Font.BOLD, 16); + FontManager.class.getResourceAsStream("runescape_bold.ttf")) + .deriveFont(Font.BOLD, 16); ge.registerFont(boldFont); runescapeBoldFont = StyleContext.getDefaultStyleContext() - .getFont(boldFont.getName(), Font.BOLD, 16); + .getFont(boldFont.getName(), Font.BOLD, 16); ge.registerFont(runescapeBoldFont); } catch (FontFormatException ex) @@ -77,20 +85,8 @@ public class FontManager { throw new RuntimeException("Font file not found.", ex); } - } - public static Font getRunescapeFont() - { - return runescapeFont; - } - - public static Font getRunescapeSmallFont() - { - return runescapeSmallFont; - } - - public static Font getRunescapeBoldFont() - { - return runescapeBoldFont; + defaultFont = new Font(Font.DIALOG, Font.PLAIN, 16); + defaultBoldFont = new Font(Font.DIALOG, Font.BOLD, 16); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java index cb317b8afd..b4c2ff1127 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java @@ -29,6 +29,7 @@ package net.runelite.client.ui.components; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; @@ -125,7 +126,7 @@ public class IconTextField extends JPanel textField.addMouseListener(hoverEffect); innerTxt.addMouseListener(hoverEffect); - clearButton = createRHSButton(ColorScheme.PROGRESS_ERROR_COLOR, Color.PINK); + clearButton = createRHSButton(ColorScheme.PROGRESS_ERROR_COLOR, Color.PINK, FontManager.getRunescapeBoldFont()); clearButton.setText("×"); clearButton.addActionListener(evt -> { @@ -192,7 +193,7 @@ public class IconTextField extends JPanel } }); - suggestionButton = createRHSButton(ColorScheme.LIGHT_GRAY_COLOR, ColorScheme.MEDIUM_GRAY_COLOR); + suggestionButton = createRHSButton(ColorScheme.LIGHT_GRAY_COLOR, ColorScheme.MEDIUM_GRAY_COLOR, FontManager.getDefaultBoldFont()); suggestionButton.setText("▾"); suggestionButton.addActionListener(e -> { @@ -237,11 +238,11 @@ public class IconTextField extends JPanel add(rhsButtons, BorderLayout.EAST); } - private JButton createRHSButton(Color fg, Color rollover) + private JButton createRHSButton(Color fg, Color rollover, Font font) { JButton b = new JButton(); b.setPreferredSize(new Dimension(30, 0)); - b.setFont(FontManager.getRunescapeBoldFont()); + b.setFont(font); b.setBorder(null); b.setRolloverEnabled(true); SwingUtil.removeButtonDecorations(b); 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 20638e7874..83c67c09e0 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 @@ -28,6 +28,7 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; @@ -50,6 +51,10 @@ public class LineComponent implements LayoutableRenderableEntity @Builder.Default private Color rightColor = Color.WHITE; + private Font leftFont; + + private Font rightFont; + @Builder.Default private Point preferredLocation = new Point(); @@ -67,13 +72,16 @@ public class LineComponent implements LayoutableRenderableEntity final String left = MoreObjects.firstNonNull(this.left, ""); final String right = MoreObjects.firstNonNull(this.right, ""); - final FontMetrics metrics = graphics.getFontMetrics(); + final Font leftFont = MoreObjects.firstNonNull(this.leftFont, graphics.getFont()); + final Font rightFont = MoreObjects.firstNonNull(this.rightFont, graphics.getFont()); + final FontMetrics lfm = graphics.getFontMetrics(leftFont), rfm = graphics.getFontMetrics(rightFont); + final int fmHeight = Math.max(lfm.getHeight(), rfm.getHeight()); final int baseX = preferredLocation.x; - final int baseY = preferredLocation.y + metrics.getHeight(); + final int baseY = preferredLocation.y + fmHeight; int x = baseX; int y = baseY; - final int leftFullWidth = getLineWidth(left, metrics); - final int rightFullWidth = getLineWidth(right, metrics); + final int leftFullWidth = getLineWidth(left, lfm); + final int rightFullWidth = getLineWidth(right, rfm); final TextComponent textComponent = new TextComponent(); if (preferredSize.width < leftFullWidth + rightFullWidth) @@ -87,8 +95,8 @@ public class LineComponent implements LayoutableRenderableEntity leftSmallWidth -= rightSmallWidth; } - final String[] leftSplitLines = lineBreakText(left, leftSmallWidth, metrics); - final String[] rightSplitLines = lineBreakText(right, rightSmallWidth, metrics); + final String[] leftSplitLines = lineBreakText(left, leftSmallWidth, lfm); + final String[] rightSplitLines = lineBreakText(right, rightSmallWidth, rfm); int lineCount = Math.max(leftSplitLines.length, rightSplitLines.length); @@ -100,19 +108,21 @@ public class LineComponent implements LayoutableRenderableEntity textComponent.setPosition(new Point(x, y)); textComponent.setText(leftText); textComponent.setColor(leftColor); + textComponent.setFont(leftFont); textComponent.render(graphics); } if (i < rightSplitLines.length) { final String rightText = rightSplitLines[i]; - textComponent.setPosition(new Point(x + preferredSize.width - getLineWidth(rightText, metrics), y)); + textComponent.setPosition(new Point(x + preferredSize.width - getLineWidth(rightText, rfm), y)); textComponent.setText(rightText); textComponent.setColor(rightColor); + textComponent.setFont(rightFont); textComponent.render(graphics); } - y += metrics.getHeight(); + y += fmHeight; } final Dimension dimension = new Dimension(preferredSize.width, y - baseY); @@ -126,6 +136,7 @@ public class LineComponent implements LayoutableRenderableEntity textComponent.setPosition(new Point(x, y)); textComponent.setText(left); textComponent.setColor(leftColor); + textComponent.setFont(leftFont); textComponent.render(graphics); } @@ -134,10 +145,11 @@ public class LineComponent implements LayoutableRenderableEntity textComponent.setPosition(new Point(x + preferredSize.width - rightFullWidth, y)); textComponent.setText(right); textComponent.setColor(rightColor); + textComponent.setFont(rightFont); textComponent.render(graphics); } - y += metrics.getHeight(); + y += fmHeight; 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/TextComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java index 45326fea28..0b6054a466 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java @@ -26,10 +26,12 @@ package net.runelite.client.ui.overlay.components; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; import java.util.regex.Pattern; +import javax.annotation.Nullable; import lombok.Setter; import net.runelite.client.ui.overlay.RenderableEntity; import net.runelite.client.util.ColorUtil; @@ -45,10 +47,22 @@ public class TextComponent implements RenderableEntity private Point position = new Point(); private Color color = Color.WHITE; private boolean outline; + /** + * The text font. + */ + @Nullable + private Font font; @Override public Dimension render(Graphics2D graphics) { + Font originalFont = null; + if (font != null) + { + originalFont = graphics.getFont(); + graphics.setFont(font); + } + final FontMetrics fontMetrics = graphics.getFontMetrics(); if (COL_TAG_PATTERN_W_LOOKAHEAD.matcher(text).find()) @@ -105,6 +119,14 @@ public class TextComponent implements RenderableEntity graphics.drawString(text, position.x, position.y); } - return new Dimension(fontMetrics.stringWidth(text), fontMetrics.getHeight()); + int width = fontMetrics.stringWidth(text); + int height = fontMetrics.getHeight(); + + if (originalFont != null) + { + graphics.setFont(originalFont); + } + + return new Dimension(width, height); } } diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java index dfee412c03..e842005dba 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java @@ -26,6 +26,7 @@ package net.runelite.client.util; import com.google.common.base.Strings; +import com.google.gson.Gson; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.datatransfer.Clipboard; @@ -54,7 +55,6 @@ import net.runelite.api.GameState; import net.runelite.api.WorldType; import net.runelite.client.Notifier; import static net.runelite.client.RuneLite.SCREENSHOT_DIR; -import net.runelite.http.api.RuneLiteAPI; import okhttp3.Call; import okhttp3.Callback; import okhttp3.HttpUrl; @@ -75,6 +75,7 @@ public class ImageCapture private final Client client; private final Notifier notifier; private final OkHttpClient okHttpClient; + private final Gson gson; private final String imgurClientId; @Inject @@ -82,12 +83,14 @@ public class ImageCapture final Client client, final Notifier notifier, final OkHttpClient okHttpClient, + final Gson gson, @Named("runelite.imgur.client.id") final String imgurClientId ) { this.client = client; this.notifier = notifier; this.okHttpClient = okHttpClient; + this.gson = gson; this.imgurClientId = imgurClientId; } @@ -204,7 +207,7 @@ public class ImageCapture */ private void uploadScreenshot(File screenshotFile, boolean notify) throws IOException { - String json = RuneLiteAPI.GSON.toJson(new ImageUploadRequest(screenshotFile)); + String json = gson.toJson(new ImageUploadRequest(screenshotFile)); Request request = new Request.Builder() .url(IMGUR_IMAGE_UPLOAD_URL) @@ -225,8 +228,8 @@ public class ImageCapture { try (InputStream in = response.body().byteStream()) { - ImageUploadResponse imageUploadResponse = RuneLiteAPI.GSON - .fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), ImageUploadResponse.class); + ImageUploadResponse imageUploadResponse = + gson.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), ImageUploadResponse.class); if (imageUploadResponse.isSuccess()) { diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java index 488eb67108..92e3f8c773 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java @@ -397,8 +397,9 @@ public class ImageUtil { for (int y = 0; y < filledImage.getHeight(); y++) { - final Color pixelColor = new Color(image.getRGB(x, y), true); - if (pixelColor.getAlpha() == 0) + int pixel = image.getRGB(x, y); + int a = pixel >>> 24; + if (a == 0) { continue; } diff --git a/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java b/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java index 49823b5cca..2b838e409c 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java +++ b/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java @@ -182,7 +182,7 @@ public class QuantityFormatter } /** - * Calculates, given a string with a value denominator (ex. 20K) + * Calculates, given a string with a value denominator (for example, 20K) * the multiplier that the denominator represents (in this case 1000). * * @param string The string to check. diff --git a/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java index 60b3b305f1..fbcc28d28d 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java @@ -25,6 +25,8 @@ */ package net.runelite.client.util; +import com.google.common.io.ByteStreams; +import java.io.IOException; import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -36,7 +38,7 @@ public class ReflectUtil { } - public static MethodHandles.Lookup privateLookupIn(Class clazz) + public static MethodHandles.Lookup privateLookupIn(Class clazz) { try { @@ -44,7 +46,16 @@ public class ReflectUtil // we need to access it via reflection. This is preferred way because it's Java 9+ public api and is // likely to not change final Method privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); - return (MethodHandles.Lookup) privateLookupIn.invoke(null, clazz, MethodHandles.lookup()); + MethodHandles.Lookup caller; + if (clazz.getClassLoader() instanceof PrivateLookupableClassLoader) + { + caller = ((PrivateLookupableClassLoader) clazz.getClassLoader()).getLookup(); + } + else + { + caller = MethodHandles.lookup(); + } + return (MethodHandles.Lookup) privateLookupIn.invoke(null, clazz, caller); } catch (InvocationTargetException | IllegalAccessException e) { @@ -69,4 +80,51 @@ public class ReflectUtil } } } + + public interface PrivateLookupableClassLoader + { + // define class is protected final so this needs a different name to become public + Class defineClass0(String name, byte[] b, int off, int len) throws ClassFormatError; + + MethodHandles.Lookup getLookup(); + void setLookup(MethodHandles.Lookup lookup); + } + + /** + * Allows private Lookups to be created for classes in this ClassLoader + *

+ * Due to JDK-8173978 it is impossible to create get a lookup with module scoped permissions when teleporting + * between modules. Since external plugins are loaded in a separate classloader to us they are contained in unique + * unnamed modules. Since we (via LambdaMetafactory) are creating a hidden class in that module, we require module + * scoped access to it, and since the methods can be private, we also require private access. The only way to get + * MODULE|PRIVATE is to either 1) invokedynamic in that class, 2) call MethodHandles.lookup() from that class, or + * 3) call privateLookupIn with an existing lookup with PRIVATE|MODULE created from a class in the same module. + * Our solution is to make classloaders call this method which will define a class in the classloader's unnamed + * module that calls MethodHandles.lookup() and stores it in the classloader for later use. + */ + public static void installLookupHelper(PrivateLookupableClassLoader cl) + { + try + { + String name = PrivateLookupHelper.class.getName(); + byte[] classData = ByteStreams.toByteArray(ReflectUtil.class.getResourceAsStream("/" + name.replace('.', '/') + ".class")); + Class clazz = cl.defineClass0(name, classData, 0, classData.length); + + // force to run + clazz.getConstructor().newInstance(); + } + catch (IOException | ReflectiveOperationException e) + { + throw new RuntimeException("unable to install lookup helper", e); + } + } + + public static class PrivateLookupHelper + { + static + { + PrivateLookupableClassLoader pcl = (PrivateLookupableClassLoader) PrivateLookupHelper.class.getClassLoader(); + pcl.setLookup(MethodHandles.lookup()); + } + } } diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index 62877d1869..9543697a90 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -2727,6 +2727,10 @@ 2464, 8936 ], + "black dhide vambraces": [ + 2491, + 25494 + ], "blue dhide chaps": [ 2493, 7382, @@ -2743,7 +2747,8 @@ 2497, 12383, 12387, - 20424 + 20424, + 25493 ], "blue dhide body": [ 2499, @@ -2761,7 +2766,8 @@ 2503, 12381, 12385, - 20423 + 20423, + 25492 ], "dragon chainbody": [ 2513, @@ -7760,7 +7766,15 @@ ], "toxic blowpipe": [ 12924, - 12926 + 12926, + 25484, + 25485, + 25486, + 25487, + 25488, + 25489, + 25490, + 25491 ], "serpentine helm": [ 12929, @@ -9240,21 +9254,24 @@ 23887, 23888, 23971, - 23973 + 23973, + 25495 ], "crystal body": [ 23889, 23890, 23891, 23975, - 23977 + 23977, + 25496 ], "crystal legs": [ 23892, 23893, 23894, 23979, - 23981 + 23981, + 25497 ], "crystal staff": [ 23898, @@ -9623,10 +9640,6 @@ 25319, 25338 ], - "gnome child": [ - 25320, - 25321 - ], "soul cape": [ 25344, 25346 @@ -9635,5 +9648,25 @@ 25380, 25383, 25386 + ], + "bronze coffin": [ + 25459, + 25469 + ], + "steel coffin": [ + 25461, + 25470 + ], + "black coffin": [ + 25463, + 25471 + ], + "silver coffin": [ + 25465, + 25472 + ], + "gold coffin": [ + 25467, + 25473 ] } \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png index 3e41077561..c5b238a9d0 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/alchemical_hydra.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/alchemical_hydra.png index 3032e57ec4..b34ed9c93e 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/alchemical_hydra.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/alchemical_hydra.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/barrows_chests.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/barrows_chests.png index ba5c55efae..1560f1aaaa 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/barrows_chests.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/barrows_chests.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/bryophyta.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/bryophyta.png index 8cebd91ecf..68c4e2c904 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/bryophyta.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/bryophyta.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/callisto.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/callisto.png index 6f307a26d5..2248304cfe 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/callisto.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/callisto.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png index 4f7ef937cd..f7dc1f8047 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric.png index a7240d11f0..71bfdd30cf 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric_challenge_mode.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric_challenge_mode.png index c298966a16..31cc4b9cca 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric_challenge_mode.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric_challenge_mode.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_elemental.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_elemental.png index cc36114993..92ed8353fe 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_elemental.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_elemental.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_fanatic.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_fanatic.png index 73e680aef6..b712e9b70a 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_fanatic.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_fanatic.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png index e207d7e791..9f1d6d20cc 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/corporeal_beast.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/corporeal_beast.png index cd113c8ad9..26c69b2e5c 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/corporeal_beast.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/corporeal_beast.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/crazy_archaeologist.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/crazy_archaeologist.png index 53d758bf8e..d7cd6eaf1a 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/crazy_archaeologist.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/crazy_archaeologist.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png index 6b5543b5e1..bc6612dbf4 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png index fc2bcbc3a0..a18662f702 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_supreme.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_supreme.png index 044291cc4a..4cb52e4156 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_supreme.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_supreme.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/deranged_archaeologist.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/deranged_archaeologist.png index 8dfae8c2fb..10ee3e8fb0 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/deranged_archaeologist.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/deranged_archaeologist.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png index 1d8e4334fa..cefbc3c19b 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png index f814bbd2d5..48619319dc 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/grotesque_guardians.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/grotesque_guardians.png index 98606aed11..cf0bd826d5 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/grotesque_guardians.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/grotesque_guardians.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png index dffc71404c..a85a83ce3c 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kalphite_queen.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kalphite_queen.png index a6b77f9426..c88f0bb448 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kalphite_queen.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kalphite_queen.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png index 3bc8a77466..c162208002 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kraken.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kraken.png index c42e5d3fc9..b45dd224fb 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kraken.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kraken.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kreearra.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kreearra.png index 74b9eae788..2bc9631476 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kreearra.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kreearra.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kril_tsutsaroth.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kril_tsutsaroth.png index dfe129ae77..878a14c18b 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kril_tsutsaroth.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kril_tsutsaroth.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png index 3d2c0a4606..7f523c6b87 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png index 22907bb92f..c0f7645c02 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/obor.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/obor.png index 8c9ea13036..eb9fc64725 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/obor.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/obor.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/sarachnis.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/sarachnis.png index e74c398976..cbea6a8024 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/sarachnis.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/sarachnis.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png index eeb6310454..f39f9baa6e 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/skotizo.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/skotizo.png index cd96bbcca0..8888d2c315 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/skotizo.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/skotizo.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_corrupted_gauntlet.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_corrupted_gauntlet.png index 9553dde2c1..f1e2b6ec3a 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_corrupted_gauntlet.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_corrupted_gauntlet.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png index e34fbe3d15..3e03f805c1 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/theatre_of_blood.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/theatre_of_blood.png index 0d05a8ab1e..5234c59637 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/theatre_of_blood.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/theatre_of_blood.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/thermonuclear_smoke_devil.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/thermonuclear_smoke_devil.png index 7869a9a817..d7315af194 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/thermonuclear_smoke_devil.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/thermonuclear_smoke_devil.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tzkal_zuk.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tzkal_zuk.png index 8b3262cd8b..1c6a966f19 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tzkal_zuk.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tzkal_zuk.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tztok_jad.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tztok_jad.png index 6ccee5515e..d181c8d93c 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tztok_jad.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tztok_jad.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/venenatis.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/venenatis.png index df08980743..76dbc9fac3 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/venenatis.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/venenatis.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png index 383d30a119..67a7b3d645 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png index 03bcc75ed4..c3732b1d02 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/wintertodt.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/wintertodt.png index eb1d8f47bb..478e0f968d 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/wintertodt.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/wintertodt.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zalcano.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zalcano.png index c4d6e21be0..72a0a1714b 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zalcano.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zalcano.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zulrah.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zulrah.png index 83d939a1ac..44a28c4cbd 100644 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zulrah.png and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zulrah.png differ diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java new file mode 100644 index 0000000000..967802b2cf --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java @@ -0,0 +1,997 @@ +/* + * Copyright (c) 2017, Adam + * 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.slayer; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.ScheduledExecutorService; +import javax.inject.Inject; +import net.runelite.api.ChatMessageType; +import static net.runelite.api.ChatMessageType.GAMEMESSAGE; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.Hitsplat; +import net.runelite.api.MessageNode; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.Player; +import net.runelite.api.Skill; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.events.ActorDeath; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.HitsplatApplied; +import net.runelite.api.events.StatChanged; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.Notifier; +import net.runelite.client.chat.ChatCommandManager; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.http.api.chat.ChatClient; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class SlayerPluginTest +{ + private static final String TASK_NEW = "Your new task is to kill 231 Suqahs."; + private static final String TASK_NEW_KONAR = "You are to bring balance to 147 Wyrms in the Karuulm Slayer Dungeon."; + private static final String TASK_NEW_KONAR_2 = "You are to bring balance to 142 Hellhounds in Witchhaven Dungeon."; + private static final String TASK_NEW_KONAR_3 = "You are to bring balance to 135 Trolls south of Mount Quidamortem."; + private static final String TASK_NEW_FIRST = "We'll start you off hunting goblins, you'll need to kill 17 of them."; + private static final String TASK_NEW_FIRST_KONAR = "We'll start you off bringing balance to cows, you'll need to kill 44 of them."; + private static final String TASK_NEW_NPC_CONTACT = "Excellent, you're doing great. Your new task is to kill
211 Suqahs."; + private static final String TASK_NEW_FROM_PARTNER = "You have received a new Slayer assignment from breaklulz: Dust Devils (377)"; + private static final String TASK_CHECKSLAYERGEM = "You're assigned to kill Suqahs; only 211 more to go."; + private static final String TASK_CHECKSLAYERGEM_WILDERNESS = "You're assigned to kill Suqahs in the Wilderness; only 211 more to go."; + private static final String TASK_CHECKSLAYERGEM_KONAR = "You're assigned to kill Blue dragons in the Ogre Enclave; only 122 more to go."; + private static final String TASK_UPDATE_COMBAT_BRACELET = "You still need to kill 30 monsters to complete your current Slayer assignment"; + + private static final String TASK_BOSS_NEW = "Excellent. You're now assigned to kill Vet'ion 3 times.
Your reward point tally is 914."; + private static final String TASK_BOSS_NEW_THE = "Excellent. You're now assigned to kill the Chaos
Elemental 3 times. Your reward point tally is 914."; + private static final String TASK_KONAR_BOSS = "You're now assigned to bring balance to the Alchemical
Hydra 35 times. Your reward point tally is 724."; + + private static final String TASK_EXISTING = "You're still hunting suqahs; you have 222 to go. Come
back when you've finished your task."; + private static final String TASK_EXISTING_KONAR = "You're still bringing balance to adamant dragons in the Lithkren Vault, with 3 to go. Come back when you're finished."; + private static final String TASK_EXISTING_WILDERNESS = "You're still meant to be slaying bandits in the Wilderness; you have 99 to go. Come back when you've finished your task."; + + private static final String TASK_ACTIVATESLAYERGEM = "You're currently assigned to kill fossil island wyverns; only 23 more to go. Your reward point tally is 46."; + private static final String TASK_ACTIVATESLAYERGEM_KONAR = "You're currently assigned to bring balance to adamant dragons in the Lithkren Vault; you have 3 more to go. Your reward point tally is 16."; + private static final String TASK_ACTIVATESLAYERGEM_WILDERNESS = "You're currently assigned to kill bandits in the Wilderness; only 99 more to go. Your reward point tally is 34."; + + private static final String REWARD_POINTS = "Reward points: 17,566"; + + private static final String TASK_ONE = "You've completed 1 task and will need 4 more before you start receiving Slayer points; return to a Slayer master."; + private static final String TASK_COMPLETE_NO_POINTS = "You've completed 3 tasks and will need 2 more before you start receiving Slayer points; return to a Slayer master."; + private static final String TASK_POINTS = "You've completed 9 tasks and received 10 points, giving you a total of 18,000; return to a Slayer master."; + private static final String TASK_LARGE_STREAK = "You've completed 2,465 tasks and received 15 points, giving you a total of 131,071; return to a Slayer master."; + private static final String TASK_COMPETE_TURAEL = "You've completed 104 tasks . You'll be eligible to earn reward points if you complete tasks from a more advanced Slayer Master."; + private static final String TASK_MAX_STREAK = "You've completed at least 16,000 tasks and received 15 points, giving you a total of 131,071; return to a Slayer master."; + private static final String TASK_MAX_POINTS = "You've completed 9 tasks and reached the maximum amount of Slayer points (131,071); return to a Slayer master."; + private static final String TASK_WILDERNESS = "You've completed 9 Wilderness tasks and received 10 points, giving you a total of 18,000; return to a Slayer master."; + + private static final String TASK_COMPLETE = "You need something new to hunt."; + private static final String TASK_CANCELED = "Your task has been cancelled."; + + private static final String SUPERIOR_MESSAGE = "A superior foe has appeared..."; + + private static final String BRACLET_SLAUGHTER = "Your bracelet of slaughter prevents your slayer count from decreasing. It has 9 charges left."; + private static final String BRACLET_EXPEDITIOUS = "Your expeditious bracelet helps you progress your slayer task faster. It has 9 charges left."; + + private static final String BRACLET_SLAUGHTER_V2 = "Your bracelet of slaughter prevents your slayer count from decreasing. It has 1 charge left."; + private static final String BRACLET_EXPEDITIOUS_V2 = "Your expeditious bracelet helps you progress your slayer faster. It has 1 charge left."; + + private static final String BRACLET_SLAUGHTER_V3 = "Your bracelet of slaughter prevents your slayer count from decreasing. It then crumbles to dust."; + private static final String BRACLET_EXPEDITIOUS_V3 = "Your expeditious bracelet helps you progress your slayer faster. It then crumbles to dust."; + + private static final String CHAT_BRACELET_SLAUGHTER_CHARGE = "Your bracelet of slaughter has 12 charges left."; + private static final String CHAT_BRACELET_EXPEDITIOUS_CHARGE = "Your expeditious bracelet has 12 charges left."; + + private static final String CHAT_BRACELET_SLAUGHTER_CHARGE_ONE = "Your bracelet of slaughter has 1 charge left."; + private static final String CHAT_BRACELET_EXPEDITIOUS_CHARGE_ONE = "Your expeditious bracelet has 1 charge left."; + + private static final String BREAK_SLAUGHTER = "The bracelet shatters. Your next bracelet of slaughter
will start afresh from 30 charges."; + private static final String BREAK_EXPEDITIOUS = "The bracelet shatters. Your next expeditious bracelet
will start afresh from 30 charges."; + + @Mock + @Bind + Client client; + + @Mock + @Bind + SlayerConfig slayerConfig; + + @Mock + @Bind + OverlayManager overlayManager; + + @Mock + @Bind + SlayerOverlay overlay; + + @Mock + @Bind + InfoBoxManager infoBoxManager; + + @Mock + @Bind + ItemManager itemManager; + + @Mock + @Bind + Notifier notifier; + + @Mock + @Bind + ChatMessageManager chatMessageManager; + + @Mock + @Bind + ChatCommandManager chatCommandManager; + + @Mock + @Bind + ScheduledExecutorService executor; + + @Mock + @Bind + ChatClient chatClient; + + @Inject + SlayerPlugin slayerPlugin; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testNewTask() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Suqahs", slayerPlugin.getTaskName()); + assertEquals(231, slayerPlugin.getAmount()); + } + + @Test + public void testNewKonarTask() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW_KONAR); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Wyrms", slayerPlugin.getTaskName()); + assertEquals(147, slayerPlugin.getAmount()); + assertEquals("Karuulm Slayer Dungeon", slayerPlugin.getTaskLocation()); + } + + @Test + public void testNewKonarTask2() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW_KONAR_2); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Hellhounds", slayerPlugin.getTaskName()); + assertEquals(142, slayerPlugin.getAmount()); + assertEquals("Witchhaven Dungeon", slayerPlugin.getTaskLocation()); + } + + @Test + public void testNewKonarTask3() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW_KONAR_3); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Trolls", slayerPlugin.getTaskName()); + assertEquals(135, slayerPlugin.getAmount()); + assertEquals("Mount Quidamortem", slayerPlugin.getTaskLocation()); + } + + @Test + public void testFirstTask() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW_FIRST); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("goblins", slayerPlugin.getTaskName()); + assertEquals(17, slayerPlugin.getAmount()); + } + + @Test + public void testFirstTaskKonar() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW_FIRST_KONAR); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("cows", slayerPlugin.getTaskName()); + assertEquals(44, slayerPlugin.getAmount()); + } + + @Test + public void testNewNpcContactTask() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW_NPC_CONTACT); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Suqahs", slayerPlugin.getTaskName()); + assertEquals(211, slayerPlugin.getAmount()); + } + + @Test + public void testBossTask() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_BOSS_NEW); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Vet'ion", slayerPlugin.getTaskName()); + assertEquals(3, slayerPlugin.getAmount()); + verify(slayerConfig).points(914); + } + + @Test + public void testBossTaskThe() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_BOSS_NEW_THE); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Chaos Elemental", slayerPlugin.getTaskName()); + assertEquals(3, slayerPlugin.getAmount()); + verify(slayerConfig).points(914); + } + + @Test + public void testKonarBossTask() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_KONAR_BOSS); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("Alchemical Hydra", slayerPlugin.getTaskName()); + assertEquals(35, slayerPlugin.getAmount()); + verify(slayerConfig).points(724); + } + + @Test + public void testPartnerTask() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_NEW_FROM_PARTNER, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals("Dust Devils", slayerPlugin.getTaskName()); + assertEquals(377, slayerPlugin.getAmount()); + } + + @Test + public void testCheckSlayerGem() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_CHECKSLAYERGEM, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + assertEquals("Suqahs", slayerPlugin.getTaskName()); + assertEquals(211, slayerPlugin.getAmount()); + } + + @Test + public void testCheckSlayerGemWildernessTask() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_CHECKSLAYERGEM_WILDERNESS, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + assertEquals("Suqahs", slayerPlugin.getTaskName()); + assertEquals(211, slayerPlugin.getAmount()); + assertEquals("Wilderness", slayerPlugin.getTaskLocation()); + } + + @Test + public void testCheckSlayerGemKonarTask() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_CHECKSLAYERGEM_KONAR, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals("Blue dragons", slayerPlugin.getTaskName()); + assertEquals(122, slayerPlugin.getAmount()); + assertEquals("Ogre Enclave", slayerPlugin.getTaskLocation()); + } + + @Test + public void testExistingTask() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_EXISTING); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("suqahs", slayerPlugin.getTaskName()); + assertEquals(222, slayerPlugin.getAmount()); + } + + @Test + public void testExistingTaskKonar() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_EXISTING_KONAR); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("adamant dragons", slayerPlugin.getTaskName()); + assertEquals(3, slayerPlugin.getAmount()); + assertEquals("Lithkren Vault", slayerPlugin.getTaskLocation()); + } + + @Test + public void testExistingTaskWilderness() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_EXISTING_WILDERNESS); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("bandits", slayerPlugin.getTaskName()); + assertEquals(99, slayerPlugin.getAmount()); + assertEquals("Wilderness", slayerPlugin.getTaskLocation()); + } + + @Test + public void testSlayergemActivate() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_ACTIVATESLAYERGEM); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("fossil island wyverns", slayerPlugin.getTaskName()); + assertEquals(23, slayerPlugin.getAmount()); + } + + @Test + public void testSlayergemActivateKonar() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_ACTIVATESLAYERGEM_KONAR); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("adamant dragons", slayerPlugin.getTaskName()); + assertEquals(3, slayerPlugin.getAmount()); + assertEquals("Lithkren Vault", slayerPlugin.getTaskLocation()); + } + + @Test + public void testSlayergemActivateWilderness() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_ACTIVATESLAYERGEM_WILDERNESS); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals("bandits", slayerPlugin.getTaskName()); + assertEquals(99, slayerPlugin.getAmount()); + assertEquals("Wilderness", slayerPlugin.getTaskLocation()); + } + + @Test + public void testRewardPointsWidget() + { + Widget rewardBar = mock(Widget.class); + Widget rewardBarText = mock(Widget.class); + Widget[] rewardBarChildren = new Widget[]{rewardBarText}; + + when(rewardBar.getDynamicChildren()).thenReturn(rewardBarChildren); + when(rewardBarText.getText()).thenReturn(REWARD_POINTS); + when(client.getWidget(WidgetInfo.SLAYER_REWARDS_TOPBAR)).thenReturn(rewardBar); + slayerPlugin.onGameTick(new GameTick()); + + verify(slayerConfig).points(17566); + } + + @Test + public void testOneTask() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_ONE, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(1); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testNoPoints() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_COMPLETE_NO_POINTS, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(3); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testPoints() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_POINTS, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(9); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + verify(slayerConfig).points(18_000); + } + + @Test + public void testLargeStreak() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_LARGE_STREAK, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(2465); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + verify(slayerConfig).points(131_071); + } + + @Test + public void testTaskCompleteTurael() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_COMPETE_TURAEL, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(104); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testTaskMaxStreak() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_MAX_STREAK, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(16_000); + verify(slayerConfig).points(131_071); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testTaskMaxPoints() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_MAX_POINTS, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(9); + verify(slayerConfig).points(131_071); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testTaskWilderness() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_WILDERNESS, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(9); + verify(slayerConfig).points(18_000); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testComplete() + { + slayerPlugin.setTaskName("cows"); + slayerPlugin.setAmount(42); + + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_COMPLETE, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testCancelled() + { + slayerPlugin.setTaskName("cows"); + slayerPlugin.setAmount(42); + + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_CANCELED, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testSuperiorNotification() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Superior", SUPERIOR_MESSAGE, null, 0); + + when(slayerConfig.showSuperiorNotification()).thenReturn(true); + slayerPlugin.onChatMessage(chatMessageEvent); + verify(notifier).notify(SUPERIOR_MESSAGE); + + when(slayerConfig.showSuperiorNotification()).thenReturn(false); + slayerPlugin.onChatMessage(chatMessageEvent); + verifyNoMoreInteractions(notifier); + } + + @Test + public void testCorrectlyCapturedTaskKill() + { + final Player player = mock(Player.class); + when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); + when(client.getLocalPlayer()).thenReturn(player); + + StatChanged statChanged = new StatChanged( + Skill.SLAYER, + 100, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + slayerPlugin.setTaskName("Dagannoth"); + slayerPlugin.setAmount(143); + + statChanged = new StatChanged( + Skill.SLAYER, + 110, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals(142, slayerPlugin.getAmount()); + } + + @Test + public void testIncorrectlyCapturedTaskKill() + { + final Player player = mock(Player.class); + when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); + when(client.getLocalPlayer()).thenReturn(player); + + StatChanged statChanged = new StatChanged( + Skill.SLAYER, + 100, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + slayerPlugin.setTaskName("Monster"); + slayerPlugin.setAmount(98); + + assert Task.getTask("Monster") == null; + + statChanged = new StatChanged( + Skill.SLAYER, + 110, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals(97, slayerPlugin.getAmount()); + } + + @Test + public void testJadTaskKill() + { + final Player player = mock(Player.class); + when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); + when(client.getLocalPlayer()).thenReturn(player); + + StatChanged statChanged = new StatChanged( + Skill.SLAYER, + 100, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + slayerPlugin.setTaskName("TzTok-Jad"); + slayerPlugin.setAmount(1); + + // One bat kill + statChanged = new StatChanged( + Skill.SLAYER, + 110, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals(1, slayerPlugin.getAmount()); + + // One Jad kill + statChanged = new StatChanged( + Skill.SLAYER, + 25360, + -1, + -1 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testZukTaskKill() + { + final Player player = mock(Player.class); + when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); + when(client.getLocalPlayer()).thenReturn(player); + + StatChanged statChanged = new StatChanged( + Skill.SLAYER, + 110, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + slayerPlugin.setTaskName("TzKal-Zuk"); + slayerPlugin.setAmount(1); + + // One bat kill + statChanged = new StatChanged( + Skill.SLAYER, + 125, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals(1, slayerPlugin.getAmount()); + + // One Zuk kill + statChanged = new StatChanged( + Skill.SLAYER, + 102_015, + -1, + -1 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testBraceletSlaughter() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_SLAUGHTER, null, 0); + + slayerPlugin.setAmount(42); + slayerPlugin.setSlaughterChargeCount(10); + + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(9, slayerPlugin.getSlaughterChargeCount()); + assertEquals(43, slayerPlugin.getAmount()); + + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", CHAT_BRACELET_SLAUGHTER_CHARGE, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(12, slayerPlugin.getSlaughterChargeCount()); + + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", CHAT_BRACELET_SLAUGHTER_CHARGE_ONE, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(1, slayerPlugin.getSlaughterChargeCount()); + + slayerPlugin.setSlaughterChargeCount(1); + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_SLAUGHTER_V3, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(30, slayerPlugin.getSlaughterChargeCount()); + + Widget braceletBreakWidget = mock(Widget.class); + when(braceletBreakWidget.getText()).thenReturn(BREAK_SLAUGHTER); + when(client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT)).thenReturn(braceletBreakWidget); + + slayerPlugin.setSlaughterChargeCount(-1); + slayerPlugin.onGameTick(new GameTick()); + assertEquals(30, slayerPlugin.getSlaughterChargeCount()); + + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_SLAUGHTER_V2, null, 0); + + slayerPlugin.setAmount(42); + slayerPlugin.setSlaughterChargeCount(2); + + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(1, slayerPlugin.getSlaughterChargeCount()); + assertEquals(43, slayerPlugin.getAmount()); + } + + @Test + public void testBraceletExpeditious() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_EXPEDITIOUS, null, 0); + + slayerPlugin.setAmount(42); + slayerPlugin.setExpeditiousChargeCount(10); + + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(41, slayerPlugin.getAmount()); + assertEquals(9, slayerPlugin.getExpeditiousChargeCount()); + + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(12, slayerPlugin.getExpeditiousChargeCount()); + + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE_ONE, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(1, slayerPlugin.getExpeditiousChargeCount()); + + slayerPlugin.setExpeditiousChargeCount(1); + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_EXPEDITIOUS_V3, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(30, slayerPlugin.getExpeditiousChargeCount()); + + Widget braceletBreakWidget = mock(Widget.class); + when(braceletBreakWidget.getText()).thenReturn(BREAK_EXPEDITIOUS); + when(client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT)).thenReturn(braceletBreakWidget); + + slayerPlugin.setExpeditiousChargeCount(-1); + slayerPlugin.onGameTick(new GameTick()); + assertEquals(30, slayerPlugin.getExpeditiousChargeCount()); + + chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", BRACLET_EXPEDITIOUS_V2, null, 0); + + slayerPlugin.setAmount(42); + slayerPlugin.setExpeditiousChargeCount(2); + + slayerPlugin.onChatMessage(chatMessageEvent); + + assertEquals(41, slayerPlugin.getAmount()); + assertEquals(1, slayerPlugin.getExpeditiousChargeCount()); + } + + @Test + public void testCombatBraceletUpdate() + { + final Player player = mock(Player.class); + when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); + when(client.getLocalPlayer()).thenReturn(player); + + slayerPlugin.setTaskName("Suqahs"); + slayerPlugin.setAmount(231); + + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", TASK_UPDATE_COMBAT_BRACELET, null, 0); + slayerPlugin.onChatMessage(chatMessage); + + assertEquals("Suqahs", slayerPlugin.getTaskName()); + slayerPlugin.killed(1); + assertEquals(30, slayerPlugin.getAmount()); + } + + @Test + public void updateInitialAmount() + { + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_EXISTING); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + assertEquals(222, slayerPlugin.getInitialAmount()); + } + + @Test + public void testTaskLookup() throws IOException + { + net.runelite.http.api.chat.Task task = new net.runelite.http.api.chat.Task(); + task.setTask("Abyssal demons"); + task.setLocation("Abyss"); + task.setAmount(42); + task.setInitialAmount(42); + + when(slayerConfig.taskCommand()).thenReturn(true); + when(chatClient.getTask(anyString())).thenReturn(task); + + ChatMessage setMessage = new ChatMessage(); + setMessage.setType(ChatMessageType.PUBLICCHAT); + setMessage.setName("Adam"); + setMessage.setMessageNode(mock(MessageNode.class)); + + slayerPlugin.taskLookup(setMessage, "!task"); + + verify(chatMessageManager).update(any(MessageNode.class)); + } + + @Test + public void testTaskLookupInvalid() throws IOException + { + net.runelite.http.api.chat.Task task = new net.runelite.http.api.chat.Task(); + task.setTask("task<"); + task.setLocation("loc"); + task.setAmount(42); + task.setInitialAmount(42); + + when(slayerConfig.taskCommand()).thenReturn(true); + when(chatClient.getTask(anyString())).thenReturn(task); + + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.PUBLICCHAT); + chatMessage.setName("Adam"); + chatMessage.setMessageNode(mock(MessageNode.class)); + + slayerPlugin.taskLookup(chatMessage, "!task"); + + verify(chatMessageManager, never()).update(any(MessageNode.class)); + } + + @Test + public void testNewAccountSlayerKill() + { + final Player player = mock(Player.class); + when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); + when(client.getLocalPlayer()).thenReturn(player); + + slayerPlugin.setTaskName("Bears"); + slayerPlugin.setAmount(35); + + StatChanged statChanged = new StatChanged( + Skill.SLAYER, + 0, + 1, + 1 + ); + slayerPlugin.onStatChanged(statChanged); + + statChanged = new StatChanged( + Skill.SLAYER, + 27, + 1, + 1 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals(34, slayerPlugin.getAmount()); + } + + @Test + public void infoboxNotAddedOnLogin() + { + when(slayerConfig.taskName()).thenReturn(Task.BLOODVELD.getName()); + + GameStateChanged loggingIn = new GameStateChanged(); + loggingIn.setGameState(GameState.LOGGING_IN); + slayerPlugin.onGameStateChanged(loggingIn); + + GameStateChanged loggedIn = new GameStateChanged(); + loggedIn.setGameState(GameState.LOGGED_IN); + slayerPlugin.onGameStateChanged(loggedIn); + + verify(infoBoxManager, never()).addInfoBox(any()); + } + + @Test + public void testMultikill() + { + final Player player = mock(Player.class); + when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0)); + when(client.getLocalPlayer()).thenReturn(player); + + // Setup xp cache + StatChanged statChanged = new StatChanged( + Skill.SLAYER, + 0, + 1, + 1 + ); + slayerPlugin.onStatChanged(statChanged); + + NPCComposition npcComposition = mock(NPCComposition.class); + when(npcComposition.getActions()).thenReturn(new String[]{"Attack"}); + + NPC npc1 = mock(NPC.class); + when(npc1.getName()).thenReturn("Suqah"); + when(npc1.getTransformedComposition()).thenReturn(npcComposition); + + NPC npc2 = mock(NPC.class); + when(npc2.getName()).thenReturn("Suqah"); + when(npc2.getTransformedComposition()).thenReturn(npcComposition); + + when(client.getNpcs()).thenReturn(Arrays.asList(npc1, npc2)); + + // Set task + Widget npcDialog = mock(Widget.class); + when(npcDialog.getText()).thenReturn(TASK_NEW); + when(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT)).thenReturn(npcDialog); + slayerPlugin.onGameTick(new GameTick()); + + // Damage both npcs + Hitsplat hitsplat = new Hitsplat(Hitsplat.HitsplatType.DAMAGE_ME, 1, 1); + HitsplatApplied hitsplatApplied = new HitsplatApplied(); + hitsplatApplied.setHitsplat(hitsplat); + hitsplatApplied.setActor(npc1); + slayerPlugin.onHitsplatApplied(hitsplatApplied); + + hitsplatApplied.setActor(npc2); + slayerPlugin.onHitsplatApplied(hitsplatApplied); + + // Kill both npcs + slayerPlugin.onActorDeath(new ActorDeath(npc1)); + slayerPlugin.onActorDeath(new ActorDeath(npc2)); + + slayerPlugin.onGameTick(new GameTick()); + + statChanged = new StatChanged( + Skill.SLAYER, + 105, + 2, + 2 + ); + slayerPlugin.onStatChanged(statChanged); + + assertEquals("Suqahs", slayerPlugin.getTaskName()); + assertEquals(229, slayerPlugin.getAmount()); // 2 kills + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/xpglobes/XpGlobesPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/xpglobes/XpGlobesPluginTest.java new file mode 100644 index 0000000000..bfc5de4b0d --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/xpglobes/XpGlobesPluginTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2021, Wright + * 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.xpglobes; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import javax.inject.Inject; +import net.runelite.api.Experience; +import net.runelite.api.Skill; +import net.runelite.api.events.StatChanged; +import net.runelite.client.plugins.xptracker.XpTrackerService; +import net.runelite.client.ui.overlay.OverlayManager; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class XpGlobesPluginTest +{ + private static final int VIRTUAL_LEVEL_TOTAL_XP = Experience.getXpForLevel(Experience.MAX_REAL_LEVEL + 1); + + @Inject + private XpGlobesPlugin xpGlobesPlugin; + + @Mock + @Bind + private OverlayManager overlayManager; + + @Mock + @Bind + private XpGlobesOverlay xpGlobesOverlay; + + @Mock + @Bind + private XpTrackerService xpTrackerService; + + @Mock + @Bind + private XpGlobesConfig xpGlobesConfig; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP, Skill.AGILITY); + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + @Test + public void testVirtualLevelInGlobeIsNotShownByDefault() + { + when(xpGlobesConfig.showVirtualLevel()).thenReturn(false); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertEquals(Experience.MAX_REAL_LEVEL, xpGlobesPlugin.getXpGlobes().get(0).getCurrentLevel()); + } + + @Test + public void testVirtualLevelInGlobeIsShownWhenConfigured() + { + when(xpGlobesConfig.showVirtualLevel()).thenReturn(true); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertEquals(Experience.getLevelForXp(VIRTUAL_LEVEL_TOTAL_XP + 1), xpGlobesPlugin.getXpGlobes().get(0).getCurrentLevel()); + } + + @Test + public void testGlobeIsNotShownWhenHideMaxAndShowVirtualLevelConfigured() + { + when(xpGlobesConfig.hideMaxed()).thenReturn(true); + lenient().when(xpGlobesConfig.showVirtualLevel()).thenReturn(true); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + @Test + public void testGlobeIsNotShownWhenHideMaxConfigured() + { + when(xpGlobesConfig.hideMaxed()).thenReturn(true); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + @Test + public void testGlobeIsShownOnXpGainBelowMaxWhenHideMaxConfigured() + { + lenient().when(xpGlobesConfig.hideMaxed()).thenReturn(true); + + int totalXp = 1; + statChanged(totalXp, Skill.FARMING); + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + + statChanged(totalXp + 150, Skill.FARMING); + + assertEquals(Experience.getLevelForXp(totalXp + 150), xpGlobesPlugin.getXpGlobes().get(0).getCurrentLevel()); + } + + @Test + public void testStatChangesFromBoostDoNotAffectXpGlobes() + { + statChanged(VIRTUAL_LEVEL_TOTAL_XP, Skill.AGILITY, 5); + + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + private void statChanged(int totalXp, Skill skill) + { + statChanged(totalXp, skill, 0); + } + + private void statChanged(int totalXp, Skill skill, int boostedLevel) + { + // A statChanged event uses the max real level + int statChangedLevel = Math.min(Experience.getLevelForXp(totalXp), Experience.MAX_REAL_LEVEL); + + StatChanged firstStatChangedEvent = new StatChanged( + skill, + totalXp, + statChangedLevel, + boostedLevel + ); + + // The first xp change is cached + xpGlobesPlugin.onStatChanged(firstStatChangedEvent); + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameEngineMixin.java similarity index 96% rename from runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java rename to runelite-mixins/src/main/java/net/runelite/mixins/RSGameEngineMixin.java index 221063ce75..2573152106 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameEngineMixin.java @@ -35,10 +35,10 @@ import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; import net.runelite.rs.api.RSClient; -import net.runelite.rs.api.RSGameShell; +import net.runelite.rs.api.RSGameEngine; -@Mixin(RSGameShell.class) -public abstract class RSGameShellMixin implements RSGameShell +@Mixin(RSGameEngine.class) +public abstract class RSGameEngineMixin implements RSGameEngine { @Shadow("client") private static RSClient client; diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/StretchedModeMaxSizeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/StretchedModeMaxSizeMixin.java index da1a9e6fc0..de0638e6bd 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/StretchedModeMaxSizeMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/StretchedModeMaxSizeMixin.java @@ -6,10 +6,10 @@ import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; import net.runelite.rs.api.RSClient; -import net.runelite.rs.api.RSGameShell; +import net.runelite.rs.api.RSGameEngine; -@Mixin(RSGameShell.class) -public abstract class StretchedModeMaxSizeMixin implements RSGameShell +@Mixin(RSGameEngine.class) +public abstract class StretchedModeMaxSizeMixin implements RSGameEngine { @Shadow("client") private static RSClient client; diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java index fe3f6c7003..bddfbe6f71 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java @@ -1,14 +1,36 @@ package net.runelite.rs.api; +import net.runelite.api.AbstractArchive; import net.runelite.api.IndexDataBase; import net.runelite.mapping.Import; -public interface RSAbstractArchive extends IndexDataBase +public interface RSAbstractArchive extends IndexDataBase, AbstractArchive { @Import("takeFile") + @Override byte[] getConfigData(int archiveId, int fileId); @Import("getGroupFileIds") @Override - int[] getFileIds(int group); + int[] getFileIds(int groupId); + + @Import("groupCount") + @Override + int getGroupCount(); + + @Import("fileIds") + @Override + int[][] getFileIds(); + + @Import("getFile") + @Override + byte[] getFile(int groupId, int fileId); + + @Import("getGroupFileCount") + @Override + int getGroupFileCount(int groupId); + + @Import("fileCounts") + @Override + int[] getFileCounts(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java b/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java index b43e772f62..3772548707 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java @@ -1,12 +1,37 @@ package net.runelite.rs.api; +import net.runelite.api.Buffer; import net.runelite.mapping.Import; -public interface RSBuffer extends RSNode +public interface RSBuffer extends Buffer, RSNode { @Import("array") byte[] getPayload(); @Import("offset") int getOffset(); + + @Import("writeByte") + @Override + void writeByte(int var1); + + @Import("writeShort") + @Override + void writeShort(int var1); + + @Import("writeMedium") + @Override + void writeMedium(int var1); + + @Import("writeInt") + @Override + void writeInt(int var1); + + @Import("writeLong") + @Override + void writeLong(long var1); + + @Import("writeStringCp1252NullTerminated") + @Override + void writeStringCp1252NullTerminated(String string); } \ No newline at end of file diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 90d9cb0779..66318eef50 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -26,6 +26,7 @@ package net.runelite.rs.api; import java.math.BigInteger; import java.util.Map; +import net.runelite.api.AbstractArchive; import net.runelite.api.Client; import net.runelite.api.SpritePixels; import net.runelite.api.World; @@ -33,7 +34,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.mapping.Construct; import net.runelite.mapping.Import; -public interface RSClient extends RSGameShell, Client +public interface RSClient extends RSGameEngine, Client { @Import("cameraX") @Override @@ -1350,4 +1351,51 @@ public interface RSClient extends RSGameShell, Client RSIterableNodeHashTable newIterableNodeHashTable(int size); RSVarbitComposition getVarbitComposition(int id); + + @Override + @Import("SequenceDefinition_skeletonsArchive") + RSAbstractArchive getSequenceDefinition_skeletonsArchive(); + + @Override + @Import("SequenceDefinition_archive") + RSAbstractArchive getSequenceDefinition_archive(); + + @Override + @Import("SequenceDefinition_animationsArchive") + RSAbstractArchive getSequenceDefinition_animationsArchive(); + + @Override + @Import("NpcDefinition_archive") + AbstractArchive getNpcDefinition_archive(); + + @Override + @Import("ObjectDefinition_modelsArchive") + AbstractArchive getObjectDefinition_modelsArchive(); + + @Override + @Import("ObjectDefinition_archive") + RSAbstractArchive getObjectDefinition_archive(); + + @Override + @Import("ItemDefinition_archive") + RSAbstractArchive getItemDefinition_archive(); + + @Override + @Import("KitDefinition_archive") + AbstractArchive getKitDefinition_archive(); + + @Override + @Import("KitDefinition_modelsArchive") + AbstractArchive getKitDefinition_modelsArchive(); + + @Override + @Import("SpotAnimationDefinition_archive") + AbstractArchive getSpotAnimationDefinition_archive(); + + @Override + @Import("SpotAnimationDefinition_modelArchive") + AbstractArchive getSpotAnimationDefinition_modelArchive(); + + @Construct + RSBuffer createBuffer(byte[] bytes); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSGameShell.java b/runescape-api/src/main/java/net/runelite/rs/api/RSGameEngine.java similarity index 96% rename from runescape-api/src/main/java/net/runelite/rs/api/RSGameShell.java rename to runescape-api/src/main/java/net/runelite/rs/api/RSGameEngine.java index fe27edcd9a..345845d9ee 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSGameShell.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSGameEngine.java @@ -24,11 +24,11 @@ */ package net.runelite.rs.api; -import net.runelite.api.GameShell; +import net.runelite.api.GameEngine; import java.awt.Canvas; import net.runelite.mapping.Import; -public interface RSGameShell extends GameShell +public interface RSGameEngine extends GameEngine { @Import("canvas") Canvas getCanvas(); diff --git a/runescape-client/src/main/java/ArchiveLoader.java b/runescape-client/src/main/java/ArchiveLoader.java index d5a24dbe3a..347f638dcb 100644 --- a/runescape-client/src/main/java/ArchiveLoader.java +++ b/runescape-client/src/main/java/ArchiveLoader.java @@ -526,7 +526,7 @@ public class ArchiveLoader { class22.field107 = "Can't login? Click here."; // L: 1256 } - GameShell.field481 = new Bounds(Login.loginBoxCenter, var31, var1.stringWidth(class22.field107), 11); // L: 1259 + GameEngine.field481 = new Bounds(Login.loginBoxCenter, var31, var1.stringWidth(class22.field107), 11); // L: 1259 GrandExchangeOfferOwnWorldComparator.field643 = new Bounds(Login.loginBoxCenter, var31, var1.stringWidth("Still having trouble logging in?"), 11); // L: 1260 var1.drawCentered(class22.field107, Login.loginBoxCenter, var31, 16777215, 0); // L: 1261 } else if (Login.loginIndex == 3) { // L: 1263 diff --git a/runescape-client/src/main/java/Canvas.java b/runescape-client/src/main/java/Canvas.java index 5d60bc2c12..26d20936c1 100644 --- a/runescape-client/src/main/java/Canvas.java +++ b/runescape-client/src/main/java/Canvas.java @@ -78,7 +78,7 @@ public final class Canvas extends java.awt.Canvas { DynamicObject.archive2 = WorldMapCacheName.newArchive(2, true, false, true); // L: 1744 class330.archive3 = WorldMapCacheName.newArchive(3, false, true, true); // L: 1745 class227.archive4 = WorldMapCacheName.newArchive(4, false, true, true); // L: 1746 - GameShell.archive5 = WorldMapCacheName.newArchive(5, true, true, true); // L: 1747 + GameEngine.archive5 = WorldMapCacheName.newArchive(5, true, true, true); // L: 1747 class217.archive6 = WorldMapCacheName.newArchive(6, true, true, true); // L: 1748 BuddyRankComparator.archive7 = WorldMapCacheName.newArchive(7, false, true, true); // L: 1749 Messages.archive8 = WorldMapCacheName.newArchive(8, false, true, true); // L: 1750 @@ -103,7 +103,7 @@ public final class Canvas extends java.awt.Canvas { var12 += DynamicObject.archive2.percentage() * 2 / 100; // L: 1771 var12 += class330.archive3.percentage() * 2 / 100; // L: 1772 var12 += class227.archive4.percentage() * 6 / 100; // L: 1773 - var12 += GameShell.archive5.percentage() * 4 / 100; // L: 1774 + var12 += GameEngine.archive5.percentage() * 4 / 100; // L: 1774 var12 += class217.archive6.percentage() * 2 / 100; // L: 1775 var12 += BuddyRankComparator.archive7.percentage() * 56 / 100; // L: 1776 var12 += Messages.archive8.percentage() * 2 / 100; // L: 1777 @@ -128,7 +128,7 @@ public final class Canvas extends java.awt.Canvas { UserComparator4.method3469(SceneTilePaint.archive0, "Animations"); // L: 1794 UserComparator4.method3469(WorldMapSprite.archive1, "Skeletons"); // L: 1795 UserComparator4.method3469(class227.archive4, "Sound FX"); // L: 1796 - UserComparator4.method3469(GameShell.archive5, "Maps"); // L: 1797 + UserComparator4.method3469(GameEngine.archive5, "Maps"); // L: 1797 UserComparator4.method3469(class217.archive6, "Music Tracks"); // L: 1798 UserComparator4.method3469(BuddyRankComparator.archive7, "Models"); // L: 1799 UserComparator4.method3469(Messages.archive8, "Sprites"); // L: 1800 @@ -152,7 +152,7 @@ public final class Canvas extends java.awt.Canvas { WorldMapIcon_0.method270(22050, !Client.isLowDetail, 2); // L: 1815 MidiPcmStream var20 = new MidiPcmStream(); // L: 1816 var20.method3759(9, 128); // L: 1817 - AbstractWorldMapData.pcmPlayer0 = UserComparator6.method3526(GameShell.taskHandler, 0, 22050); // L: 1818 + AbstractWorldMapData.pcmPlayer0 = UserComparator6.method3526(GameEngine.taskHandler, 0, 22050); // L: 1818 AbstractWorldMapData.pcmPlayer0.setStream(var20); // L: 1819 var21 = Client.archive15; // L: 1820 var2 = FontName.archive14; // L: 1821 @@ -161,7 +161,7 @@ public final class Canvas extends java.awt.Canvas { class206.musicSamplesArchive = var2; // L: 1825 class206.soundEffectsArchive = var16; // L: 1826 class206.midiPcmStream = var20; // L: 1827 - FriendLoginUpdate.pcmPlayer1 = UserComparator6.method3526(GameShell.taskHandler, 1, 2048); // L: 1829 + FriendLoginUpdate.pcmPlayer1 = UserComparator6.method3526(GameEngine.taskHandler, 1, 2048); // L: 1829 WorldMapManager.pcmStreamMixer = new PcmStreamMixer(); // L: 1830 FriendLoginUpdate.pcmPlayer1.setStream(WorldMapManager.pcmStreamMixer); // L: 1831 ItemLayer.decimator = new Decimator(22050, PcmPlayer.field1443); // L: 1832 @@ -498,7 +498,7 @@ public final class Canvas extends java.awt.Canvas { } } else if (Client.titleLoadingStage == 110) { // L: 2132 SoundCache.mouseRecorder = new MouseRecorder(); // L: 2133 - GameShell.taskHandler.newThreadTask(SoundCache.mouseRecorder, 10); // L: 2134 + GameEngine.taskHandler.newThreadTask(SoundCache.mouseRecorder, 10); // L: 2134 Login.Login_loadingText = "Loaded input handler"; // L: 2135 Login.Login_loadingPercent = 92; // L: 2136 Client.titleLoadingStage = 120; // L: 2137 diff --git a/runescape-client/src/main/java/Client.java b/runescape-client/src/main/java/Client.java index 69fafe983f..3190819024 100644 --- a/runescape-client/src/main/java/Client.java +++ b/runescape-client/src/main/java/Client.java @@ -15,7 +15,7 @@ import netscape.javascript.JSObject; @Implements("Client") @ObfuscatedName("client") -public final class Client extends GameShell implements Usernamed { +public final class Client extends GameEngine implements Usernamed { @ObfuscatedName("ns") @ObfuscatedSignature( descriptor = "Lhe;" @@ -1691,7 +1691,7 @@ public final class Client extends GameShell implements Usernamed { int var2; for (var2 = 0; var2 < WorldMapIcon_0.regionLandArchives.length; ++var2) { // L: 947 if (class41.regionMapArchiveIds[var2] != -1 && WorldMapIcon_0.regionLandArchives[var2] == null) { // L: 948 949 - WorldMapIcon_0.regionLandArchives[var2] = GameShell.archive5.takeFile(class41.regionMapArchiveIds[var2], 0); // L: 950 + WorldMapIcon_0.regionLandArchives[var2] = GameEngine.archive5.takeFile(class41.regionMapArchiveIds[var2], 0); // L: 950 if (WorldMapIcon_0.regionLandArchives[var2] == null) { // L: 951 var43 = false; // L: 952 ++field700; // L: 953 @@ -1699,7 +1699,7 @@ public final class Client extends GameShell implements Usernamed { } if (GrandExchangeOfferTotalQuantityComparator.regionLandArchiveIds[var2] != -1 && MouseRecorder.regionMapArchives[var2] == null) { // L: 957 958 - MouseRecorder.regionMapArchives[var2] = GameShell.archive5.takeFileEncrypted(GrandExchangeOfferTotalQuantityComparator.regionLandArchiveIds[var2], 0, class227.xteaKeys[var2]); // L: 959 + MouseRecorder.regionMapArchives[var2] = GameEngine.archive5.takeFileEncrypted(GrandExchangeOfferTotalQuantityComparator.regionLandArchiveIds[var2], 0, class227.xteaKeys[var2]); // L: 959 if (MouseRecorder.regionMapArchives[var2] == null) { // L: 960 var43 = false; // L: 961 ++field700; // L: 962 @@ -2050,8 +2050,8 @@ public final class Client extends GameShell implements Usernamed { for (var46 = var4 - 1; var46 <= var5 + 1; ++var46) { // L: 1223 for (var9 = var6 - 1; var9 <= var7 + 1; ++var9) { // L: 1224 if (var46 < var4 || var46 > var5 || var9 < var6 || var9 > var7) { // L: 1225 - GameShell.archive5.loadRegionFromName("m" + var46 + "_" + var9); // L: 1226 - GameShell.archive5.loadRegionFromName("l" + var46 + "_" + var9); // L: 1227 + GameEngine.archive5.loadRegionFromName("m" + var46 + "_" + var9); // L: 1226 + GameEngine.archive5.loadRegionFromName("l" + var46 + "_" + var9); // L: 1227 } } } @@ -2076,11 +2076,11 @@ public final class Client extends GameShell implements Usernamed { class225.clock.mark(); // L: 1250 for (var5 = 0; var5 < 32; ++var5) { // L: 1251 - GameShell.graphicsTickTimes[var5] = 0L; + GameEngine.graphicsTickTimes[var5] = 0L; } for (var5 = 0; var5 < 32; ++var5) { // L: 1252 - GameShell.clientTickTimes[var5] = 0L; + GameEngine.clientTickTimes[var5] = 0L; } class8.gameCyclesToDo = 0; // L: 1253 @@ -2687,7 +2687,7 @@ public final class Client extends GameShell implements Usernamed { if (--field864 + 1 <= 0) { // L: 1561 try { if (js5ConnectState == 0) { // L: 1563 - WorldMapManager.js5SocketTask = GameShell.taskHandler.newSocketTask(WorldMapSprite.worldHost, ArchiveDiskAction.port3); // L: 1564 + WorldMapManager.js5SocketTask = GameEngine.taskHandler.newSocketTask(WorldMapSprite.worldHost, ArchiveDiskAction.port3); // L: 1564 ++js5ConnectState; // L: 1565 } @@ -2706,7 +2706,7 @@ public final class Client extends GameShell implements Usernamed { if (useBufferedSocket) { // L: 1575 TaskHandler.js5Socket = class219.method4011((Socket)WorldMapManager.js5SocketTask.result, 40000, 5000); // L: 1576 } else { - TaskHandler.js5Socket = new NetSocket((Socket)WorldMapManager.js5SocketTask.result, GameShell.taskHandler, 5000); // L: 1579 + TaskHandler.js5Socket = new NetSocket((Socket)WorldMapManager.js5SocketTask.result, GameEngine.taskHandler, 5000); // L: 1579 } Buffer var1 = new Buffer(5); // L: 1581 @@ -2875,7 +2875,7 @@ public final class Client extends GameShell implements Usernamed { if (loginState == 1) { // L: 2221 if (WorldMapID.socketTask == null) { // L: 2222 - WorldMapID.socketTask = GameShell.taskHandler.newSocketTask(WorldMapSprite.worldHost, ArchiveDiskAction.port3); // L: 2223 + WorldMapID.socketTask = GameEngine.taskHandler.newSocketTask(WorldMapSprite.worldHost, ArchiveDiskAction.port3); // L: 2223 } if (WorldMapID.socketTask.status == 2) { // L: 2225 @@ -2886,7 +2886,7 @@ public final class Client extends GameShell implements Usernamed { if (useBufferedSocket) { // L: 2227 var1 = class219.method4011((Socket)WorldMapID.socketTask.result, 40000, 5000); // L: 2228 } else { - var1 = new NetSocket((Socket)WorldMapID.socketTask.result, GameShell.taskHandler, 5000); // L: 2231 + var1 = new NetSocket((Socket)WorldMapID.socketTask.result, GameEngine.taskHandler, 5000); // L: 2231 } packetWriter.setSocket((AbstractSocket)var1); // L: 2233 @@ -3042,7 +3042,7 @@ public final class Client extends GameShell implements Usernamed { var5.packetBuffer.writeBytes(var29.array, 0, var29.array.length); // L: 2364 var5.packetBuffer.writeByte(clientType); // L: 2365 var5.packetBuffer.writeInt(0); // L: 2366 - var5.packetBuffer.method5718(GameShell.archive5.hash); // L: 2367 + var5.packetBuffer.method5718(GameEngine.archive5.hash); // L: 2367 var5.packetBuffer.method5718(GrandExchangeOfferUnitPriceComparator.archive13.hash); // L: 2368 var5.packetBuffer.method5718(PacketBufferNode.archive12.hash); // L: 2369 var5.packetBuffer.method5587(ItemContainer.archive11.hash); // L: 2370 @@ -3164,7 +3164,7 @@ public final class Client extends GameShell implements Usernamed { if (loginState == 13) { // L: 2493 field892 = 0; // L: 2494 - GameShell.setLoginResponseString("You have only just left another world.", "Your profile will be transferred in:", field682 / 60 + " seconds."); // L: 2495 + GameEngine.setLoginResponseString("You have only just left another world.", "Your profile will be transferred in:", field682 / 60 + " seconds."); // L: 2495 if (--field682 <= 0) { // L: 2496 loginState = 0; } @@ -3270,7 +3270,7 @@ public final class Client extends GameShell implements Usernamed { String var25 = var2.readStringCp1252NullTerminated(); // L: 2591 String var33 = var2.readStringCp1252NullTerminated(); // L: 2592 String var27 = var2.readStringCp1252NullTerminated(); // L: 2593 - GameShell.setLoginResponseString(var25, var33, var27); // L: 2594 + GameEngine.setLoginResponseString(var25, var33, var27); // L: 2594 WorldMapCacheName.updateGameState(10); // L: 2595 } @@ -5333,7 +5333,7 @@ public final class Client extends GameShell implements Usernamed { var57.packetBuffer.method5569(var18); // L: 6401 var57.packetBuffer.method5718(var16); // L: 6402 var57.packetBuffer.method5587(var5); // L: 6403 - var57.packetBuffer.method5568(GameShell.fps); // L: 6404 + var57.packetBuffer.method5568(GameEngine.fps); // L: 6404 packetWriter.addNode(var57); // L: 6405 var1.serverPacket = null; // L: 6406 return true; // L: 6407 diff --git a/runescape-client/src/main/java/FontName.java b/runescape-client/src/main/java/FontName.java index a4562658d8..e65da8c031 100644 --- a/runescape-client/src/main/java/FontName.java +++ b/runescape-client/src/main/java/FontName.java @@ -237,7 +237,7 @@ public class FontName { if (var10.contentType == 1336) { // L: 9016 if (Client.displayFps) { // L: 9017 var13 += 15; // L: 9018 - WorldMapLabelSize.fontPlain12.drawRightAligned("Fps:" + GameShell.fps, var12 + var10.width, var13, 16776960, -1); // L: 9019 + WorldMapLabelSize.fontPlain12.drawRightAligned("Fps:" + GameEngine.fps, var12 + var10.width, var13, 16776960, -1); // L: 9019 var13 += 15; // L: 9020 Runtime var42 = Runtime.getRuntime(); // L: 9021 var20 = (int)((var42.totalMemory() - var42.freeMemory()) / 1024L); // L: 9022 diff --git a/runescape-client/src/main/java/GameShell.java b/runescape-client/src/main/java/GameEngine.java similarity index 98% rename from runescape-client/src/main/java/GameShell.java rename to runescape-client/src/main/java/GameEngine.java index b61fe0534e..23d72bba20 100644 --- a/runescape-client/src/main/java/GameShell.java +++ b/runescape-client/src/main/java/GameEngine.java @@ -26,7 +26,7 @@ import net.runelite.mapping.ObfuscatedSignature; @ObfuscatedName("bd") @Implements("GameShell") -public abstract class GameShell extends Applet implements Runnable, FocusListener, WindowListener { +public abstract class GameEngine extends Applet implements Runnable, FocusListener, WindowListener { @ObfuscatedName("h") @ObfuscatedSignature( descriptor = "Lfa;" @@ -38,7 +38,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene descriptor = "Lbd;" ) @Export("gameShell") - static GameShell gameShell; + static GameEngine gameEngine; @ObfuscatedName("t") @ObfuscatedGetter( intValue = 548418733 @@ -192,7 +192,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene final EventQueue eventQueue; static { - gameShell = null; // L: 41 + gameEngine = null; // L: 41 GameShell_redundantStartThreadCount = 0; // L: 43 stopTimeMs = 0L; // L: 44 isKilled = false; // L: 45 @@ -207,7 +207,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene garbageCollectorLastCheckTimeMs = -1L; // L: 86 } - protected GameShell() { + protected GameEngine() { this.hasErrored = false; // L: 46 this.canvasX = 0; // L: 59 this.canvasY = 0; // L: 60 @@ -451,7 +451,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene @Export("startThread") protected final void startThread(int var1, int var2, int var3) { try { - if (gameShell != null) { // L: 220 + if (gameEngine != null) { // L: 220 ++GameShell_redundantStartThreadCount; // L: 221 if (GameShell_redundantStartThreadCount >= 3) { // L: 222 this.error("alreadyloaded"); // L: 223 @@ -462,7 +462,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene return; // L: 227 } - gameShell = this; // L: 229 + gameEngine = this; // L: 229 IgnoreList.canvasWidth = var1; // L: 230 ModelData0.canvasHeight = var2; // L: 231 RunException.RunException_revision = var3; // L: 232 @@ -851,7 +851,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene protected abstract void vmethod1777(); public final synchronized void paint(Graphics var1) { - if (this == gameShell && !isKilled) { // L: 449 + if (this == gameEngine && !isKilled) { // L: 449 this.fullRedraw = true; // L: 450 if (class298.currentTimeMillis() - this.field472 > 1000L) { // L: 451 Rectangle var2 = var1.getClipBounds(); // L: 452 @@ -864,7 +864,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene } // L: 455 public final void destroy() { - if (this == gameShell && !isKilled) { // L: 438 + if (this == gameEngine && !isKilled) { // L: 438 stopTimeMs = class298.currentTimeMillis(); // L: 439 class236.sleepExact(5000L); // L: 440 this.kill(); // L: 441 @@ -899,13 +899,13 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene public abstract void init(); public final void stop() { - if (this == gameShell && !isKilled) { // L: 433 + if (this == gameEngine && !isKilled) { // L: 433 stopTimeMs = class298.currentTimeMillis() + 4000L; // L: 434 } } // L: 435 public final void start() { - if (this == gameShell && !isKilled) { // L: 428 + if (this == gameEngine && !isKilled) { // L: 428 stopTimeMs = 0L; // L: 429 } } // L: 430 diff --git a/runescape-client/src/main/java/GrandExchangeEvent.java b/runescape-client/src/main/java/GrandExchangeEvent.java index d0566d1427..86a473496b 100644 --- a/runescape-client/src/main/java/GrandExchangeEvent.java +++ b/runescape-client/src/main/java/GrandExchangeEvent.java @@ -132,11 +132,11 @@ public class GrandExchangeEvent { int var0; for (var0 = 0; var0 < 32; ++var0) { // L: 422 - GameShell.graphicsTickTimes[var0] = 0L; + GameEngine.graphicsTickTimes[var0] = 0L; } for (var0 = 0; var0 < 32; ++var0) { // L: 423 - GameShell.clientTickTimes[var0] = 0L; + GameEngine.clientTickTimes[var0] = 0L; } class8.gameCyclesToDo = 0; // L: 424 diff --git a/runescape-client/src/main/java/GrandExchangeOfferNameComparator.java b/runescape-client/src/main/java/GrandExchangeOfferNameComparator.java index 26a884fba0..92f6c97873 100644 --- a/runescape-client/src/main/java/GrandExchangeOfferNameComparator.java +++ b/runescape-client/src/main/java/GrandExchangeOfferNameComparator.java @@ -108,8 +108,8 @@ final class GrandExchangeOfferNameComparator implements Comparator { GarbageCollectorMXBean var2 = (GarbageCollectorMXBean)var1.next(); // L: 570 if (var2.isValid()) { // L: 572 class25.garbageCollector = var2; // L: 573 - GameShell.garbageCollectorLastCheckTimeMs = -1L; // L: 574 - GameShell.garbageCollectorLastCollectionTime = -1L; // L: 575 + GameEngine.garbageCollectorLastCheckTimeMs = -1L; // L: 574 + GameEngine.garbageCollectorLastCollectionTime = -1L; // L: 575 } } } catch (Throwable var11) { // L: 580 @@ -119,16 +119,16 @@ final class GrandExchangeOfferNameComparator implements Comparator { if (class25.garbageCollector != null) { // L: 582 long var9 = class298.currentTimeMillis(); // L: 583 long var3 = class25.garbageCollector.getCollectionTime(); // L: 584 - if (-1L != GameShell.garbageCollectorLastCollectionTime) { // L: 585 - long var5 = var3 - GameShell.garbageCollectorLastCollectionTime; // L: 586 - long var7 = var9 - GameShell.garbageCollectorLastCheckTimeMs; // L: 587 + if (-1L != GameEngine.garbageCollectorLastCollectionTime) { // L: 585 + long var5 = var3 - GameEngine.garbageCollectorLastCollectionTime; // L: 586 + long var7 = var9 - GameEngine.garbageCollectorLastCheckTimeMs; // L: 587 if (var7 != 0L) { // L: 588 var0 = (int)(100L * var5 / var7); } } - GameShell.garbageCollectorLastCollectionTime = var3; // L: 590 - GameShell.garbageCollectorLastCheckTimeMs = var9; // L: 591 + GameEngine.garbageCollectorLastCollectionTime = var3; // L: 590 + GameEngine.garbageCollectorLastCheckTimeMs = var9; // L: 591 } return var0; // L: 593 diff --git a/runescape-client/src/main/java/ItemContainer.java b/runescape-client/src/main/java/ItemContainer.java index 27b759e733..c5a3f4bafb 100644 --- a/runescape-client/src/main/java/ItemContainer.java +++ b/runescape-client/src/main/java/ItemContainer.java @@ -170,8 +170,8 @@ public class ItemContainer extends Node { var8 = var7 + (var6 << 8); // L: 5317 if (!var16 || var7 != 49 && var7 != 149 && var7 != 147 && var6 != 50 && (var6 != 49 || var7 != 47)) { // L: 5318 FileSystem.regions[var4] = var8; // L: 5319 - class41.regionMapArchiveIds[var4] = GameShell.archive5.getGroupId("m" + var6 + "_" + var7); // L: 5320 - GrandExchangeOfferTotalQuantityComparator.regionLandArchiveIds[var4] = GameShell.archive5.getGroupId("l" + var6 + "_" + var7); // L: 5321 + class41.regionMapArchiveIds[var4] = GameEngine.archive5.getGroupId("m" + var6 + "_" + var7); // L: 5320 + GrandExchangeOfferTotalQuantityComparator.regionLandArchiveIds[var4] = GameEngine.archive5.getGroupId("l" + var6 + "_" + var7); // L: 5321 ++var4; // L: 5322 } } @@ -236,8 +236,8 @@ public class ItemContainer extends Node { FileSystem.regions[var5] = var12; // L: 5368 var13 = var12 >> 8 & 255; // L: 5369 int var14 = var12 & 255; // L: 5370 - class41.regionMapArchiveIds[var5] = GameShell.archive5.getGroupId("m" + var13 + "_" + var14); // L: 5371 - GrandExchangeOfferTotalQuantityComparator.regionLandArchiveIds[var5] = GameShell.archive5.getGroupId("l" + var13 + "_" + var14); // L: 5372 + class41.regionMapArchiveIds[var5] = GameEngine.archive5.getGroupId("m" + var13 + "_" + var14); // L: 5371 + GrandExchangeOfferTotalQuantityComparator.regionLandArchiveIds[var5] = GameEngine.archive5.getGroupId("l" + var13 + "_" + var14); // L: 5372 ++var5; // L: 5373 } } diff --git a/runescape-client/src/main/java/Messages.java b/runescape-client/src/main/java/Messages.java index 9ef82f2c62..b8cb8a37df 100644 --- a/runescape-client/src/main/java/Messages.java +++ b/runescape-client/src/main/java/Messages.java @@ -94,6 +94,6 @@ public class Messages { ) static void method2285() { Login.loginIndex = 24; // L: 1517 - GameShell.setLoginResponseString("The game servers are currently being updated.", "Please wait a few minutes and try again.", ""); // L: 1518 + GameEngine.setLoginResponseString("The game servers are currently being updated.", "Please wait a few minutes and try again.", ""); // L: 1518 } // L: 1519 } diff --git a/runescape-client/src/main/java/SequenceDefinition.java b/runescape-client/src/main/java/SequenceDefinition.java index 5e7a03606e..561e3fb410 100644 --- a/runescape-client/src/main/java/SequenceDefinition.java +++ b/runescape-client/src/main/java/SequenceDefinition.java @@ -381,7 +381,7 @@ public class SequenceDefinition extends DualNode { garbageValue = "1" ) @Export("doCycleTitle") - static void doCycleTitle(GameShell var0) { + static void doCycleTitle(GameEngine var0) { int var2; int var3; int var4; @@ -662,12 +662,12 @@ public class SequenceDefinition extends DualNode { var35 += 15; // L: 496 var36 = 361; // L: 497 - if (GameShell.field481 != null) { // L: 498 - var38 = GameShell.field481.highX / 2; // L: 499 - if (var4 == 1 && var44 >= GameShell.field481.lowX - var38 && var44 <= var38 + GameShell.field481.lowX && var34 >= var36 - 15 && var34 < var36) { // L: 500 + if (GameEngine.field481 != null) { // L: 498 + var38 = GameEngine.field481.highX / 2; // L: 499 + if (var4 == 1 && var44 >= GameEngine.field481.lowX - var38 && var44 <= var38 + GameEngine.field481.lowX && var34 >= var36 - 15 && var34 < var36) { // L: 500 switch(Login.field1190) { // L: 501 case 1: - GameShell.setLoginResponseString("Please enter your username.", "If you created your account after November", "2010, this will be the creation email address."); // L: 504 + GameEngine.setLoginResponseString("Please enter your username.", "If you created your account after November", "2010, this will be the creation email address."); // L: 504 Login.loginIndex = 5; // L: 505 return; // L: 506 case 2: @@ -681,16 +681,16 @@ public class SequenceDefinition extends DualNode { if (var4 == 1 && var44 >= var38 - 75 && var44 <= var38 + 75 && var34 >= var37 - 20 && var34 <= var37 + 20) { // L: 518 Login.Login_username = Login.Login_username.trim(); // L: 519 if (Login.Login_username.length() == 0) { // L: 520 - GameShell.setLoginResponseString("", "Please enter your username/email address.", ""); // L: 521 + GameEngine.setLoginResponseString("", "Please enter your username/email address.", ""); // L: 521 return; // L: 522 } if (Login.Login_password.length() == 0) { // L: 524 - GameShell.setLoginResponseString("", "Please enter your password.", ""); // L: 525 + GameEngine.setLoginResponseString("", "Please enter your password.", ""); // L: 525 return; // L: 526 } - GameShell.setLoginResponseString("", "Connecting to server...", ""); // L: 528 + GameEngine.setLoginResponseString("", "Connecting to server...", ""); // L: 528 WorldMapDecoration.method380(false); // L: 529 WorldMapCacheName.updateGameState(20); // L: 530 return; // L: 531 @@ -782,16 +782,16 @@ public class SequenceDefinition extends DualNode { if (StudioGame.field3135 == 84) { // L: 591 Login.Login_username = Login.Login_username.trim(); // L: 592 if (Login.Login_username.length() == 0) { // L: 593 - GameShell.setLoginResponseString("", "Please enter your username/email address.", ""); // L: 594 + GameEngine.setLoginResponseString("", "Please enter your username/email address.", ""); // L: 594 return; // L: 595 } if (Login.Login_password.length() == 0) { // L: 597 - GameShell.setLoginResponseString("", "Please enter your password.", ""); // L: 598 + GameEngine.setLoginResponseString("", "Please enter your password.", ""); // L: 598 return; // L: 599 } - GameShell.setLoginResponseString("", "Connecting to server...", ""); // L: 601 + GameEngine.setLoginResponseString("", "Connecting to server...", ""); // L: 601 WorldMapDecoration.method380(false); // L: 602 WorldMapCacheName.updateGameState(20); // L: 603 return; // L: 604 @@ -880,7 +880,7 @@ public class SequenceDefinition extends DualNode { var35 = Login.loginBoxX + 180; // L: 688 var8 = 326; // L: 689 if (var4 == 1 && var44 >= var35 - 75 && var44 <= var35 + 75 && var34 >= var8 - 20 && var34 <= var8 + 20) { // L: 690 - GameShell.setLoginResponseString("Please enter your username.", "If you created your account after November", "2010, this will be the creation email address."); // L: 691 + GameEngine.setLoginResponseString("Please enter your username.", "If you created your account after November", "2010, this will be the creation email address."); // L: 691 Login.loginIndex = 5; // L: 692 return; // L: 693 } @@ -892,14 +892,14 @@ public class SequenceDefinition extends DualNode { if (var4 == 1 && var44 >= var35 - 75 && var44 <= var35 + 75 && var34 >= var8 - 20 && var34 <= var8 + 20) { // L: 699 SecureRandomCallable.otp.trim(); // L: 700 if (SecureRandomCallable.otp.length() != 6) { // L: 701 - GameShell.setLoginResponseString("", "Please enter a 6-digit PIN.", ""); // L: 702 + GameEngine.setLoginResponseString("", "Please enter a 6-digit PIN.", ""); // L: 702 return; // L: 703 } WorldMapSection1.field313 = Integer.parseInt(SecureRandomCallable.otp); // L: 705 SecureRandomCallable.otp = ""; // L: 706 WorldMapDecoration.method380(true); // L: 707 - GameShell.setLoginResponseString("", "Connecting to server...", ""); // L: 708 + GameEngine.setLoginResponseString("", "Connecting to server...", ""); // L: 708 WorldMapCacheName.updateGameState(20); // L: 709 return; // L: 710 } @@ -945,14 +945,14 @@ public class SequenceDefinition extends DualNode { if (StudioGame.field3135 == 84) { // L: 743 SecureRandomCallable.otp.trim(); // L: 744 if (SecureRandomCallable.otp.length() != 6) { // L: 745 - GameShell.setLoginResponseString("", "Please enter a 6-digit PIN.", ""); // L: 746 + GameEngine.setLoginResponseString("", "Please enter a 6-digit PIN.", ""); // L: 746 return; // L: 747 } WorldMapSection1.field313 = Integer.parseInt(SecureRandomCallable.otp); // L: 749 SecureRandomCallable.otp = ""; // L: 750 WorldMapDecoration.method380(true); // L: 751 - GameShell.setLoginResponseString("", "Connecting to server...", ""); // L: 752 + GameEngine.setLoginResponseString("", "Connecting to server...", ""); // L: 752 WorldMapCacheName.updateGameState(20); // L: 753 return; // L: 754 } @@ -1016,7 +1016,7 @@ public class SequenceDefinition extends DualNode { var8 = 321; // L: 812 if (var4 == 1 && var44 >= var35 - 75 && var44 <= var35 + 75 && var34 >= var8 - 20 && var34 <= var8 + 20) { // L: 813 AttackOption.openURL(AbstractWorldMapIcon.method632("secure", true) + "m=dob/set_dob.ws", true, false); // L: 814 - GameShell.setLoginResponseString("", "Page has opened in a new window.", "(Please check your popup blocker.)"); // L: 815 + GameEngine.setLoginResponseString("", "Page has opened in a new window.", "(Please check your popup blocker.)"); // L: 815 Login.loginIndex = 6; // L: 816 return; // L: 817 } @@ -1030,7 +1030,7 @@ public class SequenceDefinition extends DualNode { var8 = 321; // L: 826 if (var4 == 1 && var44 >= var35 - 75 && var44 <= var35 + 75 && var34 >= var8 - 20 && var34 <= var8 + 20) { // L: 827 AttackOption.openURL("https://www.jagex.com/terms/privacy", true, false); // L: 828 - GameShell.setLoginResponseString("", "Page has opened in a new window.", "(Please check your popup blocker.)"); // L: 829 + GameEngine.setLoginResponseString("", "Page has opened in a new window.", "(Please check your popup blocker.)"); // L: 829 Login.loginIndex = 6; // L: 830 return; // L: 831 } @@ -1056,7 +1056,7 @@ public class SequenceDefinition extends DualNode { var37 = 276; // L: 852 if (var4 == 1 && var44 >= var38 - 75 && var44 <= var38 + 75 && var34 >= var37 - 20 && var34 <= var37 + 20) { // L: 853 AttackOption.openURL(var30, true, false); // L: 854 - GameShell.setLoginResponseString("", "Page has opened in a new window.", "(Please check your popup blocker.)"); // L: 855 + GameEngine.setLoginResponseString("", "Page has opened in a new window.", "(Please check your popup blocker.)"); // L: 855 Login.loginIndex = 6; // L: 856 return; // L: 857 } diff --git a/runescape-client/src/main/java/UserComparator8.java b/runescape-client/src/main/java/UserComparator8.java index e6da9b50b7..b36ec51570 100644 --- a/runescape-client/src/main/java/UserComparator8.java +++ b/runescape-client/src/main/java/UserComparator8.java @@ -44,11 +44,11 @@ public class UserComparator8 extends AbstractUserComparator { @Export("getLoginError") static void getLoginError(int var0) { if (var0 == -3) { // L: 2791 - GameShell.setLoginResponseString("Connection timed out.", "Please try using a different world.", ""); + GameEngine.setLoginResponseString("Connection timed out.", "Please try using a different world.", ""); } else if (var0 == -2) { // L: 2792 - GameShell.setLoginResponseString("Error connecting to server.", "Please try using a different world.", ""); + GameEngine.setLoginResponseString("Error connecting to server.", "Please try using a different world.", ""); } else if (var0 == -1) { // L: 2793 - GameShell.setLoginResponseString("No response from server.", "Please try using a different world.", ""); + GameEngine.setLoginResponseString("No response from server.", "Please try using a different world.", ""); } else if (var0 == 3) { // L: 2794 Login.loginIndex = 3; // L: 2795 Login.field1190 = 1; // L: 2796 @@ -57,66 +57,66 @@ public class UserComparator8 extends AbstractUserComparator { Login.field1199 = 0; // L: 2801 } else if (var0 == 5) { // L: 2804 Login.field1190 = 2; // L: 2805 - GameShell.setLoginResponseString("Your account has not logged out from its last", "session or the server is too busy right now.", "Please try again in a few minutes."); // L: 2806 + GameEngine.setLoginResponseString("Your account has not logged out from its last", "session or the server is too busy right now.", "Please try again in a few minutes."); // L: 2806 } else if (var0 != 68 && (Client.onMobile || var0 != 6)) { // L: 2808 if (var0 == 7) { // L: 2811 - GameShell.setLoginResponseString("This world is full.", "Please use a different world.", ""); + GameEngine.setLoginResponseString("This world is full.", "Please use a different world.", ""); } else if (var0 == 8) { // L: 2812 - GameShell.setLoginResponseString("Unable to connect.", "Login server offline.", ""); + GameEngine.setLoginResponseString("Unable to connect.", "Login server offline.", ""); } else if (var0 == 9) { // L: 2813 - GameShell.setLoginResponseString("Login limit exceeded.", "Too many connections from your address.", ""); + GameEngine.setLoginResponseString("Login limit exceeded.", "Too many connections from your address.", ""); } else if (var0 == 10) { // L: 2814 - GameShell.setLoginResponseString("Unable to connect.", "Bad session id.", ""); + GameEngine.setLoginResponseString("Unable to connect.", "Bad session id.", ""); } else if (var0 == 11) { // L: 2815 - GameShell.setLoginResponseString("We suspect someone knows your password.", "Press 'change your password' on front page.", ""); + GameEngine.setLoginResponseString("We suspect someone knows your password.", "Press 'change your password' on front page.", ""); } else if (var0 == 12) { // L: 2816 - GameShell.setLoginResponseString("You need a members account to login to this world.", "Please subscribe, or use a different world.", ""); + GameEngine.setLoginResponseString("You need a members account to login to this world.", "Please subscribe, or use a different world.", ""); } else if (var0 == 13) { // L: 2817 - GameShell.setLoginResponseString("Could not complete login.", "Please try using a different world.", ""); + GameEngine.setLoginResponseString("Could not complete login.", "Please try using a different world.", ""); } else if (var0 == 14) { // L: 2818 - GameShell.setLoginResponseString("The server is being updated.", "Please wait 1 minute and try again.", ""); + GameEngine.setLoginResponseString("The server is being updated.", "Please wait 1 minute and try again.", ""); } else if (var0 == 16) { // L: 2819 - GameShell.setLoginResponseString("Too many login attempts.", "Please wait a few minutes before trying again.", ""); + GameEngine.setLoginResponseString("Too many login attempts.", "Please wait a few minutes before trying again.", ""); } else if (var0 == 17) { // L: 2820 - GameShell.setLoginResponseString("You are standing in a members-only area.", "To play on this world move to a free area first", ""); + GameEngine.setLoginResponseString("You are standing in a members-only area.", "To play on this world move to a free area first", ""); } else if (var0 == 18) { // L: 2821 Login.loginIndex = 12; // L: 2823 Login.field1199 = 1; // L: 2824 } else if (var0 == 19) { // L: 2827 - GameShell.setLoginResponseString("This world is running a closed Beta.", "Sorry invited players only.", "Please use a different world."); + GameEngine.setLoginResponseString("This world is running a closed Beta.", "Sorry invited players only.", "Please use a different world."); } else if (var0 == 20) { // L: 2828 - GameShell.setLoginResponseString("Invalid loginserver requested.", "Please try using a different world.", ""); + GameEngine.setLoginResponseString("Invalid loginserver requested.", "Please try using a different world.", ""); } else if (var0 == 22) { // L: 2829 - GameShell.setLoginResponseString("Malformed login packet.", "Please try again.", ""); + GameEngine.setLoginResponseString("Malformed login packet.", "Please try again.", ""); } else if (var0 == 23) { // L: 2830 - GameShell.setLoginResponseString("No reply from loginserver.", "Please wait 1 minute and try again.", ""); + GameEngine.setLoginResponseString("No reply from loginserver.", "Please wait 1 minute and try again.", ""); } else if (var0 == 24) { // L: 2831 - GameShell.setLoginResponseString("Error loading your profile.", "Please contact customer support.", ""); + GameEngine.setLoginResponseString("Error loading your profile.", "Please contact customer support.", ""); } else if (var0 == 25) { // L: 2832 - GameShell.setLoginResponseString("Unexpected loginserver response.", "Please try using a different world.", ""); + GameEngine.setLoginResponseString("Unexpected loginserver response.", "Please try using a different world.", ""); } else if (var0 == 26) { // L: 2833 - GameShell.setLoginResponseString("This computers address has been blocked", "as it was used to break our rules.", ""); + GameEngine.setLoginResponseString("This computers address has been blocked", "as it was used to break our rules.", ""); } else if (var0 == 27) { // L: 2834 - GameShell.setLoginResponseString("", "Service unavailable.", ""); + GameEngine.setLoginResponseString("", "Service unavailable.", ""); } else if (var0 == 31) { // L: 2835 - GameShell.setLoginResponseString("Your account must have a displayname set", "in order to play the game. Please set it", "via the website, or the main game."); + GameEngine.setLoginResponseString("Your account must have a displayname set", "in order to play the game. Please set it", "via the website, or the main game."); } else if (var0 == 32) { - GameShell.setLoginResponseString("Your attempt to log into your account was", "unsuccessful. Don't worry, you can sort", "this out by visiting the billing system."); // L: 2836 + GameEngine.setLoginResponseString("Your attempt to log into your account was", "unsuccessful. Don't worry, you can sort", "this out by visiting the billing system."); // L: 2836 } else if (var0 == 37) { // L: 2837 - GameShell.setLoginResponseString("Your account is currently inaccessible.", "Please try again in a few minutes.", ""); + GameEngine.setLoginResponseString("Your account is currently inaccessible.", "Please try again in a few minutes.", ""); } else if (var0 == 38) { // L: 2838 - GameShell.setLoginResponseString("You need to vote to play!", "Visit runescape.com and vote,", "and then come back here!"); + GameEngine.setLoginResponseString("You need to vote to play!", "Visit runescape.com and vote,", "and then come back here!"); } else if (var0 == 55) { // L: 2839 Login.loginIndex = 8; // L: 2840 } else { if (var0 == 56) { // L: 2842 - GameShell.setLoginResponseString("Enter the 6-digit code generated by your", "authenticator app.", ""); // L: 2843 + GameEngine.setLoginResponseString("Enter the 6-digit code generated by your", "authenticator app.", ""); // L: 2843 WorldMapCacheName.updateGameState(11); // L: 2844 return; // L: 2845 } if (var0 == 57) { // L: 2847 - GameShell.setLoginResponseString("The code you entered was incorrect.", "Please try again.", ""); // L: 2848 + GameEngine.setLoginResponseString("The code you entered was incorrect.", "Please try again.", ""); // L: 2848 WorldMapCacheName.updateGameState(11); // L: 2849 return; // L: 2850 } @@ -124,11 +124,11 @@ public class UserComparator8 extends AbstractUserComparator { if (var0 == 61) { // L: 2852 Login.loginIndex = 7; // L: 2853 } else { - GameShell.setLoginResponseString("Unexpected server response", "Please try using a different world.", ""); // L: 2855 + GameEngine.setLoginResponseString("Unexpected server response", "Please try using a different world.", ""); // L: 2855 } } } else { - GameShell.setLoginResponseString("RuneScape has been updated!", "Please reload this page.", ""); // L: 2809 + GameEngine.setLoginResponseString("RuneScape has been updated!", "Please reload this page.", ""); // L: 2809 } WorldMapCacheName.updateGameState(10); // L: 2856 diff --git a/runescape-client/src/main/java/WorldMapRectangle.java b/runescape-client/src/main/java/WorldMapRectangle.java index 2a05e24647..cb925cfab9 100644 --- a/runescape-client/src/main/java/WorldMapRectangle.java +++ b/runescape-client/src/main/java/WorldMapRectangle.java @@ -140,7 +140,7 @@ public final class WorldMapRectangle { WorldMapSprite.archive1.clearFiles(); // L: 2905 class330.archive3.clearFiles(); // L: 2906 class227.archive4.clearFiles(); // L: 2907 - GameShell.archive5.clearFiles(); // L: 2908 + GameEngine.archive5.clearFiles(); // L: 2908 class217.archive6.clearFiles(); // L: 2909 BuddyRankComparator.archive7.clearFiles(); // L: 2910 Messages.archive8.clearFiles(); // L: 2911 diff --git a/runescape-client/src/main/java/WorldMapSection1.java b/runescape-client/src/main/java/WorldMapSection1.java index e383cd225e..0b7208b2f0 100644 --- a/runescape-client/src/main/java/WorldMapSection1.java +++ b/runescape-client/src/main/java/WorldMapSection1.java @@ -182,7 +182,7 @@ public class WorldMapSection1 implements WorldMapSection { switch(var0) { // L: 2941 case 1: Login.loginIndex = 24; // L: 2950 - GameShell.setLoginResponseString("", "You were disconnected from the server.", ""); // L: 2951 + GameEngine.setLoginResponseString("", "You were disconnected from the server.", ""); // L: 2951 break; case 2: Messages.method2285(); // L: 2944 diff --git a/runescape-client/src/main/java/class7.java b/runescape-client/src/main/java/class7.java index 5ebfdf7f0c..187c84a75f 100644 --- a/runescape-client/src/main/java/class7.java +++ b/runescape-client/src/main/java/class7.java @@ -444,7 +444,7 @@ public enum class7 implements Enumerated { static void method83() { Login.Login_username = Login.Login_username.trim(); // L: 896 if (Login.Login_username.length() == 0) { // L: 897 - GameShell.setLoginResponseString("Please enter your username.", "If you created your account after November", "2010, this will be the creation email address."); // L: 898 + GameEngine.setLoginResponseString("Please enter your username.", "If you created your account after November", "2010, this will be the creation email address."); // L: 898 } else { long var1; try { @@ -488,23 +488,23 @@ public enum class7 implements Enumerated { switch(var0) { // L: 936 case 2: - GameShell.setLoginResponseString(Strings.field3053, Strings.field3054, Strings.field3055); // L: 941 + GameEngine.setLoginResponseString(Strings.field3053, Strings.field3054, Strings.field3055); // L: 941 Login.loginIndex = 6; // L: 942 break; // L: 943 case 3: - GameShell.setLoginResponseString("", "Error connecting to server.", ""); // L: 954 + GameEngine.setLoginResponseString("", "Error connecting to server.", ""); // L: 954 break; case 4: - GameShell.setLoginResponseString("The part of the website you are trying", "to connect to is offline at the moment.", "Please try again later."); // L: 951 + GameEngine.setLoginResponseString("The part of the website you are trying", "to connect to is offline at the moment.", "Please try again later."); // L: 951 break; // L: 952 case 5: - GameShell.setLoginResponseString("Sorry, there was an error trying to", "log you in to this part of the website.", "Please try again later."); // L: 938 + GameEngine.setLoginResponseString("Sorry, there was an error trying to", "log you in to this part of the website.", "Please try again later."); // L: 938 break; // L: 939 case 6: - GameShell.setLoginResponseString("", "Error connecting to server.", ""); // L: 948 + GameEngine.setLoginResponseString("", "Error connecting to server.", ""); // L: 948 break; // L: 949 case 7: - GameShell.setLoginResponseString("You must enter a valid login to proceed. For accounts", "created after 24th November 2010, please use your", "email address. Otherwise please use your username."); // L: 945 + GameEngine.setLoginResponseString("You must enter a valid login to proceed. For accounts", "created after 24th November 2010, please use your", "email address. Otherwise please use your username."); // L: 945 } }